summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore9
-rw-r--r--ChangeLog6
-rw-r--r--ConvertUTF/ConvertUTF.c539
-rw-r--r--ConvertUTF/ConvertUTF.h149
-rw-r--r--ConvertUTF/readme.txt43
-rw-r--r--Makefile.am14
-rw-r--r--PKGBUILD5
-rw-r--r--PORTABLE_BUILD1
-rw-r--r--PORTABLE_VERSION1
-rw-r--r--about.txt4
-rw-r--r--common.h17
-rw-r--r--conf.c95
-rw-r--r--conf.h22
-rw-r--r--configure.ac204
-rw-r--r--deadbeef.h393
-rw-r--r--dsppreset.c140
-rw-r--r--dsppreset.h (renamed from plugins/supereq/supereq.h)20
-rw-r--r--examples/decoder_template.c (renamed from decoder_template.c)59
-rw-r--r--examples/dsp_template.c133
-rwxr-xr-xinsertlicense.sh20
-rw-r--r--junklib.c691
-rw-r--r--junklib.h2
-rw-r--r--lib-x86-32/include/FLAC/Makefile.am42
-rw-r--r--lib-x86-32/include/FLAC/all.h370
-rw-r--r--lib-x86-32/include/FLAC/assert.h45
-rw-r--r--lib-x86-32/include/FLAC/callback.h184
-rw-r--r--lib-x86-32/include/FLAC/export.h91
-rw-r--r--lib-x86-32/include/FLAC/format.h1010
-rw-r--r--lib-x86-32/include/FLAC/metadata.h2181
-rw-r--r--lib-x86-32/include/FLAC/ordinals.h80
-rw-r--r--lib-x86-32/include/FLAC/stream_decoder.h1559
-rw-r--r--lib-x86-32/include/FLAC/stream_encoder.h1768
-rw-r--r--lib-x86-32/include/cddb/Makefile.am9
-rw-r--r--lib-x86-32/include/cddb/cddb.h97
-rw-r--r--lib-x86-32/include/cddb/cddb_cmd.h185
-rw-r--r--lib-x86-32/include/cddb/cddb_cmd_ni.h68
-rw-r--r--lib-x86-32/include/cddb/cddb_config.h37
-rw-r--r--lib-x86-32/include/cddb/cddb_config.h.in37
-rw-r--r--lib-x86-32/include/cddb/cddb_conn.h562
-rw-r--r--lib-x86-32/include/cddb/cddb_conn_ni.h178
-rw-r--r--lib-x86-32/include/cddb/cddb_disc.h450
-rw-r--r--lib-x86-32/include/cddb/cddb_error.h118
-rw-r--r--lib-x86-32/include/cddb/cddb_log.h87
-rw-r--r--lib-x86-32/include/cddb/cddb_log_ni.h59
-rw-r--r--lib-x86-32/include/cddb/cddb_net.h133
-rw-r--r--lib-x86-32/include/cddb/cddb_ni.h189
-rw-r--r--lib-x86-32/include/cddb/cddb_regex.h74
-rw-r--r--lib-x86-32/include/cddb/cddb_site.h248
-rw-r--r--lib-x86-32/include/cddb/cddb_track.h244
-rw-r--r--lib-x86-32/include/cddb/ll.h148
-rw-r--r--lib-x86-32/include/cddb/version.h12
-rw-r--r--lib-x86-32/include/cddb/version.h.in12
-rw-r--r--lib-x86-32/include/cdio/Makefile.am62
-rw-r--r--lib-x86-32/include/cdio/audio.h148
-rw-r--r--lib-x86-32/include/cdio/bytesex.h220
-rw-r--r--lib-x86-32/include/cdio/bytesex_asm.h130
-rw-r--r--lib-x86-32/include/cdio/cd_types.h175
-rw-r--r--lib-x86-32/include/cdio/cdda.h411
-rw-r--r--lib-x86-32/include/cdio/cdio.h84
-rw-r--r--lib-x86-32/include/cdio/cdio_config.h258
-rw-r--r--lib-x86-32/include/cdio/cdtext.h125
-rw-r--r--lib-x86-32/include/cdio/device.h995
-rw-r--r--lib-x86-32/include/cdio/disc.h108
-rw-r--r--lib-x86-32/include/cdio/ds.h98
-rw-r--r--lib-x86-32/include/cdio/dvd.h112
-rw-r--r--lib-x86-32/include/cdio/ecma_167.h1006
-rw-r--r--lib-x86-32/include/cdio/iso9660.h1116
-rw-r--r--lib-x86-32/include/cdio/logging.h136
-rw-r--r--lib-x86-32/include/cdio/mmc.h907
-rw-r--r--lib-x86-32/include/cdio/paranoia.h202
-rw-r--r--lib-x86-32/include/cdio/posix.h43
-rw-r--r--lib-x86-32/include/cdio/read.h235
-rw-r--r--lib-x86-32/include/cdio/rock.h396
-rw-r--r--lib-x86-32/include/cdio/sector.h286
-rw-r--r--lib-x86-32/include/cdio/track.h269
-rw-r--r--lib-x86-32/include/cdio/types.h327
-rw-r--r--lib-x86-32/include/cdio/udf.h171
-rw-r--r--lib-x86-32/include/cdio/udf_file.h117
-rw-r--r--lib-x86-32/include/cdio/udf_time.h80
-rw-r--r--lib-x86-32/include/cdio/utf8.h92
-rw-r--r--lib-x86-32/include/cdio/util.h117
-rw-r--r--lib-x86-32/include/cdio/version.h12
-rw-r--r--lib-x86-32/include/cdio/version.h.in12
-rw-r--r--lib-x86-32/include/cdio/xa.h179
-rw-r--r--lib-x86-32/include/curl/Makefile.am25
-rw-r--r--lib-x86-32/include/curl/curl.h2119
-rw-r--r--lib-x86-32/include/curl/curlbuild.h191
-rw-r--r--lib-x86-32/include/curl/curlbuild.h.cmake180
-rw-r--r--lib-x86-32/include/curl/curlbuild.h.in190
-rw-r--r--lib-x86-32/include/curl/curlrules.h252
-rw-r--r--lib-x86-32/include/curl/curlver.h69
-rw-r--r--lib-x86-32/include/curl/easy.h102
-rw-r--r--lib-x86-32/include/curl/mprintf.h81
-rw-r--r--lib-x86-32/include/curl/multi.h345
-rw-r--r--lib-x86-32/include/curl/stdcheaders.h33
-rw-r--r--lib-x86-32/include/curl/typecheck-gcc.h584
-rw-r--r--lib-x86-32/include/curl/types.h1
-rw-r--r--lib-x86-32/include/dbus-1/dbus/dbus-address.h67
-rw-r--r--lib-x86-32/include/dbus-1/dbus/dbus-arch-deps.h67
-rw-r--r--lib-x86-32/include/dbus-1/dbus/dbus-auth-script.h37
-rw-r--r--lib-x86-32/include/dbus-1/dbus/dbus-auth.h83
-rw-r--r--lib-x86-32/include/dbus-1/dbus/dbus-bus.h95
-rw-r--r--lib-x86-32/include/dbus-1/dbus/dbus-connection-internal.h121
-rw-r--r--lib-x86-32/include/dbus-1/dbus/dbus-connection.h495
-rw-r--r--lib-x86-32/include/dbus-1/dbus/dbus-credentials.h79
-rw-r--r--lib-x86-32/include/dbus-1/dbus/dbus-dataslot.h96
-rw-r--r--lib-x86-32/include/dbus-1/dbus/dbus-errors.h90
-rw-r--r--lib-x86-32/include/dbus-1/dbus/dbus-file.h63
-rw-r--r--lib-x86-32/include/dbus-1/dbus/dbus-hash.h151
-rw-r--r--lib-x86-32/include/dbus-1/dbus/dbus-internals.h367
-rw-r--r--lib-x86-32/include/dbus-1/dbus/dbus-keyring.h52
-rw-r--r--lib-x86-32/include/dbus-1/dbus/dbus-list.h98
-rw-r--r--lib-x86-32/include/dbus-1/dbus/dbus-macros.h174
-rw-r--r--lib-x86-32/include/dbus-1/dbus/dbus-mainloop.h76
-rw-r--r--lib-x86-32/include/dbus-1/dbus/dbus-marshal-basic.h273
-rw-r--r--lib-x86-32/include/dbus-1/dbus/dbus-marshal-byteswap.h37
-rw-r--r--lib-x86-32/include/dbus-1/dbus/dbus-marshal-header.h128
-rw-r--r--lib-x86-32/include/dbus-1/dbus/dbus-marshal-recursive.h191
-rw-r--r--lib-x86-32/include/dbus-1/dbus/dbus-marshal-validate.h198
-rw-r--r--lib-x86-32/include/dbus-1/dbus/dbus-memory.h65
-rw-r--r--lib-x86-32/include/dbus-1/dbus/dbus-mempool.h44
-rw-r--r--lib-x86-32/include/dbus-1/dbus/dbus-message-factory.h61
-rw-r--r--lib-x86-32/include/dbus-1/dbus/dbus-message-internal.h89
-rw-r--r--lib-x86-32/include/dbus-1/dbus/dbus-message-private.h148
-rw-r--r--lib-x86-32/include/dbus-1/dbus/dbus-message.h309
-rw-r--r--lib-x86-32/include/dbus-1/dbus/dbus-misc.h52
-rw-r--r--lib-x86-32/include/dbus-1/dbus/dbus-nonce.h72
-rw-r--r--lib-x86-32/include/dbus-1/dbus/dbus-object-tree.h62
-rw-r--r--lib-x86-32/include/dbus-1/dbus/dbus-pending-call-internal.h67
-rw-r--r--lib-x86-32/include/dbus-1/dbus/dbus-pending-call.h76
-rw-r--r--lib-x86-32/include/dbus-1/dbus/dbus-pipe.h59
-rw-r--r--lib-x86-32/include/dbus-1/dbus/dbus-protocol.h462
-rw-r--r--lib-x86-32/include/dbus-1/dbus/dbus-resources.h57
-rw-r--r--lib-x86-32/include/dbus-1/dbus/dbus-server-debug-pipe.h47
-rw-r--r--lib-x86-32/include/dbus-1/dbus/dbus-server-protected.h159
-rw-r--r--lib-x86-32/include/dbus-1/dbus/dbus-server-socket.h52
-rw-r--r--lib-x86-32/include/dbus-1/dbus/dbus-server-unix.h37
-rw-r--r--lib-x86-32/include/dbus-1/dbus/dbus-server-win.h36
-rw-r--r--lib-x86-32/include/dbus-1/dbus/dbus-server.h106
-rw-r--r--lib-x86-32/include/dbus-1/dbus/dbus-sha.h55
-rw-r--r--lib-x86-32/include/dbus-1/dbus/dbus-shared.h131
-rw-r--r--lib-x86-32/include/dbus-1/dbus/dbus-shell.h41
-rw-r--r--lib-x86-32/include/dbus-1/dbus/dbus-signature.h92
-rw-r--r--lib-x86-32/include/dbus-1/dbus/dbus-sockets-win.h76
-rw-r--r--lib-x86-32/include/dbus-1/dbus/dbus-spawn.h61
-rw-r--r--lib-x86-32/include/dbus-1/dbus/dbus-string-private.h124
-rw-r--r--lib-x86-32/include/dbus-1/dbus/dbus-string.h332
-rw-r--r--lib-x86-32/include/dbus-1/dbus/dbus-sysdeps-unix.h138
-rw-r--r--lib-x86-32/include/dbus-1/dbus/dbus-sysdeps-win.h88
-rw-r--r--lib-x86-32/include/dbus-1/dbus/dbus-sysdeps-wince-glue.h246
-rw-r--r--lib-x86-32/include/dbus-1/dbus/dbus-sysdeps.h531
-rw-r--r--lib-x86-32/include/dbus-1/dbus/dbus-test.h83
-rw-r--r--lib-x86-32/include/dbus-1/dbus/dbus-threads-internal.h53
-rw-r--r--lib-x86-32/include/dbus-1/dbus/dbus-threads.h198
-rw-r--r--lib-x86-32/include/dbus-1/dbus/dbus-timeout.h75
-rw-r--r--lib-x86-32/include/dbus-1/dbus/dbus-transport-protected.h146
-rw-r--r--lib-x86-32/include/dbus-1/dbus/dbus-transport-socket.h46
-rw-r--r--lib-x86-32/include/dbus-1/dbus/dbus-transport-unix.h37
-rw-r--r--lib-x86-32/include/dbus-1/dbus/dbus-transport-win.h33
-rw-r--r--lib-x86-32/include/dbus-1/dbus/dbus-transport.h103
-rw-r--r--lib-x86-32/include/dbus-1/dbus/dbus-types.h139
-rw-r--r--lib-x86-32/include/dbus-1/dbus/dbus-userdb.h121
-rw-r--r--lib-x86-32/include/dbus-1/dbus/dbus-uuidgen.h47
-rw-r--r--lib-x86-32/include/dbus-1/dbus/dbus-watch.h83
-rw-r--r--lib-x86-32/include/dbus-1/dbus/dbus.h103
-rw-r--r--lib-x86-32/include/dbus-1/dbus/sd-daemon.h257
-rw-r--r--lib-x86-32/include/faad.h35
-rw-r--r--lib-x86-32/include/libavcodec/avcodec.h3968
-rw-r--r--lib-x86-32/include/libavcodec/avfft.h99
-rw-r--r--lib-x86-32/include/libavcodec/dxva2.h68
-rw-r--r--lib-x86-32/include/libavcodec/opt.h211
-rw-r--r--lib-x86-32/include/libavcodec/vaapi.h167
-rw-r--r--lib-x86-32/include/libavcodec/vdpau.h89
-rw-r--r--lib-x86-32/include/libavcodec/xvmc.h172
-rw-r--r--lib-x86-32/include/libavformat/avformat.h1369
-rw-r--r--lib-x86-32/include/libavformat/avio.h525
-rw-r--r--lib-x86-32/include/libavutil/adler32.h30
-rw-r--r--lib-x86-32/include/libavutil/attributes.h113
-rw-r--r--lib-x86-32/include/libavutil/avconfig.h5
-rw-r--r--lib-x86-32/include/libavutil/avstring.h117
-rw-r--r--lib-x86-32/include/libavutil/avutil.h89
-rw-r--r--lib-x86-32/include/libavutil/base64.h49
-rw-r--r--lib-x86-32/include/libavutil/common.h308
-rw-r--r--lib-x86-32/include/libavutil/crc.h44
-rw-r--r--lib-x86-32/include/libavutil/error.h72
-rw-r--r--lib-x86-32/include/libavutil/fifo.h116
-rw-r--r--lib-x86-32/include/libavutil/intfloat_readwrite.h40
-rw-r--r--lib-x86-32/include/libavutil/log.h123
-rw-r--r--lib-x86-32/include/libavutil/lzo.h66
-rw-r--r--lib-x86-32/include/libavutil/mathematics.h98
-rw-r--r--lib-x86-32/include/libavutil/md5.h36
-rw-r--r--lib-x86-32/include/libavutil/mem.h125
-rw-r--r--lib-x86-32/include/libavutil/pixdesc.h154
-rw-r--r--lib-x86-32/include/libavutil/pixfmt.h163
-rw-r--r--lib-x86-32/include/libavutil/rational.h129
-rw-r--r--lib-x86-32/include/libavutil/sha1.h57
-rw-r--r--lib-x86-32/include/mad.h964
-rw-r--r--lib-x86-32/include/neaacdec.h258
-rw-r--r--lib-x86-32/include/ogg/Makefile.am6
-rw-r--r--lib-x86-32/include/ogg/config_types.h11
-rw-r--r--lib-x86-32/include/ogg/config_types.h.in11
-rw-r--r--lib-x86-32/include/ogg/ogg.h208
-rw-r--r--lib-x86-32/include/ogg/os_types.h148
-rw-r--r--lib-x86-32/include/samplerate.h197
-rw-r--r--lib-x86-32/include/sndfile.h665
-rw-r--r--lib-x86-32/include/vorbis/Makefile.am7
-rw-r--r--lib-x86-32/include/vorbis/codec.h243
-rw-r--r--lib-x86-32/include/vorbis/vorbisenc.h436
-rw-r--r--lib-x86-32/include/vorbis/vorbisfile.h206
-rw-r--r--lib-x86-32/include/wavpack.h302
-rw-r--r--lib-x86-32/include/zconf.h428
-rw-r--r--lib-x86-32/include/zlib.h1613
-rw-r--r--lib-x86-32/libFLAC.abin0 -> 1118698 bytes
-rw-r--r--lib-x86-32/libavcodec.abin0 -> 4589898 bytes
-rw-r--r--lib-x86-32/libavcore.abin0 -> 42146 bytes
-rw-r--r--lib-x86-32/libavformat.abin0 -> 1252606 bytes
-rw-r--r--lib-x86-32/libavutil.abin0 -> 407976 bytes
-rw-r--r--lib-x86-32/libcddb.abin0 -> 233246 bytes
-rw-r--r--lib-x86-32/libcdio.abin0 -> 717360 bytes
-rw-r--r--lib-x86-32/libcurl.abin0 -> 378006 bytes
-rw-r--r--lib-x86-32/libdbus-1.abin0 -> 1696224 bytes
-rw-r--r--lib-x86-32/libexpat.abin0 -> 469568 bytes
-rw-r--r--lib-x86-32/libfaad.abin0 -> 932958 bytes
-rw-r--r--lib-x86-32/libidn.abin0 -> 343434 bytes
-rw-r--r--lib-x86-32/libiso9660.abin0 -> 154358 bytes
-rw-r--r--lib-x86-32/libmad.abin0 -> 263700 bytes
-rw-r--r--lib-x86-32/libogg.abin0 -> 53912 bytes
-rw-r--r--lib-x86-32/libopencore-amrnb.abin0 -> 1157144 bytes
-rw-r--r--lib-x86-32/libopencore-amrwb.abin0 -> 397826 bytes
-rw-r--r--lib-x86-32/libsamplerate.abin0 -> 1550646 bytes
-rw-r--r--lib-x86-32/libsndfile.abin0 -> 2125266 bytes
-rw-r--r--lib-x86-32/libudf.abin0 -> 107594 bytes
-rw-r--r--lib-x86-32/libvorbis.abin0 -> 180710 bytes
-rw-r--r--lib-x86-32/libvorbisenc.abin0 -> 1625594 bytes
-rw-r--r--lib-x86-32/libvorbisfile.abin0 -> 30084 bytes
-rw-r--r--lib-x86-32/libwavpack.abin0 -> 498084 bytes
-rw-r--r--lib-x86-32/libz.abin0 -> 98474 bytes
-rw-r--r--main.c222
-rw-r--r--messagepump.c12
-rw-r--r--messagepump.h4
-rw-r--r--metacache.c2
-rw-r--r--metacache.h2
-rw-r--r--optmath.h2
-rw-r--r--playback.h34
-rw-r--r--playlist.c1091
-rw-r--r--playlist.h65
-rw-r--r--plmeta.c232
-rw-r--r--pltmeta.c211
-rw-r--r--pltmeta.h55
-rw-r--r--plugins.c676
-rw-r--r--plugins.h43
-rw-r--r--plugins/aac/aac.c382
-rw-r--r--plugins/aac/aac_parser.c4
-rw-r--r--plugins/aac/aac_parser.h2
-rw-r--r--plugins/adplug/Makefile.am8
-rw-r--r--plugins/adplug/adplug-db.cpp62
-rw-r--r--plugins/adplug/libbinio/binfile.cpp28
-rw-r--r--plugins/adplug/libbinio/binfile.h4
-rw-r--r--plugins/adplug/plugin.c35
-rw-r--r--plugins/alsa/alsa.c370
-rw-r--r--plugins/ao/Makefile32
-rw-r--r--plugins/ao/Makefile.am27
-rw-r--r--plugins/ao/eng_ssf/m68kcpu.c2
-rw-r--r--plugins/ao/plugin.c97
-rw-r--r--plugins/artwork/Makefile.am4
-rw-r--r--plugins/artwork/albumartorg.c2
-rw-r--r--plugins/artwork/albumartorg.h2
-rw-r--r--plugins/artwork/artwork.c464
-rw-r--r--plugins/artwork/artwork.h3
-rw-r--r--plugins/artwork/escape.h2
-rw-r--r--plugins/artwork/lastfm.c2
-rw-r--r--plugins/artwork/lastfm.h2
-rw-r--r--plugins/cdda/cdda.c101
-rw-r--r--plugins/converter/Makefile32
-rw-r--r--plugins/converter/callbacks.c11
-rw-r--r--plugins/converter/callbacks.h124
-rw-r--r--plugins/converter/converter.c906
-rw-r--r--plugins/converter/converter.glade1839
-rw-r--r--plugins/converter/converter.gladep11
-rw-r--r--plugins/converter/converter.h150
-rw-r--r--plugins/converter/convgui.c1301
-rw-r--r--plugins/converter/interface.c890
-rw-r--r--plugins/converter/interface.h9
-rw-r--r--plugins/converter/support.c144
-rw-r--r--plugins/converter/support.h69
-rw-r--r--plugins/dca/Makefile.am3
-rw-r--r--plugins/dca/convert2s16.c218
-rw-r--r--plugins/dca/dcaplug.c162
-rw-r--r--plugins/dsp_libsrc/Makefile.am12
-rw-r--r--plugins/dsp_libsrc/src.c286
-rw-r--r--plugins/dsp_libsrc/src.h28
-rw-r--r--plugins/dumb/Makefile (renamed from plugins/dumb/Makefile.am)53
-rw-r--r--plugins/dumb/cdumb.c176
-rw-r--r--plugins/dumb/dumb-kode54/src/it/loadmod.c4
-rw-r--r--plugins/dumb/dumb-kode54/src/it/loadmod2.c4
-rw-r--r--plugins/dumb/dumb-kode54/src/it/readmod.c8
-rw-r--r--plugins/dumb/dumb-kode54/src/it/readmod2.c4
-rw-r--r--plugins/ffap/ffap.c143
-rw-r--r--plugins/ffmpeg/ChangeLog5
-rw-r--r--plugins/ffmpeg/ffmpeg.c228
-rw-r--r--plugins/flac/flac.c400
-rw-r--r--plugins/gme/Makefile.am7
-rw-r--r--plugins/gme/cgme.c248
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Sap_Apu.cpp2
-rw-r--r--plugins/gtkui/Makefile.am49
-rw-r--r--plugins/gtkui/actions.c2
-rw-r--r--plugins/gtkui/actions.h2
-rw-r--r--plugins/gtkui/callbacks.c250
-rw-r--r--plugins/gtkui/callbacks.h166
-rw-r--r--plugins/gtkui/coverart.c72
-rw-r--r--plugins/gtkui/coverart.h2
-rw-r--r--plugins/gtkui/ddbcellrenderertextmultiline.c51
-rw-r--r--plugins/gtkui/ddbcellrenderertextmultiline.h2
-rw-r--r--plugins/gtkui/ddbcellrenderertextmultiline.vala14
-rw-r--r--plugins/gtkui/ddbequalizer.c2
-rw-r--r--plugins/gtkui/ddbequalizer.h2
-rw-r--r--plugins/gtkui/ddblistview.c293
-rw-r--r--plugins/gtkui/ddblistview.h6
-rw-r--r--plugins/gtkui/ddbseekbar.c4
-rw-r--r--plugins/gtkui/ddbseekbar.h2
-rw-r--r--plugins/gtkui/ddbtabstrip.c94
-rw-r--r--plugins/gtkui/ddbtabstrip.h2
-rw-r--r--plugins/gtkui/ddbvolumebar.c2
-rw-r--r--plugins/gtkui/ddbvolumebar.h2
-rw-r--r--plugins/gtkui/deadbeef.glade3249
-rw-r--r--plugins/gtkui/deadbeef.gladep1
-rw-r--r--plugins/gtkui/drawing.h8
-rw-r--r--plugins/gtkui/dspconfig.c482
-rw-r--r--plugins/gtkui/dspconfig.h29
-rw-r--r--plugins/gtkui/eq.c202
-rw-r--r--plugins/gtkui/eq.h6
-rw-r--r--plugins/gtkui/fileman.c51
-rw-r--r--plugins/gtkui/gdkdrawing.c52
-rw-r--r--plugins/gtkui/gtkui.c266
-rw-r--r--plugins/gtkui/gtkui.h24
-rw-r--r--plugins/gtkui/gtkui_api.h28
-rw-r--r--plugins/gtkui/interface.c1664
-rw-r--r--plugins/gtkui/interface.h7
-rw-r--r--plugins/gtkui/mainplaylist.c22
-rw-r--r--plugins/gtkui/mainplaylist.h2
-rw-r--r--plugins/gtkui/parser.c2
-rw-r--r--plugins/gtkui/parser.h2
-rw-r--r--plugins/gtkui/plcommon.c48
-rw-r--r--plugins/gtkui/plcommon.h2
-rw-r--r--plugins/gtkui/pluginconf.c360
-rw-r--r--plugins/gtkui/pluginconf.h28
-rw-r--r--plugins/gtkui/prefwin.c514
-rw-r--r--plugins/gtkui/progress.c46
-rw-r--r--plugins/gtkui/progress.h2
-rw-r--r--plugins/gtkui/search.c78
-rw-r--r--plugins/gtkui/search.h5
-rw-r--r--plugins/gtkui/support.h2
-rw-r--r--plugins/gtkui/tagwritersettings.c204
-rw-r--r--plugins/gtkui/tagwritersettings.h25
-rw-r--r--plugins/gtkui/timeline.c2
-rw-r--r--plugins/gtkui/timeline.h2
-rw-r--r--plugins/gtkui/trkproperties.c670
-rw-r--r--plugins/gtkui/trkproperties.h4
-rw-r--r--plugins/gtkui/wingeom.c101
-rw-r--r--plugins/gtkui/wingeom.h31
-rw-r--r--plugins/hotkeys/hotkeys.c51
-rw-r--r--plugins/hotkeys/hotkeys.h2
-rw-r--r--plugins/lastfm/lastfm.c48
-rw-r--r--plugins/m3u/Makefile.am11
-rw-r--r--plugins/m3u/m3u.c469
-rw-r--r--plugins/mms/mmsplug.c41
-rw-r--r--plugins/mpgmad/mpgmad.c534
-rw-r--r--plugins/musepack/Makefile.am2
-rw-r--r--plugins/musepack/mpc_decoder.c6
-rw-r--r--plugins/musepack/musepack.c190
-rw-r--r--plugins/notify/notify.c321
-rw-r--r--plugins/nullout/nullout.c73
-rw-r--r--plugins/oss/oss.c243
-rw-r--r--plugins/pulse/pulse.c231
-rw-r--r--plugins/shellexec/Makefile.am2
-rw-r--r--plugins/shellexec/shellexec.c25
-rw-r--r--plugins/shn/Makefile22
-rw-r--r--plugins/shn/Makefile.am10
-rw-r--r--plugins/shn/shn.c126
-rw-r--r--plugins/sid/Makefile.am6
-rw-r--r--plugins/sid/csid.cpp96
-rw-r--r--plugins/sid/csid.h4
-rw-r--r--plugins/sid/plugin.c39
-rw-r--r--plugins/sid/sidplay-libs/libsidplay/src/sidtune/SidTune.cpp13
-rw-r--r--plugins/sndfile/sndfile.c322
-rw-r--r--plugins/soundtouch/Makefile52
-rw-r--r--plugins/soundtouch/plugin.c308
-rw-r--r--plugins/soundtouch/soundtouch/COPYING.TXT458
-rw-r--r--plugins/soundtouch/soundtouch/README.html752
-rw-r--r--plugins/soundtouch/soundtouch/include/BPMDetect.h161
-rw-r--r--plugins/soundtouch/soundtouch/include/FIFOSampleBuffer.h174
-rw-r--r--plugins/soundtouch/soundtouch/include/FIFOSamplePipe.h221
-rw-r--r--plugins/soundtouch/soundtouch/include/STTypes.h149
-rw-r--r--plugins/soundtouch/soundtouch/include/SoundTouch.h252
-rw-r--r--plugins/soundtouch/soundtouch/include/soundtouch_config.h88
-rw-r--r--plugins/soundtouch/soundtouch/source/SoundTouch/3dnow_win.cpp349
-rw-r--r--plugins/soundtouch/soundtouch/source/SoundTouch/AAFilter.cpp184
-rw-r--r--plugins/soundtouch/soundtouch/source/SoundTouch/AAFilter.h91
-rw-r--r--plugins/soundtouch/soundtouch/source/SoundTouch/BPMDetect.cpp308
-rw-r--r--plugins/soundtouch/soundtouch/source/SoundTouch/FIFOSampleBuffer.cpp262
-rw-r--r--plugins/soundtouch/soundtouch/source/SoundTouch/FIRFilter.cpp269
-rw-r--r--plugins/soundtouch/soundtouch/source/SoundTouch/FIRFilter.h164
-rw-r--r--plugins/soundtouch/soundtouch/source/SoundTouch/PeakFinder.cpp239
-rw-r--r--plugins/soundtouch/soundtouch/source/SoundTouch/PeakFinder.h93
-rw-r--r--plugins/soundtouch/soundtouch/source/SoundTouch/RateTransposer.cpp628
-rw-r--r--plugins/soundtouch/soundtouch/source/SoundTouch/RateTransposer.h159
-rw-r--r--plugins/soundtouch/soundtouch/source/SoundTouch/SoundTouch.cpp480
-rw-r--r--plugins/soundtouch/soundtouch/source/SoundTouch/TDStretch.cpp1045
-rw-r--r--plugins/soundtouch/soundtouch/source/SoundTouch/TDStretch.h275
-rw-r--r--plugins/soundtouch/soundtouch/source/SoundTouch/cpu_detect.h62
-rw-r--r--plugins/soundtouch/soundtouch/source/SoundTouch/cpu_detect_x86_gcc.cpp135
-rw-r--r--plugins/soundtouch/soundtouch/source/SoundTouch/cpu_detect_x86_win.cpp129
-rw-r--r--plugins/soundtouch/soundtouch/source/SoundTouch/mmx_optimized.cpp320
-rw-r--r--plugins/soundtouch/soundtouch/source/SoundTouch/sse_optimized.cpp510
-rw-r--r--plugins/soundtouch/st.cpp112
-rw-r--r--plugins/soundtouch/st.h115
-rw-r--r--plugins/supereq/Equ.cpp602
-rw-r--r--plugins/supereq/Equ.h56
-rw-r--r--plugins/supereq/Fftsg_fl.cpp29
-rw-r--r--plugins/supereq/Makefile.am47
-rw-r--r--plugins/supereq/ff_rdft.c63
-rw-r--r--plugins/supereq/ffmpeg_fft/README9
-rw-r--r--plugins/supereq/ffmpeg_fft/config.h904
-rw-r--r--plugins/supereq/ffmpeg_fft/ffmpeg_fft.h95
-rw-r--r--plugins/supereq/ffmpeg_fft/libavcodec/arm/asm.S104
-rw-r--r--plugins/supereq/ffmpeg_fft/libavcodec/arm/fft_init_arm.c71
-rw-r--r--plugins/supereq/ffmpeg_fft/libavcodec/arm/fft_neon.S372
-rw-r--r--plugins/supereq/ffmpeg_fft/libavcodec/arm/rdft_neon.S151
-rw-r--r--plugins/supereq/ffmpeg_fft/libavcodec/arm/simple_idct_neon.S372
-rw-r--r--plugins/supereq/ffmpeg_fft/libavcodec/avfft.c142
-rw-r--r--plugins/supereq/ffmpeg_fft/libavcodec/avfft.h103
-rw-r--r--plugins/supereq/ffmpeg_fft/libavcodec/dct.c228
-rw-r--r--plugins/supereq/ffmpeg_fft/libavcodec/dct32.c262
-rw-r--r--plugins/supereq/ffmpeg_fft/libavcodec/dct32.h10
-rw-r--r--plugins/supereq/ffmpeg_fft/libavcodec/fft.c300
-rw-r--r--plugins/supereq/ffmpeg_fft/libavcodec/fft.h244
-rw-r--r--plugins/supereq/ffmpeg_fft/libavcodec/rdft.c137
-rw-r--r--plugins/supereq/ffmpeg_fft/libavutil/attributes.h122
-rw-r--r--plugins/supereq/ffmpeg_fft/libavutil/avconfig.h5
-rw-r--r--plugins/supereq/ffmpeg_fft/libavutil/avutil.h90
-rw-r--r--plugins/supereq/ffmpeg_fft/libavutil/common.h347
-rw-r--r--plugins/supereq/ffmpeg_fft/libavutil/intfloat_readwrite.c98
-rw-r--r--plugins/supereq/ffmpeg_fft/libavutil/intfloat_readwrite.h41
-rw-r--r--plugins/supereq/ffmpeg_fft/libavutil/mathematics.c181
-rw-r--r--plugins/supereq/ffmpeg_fft/libavutil/mathematics.h110
-rw-r--r--plugins/supereq/ffmpeg_fft/libavutil/mem.c176
-rw-r--r--plugins/supereq/ffmpeg_fft/libavutil/mem.h128
-rw-r--r--plugins/supereq/ffmpeg_fft/libavutil/rational.c131
-rw-r--r--plugins/supereq/ffmpeg_fft/libavutil/rational.h130
-rw-r--r--plugins/supereq/ffmpeg_fft/libffmpeg_fft.ver4
-rw-r--r--plugins/supereq/ffmpeg_fft/publik.h6
-rw-r--r--plugins/supereq/nsfft-1.00/README15
-rw-r--r--plugins/supereq/nsfft-1.00/dft/DFT.c327
-rw-r--r--plugins/supereq/nsfft-1.00/dft/DFT.h56
-rw-r--r--plugins/supereq/nsfft-1.00/dft/DFTUndiff.c1807
-rw-r--r--plugins/supereq/nsfft-1.00/dft/DFTUndiff.h114
l---------plugins/supereq/nsfft-1.00/dft/Makefile1
-rw-r--r--plugins/supereq/nsfft-1.00/dft/Makefile.altivec26
-rw-r--r--plugins/supereq/nsfft-1.00/dft/Makefile.neon26
-rw-r--r--plugins/supereq/nsfft-1.00/dft/Makefile.purec35
-rw-r--r--plugins/supereq/nsfft-1.00/dft/Makefile.x8629
-rw-r--r--plugins/supereq/nsfft-1.00/dft/Makefile.x86avx35
-rw-r--r--plugins/supereq/nsfft-1.00/dfttest/DFTExample.c88
-rw-r--r--plugins/supereq/nsfft-1.00/dfttest/DFTTestFFTW.c317
-rw-r--r--plugins/supereq/nsfft-1.00/dfttest/DFTTestNaive.c419
-rw-r--r--plugins/supereq/nsfft-1.00/dfttest/DFTTestOoura.c260
-rw-r--r--plugins/supereq/nsfft-1.00/dfttest/Makefile35
-rw-r--r--plugins/supereq/nsfft-1.00/dfttest/pi_fft.c.patch131
-rw-r--r--plugins/supereq/nsfft-1.00/doc/default.css34
-rw-r--r--plugins/supereq/nsfft-1.00/doc/index.xhtml2016
-rw-r--r--plugins/supereq/nsfft-1.00/doc/nsfft.pdfbin0 -> 78973 bytes
-rw-r--r--plugins/supereq/nsfft-1.00/ooura/Makefile11
-rw-r--r--plugins/supereq/nsfft-1.00/ooura/README2
-rw-r--r--plugins/supereq/nsfft-1.00/ooura/fftsg.c3314
-rw-r--r--plugins/supereq/nsfft-1.00/ooura/pi_fft.c1616
l---------plugins/supereq/nsfft-1.00/simd/Makefile1
-rw-r--r--plugins/supereq/nsfft-1.00/simd/Makefile.altivec26
-rw-r--r--plugins/supereq/nsfft-1.00/simd/Makefile.neon26
-rw-r--r--plugins/supereq/nsfft-1.00/simd/Makefile.purec35
-rw-r--r--plugins/supereq/nsfft-1.00/simd/Makefile.x8635
-rw-r--r--plugins/supereq/nsfft-1.00/simd/Makefile.x86avx35
-rw-r--r--plugins/supereq/nsfft-1.00/simd/SIMDBase.c454
-rw-r--r--plugins/supereq/nsfft-1.00/simd/SIMDBase.h53
-rw-r--r--plugins/supereq/nsfft-1.00/simd/SIMDBaseUndiff.c38
-rw-r--r--plugins/supereq/nsfft-1.00/simd/SIMDBaseUndiff.h231
-rw-r--r--plugins/supereq/paramlist.hpp31
-rw-r--r--plugins/supereq/shibatch_rdft.c71
-rw-r--r--plugins/supereq/supereq.c412
-rw-r--r--plugins/tta/filter.h4
-rw-r--r--plugins/tta/ttadec.c4
-rw-r--r--plugins/tta/ttaplug.c137
-rw-r--r--plugins/uade2/plugin.c692
-rw-r--r--plugins/uade2/uade-2.13/AUTHORS59
-rw-r--r--plugins/uade2/uade-2.13/COPYING12
-rw-r--r--plugins/uade2/uade-2.13/COPYING.GPL340
-rw-r--r--plugins/uade2/uade-2.13/COPYING.LGPL504
-rw-r--r--plugins/uade2/uade-2.13/ChangeLog1907
-rw-r--r--plugins/uade2/uade-2.13/README53
-rw-r--r--plugins/uade2/uade-2.13/src/frontends/common/amifilemagic.c1168
-rw-r--r--plugins/uade2/uade-2.13/src/frontends/common/amifilemagic.h9
-rw-r--r--plugins/uade2/uade-2.13/src/frontends/common/eagleplayer.c502
-rw-r--r--plugins/uade2/uade-2.13/src/frontends/common/eagleplayer.h127
-rw-r--r--plugins/uade2/uade-2.13/src/frontends/common/effects.c490
-rw-r--r--plugins/uade2/uade-2.13/src/frontends/common/effects.h42
-rw-r--r--plugins/uade2/uade-2.13/src/frontends/common/md5.c247
-rw-r--r--plugins/uade2/uade-2.13/src/frontends/common/md5.copyright8
-rw-r--r--plugins/uade2/uade-2.13/src/frontends/common/md5.h21
-rw-r--r--plugins/uade2/uade-2.13/src/frontends/common/songdb.c798
-rw-r--r--plugins/uade2/uade-2.13/src/frontends/common/songdb.h24
-rw-r--r--plugins/uade2/uade-2.13/src/frontends/common/songinfo.c721
-rw-r--r--plugins/uade2/uade-2.13/src/frontends/common/songinfo.h19
-rw-r--r--plugins/uade2/uade-2.13/src/frontends/common/support.c183
-rw-r--r--plugins/uade2/uade-2.13/src/frontends/common/support.h31
-rw-r--r--plugins/uade2/uade-2.13/src/frontends/common/uadeconf.c888
-rw-r--r--plugins/uade2/uade-2.13/src/frontends/common/uadeconf.h27
-rw-r--r--plugins/uade2/uade-2.13/src/frontends/common/uadeconfstructure.h139
-rw-r--r--plugins/uade2/uade-2.13/src/frontends/common/uadecontrol.c249
-rw-r--r--plugins/uade2/uade-2.13/src/frontends/common/uadecontrol.h24
-rw-r--r--plugins/uade2/uade-2.13/src/frontends/common/uadestate.h25
-rw-r--r--plugins/uade2/uade-2.13/src/frontends/common/unixwalkdir.c69
-rw-r--r--plugins/uade2/uade-2.13/src/frontends/common/unixwalkdir.h16
-rw-r--r--plugins/uade2/uade-2.13/src/frontends/common/vplist.c115
-rw-r--r--plugins/uade2/uade-2.13/src/frontends/common/vplist.h44
-rw-r--r--plugins/uade2/uade-2.13/src/include/.gitignore4
-rw-r--r--plugins/uade2/uade-2.13/src/include/amigafilter.h10
-rw-r--r--plugins/uade2/uade-2.13/src/include/amigamsg.h24
-rw-r--r--plugins/uade2/uade-2.13/src/include/audio.h57
-rw-r--r--plugins/uade2/uade-2.13/src/include/cia.h26
-rw-r--r--plugins/uade2/uade-2.13/src/include/commpipe.h155
-rw-r--r--plugins/uade2/uade-2.13/src/include/compiler.h111
-rw-r--r--plugins/uade2/uade-2.13/src/include/custom.h115
-rw-r--r--plugins/uade2/uade-2.13/src/include/debug.h25
-rw-r--r--plugins/uade2/uade-2.13/src/include/events.h83
-rw-r--r--plugins/uade2/uade-2.13/src/include/execlib.h40
-rw-r--r--plugins/uade2/uade-2.13/src/include/gensound.h19
-rw-r--r--plugins/uade2/uade-2.13/src/include/memory.h181
-rw-r--r--plugins/uade2/uade-2.13/src/include/newcpu.h275
-rw-r--r--plugins/uade2/uade-2.13/src/include/options.h262
-rw-r--r--plugins/uade2/uade-2.13/src/include/osemu.h19
-rw-r--r--plugins/uade2/uade-2.13/src/include/readcpu.h99
-rw-r--r--plugins/uade2/uade-2.13/src/include/sinctable.h7
-rw-r--r--plugins/uade2/uade-2.13/src/include/sysdeps.h347
-rw-r--r--plugins/uade2/uade-2.13/src/include/text_scope.h21
-rw-r--r--plugins/uade2/uade-2.13/src/include/uade.h43
-rw-r--r--plugins/uade2/uade-2.13/src/include/uadeconstants.h10
-rw-r--r--plugins/uade2/uade-2.13/src/include/uadeipc.h77
-rw-r--r--plugins/uade2/uade-2.13/src/include/uadeutils.h27
-rw-r--r--plugins/uade2/uade-2.13/src/include/uae.h30
-rw-r--r--plugins/uade2/uade-2.13/src/include/unixatomic.h15
-rw-r--r--plugins/uade2/uade-2.13/src/include/unixsupport.h32
-rw-r--r--plugins/uade2/uade-2.13/src/ossupport.c48
-rw-r--r--plugins/uade2/uade-2.13/src/uadeipc.c291
-rw-r--r--plugins/uade2/uade-2.13/src/unixatomic.c149
-rw-r--r--plugins/uade2/uade-2.13/src/unixsupport.c350
-rw-r--r--plugins/vfs_curl/Makefile.am2
-rw-r--r--plugins/vfs_curl/vfs_curl.c260
-rw-r--r--plugins/vfs_zip/Makefile.am9
-rw-r--r--plugins/vfs_zip/vfs_zip.c255
-rw-r--r--plugins/vorbis/vorbis.c230
-rw-r--r--plugins/vtx/vtx.c81
-rw-r--r--plugins/wavpack/COPYING26
-rw-r--r--plugins/wavpack/wavpack.c257
-rw-r--r--plugins/wildmidi/wildmidiplug.c58
-rw-r--r--po/LINGUAS7
-rw-r--r--po/be.po1457
-rw-r--r--premix.c438
-rw-r--r--premix.h27
-rw-r--r--replaygain.c237
-rw-r--r--replaygain.h48
-rw-r--r--ringbuf.c85
-rw-r--r--ringbuf.h40
-rwxr-xr-xscripts/configure_minimal.sh1
-rwxr-xr-xscripts/extract_translators.pl (renamed from extract_translators.pl)0
-rw-r--r--scripts/pluginstall.sh3
-rwxr-xr-xscripts/portable_build.sh17
-rwxr-xr-xscripts/portable_package.sh74
-rwxr-xr-xscripts/portable_package_partial.sh36
-rwxr-xr-xscripts/portable_postbuild.sh52
-rwxr-xr-xscripts/portable_upload.sh9
-rwxr-xr-xscripts/quickinstall.sh43
-rw-r--r--scripts/u8_casemap/UnicodeData.txt23697
-rw-r--r--scripts/u8_casemap/u8_casemap.pl49
-rwxr-xr-xscripts/u8_gperf.sh (renamed from u8_gperf.sh)0
-rw-r--r--shortlicense2
-rw-r--r--sj_to_unicode.h6881
-rw-r--r--streamer.c1368
-rw-r--r--streamer.h14
-rw-r--r--threading.h8
-rw-r--r--threading_pthread.c23
-rw-r--r--tools/apbuild/Apbuild/GCC.pm539
-rw-r--r--tools/apbuild/Apbuild/Utils.pm195
-rw-r--r--tools/apbuild/BINARY-PORTABILITY-NOTES36
-rw-r--r--tools/apbuild/ChangeLog375
-rw-r--r--tools/apbuild/Makefile55
-rw-r--r--tools/apbuild/README1
-rwxr-xr-xtools/apbuild/apg++10
-rwxr-xr-xtools/apbuild/apgcc1023
-rw-r--r--tools/apbuild/apsymbols.h275
-rwxr-xr-xtools/apbuild/buildlist48
-rw-r--r--tools/apbuild/ctype.h268
-rwxr-xr-xtools/apbuild/make-icons58
-rwxr-xr-xtools/apbuild/relaytool584
-rw-r--r--tools/apbuild/relaytool.m428
-rwxr-xr-xtools/apbuild/scandeps137
-rw-r--r--tools/apbuild/test-app/randomapp1.c16
-rw-r--r--tools/pluginfo/Makefile9
-rw-r--r--tools/pluginfo/pluginfo.c77
-rw-r--r--translators.txt21
-rw-r--r--u8_lc_map.h2720
-rw-r--r--u8_lc_map.txt981
-rw-r--r--utf8.c41
-rw-r--r--utf8.h8
-rw-r--r--vfs.c11
-rw-r--r--vfs.h2
-rw-r--r--vfs_stdio.c70
-rw-r--r--volume.c2
-rw-r--r--volume.h2
617 files changed, 147204 insertions, 7820 deletions
diff --git a/.gitignore b/.gitignore
index fa4d4231..c5d3a157 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,4 @@
*.o
-*.a
*.bak
*~
*.tar.gz
@@ -7,7 +6,11 @@
.exec
aclocal.m4
configure
-Makefile
+plugins/*/Makefile
+intl/Makefile
+icons/Makefile
+pixmaps/Makefile
+po/Makefile
Makefile.in
config.h
config.h.in
@@ -45,3 +48,5 @@ vala.stamp
POTFILES
stamp-it
po/Makevars.template
+*.so
+tools/pluginfo/pluginfo
diff --git a/ChangeLog b/ChangeLog
index 2eb9edf4..83cdab20 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+version 0.4.4
+ fixed race condition in streamer interaction with output plugins
+ atexit and sigterm handlers are not used anymore to prevent playlist corruption when X session is being killed
+ artwork plugin doesn't have direct libcurl dependency anymore
+ merged new translations from LXDE branch
+
version 0.4.3
fixed crash in OSS plugin
fixed random crashes caused by upgrading to libcurl-7.21.2
diff --git a/ConvertUTF/ConvertUTF.c b/ConvertUTF/ConvertUTF.c
new file mode 100644
index 00000000..9b3deebd
--- /dev/null
+++ b/ConvertUTF/ConvertUTF.c
@@ -0,0 +1,539 @@
+/*
+ * Copyright 2001-2004 Unicode, Inc.
+ *
+ * Disclaimer
+ *
+ * This source code is provided as is by Unicode, Inc. No claims are
+ * made as to fitness for any particular purpose. No warranties of any
+ * kind are expressed or implied. The recipient agrees to determine
+ * applicability of information provided. If this file has been
+ * purchased on magnetic or optical media from Unicode, Inc., the
+ * sole remedy for any claim will be exchange of defective media
+ * within 90 days of receipt.
+ *
+ * Limitations on Rights to Redistribute This Code
+ *
+ * Unicode, Inc. hereby grants the right to freely use the information
+ * supplied in this file in the creation of products supporting the
+ * Unicode Standard, and to make copies of this file in any form
+ * for internal or external distribution as long as this notice
+ * remains attached.
+ */
+
+/* ---------------------------------------------------------------------
+
+ Conversions between UTF32, UTF-16, and UTF-8. Source code file.
+ Author: Mark E. Davis, 1994.
+ Rev History: Rick McGowan, fixes & updates May 2001.
+ Sept 2001: fixed const & error conditions per
+ mods suggested by S. Parent & A. Lillich.
+ June 2002: Tim Dodd added detection and handling of incomplete
+ source sequences, enhanced error detection, added casts
+ to eliminate compiler warnings.
+ July 2003: slight mods to back out aggressive FFFE detection.
+ Jan 2004: updated switches in from-UTF8 conversions.
+ Oct 2004: updated to use UNI_MAX_LEGAL_UTF32 in UTF-32 conversions.
+
+ See the header file "ConvertUTF.h" for complete documentation.
+
+------------------------------------------------------------------------ */
+
+
+#include "ConvertUTF.h"
+#ifdef CVTUTF_DEBUG
+#include <stdio.h>
+#endif
+
+static const int halfShift = 10; /* used for shifting by 10 bits */
+
+static const UTF32 halfBase = 0x0010000UL;
+static const UTF32 halfMask = 0x3FFUL;
+
+#define UNI_SUR_HIGH_START (UTF32)0xD800
+#define UNI_SUR_HIGH_END (UTF32)0xDBFF
+#define UNI_SUR_LOW_START (UTF32)0xDC00
+#define UNI_SUR_LOW_END (UTF32)0xDFFF
+#define false 0
+#define true 1
+
+/* --------------------------------------------------------------------- */
+
+ConversionResult ConvertUTF32toUTF16 (
+ const UTF32** sourceStart, const UTF32* sourceEnd,
+ UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags) {
+ ConversionResult result = conversionOK;
+ const UTF32* source = *sourceStart;
+ UTF16* target = *targetStart;
+ while (source < sourceEnd) {
+ UTF32 ch;
+ if (target >= targetEnd) {
+ result = targetExhausted; break;
+ }
+ ch = *source++;
+ if (ch <= UNI_MAX_BMP) { /* Target is a character <= 0xFFFF */
+ /* UTF-16 surrogate values are illegal in UTF-32; 0xffff or 0xfffe are both reserved values */
+ if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {
+ if (flags == strictConversion) {
+ --source; /* return to the illegal value itself */
+ result = sourceIllegal;
+ break;
+ } else {
+ *target++ = UNI_REPLACEMENT_CHAR;
+ }
+ } else {
+ *target++ = (UTF16)ch; /* normal case */
+ }
+ } else if (ch > UNI_MAX_LEGAL_UTF32) {
+ if (flags == strictConversion) {
+ result = sourceIllegal;
+ } else {
+ *target++ = UNI_REPLACEMENT_CHAR;
+ }
+ } else {
+ /* target is a character in range 0xFFFF - 0x10FFFF. */
+ if (target + 1 >= targetEnd) {
+ --source; /* Back up source pointer! */
+ result = targetExhausted; break;
+ }
+ ch -= halfBase;
+ *target++ = (UTF16)((ch >> halfShift) + UNI_SUR_HIGH_START);
+ *target++ = (UTF16)((ch & halfMask) + UNI_SUR_LOW_START);
+ }
+ }
+ *sourceStart = source;
+ *targetStart = target;
+ return result;
+}
+
+/* --------------------------------------------------------------------- */
+
+ConversionResult ConvertUTF16toUTF32 (
+ const UTF16** sourceStart, const UTF16* sourceEnd,
+ UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags) {
+ ConversionResult result = conversionOK;
+ const UTF16* source = *sourceStart;
+ UTF32* target = *targetStart;
+ UTF32 ch, ch2;
+ while (source < sourceEnd) {
+ const UTF16* oldSource = source; /* In case we have to back up because of target overflow. */
+ ch = *source++;
+ /* If we have a surrogate pair, convert to UTF32 first. */
+ if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END) {
+ /* If the 16 bits following the high surrogate are in the source buffer... */
+ if (source < sourceEnd) {
+ ch2 = *source;
+ /* If it's a low surrogate, convert to UTF32. */
+ if (ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END) {
+ ch = ((ch - UNI_SUR_HIGH_START) << halfShift)
+ + (ch2 - UNI_SUR_LOW_START) + halfBase;
+ ++source;
+ } else if (flags == strictConversion) { /* it's an unpaired high surrogate */
+ --source; /* return to the illegal value itself */
+ result = sourceIllegal;
+ break;
+ }
+ } else { /* We don't have the 16 bits following the high surrogate. */
+ --source; /* return to the high surrogate */
+ result = sourceExhausted;
+ break;
+ }
+ } else if (flags == strictConversion) {
+ /* UTF-16 surrogate values are illegal in UTF-32 */
+ if (ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END) {
+ --source; /* return to the illegal value itself */
+ result = sourceIllegal;
+ break;
+ }
+ }
+ if (target >= targetEnd) {
+ source = oldSource; /* Back up source pointer! */
+ result = targetExhausted; break;
+ }
+ *target++ = ch;
+ }
+ *sourceStart = source;
+ *targetStart = target;
+#ifdef CVTUTF_DEBUG
+if (result == sourceIllegal) {
+ fprintf(stderr, "ConvertUTF16toUTF32 illegal seq 0x%04x,%04x\n", ch, ch2);
+ fflush(stderr);
+}
+#endif
+ return result;
+}
+
+/* --------------------------------------------------------------------- */
+
+/*
+ * Index into the table below with the first byte of a UTF-8 sequence to
+ * get the number of trailing bytes that are supposed to follow it.
+ * Note that *legal* UTF-8 values can't have 4 or 5-bytes. The table is
+ * left as-is for anyone who may want to do such conversion, which was
+ * allowed in earlier algorithms.
+ */
+static const char trailingBytesForUTF8[256] = {
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5
+};
+
+/*
+ * Magic values subtracted from a buffer value during UTF8 conversion.
+ * This table contains as many values as there might be trailing bytes
+ * in a UTF-8 sequence.
+ */
+static const UTF32 offsetsFromUTF8[6] = { 0x00000000UL, 0x00003080UL, 0x000E2080UL,
+ 0x03C82080UL, 0xFA082080UL, 0x82082080UL };
+
+/*
+ * Once the bits are split out into bytes of UTF-8, this is a mask OR-ed
+ * into the first byte, depending on how many bytes follow. There are
+ * as many entries in this table as there are UTF-8 sequence types.
+ * (I.e., one byte sequence, two byte... etc.). Remember that sequencs
+ * for *legal* UTF-8 will be 4 or fewer bytes total.
+ */
+static const UTF8 firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
+
+/* --------------------------------------------------------------------- */
+
+/* The interface converts a whole buffer to avoid function-call overhead.
+ * Constants have been gathered. Loops & conditionals have been removed as
+ * much as possible for efficiency, in favor of drop-through switches.
+ * (See "Note A" at the bottom of the file for equivalent code.)
+ * If your compiler supports it, the "isLegalUTF8" call can be turned
+ * into an inline function.
+ */
+
+/* --------------------------------------------------------------------- */
+
+ConversionResult ConvertUTF16toUTF8 (
+ const UTF16** sourceStart, const UTF16* sourceEnd,
+ UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags) {
+ ConversionResult result = conversionOK;
+ const UTF16* source = *sourceStart;
+ UTF8* target = *targetStart;
+ while (source < sourceEnd) {
+ UTF32 ch;
+ unsigned short bytesToWrite = 0;
+ const UTF32 byteMask = 0xBF;
+ const UTF32 byteMark = 0x80;
+ const UTF16* oldSource = source; /* In case we have to back up because of target overflow. */
+ ch = *source++;
+ /* If we have a surrogate pair, convert to UTF32 first. */
+ if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END) {
+ /* If the 16 bits following the high surrogate are in the source buffer... */
+ if (source < sourceEnd) {
+ UTF32 ch2 = *source;
+ /* If it's a low surrogate, convert to UTF32. */
+ if (ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END) {
+ ch = ((ch - UNI_SUR_HIGH_START) << halfShift)
+ + (ch2 - UNI_SUR_LOW_START) + halfBase;
+ ++source;
+ } else if (flags == strictConversion) { /* it's an unpaired high surrogate */
+ --source; /* return to the illegal value itself */
+ result = sourceIllegal;
+ break;
+ }
+ } else { /* We don't have the 16 bits following the high surrogate. */
+ --source; /* return to the high surrogate */
+ result = sourceExhausted;
+ break;
+ }
+ } else if (flags == strictConversion) {
+ /* UTF-16 surrogate values are illegal in UTF-32 */
+ if (ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END) {
+ --source; /* return to the illegal value itself */
+ result = sourceIllegal;
+ break;
+ }
+ }
+ /* Figure out how many bytes the result will require */
+ if (ch < (UTF32)0x80) { bytesToWrite = 1;
+ } else if (ch < (UTF32)0x800) { bytesToWrite = 2;
+ } else if (ch < (UTF32)0x10000) { bytesToWrite = 3;
+ } else if (ch < (UTF32)0x110000) { bytesToWrite = 4;
+ } else { bytesToWrite = 3;
+ ch = UNI_REPLACEMENT_CHAR;
+ }
+
+ target += bytesToWrite;
+ if (target > targetEnd) {
+ source = oldSource; /* Back up source pointer! */
+ target -= bytesToWrite; result = targetExhausted; break;
+ }
+ switch (bytesToWrite) { /* note: everything falls through. */
+ case 4: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
+ case 3: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
+ case 2: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
+ case 1: *--target = (UTF8)(ch | firstByteMark[bytesToWrite]);
+ }
+ target += bytesToWrite;
+ }
+ *sourceStart = source;
+ *targetStart = target;
+ return result;
+}
+
+/* --------------------------------------------------------------------- */
+
+/*
+ * Utility routine to tell whether a sequence of bytes is legal UTF-8.
+ * This must be called with the length pre-determined by the first byte.
+ * If not calling this from ConvertUTF8to*, then the length can be set by:
+ * length = trailingBytesForUTF8[*source]+1;
+ * and the sequence is illegal right away if there aren't that many bytes
+ * available.
+ * If presented with a length > 4, this returns false. The Unicode
+ * definition of UTF-8 goes up to 4-byte sequences.
+ */
+
+static Boolean isLegalUTF8(const UTF8 *source, int length) {
+ UTF8 a;
+ const UTF8 *srcptr = source+length;
+ switch (length) {
+ default: return false;
+ /* Everything else falls through when "true"... */
+ case 4: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false;
+ case 3: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false;
+ case 2: if ((a = (*--srcptr)) > 0xBF) return false;
+
+ switch (*source) {
+ /* no fall-through in this inner switch */
+ case 0xE0: if (a < 0xA0) return false; break;
+ case 0xED: if (a > 0x9F) return false; break;
+ case 0xF0: if (a < 0x90) return false; break;
+ case 0xF4: if (a > 0x8F) return false; break;
+ default: if (a < 0x80) return false;
+ }
+
+ case 1: if (*source >= 0x80 && *source < 0xC2) return false;
+ }
+ if (*source > 0xF4) return false;
+ return true;
+}
+
+/* --------------------------------------------------------------------- */
+
+/*
+ * Exported function to return whether a UTF-8 sequence is legal or not.
+ * This is not used here; it's just exported.
+ */
+Boolean isLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd) {
+ int length = trailingBytesForUTF8[*source]+1;
+ if (source+length > sourceEnd) {
+ return false;
+ }
+ return isLegalUTF8(source, length);
+}
+
+/* --------------------------------------------------------------------- */
+
+ConversionResult ConvertUTF8toUTF16 (
+ const UTF8** sourceStart, const UTF8* sourceEnd,
+ UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags) {
+ ConversionResult result = conversionOK;
+ const UTF8* source = *sourceStart;
+ UTF16* target = *targetStart;
+ while (source < sourceEnd) {
+ UTF32 ch = 0;
+ unsigned short extraBytesToRead = trailingBytesForUTF8[*source];
+ if (source + extraBytesToRead >= sourceEnd) {
+ result = sourceExhausted; break;
+ }
+ /* Do this check whether lenient or strict */
+ if (! isLegalUTF8(source, extraBytesToRead+1)) {
+ result = sourceIllegal;
+ break;
+ }
+ /*
+ * The cases all fall through. See "Note A" below.
+ */
+ switch (extraBytesToRead) {
+ case 5: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */
+ case 4: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */
+ case 3: ch += *source++; ch <<= 6;
+ case 2: ch += *source++; ch <<= 6;
+ case 1: ch += *source++; ch <<= 6;
+ case 0: ch += *source++;
+ }
+ ch -= offsetsFromUTF8[extraBytesToRead];
+
+ if (target >= targetEnd) {
+ source -= (extraBytesToRead+1); /* Back up source pointer! */
+ result = targetExhausted; break;
+ }
+ if (ch <= UNI_MAX_BMP) { /* Target is a character <= 0xFFFF */
+ /* UTF-16 surrogate values are illegal in UTF-32 */
+ if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {
+ if (flags == strictConversion) {
+ source -= (extraBytesToRead+1); /* return to the illegal value itself */
+ result = sourceIllegal;
+ break;
+ } else {
+ *target++ = UNI_REPLACEMENT_CHAR;
+ }
+ } else {
+ *target++ = (UTF16)ch; /* normal case */
+ }
+ } else if (ch > UNI_MAX_UTF16) {
+ if (flags == strictConversion) {
+ result = sourceIllegal;
+ source -= (extraBytesToRead+1); /* return to the start */
+ break; /* Bail out; shouldn't continue */
+ } else {
+ *target++ = UNI_REPLACEMENT_CHAR;
+ }
+ } else {
+ /* target is a character in range 0xFFFF - 0x10FFFF. */
+ if (target + 1 >= targetEnd) {
+ source -= (extraBytesToRead+1); /* Back up source pointer! */
+ result = targetExhausted; break;
+ }
+ ch -= halfBase;
+ *target++ = (UTF16)((ch >> halfShift) + UNI_SUR_HIGH_START);
+ *target++ = (UTF16)((ch & halfMask) + UNI_SUR_LOW_START);
+ }
+ }
+ *sourceStart = source;
+ *targetStart = target;
+ return result;
+}
+
+/* --------------------------------------------------------------------- */
+
+ConversionResult ConvertUTF32toUTF8 (
+ const UTF32** sourceStart, const UTF32* sourceEnd,
+ UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags) {
+ ConversionResult result = conversionOK;
+ const UTF32* source = *sourceStart;
+ UTF8* target = *targetStart;
+ while (source < sourceEnd) {
+ UTF32 ch;
+ unsigned short bytesToWrite = 0;
+ const UTF32 byteMask = 0xBF;
+ const UTF32 byteMark = 0x80;
+ ch = *source++;
+ if (flags == strictConversion ) {
+ /* UTF-16 surrogate values are illegal in UTF-32 */
+ if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {
+ --source; /* return to the illegal value itself */
+ result = sourceIllegal;
+ break;
+ }
+ }
+ /*
+ * Figure out how many bytes the result will require. Turn any
+ * illegally large UTF32 things (> Plane 17) into replacement chars.
+ */
+ if (ch < (UTF32)0x80) { bytesToWrite = 1;
+ } else if (ch < (UTF32)0x800) { bytesToWrite = 2;
+ } else if (ch < (UTF32)0x10000) { bytesToWrite = 3;
+ } else if (ch <= UNI_MAX_LEGAL_UTF32) { bytesToWrite = 4;
+ } else { bytesToWrite = 3;
+ ch = UNI_REPLACEMENT_CHAR;
+ result = sourceIllegal;
+ }
+
+ target += bytesToWrite;
+ if (target > targetEnd) {
+ --source; /* Back up source pointer! */
+ target -= bytesToWrite; result = targetExhausted; break;
+ }
+ switch (bytesToWrite) { /* note: everything falls through. */
+ case 4: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
+ case 3: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
+ case 2: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
+ case 1: *--target = (UTF8) (ch | firstByteMark[bytesToWrite]);
+ }
+ target += bytesToWrite;
+ }
+ *sourceStart = source;
+ *targetStart = target;
+ return result;
+}
+
+/* --------------------------------------------------------------------- */
+
+ConversionResult ConvertUTF8toUTF32 (
+ const UTF8** sourceStart, const UTF8* sourceEnd,
+ UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags) {
+ ConversionResult result = conversionOK;
+ const UTF8* source = *sourceStart;
+ UTF32* target = *targetStart;
+ while (source < sourceEnd) {
+ UTF32 ch = 0;
+ unsigned short extraBytesToRead = trailingBytesForUTF8[*source];
+ if (source + extraBytesToRead >= sourceEnd) {
+ result = sourceExhausted; break;
+ }
+ /* Do this check whether lenient or strict */
+ if (! isLegalUTF8(source, extraBytesToRead+1)) {
+ result = sourceIllegal;
+ break;
+ }
+ /*
+ * The cases all fall through. See "Note A" below.
+ */
+ switch (extraBytesToRead) {
+ case 5: ch += *source++; ch <<= 6;
+ case 4: ch += *source++; ch <<= 6;
+ case 3: ch += *source++; ch <<= 6;
+ case 2: ch += *source++; ch <<= 6;
+ case 1: ch += *source++; ch <<= 6;
+ case 0: ch += *source++;
+ }
+ ch -= offsetsFromUTF8[extraBytesToRead];
+
+ if (target >= targetEnd) {
+ source -= (extraBytesToRead+1); /* Back up the source pointer! */
+ result = targetExhausted; break;
+ }
+ if (ch <= UNI_MAX_LEGAL_UTF32) {
+ /*
+ * UTF-16 surrogate values are illegal in UTF-32, and anything
+ * over Plane 17 (> 0x10FFFF) is illegal.
+ */
+ if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {
+ if (flags == strictConversion) {
+ source -= (extraBytesToRead+1); /* return to the illegal value itself */
+ result = sourceIllegal;
+ break;
+ } else {
+ *target++ = UNI_REPLACEMENT_CHAR;
+ }
+ } else {
+ *target++ = ch;
+ }
+ } else { /* i.e., ch > UNI_MAX_LEGAL_UTF32 */
+ result = sourceIllegal;
+ *target++ = UNI_REPLACEMENT_CHAR;
+ }
+ }
+ *sourceStart = source;
+ *targetStart = target;
+ return result;
+}
+
+/* ---------------------------------------------------------------------
+
+ Note A.
+ The fall-through switches in UTF-8 reading code save a
+ temp variable, some decrements & conditionals. The switches
+ are equivalent to the following loop:
+ {
+ int tmpBytesToRead = extraBytesToRead+1;
+ do {
+ ch += *source++;
+ --tmpBytesToRead;
+ if (tmpBytesToRead) ch <<= 6;
+ } while (tmpBytesToRead > 0);
+ }
+ In UTF-8 writing code, the switches on "bytesToWrite" are
+ similarly unrolled loops.
+
+ --------------------------------------------------------------------- */
diff --git a/ConvertUTF/ConvertUTF.h b/ConvertUTF/ConvertUTF.h
new file mode 100644
index 00000000..e2649153
--- /dev/null
+++ b/ConvertUTF/ConvertUTF.h
@@ -0,0 +1,149 @@
+/*
+ * Copyright 2001-2004 Unicode, Inc.
+ *
+ * Disclaimer
+ *
+ * This source code is provided as is by Unicode, Inc. No claims are
+ * made as to fitness for any particular purpose. No warranties of any
+ * kind are expressed or implied. The recipient agrees to determine
+ * applicability of information provided. If this file has been
+ * purchased on magnetic or optical media from Unicode, Inc., the
+ * sole remedy for any claim will be exchange of defective media
+ * within 90 days of receipt.
+ *
+ * Limitations on Rights to Redistribute This Code
+ *
+ * Unicode, Inc. hereby grants the right to freely use the information
+ * supplied in this file in the creation of products supporting the
+ * Unicode Standard, and to make copies of this file in any form
+ * for internal or external distribution as long as this notice
+ * remains attached.
+ */
+
+/* ---------------------------------------------------------------------
+
+ Conversions between UTF32, UTF-16, and UTF-8. Header file.
+
+ Several funtions are included here, forming a complete set of
+ conversions between the three formats. UTF-7 is not included
+ here, but is handled in a separate source file.
+
+ Each of these routines takes pointers to input buffers and output
+ buffers. The input buffers are const.
+
+ Each routine converts the text between *sourceStart and sourceEnd,
+ putting the result into the buffer between *targetStart and
+ targetEnd. Note: the end pointers are *after* the last item: e.g.
+ *(sourceEnd - 1) is the last item.
+
+ The return result indicates whether the conversion was successful,
+ and if not, whether the problem was in the source or target buffers.
+ (Only the first encountered problem is indicated.)
+
+ After the conversion, *sourceStart and *targetStart are both
+ updated to point to the end of last text successfully converted in
+ the respective buffers.
+
+ Input parameters:
+ sourceStart - pointer to a pointer to the source buffer.
+ The contents of this are modified on return so that
+ it points at the next thing to be converted.
+ targetStart - similarly, pointer to pointer to the target buffer.
+ sourceEnd, targetEnd - respectively pointers to the ends of the
+ two buffers, for overflow checking only.
+
+ These conversion functions take a ConversionFlags argument. When this
+ flag is set to strict, both irregular sequences and isolated surrogates
+ will cause an error. When the flag is set to lenient, both irregular
+ sequences and isolated surrogates are converted.
+
+ Whether the flag is strict or lenient, all illegal sequences will cause
+ an error return. This includes sequences such as: <F4 90 80 80>, <C0 80>,
+ or <A0> in UTF-8, and values above 0x10FFFF in UTF-32. Conformant code
+ must check for illegal sequences.
+
+ When the flag is set to lenient, characters over 0x10FFFF are converted
+ to the replacement character; otherwise (when the flag is set to strict)
+ they constitute an error.
+
+ Output parameters:
+ The value "sourceIllegal" is returned from some routines if the input
+ sequence is malformed. When "sourceIllegal" is returned, the source
+ value will point to the illegal value that caused the problem. E.g.,
+ in UTF-8 when a sequence is malformed, it points to the start of the
+ malformed sequence.
+
+ Author: Mark E. Davis, 1994.
+ Rev History: Rick McGowan, fixes & updates May 2001.
+ Fixes & updates, Sept 2001.
+
+------------------------------------------------------------------------ */
+
+/* ---------------------------------------------------------------------
+ The following 4 definitions are compiler-specific.
+ The C standard does not guarantee that wchar_t has at least
+ 16 bits, so wchar_t is no less portable than unsigned short!
+ All should be unsigned values to avoid sign extension during
+ bit mask & shift operations.
+------------------------------------------------------------------------ */
+
+typedef unsigned long UTF32; /* at least 32 bits */
+typedef unsigned short UTF16; /* at least 16 bits */
+typedef unsigned char UTF8; /* typically 8 bits */
+typedef unsigned char Boolean; /* 0 or 1 */
+
+/* Some fundamental constants */
+#define UNI_REPLACEMENT_CHAR (UTF32)0x0000FFFD
+#define UNI_MAX_BMP (UTF32)0x0000FFFF
+#define UNI_MAX_UTF16 (UTF32)0x0010FFFF
+#define UNI_MAX_UTF32 (UTF32)0x7FFFFFFF
+#define UNI_MAX_LEGAL_UTF32 (UTF32)0x0010FFFF
+
+typedef enum {
+ conversionOK, /* conversion successful */
+ sourceExhausted, /* partial character in source, but hit end */
+ targetExhausted, /* insuff. room in target for conversion */
+ sourceIllegal /* source sequence is illegal/malformed */
+} ConversionResult;
+
+typedef enum {
+ strictConversion = 0,
+ lenientConversion
+} ConversionFlags;
+
+/* This is for C++ and does no harm in C */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ConversionResult ConvertUTF8toUTF16 (
+ const UTF8** sourceStart, const UTF8* sourceEnd,
+ UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags);
+
+ConversionResult ConvertUTF16toUTF8 (
+ const UTF16** sourceStart, const UTF16* sourceEnd,
+ UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags);
+
+ConversionResult ConvertUTF8toUTF32 (
+ const UTF8** sourceStart, const UTF8* sourceEnd,
+ UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags);
+
+ConversionResult ConvertUTF32toUTF8 (
+ const UTF32** sourceStart, const UTF32* sourceEnd,
+ UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags);
+
+ConversionResult ConvertUTF16toUTF32 (
+ const UTF16** sourceStart, const UTF16* sourceEnd,
+ UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags);
+
+ConversionResult ConvertUTF32toUTF16 (
+ const UTF32** sourceStart, const UTF32* sourceEnd,
+ UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags);
+
+Boolean isLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd);
+
+#ifdef __cplusplus
+}
+#endif
+
+/* --------------------------------------------------------------------- */
diff --git a/ConvertUTF/readme.txt b/ConvertUTF/readme.txt
new file mode 100644
index 00000000..b9f17fb8
--- /dev/null
+++ b/ConvertUTF/readme.txt
@@ -0,0 +1,43 @@
+
+The accompanying C source code file "ConvertUTF.c" and the associated header
+file "ConvertUTF.h" provide for conversion between various transformation
+formats of Unicode characters. The following conversions are supported:
+
+ UTF-32 to UTF-16
+ UTF-32 to UTF-8
+ UTF-16 to UTF-32
+ UTF-16 to UTF-8
+ UTF-8 to UTF-16
+ UTF-8 to UTF-32
+
+In addition, there is a test harness which runs various tests.
+
+The files "CVTUTF7.C" and "CVTUTF7.H" are for archival and historical purposes
+only. They have not been updated to Unicode 3.0 or later and should be
+considered obsolescent. "CVTUTF7.C" contains two functions that can convert
+between UCS2 (i.e., the BMP characters only) and UTF-7. Surrogates are
+not supported, the code has not been tested, and should be considered
+unsuitable for general purpose use.
+
+Please submit any bug reports about these programs here:
+
+ http://www.unicode.org/unicode/reporting.html
+
+Version 1.0: initial version.
+
+Version 1.1: corrected some minor problems; added stricter checks.
+
+Version 1.2: corrected switch statements associated with "extraBytesToRead"
+ in 4 & 5 byte cases, in functions for conversion from UTF8.
+ Note: formally, the 4 & 5 byte cases are illegal in the latest
+ UTF8, but the table and this code has always catered for those,
+ cases since at one time they were legal.
+
+Version 1.3: Updated UTF-8 legality check;
+ updated to use UNI_MAX_LEGAL_UTF32 in UTF-32 conversions
+ Updated UTF-8 legality tests in harness.c
+
+
+Last update: October 19, 2004
+
+
diff --git a/Makefile.am b/Makefile.am
index eb1eb738..056b4a9d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -20,23 +20,27 @@ deadbeef_SOURCES =\
main.c common.h deadbeef.h\
plugins.c plugins.h moduleconf.h\
playlist.c playlist.h \
+ plmeta.c pltmeta.c pltmeta.h\
streamer.c streamer.h\
+ premix.c premix.h\
messagepump.c messagepump.h\
conf.c conf.h\
- playback.h\
threading_pthread.c threading.h\
volume.c volume.h\
- junklib.h junklib.c utf8.c utf8.h u8_lc_map.h\
+ junklib.h junklib.c utf8.c utf8.h u8_lc_map.h ConvertUTF/ConvertUTF.c ConvertUTF/ConvertUTF.h\
optmath.h\
vfs.c vfs.h vfs_stdio.c\
md5/md5.c md5/md5.h\
metacache.c metacache.h\
- gettext.h
+ gettext.h\
+ ringbuf.c ringbuf.h\
+ dsppreset.c dsppreset.h\
+ replaygain.c replaygain.h
sdkdir = $(pkgincludedir)
sdk_HEADERS = deadbeef.h
-deadbeef_LDADD = $(LDADD) $(DEPS_LIBS) $(ICONV_LIB) -lm
+deadbeef_LDADD = $(LDADD) $(DEPS_LIBS) $(ICONV_LIB) -lm -ldl -lpthread
AM_CFLAGS = $(DEPS_CFLAGS) -std=c99
AM_CPPFLAGS = $(DEPS_CFLAGS)
@@ -51,6 +55,6 @@ docs_DATA = README help.txt about.txt translators.txt ChangeLog\
desktopdir = $(datadir)/applications
desktop_DATA = deadbeef.desktop
-EXTRA_DIST = $(docs_DATA) $(desktop_DATA) $(INTLTOOL_FILES) translation/extra.c
+EXTRA_DIST = $(docs_DATA) $(desktop_DATA) $(INTLTOOL_FILES) translation/extra.c sj_to_unicode.h
ACLOCAL_AMFLAGS = -I m4
diff --git a/PKGBUILD b/PKGBUILD
index 69793ebd..d8ec9022 100644
--- a/PKGBUILD
+++ b/PKGBUILD
@@ -1,7 +1,7 @@
# Maintainer: Alexey Yakovenko <waker@users.sourceforge.net>
pkgname=deadbeef
-pkgver=0.4.3
+pkgver=0.4.4
pkgrel=1
pkgdesc="mp3/ogg/flac/ape/sid/mod/nsf/m4a/mpc/shn music player based on GTK2"
arch=(i686 x86_64)
@@ -12,7 +12,8 @@ depends=('gtk2' 'libsamplerate' 'alsa-lib')
optdepends=('libvorbis: ogg vorbis playback', 'libmad: mp1/2/3 playback', 'flac: flac playback', 'curl: lastfm scrobbler, shoutcast, icecast, podcast support', 'wavpack: wv playback', 'libsndfile: wav playback', "libcdio: audio cd plugin", "libcddb: audio cd plugin", "ffmpeg: for wma, aa3, oma, ac3, etc", "libmms: required for MMS protocol support", "faad2: required for AAC/MP4 support", "dbus: required for OSD notifications support", "pulseaudio: required for PulseAudio output plugin", "libx11: required for global hotkeys plugin", )
install=deadbeef.install
source=(http://downloads.sourceforge.net/project/$pkgname/$pkgname-$pkgver.tar.bz2)
-md5sums=('a3c9b9347de7114fe4bf939592fd570f')
+md5sums=('546e63d456d6a5625461019b15501e38')
+
options=('!libtool')
build() {
diff --git a/PORTABLE_BUILD b/PORTABLE_BUILD
new file mode 100644
index 00000000..0cfbf088
--- /dev/null
+++ b/PORTABLE_BUILD
@@ -0,0 +1 @@
+2
diff --git a/PORTABLE_VERSION b/PORTABLE_VERSION
new file mode 100644
index 00000000..d64531f1
--- /dev/null
+++ b/PORTABLE_VERSION
@@ -0,0 +1 @@
+devel
diff --git a/about.txt b/about.txt
index ea4be910..68fbb3c5 100644
--- a/about.txt
+++ b/about.txt
@@ -1,5 +1,5 @@
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
-Copyright © 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+Copyright © 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
http://deadbeef.sf.net
This program is free software; you can redistribute it and/or
@@ -80,7 +80,7 @@ Copyright © Simon White and other authors.
ffap - monkey's audio decoder based on code from ffmpeg and rockbox
-Copyright © 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+Copyright © 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
Copyright © 2007 Benjamin Zores <ben@geexbox.org>
Copyright © 2007 Dave Chapman
diff --git a/common.h b/common.h
index dfecb27a..6b5fc743 100644
--- a/common.h
+++ b/common.h
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -18,12 +18,21 @@
#ifndef __COMMON_H
#define __COMMON_H
+#include <limits.h>
+#ifndef PATH_MAX
+#define PATH_MAX 1024 /* max # of characters in a path name */
+#endif
+
#define min(x,y) ((x)<(y)?(x):(y))
#define max(x,y) ((x)>(y)?(x):(y))
// those are defined in main.c
-extern char confdir[1024]; // $HOME/.config
-extern char dbconfdir[1024]; // $HOME/.config/deadbeef
-extern char sessfile[1024]; // $HOME/.config/deadbeef/session
+extern char confdir[PATH_MAX]; // $HOME/.config
+extern char dbconfdir[PATH_MAX]; // $HOME/.config/deadbeef
+extern char dbinstalldir[PATH_MAX]; // see deadbeef->get_prefix
+extern char dbdocdir[PATH_MAX]; // see deadbeef->get_doc_dir
+extern char dbplugindir[PATH_MAX]; // see deadbeef->get_plugin_dir
+extern char dbpixmapdir[PATH_MAX]; // see deadbeef->get_pixmap_dir
+
#endif // __COMMON_H
diff --git a/conf.c b/conf.c
index b86e0836..887ad053 100644
--- a/conf.c
+++ b/conf.c
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -19,10 +19,41 @@
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
+#include <inttypes.h>
#include "conf.h"
+#include "threading.h"
+
+#define min(x,y) ((x)<(y)?(x):(y))
static DB_conf_item_t *conf_items;
static int changed = 0;
+static uintptr_t mutex;
+
+void
+conf_init (void) {
+ mutex = mutex_create ();
+}
+
+void
+conf_lock (void) {
+ mutex_lock (mutex);
+}
+
+void
+conf_unlock (void) {
+ mutex_unlock (mutex);
+}
+
+void
+conf_free (void) {
+ mutex_lock (mutex);
+ DB_conf_item_t *next = NULL;
+ for (DB_conf_item_t *it = conf_items; it; it = next) {
+ next = it->next;
+ conf_item_free (it);
+ }
+ mutex_free (mutex);
+}
int
conf_load (void) {
@@ -34,6 +65,7 @@ conf_load (void) {
fprintf (stderr, "failed to load config file\n");
return -1;
}
+ conf_lock ();
int line = 0;
while (fgets (str, 1024, fp) != NULL) {
line++;
@@ -69,6 +101,7 @@ conf_load (void) {
}
fclose (fp);
changed = 0;
+ conf_unlock ();
return 0;
}
@@ -82,24 +115,18 @@ conf_save (void) {
fprintf (stderr, "failed to open config file for writing\n");
return -1;
}
+ conf_lock ();
for (DB_conf_item_t *it = conf_items; it; it = it->next) {
fprintf (fp, "%s %s\n", it->key, it->value);
}
fclose (fp);
+ conf_unlock ();
return 0;
}
void
-conf_free (void) {
- DB_conf_item_t *next = NULL;
- for (DB_conf_item_t *it = conf_items; it; it = next) {
- next = it->next;
- conf_item_free (it);
- }
-}
-
-void
conf_item_free (DB_conf_item_t *it) {
+ conf_lock ();
if (it) {
if (it->key) {
free (it->key);
@@ -109,10 +136,11 @@ conf_item_free (DB_conf_item_t *it) {
}
free (it);
}
+ conf_unlock ();
}
const char *
-conf_get_str (const char *key, const char *def) {
+conf_get_str_fast (const char *key, const char *def) {
for (DB_conf_item_t *it = conf_items; it; it = it->next) {
if (!strcasecmp (key, it->key)) {
return it->value;
@@ -121,18 +149,46 @@ conf_get_str (const char *key, const char *def) {
return def;
}
+void
+conf_get_str (const char *key, const char *def, char *buffer, int buffer_size) {
+ conf_lock ();
+ const char *out = conf_get_str_fast (key, def);
+ if (out) {
+ int n = strlen (out)+1;
+ n = min (n, buffer_size);
+ memcpy (buffer, out, n);
+ buffer[buffer_size-1] = 0;
+ }
+ else {
+ *buffer = 0;
+ }
+ conf_unlock ();
+}
+
float
conf_get_float (const char *key, float def) {
- const char *v = conf_get_str (key, NULL);
+ conf_lock ();
+ const char *v = conf_get_str_fast (key, NULL);
+ conf_unlock ();
return v ? atof (v) : def;
}
int
conf_get_int (const char *key, int def) {
- const char *v = conf_get_str (key, NULL);
+ conf_lock ();
+ const char *v = conf_get_str_fast (key, NULL);
+ conf_unlock ();
return v ? atoi (v) : def;
}
+int64_t
+conf_get_int64 (const char *key, int64_t def) {
+ conf_lock ();
+ const char *v = conf_get_str_fast (key, NULL);
+ conf_unlock ();
+ return v ? atoll (v) : def;
+}
+
DB_conf_item_t *
conf_find (const char *group, DB_conf_item_t *prev) {
int l = strlen (group);
@@ -146,6 +202,7 @@ conf_find (const char *group, DB_conf_item_t *prev) {
void
conf_set_str (const char *key, const char *val) {
+ conf_lock ();
changed = 1;
DB_conf_item_t *prev = NULL;
for (DB_conf_item_t *it = conf_items; it; it = it->next) {
@@ -153,6 +210,7 @@ conf_set_str (const char *key, const char *val) {
if (!cmp) {
free (it->value);
it->value = strdup (val);
+ conf_unlock ();
return;
}
else if (cmp < 0) {
@@ -161,6 +219,7 @@ conf_set_str (const char *key, const char *val) {
prev = it;
}
if (!val) {
+ conf_unlock ();
return;
}
DB_conf_item_t *it = malloc (sizeof (DB_conf_item_t));
@@ -176,6 +235,7 @@ conf_set_str (const char *key, const char *val) {
it->next = conf_items;
conf_items = it;
}
+ conf_unlock ();
}
void
@@ -186,6 +246,13 @@ conf_set_int (const char *key, int val) {
}
void
+conf_set_int64 (const char *key, int64_t val) {
+ char s[20];
+ snprintf (s, sizeof (s), PRId64, val);
+ conf_set_str (key, s);
+}
+
+void
conf_set_float (const char *key, float val) {
char s[10];
snprintf (s, sizeof (s), "%0.7f", val);
@@ -205,6 +272,7 @@ conf_setchanged (int c) {
void
conf_remove_items (const char *key) {
int l = strlen (key);
+ conf_lock ();
DB_conf_item_t *prev = NULL;
DB_conf_item_t *it;
for (it = conf_items; it; prev = it, it = it->next) {
@@ -227,4 +295,5 @@ conf_remove_items (const char *key) {
else {
conf_items = next;
}
+ conf_unlock ();
}
diff --git a/conf.h b/conf.h
index 771c3a6b..c20c01cc 100644
--- a/conf.h
+++ b/conf.h
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -27,16 +27,28 @@ int
conf_save (void);
void
+conf_init (void);
+
+void
conf_free (void);
+void
+conf_lock (void);
+
+void
+conf_unlock (void);
+
int
conf_ischanged (void);
void
conf_setchanged (int c);
+void
+conf_get_str (const char *key, const char *def, char *buffer, int buffer_size);
+
const char *
-conf_get_str (const char *key, const char *def);
+conf_get_str_fast (const char *key, const char *def);
float
conf_get_float (const char *key, float def);
@@ -44,6 +56,9 @@ conf_get_float (const char *key, float def);
int
conf_get_int (const char *key, int def);
+int64_t
+conf_get_int64 (const char *key, int64_t def);
+
void
conf_set_str (const char *key, const char *val);
@@ -51,6 +66,9 @@ void
conf_set_int (const char *key, int val);
void
+conf_set_int64 (const char *key, int64_t val);
+
+void
conf_set_float (const char *key, float val);
DB_conf_item_t *
diff --git a/configure.ac b/configure.ac
index 7a113167..790e4390 100644
--- a/configure.ac
+++ b/configure.ac
@@ -15,6 +15,7 @@ AC_PROG_LIBTOOL
AC_CONFIG_MACRO_DIR([m4])
AC_C_BIGENDIAN
AM_GNU_GETTEXT
+PKG_PROG_PKG_CONFIG
IT_PROG_INTLTOOL([0.40.0])
GETTEXT_PACKAGE=deadbeef
@@ -33,15 +34,23 @@ fi
case "$host" in
i386-*-* | i486-*-* | i586-*-* | i686-*-* | i86pc-*-*)
AC_DEFINE(ARCH_X86_32, 1, [architecture is x86])
+ LIB="lib-x86-32"
+ ;;
+ x86_64-apple-*)
+ AC_DEFINE(ARCH_X86_64_OSX, 1, [architecture is x86_64 for OSX])
+ LIB="lib-x86-64-osx"
;;
x86_64-*-* | amd64-*-*)
AC_DEFINE(ARCH_X86_64, 1, [architecture is x86_64])
+ LIB="lib-x86-64"
;;
powerpc-*-* )
AC_DEFINE(ARCH_PPC_32, 1, [architecture is ppc32])
+ LIB="lib-ppc-32"
;;
powerpc64-*-* )
AC_DEFINE(ARCH_PPC_64, 1, [architecture is ppc64])
+ LIB="lib-ppc-64"
;;
*)
AC_DEFINE(ARCH_UNKNOWN, 1, [architecture is unknown])
@@ -50,21 +59,19 @@ esac
test "x$prefix" = xNONE && prefix=$ac_default_prefix
+
dnl INSANE_CFLAGS="-Wformat -Wdisabled-optimization -Wcomment -Wchar-subscripts -Wunused-function -Wunused-value -Wuninitialized -Wtype-limits -Wbad-function-cast"
dnl INSANE_CXXFLAGS="-Wcomment -Wchar-subscripts -Wunused-function -Wunused-value -Wuninitialized -Wtype-limits"
AC_SUBST(INSANE_CFLAGS)
AC_SUBST(INSANE_CXXFLAGS)
-CXXFLAGS="$CXXFLAGS $INSANE_CXXFLAGS -D_GNU_SOURCE -DLIBDIR=\\\"$libdir\\\" -DPREFIX=\\\"$prefix\\\" -DDOCDIR=\\\"$docdir\\\""
-CFLAGS="$CFLAGS $INSANE_CFLAGS -D_GNU_SOURCE -DLIBDIR=\\\"$libdir\\\" -DPREFIX=\\\"$prefix\\\" -DDOCDIR=\\\"$docdir\\\""
-
AC_ARG_ENABLE(nullout, [AS_HELP_STRING([--disable-nullout ], [disable NULL output plugin (default: enabled)])], [enable_nullout=$enableval], [enable_nullout=yes])
AC_ARG_ENABLE(alsa, [AS_HELP_STRING([--disable-alsa ], [disable ALSA output plugin (default: enabled)])], [enable_alsa=$enableval], [enable_alsa=yes])
AC_ARG_ENABLE(oss, [AS_HELP_STRING([--disable-oss ], [disable Open Sound System output plugin (default: enabled)])], [enable_oss=$enableval], [enable_oss=yes])
AC_ARG_ENABLE(pulse, [AS_HELP_STRING([--disable-pulse ], [disable PulseAudio output plugin (default: enabled)])], [enable_pulse=$enableval], [enable_pulse=yes])
AC_ARG_ENABLE(gtkui, [AS_HELP_STRING([--disable-gtkui ], [disable standard GTK2 user interface plugin (default: enabled)])], [enable_gtkui=$enableval], [enable_gtkui=yes])
-AC_ARG_ENABLE(gtk3, [AS_HELP_STRING([--enable-gtk3 ], [use GTK3 library (default: disabled)])], [enable_gtk3=$enableval], [enable_gtk3=no])
+dnl AC_ARG_ENABLE(gtk3, [AS_HELP_STRING([--enable-gtk3 ], [use GTK3 library (default: disabled)])], [enable_gtk3=$enableval], [enable_gtk3=no])
AC_ARG_ENABLE(vfs_curl, [AS_HELP_STRING([--disable-vfs-curl], [disable HTTP streaming vfs plugin (default: enabled)])], [enable_vfs_curl=$enableval], [enable_vfs_curl=yes])
AC_ARG_ENABLE(lfm, [AS_HELP_STRING([--disable-lfm ], [disable last.fm/libre.fm scrobbler plugin (default: enabled)])], [enable_lfm=$enableval], [enable_lfm=yes])
AC_ARG_ENABLE(artwork, [AS_HELP_STRING([--disable-artwork ], [disable album art loader plugin (default: enabled)])], [enable_artwork=$enableval], [enable_artwork=yes])
@@ -82,7 +89,6 @@ AC_ARG_ENABLE(sndfile, [AS_HELP_STRING([--disable-sndfile ], [disable libsndfil
AC_ARG_ENABLE(wavpack, [AS_HELP_STRING([--disable-wavpack ], [disable wavpack plugin (default: enabled)])], [enable_wavpack=$enableval], [enable_wavpack=yes])
AC_ARG_ENABLE(cdda, [AS_HELP_STRING([--disable-cdda ], [disable CD-Audio plugin (default: enabled)])], [enable_cdda=$enableval], [enable_cdda=yes])
AC_ARG_ENABLE(gme, [AS_HELP_STRING([--disable-gme ], [disable Game Music Emu plugin for NSF, AY, etc (default: enabled)])], [enable_gme=$enableval], [enable_gme=yes])
-AC_ARG_ENABLE(dumb, [AS_HELP_STRING([--disable-dumb ], [disable D.U.M.B. plugin for MOD, S3M and other tracker formats (default: enabled)])], [enable_dumb=$enableval], [enable_dumb=yes])
AC_ARG_ENABLE(notify, [AS_HELP_STRING([--disable-notify ], [disable notification-daemon support plugin (default: enabled)])], [enable_notify=$enableval], [enable_notify=yes])
AC_ARG_ENABLE(shellexec, [AS_HELP_STRING([--disable-shellexec], [disable shell commands plugin (default: enabled)])], [enable_shellexec=$enableval], [enable_shellexec=yes])
AC_ARG_ENABLE(musepack, [AS_HELP_STRING([--disable-musepack], [disable musepack plugin (default: enabled)])], [enable_musepack=$enableval], [enable_musepack=yes])
@@ -91,17 +97,59 @@ AC_ARG_ENABLE(tta, [AS_HELP_STRING([--disable-tta ], [disable tta plugi
AC_ARG_ENABLE(dca, [AS_HELP_STRING([--disable-dca ], [disable dca (DTS audio) plugin (default: enabled)])], [enable_dca=$enableval], [enable_dca=yes])
AC_ARG_ENABLE(aac, [AS_HELP_STRING([--disable-aac ], [disable AAC decoder based on FAAD2 (default: enabled)])], [enable_aac=$enableval], [enable_aac=yes])
AC_ARG_ENABLE(mms, [AS_HELP_STRING([--disable-mms ], [disable MMS streaming vfs plugin (default: enabled)])], [enable_mms=$enableval], [enable_mms=yes])
-AC_ARG_ENABLE(shn, [AS_HELP_STRING([--disable-shn ], [disable shorten plugin (default: enabled)])], [enable_shn=$enableval], [enable_shn=yes])
-AC_ARG_ENABLE(ao, [AS_HELP_STRING([--disable-ao ], [disable audio overload plugin (default: enabled)])], [enable_ao=$enableval], [enable_ao=yes])
+AC_ARG_ENABLE(staticlink, [AS_HELP_STRING([--enable-staticlink], [link everything statically (default: disabled)])], [enable_staticlink=$enableval], [enable_staticlink=no])
+AC_ARG_ENABLE(portable, [AS_HELP_STRING([--enable-portable ], [make portable build (default: disabled, opts: yes,no,full)])], [enable_portable=$enableval], [enable_portable=no])
+AC_ARG_ENABLE(src, [AS_HELP_STRING([--enable-src ], [build libsamplerate (SRC) plugin (default: auto)])], [enable_src=$enableval], [enable_src=yes])
+AC_ARG_ENABLE(m3u, [AS_HELP_STRING([--enable-m3u ], [build m3u plugin (default: auto)])], [enable_m3u=$enableval], [enable_m3u=yes])
+AC_ARG_ENABLE(vfs-zip, [AS_HELP_STRING([--enable-vfs-zip ], [build vfs_zip plugin (default: auto)])], [enable_vfs_zip=$enableval], [enable_vfs_zip=yes])
+
+if test "x$enable_staticlink" != "xno" ; then
+ AC_DEFINE_UNQUOTED([STATICLINK], [1], [Define if building static version])
+ STATICLINK=yes
+fi
+
+if test "x$enable_portable" != "xno" && test "x$enable_staticlink" != "xno" ; then
+ AC_DEFINE_UNQUOTED([PORTABLE], [1], [Define if building portable version])
+ PORTABLE=yes
+
+
+ if test "x$enable_portable" == "xfull" ; then
+ AC_DEFINE_UNQUOTED([PORTABLE_FULL], [1], [Define if portable version should keep configs in app folder])
+ PORTABLE_FULL=yes
+ fi
+
+ PREFIXFLAGS="-DPREFIX=donotuse -DLIBDIR=donotuse -DDOCDIR=donotuse -I./$LIB/include -I../../$LIB/include"
+else
+ PREFIXFLAGS=" -DLIBDIR=\\\"$libdir\\\" -DPREFIX=\\\"$prefix\\\" -DDOCDIR=\\\"$docdir\\\""
+fi
+
+CXXFLAGS="$CXXFLAGS $INSANE_CXXFLAGS -D_GNU_SOURCE $PREFIXFLAGS"
+CFLAGS="$CFLAGS $INSANE_CFLAGS -D_GNU_SOURCE $PREFIXFLAGS"
-PKG_CHECK_MODULES(DEPS, samplerate)
+if test "x$enable_staticlink" != "xno" ; then
+ HAVE_ZLIB=yes
+ ZLIB_LIBS="../../$LIB/libz.a"
+else
+ AC_CHECK_LIB([z], [main], [HAVE_ZLIB=yes])
+ ZLIB_LIBS="-lz"
+fi
+AC_SUBST(ZLIB_LIBS)
+
+if test "x$enable_staticlink" != "xno" ; then
+ HAVE_ZIP=yes
+ ZIP_LIBS="../../$LIB/libzip.a"
+else
+ AC_CHECK_LIB([zip], [main], [HAVE_ZIP=yes])
+ ZIP_LIBS="-lzip"
+fi
+AC_SUBST(ZIP_LIBS)
if test "x$enable_gtkui" != "xno" ; then
- if test "x$enable_gtk3" == "xyes" ; then
- PKG_CHECK_MODULES(GTKUI_DEPS, gtk+-3.0 >= 2.90 gthread-2.0 glib-2.0, HAVE_GTK=yes, HAVE_GTK=no)
- else
+dnl if test "x$enable_gtk3" == "xyes" ; then
+dnl PKG_CHECK_MODULES(GTKUI_DEPS, gtk+-3.0 >= 2.90 gthread-2.0 glib-2.0, HAVE_GTK=yes, HAVE_GTK=no)
+dnl else
PKG_CHECK_MODULES(GTKUI_DEPS, gtk+-2.0 >= 2.12 gthread-2.0 glib-2.0, HAVE_GTK=yes, HAVE_GTK=no)
- fi
+dnl fi
else
HAVE_GTK=no
fi
@@ -111,21 +159,24 @@ if test "x$enable_alsa" != "xno" ; then
fi
if test "x$enable_ffmpeg" != "xno" ; then
+if test "x$enable_staticlink" != "xno" ; then
+ FFMPEG_DEPS_LIBS="../../$LIB/libavcodec.a -lpthread ../../$LIB/libavformat.a ../../$LIB/libavcodec.a ../../$LIB/libavutil.a ../../$LIB/libavcore.a -lm ../../$LIB/libz.a "
+ AC_SUBST(FFMPEG_DEPS_LIBS)
+ HAVE_FFMPEG=yes
+else
PKG_CHECK_MODULES(FFMPEG_DEPS, libavcodec >= 51.0.0 libavutil libavformat >= 52.0.0, HAVE_FFMPEG=yes, HAVE_FFMPEG=no)
fi
+fi
if test "x$enable_pulse" != "xno" ; then
PKG_CHECK_MODULES(PULSE_DEPS, libpulse-simple, HAVE_PULSE=yes, HAVE_PULSE=no)
fi
-AC_CHECK_LIB([pthread], [main])
-AC_CHECK_LIB([dl], [main])
-
AC_CHECK_HEADER([iconv.h],[],[iconv.h not found.])
AC_CHECK_LIB([iconv], [main], [have_iconv=yes], [have_iconv=no])
if test "x${have_iconv}" = "xyes" ; then
-ICONV_LIB="-liconv"
+ ICONV_LIB="-liconv"
AC_SUBST(ICONV_LIB)
AC_DEFINE(HAVE_LIBICONV,1,[Use libiconv instead of glibc iconv])
fi
@@ -136,17 +187,33 @@ if test ${HAVE_SSE2}; then
fi
dnl curl lib
-AC_CHECK_LIB([curl], [main], [HAVE_CURL=yes])
-if test "x$HAVE_CURL" = "xyes"; then
+if test "x$enable_staticlink" != "xno" ; then
+ HAVE_CURL=yes
+ CURL_LIBS="../../$LIB/libcurl.a -lrt"
+ AC_SUBST(CURL_LIBS)
+else
+ AC_CHECK_LIB([curl], [main], [HAVE_CURL=yes])
CURL_LIBS="-lcurl"
AC_SUBST(CURL_LIBS)
fi
-PKG_CHECK_MODULES(DBUS_DEPS, dbus-1, HAVE_DBUS=yes, HAVE_DBUS=no)
+if test "x$enable_staticlink" != "xno" ; then
+ HAVE_DBUS=yes
+ DBUS_DEPS_LIBS="../../$LIB/libdbus-1.a ../../$LIB/libexpat.a -lrt"
+ DBUS_DEPS_CFLAGS="-I../../$LIB/include/dbus-1"
+ AC_SUBST(DBUS_DEPS_LIBS)
+else
+ PKG_CHECK_MODULES(DBUS_DEPS, dbus-1, HAVE_DBUS=yes, HAVE_DBUS=no)
+fi
dnl mpgmad plugin
if test "x$enable_mpgmad" != "xno" ; then
+if test "x$enable_staticlink" != "xno" ; then
+ HAVE_MPGMAD=yes
+ MAD_LIBS="../../$LIB/libmad.a"
+ AC_SUBST(MAD_LIBS)
+else
AC_CHECK_LIB([mad], [main], [HAVE_LIBMAD=yes])
if test "x$HAVE_LIBMAD" = "xyes" ; then
HAVE_MPGMAD=yes
@@ -154,9 +221,15 @@ if test "x$enable_mpgmad" != "xno" ; then
AC_SUBST(MAD_LIBS)
fi
fi
+fi
dnl vorbis plugin
if test "x$enable_vorbis" != "xno" ; then
+if test "x$enable_staticlink" != "xno" ; then
+ HAVE_VORBISPLUGIN=yes
+ VORBIS_LIBS="../../$LIB/libogg.a ../../$LIB/libvorbis.a ../../$LIB/libvorbisenc.a ../../$LIB/libvorbisfile.a"
+ AC_SUBST(VORBIS_LIBS)
+else
AC_CHECK_LIB([vorbis], [main], [HAVE_VORBIS=yes])
AC_CHECK_LIB([vorbisfile], [main], [HAVE_VORBISFILE=yes])
if test "x$HAVE_VORBIS" = "xyes" && test "x$HAVE_VORBISFILE" = "xyes" ; then
@@ -165,9 +238,15 @@ if test "x$enable_vorbis" != "xno" ; then
AC_SUBST(VORBIS_LIBS)
fi
fi
+fi
dnl flac plugin
if test "x$enable_flac" != "xno" ; then
+if test "x$enable_staticlink" != "xno" ; then
+ HAVE_FLACPLUGIN=yes
+ FLAC_LIBS="../../$LIB/libFLAC.a ../../$LIB/libogg.a"
+ AC_SUBST(FLAC_LIBS)
+else
AC_CHECK_LIB([FLAC], [main], [HAVE_FLAC=yes])
if test "x$HAVE_FLAC" = "xyes" ; then
HAVE_FLACPLUGIN=yes
@@ -175,9 +254,15 @@ if test "x$enable_flac" != "xno" ; then
AC_SUBST(FLAC_LIBS)
fi
fi
+fi
dnl wavpack plugin
if test "x$enable_wavpack" != "xno" ; then
+if test "x$enable_staticlink" != "xno" ; then
+ HAVE_WAVPACKPLUGIN=yes
+ WAVPACK_LIBS="../../$LIB/libwavpack.a"
+ AC_SUBST(WAVPACK_LIBS)
+else
AC_CHECK_LIB([wavpack], [main], [HAVE_WAVPACK=yes])
if test "x$HAVE_WAVPACK" = "xyes" ; then
HAVE_WAVPACKPLUGIN=yes
@@ -185,9 +270,15 @@ if test "x$enable_wavpack" != "xno" ; then
AC_SUBST(WAVPACK_LIBS)
fi
fi
+fi
dnl libsndfile plugin
if test "x$enable_sndfile" != "xno" ; then
+if test "x$enable_staticlink" != "xno" ; then
+ HAVE_SNDFILEPLUGIN=yes
+ SNDFILE_LIBS="../../$LIB/libsndfile.a"
+ AC_SUBST(SNDFILE_LIBS)
+else
AC_CHECK_LIB([sndfile], [main], [HAVE_SNDFILE=yes])
if test "x$HAVE_SNDFILE" = "xyes" ; then
HAVE_SNDFILEPLUGIN=yes
@@ -195,18 +286,24 @@ if test "x$enable_sndfile" != "xno" ; then
AC_SUBST(SNDFILE_LIBS)
fi
fi
+fi
dnl vfs_curl plugin
if test "x$enable_vfs_curl" != "xno" ; then
if test "x$HAVE_CURL" = "xyes" ; then
HAVE_VFS_CURL=yes
- VFS_CURL_LIBS="-lcurl"
+ VFS_CURL_LIBS="$CURL_LIBS"
AC_SUBST(VFS_CURL_LIBS)
fi
fi
dnl cdda plugin
if test "x$enable_cdda" != "xno" ; then
+if test "x$enable_staticlink" != "xno" ; then
+ HAVE_CDDAPLUGIN=yes
+ CDDA_LIBS="../../$LIB/libcdio.a ../../$LIB/libudf.a ../../$LIB/libiso9660.a ../../$LIB/libcddb.a"
+ AC_SUBST(CDDA_LIBS)
+else
AC_CHECK_LIB([cdio], [main], [HAVE_CDIO=yes])
AC_CHECK_LIB([cddb], [main], [HAVE_CDDB=yes])
if test "x$HAVE_CDIO" = "xyes" && test "x$HAVE_CDDB" = "xyes" ; then
@@ -215,6 +312,7 @@ if test "x$enable_cdda" != "xno" ; then
AC_SUBST(CDDA_LIBS)
fi
fi
+fi
dnl gtkui plugin
if test "x$enable_gtkui" != "xno" ; then
@@ -230,10 +328,14 @@ if test "x$enable_alsa" != "xno" ; then
fi
if test "x$enable_ffmpeg" != "xno" ; then
+if test "x$enable_staticlink" = "xno" ; then
if test "x$HAVE_FFMPEG" = "xyes" ; then
HAVE_FFMPEGPLUGIN=yes
AC_CHECK_HEADER([ffmpeg/avformat.h], FFMPEG_DEPS_CFLAGS="$FFMPEG_DEPS_CFLAGS -D FFMPEG_OLD")
fi
+else
+ HAVE_FFMPEGPLUGIN=yes
+fi
fi
if test "x$enable_hotkeys" != "xno" ; then
@@ -303,7 +405,8 @@ if test "x$enable_shellexec" != "xno" ; then
fi
if test "x$enable_artwork" != "xno" ; then
- if test "x$HAVE_CURL" = "xyes" && test "x$HAVE_VFS_CURL" = "xyes" ; then
+ PKG_CHECK_MODULES(IMLIB2_DEPS, imlib2, HAVE_IMLIB2=yes, HAVE_IMLIB2=no)
+ if test "x$HAVE_CURL" = "xyes" && test "x$HAVE_VFS_CURL" = "xyes" && test "x$HAVE_IMLIB2" == "xyes" ; then
HAVE_ARTWORK=yes
fi
fi
@@ -324,6 +427,19 @@ if test "x$enable_nullout" != "xno" ; then
HAVE_NULLOUT=yes
fi
+if test "x$enable_src" != "xno" ; then
+if test "x$enable_staticlink" != "xno" ; then
+ LIBSAMPLERATE_DEPS_LIBS="../../$LIB/libsamplerate.a -lpthread -ldl"
+ AC_SUBST(LIBSAMPLERATE_DEPS_LIBS)
+ HAVE_DSP_SRC=yes
+else
+ PKG_CHECK_MODULES(LIBSAMPLERATE_DEPS, samplerate, HAVE_LIBSAMPLERATE=yes, HAVE_LIBSAMPLERATE=no)
+ if test "x$HAVE_LIBSAMPLERATE" = "xyes" ; then
+ HAVE_DSP_SRC=yes
+ fi
+fi
+fi
+
if test "x$enable_supereq" != "xno" ; then
HAVE_SUPEREQ=yes
fi
@@ -336,10 +452,6 @@ if test "x$enable_gme" != "xno" ; then
HAVE_GME=yes
fi
-if test "x$enable_dumb" != "xno" ; then
- HAVE_DUMB=yes
-fi
-
if test "x$HAVE_DBUS" = "xyes" && test "x$enable_notify" != "xno" ; then
HAVE_NOTIFY=yes
NOTIFY_LIBS="$DBUS_DEPS_LIBS"
@@ -365,6 +477,11 @@ if test "x$enable_dca" != "xno" ; then
fi
if test "x$enable_aac" != "xno" ; then
+if test "x$enable_staticlink" != "xno" ; then
+ FAAD2_LIBS="../../$LIB/libfaad.a"
+ AC_SUBST(FAAD2_LIBS)
+ HAVE_AAC=yes
+else
AC_CHECK_LIB([faad], [main], [HAVE_FAAD=1])
if test ${HAVE_FAAD} ; then
FAAD2_LIBS="-lfaad"
@@ -372,6 +489,7 @@ if test "x$enable_aac" != "xno" ; then
HAVE_AAC=yes
fi
fi
+fi
if test "x$enable_mms" != "xno" ; then
LIBMMS_LIBS=""
@@ -379,20 +497,17 @@ if test "x$enable_mms" != "xno" ; then
HAVE_MMS=yes
fi
-if test "x$enable_shn" != "xno" ; then
- HAVE_SHN=yes
+if test "x$enable_m3u" != "xno" ; then
+ HAVE_M3U=yes
fi
-if test "x$enable_ao" != "xno" ; then
- AC_CHECK_LIB([z], [main], [HAVE_ZLIB=yes])
- if test "x$HAVE_ZLIB" = "xyes"; then
- ZLIB_LIBS="-lz"
- AC_SUBST(ZLIB_LIBS)
- HAVE_AO=yes
+if test "x$enable_vfs_zip" != "xno" ; then
+ if test "x$HAVE_ZLIB" = "xyes" && test "x$HAVE_ZIP" = "xyes" ; then
+ HAVE_VFS_ZIP=yes
fi
fi
-PLUGINS_DIRS="plugins/lastfm plugins/mpgmad plugins/vorbis plugins/flac plugins/wavpack plugins/sndfile plugins/vfs_curl plugins/cdda plugins/gtkui plugins/alsa plugins/ffmpeg plugins/hotkeys plugins/oss plugins/artwork plugins/adplug plugins/ffap plugins/sid plugins/nullout plugins/supereq plugins/vtx plugins/gme plugins/dumb plugins/pulse plugins/notify plugins/musepack plugins/wildmidi plugins/tta plugins/dca plugins/aac plugins/mms plugins/shn plugins/ao plugins/shellexec"
+PLUGINS_DIRS="plugins/lastfm plugins/mpgmad plugins/vorbis plugins/flac plugins/wavpack plugins/sndfile plugins/vfs_curl plugins/cdda plugins/gtkui plugins/alsa plugins/ffmpeg plugins/hotkeys plugins/oss plugins/artwork plugins/adplug plugins/ffap plugins/sid plugins/nullout plugins/supereq plugins/vtx plugins/gme plugins/pulse plugins/notify plugins/musepack plugins/wildmidi plugins/tta plugins/dca plugins/aac plugins/mms plugins/shellexec plugins/dsp_libsrc plugins/m3u plugins/vfs_zip"
AM_CONDITIONAL(HAVE_VORBIS, test "x$HAVE_VORBISPLUGIN" = "xyes")
AM_CONDITIONAL(HAVE_FLAC, test "x$HAVE_FLACPLUGIN" = "xyes")
@@ -410,7 +525,6 @@ AM_CONDITIONAL(HAVE_SID, test "x$HAVE_SID" = "xyes")
AM_CONDITIONAL(HAVE_NULLOUT, test "x$HAVE_NULLOUT" = "xyes")
AM_CONDITIONAL(HAVE_VTX, test "x$HAVE_VTX" = "xyes")
AM_CONDITIONAL(HAVE_GME, test "x$HAVE_GME" = "xyes")
-AM_CONDITIONAL(HAVE_DUMB, test "x$HAVE_DUMB" = "xyes")
AM_CONDITIONAL(HAVE_LASTFM, test "x$HAVE_LASTFM" = "xyes")
AM_CONDITIONAL(HAVE_VFS_CURL, test "x$HAVE_VFS_CURL" = "xyes")
AM_CONDITIONAL(HAVE_HOTKEYS, test "x$HAVE_HOTKEYS" = "xyes")
@@ -425,8 +539,12 @@ AM_CONDITIONAL(HAVE_TTA, test "x$HAVE_TTA" = "xyes")
AM_CONDITIONAL(HAVE_DCA, test "x$HAVE_DCA" = "xyes")
AM_CONDITIONAL(HAVE_AAC, test "x$HAVE_AAC" = "xyes")
AM_CONDITIONAL(HAVE_MMS, test "x$HAVE_MMS" = "xyes")
-AM_CONDITIONAL(HAVE_SHN, test "x$HAVE_SHN" = "xyes")
-AM_CONDITIONAL(HAVE_AO, test "x$HAVE_AO" = "xyes")
+AM_CONDITIONAL(STATICLINK, test "x$STATICLINK" = "xyes")
+AM_CONDITIONAL(PORTABLE, test "x$PORTABLE" = "xyes")
+AM_CONDITIONAL(PORTABLE_FULL, test "x$PORTABLE_FULL" = "xyes")
+AM_CONDITIONAL(HAVE_DSP_SRC, test "x$HAVE_DSP_SRC" = "xyes")
+AM_CONDITIONAL(HAVE_M3U, test "x$HAVE_M3U" = "xyes")
+AM_CONDITIONAL(HAVE_VFS_ZIP, test "x$HAVE_VFS_ZIP" = "xyes")
AC_SUBST(PLUGINS_DIRS)
@@ -455,7 +573,6 @@ AC_DEFUN([PRINT_PLUGIN_INFO],
PRINT_PLUGIN_INFO([stdio],[Standard IO plugin],[true])
PRINT_PLUGIN_INFO([gme],[chiptune music player based on GME],[test "x$HAVE_GME" = "xyes"])
-PRINT_PLUGIN_INFO([dumb],[module player based on DUMB library],[test "x$HAVE_DUMB" = "xyes"])
PRINT_PLUGIN_INFO([nullout],[NULL output],[test "x$HAVE_NULLOUT" = "xyes"])
PRINT_PLUGIN_INFO([alsa],[ALSA output],[test "x$HAVE_ALSA" = "xyes"])
PRINT_PLUGIN_INFO([sid],[SID player based on libsidplay2],[test "x$HAVE_SID" = "xyes"])
@@ -485,8 +602,9 @@ PRINT_PLUGIN_INFO([tta],[TTA player plugin],[test "x$HAVE_TTA" = "xyes"])
PRINT_PLUGIN_INFO([dca],[libdca (DTS Audio) player plugin],[test "x$HAVE_DCA" = "xyes"])
PRINT_PLUGIN_INFO([aac],[AAC player (m4a, aac, mp4) based on FAAD2],[test "x$HAVE_AAC" = "xyes"])
PRINT_PLUGIN_INFO([mms],[mms streaming support],[test "x$HAVE_MMS" = "xyes"])
-PRINT_PLUGIN_INFO([shn],[shorten player based on xmms-shn],[test "x$HAVE_SHN" = "xyes"])
-PRINT_PLUGIN_INFO([ao],[psf1/psf2/spu/ssf player using Audio Overload],[test "x$HAVE_AO" = "xyes"])
+PRINT_PLUGIN_INFO([dsp_src],[High quality samplerate conversion using libsamplerate],[test "x$HAVE_DSP_SRC" = "xyes"])
+PRINT_PLUGIN_INFO([m3u],[M3U and PLS playlist support],[test "x$HAVE_M3U" = "xyes"])
+PRINT_PLUGIN_INFO([vfs_zip],[zip archive support],[test "x$HAVE_VFS_ZIP" = "xyes"])
echo
@@ -495,7 +613,6 @@ Makefile
pixmaps/Makefile
icons/Makefile
plugins/gme/Makefile
-plugins/dumb/Makefile
plugins/alsa/Makefile
plugins/hotkeys/Makefile
plugins/lastfm/Makefile
@@ -525,8 +642,9 @@ plugins/tta/Makefile
plugins/dca/Makefile
plugins/aac/Makefile
plugins/mms/Makefile
-plugins/shn/Makefile
-plugins/ao/Makefile
+plugins/dsp_libsrc/Makefile
+plugins/m3u/Makefile
+plugins/vfs_zip/Makefile
intl/Makefile
po/Makefile.in
deadbeef.desktop
diff --git a/deadbeef.h b/deadbeef.h
index 556ef1b6..31d36ca7 100644
--- a/deadbeef.h
+++ b/deadbeef.h
@@ -2,7 +2,7 @@
deadbeef.h -- plugin API of the DeaDBeeF audio player
http://deadbeef.sourceforge.net
- Copyright (C) 2009 Alexey Yakovenko
+ Copyright (C) 2009-2011 Alexey Yakovenko
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@@ -30,6 +30,7 @@
#include <stdint.h>
#include <time.h>
#include <stdio.h>
+#include <dirent.h>
#ifdef __cplusplus
extern "C" {
@@ -55,6 +56,8 @@ extern "C" {
// api version history:
// 9.9 -- devel
+// 0.10 -- deadbeef-0.4.4-portable-r1
+// 0.9 -- deadbeef-0.4.3-portable-build3
// 0.8 -- deadbeef-0.4.2
// 0.7 -- deabdeef-0.4.0
// 0.6 -- deadbeef-0.3.3
@@ -64,8 +67,8 @@ extern "C" {
// 0.2 -- deadbeef-0.2.3
// 0.1 -- deadbeef-0.2.0
-#define DB_API_VERSION_MAJOR 0
-#define DB_API_VERSION_MINOR 8
+#define DB_API_VERSION_MAJOR 9
+#define DB_API_VERSION_MINOR 9
#define DB_PLUGIN_SET_API_VERSION\
.plugin.api_vmajor = DB_API_VERSION_MAJOR,\
@@ -101,25 +104,17 @@ enum {
// playlist item
// these are "public" fields, available to plugins
typedef struct DB_playItem_s {
- char *fname; // full pathname
- const char *decoder_id;
- int tracknum; // used for stuff like sid, nsf, cue (will be ignored by most codecs)
int startsample; // start sample of track, or -1 for auto
int endsample; // end sample of track, or -1 for auto
int shufflerating; // sort order for shuffle mode
float playtime; // actual playback time of this track in seconds
time_t started_timestamp; // result of calling time(NULL)
- const char *filetype; // e.g. MP3 or OGG
- float replaygain_album_gain;
- float replaygain_album_peak;
- float replaygain_track_gain;
- float replaygain_track_peak;
} DB_playItem_t;
typedef struct DB_metaInfo_s {
+ struct DB_metaInfo_s *next;
const char *key;
const char *value;
- struct DB_metaInfo_s *next;
} DB_metaInfo_t;
// FIXME: that needs to be in separate plugin
@@ -166,6 +161,7 @@ enum {
DB_PLUGIN_DSP = 3,
DB_PLUGIN_MISC = 4,
DB_PLUGIN_VFS = 5,
+ DB_PLUGIN_PLAYLIST = 6,
};
// output plugin states
@@ -178,8 +174,9 @@ enum output_state_t {
// playback order
enum playback_order_t {
PLAYBACK_ORDER_LINEAR = 0,
- PLAYBACK_ORDER_SHUFFLE = 1,
+ PLAYBACK_ORDER_SHUFFLE_TRACKS = 1,
PLAYBACK_ORDER_RANDOM = 2,
+ PLAYBACK_ORDER_SHUFFLE_ALBUMS = 3,
};
// playback modes
@@ -221,7 +218,6 @@ typedef int (*DB_callback_t)(DB_event_t *, uintptr_t data);
// events
enum {
- DB_EV_FRAMEUPDATE = 0, // ticks around 20 times per second, but ticker may stop sometimes
DB_EV_SONGCHANGED = 1, // triggers when song was just changed
DB_EV_SONGSTARTED = 2, // triggers when song started playing (for scrobblers and such)
DB_EV_SONGFINISHED = 3, // triggers when song finished playing (for scrobblers and such)
@@ -245,20 +241,29 @@ enum pl_column_t {
DB_COLUMN_ID_MAX
};
+// replaygain constants
+enum {
+ DDB_REPLAYGAIN_ALBUMGAIN,
+ DDB_REPLAYGAIN_ALBUMPEAK,
+ DDB_REPLAYGAIN_TRACKGAIN,
+ DDB_REPLAYGAIN_TRACKPEAK,
+};
+
// message ids for communicating with player
enum {
M_SONGFINISHED,
- M_NEXTSONG,
- M_PREVSONG,
- M_PLAYSONG,
- M_PLAYSONGNUM,
- M_STOPSONG,
- M_PAUSESONG,
- M_PLAYRANDOM,
+ M_NEXT,
+ M_PREV,
+ M_PLAY_CURRENT,
+ M_PLAY_NUM,
+ M_STOP,
+ M_PAUSE,
+ M_PLAY_RANDOM,
M_TERMINATE, // must be sent to player thread to terminate
- M_PLAYLISTREFRESH,
+ M_PLAYLIST_REFRESH, // means
M_REINIT_SOUND,
- M_CONFIGCHANGED, // no arguments
+ M_CONFIG_CHANGED, // no arguments
+ M_TOGGLE_PAUSE,
};
// typecasting macros
@@ -277,6 +282,15 @@ typedef struct DB_md5_s {
char data[88];
} DB_md5_t;
+typedef struct {
+ int bps;
+ int channels;
+ int samplerate;
+ uint32_t channelmask;
+ int is_float; // bps must be 32 if this is true
+ int is_bigendian;
+} ddb_waveformat_t;
+
// forward decl for plugin struct
struct DB_plugin_s;
@@ -285,27 +299,24 @@ typedef struct {
// versioning
int vmajor;
int vminor;
+
// event subscribing
void (*ev_subscribe) (struct DB_plugin_s *plugin, int ev, DB_callback_t callback, uintptr_t data);
void (*ev_unsubscribe) (struct DB_plugin_s *plugin, int ev, DB_callback_t callback, uintptr_t data);
+
// md5sum calc
void (*md5) (uint8_t sig[16], const char *in, int len);
void (*md5_to_str) (char *str, const uint8_t sig[16]);
void (*md5_init)(DB_md5_t *s);
void (*md5_append)(DB_md5_t *s, const uint8_t *data, int nbytes);
void (*md5_finish)(DB_md5_t *s, uint8_t digest[16]);
+
// playback control
struct DB_output_s* (*get_output) (void);
- void (*playback_next) (void);
- void (*playback_prev) (void);
- void (*playback_pause) (void);
- void (*playback_stop) (void);
- void (*playback_play) (void);
- void (*playback_random) (void);
float (*playback_get_pos) (void); // [0..100]
void (*playback_set_pos) (float pos); // [0..100]
+
// streamer access
- // FIXME: needs to be thread-safe
DB_playItem_t *(*streamer_get_playing_track) (void);
DB_playItem_t *(*streamer_get_streaming_track) (void);
float (*streamer_get_playpos) (void);
@@ -317,13 +328,28 @@ typedef struct {
int (*streamer_get_apx_bitrate) (void);
struct DB_fileinfo_s *(*streamer_get_current_fileinfo) (void);
int (*streamer_get_current_playlist) (void);
+ struct ddb_dsp_context_s * (*streamer_get_dsp_chain) (void);
+ void (*streamer_set_dsp_chain) (struct ddb_dsp_context_s *chain);
+ void (*streamer_dsp_refresh) (void); // call after changing parameters
+
+ // system folders
+ // normally functions will return standard folders derived from --prefix
+ // portable version will return pathes specified in comments below
+ const char *(*get_config_dir) (void); // installdir/config | $XDG_CONFIG_HOME/.config/deadbeef
+ const char *(*get_prefix) (void); // installdir | PREFIX
+ const char *(*get_doc_dir) (void); // installdir/doc | DOCDIR
+ const char *(*get_plugin_dir) (void); // installdir/plugins | LIBDIR/deadbeef
+ const char *(*get_pixmap_dir) (void); // installdir/pixmaps | PREFIX "/share/deadbeef/pixmaps"
+
// process control
- const char *(*get_config_dir) (void);
void (*quit) (void);
+
// threading
intptr_t (*thread_start) (void (*fn)(void *ctx), void *ctx);
intptr_t (*thread_start_low_priority) (void (*fn)(void *ctx), void *ctx);
int (*thread_join) (intptr_t tid);
+ int (*thread_detach) (intptr_t tid);
+ void (*thread_exit) (void *retval);
uintptr_t (*mutex_create) (void);
uintptr_t (*mutex_create_nonrecursive) (void);
void (*mutex_free) (uintptr_t mtx);
@@ -334,31 +360,51 @@ typedef struct {
int (*cond_wait) (uintptr_t cond, uintptr_t mutex);
int (*cond_signal) (uintptr_t cond);
int (*cond_broadcast) (uintptr_t cond);
+
// playlist management
int (*plt_get_count) (void);
DB_playItem_t * (*plt_get_head) (int plt);
int (*plt_get_sel_count) (int plt);
int (*plt_add) (int before, const char *title);
void (*plt_remove) (int plt);
- void (*plt_free) (void);
void (*plt_set_curr) (int plt);
int (*plt_get_curr) (void);
- int (*plt_get_title) (int plt, char *buffer, int bufsize);
- int (*plt_set_title) (int plt, const char *title);
void (*plt_move) (int from, int before);
- // playlist control
+
+ // getting and working with a handle must be guarded using plt_lock/unlock
+ void *(*plt_get_handle) (int idx);
+ int (*plt_get_title) (void *handle, char *buffer, int bufsize);
+ int (*plt_set_title) (void *handle, const char *title);
+
+ // playlist metadata
+ // this kind of metadata is stored in playlist (dbpl) files
+ void (*plt_add_meta) (void *handle, const char *key, const char *value);
+ void (*plt_replace_meta) (void *handle, const char *key, const char *value);
+ void (*plt_append_meta) (void *handle, const char *key, const char *value);
+ void (*plt_set_meta_int) (void *handle, const char *key, int value);
+ void (*plt_set_meta_float) (void *handle, const char *key, float value);
+ const char *(*plt_find_meta) (void *handle, const char *key);
+ DB_metaInfo_t * (*plt_get_metadata_head) (void *handle); // returns head of metadata linked list
+ void (*plt_delete_metadata) (void *handle, DB_metaInfo_t *meta);
+ int (*plt_find_meta_int) (void *handle, const char *key, int def);
+ float (*plt_find_meta_float) (void *handle, const char *key, float def);
+ void (*plt_delete_all_meta) (void *handle);
+
+ // playlist locking
void (*pl_lock) (void);
void (*pl_unlock) (void);
void (*plt_lock) (void);
void (*plt_unlock) (void);
+
// playlist tracks access
DB_playItem_t * (*pl_item_alloc) (void);
+ DB_playItem_t * (*pl_item_alloc_init) (const char *fname, const char *decoder_id);
void (*pl_item_ref) (DB_playItem_t *it);
void (*pl_item_unref) (DB_playItem_t *it);
void (*pl_item_copy) (DB_playItem_t *out, DB_playItem_t *in);
int (*pl_add_file) (const char *fname, int (*cb)(DB_playItem_t *it, void *data), void *user_data);
int (*pl_add_dir) (const char *dirname, int (*cb)(DB_playItem_t *it, void *data), void *user_data);
- void (*pl_add_files_begin) (void);
+ void (*pl_add_files_begin) (int playlist);
void (*pl_add_files_end) (void);
DB_playItem_t *(*pl_insert_item) (DB_playItem_t *after, DB_playItem_t *it);
DB_playItem_t *(*pl_insert_dir) (DB_playItem_t *after, const char *dirname, int *pabort, int (*cb)(DB_playItem_t *it, void *data), void *user_data);
@@ -416,25 +462,41 @@ typedef struct {
// _escaped version wraps all conversions with '' and replaces every ' in conversions with \'
int (*pl_format_title_escaped) (DB_playItem_t *it, int idx, char *s, int size, int id, const char *fmt);
void (*pl_format_time) (float t, char *dur, int size);
- void (*pl_format_item_display_name) (DB_playItem_t *it, char *str, int len);
void (*pl_move_items) (int iter, int plt_from, DB_playItem_t *drop_before, uint32_t *indexes, int count);
void (*pl_copy_items) (int iter, int plt_from, DB_playItem_t *before, uint32_t *indices, int cnt);
void (*pl_search_reset) (void);
void (*pl_search_process) (const char *text);
- // metainfo
+
+ // direct access to metadata structures
+ // not thread-safe, make sure to wrap with pl_lock/pl_unlock
+ DB_metaInfo_t * (*pl_get_metadata_head) (DB_playItem_t *it); // returns head of metadata linked list
+ void (*pl_delete_metadata) (DB_playItem_t *it, DB_metaInfo_t *meta);
+
+ // high-level access to metadata
void (*pl_add_meta) (DB_playItem_t *it, const char *key, const char *value);
void (*pl_append_meta) (DB_playItem_t *it, const char *key, const char *value);
- // must be used from within explicit pl_lock/unlock block
+ void (*pl_set_meta_int) (DB_playItem_t *it, const char *key, int value);
+ void (*pl_set_meta_float) (DB_playItem_t *it, const char *key, float value);
+ void (*pl_delete_meta) (DB_playItem_t *it, const char *key);
+
+ // this function is not thread-safe
+ // make sure to wrap it with pl_lock/pl_unlock block
const char *(*pl_find_meta) (DB_playItem_t *it, const char *key);
+
+ // following functions are thread-safe
+ int (*pl_find_meta_int) (DB_playItem_t *it, const char *key, int def);
+ float (*pl_find_meta_float) (DB_playItem_t *it, const char *key, float def);
void (*pl_replace_meta) (DB_playItem_t *it, const char *key, const char *value);
void (*pl_delete_all_meta) (DB_playItem_t *it);
- DB_metaInfo_t * (*pl_get_metadata) (DB_playItem_t *it);
void (*pl_set_item_duration) (DB_playItem_t *it, float duration);
float (*pl_get_item_duration) (DB_playItem_t *it);
uint32_t (*pl_get_item_flags) (DB_playItem_t *it);
void (*pl_set_item_flags) (DB_playItem_t *it, uint32_t flags);
void (*pl_sort) (int iter, int id, const char *format, int ascending);
void (*pl_items_copy_junk)(DB_playItem_t *from, DB_playItem_t *first, DB_playItem_t *last);
+ // idx is one of DDB_REPLAYGAIN_* constants
+ void (*pl_set_item_replaygain) (DB_playItem_t *it, int idx, float value);
+ float (*pl_get_item_replaygain) (DB_playItem_t *it, int idx);
// playqueue support
int (*pl_playqueue_push) (DB_playItem_t *it);
@@ -442,15 +504,18 @@ typedef struct {
void (*pl_playqueue_pop) (void);
void (*pl_playqueue_remove) (DB_playItem_t *it);
int (*pl_playqueue_test) (DB_playItem_t *it);
+
// cuesheet support
DB_playItem_t *(*pl_insert_cue_from_buffer) (DB_playItem_t *after, DB_playItem_t *origin, const uint8_t *buffer, int buffersize, int numsamples, int samplerate);
DB_playItem_t * (*pl_insert_cue) (DB_playItem_t *after, DB_playItem_t *origin, int numsamples, int samplerate);
+
// volume control
void (*volume_set_db) (float dB);
float (*volume_get_db) (void);
void (*volume_set_amp) (float amp);
float (*volume_get_amp) (void);
float (*volume_get_min_db) (void);
+
// junk reading/writing
int (*junk_id3v1_read) (DB_playItem_t *it, DB_FILE *fp);
int (*junk_id3v1_find) (DB_FILE *fp);
@@ -481,6 +546,7 @@ typedef struct {
int (*junk_recode) (const char *in, int inlen, char *out, int outlen, const char *cs);
int (*junk_iconv) (const char *in, int inlen, char *out, int outlen, const char *cs_in, const char *cs_out);
int (*junk_rewrite_tags) (DB_playItem_t *it, uint32_t flags, int id3v2_version, const char *id3v1_encoding);
+
// vfs
DB_FILE* (*fopen) (const char *fname);
void (*fclose) (DB_FILE *f);
@@ -492,33 +558,59 @@ typedef struct {
const char *(*fget_content_type) (DB_FILE *stream);
void (*fset_track) (DB_FILE *stream, DB_playItem_t *it);
void (*fabort) (DB_FILE *stream);
+
// message passing
int (*sendmessage) (uint32_t id, uintptr_t ctx, uint32_t p1, uint32_t p2);
+
// configuration access
- const char * (*conf_get_str) (const char *key, const char *def);
+ //
+ // conf_get_str_fast is not thread-safe, and
+ // must only be used from within conf_lock/conf_unlock block
+ // it should be preferred for fast non-blocking lookups
+ //
+ // all the other config access functions are thread safe
+ void (*conf_lock) (void);
+ void (*conf_unlock) (void);
+ const char * (*conf_get_str_fast) (const char *key, const char *def);
+ void (*conf_get_str) (const char *key, const char *def, char *buffer, int buffer_size);
float (*conf_get_float) (const char *key, float def);
int (*conf_get_int) (const char *key, int def);
+ int64_t (*conf_get_int64) (const char *key, int64_t def);
void (*conf_set_str) (const char *key, const char *val);
void (*conf_set_int) (const char *key, int val);
+ void (*conf_set_int64) (const char *key, int64_t val);
void (*conf_set_float) (const char *key, float val);
DB_conf_item_t * (*conf_find) (const char *group, DB_conf_item_t *prev);
void (*conf_remove_items) (const char *key);
int (*conf_save) (void);
+
// plugin communication
struct DB_decoder_s **(*plug_get_decoder_list) (void);
+ struct DB_vfs_s **(*plug_get_vfs_list) (void);
struct DB_output_s **(*plug_get_output_list) (void);
struct DB_dsp_s **(*plug_get_dsp_list) (void);
+ struct DB_playlist_s **(*plug_get_playlist_list) (void);
struct DB_plugin_s **(*plug_get_list) (void);
- int (*plug_activate) (struct DB_plugin_s *p, int activate);
+ const char **(*plug_get_gui_names) (void);
const char * (*plug_get_decoder_id) (const char *id);
void (*plug_remove_decoder_id) (const char *id);
struct DB_plugin_s *(*plug_get_for_id) (const char *id);
+
// plugin events
void (*plug_trigger_event_trackchange) (DB_playItem_t *from, DB_playItem_t *to);
void (*plug_trigger_event_trackinfochanged) (DB_playItem_t *track);
void (*plug_trigger_event_playlistchanged) (void);
+
// misc utilities
int (*is_local_file) (const char *fname); // returns 1 for local filename, 0 otherwise
+
+ // pcm utilities
+ int (*pcm_convert) (const ddb_waveformat_t * inputfmt, const char *input, const ddb_waveformat_t *outputfmt, char *output, int inputsize);
+
+ // dsp preset management
+ int (*dsp_preset_load) (const char *fname, struct ddb_dsp_context_s **head);
+ int (*dsp_preset_save) (const char *fname, struct ddb_dsp_context_s *head);
+ void (*dsp_preset_free) (struct ddb_dsp_context_s *head);
} DB_functions_t;
enum {
@@ -570,19 +662,22 @@ typedef struct DB_plugin_s {
// plugin version
int16_t version_major;
int16_t version_minor;
- // may be deactivated on failures after load
- int inactive;
- // prevent plugin from being dynamically stopped
- int nostop;
+
+ uint32_t flags; // currently unused
+ uint32_t reserved1;
+ uint32_t reserved2;
+ uint32_t reserved3;
// any of those can be left NULL
// though it's much better to fill them with something useful
const char *id; // id used for serialization and runtime binding
const char *name; // short name
- const char *descr; // short description
- const char *author; // author's name
- const char *email; // author's email
- const char *website; // author's website
+ const char *descr; // short description (what the plugin is doing)
+ const char *copyright; // copyright notice(s), list of developers, links to original works, etc
+ const char *website; // plugin website
+
+ // plugin-specific command interface; can be NULL
+ int (*command) (int cmd, ...);
// start is called to start plugin; can be NULL
int (*start) (void);
@@ -594,6 +689,10 @@ typedef struct DB_plugin_s {
// it is called after all plugin's start method was executed
// can be NULL
int (*connect) (void);
+
+ // opposite of connect, will be called before stop, while all plugins are still
+ // in "started" state
+ int (*disconnect) (void);
// exec_cmdline may be called at any moment when user sends commandline to player
// can be NULL if plugin doesn't support commandline processing
@@ -609,20 +708,54 @@ typedef struct DB_plugin_s {
const char *configdialog;
} DB_plugin_t;
+// file format stuff
+
+// channel mask - combine following flags to tell streamer which channels are
+// present in input/output streams
+enum {
+ DDB_SPEAKER_FRONT_LEFT = 0x1,
+ DDB_SPEAKER_FRONT_RIGHT = 0x2,
+ DDB_SPEAKER_FRONT_CENTER = 0x4,
+ DDB_SPEAKER_LOW_FREQUENCY = 0x8,
+ DDB_SPEAKER_BACK_LEFT = 0x10,
+ DDB_SPEAKER_BACK_RIGHT = 0x20,
+ DDB_SPEAKER_FRONT_LEFT_OF_CENTER = 0x40,
+ DDB_SPEAKER_FRONT_RIGHT_OF_CENTER = 0x80,
+ DDB_SPEAKER_BACK_CENTER = 0x100,
+ DDB_SPEAKER_SIDE_LEFT = 0x200,
+ DDB_SPEAKER_SIDE_RIGHT = 0x400,
+ DDB_SPEAKER_TOP_CENTER = 0x800,
+ DDB_SPEAKER_TOP_FRONT_LEFT = 0x1000,
+ DDB_SPEAKER_TOP_FRONT_CENTER = 0x2000,
+ DDB_SPEAKER_TOP_FRONT_RIGHT = 0x4000,
+ DDB_SPEAKER_TOP_BACK_LEFT = 0x8000,
+ DDB_SPEAKER_TOP_BACK_CENTER = 0x10000,
+ DDB_SPEAKER_TOP_BACK_RIGHT = 0x20000
+};
+
typedef struct DB_fileinfo_s {
struct DB_decoder_s *plugin;
- int bps;
- int channels;
- int samplerate;
+
+ // these parameters should be set in decoder->open
+ ddb_waveformat_t fmt;
+
+ // readpos should be updated to current decoder time (in seconds)
float readpos;
+
+ // this is the (optional) file handle, that can be used by streamer to
+ // request interruption of current read operation
DB_FILE *file;
} DB_fileinfo_t;
+enum {
+ DDB_DECODER_HINT_16BIT = 0x1, // that flag means streamer prefers 16 bit streams for performance reasons
+};
+
// decoder plugin
typedef struct DB_decoder_s {
DB_plugin_t plugin;
- DB_fileinfo_t *(*open) (void);
+ DB_fileinfo_t *(*open) (uint32_t hints);
// init is called to prepare song to be started
int (*init) (DB_fileinfo_t *info, DB_playItem_t *it);
@@ -632,12 +765,7 @@ typedef struct DB_decoder_s {
// read is called by streamer to decode specified number of bytes
// must return number of bytes that were successfully decoded (sample aligned)
-
- // read_int16 must always output 16 bit signed integer samples
- int (*read_int16) (DB_fileinfo_t *info, char *buffer, int size);
-
- // read_float32 must always output 32 bit floating point samples
- int (*read_float32) (DB_fileinfo_t *info, char *buffer, int size);
+ int (*read) (DB_fileinfo_t *info, char *buffer, int nbytes);
int (*seek) (DB_fileinfo_t *info, float seconds);
@@ -660,6 +788,10 @@ typedef struct DB_decoder_s {
// NULL terminated array of all supported extensions
const char **exts;
+ // NULL terminated array of all supported prefixes (UADE support needs that)
+ // e.g. "mod.song_title"
+ const char **prefixes;
+
// NULL terminated array of all file type names
const char **filetypes;
} DB_decoder_t;
@@ -671,8 +803,8 @@ typedef struct DB_output_s {
int (*init) (void);
// free is called if output plugin was changed to another, or unload is about to happen
int (*free) (void);
- // reconfigure output to another samplerate, if supported
- int (*change_rate) (int rate);
+ // reconfigure output to another format
+ int (*setformat) (ddb_waveformat_t *fmt);
// play, stop, pause, unpause are called by deadbeef in response to user
// events, or as part of streaming process
int (*play) (void);
@@ -681,27 +813,65 @@ typedef struct DB_output_s {
int (*unpause) (void);
// one of output_state_t enum values
int (*state) (void);
- // following functions must return output sampling rate, bits per sample and number
- // of channels
- int (*samplerate) (void);
- int (*bitspersample) (void);
- int (*channels) (void);
- // must return 0 for little endian output, or 1 for big endian
- int (*endianness) (void);
// soundcard enumeration (can be NULL)
void (*enum_soundcards) (void (*callback)(const char *name, const char *desc, void*), void *userdata);
+
+ // parameters of current output
+ ddb_waveformat_t fmt;
+
+ // set to 1 if volume control is done internally by plugin
+ int has_volume;
} DB_output_t;
// dsp plugin
+// see also: examples/dsp_template.c in git
+#define DDB_INIT_DSP_CONTEXT(var,type,plug) {\
+ memset(var,0,sizeof(type));\
+ var->ctx.plugin=plug;\
+ var->ctx.enabled=1;\
+}
+
+typedef struct ddb_dsp_context_s {
+ // pointer to DSP plugin which created this context
+ struct DB_dsp_s *plugin;
+
+ // pointer to the next DSP plugin context in the chain
+ struct ddb_dsp_context_s *next;
+
+ // read only flag; set by DB_dsp_t::enable
+ unsigned enabled : 1;
+} ddb_dsp_context_t;
+
typedef struct DB_dsp_s {
DB_plugin_t plugin;
- // process gets called before SRC
- // stereo samples are stored in interleaved format
- // stereo sample is counted as 1 sample
- int (*process_int16) (int16_t *samples, int nsamples, int nch, int bps, int srate);
- void (*reset) (void);
- void (*enable) (int e);
- int (*enabled) (void);
+
+ ddb_dsp_context_t* (*open) (void);
+
+ void (*close) (ddb_dsp_context_t *ctx);
+
+ // samples are always interleaved floating point
+ // returned value is number of output frames (multichannel samples)
+ // plugins are allowed to modify channels, samplerate, channelmask in the fmt structure
+ // buffer size can fit up to maxframes frames
+ // by default ratio=1, and plugins don't need to touch it unless they have to
+ int (*process) (ddb_dsp_context_t *ctx, float *samples, int frames, int maxframes, ddb_waveformat_t *fmt, float *ratio);
+
+ void (*reset) (ddb_dsp_context_t *ctx);
+
+ // num_params can be NULL, to indicate that plugin doesn't expose any params
+ //
+ // if num_params is non-NULL -- get_param_name, set_param and get_param must
+ // all be implemented
+ //
+ // param names are for display-only, and are allowed to contain spaces
+ int (*num_params) (void);
+ const char *(*get_param_name) (int p);
+ void (*set_param) (ddb_dsp_context_t *ctx, int p, const char *val);
+ void (*get_param) (ddb_dsp_context_t *ctx, int p, char *str, int len);
+
+ // config dialog implementation uses set/get param, so they must be
+ // implemented if this is nonzero
+ const char *configdialog;
} DB_dsp_t;
// misc plugin
@@ -717,27 +887,84 @@ typedef struct {
// api is based on stdio
typedef struct DB_vfs_s {
DB_plugin_t plugin;
+
+// capabilities
+ const char **(*get_schemes) (void); // NULL-terminated list of supported schemes, e.g. {"http://", "ftp://", NULL}; can be NULL
+
+ int (*is_streaming) (void); // return 1 if the plugin streaming data over slow connection, e.g. http; plugins will avoid scanning entire files if this is the case
+
+ int (*is_container) (const char *fname); // should return 1 if this plugin can parse specified file
+
+// this is an evil hack to interrupt frozen vfs_curl streams
+// FIXME: pass it through command API
+ void (*abort) (DB_FILE *stream);
+
+// file access, follows stdio API with few extension
DB_FILE* (*open) (const char *fname);
- void (*set_track) (DB_FILE *f, DB_playItem_t *it);
void (*close) (DB_FILE *f);
size_t (*read) (void *ptr, size_t size, size_t nmemb, DB_FILE *stream);
int (*seek) (DB_FILE *stream, int64_t offset, int whence);
int64_t (*tell) (DB_FILE *stream);
void (*rewind) (DB_FILE *stream);
- int64_t (*getlength)(DB_FILE *stream);
+ int64_t (*getlength) (DB_FILE *stream);
+
+ // should return mime-type of a stream, if known; can be NULL
const char * (*get_content_type) (DB_FILE *stream);
- void (*abort) (DB_FILE *stream);
- const char **scheme_names; // NULL-terminated list of supported schemes, e.g. {"http", "ftp", NULL}
- unsigned streaming : 1;
+
+ // associates stream with a track, to allow dynamic metadata updating, like
+ // in icy protocol
+ void (*set_track) (DB_FILE *f, DB_playItem_t *it);
+
+// folder access, follows dirent API, and uses dirent data structures
+ int (*scandir) (const char *dir, struct dirent ***namelist, int (*selector) (const struct dirent *), int (*cmp) (const struct dirent **, const struct dirent **));
} DB_vfs_t;
// gui plugin
-// implements pretty much anything it wants
-// works mostly like misc plugin, except we need separate type for that
+// only one gui plugin can be running at the same time
+// should provide GUI services to other plugins
+
+// this structure represents a gui dialog with callbacks to set/get params
+// documentation should be available here:
+// https://sourceforge.net/apps/mediawiki/deadbeef/index.php?title=Development:Gui_Script
+typedef struct {
+ const char *title;
+ const char *layout;
+ void (*set_param) (const char *key, const char *value);
+ void (*get_param) (const char *key, char *value, int len, const char *def);
+} ddb_dialog_t;
+
+enum {
+ ddb_button_ok,
+ ddb_button_cancel,
+ ddb_button_close,
+ ddb_button_apply,
+ ddb_button_yes,
+ ddb_button_no,
+ ddb_button_max,
+};
+
typedef struct DB_gui_s {
DB_plugin_t plugin;
+
+ // returns response code (ddb_button_*)
+ // buttons is a bitset, e.g. (1<<ddb_button_ok)|(1<<ddb_button_cancel)
+ int (*run_dialog) (ddb_dialog_t *dlg, uint32_t buttons, int (*callback)(int button, void *ctx), void *ctx);
} DB_gui_t;
+// playlist plugin
+typedef struct DB_playlist_s {
+ DB_plugin_t plugin;
+
+ DB_playItem_t * (*load) (DB_playItem_t *after, const char *fname, int *pabort, int (*cb)(DB_playItem_t *it, void *data), void *user_data);
+
+ // will save items from first to last (inclusive)
+ // format is determined by extension
+ // playlist is protected from changes during the call
+ int (*save) (const char *fname, DB_playItem_t *first, DB_playItem_t *last);
+
+ const char **extensions; // NULL-terminated list of supported file extensions, e.g. {"m3u", "pls", NULL}
+} DB_playlist_t;
+
#ifdef __cplusplus
}
#endif
diff --git a/dsppreset.c b/dsppreset.c
new file mode 100644
index 00000000..840a7b29
--- /dev/null
+++ b/dsppreset.c
@@ -0,0 +1,140 @@
+/*
+ DeaDBeeF - ultimate music player for GNU/Linux systems with X11
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "deadbeef.h"
+#include "plugins.h"
+
+void
+dsp_preset_free (ddb_dsp_context_t *head) {
+ while (head) {
+ ddb_dsp_context_t *next = head->next;
+ head->plugin->close (head);
+ head = next;
+ }
+}
+
+int
+dsp_preset_load (const char *fname, ddb_dsp_context_t **head) {
+ if (!head) {
+ return -1;
+ }
+ int err = 1;
+ FILE *fp = fopen (fname, "rt");
+ if (!fp) {
+ return -1;
+ }
+
+ ddb_dsp_context_t *tail = NULL;
+
+ char temp[100];
+ for (;;) {
+ // plugin {
+ int err = fscanf (fp, "%100s {\n", temp);
+ if (err == EOF) {
+ break;
+ }
+ else if (1 != err) {
+ fprintf (stderr, "error plugin name\n");
+ goto error;
+ }
+
+ DB_dsp_t *plug = (DB_dsp_t *)plug_get_for_id (temp);
+ if (!plug) {
+ fprintf (stderr, "ddb_dsp_preset_load: plugin %s not found. preset will not be loaded\n", temp);
+ goto error;
+ }
+ ddb_dsp_context_t *ctx = plug->open ();
+ if (!ctx) {
+ fprintf (stderr, "ddb_dsp_preset_load: failed to open ctxance of plugin %s\n", temp);
+ goto error;
+ }
+
+ if (tail) {
+ tail->next = ctx;
+ tail = ctx;
+ }
+ else {
+ tail = *head = ctx;
+ }
+
+ int n = 0;
+ for (;;) {
+ char value[1000];
+ if (!fgets (temp, sizeof (temp), fp)) {
+ fprintf (stderr, "unexpected eof while reading plugin params\n");
+ goto error;
+ }
+ if (!strcmp (temp, "}\n")) {
+ break;
+ }
+ else if (1 != sscanf (temp, "\t%1000[^\n]\n", value)) {
+ fprintf (stderr, "error loading param %d\n", n);
+ goto error;
+ }
+ if (plug->num_params) {
+ plug->set_param (ctx, n, value);
+ }
+ n++;
+ }
+ }
+
+ err = 0;
+error:
+ if (err) {
+ fprintf (stderr, "error loading %s\n", fname);
+ }
+ if (fp) {
+ fclose (fp);
+ }
+ if (err && *head) {
+ dsp_preset_free (*head);
+ *head = NULL;
+ }
+ return err ? -1 : 0;
+}
+
+int
+dsp_preset_save (const char *path, ddb_dsp_context_t *head) {
+ FILE *fp = fopen (path, "w+t");
+ if (!fp) {
+ return -1;
+ }
+
+ ddb_dsp_context_t *ctx = head;
+ while (ctx) {
+ fprintf (fp, "%s {\n", ctx->plugin->plugin.id);
+ if (ctx->plugin->num_params) {
+ int n = ctx->plugin->num_params ();
+ int i;
+ for (i = 0; i < n; i++) {
+ char v[1000];
+ ctx->plugin->get_param (ctx, i, v, sizeof (v));
+ fprintf (fp, "\t%s\n", v);
+ }
+ }
+ fprintf (fp, "}\n");
+ ctx = ctx->next;
+ }
+
+ fclose (fp);
+ return 0;
+}
diff --git a/plugins/supereq/supereq.h b/dsppreset.h
index 32298ef1..37354f9f 100644
--- a/plugins/supereq/supereq.h
+++ b/dsppreset.h
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@@ -16,16 +16,16 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+#ifndef __DSPPRESET_H
+#define __DSPPRESET_H
-#ifndef __SUPEREQ_H
-#define __SUPEREQ_H
+void
+dsp_preset_free (ddb_dsp_context_t *head);
-typedef struct DB_supereq_dsp_s {
- DB_dsp_t dsp;
- float (*get_band) (int band);
- void (*set_band) (int band, float value);
- float (*get_preamp) (void);
- void (*set_preamp) (float value);
-} DB_supereq_dsp_t;
+int
+dsp_preset_load (const char *fname, ddb_dsp_context_t **head);
+
+int
+dsp_preset_save (const char *path, ddb_dsp_context_t *head);
#endif
diff --git a/decoder_template.c b/examples/decoder_template.c
index 1f529555..b6e6585b 100644
--- a/decoder_template.c
+++ b/examples/decoder_template.c
@@ -1,26 +1,11 @@
-/*
- DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-*/
-
// this is a decoder plugin skeleton
// use to create new decoder plugins
-#include "../../deadbeef.h"
+#include <stdlib.h>
+#include <string.h>
+#include <deadbeef/deadbeef.h>
+
+#define trace(...) { fprintf(stderr, __VA_ARGS__); }
static DB_decoder_t plugin;
static DB_functions_t *deadbeef;
@@ -37,7 +22,7 @@ static const char *filetypes[] = { "example", NULL }; // e.g. MP3
// allocate codec control structure
static DB_fileinfo_t *
-example_open (void) {
+example_open (uint32_t hints) {
DB_fileinfo_t *_info = malloc (sizeof (example_info_t));
example_info_t *info = (example_info_t *)_info;
memset (info, 0, sizeof (example_info_t));
@@ -50,9 +35,14 @@ static int
example_init (DB_fileinfo_t *_info, DB_playItem_t *it) {
example_info_t *info = (example_info_t *)_info;
- _info->bps = ;
- _info->channels = ;
- _info->samplerate = ;
+ // take this parameters from your input file
+ // we set constants for clarity sake
+ _info->fmt.bps = 16;
+ _info->fmt.channels = 2;
+ _info->fmt.samplerate = 44100;
+ for (int i = 0; i < _info->fmt.channels; i++) {
+ _info->fmt.channelmask |= 1 << i;
+ }
_info->readpos = 0;
_info->plugin = &plugin;
@@ -63,6 +53,7 @@ example_init (DB_fileinfo_t *_info, DB_playItem_t *it) {
}
else {
info->startsample = 0;
+ int TOTALSAMPLES = 1000; // calculate from file
info->endsample = TOTALSAMPLES-1;
}
return 0;
@@ -82,9 +73,9 @@ example_free (DB_fileinfo_t *_info) {
// return number of decoded bytes
// or 0 on EOF/error
static int
-example_read_int16 (DB_fileinfo_t *_info, char *bytes, int size) {
+example_read (DB_fileinfo_t *_info, char *bytes, int size) {
example_info_t *info = (example_info_t *)_info;
- info->currentsample += size / (_info->channels * _info->bps/8);
+ info->currentsample += size / (_info->fmt.channels * _info->fmt.bps/8);
return size;
}
@@ -96,7 +87,7 @@ example_seek_sample (DB_fileinfo_t *_info, int sample) {
example_info_t *info = (example_info_t *)_info;
info->currentsample = sample + info->startsample;
- _info->readpos = (float)sample / _info->samplerate;
+ _info->readpos = (float)sample / _info->fmt.samplerate;
return 0;
}
@@ -105,7 +96,7 @@ example_seek_sample (DB_fileinfo_t *_info, int sample) {
// return -1 on failure
static int
example_seek (DB_fileinfo_t *_info, float time) {
- return example_seek_sample (_info, time * _info->samplerate);
+ return example_seek_sample (_info, time * _info->fmt.samplerate);
}
// read information from the track
@@ -116,20 +107,13 @@ example_seek (DB_fileinfo_t *_info, float time) {
static DB_playItem_t *
example_insert (DB_playItem_t *after, const char *fname) {
-// example code (won't compile):
-
// open file
DB_FILE *fp = deadbeef->fopen (fname);
if (!fp) {
trace ("example: failed to fopen %s\n", fname);
return NULL;
}
- // setup decoder to use vfs
- decoder_callbacks_t cb = {
- open = vfs_open_wrapper,
- .... etc ....
- }
- decoder_info_t *di = decoder_open_callbacks (&cb);
+ decoder_info_t *di = decoder_open ();
if (!di) {
trace ("example: failed to init decoder\n");
return NULL;
@@ -220,8 +204,7 @@ static DB_decoder_t plugin = {
.plugin.stop = example_stop,
.init = example_init,
.free = example_free,
- .read_int16 = example_read_int16,
-// .read_float32 = example_read_float32,
+ .read = example_read,
.seek = example_seek,
.seek_sample = example_seek_sample,
.insert = example_insert,
diff --git a/examples/dsp_template.c b/examples/dsp_template.c
new file mode 100644
index 00000000..24b53759
--- /dev/null
+++ b/examples/dsp_template.c
@@ -0,0 +1,133 @@
+// this is a dsp plugin skeleton/example
+// use to create new dsp plugins
+
+// usage:
+// 1. copy to your plugin folder
+// 2. s/example/plugname/g
+// 3. s/EXAMPLE/PLUGNAME/g
+
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <deadbeef/deadbeef.h>
+
+enum {
+ EXAMPLE_PARAM_LEVEL,
+ EXAMPLE_PARAM_COUNT
+};
+
+static DB_functions_t *deadbeef;
+static DB_dsp_t plugin;
+
+typedef struct {
+ ddb_dsp_context_t ctx;
+ // instance-specific variables here
+ float level; // this is example
+} ddb_example_t;
+
+ddb_dsp_context_t*
+example_open (void) {
+ ddb_example_t *example = malloc (sizeof (ddb_example_t));
+ DDB_INIT_DSP_CONTEXT (example,ddb_example_t,&plugin);
+
+ // initialize
+ example->level = 0.5;
+
+ return (ddb_dsp_context_t *)example;
+}
+
+void
+example_close (ddb_dsp_context_t *ctx) {
+ ddb_example_t *example = (ddb_example_t *)ctx;
+
+ // free instance-specific allocations
+
+ free (example);
+}
+
+void
+example_reset (ddb_dsp_context_t *ctx) {
+ // use this method to flush dsp buffers, reset filters, etc
+}
+
+int
+example_process (ddb_dsp_context_t *ctx, float *samples, int nframes, ddb_waveformat_t *fmt) {
+ ddb_example_t *example = (ddb_example_t *)ctx;
+ for (int i = 0; i < nframes*fmt->channels; i++) {
+ samples[i] *= example->level;
+ }
+ return nframes;
+}
+
+const char *
+example_get_param_name (int p) {
+ switch (p) {
+ case EXAMPLE_PARAM_LEVEL:
+ return "Volume level";
+ default:
+ fprintf (stderr, "example_param_name: invalid param index (%d)\n", p);
+ }
+ return NULL;
+}
+
+int
+example_num_params (void) {
+ return EXAMPLE_PARAM_COUNT;
+}
+
+void
+example_set_param (ddb_dsp_context_t *ctx, int p, const char *val) {
+ ddb_example_t *example = (ddb_example_t *)ctx;
+ switch (p) {
+ case EXAMPLE_PARAM_LEVEL:
+ example->level = atof (val);
+ break;
+ default:
+ fprintf (stderr, "example_param: invalid param index (%d)\n", p);
+ }
+}
+
+void
+example_get_param (ddb_dsp_context_t *ctx, int p, char *val, int sz) {
+ ddb_example_t *example = (ddb_example_t *)ctx;
+ switch (p) {
+ case EXAMPLE_PARAM_LEVEL:
+ snprintf (val, sz, "%f", example->level);
+ break;
+ default:
+ fprintf (stderr, "example_get_param: invalid param index (%d)\n", p);
+ }
+}
+
+static const char settings_dlg[] =
+ "property \"Volume Level\" spinbtn[0,2,0.1] 0 0.5;\n"
+;
+
+static DB_dsp_t plugin = {
+ .plugin.api_vmajor = DB_API_VERSION_MAJOR,
+ .plugin.api_vminor = DB_API_VERSION_MINOR,
+ .open = example_open,
+ .close = example_close,
+ .process = example_process,
+ .plugin.version_major = 0,
+ .plugin.version_minor = 1,
+ .plugin.type = DB_PLUGIN_DSP,
+ .plugin.id = "example",
+ .plugin.name = "example",
+ .plugin.descr = "example DSP Plugin",
+ .plugin.author = "",
+ .plugin.email = "",
+ .plugin.website = "",
+ .num_params = example_num_params,
+ .get_param_name = example_get_param_name,
+ .set_param = example_set_param,
+ .get_param = example_get_param,
+ .reset = example_reset,
+ .configdialog = settings_dlg,
+};
+
+DB_plugin_t *
+example_load (DB_functions_t *f) {
+ deadbeef = f;
+ return &plugin.plugin;
+}
diff --git a/insertlicense.sh b/insertlicense.sh
deleted file mode 100755
index b046a61c..00000000
--- a/insertlicense.sh
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/bin/bash
-echo "IMPORTANT: Hit C-c if you forgot to backup/commit stuff!!!"
-read
-ls *.c *.h *.cpp | while read i; do
- if [ "$i" == "deadbeef.h" ] || [ "$i" == "config.h" ] || grep --silent "DO NOT EDIT" "$i" ; then
- echo "skipping $i (blacklist)"
- elif grep --silent "DeaDBeeF - ultimate music player for GNU/Linux systems with X11" "$i" ; then
- if grep --silent "version 3 of the License" "$i" ; then
- echo "changing $i to gpl2"
- sed -i 's/version 3 of the License/version 2 of the License/' "$i"
- else
- echo "skipping $i (already has license)"
- fi
- else
- echo "adding license text to $i"
- cat shortlicense >/tmp/deadbeef.lic.tmp
- cat "$i" >>/tmp/deadbeef.lic.tmp
- mv /tmp/deadbeef.lic.tmp "$i"
- fi
-done
diff --git a/junklib.c b/junklib.c
index 254f9942..0ed85419 100644
--- a/junklib.c
+++ b/junklib.c
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -23,8 +23,18 @@
#include <stdlib.h>
#include <string.h>
#if HAVE_ICONV
-#define LIBICONV_PLUG
-#include <iconv.h>
+ #define LIBICONV_PLUG
+ #include <iconv.h>
+#elif HAVE_ICU
+ #warning icu
+ #include <unicode/utypes.h>
+ #include <unicode/ucnv.h>
+#else
+ #define DDB_RECODE
+ #include "ConvertUTF/ConvertUTF.h"
+uint16_t sj_to_unicode[] = {
+ #include "sj_to_unicode.h"
+};
#endif
#include <limits.h>
#include <errno.h>
@@ -41,7 +51,7 @@
#define MAX_ID3V2_FRAME_SIZE 100000
#define MAX_ID3V2_APIC_FRAME_SIZE 2000000
-#define UTF8 "utf-8"
+#define UTF8_STR "utf-8"
//#define trace(...) { fprintf(stderr, __VA_ARGS__); }
#define trace(fmt,...)
@@ -60,30 +70,63 @@ enum {
MAP_APEV2 = 4
};
+// map of known id3v2 and apev2 text tags
+// order: ddb, id3-2.3, 2.4, 2.2, apev2
static const char *frame_mapping[] = {
+// these tags will be displayed and edited uniformly for all tag types
"artist", "TPE1", "TPE1", "TP1", "Artist",
- "band", "TPE2", "TPE2", "TP2", "Album artist",
"disc", "TPOS", "TPOS", "TPA", "Disc",
"title", "TIT2", "TIT2", "TT2", "Title",
"album", "TALB", "TALB", "TAL", "Album",
"copyright", "TCOP", "TCOP", "TCO", "Copyright",
"genre", "TCON", "TCON", "TCO", "Genre",
- "vendor", "TENC", "TENC", "TEN", "ENCODER",
"composer", "TCOM", "TCOM", "TCM", "Composer",
- "year", "TYER", "TDRC", "TYE", "Year",
- "track", "TRCK", "TRCK", "TRK", "Track",
- "comment", NULL, NULL, NULL, "Comment",
- "cuesheet", NULL, NULL, NULL, "Cuesheet",
- "performer", "TXXX", "TXXX", "TXX", "Performer",
-// "band", "TXXX", "TXXX", "TXX", "Album artist", // fb2k only
-// "date", "TXXX", "TXXX", "TXX", "Date", // fb2k only
+ "year", "TYER", "TDRC", "TYE", "Year", // NOTE: TDRC and TYER are slightly different, and are converted on read/write
+ "track", "TRCK", "TRCK", "TRK", "Track", // NOTE: this is special case when writing id3v2
+// misc id3v2 fields
+// these might or might not have appropriate fields in every tag type
+ "BAND", "TPE2", "TPE2", "TP2", NULL,
+ "ENCODER", "TENC", "TENC", "TEN", NULL,
+ "BEATS_PER_MINUTE", "TBPM", "TBPM", "TBP", NULL,
+ "PLAYLIST_DELAY", "TDLY", "TDLY", "TDY", NULL,
+ "TEXT_WRITERS", "TEXT", "TEXT", "TXT", NULL,
+ "FILE_TYPE", "TFLT", "TFLT", "TFT", NULL,
+ "CONTENT_GROUP_DESCRIPTION", "TIT1", "TIT1", "TT1", NULL,
+ "SUBTITLE", "TIT3", "TIT3", "TT3", NULL,
+ "INITIAL_KEY", "TKEY", "TKEY", "TKE", NULL,
+ "LANGUAGES", "TLAN", "TLAN", "TLA", NULL,
+ "LENGTH", "TLEN", "TLEN", "TLE", NULL,
+ "MEDIA_TYPE", "TMED", "TMED", "TMT", NULL,
+ "ORIGINAL_ALBUM_TITLE", "TOAL", "TOAL", "TOT", NULL,
+ "ORIGINAL_FILENAME", "TOFN", "TOFN", "TOF", NULL,
+ "ORIGINAL_TEXT_WRITERS", "TOLY", "TOLY", "TOL", NULL,
+ "ORIGINAL_ARTISTS", "TOPE", "TOPE", "TOA", NULL,
+ "FILE_OWNER", "TOWN", "TOWN", NULL, NULL,
+ "PERFORMER_REFINEMENT", "TPE3", "TPE3", "TP3", NULL,
+ "MODIFIED_BY", "TPE4", "TPE4", "TP4", NULL,
+ "PUBLISHER", "TPUB", "TPUB", "TPB", NULL,
+ "INTERNET_RADIO_STATION_NAME", "TRSN", "TRSN", NULL, NULL,
+ "INTERNET_RADIO_STATION_OWNER", "TRSO", "TRSO", NULL, NULL,
+ "ISRC", "TSRC", "TSRC", NULL, NULL,
+ "ENCODING_SOFTWARE_HARDWARE", "TSSE", "TSSE", "TSS", NULL,
+ "RECORDING_TIME", NULL, "TDRC", NULL, NULL,
+ "RELEASE_TIME", NULL, "TDRL", NULL, NULL,
+ "TAGGING_TIME", NULL, "TDTG", NULL, NULL,
+ "ALBUM_SORT_ORDER", NULL, "TSOA", NULL, NULL,
+ "PERFORMER_SORT_ORDER", NULL, "TSOP", NULL, NULL,
+ "TITLE_SORT_ORDER", NULL, "TSOT", NULL, NULL,
+ "SIZE", "TSIZ", NULL, "TSI", NULL,
+ "RECORDING_DATES", "TRDA", NULL, "TRD", NULL,
+ "INVOLVED_PEOPLE_LIST", NULL, "TIPL", NULL, NULL,
+ "MUSICIAN_CREDITS_LIST", NULL, "TMCL", NULL, NULL,
+ "ENCODING_TIME", NULL, "TDEN", NULL, NULL,
+ "ORIGINAL_RELEASE_TIME", NULL, "TDOR", NULL, NULL,
+ "MOOD", NULL, "TMOO", NULL, NULL,
+ "PRODUCED_NOTICE", NULL, "TPRO", NULL, NULL,
NULL
};
static const char *txx_mapping[] = {
- "performer", "performer",
- "album artist", "albumartist",
- "date", "date",
"replaygain_album_gain", NULL,
"replaygain_album_peak", NULL,
"replaygain_track_gain", NULL,
@@ -152,8 +195,261 @@ extract_f32 (unsigned char *buf) {
return f;
}
+#ifdef DDB_RECODE
+
+static int
+cp1251_to_utf8(const uint8_t *in, int inlen, uint8_t *out, int outlen){
+ int len = 0;
+ while (inlen > 0 && outlen-len > 2) {
+ uint8_t c=*in;
+ if (c>=192 && c<=239) {
+ *out++ = 208;
+ *out++ = c - 48;
+ len += 2;
+ }
+ else if (c>239) {
+ *out++ = 209;
+ *out++ = c - 112;
+ len += 2;
+ }
+ else if (c==184) {
+ *out++ = 0xd1;
+ *out++ = 0x91;
+ len += 2;
+ }
+ else if (c==168) {
+ *out++ = 208;
+ *out++ = 129;
+ len += 2;
+ }
+ else {
+ *out++ = c;
+ len++;
+ }
+ in++;
+ inlen--;
+ }
+ *out = 0;
+ return len;
+}
+
+static int
+iso8859_1_to_utf8(const uint8_t *in, int inlen, uint8_t *out, int outlen){
+ int len = 0;
+ while (inlen > 0 && outlen-len > 2) {
+ uint8_t c=*in;
+
+ switch (c) {
+ case 192 ... 255:
+ *out++ = 195;
+ *out++ = c - 64;
+ len += 2;
+ break;
+ case 160 ... 191:
+ *out++ = 0xc2;
+ *out++ = c;
+ len += 2;
+ break;
+#define CONV2(x,y,z) case x:\
+ *out++ = y;\
+ *out++ = z;\
+ len += 2;\
+ break;
+#define CONV3(x,y,z,w) case x:\
+ *out++ = y;\
+ *out++ = z;\
+ *out++ = w;\
+ len += 3;\
+ break;
+ CONV2(0x9f,0xc5,0xb8);
+ CONV2(0x9e,0xc5,0xbe);
+ CONV3(0x9d,0xef,0xbf,0xbd);
+ CONV3(0x80,0xe2,0x82,0xac);
+ CONV3(0x81,0xef,0xbf,0xbd);
+ CONV3(0x82,0xe2,0x80,0x9a);
+ CONV2(0x83,0xc6,0x92);
+ CONV3(0x84,0xe2,0x80,0x9e);
+ CONV3(0x85,0xe2,0x80,0xa6);
+ CONV3(0x86,0xe2,0x80,0xa0);
+ CONV3(0x87,0xe2,0x80,0xa1);
+ CONV2(0x88,0xcb,0x86);
+ CONV3(0x89,0xe2,0x80,0xb0);
+ CONV2(0x8a,0xc5,0xa0);
+ CONV3(0x8b,0xe2,0x80,0xb9);
+ CONV2(0x8c,0xc5,0x92);
+ CONV3(0x8d,0xef,0xbf,0xbd);
+ CONV2(0x8e,0xc5,0xbd);
+ CONV3(0x8f,0xef,0xbf,0xbd);
+ CONV3(0x90,0xef,0xbf,0xbd);
+ CONV3(0x91,0xe2,0x80,0x98);
+ CONV3(0x92,0xe2,0x80,0x99);
+ CONV3(0x93,0xe2,0x80,0x9c);
+ CONV3(0x94,0xe2,0x80,0x9d);
+ CONV3(0x95,0xe2,0x80,0xa2);
+ CONV3(0x96,0xe2,0x80,0x93);
+ CONV3(0x97,0xe2,0x80,0x94);
+ CONV2(0x98,0xcb,0x9c);
+ CONV3(0x99,0xe2,0x84,0xa2);
+ CONV2(0x9a,0xc5,0xa1);
+ CONV3(0x9b,0xe2,0x80,0xba);
+ CONV2(0x9c,0xc5,0x93);
+#undef CONV2
+#undef CONV3
+ default:
+ if (c >= 127) {
+ trace ("iso8859 char: %d\n", c);
+ }
+ *out++ = c;
+ len++;
+ break;
+ }
+
+ in++;
+ inlen--;
+ }
+ *out = 0;
+ return len;
+}
+
+int ddb_iconv (const char *cs_out, const char *cs_in, char *out, int outlen, const char *in, int inlen) {
+ int len = -1;
+ *out = 0;
+ if (inlen==0) {
+ return 0;
+ }
+ // to utf8 branch
+ if (!strcmp (cs_out, UTF8_STR)) {
+ if (!strcmp (cs_in, UTF8_STR)) {
+ memcpy (out, in, inlen);
+ out[inlen] = 0;
+ int valid = u8_valid (out, inlen, NULL);
+ if (valid) {
+ len = inlen;
+ }
+ }
+ else if (!strcasecmp (cs_in, "cp1251")) {
+ len = cp1251_to_utf8 (in, inlen, out, outlen);
+ }
+ else if (!strcasecmp (cs_in, "iso8859-1")) {
+ len = iso8859_1_to_utf8 (in, inlen, out, outlen);
+ }
+ else if (!strcasecmp (cs_in, "UTF-16LE") || !strcasecmp (cs_in, "UCS-2LE")) {
+ char *target = out;
+ ConversionResult result = ConvertUTF16toUTF8 ((const UTF16**)&in, (const UTF16*)(in + inlen), (UTF8**)&target, (UTF8*)(out + outlen), strictConversion);
+ if (result == conversionOK) {
+ *target = 0;
+ len = target - out;
+ }
+ }
+ else if (!strcasecmp (cs_in, "UTF-16BE") || !strcasecmp (cs_in, "UCS-2BE")) {
+ assert (0);
+ // convert to big endian
+ char temp[inlen];
+ for (int i = 0; i < inlen; i += 2) {
+ temp[i] = in[i+1];
+ temp[i+1] = in[i];
+ }
+ char *target = out;
+ char *src = temp;
+ ConversionResult result = ConvertUTF16toUTF8 ((const UTF16**)&src, (const UTF16*)(temp + inlen), (UTF8**)&target, (UTF8*)(out + outlen), strictConversion);
+ if (result == conversionOK) {
+ *target = 0;
+ len = target - out;
+ }
+ }
+ else if (!strcasecmp (cs_in, "SHIFT-JIS")) {
+ int len = 0;
+ while (inlen > 0 && len < outlen) {
+ if (*in > 0) {
+ *out++ = *in++;
+ inlen--;
+ len++;
+ }
+ else if (inlen < 2) {
+ return -1;
+ }
+ else {
+ // find character in table
+ uint16_t c = (((uint8_t*)in)[0] << 8) | ((uint8_t*)in)[1];
+ int i;
+ for (i = 0; sj_to_unicode[i]; i += 2) {
+ if (c == sj_to_unicode[i]) {
+ break;
+ }
+ }
+ if (sj_to_unicode[i]) {
+ // slow conversion!
+ char unicode_val[2] = { (sj_to_unicode[i+1] & 0xff00) >> 8, sj_to_unicode[i+1] & 0xff };
+ char utf8_val[5];
+ char *src = unicode_val, *dst = utf8_val;
+
+ ConversionResult res = ConvertUTF16toUTF8 ((const UTF16**)&src, (const UTF16 *)(src+2), (UTF8**)&dst, dst+5, strictConversion);
+ if (res == conversionOK) {
+ if (src - utf8_val < outlen-len) {
+ memcpy (out, utf8_val, src - utf8_val);
+ out += src - utf8_val;
+ len += src - utf8_val;
+ inlen -= 2;
+ in += 2;
+ }
+ else {
+ return -1;
+ }
+ }
+ else {
+ return -1;
+ }
+ }
+ else {
+ return -1; // error
+ }
+ }
+ }
+ }
+ else {
+ fprintf (stderr, "invalid conversion request: %s -> %s\n", cs_in, cs_out);
+ }
+ }
+ else if (!strcmp (cs_in, UTF8_STR)) {
+ if (!strcasecmp (cs_out, "UTF-16LE") || !strcasecmp (cs_out, "UCS-2LE")) {
+ char *target = out;
+ ConversionResult result = ConvertUTF8toUTF16 ((const UTF8**)&in, (const UTF8*)(in + inlen), (UTF16**)&target, (UTF16*)(out + outlen), strictConversion);
+ if (result == conversionOK) {
+ *target = 0;
+ *(target+1) = 0;
+ len = target - out;
+ }
+ }
+ else if (!strcasecmp (cs_out, "UTF-16BE") || !strcasecmp (cs_out, "UCS-2BE")) {
+ assert (0);
+ char temp[outlen];
+ char *target = temp;
+ const char *src = in;
+ ConversionResult result = ConvertUTF16toUTF8 ((const UTF16**)&src, (const UTF16*)(src + inlen), (UTF8**)&target, (UTF8*)(target + outlen), strictConversion);
+ if (result == conversionOK) {
+ len = target - temp;
+ // convert to big endian
+ for (int i = 0; i < len; i += 2) {
+ out[i] = temp[i+1];
+ out[i+1] = temp[i];
+ }
+ }
+ }
+ else {
+ fprintf (stderr, "invalid conversion request: %s -> %s\n", cs_in, cs_out);
+ }
+ }
+ else {
+ fprintf (stderr, "invalid conversion request: %s -> %s\n", cs_in, cs_out);
+ }
+ trace ("\033[0;31mddb_iconv: %s -> %s, in: %s, out: %s\033[37;0m\n", cs_in, cs_out, in, out);
+ return len;
+}
+#endif
+
int
junk_iconv (const char *in, int inlen, char *out, int outlen, const char *cs_in, const char *cs_out) {
+// NOTE: this function must support utf8->utf8 conversion, used for validation
#if HAVE_ICONV
iconv_t cd = iconv_open (cs_out, cs_in);
if (cd == (iconv_t)-1) {
@@ -181,9 +477,16 @@ junk_iconv (const char *in, int inlen, char *out, int outlen, const char *cs_in,
}
//trace ("iconv out: %s (len=%d)\n", out, pout - out);
return pout - out;
-#elif TARGET_ANDROID
- // TODO: android charset conversion
- return 0;
+#elif defined(HAVE_ICU)
+ int status = 0;
+ trace ("ICU convert from %s to %s input %s\n", cs_in, cs_out, in);
+ int32_t len = ucnv_convert (cs_out, cs_in, out, outlen, in, inlen, &status);
+ out[len] = 0;
+ trace ("ICU out: %s\n", out);
+ return len;
+#else
+ int len = ddb_iconv (cs_out, cs_in, out, outlen, in, inlen);
+ return len;
#endif
}
@@ -373,17 +676,19 @@ convstr_id3v2 (int version, uint8_t encoding, const unsigned char* str, int sz)
// detect encoding
if (version == 4 && encoding == 2) {
- trace ("utf16be\n");
enc = "UTF-16BE";
}
else if (version == 4 && encoding == 3) {
- enc = UTF8;
+ enc = UTF8_STR;
}
else if (encoding == 0) {
// hack to add limited cp1251 recoding support
if (can_be_russian (str)) {
enc = "cp1251";
}
+ else {
+ enc = "iso8859-1";
+ }
}
else if (encoding != 1 && !(version == 4 && encoding == 3)){
return NULL; // invalid encoding
@@ -410,40 +715,31 @@ convstr_id3v2 (int version, uint8_t encoding, const unsigned char* str, int sz)
}
}
else {
- trace ("utf16\n");
enc = "UTF-16";
}
}
- else if (encoding == 0) {
- // hack to add limited cp1251 recoding support
- if (can_be_russian (str)) {
- enc = "cp1251";
- }
- else {
- enc = "iso8859-1";
- }
- }
+
+ trace ("encoding: %s\n", enc);
int converted_sz = 0;
- if ((converted_sz = junk_iconv (str, sz, out, sizeof (out), enc, UTF8)) < 0) {
+ if ((converted_sz = junk_iconv (str, sz, out, sizeof (out), enc, UTF8_STR)) < 0) {
return NULL;
}
- else {
- int n;
- for (n = 0; n < converted_sz; n++) {
- if (out[n] == 0 && n != converted_sz-1) {
- out[n] = '\n';
- }
+// trace ("%s -> %s\n", str, out);
+ int n;
+ for (n = 0; n < converted_sz; n++) {
+ if (out[n] == 0 && n != converted_sz-1) {
+ out[n] = '\n';
}
- // trim trailing linebreaks
- for (n = converted_sz-2; n >= 0; n--) {
- if (out[n] == '\n') {
- out[n] = 0;
- }
- else {
- break;
- }
+ }
+ // trim trailing linebreaks
+ for (n = converted_sz-2; n >= 0; n--) {
+ if (out[n] == '\n') {
+ out[n] = 0;
+ }
+ else {
+ break;
}
}
return strdup (out);
@@ -463,16 +759,18 @@ convstr_id3v1 (const char* str, int sz) {
return out;
}
- // check for utf8 (hack)
- if (junk_iconv (str, sz, out, sizeof (out), UTF8, UTF8) > 0) {
- return out;
+ // check for valid utf8
+ int valid = u8_valid (str, sz, NULL);
+ if (valid) {
+ return str;
}
const char *enc = "iso8859-1";
if (can_be_russian (str)) {
enc = "cp1251";
}
- if (junk_iconv (str, sz, out, sizeof (out), enc, UTF8) > 0) {
+ int len = junk_iconv (str, sz, out, sizeof (out), enc, UTF8_STR);
+ if (len >= 0) {
return out;
}
return NULL;
@@ -539,14 +837,11 @@ junk_id3v1_read (playItem_t *it, DB_FILE *fp) {
// "RX" = "Remix" (id3v2)
if (genreid == 0xff) {
- genre = "None";
+ //genre = "None";
}
else if (genreid <= 147) {
genre = junk_genretbl[genreid];
}
- else {
- genre = "";
- }
// add meta
// trace ("%s - %s - %s - %s - %s - %s\n", title, artist, album, year, comment, genre);
@@ -565,7 +860,7 @@ junk_id3v1_read (playItem_t *it, DB_FILE *fp) {
if (*comment) {
pl_add_meta (it, "comment", convstr_id3v1 (comment, strlen (comment)));
}
- if (*genre) {
+ if (genre && *genre) {
pl_add_meta (it, "genre", convstr_id3v1 (genre, strlen (genre)));
}
if (tracknum != 0) {
@@ -598,7 +893,7 @@ junk_id3v1_write (FILE *fp, playItem_t *it) {
meta = pl_find_meta (it, name);\
if (meta) {\
char temp[1000];\
- int l = junk_iconv (meta, strlen (meta), temp, sizeof (temp), UTF8, "ASCII");\
+ int l = junk_iconv (meta, strlen (meta), temp, sizeof (temp), UTF8_STR, "ASCII");\
if (l == -1) {\
memset (store, 0, sizeof (store));\
}\
@@ -812,21 +1107,25 @@ junk_apev2_add_frame (playItem_t *it, DB_apev2_tag_t *tag_store, DB_apev2_frame_
if (!frame_mapping[m]) {
if (!strncasecmp (key, "replaygain_album_gain", 21)) {
- it->replaygain_album_gain = atof (value);
+ pl_set_item_replaygain (it, DDB_REPLAYGAIN_ALBUMGAIN, atof (value));
trace ("album_gain=%s\n", value);
}
else if (!strncasecmp (key, "replaygain_album_peak", 21)) {
- it->replaygain_album_peak = atof (value);
+ pl_set_item_replaygain (it, DDB_REPLAYGAIN_ALBUMPEAK, atof (value));
trace ("album_peak=%s\n", value);
}
else if (!strncasecmp (key, "replaygain_track_gain", 21)) {
- it->replaygain_track_gain = atof (value);
+ pl_set_item_replaygain (it, DDB_REPLAYGAIN_TRACKGAIN, atof (value));
trace ("track_gain=%s\n", value);
}
else if (!strncasecmp (key, "replaygain_track_peak", 21)) {
- it->replaygain_track_peak = atof (value);
+ pl_set_item_replaygain (it, DDB_REPLAYGAIN_TRACKPEAK, atof (value));
trace ("track_peak=%s\n", value);
}
+ else {
+ trace ("%s=%s\n", key, value);
+ pl_append_meta (it, key, value);;
+ }
}
}
}
@@ -1193,9 +1492,9 @@ junk_id3v2_add_text_frame (DB_id3v2_tag_t *tag, const char *frame_id, const char
encoding = 3;
}
else {
- outlen = junk_iconv (value, inlen, out, sizeof (out), UTF8, "ISO-8859-1");
+ outlen = junk_iconv (value, inlen, out, sizeof (out), UTF8_STR, "ISO-8859-1");
if (outlen == -1) {
- outlen = junk_iconv (value, inlen, out+2, sizeof (out) - 2, UTF8, "UCS-2LE");
+ outlen = junk_iconv (value, inlen, out+2, sizeof (out) - 2, UTF8_STR, "UCS-2LE");
if (outlen <= 0) {
return NULL;
}
@@ -1259,9 +1558,9 @@ junk_id3v2_add_comment_frame (DB_id3v2_tag_t *tag, const char *lang, const char
l = sizeof (input);
}
else {
- l = junk_iconv (input, sizeof (input), buffer, sizeof (buffer), UTF8, "iso8859-1");
+ l = junk_iconv (input, sizeof (input), buffer, sizeof (buffer), UTF8_STR, "iso8859-1");
if (l <= 0) {
- l = junk_iconv (input, sizeof (input), buffer+2, sizeof (buffer) - 2, UTF8, "UCS-2LE");
+ l = junk_iconv (input, sizeof (input), buffer+2, sizeof (buffer) - 2, UTF8_STR, "UCS-2LE");
if (l <= 0) {
trace ("failed to encode to ucs2 or iso8859-1\n");
return NULL;
@@ -1325,6 +1624,28 @@ junk_id3v2_remove_txxx_frame (DB_id3v2_tag_t *tag, const char *key) {
return 0;
}
+int
+junk_id3v2_remove_all_txxx_frames (DB_id3v2_tag_t *tag) {
+ DB_id3v2_frame_t *prev = NULL;
+ for (DB_id3v2_frame_t *f = tag->frames; f; ) {
+ DB_id3v2_frame_t *next = f->next;
+ if (!strcmp (f->id, "TXXX")) {
+ if (prev) {
+ prev->next = f->next;
+ }
+ else {
+ tag->frames = f->next;
+ }
+ free (f);
+ }
+ else {
+ prev = f;
+ }
+ f = next;
+ }
+ return 0;
+}
+
DB_id3v2_frame_t *
junk_id3v2_add_txxx_frame (DB_id3v2_tag_t *tag, const char *key, const char *value) {
int keylen = strlen (key);
@@ -1349,9 +1670,9 @@ junk_id3v2_add_txxx_frame (DB_id3v2_tag_t *tag, const char *key, const char *val
memcpy (out + keylen + 1, value, valuelen);
}
else { // version 3
- res = junk_iconv (buffer, len, out, sizeof (out), UTF8, "ISO-8859-1");
+ res = junk_iconv (buffer, len, out, sizeof (out), UTF8_STR, "ISO-8859-1");
if (res == -1) {
- res = junk_iconv (buffer, len, out+2, sizeof (out) - 2, UTF8, "UCS-2LE");
+ res = junk_iconv (buffer, len, out+2, sizeof (out) - 2, UTF8_STR, "UCS-2LE");
if (res == -1) {
return NULL;
}
@@ -2025,6 +2346,28 @@ junk_apev2_remove_frames (DB_apev2_tag_t *tag, const char *frame_id) {
return 0;
}
+int
+junk_apev2_remove_all_text_frames (DB_apev2_tag_t *tag) {
+ DB_apev2_frame_t *prev = NULL;
+ for (DB_apev2_frame_t *f = tag->frames; f; ) {
+ DB_apev2_frame_t *next = f->next;
+ int valuetype = ((f->flags >> 1) & 3);
+ if (valuetype == 0) {
+ if (prev) {
+ prev->next = f->next;
+ }
+ else {
+ tag->frames = f->next;
+ }
+ free (f);
+ }
+ else {
+ prev = f;
+ }
+ f = next;
+ }
+ return 0;
+}
DB_apev2_frame_t *
junk_apev2_add_text_frame (DB_apev2_tag_t *tag, const char *frame_id, const char *value) {
trace ("adding apev2 frame %s %s\n", frame_id, value);
@@ -2492,28 +2835,30 @@ junk_id3v2_load_txx (int version_major, playItem_t *it, uint8_t *readptr, int sy
}
if (val) {
+ // skip utf8 BOM (can be produced by iconv FEFF/FFFE)
+ int l = strlen (val);
+ uint8_t bom[] = { 0xEF, 0xBB, 0xBF };
+ if (l >= 3 && !memcmp (val, bom, 3)) {
+ val += 3;
+ }
+
if (!strcasecmp (txx, "replaygain_album_gain")) {
- it->replaygain_album_gain = atof (val);
+ pl_set_item_replaygain (it, DDB_REPLAYGAIN_ALBUMGAIN, atof (val));
}
else if (!strcasecmp (txx, "replaygain_album_peak")) {
- it->replaygain_album_peak = atof (val);
+ pl_set_item_replaygain (it, DDB_REPLAYGAIN_ALBUMPEAK, atof (val));
}
else if (!strcasecmp (txx, "replaygain_track_gain")) {
- it->replaygain_track_gain = atof (val);
+ pl_set_item_replaygain (it, DDB_REPLAYGAIN_TRACKGAIN, atof (val));
}
else if (!strcasecmp (txx, "replaygain_track_peak")) {
- it->replaygain_track_peak = atof (val);
- }
- else if (!strcasecmp (txx, "performer")) {
- pl_replace_meta (it, "performer", val);
+ pl_set_item_replaygain (it, DDB_REPLAYGAIN_TRACKPEAK, atof (val));
}
- else if (!strcasecmp (txx, "album artist")) {
- pl_replace_meta (it, "band", val);
- }
- else if (!strcasecmp (txx, "date")) {
- pl_replace_meta (it, "year", val);
+ else {
+ pl_append_meta (it, txx, val);
}
}
+
free (txx);
return 0;
@@ -2521,6 +2866,7 @@ junk_id3v2_load_txx (int version_major, playItem_t *it, uint8_t *readptr, int sy
int
junk_id3v2_add_genre (playItem_t *it, char *genre) {
+ int numeric = 0;
if (genre[0] == '(') {
// find matching parenthesis
char *p = &genre[1];
@@ -2530,13 +2876,14 @@ junk_id3v2_add_genre (playItem_t *it, char *genre) {
}
p++;
}
- if (*p == ')' && p[1] == 0) {
+ if (*p == ')') {
*p = 0;
memmove (genre, genre+1, p-genre);
+ numeric = 1;
}
}
- // check if it is numeric
- if (genre) {
+ if (!numeric) {
+ // check if it is numeric
const char *p = genre;
while (*p) {
if (!isdigit (*p)) {
@@ -2545,29 +2892,36 @@ junk_id3v2_add_genre (playItem_t *it, char *genre) {
p++;
}
if (*p == 0 && p > genre) {
- int genre_id = atoi (genre);
- if (genre_id >= 0) {
- const char *genre_str = NULL;
- if (genre_id <= 147) {
- genre_str = junk_genretbl[genre_id];
- }
- else if (genre_id == 0xff) {
- genre_str = "None";
- }
- if (genre_str) {
- pl_add_meta (it, "genre", genre_str);
- }
- }
- }
- else if (!strcmp (genre, "CR")) {
- pl_add_meta (it, "genre", "Cover");
+ numeric = 1;
}
- else if (!strcmp (genre, "RX")) {
- pl_add_meta (it, "genre", "Remix");
+ }
+
+ if (numeric) {
+ int genre_id = atoi (genre);
+ if (genre_id >= 0) {
+ const char *genre_str = NULL;
+ if (genre_id <= 147) {
+ genre_str = junk_genretbl[genre_id];
+ }
+ else if (genre_id == 0xff) {
+ // genre_str = "None";
+ }
+ if (genre_str) {
+ pl_add_meta (it, "genre", genre_str);
+ return 0;
+ }
}
}
+ else if (!strcmp (genre, "CR")) {
+ pl_add_meta (it, "genre", "Cover");
+ }
+ else if (!strcmp (genre, "RX")) {
+ pl_add_meta (it, "genre", "Remix");
+ }
+ else {
+ pl_add_meta (it, "genre", genre);
+ }
- pl_add_meta (it, "genre", genre);
return 0;
}
@@ -3016,11 +3370,12 @@ junk_detect_charset (const char *s) {
int
junk_recode (const char *in, int inlen, char *out, int outlen, const char *cs) {
- return junk_iconv (in, inlen, out, outlen, cs, UTF8);
+ return junk_iconv (in, inlen, out, outlen, cs, UTF8_STR);
}
int
junk_rewrite_tags (playItem_t *it, uint32_t junk_flags, int id3v2_version, const char *id3v1_encoding) {
+ trace ("junk_rewrite_tags %X\n", junk_flags);
int err = -1;
char *buffer = NULL;
DB_FILE *fp = NULL;
@@ -3035,8 +3390,10 @@ junk_rewrite_tags (playItem_t *it, uint32_t junk_flags, int id3v2_version, const
int write_apev2 = junk_flags & JUNK_WRITE_APEV2;
// find the beginning and the end of audio data
- fp = deadbeef->fopen (it->fname);
+ const char *fname = pl_find_meta (it, ":URI");
+ fp = deadbeef->fopen (fname);
if (!fp) {
+ trace ("file not found %s\n", fname);
return -1;
}
@@ -3085,7 +3442,7 @@ junk_rewrite_tags (playItem_t *it, uint32_t junk_flags, int id3v2_version, const
// open output file
out = NULL;
char tmppath[PATH_MAX];
- snprintf (tmppath, sizeof (tmppath), "%s.temp", it->fname);
+ snprintf (tmppath, sizeof (tmppath), "%s.temp", pl_find_meta (it, ":URI"));
out = fopen (tmppath, "w+b");
trace ("will write tags into %s\n", tmppath);
@@ -3102,7 +3459,7 @@ junk_rewrite_tags (playItem_t *it, uint32_t junk_flags, int id3v2_version, const
if (!strip_id3v2 && !write_id3v2 && id3v2_size > 0) {
if (deadbeef->fseek (fp, id3v2_start, SEEK_SET) == -1) {
- trace ("cmp3_write_metadata: failed to seek to original id3v2 tag position in %s\n", it->fname);
+ trace ("cmp3_write_metadata: failed to seek to original id3v2 tag position in %s\n", pl_find_meta (it, ":URI"));
goto error;
}
uint8_t *buf = malloc (id3v2_size);
@@ -3111,18 +3468,19 @@ junk_rewrite_tags (playItem_t *it, uint32_t junk_flags, int id3v2_version, const
goto error;
}
if (deadbeef->fread (buf, 1, id3v2_size, fp) != id3v2_size) {
- trace ("cmp3_write_metadata: failed to read original id3v2 tag from %s\n", it->fname);
+ trace ("cmp3_write_metadata: failed to read original id3v2 tag from %s\n", pl_find_meta (it, ":URI"));
free (buf);
goto error;
}
if (fwrite (buf, 1, id3v2_size, out) != id3v2_size) {
- trace ("cmp3_write_metadata: failed to copy original id3v2 tag from %s to temp file\n", it->fname);
+ trace ("cmp3_write_metadata: failed to copy original id3v2 tag from %s to temp file\n", pl_find_meta (it, ":URI"));
free (buf);
goto error;
}
free (buf);
}
else if (write_id3v2) {
+ trace ("writing id3v2\n");
if (id3v2_size <= 0 || strip_id3v2 || deadbeef->junk_id3v2_read_full (NULL, &id3v2, fp) != 0) {
deadbeef->junk_id3v2_free (&id3v2);
memset (&id3v2, 0, sizeof (id3v2));
@@ -3158,43 +3516,52 @@ junk_rewrite_tags (playItem_t *it, uint32_t junk_flags, int id3v2_version, const
}
}
- // remove all known txxx frames
- for (int txx = 0; txx_mapping[txx]; txx += 2) {
- trace ("removing txxx %s\n", txx_mapping[txx])
- junk_id3v2_remove_txxx_frame (&id3v2, txx_mapping[txx]);
- }
+ junk_id3v2_remove_all_txxx_frames (&id3v2);
// COMM
junk_id3v2_remove_frames (&id3v2, "COMM");
const char *val = pl_find_meta (it, "comment");
if (val && *val) {
+ junk_id3v2_remove_frames (&id3v2, "COMM");
junk_id3v2_add_comment_frame (&id3v2, "eng", "", val);
}
- // add all basic frames
+ // remove all known normal frames (they will be refilled from track metadata)
+ int idx = id3v2.version[0] == 3 ? MAP_ID3V23 : MAP_ID3V24;
for (int i = 0; frame_mapping[i]; i += FRAME_MAPPINGS) {
- const char *frm_name = id3v2_version == 3 ? frame_mapping[i+MAP_ID3V23] : frame_mapping[i+MAP_ID3V24];
- if (frm_name) {
- if (strcmp (frm_name, "TXXX")) {
- junk_id3v2_remove_frames (&id3v2, frm_name);
- }
- const char *val = pl_find_meta (it, frame_mapping[i+MAP_DDB]);
- if (val && *val) {
- if (strcmp (frm_name, "TXXX")) {
- trace ("add_frame %s %s\n", frm_name, val);
- junk_id3v2_add_text_frame (&id3v2, frm_name, val);
- //junk_id3v2_add_text_frame (&id3v2, frm_name, "test line 1\nтестовая строка №2");
- }
- else {
- for (int txx = 0; txx_mapping[txx]; txx += 2) {
- if (txx_mapping[txx+1] && !strcmp (frame_mapping[i+MAP_DDB], txx_mapping[txx+1])) {
- trace ("add_txxx_frame %s %s\n", txx_mapping[txx], val);
- junk_id3v2_add_txxx_frame (&id3v2, txx_mapping[txx], val);
- }
+ if (frame_mapping[i+idx]) {
+ junk_id3v2_remove_frames (&id3v2, frame_mapping[i+idx]);
+ trace ("removed frame %s\n", frame_mapping[i+idx]);
+ }
+ }
+
+ DB_metaInfo_t *meta = pl_get_metadata_head (it);
+ while (meta) {
+ if (meta->value && *meta->value) {
+ int i;
+ for (i = 0; frame_mapping[i]; i += FRAME_MAPPINGS) {
+ if (!strcasecmp (meta->key, frame_mapping[i+MAP_DDB])) {
+ const char *frm_name = id3v2_version == 3 ? frame_mapping[i+MAP_ID3V23] : frame_mapping[i+MAP_ID3V24];
+ if (frm_name) {
+ // field is known and supported for this tag version
+ trace ("add_frame %s %s\n", frm_name, meta->value);
+ junk_id3v2_add_text_frame (&id3v2, frm_name, meta->value);
}
+ break;
}
}
+ if (!frame_mapping[i]
+ && meta->key[0] != ':'
+ && strcasecmp (meta->key, "comment")
+ && strcasecmp (meta->key, "track")
+ && strcasecmp (meta->key, "numtracks")) {
+ // add as txxx
+ trace ("adding unknown frame as TXX %s=%s\n", meta->key, meta->value);
+ junk_id3v2_remove_txxx_frame (&id3v2, meta->key);
+ junk_id3v2_add_txxx_frame (&id3v2, meta->key, meta->value);
+ }
}
+ meta = meta->next;
}
// add tracknumber/totaltracks
@@ -3211,25 +3578,9 @@ junk_rewrite_tags (playItem_t *it, uint32_t junk_flags, int id3v2_version, const
junk_id3v2_add_text_frame (&id3v2, "TRCK", track);
}
-#if 0
- // add year/date
- const char *year = pl_find_meta (it, "year");
- if (year) {
- // FIXME: format check
- if (id3v2.version[0] == 3) {
- junk_id3v2_remove_frames (&id3v2, "TYER");
- add_frame (&id3v2, "TYER", year);
- }
- else {
- junk_id3v2_remove_frames (&id3v2, "TDRC");
- add_frame (&id3v2, "TDRC", year);
- }
- }
-#endif
-
// write tag
if (junk_id3v2_write (out, &id3v2) != 0) {
- trace ("cmp3_write_metadata: failed to write id3v2 tag to %s\n", it->fname)
+ trace ("cmp3_write_metadata: failed to write id3v2 tag to %s\n", pl_find_meta (it, ":URI"))
goto error;
}
}
@@ -3264,7 +3615,7 @@ junk_rewrite_tags (playItem_t *it, uint32_t junk_flags, int id3v2_version, const
if (!write_apev2 && !strip_apev2 && apev2_start != 0) {
trace ("copying original apev2 tag\n");
if (deadbeef->fseek (fp, apev2_start, SEEK_SET) == -1) {
- trace ("cmp3_write_metadata: failed to seek to original apev2 tag position in %s\n", it->fname);
+ trace ("cmp3_write_metadata: failed to seek to original apev2 tag position in %s\n", pl_find_meta (it, ":URI"));
goto error;
}
uint8_t *buf = malloc (apev2_size);
@@ -3273,12 +3624,12 @@ junk_rewrite_tags (playItem_t *it, uint32_t junk_flags, int id3v2_version, const
goto error;
}
if (deadbeef->fread (buf, 1, apev2_size, fp) != apev2_size) {
- trace ("cmp3_write_metadata: failed to read original apev2 tag from %s\n", it->fname);
+ trace ("cmp3_write_metadata: failed to read original apev2 tag from %s\n", pl_find_meta (it, ":URI"));
free (buf);
goto error;
}
if (fwrite (buf, 1, apev2_size, out) != apev2_size) {
- trace ("cmp3_write_metadata: failed to copy original apev2 tag from %s to temp file\n", it->fname);
+ trace ("cmp3_write_metadata: failed to copy original apev2 tag from %s to temp file\n", pl_find_meta (it, ":URI"));
free (buf);
goto error;
}
@@ -3290,15 +3641,31 @@ junk_rewrite_tags (playItem_t *it, uint32_t junk_flags, int id3v2_version, const
deadbeef->junk_apev2_free (&apev2);
memset (&apev2, 0, sizeof (apev2));
}
+
+ // remove all text frames
+ junk_apev2_remove_all_text_frames (&apev2);
+
// add all basic frames
- for (int i = 0; frame_mapping[i]; i += FRAME_MAPPINGS) {
- if (frame_mapping[i+MAP_APEV2]) {
- const char *val = pl_find_meta (it, frame_mapping[i+MAP_DDB]);
- if (val) {
- junk_apev2_remove_frames (&apev2, frame_mapping[i+MAP_APEV2]);
- junk_apev2_add_text_frame (&apev2, frame_mapping[i+MAP_APEV2], val);
+ DB_metaInfo_t *meta = pl_get_metadata_head (it);
+ while (meta) {
+ if (meta->value && *meta->value) {
+ int i;
+ for (i = 0; frame_mapping[i]; i += FRAME_MAPPINGS) {
+ if (!strcasecmp (meta->key, frame_mapping[i+MAP_DDB]) && frame_mapping[i+MAP_APEV2]) {
+ trace ("apev2 writing known field: %s=%s\n", meta->key, meta->value);
+ junk_apev2_add_text_frame (&apev2, frame_mapping[i+MAP_APEV2], meta->value);
+ break;
+ }
+ }
+ if (!frame_mapping[i]
+ && meta->key[0] != ':'
+ && strcasecmp (meta->key, "track")
+ && strcasecmp (meta->key, "numtracks")) {
+ trace ("apev2 writing unknown field: %s=%s\n", meta->key, meta->value);
+ junk_apev2_add_text_frame (&apev2, meta->key, meta->value);
}
}
+ meta = meta->next;
}
// add tracknumber/totaltracks
@@ -3317,7 +3684,7 @@ junk_rewrite_tags (playItem_t *it, uint32_t junk_flags, int id3v2_version, const
// write tag
if (deadbeef->junk_apev2_write (out, &apev2, 0, 1) != 0) {
- trace ("cmp3_write_metadata: failed to write apev2 tag to %s\n", it->fname)
+ trace ("cmp3_write_metadata: failed to write apev2 tag to %s\n", pl_find_meta (it, ":URI"))
goto error;
}
}
@@ -3325,23 +3692,23 @@ junk_rewrite_tags (playItem_t *it, uint32_t junk_flags, int id3v2_version, const
if (!write_id3v1 && !strip_id3v1 && id3v1_start != 0) {
trace ("copying original id3v1 tag %d %d %d\n", write_id3v1, strip_id3v1, id3v1_start);
if (deadbeef->fseek (fp, id3v1_start, SEEK_SET) == -1) {
- trace ("cmp3_write_metadata: failed to seek to original id3v1 tag position in %s\n", it->fname);
+ trace ("cmp3_write_metadata: failed to seek to original id3v1 tag position in %s\n", pl_find_meta (it, ":URI"));
goto error;
}
char buf[128];
if (deadbeef->fread (buf, 1, 128, fp) != 128) {
- trace ("cmp3_write_metadata: failed to read original id3v1 tag from %s\n", it->fname);
+ trace ("cmp3_write_metadata: failed to read original id3v1 tag from %s\n", pl_find_meta (it, ":URI"));
goto error;
}
if (fwrite (buf, 1, 128, out) != 128) {
- trace ("cmp3_write_metadata: failed to copy id3v1 tag from %s to temp file\n", it->fname);
+ trace ("cmp3_write_metadata: failed to copy id3v1 tag from %s to temp file\n", pl_find_meta (it, ":URI"));
goto error;
}
}
else if (write_id3v1) {
trace ("writing new id3v1 tag\n");
if (junk_id3v1_write (out, it) != 0) {
- trace ("cmp3_write_metadata: failed to write id3v1 tag to %s\n", it->fname)
+ trace ("cmp3_write_metadata: failed to write id3v1 tag to %s\n", pl_find_meta (it, ":URI"))
goto error;
}
}
@@ -3358,7 +3725,7 @@ error:
free (buffer);
}
if (!err) {
- rename (tmppath, it->fname);
+ rename (tmppath, pl_find_meta (it, ":URI"));
}
else {
unlink (tmppath);
diff --git a/junklib.h b/junklib.h
index 48d7eefc..07d99f05 100644
--- a/junklib.h
+++ b/junklib.h
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/lib-x86-32/include/FLAC/Makefile.am b/lib-x86-32/include/FLAC/Makefile.am
new file mode 100644
index 00000000..19f49b1f
--- /dev/null
+++ b/lib-x86-32/include/FLAC/Makefile.am
@@ -0,0 +1,42 @@
+# libFLAC - Free Lossless Audio Codec library
+# Copyright (C) 2000,2001,2002,2003,2004,2005,2006,2007 Josh Coalson
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# - Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# - Neither the name of the Xiph.org Foundation nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
+# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+flaccincludedir = $(includedir)/FLAC
+
+flaccinclude_HEADERS = \
+ all.h \
+ assert.h \
+ callback.h \
+ export.h \
+ format.h \
+ metadata.h \
+ ordinals.h \
+ stream_decoder.h \
+ stream_encoder.h
diff --git a/lib-x86-32/include/FLAC/all.h b/lib-x86-32/include/FLAC/all.h
new file mode 100644
index 00000000..c542c0d5
--- /dev/null
+++ b/lib-x86-32/include/FLAC/all.h
@@ -0,0 +1,370 @@
+/* libFLAC - Free Lossless Audio Codec library
+ * Copyright (C) 2000,2001,2002,2003,2004,2005,2006,2007 Josh Coalson
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of the Xiph.org Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef FLAC__ALL_H
+#define FLAC__ALL_H
+
+#include "export.h"
+
+#include "assert.h"
+#include "callback.h"
+#include "format.h"
+#include "metadata.h"
+#include "ordinals.h"
+#include "stream_decoder.h"
+#include "stream_encoder.h"
+
+/** \mainpage
+ *
+ * \section intro Introduction
+ *
+ * This is the documentation for the FLAC C and C++ APIs. It is
+ * highly interconnected; this introduction should give you a top
+ * level idea of the structure and how to find the information you
+ * need. As a prerequisite you should have at least a basic
+ * knowledge of the FLAC format, documented
+ * <A HREF="../format.html">here</A>.
+ *
+ * \section c_api FLAC C API
+ *
+ * The FLAC C API is the interface to libFLAC, a set of structures
+ * describing the components of FLAC streams, and functions for
+ * encoding and decoding streams, as well as manipulating FLAC
+ * metadata in files. The public include files will be installed
+ * in your include area (for example /usr/include/FLAC/...).
+ *
+ * By writing a little code and linking against libFLAC, it is
+ * relatively easy to add FLAC support to another program. The
+ * library is licensed under <A HREF="../license.html">Xiph's BSD license</A>.
+ * Complete source code of libFLAC as well as the command-line
+ * encoder and plugins is available and is a useful source of
+ * examples.
+ *
+ * Aside from encoders and decoders, libFLAC provides a powerful
+ * metadata interface for manipulating metadata in FLAC files. It
+ * allows the user to add, delete, and modify FLAC metadata blocks
+ * and it can automatically take advantage of PADDING blocks to avoid
+ * rewriting the entire FLAC file when changing the size of the
+ * metadata.
+ *
+ * libFLAC usually only requires the standard C library and C math
+ * library. In particular, threading is not used so there is no
+ * dependency on a thread library. However, libFLAC does not use
+ * global variables and should be thread-safe.
+ *
+ * libFLAC also supports encoding to and decoding from Ogg FLAC.
+ * However the metadata editing interfaces currently have limited
+ * read-only support for Ogg FLAC files.
+ *
+ * \section cpp_api FLAC C++ API
+ *
+ * The FLAC C++ API is a set of classes that encapsulate the
+ * structures and functions in libFLAC. They provide slightly more
+ * functionality with respect to metadata but are otherwise
+ * equivalent. For the most part, they share the same usage as
+ * their counterparts in libFLAC, and the FLAC C API documentation
+ * can be used as a supplement. The public include files
+ * for the C++ API will be installed in your include area (for
+ * example /usr/include/FLAC++/...).
+ *
+ * libFLAC++ is also licensed under
+ * <A HREF="../license.html">Xiph's BSD license</A>.
+ *
+ * \section getting_started Getting Started
+ *
+ * A good starting point for learning the API is to browse through
+ * the <A HREF="modules.html">modules</A>. Modules are logical
+ * groupings of related functions or classes, which correspond roughly
+ * to header files or sections of header files. Each module includes a
+ * detailed description of the general usage of its functions or
+ * classes.
+ *
+ * From there you can go on to look at the documentation of
+ * individual functions. You can see different views of the individual
+ * functions through the links in top bar across this page.
+ *
+ * If you prefer a more hands-on approach, you can jump right to some
+ * <A HREF="../documentation_example_code.html">example code</A>.
+ *
+ * \section porting_guide Porting Guide
+ *
+ * Starting with FLAC 1.1.3 a \link porting Porting Guide \endlink
+ * has been introduced which gives detailed instructions on how to
+ * port your code to newer versions of FLAC.
+ *
+ * \section embedded_developers Embedded Developers
+ *
+ * libFLAC has grown larger over time as more functionality has been
+ * included, but much of it may be unnecessary for a particular embedded
+ * implementation. Unused parts may be pruned by some simple editing of
+ * src/libFLAC/Makefile.am. In general, the decoders, encoders, and
+ * metadata interface are all independent from each other.
+ *
+ * It is easiest to just describe the dependencies:
+ *
+ * - All modules depend on the \link flac_format Format \endlink module.
+ * - The decoders and encoders depend on the bitbuffer.
+ * - The decoder is independent of the encoder. The encoder uses the
+ * decoder because of the verify feature, but this can be removed if
+ * not needed.
+ * - Parts of the metadata interface require the stream decoder (but not
+ * the encoder).
+ * - Ogg support is selectable through the compile time macro
+ * \c FLAC__HAS_OGG.
+ *
+ * For example, if your application only requires the stream decoder, no
+ * encoder, and no metadata interface, you can remove the stream encoder
+ * and the metadata interface, which will greatly reduce the size of the
+ * library.
+ *
+ * Also, there are several places in the libFLAC code with comments marked
+ * with "OPT:" where a #define can be changed to enable code that might be
+ * faster on a specific platform. Experimenting with these can yield faster
+ * binaries.
+ */
+
+/** \defgroup porting Porting Guide for New Versions
+ *
+ * This module describes differences in the library interfaces from
+ * version to version. It assists in the porting of code that uses
+ * the libraries to newer versions of FLAC.
+ *
+ * One simple facility for making porting easier that has been added
+ * in FLAC 1.1.3 is a set of \c #defines in \c export.h of each
+ * library's includes (e.g. \c include/FLAC/export.h). The
+ * \c #defines mirror the libraries'
+ * <A HREF="http://www.gnu.org/software/libtool/manual.html#Libtool-versioning">libtool version numbers</A>,
+ * e.g. in libFLAC there are \c FLAC_API_VERSION_CURRENT,
+ * \c FLAC_API_VERSION_REVISION, and \c FLAC_API_VERSION_AGE.
+ * These can be used to support multiple versions of an API during the
+ * transition phase, e.g.
+ *
+ * \code
+ * #if !defined(FLAC_API_VERSION_CURRENT) || FLAC_API_VERSION_CURRENT <= 7
+ * legacy code
+ * #else
+ * new code
+ * #endif
+ * \endcode
+ *
+ * The the source will work for multiple versions and the legacy code can
+ * easily be removed when the transition is complete.
+ *
+ * Another available symbol is FLAC_API_SUPPORTS_OGG_FLAC (defined in
+ * include/FLAC/export.h), which can be used to determine whether or not
+ * the library has been compiled with support for Ogg FLAC. This is
+ * simpler than trying to call an Ogg init function and catching the
+ * error.
+ */
+
+/** \defgroup porting_1_1_2_to_1_1_3 Porting from FLAC 1.1.2 to 1.1.3
+ * \ingroup porting
+ *
+ * \brief
+ * This module describes porting from FLAC 1.1.2 to FLAC 1.1.3.
+ *
+ * The main change between the APIs in 1.1.2 and 1.1.3 is that they have
+ * been simplified. First, libOggFLAC has been merged into libFLAC and
+ * libOggFLAC++ has been merged into libFLAC++. Second, both the three
+ * decoding layers and three encoding layers have been merged into a
+ * single stream decoder and stream encoder. That is, the functionality
+ * of FLAC__SeekableStreamDecoder and FLAC__FileDecoder has been merged
+ * into FLAC__StreamDecoder, and FLAC__SeekableStreamEncoder and
+ * FLAC__FileEncoder into FLAC__StreamEncoder. Only the
+ * FLAC__StreamDecoder and FLAC__StreamEncoder remain. What this means
+ * is there is now a single API that can be used to encode or decode
+ * streams to/from native FLAC or Ogg FLAC and the single API can work
+ * on both seekable and non-seekable streams.
+ *
+ * Instead of creating an encoder or decoder of a certain layer, now the
+ * client will always create a FLAC__StreamEncoder or
+ * FLAC__StreamDecoder. The old layers are now differentiated by the
+ * initialization function. For example, for the decoder,
+ * FLAC__stream_decoder_init() has been replaced by
+ * FLAC__stream_decoder_init_stream(). This init function takes
+ * callbacks for the I/O, and the seeking callbacks are optional. This
+ * allows the client to use the same object for seekable and
+ * non-seekable streams. For decoding a FLAC file directly, the client
+ * can use FLAC__stream_decoder_init_file() and pass just a filename
+ * and fewer callbacks; most of the other callbacks are supplied
+ * internally. For situations where fopen()ing by filename is not
+ * possible (e.g. Unicode filenames on Windows) the client can instead
+ * open the file itself and supply the FILE* to
+ * FLAC__stream_decoder_init_FILE(). The init functions now returns a
+ * FLAC__StreamDecoderInitStatus instead of FLAC__StreamDecoderState.
+ * Since the callbacks and client data are now passed to the init
+ * function, the FLAC__stream_decoder_set_*_callback() functions and
+ * FLAC__stream_decoder_set_client_data() are no longer needed. The
+ * rest of the calls to the decoder are the same as before.
+ *
+ * There are counterpart init functions for Ogg FLAC, e.g.
+ * FLAC__stream_decoder_init_ogg_stream(). All the rest of the calls
+ * and callbacks are the same as for native FLAC.
+ *
+ * As an example, in FLAC 1.1.2 a seekable stream decoder would have
+ * been set up like so:
+ *
+ * \code
+ * FLAC__SeekableStreamDecoder *decoder = FLAC__seekable_stream_decoder_new();
+ * if(decoder == NULL) do_something;
+ * FLAC__seekable_stream_decoder_set_md5_checking(decoder, true);
+ * [... other settings ...]
+ * FLAC__seekable_stream_decoder_set_read_callback(decoder, my_read_callback);
+ * FLAC__seekable_stream_decoder_set_seek_callback(decoder, my_seek_callback);
+ * FLAC__seekable_stream_decoder_set_tell_callback(decoder, my_tell_callback);
+ * FLAC__seekable_stream_decoder_set_length_callback(decoder, my_length_callback);
+ * FLAC__seekable_stream_decoder_set_eof_callback(decoder, my_eof_callback);
+ * FLAC__seekable_stream_decoder_set_write_callback(decoder, my_write_callback);
+ * FLAC__seekable_stream_decoder_set_metadata_callback(decoder, my_metadata_callback);
+ * FLAC__seekable_stream_decoder_set_error_callback(decoder, my_error_callback);
+ * FLAC__seekable_stream_decoder_set_client_data(decoder, my_client_data);
+ * if(FLAC__seekable_stream_decoder_init(decoder) != FLAC__SEEKABLE_STREAM_DECODER_OK) do_something;
+ * \endcode
+ *
+ * In FLAC 1.1.3 it is like this:
+ *
+ * \code
+ * FLAC__StreamDecoder *decoder = FLAC__stream_decoder_new();
+ * if(decoder == NULL) do_something;
+ * FLAC__stream_decoder_set_md5_checking(decoder, true);
+ * [... other settings ...]
+ * if(FLAC__stream_decoder_init_stream(
+ * decoder,
+ * my_read_callback,
+ * my_seek_callback, // or NULL
+ * my_tell_callback, // or NULL
+ * my_length_callback, // or NULL
+ * my_eof_callback, // or NULL
+ * my_write_callback,
+ * my_metadata_callback, // or NULL
+ * my_error_callback,
+ * my_client_data
+ * ) != FLAC__STREAM_DECODER_INIT_STATUS_OK) do_something;
+ * \endcode
+ *
+ * or you could do;
+ *
+ * \code
+ * [...]
+ * FILE *file = fopen("somefile.flac","rb");
+ * if(file == NULL) do_somthing;
+ * if(FLAC__stream_decoder_init_FILE(
+ * decoder,
+ * file,
+ * my_write_callback,
+ * my_metadata_callback, // or NULL
+ * my_error_callback,
+ * my_client_data
+ * ) != FLAC__STREAM_DECODER_INIT_STATUS_OK) do_something;
+ * \endcode
+ *
+ * or just:
+ *
+ * \code
+ * [...]
+ * if(FLAC__stream_decoder_init_file(
+ * decoder,
+ * "somefile.flac",
+ * my_write_callback,
+ * my_metadata_callback, // or NULL
+ * my_error_callback,
+ * my_client_data
+ * ) != FLAC__STREAM_DECODER_INIT_STATUS_OK) do_something;
+ * \endcode
+ *
+ * Another small change to the decoder is in how it handles unparseable
+ * streams. Before, when the decoder found an unparseable stream
+ * (reserved for when the decoder encounters a stream from a future
+ * encoder that it can't parse), it changed the state to
+ * \c FLAC__STREAM_DECODER_UNPARSEABLE_STREAM. Now the decoder instead
+ * drops sync and calls the error callback with a new error code
+ * \c FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM. This is
+ * more robust. If your error callback does not discriminate on the the
+ * error state, your code does not need to be changed.
+ *
+ * The encoder now has a new setting:
+ * FLAC__stream_encoder_set_apodization(). This is for setting the
+ * method used to window the data before LPC analysis. You only need to
+ * add a call to this function if the default is not suitable. There
+ * are also two new convenience functions that may be useful:
+ * FLAC__metadata_object_cuesheet_calculate_cddb_id() and
+ * FLAC__metadata_get_cuesheet().
+ *
+ * The \a bytes parameter to FLAC__StreamDecoderReadCallback,
+ * FLAC__StreamEncoderReadCallback, and FLAC__StreamEncoderWriteCallback
+ * is now \c size_t instead of \c unsigned.
+ */
+
+/** \defgroup porting_1_1_3_to_1_1_4 Porting from FLAC 1.1.3 to 1.1.4
+ * \ingroup porting
+ *
+ * \brief
+ * This module describes porting from FLAC 1.1.3 to FLAC 1.1.4.
+ *
+ * There were no changes to any of the interfaces from 1.1.3 to 1.1.4.
+ * There was a slight change in the implementation of
+ * FLAC__stream_encoder_set_metadata(); the function now makes a copy
+ * of the \a metadata array of pointers so the client no longer needs
+ * to maintain it after the call. The objects themselves that are
+ * pointed to by the array are still not copied though and must be
+ * maintained until the call to FLAC__stream_encoder_finish().
+ */
+
+/** \defgroup porting_1_1_4_to_1_2_0 Porting from FLAC 1.1.4 to 1.2.0
+ * \ingroup porting
+ *
+ * \brief
+ * This module describes porting from FLAC 1.1.4 to FLAC 1.2.0.
+ *
+ * There were only very minor changes to the interfaces from 1.1.4 to 1.2.0.
+ * In libFLAC, \c FLAC__format_sample_rate_is_subset() was added.
+ * In libFLAC++, \c FLAC::Decoder::Stream::get_decode_position() was added.
+ *
+ * Finally, value of the constant \c FLAC__FRAME_HEADER_RESERVED_LEN
+ * has changed to reflect the conversion of one of the reserved bits
+ * into active use. It used to be \c 2 and now is \c 1. However the
+ * FLAC frame header length has not changed, so to skip the proper
+ * number of bits, use \c FLAC__FRAME_HEADER_RESERVED_LEN +
+ * \c FLAC__FRAME_HEADER_BLOCKING_STRATEGY_LEN
+ */
+
+/** \defgroup flac FLAC C API
+ *
+ * The FLAC C API is the interface to libFLAC, a set of structures
+ * describing the components of FLAC streams, and functions for
+ * encoding and decoding streams, as well as manipulating FLAC
+ * metadata in files.
+ *
+ * You should start with the format components as all other modules
+ * are dependent on it.
+ */
+
+#endif
diff --git a/lib-x86-32/include/FLAC/assert.h b/lib-x86-32/include/FLAC/assert.h
new file mode 100644
index 00000000..3fc03f31
--- /dev/null
+++ b/lib-x86-32/include/FLAC/assert.h
@@ -0,0 +1,45 @@
+/* libFLAC - Free Lossless Audio Codec library
+ * Copyright (C) 2001,2002,2003,2004,2005,2006,2007 Josh Coalson
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of the Xiph.org Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef FLAC__ASSERT_H
+#define FLAC__ASSERT_H
+
+/* we need this since some compilers (like MSVC) leave assert()s on release code (and we don't want to use their ASSERT) */
+#ifdef DEBUG
+#include <assert.h>
+#define FLAC__ASSERT(x) assert(x)
+#define FLAC__ASSERT_DECLARATION(x) x
+#else
+#define FLAC__ASSERT(x)
+#define FLAC__ASSERT_DECLARATION(x)
+#endif
+
+#endif
diff --git a/lib-x86-32/include/FLAC/callback.h b/lib-x86-32/include/FLAC/callback.h
new file mode 100644
index 00000000..c9541210
--- /dev/null
+++ b/lib-x86-32/include/FLAC/callback.h
@@ -0,0 +1,184 @@
+/* libFLAC - Free Lossless Audio Codec library
+ * Copyright (C) 2004,2005,2006,2007 Josh Coalson
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of the Xiph.org Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef FLAC__CALLBACK_H
+#define FLAC__CALLBACK_H
+
+#include "ordinals.h"
+#include <stdlib.h> /* for size_t */
+
+/** \file include/FLAC/callback.h
+ *
+ * \brief
+ * This module defines the structures for describing I/O callbacks
+ * to the other FLAC interfaces.
+ *
+ * See the detailed documentation for callbacks in the
+ * \link flac_callbacks callbacks \endlink module.
+ */
+
+/** \defgroup flac_callbacks FLAC/callback.h: I/O callback structures
+ * \ingroup flac
+ *
+ * \brief
+ * This module defines the structures for describing I/O callbacks
+ * to the other FLAC interfaces.
+ *
+ * The purpose of the I/O callback functions is to create a common way
+ * for the metadata interfaces to handle I/O.
+ *
+ * Originally the metadata interfaces required filenames as the way of
+ * specifying FLAC files to operate on. This is problematic in some
+ * environments so there is an additional option to specify a set of
+ * callbacks for doing I/O on the FLAC file, instead of the filename.
+ *
+ * In addition to the callbacks, a FLAC__IOHandle type is defined as an
+ * opaque structure for a data source.
+ *
+ * The callback function prototypes are similar (but not identical) to the
+ * stdio functions fread, fwrite, fseek, ftell, feof, and fclose. If you use
+ * stdio streams to implement the callbacks, you can pass fread, fwrite, and
+ * fclose anywhere a FLAC__IOCallback_Read, FLAC__IOCallback_Write, or
+ * FLAC__IOCallback_Close is required, and a FILE* anywhere a FLAC__IOHandle
+ * is required. \warning You generally CANNOT directly use fseek or ftell
+ * for FLAC__IOCallback_Seek or FLAC__IOCallback_Tell since on most systems
+ * these use 32-bit offsets and FLAC requires 64-bit offsets to deal with
+ * large files. You will have to find an equivalent function (e.g. ftello),
+ * or write a wrapper. The same is true for feof() since this is usually
+ * implemented as a macro, not as a function whose address can be taken.
+ *
+ * \{
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** This is the opaque handle type used by the callbacks. Typically
+ * this is a \c FILE* or address of a file descriptor.
+ */
+typedef void* FLAC__IOHandle;
+
+/** Signature for the read callback.
+ * The signature and semantics match POSIX fread() implementations
+ * and can generally be used interchangeably.
+ *
+ * \param ptr The address of the read buffer.
+ * \param size The size of the records to be read.
+ * \param nmemb The number of records to be read.
+ * \param handle The handle to the data source.
+ * \retval size_t
+ * The number of records read.
+ */
+typedef size_t (*FLAC__IOCallback_Read) (void *ptr, size_t size, size_t nmemb, FLAC__IOHandle handle);
+
+/** Signature for the write callback.
+ * The signature and semantics match POSIX fwrite() implementations
+ * and can generally be used interchangeably.
+ *
+ * \param ptr The address of the write buffer.
+ * \param size The size of the records to be written.
+ * \param nmemb The number of records to be written.
+ * \param handle The handle to the data source.
+ * \retval size_t
+ * The number of records written.
+ */
+typedef size_t (*FLAC__IOCallback_Write) (const void *ptr, size_t size, size_t nmemb, FLAC__IOHandle handle);
+
+/** Signature for the seek callback.
+ * The signature and semantics mostly match POSIX fseek() WITH ONE IMPORTANT
+ * EXCEPTION: the offset is a 64-bit type whereas fseek() is generally 'long'
+ * and 32-bits wide.
+ *
+ * \param handle The handle to the data source.
+ * \param offset The new position, relative to \a whence
+ * \param whence \c SEEK_SET, \c SEEK_CUR, or \c SEEK_END
+ * \retval int
+ * \c 0 on success, \c -1 on error.
+ */
+typedef int (*FLAC__IOCallback_Seek) (FLAC__IOHandle handle, FLAC__int64 offset, int whence);
+
+/** Signature for the tell callback.
+ * The signature and semantics mostly match POSIX ftell() WITH ONE IMPORTANT
+ * EXCEPTION: the offset is a 64-bit type whereas ftell() is generally 'long'
+ * and 32-bits wide.
+ *
+ * \param handle The handle to the data source.
+ * \retval FLAC__int64
+ * The current position on success, \c -1 on error.
+ */
+typedef FLAC__int64 (*FLAC__IOCallback_Tell) (FLAC__IOHandle handle);
+
+/** Signature for the EOF callback.
+ * The signature and semantics mostly match POSIX feof() but WATCHOUT:
+ * on many systems, feof() is a macro, so in this case a wrapper function
+ * must be provided instead.
+ *
+ * \param handle The handle to the data source.
+ * \retval int
+ * \c 0 if not at end of file, nonzero if at end of file.
+ */
+typedef int (*FLAC__IOCallback_Eof) (FLAC__IOHandle handle);
+
+/** Signature for the close callback.
+ * The signature and semantics match POSIX fclose() implementations
+ * and can generally be used interchangeably.
+ *
+ * \param handle The handle to the data source.
+ * \retval int
+ * \c 0 on success, \c EOF on error.
+ */
+typedef int (*FLAC__IOCallback_Close) (FLAC__IOHandle handle);
+
+/** A structure for holding a set of callbacks.
+ * Each FLAC interface that requires a FLAC__IOCallbacks structure will
+ * describe which of the callbacks are required. The ones that are not
+ * required may be set to NULL.
+ *
+ * If the seek requirement for an interface is optional, you can signify that
+ * a data sorce is not seekable by setting the \a seek field to \c NULL.
+ */
+typedef struct {
+ FLAC__IOCallback_Read read;
+ FLAC__IOCallback_Write write;
+ FLAC__IOCallback_Seek seek;
+ FLAC__IOCallback_Tell tell;
+ FLAC__IOCallback_Eof eof;
+ FLAC__IOCallback_Close close;
+} FLAC__IOCallbacks;
+
+/* \} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib-x86-32/include/FLAC/export.h b/lib-x86-32/include/FLAC/export.h
new file mode 100644
index 00000000..a525f29c
--- /dev/null
+++ b/lib-x86-32/include/FLAC/export.h
@@ -0,0 +1,91 @@
+/* libFLAC - Free Lossless Audio Codec library
+ * Copyright (C) 2000,2001,2002,2003,2004,2005,2006,2007 Josh Coalson
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of the Xiph.org Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef FLAC__EXPORT_H
+#define FLAC__EXPORT_H
+
+/** \file include/FLAC/export.h
+ *
+ * \brief
+ * This module contains #defines and symbols for exporting function
+ * calls, and providing version information and compiled-in features.
+ *
+ * See the \link flac_export export \endlink module.
+ */
+
+/** \defgroup flac_export FLAC/export.h: export symbols
+ * \ingroup flac
+ *
+ * \brief
+ * This module contains #defines and symbols for exporting function
+ * calls, and providing version information and compiled-in features.
+ *
+ * If you are compiling with MSVC and will link to the static library
+ * (libFLAC.lib) you should define FLAC__NO_DLL in your project to
+ * make sure the symbols are exported properly.
+ *
+ * \{
+ */
+
+#if defined(FLAC__NO_DLL) || !defined(_MSC_VER)
+#define FLAC_API
+
+#else
+
+#ifdef FLAC_API_EXPORTS
+#define FLAC_API _declspec(dllexport)
+#else
+#define FLAC_API _declspec(dllimport)
+
+#endif
+#endif
+
+/** These #defines will mirror the libtool-based library version number, see
+ * http://www.gnu.org/software/libtool/manual.html#Libtool-versioning
+ */
+#define FLAC_API_VERSION_CURRENT 10
+#define FLAC_API_VERSION_REVISION 0 /**< see above */
+#define FLAC_API_VERSION_AGE 2 /**< see above */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** \c 1 if the library has been compiled with support for Ogg FLAC, else \c 0. */
+extern FLAC_API int FLAC_API_SUPPORTS_OGG_FLAC;
+
+#ifdef __cplusplus
+}
+#endif
+
+/* \} */
+
+#endif
diff --git a/lib-x86-32/include/FLAC/format.h b/lib-x86-32/include/FLAC/format.h
new file mode 100644
index 00000000..77e2d013
--- /dev/null
+++ b/lib-x86-32/include/FLAC/format.h
@@ -0,0 +1,1010 @@
+/* libFLAC - Free Lossless Audio Codec library
+ * Copyright (C) 2000,2001,2002,2003,2004,2005,2006,2007 Josh Coalson
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of the Xiph.org Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef FLAC__FORMAT_H
+#define FLAC__FORMAT_H
+
+#include "export.h"
+#include "ordinals.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** \file include/FLAC/format.h
+ *
+ * \brief
+ * This module contains structure definitions for the representation
+ * of FLAC format components in memory. These are the basic
+ * structures used by the rest of the interfaces.
+ *
+ * See the detailed documentation in the
+ * \link flac_format format \endlink module.
+ */
+
+/** \defgroup flac_format FLAC/format.h: format components
+ * \ingroup flac
+ *
+ * \brief
+ * This module contains structure definitions for the representation
+ * of FLAC format components in memory. These are the basic
+ * structures used by the rest of the interfaces.
+ *
+ * First, you should be familiar with the
+ * <A HREF="../format.html">FLAC format</A>. Many of the values here
+ * follow directly from the specification. As a user of libFLAC, the
+ * interesting parts really are the structures that describe the frame
+ * header and metadata blocks.
+ *
+ * The format structures here are very primitive, designed to store
+ * information in an efficient way. Reading information from the
+ * structures is easy but creating or modifying them directly is
+ * more complex. For the most part, as a user of a library, editing
+ * is not necessary; however, for metadata blocks it is, so there are
+ * convenience functions provided in the \link flac_metadata metadata
+ * module \endlink to simplify the manipulation of metadata blocks.
+ *
+ * \note
+ * It's not the best convention, but symbols ending in _LEN are in bits
+ * and _LENGTH are in bytes. _LENGTH symbols are \#defines instead of
+ * global variables because they are usually used when declaring byte
+ * arrays and some compilers require compile-time knowledge of array
+ * sizes when declared on the stack.
+ *
+ * \{
+ */
+
+
+/*
+ Most of the values described in this file are defined by the FLAC
+ format specification. There is nothing to tune here.
+*/
+
+/** The largest legal metadata type code. */
+#define FLAC__MAX_METADATA_TYPE_CODE (126u)
+
+/** The minimum block size, in samples, permitted by the format. */
+#define FLAC__MIN_BLOCK_SIZE (16u)
+
+/** The maximum block size, in samples, permitted by the format. */
+#define FLAC__MAX_BLOCK_SIZE (65535u)
+
+/** The maximum block size, in samples, permitted by the FLAC subset for
+ * sample rates up to 48kHz. */
+#define FLAC__SUBSET_MAX_BLOCK_SIZE_48000HZ (4608u)
+
+/** The maximum number of channels permitted by the format. */
+#define FLAC__MAX_CHANNELS (8u)
+
+/** The minimum sample resolution permitted by the format. */
+#define FLAC__MIN_BITS_PER_SAMPLE (4u)
+
+/** The maximum sample resolution permitted by the format. */
+#define FLAC__MAX_BITS_PER_SAMPLE (32u)
+
+/** The maximum sample resolution permitted by libFLAC.
+ *
+ * \warning
+ * FLAC__MAX_BITS_PER_SAMPLE is the limit of the FLAC format. However,
+ * the reference encoder/decoder is currently limited to 24 bits because
+ * of prevalent 32-bit math, so make sure and use this value when
+ * appropriate.
+ */
+#define FLAC__REFERENCE_CODEC_MAX_BITS_PER_SAMPLE (24u)
+
+/** The maximum sample rate permitted by the format. The value is
+ * ((2 ^ 16) - 1) * 10; see <A HREF="../format.html">FLAC format</A>
+ * as to why.
+ */
+#define FLAC__MAX_SAMPLE_RATE (655350u)
+
+/** The maximum LPC order permitted by the format. */
+#define FLAC__MAX_LPC_ORDER (32u)
+
+/** The maximum LPC order permitted by the FLAC subset for sample rates
+ * up to 48kHz. */
+#define FLAC__SUBSET_MAX_LPC_ORDER_48000HZ (12u)
+
+/** The minimum quantized linear predictor coefficient precision
+ * permitted by the format.
+ */
+#define FLAC__MIN_QLP_COEFF_PRECISION (5u)
+
+/** The maximum quantized linear predictor coefficient precision
+ * permitted by the format.
+ */
+#define FLAC__MAX_QLP_COEFF_PRECISION (15u)
+
+/** The maximum order of the fixed predictors permitted by the format. */
+#define FLAC__MAX_FIXED_ORDER (4u)
+
+/** The maximum Rice partition order permitted by the format. */
+#define FLAC__MAX_RICE_PARTITION_ORDER (15u)
+
+/** The maximum Rice partition order permitted by the FLAC Subset. */
+#define FLAC__SUBSET_MAX_RICE_PARTITION_ORDER (8u)
+
+/** The version string of the release, stamped onto the libraries and binaries.
+ *
+ * \note
+ * This does not correspond to the shared library version number, which
+ * is used to determine binary compatibility.
+ */
+extern FLAC_API const char *FLAC__VERSION_STRING;
+
+/** The vendor string inserted by the encoder into the VORBIS_COMMENT block.
+ * This is a NUL-terminated ASCII string; when inserted into the
+ * VORBIS_COMMENT the trailing null is stripped.
+ */
+extern FLAC_API const char *FLAC__VENDOR_STRING;
+
+/** The byte string representation of the beginning of a FLAC stream. */
+extern FLAC_API const FLAC__byte FLAC__STREAM_SYNC_STRING[4]; /* = "fLaC" */
+
+/** The 32-bit integer big-endian representation of the beginning of
+ * a FLAC stream.
+ */
+extern FLAC_API const unsigned FLAC__STREAM_SYNC; /* = 0x664C6143 */
+
+/** The length of the FLAC signature in bits. */
+extern FLAC_API const unsigned FLAC__STREAM_SYNC_LEN; /* = 32 bits */
+
+/** The length of the FLAC signature in bytes. */
+#define FLAC__STREAM_SYNC_LENGTH (4u)
+
+
+/*****************************************************************************
+ *
+ * Subframe structures
+ *
+ *****************************************************************************/
+
+/*****************************************************************************/
+
+/** An enumeration of the available entropy coding methods. */
+typedef enum {
+ FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE = 0,
+ /**< Residual is coded by partitioning into contexts, each with it's own
+ * 4-bit Rice parameter. */
+
+ FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2 = 1
+ /**< Residual is coded by partitioning into contexts, each with it's own
+ * 5-bit Rice parameter. */
+} FLAC__EntropyCodingMethodType;
+
+/** Maps a FLAC__EntropyCodingMethodType to a C string.
+ *
+ * Using a FLAC__EntropyCodingMethodType as the index to this array will
+ * give the string equivalent. The contents should not be modified.
+ */
+extern FLAC_API const char * const FLAC__EntropyCodingMethodTypeString[];
+
+
+/** Contents of a Rice partitioned residual
+ */
+typedef struct {
+
+ unsigned *parameters;
+ /**< The Rice parameters for each context. */
+
+ unsigned *raw_bits;
+ /**< Widths for escape-coded partitions. Will be non-zero for escaped
+ * partitions and zero for unescaped partitions.
+ */
+
+ unsigned capacity_by_order;
+ /**< The capacity of the \a parameters and \a raw_bits arrays
+ * specified as an order, i.e. the number of array elements
+ * allocated is 2 ^ \a capacity_by_order.
+ */
+} FLAC__EntropyCodingMethod_PartitionedRiceContents;
+
+/** Header for a Rice partitioned residual. (c.f. <A HREF="../format.html#partitioned_rice">format specification</A>)
+ */
+typedef struct {
+
+ unsigned order;
+ /**< The partition order, i.e. # of contexts = 2 ^ \a order. */
+
+ const FLAC__EntropyCodingMethod_PartitionedRiceContents *contents;
+ /**< The context's Rice parameters and/or raw bits. */
+
+} FLAC__EntropyCodingMethod_PartitionedRice;
+
+extern FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN; /**< == 4 (bits) */
+extern FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN; /**< == 4 (bits) */
+extern FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN; /**< == 5 (bits) */
+extern FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN; /**< == 5 (bits) */
+
+extern FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER;
+/**< == (1<<FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN)-1 */
+extern FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_ESCAPE_PARAMETER;
+/**< == (1<<FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN)-1 */
+
+/** Header for the entropy coding method. (c.f. <A HREF="../format.html#residual">format specification</A>)
+ */
+typedef struct {
+ FLAC__EntropyCodingMethodType type;
+ union {
+ FLAC__EntropyCodingMethod_PartitionedRice partitioned_rice;
+ } data;
+} FLAC__EntropyCodingMethod;
+
+extern FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_TYPE_LEN; /**< == 2 (bits) */
+
+/*****************************************************************************/
+
+/** An enumeration of the available subframe types. */
+typedef enum {
+ FLAC__SUBFRAME_TYPE_CONSTANT = 0, /**< constant signal */
+ FLAC__SUBFRAME_TYPE_VERBATIM = 1, /**< uncompressed signal */
+ FLAC__SUBFRAME_TYPE_FIXED = 2, /**< fixed polynomial prediction */
+ FLAC__SUBFRAME_TYPE_LPC = 3 /**< linear prediction */
+} FLAC__SubframeType;
+
+/** Maps a FLAC__SubframeType to a C string.
+ *
+ * Using a FLAC__SubframeType as the index to this array will
+ * give the string equivalent. The contents should not be modified.
+ */
+extern FLAC_API const char * const FLAC__SubframeTypeString[];
+
+
+/** CONSTANT subframe. (c.f. <A HREF="../format.html#subframe_constant">format specification</A>)
+ */
+typedef struct {
+ FLAC__int32 value; /**< The constant signal value. */
+} FLAC__Subframe_Constant;
+
+
+/** VERBATIM subframe. (c.f. <A HREF="../format.html#subframe_verbatim">format specification</A>)
+ */
+typedef struct {
+ const FLAC__int32 *data; /**< A pointer to verbatim signal. */
+} FLAC__Subframe_Verbatim;
+
+
+/** FIXED subframe. (c.f. <A HREF="../format.html#subframe_fixed">format specification</A>)
+ */
+typedef struct {
+ FLAC__EntropyCodingMethod entropy_coding_method;
+ /**< The residual coding method. */
+
+ unsigned order;
+ /**< The polynomial order. */
+
+ FLAC__int32 warmup[FLAC__MAX_FIXED_ORDER];
+ /**< Warmup samples to prime the predictor, length == order. */
+
+ const FLAC__int32 *residual;
+ /**< The residual signal, length == (blocksize minus order) samples. */
+} FLAC__Subframe_Fixed;
+
+
+/** LPC subframe. (c.f. <A HREF="../format.html#subframe_lpc">format specification</A>)
+ */
+typedef struct {
+ FLAC__EntropyCodingMethod entropy_coding_method;
+ /**< The residual coding method. */
+
+ unsigned order;
+ /**< The FIR order. */
+
+ unsigned qlp_coeff_precision;
+ /**< Quantized FIR filter coefficient precision in bits. */
+
+ int quantization_level;
+ /**< The qlp coeff shift needed. */
+
+ FLAC__int32 qlp_coeff[FLAC__MAX_LPC_ORDER];
+ /**< FIR filter coefficients. */
+
+ FLAC__int32 warmup[FLAC__MAX_LPC_ORDER];
+ /**< Warmup samples to prime the predictor, length == order. */
+
+ const FLAC__int32 *residual;
+ /**< The residual signal, length == (blocksize minus order) samples. */
+} FLAC__Subframe_LPC;
+
+extern FLAC_API const unsigned FLAC__SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN; /**< == 4 (bits) */
+extern FLAC_API const unsigned FLAC__SUBFRAME_LPC_QLP_SHIFT_LEN; /**< == 5 (bits) */
+
+
+/** FLAC subframe structure. (c.f. <A HREF="../format.html#subframe">format specification</A>)
+ */
+typedef struct {
+ FLAC__SubframeType type;
+ union {
+ FLAC__Subframe_Constant constant;
+ FLAC__Subframe_Fixed fixed;
+ FLAC__Subframe_LPC lpc;
+ FLAC__Subframe_Verbatim verbatim;
+ } data;
+ unsigned wasted_bits;
+} FLAC__Subframe;
+
+/** == 1 (bit)
+ *
+ * This used to be a zero-padding bit (hence the name
+ * FLAC__SUBFRAME_ZERO_PAD_LEN) but is now a reserved bit. It still has a
+ * mandatory value of \c 0 but in the future may take on the value \c 0 or \c 1
+ * to mean something else.
+ */
+extern FLAC_API const unsigned FLAC__SUBFRAME_ZERO_PAD_LEN;
+extern FLAC_API const unsigned FLAC__SUBFRAME_TYPE_LEN; /**< == 6 (bits) */
+extern FLAC_API const unsigned FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN; /**< == 1 (bit) */
+
+extern FLAC_API const unsigned FLAC__SUBFRAME_TYPE_CONSTANT_BYTE_ALIGNED_MASK; /**< = 0x00 */
+extern FLAC_API const unsigned FLAC__SUBFRAME_TYPE_VERBATIM_BYTE_ALIGNED_MASK; /**< = 0x02 */
+extern FLAC_API const unsigned FLAC__SUBFRAME_TYPE_FIXED_BYTE_ALIGNED_MASK; /**< = 0x10 */
+extern FLAC_API const unsigned FLAC__SUBFRAME_TYPE_LPC_BYTE_ALIGNED_MASK; /**< = 0x40 */
+
+/*****************************************************************************/
+
+
+/*****************************************************************************
+ *
+ * Frame structures
+ *
+ *****************************************************************************/
+
+/** An enumeration of the available channel assignments. */
+typedef enum {
+ FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT = 0, /**< independent channels */
+ FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE = 1, /**< left+side stereo */
+ FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE = 2, /**< right+side stereo */
+ FLAC__CHANNEL_ASSIGNMENT_MID_SIDE = 3 /**< mid+side stereo */
+} FLAC__ChannelAssignment;
+
+/** Maps a FLAC__ChannelAssignment to a C string.
+ *
+ * Using a FLAC__ChannelAssignment as the index to this array will
+ * give the string equivalent. The contents should not be modified.
+ */
+extern FLAC_API const char * const FLAC__ChannelAssignmentString[];
+
+/** An enumeration of the possible frame numbering methods. */
+typedef enum {
+ FLAC__FRAME_NUMBER_TYPE_FRAME_NUMBER, /**< number contains the frame number */
+ FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER /**< number contains the sample number of first sample in frame */
+} FLAC__FrameNumberType;
+
+/** Maps a FLAC__FrameNumberType to a C string.
+ *
+ * Using a FLAC__FrameNumberType as the index to this array will
+ * give the string equivalent. The contents should not be modified.
+ */
+extern FLAC_API const char * const FLAC__FrameNumberTypeString[];
+
+
+/** FLAC frame header structure. (c.f. <A HREF="../format.html#frame_header">format specification</A>)
+ */
+typedef struct {
+ unsigned blocksize;
+ /**< The number of samples per subframe. */
+
+ unsigned sample_rate;
+ /**< The sample rate in Hz. */
+
+ unsigned channels;
+ /**< The number of channels (== number of subframes). */
+
+ FLAC__ChannelAssignment channel_assignment;
+ /**< The channel assignment for the frame. */
+
+ unsigned bits_per_sample;
+ /**< The sample resolution. */
+
+ FLAC__FrameNumberType number_type;
+ /**< The numbering scheme used for the frame. As a convenience, the
+ * decoder will always convert a frame number to a sample number because
+ * the rules are complex. */
+
+ union {
+ FLAC__uint32 frame_number;
+ FLAC__uint64 sample_number;
+ } number;
+ /**< The frame number or sample number of first sample in frame;
+ * use the \a number_type value to determine which to use. */
+
+ FLAC__uint8 crc;
+ /**< CRC-8 (polynomial = x^8 + x^2 + x^1 + x^0, initialized with 0)
+ * of the raw frame header bytes, meaning everything before the CRC byte
+ * including the sync code.
+ */
+} FLAC__FrameHeader;
+
+extern FLAC_API const unsigned FLAC__FRAME_HEADER_SYNC; /**< == 0x3ffe; the frame header sync code */
+extern FLAC_API const unsigned FLAC__FRAME_HEADER_SYNC_LEN; /**< == 14 (bits) */
+extern FLAC_API const unsigned FLAC__FRAME_HEADER_RESERVED_LEN; /**< == 1 (bits) */
+extern FLAC_API const unsigned FLAC__FRAME_HEADER_BLOCKING_STRATEGY_LEN; /**< == 1 (bits) */
+extern FLAC_API const unsigned FLAC__FRAME_HEADER_BLOCK_SIZE_LEN; /**< == 4 (bits) */
+extern FLAC_API const unsigned FLAC__FRAME_HEADER_SAMPLE_RATE_LEN; /**< == 4 (bits) */
+extern FLAC_API const unsigned FLAC__FRAME_HEADER_CHANNEL_ASSIGNMENT_LEN; /**< == 4 (bits) */
+extern FLAC_API const unsigned FLAC__FRAME_HEADER_BITS_PER_SAMPLE_LEN; /**< == 3 (bits) */
+extern FLAC_API const unsigned FLAC__FRAME_HEADER_ZERO_PAD_LEN; /**< == 1 (bit) */
+extern FLAC_API const unsigned FLAC__FRAME_HEADER_CRC_LEN; /**< == 8 (bits) */
+
+
+/** FLAC frame footer structure. (c.f. <A HREF="../format.html#frame_footer">format specification</A>)
+ */
+typedef struct {
+ FLAC__uint16 crc;
+ /**< CRC-16 (polynomial = x^16 + x^15 + x^2 + x^0, initialized with
+ * 0) of the bytes before the crc, back to and including the frame header
+ * sync code.
+ */
+} FLAC__FrameFooter;
+
+extern FLAC_API const unsigned FLAC__FRAME_FOOTER_CRC_LEN; /**< == 16 (bits) */
+
+
+/** FLAC frame structure. (c.f. <A HREF="../format.html#frame">format specification</A>)
+ */
+typedef struct {
+ FLAC__FrameHeader header;
+ FLAC__Subframe subframes[FLAC__MAX_CHANNELS];
+ FLAC__FrameFooter footer;
+} FLAC__Frame;
+
+/*****************************************************************************/
+
+
+/*****************************************************************************
+ *
+ * Meta-data structures
+ *
+ *****************************************************************************/
+
+/** An enumeration of the available metadata block types. */
+typedef enum {
+
+ FLAC__METADATA_TYPE_STREAMINFO = 0,
+ /**< <A HREF="../format.html#metadata_block_streaminfo">STREAMINFO</A> block */
+
+ FLAC__METADATA_TYPE_PADDING = 1,
+ /**< <A HREF="../format.html#metadata_block_padding">PADDING</A> block */
+
+ FLAC__METADATA_TYPE_APPLICATION = 2,
+ /**< <A HREF="../format.html#metadata_block_application">APPLICATION</A> block */
+
+ FLAC__METADATA_TYPE_SEEKTABLE = 3,
+ /**< <A HREF="../format.html#metadata_block_seektable">SEEKTABLE</A> block */
+
+ FLAC__METADATA_TYPE_VORBIS_COMMENT = 4,
+ /**< <A HREF="../format.html#metadata_block_vorbis_comment">VORBISCOMMENT</A> block (a.k.a. FLAC tags) */
+
+ FLAC__METADATA_TYPE_CUESHEET = 5,
+ /**< <A HREF="../format.html#metadata_block_cuesheet">CUESHEET</A> block */
+
+ FLAC__METADATA_TYPE_PICTURE = 6,
+ /**< <A HREF="../format.html#metadata_block_picture">PICTURE</A> block */
+
+ FLAC__METADATA_TYPE_UNDEFINED = 7
+ /**< marker to denote beginning of undefined type range; this number will increase as new metadata types are added */
+
+} FLAC__MetadataType;
+
+/** Maps a FLAC__MetadataType to a C string.
+ *
+ * Using a FLAC__MetadataType as the index to this array will
+ * give the string equivalent. The contents should not be modified.
+ */
+extern FLAC_API const char * const FLAC__MetadataTypeString[];
+
+
+/** FLAC STREAMINFO structure. (c.f. <A HREF="../format.html#metadata_block_streaminfo">format specification</A>)
+ */
+typedef struct {
+ unsigned min_blocksize, max_blocksize;
+ unsigned min_framesize, max_framesize;
+ unsigned sample_rate;
+ unsigned channels;
+ unsigned bits_per_sample;
+ FLAC__uint64 total_samples;
+ FLAC__byte md5sum[16];
+} FLAC__StreamMetadata_StreamInfo;
+
+extern FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN; /**< == 16 (bits) */
+extern FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN; /**< == 16 (bits) */
+extern FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN; /**< == 24 (bits) */
+extern FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN; /**< == 24 (bits) */
+extern FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN; /**< == 20 (bits) */
+extern FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN; /**< == 3 (bits) */
+extern FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN; /**< == 5 (bits) */
+extern FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN; /**< == 36 (bits) */
+extern FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MD5SUM_LEN; /**< == 128 (bits) */
+
+/** The total stream length of the STREAMINFO block in bytes. */
+#define FLAC__STREAM_METADATA_STREAMINFO_LENGTH (34u)
+
+/** FLAC PADDING structure. (c.f. <A HREF="../format.html#metadata_block_padding">format specification</A>)
+ */
+typedef struct {
+ int dummy;
+ /**< Conceptually this is an empty struct since we don't store the
+ * padding bytes. Empty structs are not allowed by some C compilers,
+ * hence the dummy.
+ */
+} FLAC__StreamMetadata_Padding;
+
+
+/** FLAC APPLICATION structure. (c.f. <A HREF="../format.html#metadata_block_application">format specification</A>)
+ */
+typedef struct {
+ FLAC__byte id[4];
+ FLAC__byte *data;
+} FLAC__StreamMetadata_Application;
+
+extern FLAC_API const unsigned FLAC__STREAM_METADATA_APPLICATION_ID_LEN; /**< == 32 (bits) */
+
+/** SeekPoint structure used in SEEKTABLE blocks. (c.f. <A HREF="../format.html#seekpoint">format specification</A>)
+ */
+typedef struct {
+ FLAC__uint64 sample_number;
+ /**< The sample number of the target frame. */
+
+ FLAC__uint64 stream_offset;
+ /**< The offset, in bytes, of the target frame with respect to
+ * beginning of the first frame. */
+
+ unsigned frame_samples;
+ /**< The number of samples in the target frame. */
+} FLAC__StreamMetadata_SeekPoint;
+
+extern FLAC_API const unsigned FLAC__STREAM_METADATA_SEEKPOINT_SAMPLE_NUMBER_LEN; /**< == 64 (bits) */
+extern FLAC_API const unsigned FLAC__STREAM_METADATA_SEEKPOINT_STREAM_OFFSET_LEN; /**< == 64 (bits) */
+extern FLAC_API const unsigned FLAC__STREAM_METADATA_SEEKPOINT_FRAME_SAMPLES_LEN; /**< == 16 (bits) */
+
+/** The total stream length of a seek point in bytes. */
+#define FLAC__STREAM_METADATA_SEEKPOINT_LENGTH (18u)
+
+/** The value used in the \a sample_number field of
+ * FLAC__StreamMetadataSeekPoint used to indicate a placeholder
+ * point (== 0xffffffffffffffff).
+ */
+extern FLAC_API const FLAC__uint64 FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER;
+
+
+/** FLAC SEEKTABLE structure. (c.f. <A HREF="../format.html#metadata_block_seektable">format specification</A>)
+ *
+ * \note From the format specification:
+ * - The seek points must be sorted by ascending sample number.
+ * - Each seek point's sample number must be the first sample of the
+ * target frame.
+ * - Each seek point's sample number must be unique within the table.
+ * - Existence of a SEEKTABLE block implies a correct setting of
+ * total_samples in the stream_info block.
+ * - Behavior is undefined when more than one SEEKTABLE block is
+ * present in a stream.
+ */
+typedef struct {
+ unsigned num_points;
+ FLAC__StreamMetadata_SeekPoint *points;
+} FLAC__StreamMetadata_SeekTable;
+
+
+/** Vorbis comment entry structure used in VORBIS_COMMENT blocks. (c.f. <A HREF="../format.html#metadata_block_vorbis_comment">format specification</A>)
+ *
+ * For convenience, the APIs maintain a trailing NUL character at the end of
+ * \a entry which is not counted toward \a length, i.e.
+ * \code strlen(entry) == length \endcode
+ */
+typedef struct {
+ FLAC__uint32 length;
+ FLAC__byte *entry;
+} FLAC__StreamMetadata_VorbisComment_Entry;
+
+extern FLAC_API const unsigned FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN; /**< == 32 (bits) */
+
+
+/** FLAC VORBIS_COMMENT structure. (c.f. <A HREF="../format.html#metadata_block_vorbis_comment">format specification</A>)
+ */
+typedef struct {
+ FLAC__StreamMetadata_VorbisComment_Entry vendor_string;
+ FLAC__uint32 num_comments;
+ FLAC__StreamMetadata_VorbisComment_Entry *comments;
+} FLAC__StreamMetadata_VorbisComment;
+
+extern FLAC_API const unsigned FLAC__STREAM_METADATA_VORBIS_COMMENT_NUM_COMMENTS_LEN; /**< == 32 (bits) */
+
+
+/** FLAC CUESHEET track index structure. (See the
+ * <A HREF="../format.html#cuesheet_track_index">format specification</A> for
+ * the full description of each field.)
+ */
+typedef struct {
+ FLAC__uint64 offset;
+ /**< Offset in samples, relative to the track offset, of the index
+ * point.
+ */
+
+ FLAC__byte number;
+ /**< The index point number. */
+} FLAC__StreamMetadata_CueSheet_Index;
+
+extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_INDEX_OFFSET_LEN; /**< == 64 (bits) */
+extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_INDEX_NUMBER_LEN; /**< == 8 (bits) */
+extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN; /**< == 3*8 (bits) */
+
+
+/** FLAC CUESHEET track structure. (See the
+ * <A HREF="../format.html#cuesheet_track">format specification</A> for
+ * the full description of each field.)
+ */
+typedef struct {
+ FLAC__uint64 offset;
+ /**< Track offset in samples, relative to the beginning of the FLAC audio stream. */
+
+ FLAC__byte number;
+ /**< The track number. */
+
+ char isrc[13];
+ /**< Track ISRC. This is a 12-digit alphanumeric code plus a trailing \c NUL byte */
+
+ unsigned type:1;
+ /**< The track type: 0 for audio, 1 for non-audio. */
+
+ unsigned pre_emphasis:1;
+ /**< The pre-emphasis flag: 0 for no pre-emphasis, 1 for pre-emphasis. */
+
+ FLAC__byte num_indices;
+ /**< The number of track index points. */
+
+ FLAC__StreamMetadata_CueSheet_Index *indices;
+ /**< NULL if num_indices == 0, else pointer to array of index points. */
+
+} FLAC__StreamMetadata_CueSheet_Track;
+
+extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_OFFSET_LEN; /**< == 64 (bits) */
+extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_NUMBER_LEN; /**< == 8 (bits) */
+extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_ISRC_LEN; /**< == 12*8 (bits) */
+extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_TYPE_LEN; /**< == 1 (bit) */
+extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_PRE_EMPHASIS_LEN; /**< == 1 (bit) */
+extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_RESERVED_LEN; /**< == 6+13*8 (bits) */
+extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_NUM_INDICES_LEN; /**< == 8 (bits) */
+
+
+/** FLAC CUESHEET structure. (See the
+ * <A HREF="../format.html#metadata_block_cuesheet">format specification</A>
+ * for the full description of each field.)
+ */
+typedef struct {
+ char media_catalog_number[129];
+ /**< Media catalog number, in ASCII printable characters 0x20-0x7e. In
+ * general, the media catalog number may be 0 to 128 bytes long; any
+ * unused characters should be right-padded with NUL characters.
+ */
+
+ FLAC__uint64 lead_in;
+ /**< The number of lead-in samples. */
+
+ FLAC__bool is_cd;
+ /**< \c true if CUESHEET corresponds to a Compact Disc, else \c false. */
+
+ unsigned num_tracks;
+ /**< The number of tracks. */
+
+ FLAC__StreamMetadata_CueSheet_Track *tracks;
+ /**< NULL if num_tracks == 0, else pointer to array of tracks. */
+
+} FLAC__StreamMetadata_CueSheet;
+
+extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_MEDIA_CATALOG_NUMBER_LEN; /**< == 128*8 (bits) */
+extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_LEAD_IN_LEN; /**< == 64 (bits) */
+extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_IS_CD_LEN; /**< == 1 (bit) */
+extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_RESERVED_LEN; /**< == 7+258*8 (bits) */
+extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_NUM_TRACKS_LEN; /**< == 8 (bits) */
+
+
+/** An enumeration of the PICTURE types (see FLAC__StreamMetadataPicture and id3 v2.4 APIC tag). */
+typedef enum {
+ FLAC__STREAM_METADATA_PICTURE_TYPE_OTHER = 0, /**< Other */
+ FLAC__STREAM_METADATA_PICTURE_TYPE_FILE_ICON_STANDARD = 1, /**< 32x32 pixels 'file icon' (PNG only) */
+ FLAC__STREAM_METADATA_PICTURE_TYPE_FILE_ICON = 2, /**< Other file icon */
+ FLAC__STREAM_METADATA_PICTURE_TYPE_FRONT_COVER = 3, /**< Cover (front) */
+ FLAC__STREAM_METADATA_PICTURE_TYPE_BACK_COVER = 4, /**< Cover (back) */
+ FLAC__STREAM_METADATA_PICTURE_TYPE_LEAFLET_PAGE = 5, /**< Leaflet page */
+ FLAC__STREAM_METADATA_PICTURE_TYPE_MEDIA = 6, /**< Media (e.g. label side of CD) */
+ FLAC__STREAM_METADATA_PICTURE_TYPE_LEAD_ARTIST = 7, /**< Lead artist/lead performer/soloist */
+ FLAC__STREAM_METADATA_PICTURE_TYPE_ARTIST = 8, /**< Artist/performer */
+ FLAC__STREAM_METADATA_PICTURE_TYPE_CONDUCTOR = 9, /**< Conductor */
+ FLAC__STREAM_METADATA_PICTURE_TYPE_BAND = 10, /**< Band/Orchestra */
+ FLAC__STREAM_METADATA_PICTURE_TYPE_COMPOSER = 11, /**< Composer */
+ FLAC__STREAM_METADATA_PICTURE_TYPE_LYRICIST = 12, /**< Lyricist/text writer */
+ FLAC__STREAM_METADATA_PICTURE_TYPE_RECORDING_LOCATION = 13, /**< Recording Location */
+ FLAC__STREAM_METADATA_PICTURE_TYPE_DURING_RECORDING = 14, /**< During recording */
+ FLAC__STREAM_METADATA_PICTURE_TYPE_DURING_PERFORMANCE = 15, /**< During performance */
+ FLAC__STREAM_METADATA_PICTURE_TYPE_VIDEO_SCREEN_CAPTURE = 16, /**< Movie/video screen capture */
+ FLAC__STREAM_METADATA_PICTURE_TYPE_FISH = 17, /**< A bright coloured fish */
+ FLAC__STREAM_METADATA_PICTURE_TYPE_ILLUSTRATION = 18, /**< Illustration */
+ FLAC__STREAM_METADATA_PICTURE_TYPE_BAND_LOGOTYPE = 19, /**< Band/artist logotype */
+ FLAC__STREAM_METADATA_PICTURE_TYPE_PUBLISHER_LOGOTYPE = 20, /**< Publisher/Studio logotype */
+ FLAC__STREAM_METADATA_PICTURE_TYPE_UNDEFINED
+} FLAC__StreamMetadata_Picture_Type;
+
+/** Maps a FLAC__StreamMetadata_Picture_Type to a C string.
+ *
+ * Using a FLAC__StreamMetadata_Picture_Type as the index to this array
+ * will give the string equivalent. The contents should not be
+ * modified.
+ */
+extern FLAC_API const char * const FLAC__StreamMetadata_Picture_TypeString[];
+
+/** FLAC PICTURE structure. (See the
+ * <A HREF="../format.html#metadata_block_picture">format specification</A>
+ * for the full description of each field.)
+ */
+typedef struct {
+ FLAC__StreamMetadata_Picture_Type type;
+ /**< The kind of picture stored. */
+
+ char *mime_type;
+ /**< Picture data's MIME type, in ASCII printable characters
+ * 0x20-0x7e, NUL terminated. For best compatibility with players,
+ * use picture data of MIME type \c image/jpeg or \c image/png. A
+ * MIME type of '-->' is also allowed, in which case the picture
+ * data should be a complete URL. In file storage, the MIME type is
+ * stored as a 32-bit length followed by the ASCII string with no NUL
+ * terminator, but is converted to a plain C string in this structure
+ * for convenience.
+ */
+
+ FLAC__byte *description;
+ /**< Picture's description in UTF-8, NUL terminated. In file storage,
+ * the description is stored as a 32-bit length followed by the UTF-8
+ * string with no NUL terminator, but is converted to a plain C string
+ * in this structure for convenience.
+ */
+
+ FLAC__uint32 width;
+ /**< Picture's width in pixels. */
+
+ FLAC__uint32 height;
+ /**< Picture's height in pixels. */
+
+ FLAC__uint32 depth;
+ /**< Picture's color depth in bits-per-pixel. */
+
+ FLAC__uint32 colors;
+ /**< For indexed palettes (like GIF), picture's number of colors (the
+ * number of palette entries), or \c 0 for non-indexed (i.e. 2^depth).
+ */
+
+ FLAC__uint32 data_length;
+ /**< Length of binary picture data in bytes. */
+
+ FLAC__byte *data;
+ /**< Binary picture data. */
+
+} FLAC__StreamMetadata_Picture;
+
+extern FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_TYPE_LEN; /**< == 32 (bits) */
+extern FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_MIME_TYPE_LENGTH_LEN; /**< == 32 (bits) */
+extern FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_DESCRIPTION_LENGTH_LEN; /**< == 32 (bits) */
+extern FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_WIDTH_LEN; /**< == 32 (bits) */
+extern FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_HEIGHT_LEN; /**< == 32 (bits) */
+extern FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_DEPTH_LEN; /**< == 32 (bits) */
+extern FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_COLORS_LEN; /**< == 32 (bits) */
+extern FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_DATA_LENGTH_LEN; /**< == 32 (bits) */
+
+
+/** Structure that is used when a metadata block of unknown type is loaded.
+ * The contents are opaque. The structure is used only internally to
+ * correctly handle unknown metadata.
+ */
+typedef struct {
+ FLAC__byte *data;
+} FLAC__StreamMetadata_Unknown;
+
+
+/** FLAC metadata block structure. (c.f. <A HREF="../format.html#metadata_block">format specification</A>)
+ */
+typedef struct {
+ FLAC__MetadataType type;
+ /**< The type of the metadata block; used determine which member of the
+ * \a data union to dereference. If type >= FLAC__METADATA_TYPE_UNDEFINED
+ * then \a data.unknown must be used. */
+
+ FLAC__bool is_last;
+ /**< \c true if this metadata block is the last, else \a false */
+
+ unsigned length;
+ /**< Length, in bytes, of the block data as it appears in the stream. */
+
+ union {
+ FLAC__StreamMetadata_StreamInfo stream_info;
+ FLAC__StreamMetadata_Padding padding;
+ FLAC__StreamMetadata_Application application;
+ FLAC__StreamMetadata_SeekTable seek_table;
+ FLAC__StreamMetadata_VorbisComment vorbis_comment;
+ FLAC__StreamMetadata_CueSheet cue_sheet;
+ FLAC__StreamMetadata_Picture picture;
+ FLAC__StreamMetadata_Unknown unknown;
+ } data;
+ /**< Polymorphic block data; use the \a type value to determine which
+ * to use. */
+} FLAC__StreamMetadata;
+
+extern FLAC_API const unsigned FLAC__STREAM_METADATA_IS_LAST_LEN; /**< == 1 (bit) */
+extern FLAC_API const unsigned FLAC__STREAM_METADATA_TYPE_LEN; /**< == 7 (bits) */
+extern FLAC_API const unsigned FLAC__STREAM_METADATA_LENGTH_LEN; /**< == 24 (bits) */
+
+/** The total stream length of a metadata block header in bytes. */
+#define FLAC__STREAM_METADATA_HEADER_LENGTH (4u)
+
+/*****************************************************************************/
+
+
+/*****************************************************************************
+ *
+ * Utility functions
+ *
+ *****************************************************************************/
+
+/** Tests that a sample rate is valid for FLAC.
+ *
+ * \param sample_rate The sample rate to test for compliance.
+ * \retval FLAC__bool
+ * \c true if the given sample rate conforms to the specification, else
+ * \c false.
+ */
+FLAC_API FLAC__bool FLAC__format_sample_rate_is_valid(unsigned sample_rate);
+
+/** Tests that a sample rate is valid for the FLAC subset. The subset rules
+ * for valid sample rates are slightly more complex since the rate has to
+ * be expressible completely in the frame header.
+ *
+ * \param sample_rate The sample rate to test for compliance.
+ * \retval FLAC__bool
+ * \c true if the given sample rate conforms to the specification for the
+ * subset, else \c false.
+ */
+FLAC_API FLAC__bool FLAC__format_sample_rate_is_subset(unsigned sample_rate);
+
+/** Check a Vorbis comment entry name to see if it conforms to the Vorbis
+ * comment specification.
+ *
+ * Vorbis comment names must be composed only of characters from
+ * [0x20-0x3C,0x3E-0x7D].
+ *
+ * \param name A NUL-terminated string to be checked.
+ * \assert
+ * \code name != NULL \endcode
+ * \retval FLAC__bool
+ * \c false if entry name is illegal, else \c true.
+ */
+FLAC_API FLAC__bool FLAC__format_vorbiscomment_entry_name_is_legal(const char *name);
+
+/** Check a Vorbis comment entry value to see if it conforms to the Vorbis
+ * comment specification.
+ *
+ * Vorbis comment values must be valid UTF-8 sequences.
+ *
+ * \param value A string to be checked.
+ * \param length A the length of \a value in bytes. May be
+ * \c (unsigned)(-1) to indicate that \a value is a plain
+ * UTF-8 NUL-terminated string.
+ * \assert
+ * \code value != NULL \endcode
+ * \retval FLAC__bool
+ * \c false if entry name is illegal, else \c true.
+ */
+FLAC_API FLAC__bool FLAC__format_vorbiscomment_entry_value_is_legal(const FLAC__byte *value, unsigned length);
+
+/** Check a Vorbis comment entry to see if it conforms to the Vorbis
+ * comment specification.
+ *
+ * Vorbis comment entries must be of the form 'name=value', and 'name' and
+ * 'value' must be legal according to
+ * FLAC__format_vorbiscomment_entry_name_is_legal() and
+ * FLAC__format_vorbiscomment_entry_value_is_legal() respectively.
+ *
+ * \param entry An entry to be checked.
+ * \param length The length of \a entry in bytes.
+ * \assert
+ * \code value != NULL \endcode
+ * \retval FLAC__bool
+ * \c false if entry name is illegal, else \c true.
+ */
+FLAC_API FLAC__bool FLAC__format_vorbiscomment_entry_is_legal(const FLAC__byte *entry, unsigned length);
+
+/** Check a seek table to see if it conforms to the FLAC specification.
+ * See the format specification for limits on the contents of the
+ * seek table.
+ *
+ * \param seek_table A pointer to a seek table to be checked.
+ * \assert
+ * \code seek_table != NULL \endcode
+ * \retval FLAC__bool
+ * \c false if seek table is illegal, else \c true.
+ */
+FLAC_API FLAC__bool FLAC__format_seektable_is_legal(const FLAC__StreamMetadata_SeekTable *seek_table);
+
+/** Sort a seek table's seek points according to the format specification.
+ * This includes a "unique-ification" step to remove duplicates, i.e.
+ * seek points with identical \a sample_number values. Duplicate seek
+ * points are converted into placeholder points and sorted to the end of
+ * the table.
+ *
+ * \param seek_table A pointer to a seek table to be sorted.
+ * \assert
+ * \code seek_table != NULL \endcode
+ * \retval unsigned
+ * The number of duplicate seek points converted into placeholders.
+ */
+FLAC_API unsigned FLAC__format_seektable_sort(FLAC__StreamMetadata_SeekTable *seek_table);
+
+/** Check a cue sheet to see if it conforms to the FLAC specification.
+ * See the format specification for limits on the contents of the
+ * cue sheet.
+ *
+ * \param cue_sheet A pointer to an existing cue sheet to be checked.
+ * \param check_cd_da_subset If \c true, check CUESHEET against more
+ * stringent requirements for a CD-DA (audio) disc.
+ * \param violation Address of a pointer to a string. If there is a
+ * violation, a pointer to a string explanation of the
+ * violation will be returned here. \a violation may be
+ * \c NULL if you don't need the returned string. Do not
+ * free the returned string; it will always point to static
+ * data.
+ * \assert
+ * \code cue_sheet != NULL \endcode
+ * \retval FLAC__bool
+ * \c false if cue sheet is illegal, else \c true.
+ */
+FLAC_API FLAC__bool FLAC__format_cuesheet_is_legal(const FLAC__StreamMetadata_CueSheet *cue_sheet, FLAC__bool check_cd_da_subset, const char **violation);
+
+/** Check picture data to see if it conforms to the FLAC specification.
+ * See the format specification for limits on the contents of the
+ * PICTURE block.
+ *
+ * \param picture A pointer to existing picture data to be checked.
+ * \param violation Address of a pointer to a string. If there is a
+ * violation, a pointer to a string explanation of the
+ * violation will be returned here. \a violation may be
+ * \c NULL if you don't need the returned string. Do not
+ * free the returned string; it will always point to static
+ * data.
+ * \assert
+ * \code picture != NULL \endcode
+ * \retval FLAC__bool
+ * \c false if picture data is illegal, else \c true.
+ */
+FLAC_API FLAC__bool FLAC__format_picture_is_legal(const FLAC__StreamMetadata_Picture *picture, const char **violation);
+
+/* \} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib-x86-32/include/FLAC/metadata.h b/lib-x86-32/include/FLAC/metadata.h
new file mode 100644
index 00000000..fff90b0b
--- /dev/null
+++ b/lib-x86-32/include/FLAC/metadata.h
@@ -0,0 +1,2181 @@
+/* libFLAC - Free Lossless Audio Codec library
+ * Copyright (C) 2001,2002,2003,2004,2005,2006,2007 Josh Coalson
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of the Xiph.org Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef FLAC__METADATA_H
+#define FLAC__METADATA_H
+
+#include <sys/types.h> /* for off_t */
+#include "export.h"
+#include "callback.h"
+#include "format.h"
+
+/* --------------------------------------------------------------------
+ (For an example of how all these routines are used, see the source
+ code for the unit tests in src/test_libFLAC/metadata_*.c, or
+ metaflac in src/metaflac/)
+ ------------------------------------------------------------------*/
+
+/** \file include/FLAC/metadata.h
+ *
+ * \brief
+ * This module provides functions for creating and manipulating FLAC
+ * metadata blocks in memory, and three progressively more powerful
+ * interfaces for traversing and editing metadata in FLAC files.
+ *
+ * See the detailed documentation for each interface in the
+ * \link flac_metadata metadata \endlink module.
+ */
+
+/** \defgroup flac_metadata FLAC/metadata.h: metadata interfaces
+ * \ingroup flac
+ *
+ * \brief
+ * This module provides functions for creating and manipulating FLAC
+ * metadata blocks in memory, and three progressively more powerful
+ * interfaces for traversing and editing metadata in native FLAC files.
+ * Note that currently only the Chain interface (level 2) supports Ogg
+ * FLAC files, and it is read-only i.e. no writing back changed
+ * metadata to file.
+ *
+ * There are three metadata interfaces of increasing complexity:
+ *
+ * Level 0:
+ * Read-only access to the STREAMINFO, VORBIS_COMMENT, CUESHEET, and
+ * PICTURE blocks.
+ *
+ * Level 1:
+ * Read-write access to all metadata blocks. This level is write-
+ * efficient in most cases (more on this below), and uses less memory
+ * than level 2.
+ *
+ * Level 2:
+ * Read-write access to all metadata blocks. This level is write-
+ * efficient in all cases, but uses more memory since all metadata for
+ * the whole file is read into memory and manipulated before writing
+ * out again.
+ *
+ * What do we mean by efficient? Since FLAC metadata appears at the
+ * beginning of the file, when writing metadata back to a FLAC file
+ * it is possible to grow or shrink the metadata such that the entire
+ * file must be rewritten. However, if the size remains the same during
+ * changes or PADDING blocks are utilized, only the metadata needs to be
+ * overwritten, which is much faster.
+ *
+ * Efficient means the whole file is rewritten at most one time, and only
+ * when necessary. Level 1 is not efficient only in the case that you
+ * cause more than one metadata block to grow or shrink beyond what can
+ * be accomodated by padding. In this case you should probably use level
+ * 2, which allows you to edit all the metadata for a file in memory and
+ * write it out all at once.
+ *
+ * All levels know how to skip over and not disturb an ID3v2 tag at the
+ * front of the file.
+ *
+ * All levels access files via their filenames. In addition, level 2
+ * has additional alternative read and write functions that take an I/O
+ * handle and callbacks, for situations where access by filename is not
+ * possible.
+ *
+ * In addition to the three interfaces, this module defines functions for
+ * creating and manipulating various metadata objects in memory. As we see
+ * from the Format module, FLAC metadata blocks in memory are very primitive
+ * structures for storing information in an efficient way. Reading
+ * information from the structures is easy but creating or modifying them
+ * directly is more complex. The metadata object routines here facilitate
+ * this by taking care of the consistency and memory management drudgery.
+ *
+ * Unless you will be using the level 1 or 2 interfaces to modify existing
+ * metadata however, you will not probably not need these.
+ *
+ * From a dependency standpoint, none of the encoders or decoders require
+ * the metadata module. This is so that embedded users can strip out the
+ * metadata module from libFLAC to reduce the size and complexity.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/** \defgroup flac_metadata_level0 FLAC/metadata.h: metadata level 0 interface
+ * \ingroup flac_metadata
+ *
+ * \brief
+ * The level 0 interface consists of individual routines to read the
+ * STREAMINFO, VORBIS_COMMENT, CUESHEET, and PICTURE blocks, requiring
+ * only a filename.
+ *
+ * They try to skip any ID3v2 tag at the head of the file.
+ *
+ * \{
+ */
+
+/** Read the STREAMINFO metadata block of the given FLAC file. This function
+ * will try to skip any ID3v2 tag at the head of the file.
+ *
+ * \param filename The path to the FLAC file to read.
+ * \param streaminfo A pointer to space for the STREAMINFO block. Since
+ * FLAC__StreamMetadata is a simple structure with no
+ * memory allocation involved, you pass the address of
+ * an existing structure. It need not be initialized.
+ * \assert
+ * \code filename != NULL \endcode
+ * \code streaminfo != NULL \endcode
+ * \retval FLAC__bool
+ * \c true if a valid STREAMINFO block was read from \a filename. Returns
+ * \c false if there was a memory allocation error, a file decoder error,
+ * or the file contained no STREAMINFO block. (A memory allocation error
+ * is possible because this function must set up a file decoder.)
+ */
+FLAC_API FLAC__bool FLAC__metadata_get_streaminfo(const char *filename, FLAC__StreamMetadata *streaminfo);
+
+/** Read the VORBIS_COMMENT metadata block of the given FLAC file. This
+ * function will try to skip any ID3v2 tag at the head of the file.
+ *
+ * \param filename The path to the FLAC file to read.
+ * \param tags The address where the returned pointer will be
+ * stored. The \a tags object must be deleted by
+ * the caller using FLAC__metadata_object_delete().
+ * \assert
+ * \code filename != NULL \endcode
+ * \code tags != NULL \endcode
+ * \retval FLAC__bool
+ * \c true if a valid VORBIS_COMMENT block was read from \a filename,
+ * and \a *tags will be set to the address of the metadata structure.
+ * Returns \c false if there was a memory allocation error, a file
+ * decoder error, or the file contained no VORBIS_COMMENT block, and
+ * \a *tags will be set to \c NULL.
+ */
+FLAC_API FLAC__bool FLAC__metadata_get_tags(const char *filename, FLAC__StreamMetadata **tags);
+
+/** Read the CUESHEET metadata block of the given FLAC file. This
+ * function will try to skip any ID3v2 tag at the head of the file.
+ *
+ * \param filename The path to the FLAC file to read.
+ * \param cuesheet The address where the returned pointer will be
+ * stored. The \a cuesheet object must be deleted by
+ * the caller using FLAC__metadata_object_delete().
+ * \assert
+ * \code filename != NULL \endcode
+ * \code cuesheet != NULL \endcode
+ * \retval FLAC__bool
+ * \c true if a valid CUESHEET block was read from \a filename,
+ * and \a *cuesheet will be set to the address of the metadata
+ * structure. Returns \c false if there was a memory allocation
+ * error, a file decoder error, or the file contained no CUESHEET
+ * block, and \a *cuesheet will be set to \c NULL.
+ */
+FLAC_API FLAC__bool FLAC__metadata_get_cuesheet(const char *filename, FLAC__StreamMetadata **cuesheet);
+
+/** Read a PICTURE metadata block of the given FLAC file. This
+ * function will try to skip any ID3v2 tag at the head of the file.
+ * Since there can be more than one PICTURE block in a file, this
+ * function takes a number of parameters that act as constraints to
+ * the search. The PICTURE block with the largest area matching all
+ * the constraints will be returned, or \a *picture will be set to
+ * \c NULL if there was no such block.
+ *
+ * \param filename The path to the FLAC file to read.
+ * \param picture The address where the returned pointer will be
+ * stored. The \a picture object must be deleted by
+ * the caller using FLAC__metadata_object_delete().
+ * \param type The desired picture type. Use \c -1 to mean
+ * "any type".
+ * \param mime_type The desired MIME type, e.g. "image/jpeg". The
+ * string will be matched exactly. Use \c NULL to
+ * mean "any MIME type".
+ * \param description The desired description. The string will be
+ * matched exactly. Use \c NULL to mean "any
+ * description".
+ * \param max_width The maximum width in pixels desired. Use
+ * \c (unsigned)(-1) to mean "any width".
+ * \param max_height The maximum height in pixels desired. Use
+ * \c (unsigned)(-1) to mean "any height".
+ * \param max_depth The maximum color depth in bits-per-pixel desired.
+ * Use \c (unsigned)(-1) to mean "any depth".
+ * \param max_colors The maximum number of colors desired. Use
+ * \c (unsigned)(-1) to mean "any number of colors".
+ * \assert
+ * \code filename != NULL \endcode
+ * \code picture != NULL \endcode
+ * \retval FLAC__bool
+ * \c true if a valid PICTURE block was read from \a filename,
+ * and \a *picture will be set to the address of the metadata
+ * structure. Returns \c false if there was a memory allocation
+ * error, a file decoder error, or the file contained no PICTURE
+ * block, and \a *picture will be set to \c NULL.
+ */
+FLAC_API FLAC__bool FLAC__metadata_get_picture(const char *filename, FLAC__StreamMetadata **picture, FLAC__StreamMetadata_Picture_Type type, const char *mime_type, const FLAC__byte *description, unsigned max_width, unsigned max_height, unsigned max_depth, unsigned max_colors);
+
+/* \} */
+
+
+/** \defgroup flac_metadata_level1 FLAC/metadata.h: metadata level 1 interface
+ * \ingroup flac_metadata
+ *
+ * \brief
+ * The level 1 interface provides read-write access to FLAC file metadata and
+ * operates directly on the FLAC file.
+ *
+ * The general usage of this interface is:
+ *
+ * - Create an iterator using FLAC__metadata_simple_iterator_new()
+ * - Attach it to a file using FLAC__metadata_simple_iterator_init() and check
+ * the exit code. Call FLAC__metadata_simple_iterator_is_writable() to
+ * see if the file is writable, or only read access is allowed.
+ * - Use FLAC__metadata_simple_iterator_next() and
+ * FLAC__metadata_simple_iterator_prev() to traverse the blocks.
+ * This is does not read the actual blocks themselves.
+ * FLAC__metadata_simple_iterator_next() is relatively fast.
+ * FLAC__metadata_simple_iterator_prev() is slower since it needs to search
+ * forward from the front of the file.
+ * - Use FLAC__metadata_simple_iterator_get_block_type() or
+ * FLAC__metadata_simple_iterator_get_block() to access the actual data at
+ * the current iterator position. The returned object is yours to modify
+ * and free.
+ * - Use FLAC__metadata_simple_iterator_set_block() to write a modified block
+ * back. You must have write permission to the original file. Make sure to
+ * read the whole comment to FLAC__metadata_simple_iterator_set_block()
+ * below.
+ * - Use FLAC__metadata_simple_iterator_insert_block_after() to add new blocks.
+ * Use the object creation functions from
+ * \link flac_metadata_object here \endlink to generate new objects.
+ * - Use FLAC__metadata_simple_iterator_delete_block() to remove the block
+ * currently referred to by the iterator, or replace it with padding.
+ * - Destroy the iterator with FLAC__metadata_simple_iterator_delete() when
+ * finished.
+ *
+ * \note
+ * The FLAC file remains open the whole time between
+ * FLAC__metadata_simple_iterator_init() and
+ * FLAC__metadata_simple_iterator_delete(), so make sure you are not altering
+ * the file during this time.
+ *
+ * \note
+ * Do not modify the \a is_last, \a length, or \a type fields of returned
+ * FLAC__StreamMetadata objects. These are managed automatically.
+ *
+ * \note
+ * If any of the modification functions
+ * (FLAC__metadata_simple_iterator_set_block(),
+ * FLAC__metadata_simple_iterator_delete_block(),
+ * FLAC__metadata_simple_iterator_insert_block_after(), etc.) return \c false,
+ * you should delete the iterator as it may no longer be valid.
+ *
+ * \{
+ */
+
+struct FLAC__Metadata_SimpleIterator;
+/** The opaque structure definition for the level 1 iterator type.
+ * See the
+ * \link flac_metadata_level1 metadata level 1 module \endlink
+ * for a detailed description.
+ */
+typedef struct FLAC__Metadata_SimpleIterator FLAC__Metadata_SimpleIterator;
+
+/** Status type for FLAC__Metadata_SimpleIterator.
+ *
+ * The iterator's current status can be obtained by calling FLAC__metadata_simple_iterator_status().
+ */
+typedef enum {
+
+ FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK = 0,
+ /**< The iterator is in the normal OK state */
+
+ FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ILLEGAL_INPUT,
+ /**< The data passed into a function violated the function's usage criteria */
+
+ FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ERROR_OPENING_FILE,
+ /**< The iterator could not open the target file */
+
+ FLAC__METADATA_SIMPLE_ITERATOR_STATUS_NOT_A_FLAC_FILE,
+ /**< The iterator could not find the FLAC signature at the start of the file */
+
+ FLAC__METADATA_SIMPLE_ITERATOR_STATUS_NOT_WRITABLE,
+ /**< The iterator tried to write to a file that was not writable */
+
+ FLAC__METADATA_SIMPLE_ITERATOR_STATUS_BAD_METADATA,
+ /**< The iterator encountered input that does not conform to the FLAC metadata specification */
+
+ FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR,
+ /**< The iterator encountered an error while reading the FLAC file */
+
+ FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR,
+ /**< The iterator encountered an error while seeking in the FLAC file */
+
+ FLAC__METADATA_SIMPLE_ITERATOR_STATUS_WRITE_ERROR,
+ /**< The iterator encountered an error while writing the FLAC file */
+
+ FLAC__METADATA_SIMPLE_ITERATOR_STATUS_RENAME_ERROR,
+ /**< The iterator encountered an error renaming the FLAC file */
+
+ FLAC__METADATA_SIMPLE_ITERATOR_STATUS_UNLINK_ERROR,
+ /**< The iterator encountered an error removing the temporary file */
+
+ FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR,
+ /**< Memory allocation failed */
+
+ FLAC__METADATA_SIMPLE_ITERATOR_STATUS_INTERNAL_ERROR
+ /**< The caller violated an assertion or an unexpected error occurred */
+
+} FLAC__Metadata_SimpleIteratorStatus;
+
+/** Maps a FLAC__Metadata_SimpleIteratorStatus to a C string.
+ *
+ * Using a FLAC__Metadata_SimpleIteratorStatus as the index to this array
+ * will give the string equivalent. The contents should not be modified.
+ */
+extern FLAC_API const char * const FLAC__Metadata_SimpleIteratorStatusString[];
+
+
+/** Create a new iterator instance.
+ *
+ * \retval FLAC__Metadata_SimpleIterator*
+ * \c NULL if there was an error allocating memory, else the new instance.
+ */
+FLAC_API FLAC__Metadata_SimpleIterator *FLAC__metadata_simple_iterator_new(void);
+
+/** Free an iterator instance. Deletes the object pointed to by \a iterator.
+ *
+ * \param iterator A pointer to an existing iterator.
+ * \assert
+ * \code iterator != NULL \endcode
+ */
+FLAC_API void FLAC__metadata_simple_iterator_delete(FLAC__Metadata_SimpleIterator *iterator);
+
+/** Get the current status of the iterator. Call this after a function
+ * returns \c false to get the reason for the error. Also resets the status
+ * to FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK.
+ *
+ * \param iterator A pointer to an existing iterator.
+ * \assert
+ * \code iterator != NULL \endcode
+ * \retval FLAC__Metadata_SimpleIteratorStatus
+ * The current status of the iterator.
+ */
+FLAC_API FLAC__Metadata_SimpleIteratorStatus FLAC__metadata_simple_iterator_status(FLAC__Metadata_SimpleIterator *iterator);
+
+/** Initialize the iterator to point to the first metadata block in the
+ * given FLAC file.
+ *
+ * \param iterator A pointer to an existing iterator.
+ * \param filename The path to the FLAC file.
+ * \param read_only If \c true, the FLAC file will be opened
+ * in read-only mode; if \c false, the FLAC
+ * file will be opened for edit even if no
+ * edits are performed.
+ * \param preserve_file_stats If \c true, the owner and modification
+ * time will be preserved even if the FLAC
+ * file is written to.
+ * \assert
+ * \code iterator != NULL \endcode
+ * \code filename != NULL \endcode
+ * \retval FLAC__bool
+ * \c false if a memory allocation error occurs, the file can't be
+ * opened, or another error occurs, else \c true.
+ */
+FLAC_API FLAC__bool FLAC__metadata_simple_iterator_init(FLAC__Metadata_SimpleIterator *iterator, const char *filename, FLAC__bool read_only, FLAC__bool preserve_file_stats);
+
+/** Returns \c true if the FLAC file is writable. If \c false, calls to
+ * FLAC__metadata_simple_iterator_set_block() and
+ * FLAC__metadata_simple_iterator_insert_block_after() will fail.
+ *
+ * \param iterator A pointer to an existing iterator.
+ * \assert
+ * \code iterator != NULL \endcode
+ * \retval FLAC__bool
+ * See above.
+ */
+FLAC_API FLAC__bool FLAC__metadata_simple_iterator_is_writable(const FLAC__Metadata_SimpleIterator *iterator);
+
+/** Moves the iterator forward one metadata block, returning \c false if
+ * already at the end.
+ *
+ * \param iterator A pointer to an existing initialized iterator.
+ * \assert
+ * \code iterator != NULL \endcode
+ * \a iterator has been successfully initialized with
+ * FLAC__metadata_simple_iterator_init()
+ * \retval FLAC__bool
+ * \c false if already at the last metadata block of the chain, else
+ * \c true.
+ */
+FLAC_API FLAC__bool FLAC__metadata_simple_iterator_next(FLAC__Metadata_SimpleIterator *iterator);
+
+/** Moves the iterator backward one metadata block, returning \c false if
+ * already at the beginning.
+ *
+ * \param iterator A pointer to an existing initialized iterator.
+ * \assert
+ * \code iterator != NULL \endcode
+ * \a iterator has been successfully initialized with
+ * FLAC__metadata_simple_iterator_init()
+ * \retval FLAC__bool
+ * \c false if already at the first metadata block of the chain, else
+ * \c true.
+ */
+FLAC_API FLAC__bool FLAC__metadata_simple_iterator_prev(FLAC__Metadata_SimpleIterator *iterator);
+
+/** Returns a flag telling if the current metadata block is the last.
+ *
+ * \param iterator A pointer to an existing initialized iterator.
+ * \assert
+ * \code iterator != NULL \endcode
+ * \a iterator has been successfully initialized with
+ * FLAC__metadata_simple_iterator_init()
+ * \retval FLAC__bool
+ * \c true if the current metadata block is the last in the file,
+ * else \c false.
+ */
+FLAC_API FLAC__bool FLAC__metadata_simple_iterator_is_last(const FLAC__Metadata_SimpleIterator *iterator);
+
+/** Get the offset of the metadata block at the current position. This
+ * avoids reading the actual block data which can save time for large
+ * blocks.
+ *
+ * \param iterator A pointer to an existing initialized iterator.
+ * \assert
+ * \code iterator != NULL \endcode
+ * \a iterator has been successfully initialized with
+ * FLAC__metadata_simple_iterator_init()
+ * \retval off_t
+ * The offset of the metadata block at the current iterator position.
+ * This is the byte offset relative to the beginning of the file of
+ * the current metadata block's header.
+ */
+FLAC_API off_t FLAC__metadata_simple_iterator_get_block_offset(const FLAC__Metadata_SimpleIterator *iterator);
+
+/** Get the type of the metadata block at the current position. This
+ * avoids reading the actual block data which can save time for large
+ * blocks.
+ *
+ * \param iterator A pointer to an existing initialized iterator.
+ * \assert
+ * \code iterator != NULL \endcode
+ * \a iterator has been successfully initialized with
+ * FLAC__metadata_simple_iterator_init()
+ * \retval FLAC__MetadataType
+ * The type of the metadata block at the current iterator position.
+ */
+FLAC_API FLAC__MetadataType FLAC__metadata_simple_iterator_get_block_type(const FLAC__Metadata_SimpleIterator *iterator);
+
+/** Get the length of the metadata block at the current position. This
+ * avoids reading the actual block data which can save time for large
+ * blocks.
+ *
+ * \param iterator A pointer to an existing initialized iterator.
+ * \assert
+ * \code iterator != NULL \endcode
+ * \a iterator has been successfully initialized with
+ * FLAC__metadata_simple_iterator_init()
+ * \retval unsigned
+ * The length of the metadata block at the current iterator position.
+ * The is same length as that in the
+ * <a href="http://flac.sourceforge.net/format.html#metadata_block_header">metadata block header</a>,
+ * i.e. the length of the metadata body that follows the header.
+ */
+FLAC_API unsigned FLAC__metadata_simple_iterator_get_block_length(const FLAC__Metadata_SimpleIterator *iterator);
+
+/** Get the application ID of the \c APPLICATION block at the current
+ * position. This avoids reading the actual block data which can save
+ * time for large blocks.
+ *
+ * \param iterator A pointer to an existing initialized iterator.
+ * \param id A pointer to a buffer of at least \c 4 bytes where
+ * the ID will be stored.
+ * \assert
+ * \code iterator != NULL \endcode
+ * \code id != NULL \endcode
+ * \a iterator has been successfully initialized with
+ * FLAC__metadata_simple_iterator_init()
+ * \retval FLAC__bool
+ * \c true if the ID was successfully read, else \c false, in which
+ * case you should check FLAC__metadata_simple_iterator_status() to
+ * find out why. If the status is
+ * \c FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ILLEGAL_INPUT, then the
+ * current metadata block is not an \c APPLICATION block. Otherwise
+ * if the status is
+ * \c FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR or
+ * \c FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR, an I/O error
+ * occurred and the iterator can no longer be used.
+ */
+FLAC_API FLAC__bool FLAC__metadata_simple_iterator_get_application_id(FLAC__Metadata_SimpleIterator *iterator, FLAC__byte *id);
+
+/** Get the metadata block at the current position. You can modify the
+ * block but must use FLAC__metadata_simple_iterator_set_block() to
+ * write it back to the FLAC file.
+ *
+ * You must call FLAC__metadata_object_delete() on the returned object
+ * when you are finished with it.
+ *
+ * \param iterator A pointer to an existing initialized iterator.
+ * \assert
+ * \code iterator != NULL \endcode
+ * \a iterator has been successfully initialized with
+ * FLAC__metadata_simple_iterator_init()
+ * \retval FLAC__StreamMetadata*
+ * The current metadata block, or \c NULL if there was a memory
+ * allocation error.
+ */
+FLAC_API FLAC__StreamMetadata *FLAC__metadata_simple_iterator_get_block(FLAC__Metadata_SimpleIterator *iterator);
+
+/** Write a block back to the FLAC file. This function tries to be
+ * as efficient as possible; how the block is actually written is
+ * shown by the following:
+ *
+ * Existing block is a STREAMINFO block and the new block is a
+ * STREAMINFO block: the new block is written in place. Make sure
+ * you know what you're doing when changing the values of a
+ * STREAMINFO block.
+ *
+ * Existing block is a STREAMINFO block and the new block is a
+ * not a STREAMINFO block: this is an error since the first block
+ * must be a STREAMINFO block. Returns \c false without altering the
+ * file.
+ *
+ * Existing block is not a STREAMINFO block and the new block is a
+ * STREAMINFO block: this is an error since there may be only one
+ * STREAMINFO block. Returns \c false without altering the file.
+ *
+ * Existing block and new block are the same length: the existing
+ * block will be replaced by the new block, written in place.
+ *
+ * Existing block is longer than new block: if use_padding is \c true,
+ * the existing block will be overwritten in place with the new
+ * block followed by a PADDING block, if possible, to make the total
+ * size the same as the existing block. Remember that a padding
+ * block requires at least four bytes so if the difference in size
+ * between the new block and existing block is less than that, the
+ * entire file will have to be rewritten, using the new block's
+ * exact size. If use_padding is \c false, the entire file will be
+ * rewritten, replacing the existing block by the new block.
+ *
+ * Existing block is shorter than new block: if use_padding is \c true,
+ * the function will try and expand the new block into the following
+ * PADDING block, if it exists and doing so won't shrink the PADDING
+ * block to less than 4 bytes. If there is no following PADDING
+ * block, or it will shrink to less than 4 bytes, or use_padding is
+ * \c false, the entire file is rewritten, replacing the existing block
+ * with the new block. Note that in this case any following PADDING
+ * block is preserved as is.
+ *
+ * After writing the block, the iterator will remain in the same
+ * place, i.e. pointing to the new block.
+ *
+ * \param iterator A pointer to an existing initialized iterator.
+ * \param block The block to set.
+ * \param use_padding See above.
+ * \assert
+ * \code iterator != NULL \endcode
+ * \a iterator has been successfully initialized with
+ * FLAC__metadata_simple_iterator_init()
+ * \code block != NULL \endcode
+ * \retval FLAC__bool
+ * \c true if successful, else \c false.
+ */
+FLAC_API FLAC__bool FLAC__metadata_simple_iterator_set_block(FLAC__Metadata_SimpleIterator *iterator, FLAC__StreamMetadata *block, FLAC__bool use_padding);
+
+/** This is similar to FLAC__metadata_simple_iterator_set_block()
+ * except that instead of writing over an existing block, it appends
+ * a block after the existing block. \a use_padding is again used to
+ * tell the function to try an expand into following padding in an
+ * attempt to avoid rewriting the entire file.
+ *
+ * This function will fail and return \c false if given a STREAMINFO
+ * block.
+ *
+ * After writing the block, the iterator will be pointing to the
+ * new block.
+ *
+ * \param iterator A pointer to an existing initialized iterator.
+ * \param block The block to set.
+ * \param use_padding See above.
+ * \assert
+ * \code iterator != NULL \endcode
+ * \a iterator has been successfully initialized with
+ * FLAC__metadata_simple_iterator_init()
+ * \code block != NULL \endcode
+ * \retval FLAC__bool
+ * \c true if successful, else \c false.
+ */
+FLAC_API FLAC__bool FLAC__metadata_simple_iterator_insert_block_after(FLAC__Metadata_SimpleIterator *iterator, FLAC__StreamMetadata *block, FLAC__bool use_padding);
+
+/** Deletes the block at the current position. This will cause the
+ * entire FLAC file to be rewritten, unless \a use_padding is \c true,
+ * in which case the block will be replaced by an equal-sized PADDING
+ * block. The iterator will be left pointing to the block before the
+ * one just deleted.
+ *
+ * You may not delete the STREAMINFO block.
+ *
+ * \param iterator A pointer to an existing initialized iterator.
+ * \param use_padding See above.
+ * \assert
+ * \code iterator != NULL \endcode
+ * \a iterator has been successfully initialized with
+ * FLAC__metadata_simple_iterator_init()
+ * \retval FLAC__bool
+ * \c true if successful, else \c false.
+ */
+FLAC_API FLAC__bool FLAC__metadata_simple_iterator_delete_block(FLAC__Metadata_SimpleIterator *iterator, FLAC__bool use_padding);
+
+/* \} */
+
+
+/** \defgroup flac_metadata_level2 FLAC/metadata.h: metadata level 2 interface
+ * \ingroup flac_metadata
+ *
+ * \brief
+ * The level 2 interface provides read-write access to FLAC file metadata;
+ * all metadata is read into memory, operated on in memory, and then written
+ * to file, which is more efficient than level 1 when editing multiple blocks.
+ *
+ * Currently Ogg FLAC is supported for read only, via
+ * FLAC__metadata_chain_read_ogg() but a subsequent
+ * FLAC__metadata_chain_write() will fail.
+ *
+ * The general usage of this interface is:
+ *
+ * - Create a new chain using FLAC__metadata_chain_new(). A chain is a
+ * linked list of FLAC metadata blocks.
+ * - Read all metadata into the the chain from a FLAC file using
+ * FLAC__metadata_chain_read() or FLAC__metadata_chain_read_ogg() and
+ * check the status.
+ * - Optionally, consolidate the padding using
+ * FLAC__metadata_chain_merge_padding() or
+ * FLAC__metadata_chain_sort_padding().
+ * - Create a new iterator using FLAC__metadata_iterator_new()
+ * - Initialize the iterator to point to the first element in the chain
+ * using FLAC__metadata_iterator_init()
+ * - Traverse the chain using FLAC__metadata_iterator_next and
+ * FLAC__metadata_iterator_prev().
+ * - Get a block for reading or modification using
+ * FLAC__metadata_iterator_get_block(). The pointer to the object
+ * inside the chain is returned, so the block is yours to modify.
+ * Changes will be reflected in the FLAC file when you write the
+ * chain. You can also add and delete blocks (see functions below).
+ * - When done, write out the chain using FLAC__metadata_chain_write().
+ * Make sure to read the whole comment to the function below.
+ * - Delete the chain using FLAC__metadata_chain_delete().
+ *
+ * \note
+ * Even though the FLAC file is not open while the chain is being
+ * manipulated, you must not alter the file externally during
+ * this time. The chain assumes the FLAC file will not change
+ * between the time of FLAC__metadata_chain_read()/FLAC__metadata_chain_read_ogg()
+ * and FLAC__metadata_chain_write().
+ *
+ * \note
+ * Do not modify the is_last, length, or type fields of returned
+ * FLAC__StreamMetadata objects. These are managed automatically.
+ *
+ * \note
+ * The metadata objects returned by FLAC__metadata_iterator_get_block()
+ * are owned by the chain; do not FLAC__metadata_object_delete() them.
+ * In the same way, blocks passed to FLAC__metadata_iterator_set_block()
+ * become owned by the chain and they will be deleted when the chain is
+ * deleted.
+ *
+ * \{
+ */
+
+struct FLAC__Metadata_Chain;
+/** The opaque structure definition for the level 2 chain type.
+ */
+typedef struct FLAC__Metadata_Chain FLAC__Metadata_Chain;
+
+struct FLAC__Metadata_Iterator;
+/** The opaque structure definition for the level 2 iterator type.
+ */
+typedef struct FLAC__Metadata_Iterator FLAC__Metadata_Iterator;
+
+typedef enum {
+ FLAC__METADATA_CHAIN_STATUS_OK = 0,
+ /**< The chain is in the normal OK state */
+
+ FLAC__METADATA_CHAIN_STATUS_ILLEGAL_INPUT,
+ /**< The data passed into a function violated the function's usage criteria */
+
+ FLAC__METADATA_CHAIN_STATUS_ERROR_OPENING_FILE,
+ /**< The chain could not open the target file */
+
+ FLAC__METADATA_CHAIN_STATUS_NOT_A_FLAC_FILE,
+ /**< The chain could not find the FLAC signature at the start of the file */
+
+ FLAC__METADATA_CHAIN_STATUS_NOT_WRITABLE,
+ /**< The chain tried to write to a file that was not writable */
+
+ FLAC__METADATA_CHAIN_STATUS_BAD_METADATA,
+ /**< The chain encountered input that does not conform to the FLAC metadata specification */
+
+ FLAC__METADATA_CHAIN_STATUS_READ_ERROR,
+ /**< The chain encountered an error while reading the FLAC file */
+
+ FLAC__METADATA_CHAIN_STATUS_SEEK_ERROR,
+ /**< The chain encountered an error while seeking in the FLAC file */
+
+ FLAC__METADATA_CHAIN_STATUS_WRITE_ERROR,
+ /**< The chain encountered an error while writing the FLAC file */
+
+ FLAC__METADATA_CHAIN_STATUS_RENAME_ERROR,
+ /**< The chain encountered an error renaming the FLAC file */
+
+ FLAC__METADATA_CHAIN_STATUS_UNLINK_ERROR,
+ /**< The chain encountered an error removing the temporary file */
+
+ FLAC__METADATA_CHAIN_STATUS_MEMORY_ALLOCATION_ERROR,
+ /**< Memory allocation failed */
+
+ FLAC__METADATA_CHAIN_STATUS_INTERNAL_ERROR,
+ /**< The caller violated an assertion or an unexpected error occurred */
+
+ FLAC__METADATA_CHAIN_STATUS_INVALID_CALLBACKS,
+ /**< One or more of the required callbacks was NULL */
+
+ FLAC__METADATA_CHAIN_STATUS_READ_WRITE_MISMATCH,
+ /**< FLAC__metadata_chain_write() was called on a chain read by
+ * FLAC__metadata_chain_read_with_callbacks()/FLAC__metadata_chain_read_ogg_with_callbacks(),
+ * or
+ * FLAC__metadata_chain_write_with_callbacks()/FLAC__metadata_chain_write_with_callbacks_and_tempfile()
+ * was called on a chain read by
+ * FLAC__metadata_chain_read()/FLAC__metadata_chain_read_ogg().
+ * Matching read/write methods must always be used. */
+
+ FLAC__METADATA_CHAIN_STATUS_WRONG_WRITE_CALL
+ /**< FLAC__metadata_chain_write_with_callbacks() was called when the
+ * chain write requires a tempfile; use
+ * FLAC__metadata_chain_write_with_callbacks_and_tempfile() instead.
+ * Or, FLAC__metadata_chain_write_with_callbacks_and_tempfile() was
+ * called when the chain write does not require a tempfile; use
+ * FLAC__metadata_chain_write_with_callbacks() instead.
+ * Always check FLAC__metadata_chain_check_if_tempfile_needed()
+ * before writing via callbacks. */
+
+} FLAC__Metadata_ChainStatus;
+
+/** Maps a FLAC__Metadata_ChainStatus to a C string.
+ *
+ * Using a FLAC__Metadata_ChainStatus as the index to this array
+ * will give the string equivalent. The contents should not be modified.
+ */
+extern FLAC_API const char * const FLAC__Metadata_ChainStatusString[];
+
+/*********** FLAC__Metadata_Chain ***********/
+
+/** Create a new chain instance.
+ *
+ * \retval FLAC__Metadata_Chain*
+ * \c NULL if there was an error allocating memory, else the new instance.
+ */
+FLAC_API FLAC__Metadata_Chain *FLAC__metadata_chain_new(void);
+
+/** Free a chain instance. Deletes the object pointed to by \a chain.
+ *
+ * \param chain A pointer to an existing chain.
+ * \assert
+ * \code chain != NULL \endcode
+ */
+FLAC_API void FLAC__metadata_chain_delete(FLAC__Metadata_Chain *chain);
+
+/** Get the current status of the chain. Call this after a function
+ * returns \c false to get the reason for the error. Also resets the
+ * status to FLAC__METADATA_CHAIN_STATUS_OK.
+ *
+ * \param chain A pointer to an existing chain.
+ * \assert
+ * \code chain != NULL \endcode
+ * \retval FLAC__Metadata_ChainStatus
+ * The current status of the chain.
+ */
+FLAC_API FLAC__Metadata_ChainStatus FLAC__metadata_chain_status(FLAC__Metadata_Chain *chain);
+
+/** Read all metadata from a FLAC file into the chain.
+ *
+ * \param chain A pointer to an existing chain.
+ * \param filename The path to the FLAC file to read.
+ * \assert
+ * \code chain != NULL \endcode
+ * \code filename != NULL \endcode
+ * \retval FLAC__bool
+ * \c true if a valid list of metadata blocks was read from
+ * \a filename, else \c false. On failure, check the status with
+ * FLAC__metadata_chain_status().
+ */
+FLAC_API FLAC__bool FLAC__metadata_chain_read(FLAC__Metadata_Chain *chain, const char *filename);
+
+/** Read all metadata from an Ogg FLAC file into the chain.
+ *
+ * \note Ogg FLAC metadata data writing is not supported yet and
+ * FLAC__metadata_chain_write() will fail.
+ *
+ * \param chain A pointer to an existing chain.
+ * \param filename The path to the Ogg FLAC file to read.
+ * \assert
+ * \code chain != NULL \endcode
+ * \code filename != NULL \endcode
+ * \retval FLAC__bool
+ * \c true if a valid list of metadata blocks was read from
+ * \a filename, else \c false. On failure, check the status with
+ * FLAC__metadata_chain_status().
+ */
+FLAC_API FLAC__bool FLAC__metadata_chain_read_ogg(FLAC__Metadata_Chain *chain, const char *filename);
+
+/** Read all metadata from a FLAC stream into the chain via I/O callbacks.
+ *
+ * The \a handle need only be open for reading, but must be seekable.
+ * The equivalent minimum stdio fopen() file mode is \c "r" (or \c "rb"
+ * for Windows).
+ *
+ * \param chain A pointer to an existing chain.
+ * \param handle The I/O handle of the FLAC stream to read. The
+ * handle will NOT be closed after the metadata is read;
+ * that is the duty of the caller.
+ * \param callbacks
+ * A set of callbacks to use for I/O. The mandatory
+ * callbacks are \a read, \a seek, and \a tell.
+ * \assert
+ * \code chain != NULL \endcode
+ * \retval FLAC__bool
+ * \c true if a valid list of metadata blocks was read from
+ * \a handle, else \c false. On failure, check the status with
+ * FLAC__metadata_chain_status().
+ */
+FLAC_API FLAC__bool FLAC__metadata_chain_read_with_callbacks(FLAC__Metadata_Chain *chain, FLAC__IOHandle handle, FLAC__IOCallbacks callbacks);
+
+/** Read all metadata from an Ogg FLAC stream into the chain via I/O callbacks.
+ *
+ * The \a handle need only be open for reading, but must be seekable.
+ * The equivalent minimum stdio fopen() file mode is \c "r" (or \c "rb"
+ * for Windows).
+ *
+ * \note Ogg FLAC metadata data writing is not supported yet and
+ * FLAC__metadata_chain_write() will fail.
+ *
+ * \param chain A pointer to an existing chain.
+ * \param handle The I/O handle of the Ogg FLAC stream to read. The
+ * handle will NOT be closed after the metadata is read;
+ * that is the duty of the caller.
+ * \param callbacks
+ * A set of callbacks to use for I/O. The mandatory
+ * callbacks are \a read, \a seek, and \a tell.
+ * \assert
+ * \code chain != NULL \endcode
+ * \retval FLAC__bool
+ * \c true if a valid list of metadata blocks was read from
+ * \a handle, else \c false. On failure, check the status with
+ * FLAC__metadata_chain_status().
+ */
+FLAC_API FLAC__bool FLAC__metadata_chain_read_ogg_with_callbacks(FLAC__Metadata_Chain *chain, FLAC__IOHandle handle, FLAC__IOCallbacks callbacks);
+
+/** Checks if writing the given chain would require the use of a
+ * temporary file, or if it could be written in place.
+ *
+ * Under certain conditions, padding can be utilized so that writing
+ * edited metadata back to the FLAC file does not require rewriting the
+ * entire file. If rewriting is required, then a temporary workfile is
+ * required. When writing metadata using callbacks, you must check
+ * this function to know whether to call
+ * FLAC__metadata_chain_write_with_callbacks() or
+ * FLAC__metadata_chain_write_with_callbacks_and_tempfile(). When
+ * writing with FLAC__metadata_chain_write(), the temporary file is
+ * handled internally.
+ *
+ * \param chain A pointer to an existing chain.
+ * \param use_padding
+ * Whether or not padding will be allowed to be used
+ * during the write. The value of \a use_padding given
+ * here must match the value later passed to
+ * FLAC__metadata_chain_write_with_callbacks() or
+ * FLAC__metadata_chain_write_with_callbacks_with_tempfile().
+ * \assert
+ * \code chain != NULL \endcode
+ * \retval FLAC__bool
+ * \c true if writing the current chain would require a tempfile, or
+ * \c false if metadata can be written in place.
+ */
+FLAC_API FLAC__bool FLAC__metadata_chain_check_if_tempfile_needed(FLAC__Metadata_Chain *chain, FLAC__bool use_padding);
+
+/** Write all metadata out to the FLAC file. This function tries to be as
+ * efficient as possible; how the metadata is actually written is shown by
+ * the following:
+ *
+ * If the current chain is the same size as the existing metadata, the new
+ * data is written in place.
+ *
+ * If the current chain is longer than the existing metadata, and
+ * \a use_padding is \c true, and the last block is a PADDING block of
+ * sufficient length, the function will truncate the final padding block
+ * so that the overall size of the metadata is the same as the existing
+ * metadata, and then just rewrite the metadata. Otherwise, if not all of
+ * the above conditions are met, the entire FLAC file must be rewritten.
+ * If you want to use padding this way it is a good idea to call
+ * FLAC__metadata_chain_sort_padding() first so that you have the maximum
+ * amount of padding to work with, unless you need to preserve ordering
+ * of the PADDING blocks for some reason.
+ *
+ * If the current chain is shorter than the existing metadata, and
+ * \a use_padding is \c true, and the final block is a PADDING block, the padding
+ * is extended to make the overall size the same as the existing data. If
+ * \a use_padding is \c true and the last block is not a PADDING block, a new
+ * PADDING block is added to the end of the new data to make it the same
+ * size as the existing data (if possible, see the note to
+ * FLAC__metadata_simple_iterator_set_block() about the four byte limit)
+ * and the new data is written in place. If none of the above apply or
+ * \a use_padding is \c false, the entire FLAC file is rewritten.
+ *
+ * If \a preserve_file_stats is \c true, the owner and modification time will
+ * be preserved even if the FLAC file is written.
+ *
+ * For this write function to be used, the chain must have been read with
+ * FLAC__metadata_chain_read()/FLAC__metadata_chain_read_ogg(), not
+ * FLAC__metadata_chain_read_with_callbacks()/FLAC__metadata_chain_read_ogg_with_callbacks().
+ *
+ * \param chain A pointer to an existing chain.
+ * \param use_padding See above.
+ * \param preserve_file_stats See above.
+ * \assert
+ * \code chain != NULL \endcode
+ * \retval FLAC__bool
+ * \c true if the write succeeded, else \c false. On failure,
+ * check the status with FLAC__metadata_chain_status().
+ */
+FLAC_API FLAC__bool FLAC__metadata_chain_write(FLAC__Metadata_Chain *chain, FLAC__bool use_padding, FLAC__bool preserve_file_stats);
+
+/** Write all metadata out to a FLAC stream via callbacks.
+ *
+ * (See FLAC__metadata_chain_write() for the details on how padding is
+ * used to write metadata in place if possible.)
+ *
+ * The \a handle must be open for updating and be seekable. The
+ * equivalent minimum stdio fopen() file mode is \c "r+" (or \c "r+b"
+ * for Windows).
+ *
+ * For this write function to be used, the chain must have been read with
+ * FLAC__metadata_chain_read_with_callbacks()/FLAC__metadata_chain_read_ogg_with_callbacks(),
+ * not FLAC__metadata_chain_read()/FLAC__metadata_chain_read_ogg().
+ * Also, FLAC__metadata_chain_check_if_tempfile_needed() must have returned
+ * \c false.
+ *
+ * \param chain A pointer to an existing chain.
+ * \param use_padding See FLAC__metadata_chain_write()
+ * \param handle The I/O handle of the FLAC stream to write. The
+ * handle will NOT be closed after the metadata is
+ * written; that is the duty of the caller.
+ * \param callbacks A set of callbacks to use for I/O. The mandatory
+ * callbacks are \a write and \a seek.
+ * \assert
+ * \code chain != NULL \endcode
+ * \retval FLAC__bool
+ * \c true if the write succeeded, else \c false. On failure,
+ * check the status with FLAC__metadata_chain_status().
+ */
+FLAC_API FLAC__bool FLAC__metadata_chain_write_with_callbacks(FLAC__Metadata_Chain *chain, FLAC__bool use_padding, FLAC__IOHandle handle, FLAC__IOCallbacks callbacks);
+
+/** Write all metadata out to a FLAC stream via callbacks.
+ *
+ * (See FLAC__metadata_chain_write() for the details on how padding is
+ * used to write metadata in place if possible.)
+ *
+ * This version of the write-with-callbacks function must be used when
+ * FLAC__metadata_chain_check_if_tempfile_needed() returns true. In
+ * this function, you must supply an I/O handle corresponding to the
+ * FLAC file to edit, and a temporary handle to which the new FLAC
+ * file will be written. It is the caller's job to move this temporary
+ * FLAC file on top of the original FLAC file to complete the metadata
+ * edit.
+ *
+ * The \a handle must be open for reading and be seekable. The
+ * equivalent minimum stdio fopen() file mode is \c "r" (or \c "rb"
+ * for Windows).
+ *
+ * The \a temp_handle must be open for writing. The
+ * equivalent minimum stdio fopen() file mode is \c "w" (or \c "wb"
+ * for Windows). It should be an empty stream, or at least positioned
+ * at the start-of-file (in which case it is the caller's duty to
+ * truncate it on return).
+ *
+ * For this write function to be used, the chain must have been read with
+ * FLAC__metadata_chain_read_with_callbacks()/FLAC__metadata_chain_read_ogg_with_callbacks(),
+ * not FLAC__metadata_chain_read()/FLAC__metadata_chain_read_ogg().
+ * Also, FLAC__metadata_chain_check_if_tempfile_needed() must have returned
+ * \c true.
+ *
+ * \param chain A pointer to an existing chain.
+ * \param use_padding See FLAC__metadata_chain_write()
+ * \param handle The I/O handle of the original FLAC stream to read.
+ * The handle will NOT be closed after the metadata is
+ * written; that is the duty of the caller.
+ * \param callbacks A set of callbacks to use for I/O on \a handle.
+ * The mandatory callbacks are \a read, \a seek, and
+ * \a eof.
+ * \param temp_handle The I/O handle of the FLAC stream to write. The
+ * handle will NOT be closed after the metadata is
+ * written; that is the duty of the caller.
+ * \param temp_callbacks
+ * A set of callbacks to use for I/O on temp_handle.
+ * The only mandatory callback is \a write.
+ * \assert
+ * \code chain != NULL \endcode
+ * \retval FLAC__bool
+ * \c true if the write succeeded, else \c false. On failure,
+ * check the status with FLAC__metadata_chain_status().
+ */
+FLAC_API FLAC__bool FLAC__metadata_chain_write_with_callbacks_and_tempfile(FLAC__Metadata_Chain *chain, FLAC__bool use_padding, FLAC__IOHandle handle, FLAC__IOCallbacks callbacks, FLAC__IOHandle temp_handle, FLAC__IOCallbacks temp_callbacks);
+
+/** Merge adjacent PADDING blocks into a single block.
+ *
+ * \note This function does not write to the FLAC file, it only
+ * modifies the chain.
+ *
+ * \warning Any iterator on the current chain will become invalid after this
+ * call. You should delete the iterator and get a new one.
+ *
+ * \param chain A pointer to an existing chain.
+ * \assert
+ * \code chain != NULL \endcode
+ */
+FLAC_API void FLAC__metadata_chain_merge_padding(FLAC__Metadata_Chain *chain);
+
+/** This function will move all PADDING blocks to the end on the metadata,
+ * then merge them into a single block.
+ *
+ * \note This function does not write to the FLAC file, it only
+ * modifies the chain.
+ *
+ * \warning Any iterator on the current chain will become invalid after this
+ * call. You should delete the iterator and get a new one.
+ *
+ * \param chain A pointer to an existing chain.
+ * \assert
+ * \code chain != NULL \endcode
+ */
+FLAC_API void FLAC__metadata_chain_sort_padding(FLAC__Metadata_Chain *chain);
+
+
+/*********** FLAC__Metadata_Iterator ***********/
+
+/** Create a new iterator instance.
+ *
+ * \retval FLAC__Metadata_Iterator*
+ * \c NULL if there was an error allocating memory, else the new instance.
+ */
+FLAC_API FLAC__Metadata_Iterator *FLAC__metadata_iterator_new(void);
+
+/** Free an iterator instance. Deletes the object pointed to by \a iterator.
+ *
+ * \param iterator A pointer to an existing iterator.
+ * \assert
+ * \code iterator != NULL \endcode
+ */
+FLAC_API void FLAC__metadata_iterator_delete(FLAC__Metadata_Iterator *iterator);
+
+/** Initialize the iterator to point to the first metadata block in the
+ * given chain.
+ *
+ * \param iterator A pointer to an existing iterator.
+ * \param chain A pointer to an existing and initialized (read) chain.
+ * \assert
+ * \code iterator != NULL \endcode
+ * \code chain != NULL \endcode
+ */
+FLAC_API void FLAC__metadata_iterator_init(FLAC__Metadata_Iterator *iterator, FLAC__Metadata_Chain *chain);
+
+/** Moves the iterator forward one metadata block, returning \c false if
+ * already at the end.
+ *
+ * \param iterator A pointer to an existing initialized iterator.
+ * \assert
+ * \code iterator != NULL \endcode
+ * \a iterator has been successfully initialized with
+ * FLAC__metadata_iterator_init()
+ * \retval FLAC__bool
+ * \c false if already at the last metadata block of the chain, else
+ * \c true.
+ */
+FLAC_API FLAC__bool FLAC__metadata_iterator_next(FLAC__Metadata_Iterator *iterator);
+
+/** Moves the iterator backward one metadata block, returning \c false if
+ * already at the beginning.
+ *
+ * \param iterator A pointer to an existing initialized iterator.
+ * \assert
+ * \code iterator != NULL \endcode
+ * \a iterator has been successfully initialized with
+ * FLAC__metadata_iterator_init()
+ * \retval FLAC__bool
+ * \c false if already at the first metadata block of the chain, else
+ * \c true.
+ */
+FLAC_API FLAC__bool FLAC__metadata_iterator_prev(FLAC__Metadata_Iterator *iterator);
+
+/** Get the type of the metadata block at the current position.
+ *
+ * \param iterator A pointer to an existing initialized iterator.
+ * \assert
+ * \code iterator != NULL \endcode
+ * \a iterator has been successfully initialized with
+ * FLAC__metadata_iterator_init()
+ * \retval FLAC__MetadataType
+ * The type of the metadata block at the current iterator position.
+ */
+FLAC_API FLAC__MetadataType FLAC__metadata_iterator_get_block_type(const FLAC__Metadata_Iterator *iterator);
+
+/** Get the metadata block at the current position. You can modify
+ * the block in place but must write the chain before the changes
+ * are reflected to the FLAC file. You do not need to call
+ * FLAC__metadata_iterator_set_block() to reflect the changes;
+ * the pointer returned by FLAC__metadata_iterator_get_block()
+ * points directly into the chain.
+ *
+ * \warning
+ * Do not call FLAC__metadata_object_delete() on the returned object;
+ * to delete a block use FLAC__metadata_iterator_delete_block().
+ *
+ * \param iterator A pointer to an existing initialized iterator.
+ * \assert
+ * \code iterator != NULL \endcode
+ * \a iterator has been successfully initialized with
+ * FLAC__metadata_iterator_init()
+ * \retval FLAC__StreamMetadata*
+ * The current metadata block.
+ */
+FLAC_API FLAC__StreamMetadata *FLAC__metadata_iterator_get_block(FLAC__Metadata_Iterator *iterator);
+
+/** Set the metadata block at the current position, replacing the existing
+ * block. The new block passed in becomes owned by the chain and it will be
+ * deleted when the chain is deleted.
+ *
+ * \param iterator A pointer to an existing initialized iterator.
+ * \param block A pointer to a metadata block.
+ * \assert
+ * \code iterator != NULL \endcode
+ * \a iterator has been successfully initialized with
+ * FLAC__metadata_iterator_init()
+ * \code block != NULL \endcode
+ * \retval FLAC__bool
+ * \c false if the conditions in the above description are not met, or
+ * a memory allocation error occurs, otherwise \c true.
+ */
+FLAC_API FLAC__bool FLAC__metadata_iterator_set_block(FLAC__Metadata_Iterator *iterator, FLAC__StreamMetadata *block);
+
+/** Removes the current block from the chain. If \a replace_with_padding is
+ * \c true, the block will instead be replaced with a padding block of equal
+ * size. You can not delete the STREAMINFO block. The iterator will be
+ * left pointing to the block before the one just "deleted", even if
+ * \a replace_with_padding is \c true.
+ *
+ * \param iterator A pointer to an existing initialized iterator.
+ * \param replace_with_padding See above.
+ * \assert
+ * \code iterator != NULL \endcode
+ * \a iterator has been successfully initialized with
+ * FLAC__metadata_iterator_init()
+ * \retval FLAC__bool
+ * \c false if the conditions in the above description are not met,
+ * otherwise \c true.
+ */
+FLAC_API FLAC__bool FLAC__metadata_iterator_delete_block(FLAC__Metadata_Iterator *iterator, FLAC__bool replace_with_padding);
+
+/** Insert a new block before the current block. You cannot insert a block
+ * before the first STREAMINFO block. You cannot insert a STREAMINFO block
+ * as there can be only one, the one that already exists at the head when you
+ * read in a chain. The chain takes ownership of the new block and it will be
+ * deleted when the chain is deleted. The iterator will be left pointing to
+ * the new block.
+ *
+ * \param iterator A pointer to an existing initialized iterator.
+ * \param block A pointer to a metadata block to insert.
+ * \assert
+ * \code iterator != NULL \endcode
+ * \a iterator has been successfully initialized with
+ * FLAC__metadata_iterator_init()
+ * \retval FLAC__bool
+ * \c false if the conditions in the above description are not met, or
+ * a memory allocation error occurs, otherwise \c true.
+ */
+FLAC_API FLAC__bool FLAC__metadata_iterator_insert_block_before(FLAC__Metadata_Iterator *iterator, FLAC__StreamMetadata *block);
+
+/** Insert a new block after the current block. You cannot insert a STREAMINFO
+ * block as there can be only one, the one that already exists at the head when
+ * you read in a chain. The chain takes ownership of the new block and it will
+ * be deleted when the chain is deleted. The iterator will be left pointing to
+ * the new block.
+ *
+ * \param iterator A pointer to an existing initialized iterator.
+ * \param block A pointer to a metadata block to insert.
+ * \assert
+ * \code iterator != NULL \endcode
+ * \a iterator has been successfully initialized with
+ * FLAC__metadata_iterator_init()
+ * \retval FLAC__bool
+ * \c false if the conditions in the above description are not met, or
+ * a memory allocation error occurs, otherwise \c true.
+ */
+FLAC_API FLAC__bool FLAC__metadata_iterator_insert_block_after(FLAC__Metadata_Iterator *iterator, FLAC__StreamMetadata *block);
+
+/* \} */
+
+
+/** \defgroup flac_metadata_object FLAC/metadata.h: metadata object methods
+ * \ingroup flac_metadata
+ *
+ * \brief
+ * This module contains methods for manipulating FLAC metadata objects.
+ *
+ * Since many are variable length we have to be careful about the memory
+ * management. We decree that all pointers to data in the object are
+ * owned by the object and memory-managed by the object.
+ *
+ * Use the FLAC__metadata_object_new() and FLAC__metadata_object_delete()
+ * functions to create all instances. When using the
+ * FLAC__metadata_object_set_*() functions to set pointers to data, set
+ * \a copy to \c true to have the function make it's own copy of the data, or
+ * to \c false to give the object ownership of your data. In the latter case
+ * your pointer must be freeable by free() and will be free()d when the object
+ * is FLAC__metadata_object_delete()d. It is legal to pass a null pointer as
+ * the data pointer to a FLAC__metadata_object_set_*() function as long as
+ * the length argument is 0 and the \a copy argument is \c false.
+ *
+ * The FLAC__metadata_object_new() and FLAC__metadata_object_clone() function
+ * will return \c NULL in the case of a memory allocation error, otherwise a new
+ * object. The FLAC__metadata_object_set_*() functions return \c false in the
+ * case of a memory allocation error.
+ *
+ * We don't have the convenience of C++ here, so note that the library relies
+ * on you to keep the types straight. In other words, if you pass, for
+ * example, a FLAC__StreamMetadata* that represents a STREAMINFO block to
+ * FLAC__metadata_object_application_set_data(), you will get an assertion
+ * failure.
+ *
+ * For convenience the FLAC__metadata_object_vorbiscomment_*() functions
+ * maintain a trailing NUL on each Vorbis comment entry. This is not counted
+ * toward the length or stored in the stream, but it can make working with plain
+ * comments (those that don't contain embedded-NULs in the value) easier.
+ * Entries passed into these functions have trailing NULs added if missing, and
+ * returned entries are guaranteed to have a trailing NUL.
+ *
+ * The FLAC__metadata_object_vorbiscomment_*() functions that take a Vorbis
+ * comment entry/name/value will first validate that it complies with the Vorbis
+ * comment specification and return false if it does not.
+ *
+ * There is no need to recalculate the length field on metadata blocks you
+ * have modified. They will be calculated automatically before they are
+ * written back to a file.
+ *
+ * \{
+ */
+
+
+/** Create a new metadata object instance of the given type.
+ *
+ * The object will be "empty"; i.e. values and data pointers will be \c 0,
+ * with the exception of FLAC__METADATA_TYPE_VORBIS_COMMENT, which will have
+ * the vendor string set (but zero comments).
+ *
+ * Do not pass in a value greater than or equal to
+ * \a FLAC__METADATA_TYPE_UNDEFINED unless you really know what you're
+ * doing.
+ *
+ * \param type Type of object to create
+ * \retval FLAC__StreamMetadata*
+ * \c NULL if there was an error allocating memory or the type code is
+ * greater than FLAC__MAX_METADATA_TYPE_CODE, else the new instance.
+ */
+FLAC_API FLAC__StreamMetadata *FLAC__metadata_object_new(FLAC__MetadataType type);
+
+/** Create a copy of an existing metadata object.
+ *
+ * The copy is a "deep" copy, i.e. dynamically allocated data within the
+ * object is also copied. The caller takes ownership of the new block and
+ * is responsible for freeing it with FLAC__metadata_object_delete().
+ *
+ * \param object Pointer to object to copy.
+ * \assert
+ * \code object != NULL \endcode
+ * \retval FLAC__StreamMetadata*
+ * \c NULL if there was an error allocating memory, else the new instance.
+ */
+FLAC_API FLAC__StreamMetadata *FLAC__metadata_object_clone(const FLAC__StreamMetadata *object);
+
+/** Free a metadata object. Deletes the object pointed to by \a object.
+ *
+ * The delete is a "deep" delete, i.e. dynamically allocated data within the
+ * object is also deleted.
+ *
+ * \param object A pointer to an existing object.
+ * \assert
+ * \code object != NULL \endcode
+ */
+FLAC_API void FLAC__metadata_object_delete(FLAC__StreamMetadata *object);
+
+/** Compares two metadata objects.
+ *
+ * The compare is "deep", i.e. dynamically allocated data within the
+ * object is also compared.
+ *
+ * \param block1 A pointer to an existing object.
+ * \param block2 A pointer to an existing object.
+ * \assert
+ * \code block1 != NULL \endcode
+ * \code block2 != NULL \endcode
+ * \retval FLAC__bool
+ * \c true if objects are identical, else \c false.
+ */
+FLAC_API FLAC__bool FLAC__metadata_object_is_equal(const FLAC__StreamMetadata *block1, const FLAC__StreamMetadata *block2);
+
+/** Sets the application data of an APPLICATION block.
+ *
+ * If \a copy is \c true, a copy of the data is stored; otherwise, the object
+ * takes ownership of the pointer. The existing data will be freed if this
+ * function is successful, otherwise the original data will remain if \a copy
+ * is \c true and malloc() fails.
+ *
+ * \note It is safe to pass a const pointer to \a data if \a copy is \c true.
+ *
+ * \param object A pointer to an existing APPLICATION object.
+ * \param data A pointer to the data to set.
+ * \param length The length of \a data in bytes.
+ * \param copy See above.
+ * \assert
+ * \code object != NULL \endcode
+ * \code object->type == FLAC__METADATA_TYPE_APPLICATION \endcode
+ * \code (data != NULL && length > 0) ||
+ * (data == NULL && length == 0 && copy == false) \endcode
+ * \retval FLAC__bool
+ * \c false if \a copy is \c true and malloc() fails, else \c true.
+ */
+FLAC_API FLAC__bool FLAC__metadata_object_application_set_data(FLAC__StreamMetadata *object, FLAC__byte *data, unsigned length, FLAC__bool copy);
+
+/** Resize the seekpoint array.
+ *
+ * If the size shrinks, elements will truncated; if it grows, new placeholder
+ * points will be added to the end.
+ *
+ * \param object A pointer to an existing SEEKTABLE object.
+ * \param new_num_points The desired length of the array; may be \c 0.
+ * \assert
+ * \code object != NULL \endcode
+ * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode
+ * \code (object->data.seek_table.points == NULL && object->data.seek_table.num_points == 0) ||
+ * (object->data.seek_table.points != NULL && object->data.seek_table.num_points > 0) \endcode
+ * \retval FLAC__bool
+ * \c false if memory allocation error, else \c true.
+ */
+FLAC_API FLAC__bool FLAC__metadata_object_seektable_resize_points(FLAC__StreamMetadata *object, unsigned new_num_points);
+
+/** Set a seekpoint in a seektable.
+ *
+ * \param object A pointer to an existing SEEKTABLE object.
+ * \param point_num Index into seekpoint array to set.
+ * \param point The point to set.
+ * \assert
+ * \code object != NULL \endcode
+ * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode
+ * \code object->data.seek_table.num_points > point_num \endcode
+ */
+FLAC_API void FLAC__metadata_object_seektable_set_point(FLAC__StreamMetadata *object, unsigned point_num, FLAC__StreamMetadata_SeekPoint point);
+
+/** Insert a seekpoint into a seektable.
+ *
+ * \param object A pointer to an existing SEEKTABLE object.
+ * \param point_num Index into seekpoint array to set.
+ * \param point The point to set.
+ * \assert
+ * \code object != NULL \endcode
+ * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode
+ * \code object->data.seek_table.num_points >= point_num \endcode
+ * \retval FLAC__bool
+ * \c false if memory allocation error, else \c true.
+ */
+FLAC_API FLAC__bool FLAC__metadata_object_seektable_insert_point(FLAC__StreamMetadata *object, unsigned point_num, FLAC__StreamMetadata_SeekPoint point);
+
+/** Delete a seekpoint from a seektable.
+ *
+ * \param object A pointer to an existing SEEKTABLE object.
+ * \param point_num Index into seekpoint array to set.
+ * \assert
+ * \code object != NULL \endcode
+ * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode
+ * \code object->data.seek_table.num_points > point_num \endcode
+ * \retval FLAC__bool
+ * \c false if memory allocation error, else \c true.
+ */
+FLAC_API FLAC__bool FLAC__metadata_object_seektable_delete_point(FLAC__StreamMetadata *object, unsigned point_num);
+
+/** Check a seektable to see if it conforms to the FLAC specification.
+ * See the format specification for limits on the contents of the
+ * seektable.
+ *
+ * \param object A pointer to an existing SEEKTABLE object.
+ * \assert
+ * \code object != NULL \endcode
+ * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode
+ * \retval FLAC__bool
+ * \c false if seek table is illegal, else \c true.
+ */
+FLAC_API FLAC__bool FLAC__metadata_object_seektable_is_legal(const FLAC__StreamMetadata *object);
+
+/** Append a number of placeholder points to the end of a seek table.
+ *
+ * \note
+ * As with the other ..._seektable_template_... functions, you should
+ * call FLAC__metadata_object_seektable_template_sort() when finished
+ * to make the seek table legal.
+ *
+ * \param object A pointer to an existing SEEKTABLE object.
+ * \param num The number of placeholder points to append.
+ * \assert
+ * \code object != NULL \endcode
+ * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode
+ * \retval FLAC__bool
+ * \c false if memory allocation fails, else \c true.
+ */
+FLAC_API FLAC__bool FLAC__metadata_object_seektable_template_append_placeholders(FLAC__StreamMetadata *object, unsigned num);
+
+/** Append a specific seek point template to the end of a seek table.
+ *
+ * \note
+ * As with the other ..._seektable_template_... functions, you should
+ * call FLAC__metadata_object_seektable_template_sort() when finished
+ * to make the seek table legal.
+ *
+ * \param object A pointer to an existing SEEKTABLE object.
+ * \param sample_number The sample number of the seek point template.
+ * \assert
+ * \code object != NULL \endcode
+ * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode
+ * \retval FLAC__bool
+ * \c false if memory allocation fails, else \c true.
+ */
+FLAC_API FLAC__bool FLAC__metadata_object_seektable_template_append_point(FLAC__StreamMetadata *object, FLAC__uint64 sample_number);
+
+/** Append specific seek point templates to the end of a seek table.
+ *
+ * \note
+ * As with the other ..._seektable_template_... functions, you should
+ * call FLAC__metadata_object_seektable_template_sort() when finished
+ * to make the seek table legal.
+ *
+ * \param object A pointer to an existing SEEKTABLE object.
+ * \param sample_numbers An array of sample numbers for the seek points.
+ * \param num The number of seek point templates to append.
+ * \assert
+ * \code object != NULL \endcode
+ * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode
+ * \retval FLAC__bool
+ * \c false if memory allocation fails, else \c true.
+ */
+FLAC_API FLAC__bool FLAC__metadata_object_seektable_template_append_points(FLAC__StreamMetadata *object, FLAC__uint64 sample_numbers[], unsigned num);
+
+/** Append a set of evenly-spaced seek point templates to the end of a
+ * seek table.
+ *
+ * \note
+ * As with the other ..._seektable_template_... functions, you should
+ * call FLAC__metadata_object_seektable_template_sort() when finished
+ * to make the seek table legal.
+ *
+ * \param object A pointer to an existing SEEKTABLE object.
+ * \param num The number of placeholder points to append.
+ * \param total_samples The total number of samples to be encoded;
+ * the seekpoints will be spaced approximately
+ * \a total_samples / \a num samples apart.
+ * \assert
+ * \code object != NULL \endcode
+ * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode
+ * \code total_samples > 0 \endcode
+ * \retval FLAC__bool
+ * \c false if memory allocation fails, else \c true.
+ */
+FLAC_API FLAC__bool FLAC__metadata_object_seektable_template_append_spaced_points(FLAC__StreamMetadata *object, unsigned num, FLAC__uint64 total_samples);
+
+/** Append a set of evenly-spaced seek point templates to the end of a
+ * seek table.
+ *
+ * \note
+ * As with the other ..._seektable_template_... functions, you should
+ * call FLAC__metadata_object_seektable_template_sort() when finished
+ * to make the seek table legal.
+ *
+ * \param object A pointer to an existing SEEKTABLE object.
+ * \param samples The number of samples apart to space the placeholder
+ * points. The first point will be at sample \c 0, the
+ * second at sample \a samples, then 2*\a samples, and
+ * so on. As long as \a samples and \a total_samples
+ * are greater than \c 0, there will always be at least
+ * one seekpoint at sample \c 0.
+ * \param total_samples The total number of samples to be encoded;
+ * the seekpoints will be spaced
+ * \a samples samples apart.
+ * \assert
+ * \code object != NULL \endcode
+ * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode
+ * \code samples > 0 \endcode
+ * \code total_samples > 0 \endcode
+ * \retval FLAC__bool
+ * \c false if memory allocation fails, else \c true.
+ */
+FLAC_API FLAC__bool FLAC__metadata_object_seektable_template_append_spaced_points_by_samples(FLAC__StreamMetadata *object, unsigned samples, FLAC__uint64 total_samples);
+
+/** Sort a seek table's seek points according to the format specification,
+ * removing duplicates.
+ *
+ * \param object A pointer to a seek table to be sorted.
+ * \param compact If \c false, behaves like FLAC__format_seektable_sort().
+ * If \c true, duplicates are deleted and the seek table is
+ * shrunk appropriately; the number of placeholder points
+ * present in the seek table will be the same after the call
+ * as before.
+ * \assert
+ * \code object != NULL \endcode
+ * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode
+ * \retval FLAC__bool
+ * \c false if realloc() fails, else \c true.
+ */
+FLAC_API FLAC__bool FLAC__metadata_object_seektable_template_sort(FLAC__StreamMetadata *object, FLAC__bool compact);
+
+/** Sets the vendor string in a VORBIS_COMMENT block.
+ *
+ * For convenience, a trailing NUL is added to the entry if it doesn't have
+ * one already.
+ *
+ * If \a copy is \c true, a copy of the entry is stored; otherwise, the object
+ * takes ownership of the \c entry.entry pointer.
+ *
+ * \note If this function returns \c false, the caller still owns the
+ * pointer.
+ *
+ * \param object A pointer to an existing VORBIS_COMMENT object.
+ * \param entry The entry to set the vendor string to.
+ * \param copy See above.
+ * \assert
+ * \code object != NULL \endcode
+ * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode
+ * \code (entry.entry != NULL && entry.length > 0) ||
+ * (entry.entry == NULL && entry.length == 0) \endcode
+ * \retval FLAC__bool
+ * \c false if memory allocation fails or \a entry does not comply with the
+ * Vorbis comment specification, else \c true.
+ */
+FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_set_vendor_string(FLAC__StreamMetadata *object, FLAC__StreamMetadata_VorbisComment_Entry entry, FLAC__bool copy);
+
+/** Resize the comment array.
+ *
+ * If the size shrinks, elements will truncated; if it grows, new empty
+ * fields will be added to the end.
+ *
+ * \param object A pointer to an existing VORBIS_COMMENT object.
+ * \param new_num_comments The desired length of the array; may be \c 0.
+ * \assert
+ * \code object != NULL \endcode
+ * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode
+ * \code (object->data.vorbis_comment.comments == NULL && object->data.vorbis_comment.num_comments == 0) ||
+ * (object->data.vorbis_comment.comments != NULL && object->data.vorbis_comment.num_comments > 0) \endcode
+ * \retval FLAC__bool
+ * \c false if memory allocation fails, else \c true.
+ */
+FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_resize_comments(FLAC__StreamMetadata *object, unsigned new_num_comments);
+
+/** Sets a comment in a VORBIS_COMMENT block.
+ *
+ * For convenience, a trailing NUL is added to the entry if it doesn't have
+ * one already.
+ *
+ * If \a copy is \c true, a copy of the entry is stored; otherwise, the object
+ * takes ownership of the \c entry.entry pointer.
+ *
+ * \note If this function returns \c false, the caller still owns the
+ * pointer.
+ *
+ * \param object A pointer to an existing VORBIS_COMMENT object.
+ * \param comment_num Index into comment array to set.
+ * \param entry The entry to set the comment to.
+ * \param copy See above.
+ * \assert
+ * \code object != NULL \endcode
+ * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode
+ * \code comment_num < object->data.vorbis_comment.num_comments \endcode
+ * \code (entry.entry != NULL && entry.length > 0) ||
+ * (entry.entry == NULL && entry.length == 0) \endcode
+ * \retval FLAC__bool
+ * \c false if memory allocation fails or \a entry does not comply with the
+ * Vorbis comment specification, else \c true.
+ */
+FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_set_comment(FLAC__StreamMetadata *object, unsigned comment_num, FLAC__StreamMetadata_VorbisComment_Entry entry, FLAC__bool copy);
+
+/** Insert a comment in a VORBIS_COMMENT block at the given index.
+ *
+ * For convenience, a trailing NUL is added to the entry if it doesn't have
+ * one already.
+ *
+ * If \a copy is \c true, a copy of the entry is stored; otherwise, the object
+ * takes ownership of the \c entry.entry pointer.
+ *
+ * \note If this function returns \c false, the caller still owns the
+ * pointer.
+ *
+ * \param object A pointer to an existing VORBIS_COMMENT object.
+ * \param comment_num The index at which to insert the comment. The comments
+ * at and after \a comment_num move right one position.
+ * To append a comment to the end, set \a comment_num to
+ * \c object->data.vorbis_comment.num_comments .
+ * \param entry The comment to insert.
+ * \param copy See above.
+ * \assert
+ * \code object != NULL \endcode
+ * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode
+ * \code object->data.vorbis_comment.num_comments >= comment_num \endcode
+ * \code (entry.entry != NULL && entry.length > 0) ||
+ * (entry.entry == NULL && entry.length == 0 && copy == false) \endcode
+ * \retval FLAC__bool
+ * \c false if memory allocation fails or \a entry does not comply with the
+ * Vorbis comment specification, else \c true.
+ */
+FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_insert_comment(FLAC__StreamMetadata *object, unsigned comment_num, FLAC__StreamMetadata_VorbisComment_Entry entry, FLAC__bool copy);
+
+/** Appends a comment to a VORBIS_COMMENT block.
+ *
+ * For convenience, a trailing NUL is added to the entry if it doesn't have
+ * one already.
+ *
+ * If \a copy is \c true, a copy of the entry is stored; otherwise, the object
+ * takes ownership of the \c entry.entry pointer.
+ *
+ * \note If this function returns \c false, the caller still owns the
+ * pointer.
+ *
+ * \param object A pointer to an existing VORBIS_COMMENT object.
+ * \param entry The comment to insert.
+ * \param copy See above.
+ * \assert
+ * \code object != NULL \endcode
+ * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode
+ * \code (entry.entry != NULL && entry.length > 0) ||
+ * (entry.entry == NULL && entry.length == 0 && copy == false) \endcode
+ * \retval FLAC__bool
+ * \c false if memory allocation fails or \a entry does not comply with the
+ * Vorbis comment specification, else \c true.
+ */
+FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_append_comment(FLAC__StreamMetadata *object, FLAC__StreamMetadata_VorbisComment_Entry entry, FLAC__bool copy);
+
+/** Replaces comments in a VORBIS_COMMENT block with a new one.
+ *
+ * For convenience, a trailing NUL is added to the entry if it doesn't have
+ * one already.
+ *
+ * Depending on the the value of \a all, either all or just the first comment
+ * whose field name(s) match the given entry's name will be replaced by the
+ * given entry. If no comments match, \a entry will simply be appended.
+ *
+ * If \a copy is \c true, a copy of the entry is stored; otherwise, the object
+ * takes ownership of the \c entry.entry pointer.
+ *
+ * \note If this function returns \c false, the caller still owns the
+ * pointer.
+ *
+ * \param object A pointer to an existing VORBIS_COMMENT object.
+ * \param entry The comment to insert.
+ * \param all If \c true, all comments whose field name matches
+ * \a entry's field name will be removed, and \a entry will
+ * be inserted at the position of the first matching
+ * comment. If \c false, only the first comment whose
+ * field name matches \a entry's field name will be
+ * replaced with \a entry.
+ * \param copy See above.
+ * \assert
+ * \code object != NULL \endcode
+ * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode
+ * \code (entry.entry != NULL && entry.length > 0) ||
+ * (entry.entry == NULL && entry.length == 0 && copy == false) \endcode
+ * \retval FLAC__bool
+ * \c false if memory allocation fails or \a entry does not comply with the
+ * Vorbis comment specification, else \c true.
+ */
+FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_replace_comment(FLAC__StreamMetadata *object, FLAC__StreamMetadata_VorbisComment_Entry entry, FLAC__bool all, FLAC__bool copy);
+
+/** Delete a comment in a VORBIS_COMMENT block at the given index.
+ *
+ * \param object A pointer to an existing VORBIS_COMMENT object.
+ * \param comment_num The index of the comment to delete.
+ * \assert
+ * \code object != NULL \endcode
+ * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode
+ * \code object->data.vorbis_comment.num_comments > comment_num \endcode
+ * \retval FLAC__bool
+ * \c false if realloc() fails, else \c true.
+ */
+FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_delete_comment(FLAC__StreamMetadata *object, unsigned comment_num);
+
+/** Creates a Vorbis comment entry from NUL-terminated name and value strings.
+ *
+ * On return, the filled-in \a entry->entry pointer will point to malloc()ed
+ * memory and shall be owned by the caller. For convenience the entry will
+ * have a terminating NUL.
+ *
+ * \param entry A pointer to a Vorbis comment entry. The entry's
+ * \c entry pointer should not point to allocated
+ * memory as it will be overwritten.
+ * \param field_name The field name in ASCII, \c NUL terminated.
+ * \param field_value The field value in UTF-8, \c NUL terminated.
+ * \assert
+ * \code entry != NULL \endcode
+ * \code field_name != NULL \endcode
+ * \code field_value != NULL \endcode
+ * \retval FLAC__bool
+ * \c false if malloc() fails, or if \a field_name or \a field_value does
+ * not comply with the Vorbis comment specification, else \c true.
+ */
+FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_entry_from_name_value_pair(FLAC__StreamMetadata_VorbisComment_Entry *entry, const char *field_name, const char *field_value);
+
+/** Splits a Vorbis comment entry into NUL-terminated name and value strings.
+ *
+ * The returned pointers to name and value will be allocated by malloc()
+ * and shall be owned by the caller.
+ *
+ * \param entry An existing Vorbis comment entry.
+ * \param field_name The address of where the returned pointer to the
+ * field name will be stored.
+ * \param field_value The address of where the returned pointer to the
+ * field value will be stored.
+ * \assert
+ * \code (entry.entry != NULL && entry.length > 0) \endcode
+ * \code memchr(entry.entry, '=', entry.length) != NULL \endcode
+ * \code field_name != NULL \endcode
+ * \code field_value != NULL \endcode
+ * \retval FLAC__bool
+ * \c false if memory allocation fails or \a entry does not comply with the
+ * Vorbis comment specification, else \c true.
+ */
+FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_entry_to_name_value_pair(const FLAC__StreamMetadata_VorbisComment_Entry entry, char **field_name, char **field_value);
+
+/** Check if the given Vorbis comment entry's field name matches the given
+ * field name.
+ *
+ * \param entry An existing Vorbis comment entry.
+ * \param field_name The field name to check.
+ * \param field_name_length The length of \a field_name, not including the
+ * terminating \c NUL.
+ * \assert
+ * \code (entry.entry != NULL && entry.length > 0) \endcode
+ * \retval FLAC__bool
+ * \c true if the field names match, else \c false
+ */
+FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_entry_matches(const FLAC__StreamMetadata_VorbisComment_Entry entry, const char *field_name, unsigned field_name_length);
+
+/** Find a Vorbis comment with the given field name.
+ *
+ * The search begins at entry number \a offset; use an offset of 0 to
+ * search from the beginning of the comment array.
+ *
+ * \param object A pointer to an existing VORBIS_COMMENT object.
+ * \param offset The offset into the comment array from where to start
+ * the search.
+ * \param field_name The field name of the comment to find.
+ * \assert
+ * \code object != NULL \endcode
+ * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode
+ * \code field_name != NULL \endcode
+ * \retval int
+ * The offset in the comment array of the first comment whose field
+ * name matches \a field_name, or \c -1 if no match was found.
+ */
+FLAC_API int FLAC__metadata_object_vorbiscomment_find_entry_from(const FLAC__StreamMetadata *object, unsigned offset, const char *field_name);
+
+/** Remove first Vorbis comment matching the given field name.
+ *
+ * \param object A pointer to an existing VORBIS_COMMENT object.
+ * \param field_name The field name of comment to delete.
+ * \assert
+ * \code object != NULL \endcode
+ * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode
+ * \retval int
+ * \c -1 for memory allocation error, \c 0 for no matching entries,
+ * \c 1 for one matching entry deleted.
+ */
+FLAC_API int FLAC__metadata_object_vorbiscomment_remove_entry_matching(FLAC__StreamMetadata *object, const char *field_name);
+
+/** Remove all Vorbis comments matching the given field name.
+ *
+ * \param object A pointer to an existing VORBIS_COMMENT object.
+ * \param field_name The field name of comments to delete.
+ * \assert
+ * \code object != NULL \endcode
+ * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode
+ * \retval int
+ * \c -1 for memory allocation error, \c 0 for no matching entries,
+ * else the number of matching entries deleted.
+ */
+FLAC_API int FLAC__metadata_object_vorbiscomment_remove_entries_matching(FLAC__StreamMetadata *object, const char *field_name);
+
+/** Create a new CUESHEET track instance.
+ *
+ * The object will be "empty"; i.e. values and data pointers will be \c 0.
+ *
+ * \retval FLAC__StreamMetadata_CueSheet_Track*
+ * \c NULL if there was an error allocating memory, else the new instance.
+ */
+FLAC_API FLAC__StreamMetadata_CueSheet_Track *FLAC__metadata_object_cuesheet_track_new(void);
+
+/** Create a copy of an existing CUESHEET track object.
+ *
+ * The copy is a "deep" copy, i.e. dynamically allocated data within the
+ * object is also copied. The caller takes ownership of the new object and
+ * is responsible for freeing it with
+ * FLAC__metadata_object_cuesheet_track_delete().
+ *
+ * \param object Pointer to object to copy.
+ * \assert
+ * \code object != NULL \endcode
+ * \retval FLAC__StreamMetadata_CueSheet_Track*
+ * \c NULL if there was an error allocating memory, else the new instance.
+ */
+FLAC_API FLAC__StreamMetadata_CueSheet_Track *FLAC__metadata_object_cuesheet_track_clone(const FLAC__StreamMetadata_CueSheet_Track *object);
+
+/** Delete a CUESHEET track object
+ *
+ * \param object A pointer to an existing CUESHEET track object.
+ * \assert
+ * \code object != NULL \endcode
+ */
+FLAC_API void FLAC__metadata_object_cuesheet_track_delete(FLAC__StreamMetadata_CueSheet_Track *object);
+
+/** Resize a track's index point array.
+ *
+ * If the size shrinks, elements will truncated; if it grows, new blank
+ * indices will be added to the end.
+ *
+ * \param object A pointer to an existing CUESHEET object.
+ * \param track_num The index of the track to modify. NOTE: this is not
+ * necessarily the same as the track's \a number field.
+ * \param new_num_indices The desired length of the array; may be \c 0.
+ * \assert
+ * \code object != NULL \endcode
+ * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode
+ * \code object->data.cue_sheet.num_tracks > track_num \endcode
+ * \code (object->data.cue_sheet.tracks[track_num].indices == NULL && object->data.cue_sheet.tracks[track_num].num_indices == 0) ||
+ * (object->data.cue_sheet.tracks[track_num].indices != NULL && object->data.cue_sheet.tracks[track_num].num_indices > 0) \endcode
+ * \retval FLAC__bool
+ * \c false if memory allocation error, else \c true.
+ */
+FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_track_resize_indices(FLAC__StreamMetadata *object, unsigned track_num, unsigned new_num_indices);
+
+/** Insert an index point in a CUESHEET track at the given index.
+ *
+ * \param object A pointer to an existing CUESHEET object.
+ * \param track_num The index of the track to modify. NOTE: this is not
+ * necessarily the same as the track's \a number field.
+ * \param index_num The index into the track's index array at which to
+ * insert the index point. NOTE: this is not necessarily
+ * the same as the index point's \a number field. The
+ * indices at and after \a index_num move right one
+ * position. To append an index point to the end, set
+ * \a index_num to
+ * \c object->data.cue_sheet.tracks[track_num].num_indices .
+ * \param index The index point to insert.
+ * \assert
+ * \code object != NULL \endcode
+ * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode
+ * \code object->data.cue_sheet.num_tracks > track_num \endcode
+ * \code object->data.cue_sheet.tracks[track_num].num_indices >= index_num \endcode
+ * \retval FLAC__bool
+ * \c false if realloc() fails, else \c true.
+ */
+FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_track_insert_index(FLAC__StreamMetadata *object, unsigned track_num, unsigned index_num, FLAC__StreamMetadata_CueSheet_Index index);
+
+/** Insert a blank index point in a CUESHEET track at the given index.
+ *
+ * A blank index point is one in which all field values are zero.
+ *
+ * \param object A pointer to an existing CUESHEET object.
+ * \param track_num The index of the track to modify. NOTE: this is not
+ * necessarily the same as the track's \a number field.
+ * \param index_num The index into the track's index array at which to
+ * insert the index point. NOTE: this is not necessarily
+ * the same as the index point's \a number field. The
+ * indices at and after \a index_num move right one
+ * position. To append an index point to the end, set
+ * \a index_num to
+ * \c object->data.cue_sheet.tracks[track_num].num_indices .
+ * \assert
+ * \code object != NULL \endcode
+ * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode
+ * \code object->data.cue_sheet.num_tracks > track_num \endcode
+ * \code object->data.cue_sheet.tracks[track_num].num_indices >= index_num \endcode
+ * \retval FLAC__bool
+ * \c false if realloc() fails, else \c true.
+ */
+FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_track_insert_blank_index(FLAC__StreamMetadata *object, unsigned track_num, unsigned index_num);
+
+/** Delete an index point in a CUESHEET track at the given index.
+ *
+ * \param object A pointer to an existing CUESHEET object.
+ * \param track_num The index into the track array of the track to
+ * modify. NOTE: this is not necessarily the same
+ * as the track's \a number field.
+ * \param index_num The index into the track's index array of the index
+ * to delete. NOTE: this is not necessarily the same
+ * as the index's \a number field.
+ * \assert
+ * \code object != NULL \endcode
+ * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode
+ * \code object->data.cue_sheet.num_tracks > track_num \endcode
+ * \code object->data.cue_sheet.tracks[track_num].num_indices > index_num \endcode
+ * \retval FLAC__bool
+ * \c false if realloc() fails, else \c true.
+ */
+FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_track_delete_index(FLAC__StreamMetadata *object, unsigned track_num, unsigned index_num);
+
+/** Resize the track array.
+ *
+ * If the size shrinks, elements will truncated; if it grows, new blank
+ * tracks will be added to the end.
+ *
+ * \param object A pointer to an existing CUESHEET object.
+ * \param new_num_tracks The desired length of the array; may be \c 0.
+ * \assert
+ * \code object != NULL \endcode
+ * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode
+ * \code (object->data.cue_sheet.tracks == NULL && object->data.cue_sheet.num_tracks == 0) ||
+ * (object->data.cue_sheet.tracks != NULL && object->data.cue_sheet.num_tracks > 0) \endcode
+ * \retval FLAC__bool
+ * \c false if memory allocation error, else \c true.
+ */
+FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_resize_tracks(FLAC__StreamMetadata *object, unsigned new_num_tracks);
+
+/** Sets a track in a CUESHEET block.
+ *
+ * If \a copy is \c true, a copy of the track is stored; otherwise, the object
+ * takes ownership of the \a track pointer.
+ *
+ * \param object A pointer to an existing CUESHEET object.
+ * \param track_num Index into track array to set. NOTE: this is not
+ * necessarily the same as the track's \a number field.
+ * \param track The track to set the track to. You may safely pass in
+ * a const pointer if \a copy is \c true.
+ * \param copy See above.
+ * \assert
+ * \code object != NULL \endcode
+ * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode
+ * \code track_num < object->data.cue_sheet.num_tracks \endcode
+ * \code (track->indices != NULL && track->num_indices > 0) ||
+ * (track->indices == NULL && track->num_indices == 0)
+ * \retval FLAC__bool
+ * \c false if \a copy is \c true and malloc() fails, else \c true.
+ */
+FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_set_track(FLAC__StreamMetadata *object, unsigned track_num, FLAC__StreamMetadata_CueSheet_Track *track, FLAC__bool copy);
+
+/** Insert a track in a CUESHEET block at the given index.
+ *
+ * If \a copy is \c true, a copy of the track is stored; otherwise, the object
+ * takes ownership of the \a track pointer.
+ *
+ * \param object A pointer to an existing CUESHEET object.
+ * \param track_num The index at which to insert the track. NOTE: this
+ * is not necessarily the same as the track's \a number
+ * field. The tracks at and after \a track_num move right
+ * one position. To append a track to the end, set
+ * \a track_num to \c object->data.cue_sheet.num_tracks .
+ * \param track The track to insert. You may safely pass in a const
+ * pointer if \a copy is \c true.
+ * \param copy See above.
+ * \assert
+ * \code object != NULL \endcode
+ * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode
+ * \code object->data.cue_sheet.num_tracks >= track_num \endcode
+ * \retval FLAC__bool
+ * \c false if \a copy is \c true and malloc() fails, else \c true.
+ */
+FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_insert_track(FLAC__StreamMetadata *object, unsigned track_num, FLAC__StreamMetadata_CueSheet_Track *track, FLAC__bool copy);
+
+/** Insert a blank track in a CUESHEET block at the given index.
+ *
+ * A blank track is one in which all field values are zero.
+ *
+ * \param object A pointer to an existing CUESHEET object.
+ * \param track_num The index at which to insert the track. NOTE: this
+ * is not necessarily the same as the track's \a number
+ * field. The tracks at and after \a track_num move right
+ * one position. To append a track to the end, set
+ * \a track_num to \c object->data.cue_sheet.num_tracks .
+ * \assert
+ * \code object != NULL \endcode
+ * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode
+ * \code object->data.cue_sheet.num_tracks >= track_num \endcode
+ * \retval FLAC__bool
+ * \c false if \a copy is \c true and malloc() fails, else \c true.
+ */
+FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_insert_blank_track(FLAC__StreamMetadata *object, unsigned track_num);
+
+/** Delete a track in a CUESHEET block at the given index.
+ *
+ * \param object A pointer to an existing CUESHEET object.
+ * \param track_num The index into the track array of the track to
+ * delete. NOTE: this is not necessarily the same
+ * as the track's \a number field.
+ * \assert
+ * \code object != NULL \endcode
+ * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode
+ * \code object->data.cue_sheet.num_tracks > track_num \endcode
+ * \retval FLAC__bool
+ * \c false if realloc() fails, else \c true.
+ */
+FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_delete_track(FLAC__StreamMetadata *object, unsigned track_num);
+
+/** Check a cue sheet to see if it conforms to the FLAC specification.
+ * See the format specification for limits on the contents of the
+ * cue sheet.
+ *
+ * \param object A pointer to an existing CUESHEET object.
+ * \param check_cd_da_subset If \c true, check CUESHEET against more
+ * stringent requirements for a CD-DA (audio) disc.
+ * \param violation Address of a pointer to a string. If there is a
+ * violation, a pointer to a string explanation of the
+ * violation will be returned here. \a violation may be
+ * \c NULL if you don't need the returned string. Do not
+ * free the returned string; it will always point to static
+ * data.
+ * \assert
+ * \code object != NULL \endcode
+ * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode
+ * \retval FLAC__bool
+ * \c false if cue sheet is illegal, else \c true.
+ */
+FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_is_legal(const FLAC__StreamMetadata *object, FLAC__bool check_cd_da_subset, const char **violation);
+
+/** Calculate and return the CDDB/freedb ID for a cue sheet. The function
+ * assumes the cue sheet corresponds to a CD; the result is undefined
+ * if the cuesheet's is_cd bit is not set.
+ *
+ * \param object A pointer to an existing CUESHEET object.
+ * \assert
+ * \code object != NULL \endcode
+ * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode
+ * \retval FLAC__uint32
+ * The unsigned integer representation of the CDDB/freedb ID
+ */
+FLAC_API FLAC__uint32 FLAC__metadata_object_cuesheet_calculate_cddb_id(const FLAC__StreamMetadata *object);
+
+/** Sets the MIME type of a PICTURE block.
+ *
+ * If \a copy is \c true, a copy of the string is stored; otherwise, the object
+ * takes ownership of the pointer. The existing string will be freed if this
+ * function is successful, otherwise the original string will remain if \a copy
+ * is \c true and malloc() fails.
+ *
+ * \note It is safe to pass a const pointer to \a mime_type if \a copy is \c true.
+ *
+ * \param object A pointer to an existing PICTURE object.
+ * \param mime_type A pointer to the MIME type string. The string must be
+ * ASCII characters 0x20-0x7e, NUL-terminated. No validation
+ * is done.
+ * \param copy See above.
+ * \assert
+ * \code object != NULL \endcode
+ * \code object->type == FLAC__METADATA_TYPE_PICTURE \endcode
+ * \code (mime_type != NULL) \endcode
+ * \retval FLAC__bool
+ * \c false if \a copy is \c true and malloc() fails, else \c true.
+ */
+FLAC_API FLAC__bool FLAC__metadata_object_picture_set_mime_type(FLAC__StreamMetadata *object, char *mime_type, FLAC__bool copy);
+
+/** Sets the description of a PICTURE block.
+ *
+ * If \a copy is \c true, a copy of the string is stored; otherwise, the object
+ * takes ownership of the pointer. The existing string will be freed if this
+ * function is successful, otherwise the original string will remain if \a copy
+ * is \c true and malloc() fails.
+ *
+ * \note It is safe to pass a const pointer to \a description if \a copy is \c true.
+ *
+ * \param object A pointer to an existing PICTURE object.
+ * \param description A pointer to the description string. The string must be
+ * valid UTF-8, NUL-terminated. No validation is done.
+ * \param copy See above.
+ * \assert
+ * \code object != NULL \endcode
+ * \code object->type == FLAC__METADATA_TYPE_PICTURE \endcode
+ * \code (description != NULL) \endcode
+ * \retval FLAC__bool
+ * \c false if \a copy is \c true and malloc() fails, else \c true.
+ */
+FLAC_API FLAC__bool FLAC__metadata_object_picture_set_description(FLAC__StreamMetadata *object, FLAC__byte *description, FLAC__bool copy);
+
+/** Sets the picture data of a PICTURE block.
+ *
+ * If \a copy is \c true, a copy of the data is stored; otherwise, the object
+ * takes ownership of the pointer. Also sets the \a data_length field of the
+ * metadata object to what is passed in as the \a length parameter. The
+ * existing data will be freed if this function is successful, otherwise the
+ * original data and data_length will remain if \a copy is \c true and
+ * malloc() fails.
+ *
+ * \note It is safe to pass a const pointer to \a data if \a copy is \c true.
+ *
+ * \param object A pointer to an existing PICTURE object.
+ * \param data A pointer to the data to set.
+ * \param length The length of \a data in bytes.
+ * \param copy See above.
+ * \assert
+ * \code object != NULL \endcode
+ * \code object->type == FLAC__METADATA_TYPE_PICTURE \endcode
+ * \code (data != NULL && length > 0) ||
+ * (data == NULL && length == 0 && copy == false) \endcode
+ * \retval FLAC__bool
+ * \c false if \a copy is \c true and malloc() fails, else \c true.
+ */
+FLAC_API FLAC__bool FLAC__metadata_object_picture_set_data(FLAC__StreamMetadata *object, FLAC__byte *data, FLAC__uint32 length, FLAC__bool copy);
+
+/** Check a PICTURE block to see if it conforms to the FLAC specification.
+ * See the format specification for limits on the contents of the
+ * PICTURE block.
+ *
+ * \param object A pointer to existing PICTURE block to be checked.
+ * \param violation Address of a pointer to a string. If there is a
+ * violation, a pointer to a string explanation of the
+ * violation will be returned here. \a violation may be
+ * \c NULL if you don't need the returned string. Do not
+ * free the returned string; it will always point to static
+ * data.
+ * \assert
+ * \code object != NULL \endcode
+ * \code object->type == FLAC__METADATA_TYPE_PICTURE \endcode
+ * \retval FLAC__bool
+ * \c false if PICTURE block is illegal, else \c true.
+ */
+FLAC_API FLAC__bool FLAC__metadata_object_picture_is_legal(const FLAC__StreamMetadata *object, const char **violation);
+
+/* \} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib-x86-32/include/FLAC/ordinals.h b/lib-x86-32/include/FLAC/ordinals.h
new file mode 100644
index 00000000..a7a5cd96
--- /dev/null
+++ b/lib-x86-32/include/FLAC/ordinals.h
@@ -0,0 +1,80 @@
+/* libFLAC - Free Lossless Audio Codec library
+ * Copyright (C) 2000,2001,2002,2003,2004,2005,2006,2007 Josh Coalson
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of the Xiph.org Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef FLAC__ORDINALS_H
+#define FLAC__ORDINALS_H
+
+#if !(defined(_MSC_VER) || defined(__BORLANDC__) || defined(__EMX__))
+#include <inttypes.h>
+#endif
+
+typedef signed char FLAC__int8;
+typedef unsigned char FLAC__uint8;
+
+#if defined(_MSC_VER) || defined(__BORLANDC__)
+typedef __int16 FLAC__int16;
+typedef __int32 FLAC__int32;
+typedef __int64 FLAC__int64;
+typedef unsigned __int16 FLAC__uint16;
+typedef unsigned __int32 FLAC__uint32;
+typedef unsigned __int64 FLAC__uint64;
+#elif defined(__EMX__)
+typedef short FLAC__int16;
+typedef long FLAC__int32;
+typedef long long FLAC__int64;
+typedef unsigned short FLAC__uint16;
+typedef unsigned long FLAC__uint32;
+typedef unsigned long long FLAC__uint64;
+#else
+typedef int16_t FLAC__int16;
+typedef int32_t FLAC__int32;
+typedef int64_t FLAC__int64;
+typedef uint16_t FLAC__uint16;
+typedef uint32_t FLAC__uint32;
+typedef uint64_t FLAC__uint64;
+#endif
+
+typedef int FLAC__bool;
+
+typedef FLAC__uint8 FLAC__byte;
+
+#ifdef true
+#undef true
+#endif
+#ifdef false
+#undef false
+#endif
+#ifndef __cplusplus
+#define true 1
+#define false 0
+#endif
+
+#endif
diff --git a/lib-x86-32/include/FLAC/stream_decoder.h b/lib-x86-32/include/FLAC/stream_decoder.h
new file mode 100644
index 00000000..9ac15947
--- /dev/null
+++ b/lib-x86-32/include/FLAC/stream_decoder.h
@@ -0,0 +1,1559 @@
+/* libFLAC - Free Lossless Audio Codec library
+ * Copyright (C) 2000,2001,2002,2003,2004,2005,2006,2007 Josh Coalson
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of the Xiph.org Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef FLAC__STREAM_DECODER_H
+#define FLAC__STREAM_DECODER_H
+
+#include <stdio.h> /* for FILE */
+#include "export.h"
+#include "format.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/** \file include/FLAC/stream_decoder.h
+ *
+ * \brief
+ * This module contains the functions which implement the stream
+ * decoder.
+ *
+ * See the detailed documentation in the
+ * \link flac_stream_decoder stream decoder \endlink module.
+ */
+
+/** \defgroup flac_decoder FLAC/ \*_decoder.h: decoder interfaces
+ * \ingroup flac
+ *
+ * \brief
+ * This module describes the decoder layers provided by libFLAC.
+ *
+ * The stream decoder can be used to decode complete streams either from
+ * the client via callbacks, or directly from a file, depending on how
+ * it is initialized. When decoding via callbacks, the client provides
+ * callbacks for reading FLAC data and writing decoded samples, and
+ * handling metadata and errors. If the client also supplies seek-related
+ * callback, the decoder function for sample-accurate seeking within the
+ * FLAC input is also available. When decoding from a file, the client
+ * needs only supply a filename or open \c FILE* and write/metadata/error
+ * callbacks; the rest of the callbacks are supplied internally. For more
+ * info see the \link flac_stream_decoder stream decoder \endlink module.
+ */
+
+/** \defgroup flac_stream_decoder FLAC/stream_decoder.h: stream decoder interface
+ * \ingroup flac_decoder
+ *
+ * \brief
+ * This module contains the functions which implement the stream
+ * decoder.
+ *
+ * The stream decoder can decode native FLAC, and optionally Ogg FLAC
+ * (check FLAC_API_SUPPORTS_OGG_FLAC) streams and files.
+ *
+ * The basic usage of this decoder is as follows:
+ * - The program creates an instance of a decoder using
+ * FLAC__stream_decoder_new().
+ * - The program overrides the default settings using
+ * FLAC__stream_decoder_set_*() functions.
+ * - The program initializes the instance to validate the settings and
+ * prepare for decoding using
+ * - FLAC__stream_decoder_init_stream() or FLAC__stream_decoder_init_FILE()
+ * or FLAC__stream_decoder_init_file() for native FLAC,
+ * - FLAC__stream_decoder_init_ogg_stream() or FLAC__stream_decoder_init_ogg_FILE()
+ * or FLAC__stream_decoder_init_ogg_file() for Ogg FLAC
+ * - The program calls the FLAC__stream_decoder_process_*() functions
+ * to decode data, which subsequently calls the callbacks.
+ * - The program finishes the decoding with FLAC__stream_decoder_finish(),
+ * which flushes the input and output and resets the decoder to the
+ * uninitialized state.
+ * - The instance may be used again or deleted with
+ * FLAC__stream_decoder_delete().
+ *
+ * In more detail, the program will create a new instance by calling
+ * FLAC__stream_decoder_new(), then call FLAC__stream_decoder_set_*()
+ * functions to override the default decoder options, and call
+ * one of the FLAC__stream_decoder_init_*() functions.
+ *
+ * There are three initialization functions for native FLAC, one for
+ * setting up the decoder to decode FLAC data from the client via
+ * callbacks, and two for decoding directly from a FLAC file.
+ *
+ * For decoding via callbacks, use FLAC__stream_decoder_init_stream().
+ * You must also supply several callbacks for handling I/O. Some (like
+ * seeking) are optional, depending on the capabilities of the input.
+ *
+ * For decoding directly from a file, use FLAC__stream_decoder_init_FILE()
+ * or FLAC__stream_decoder_init_file(). Then you must only supply an open
+ * \c FILE* or filename and fewer callbacks; the decoder will handle
+ * the other callbacks internally.
+ *
+ * There are three similarly-named init functions for decoding from Ogg
+ * FLAC streams. Check \c FLAC_API_SUPPORTS_OGG_FLAC to find out if the
+ * library has been built with Ogg support.
+ *
+ * Once the decoder is initialized, your program will call one of several
+ * functions to start the decoding process:
+ *
+ * - FLAC__stream_decoder_process_single() - Tells the decoder to process at
+ * most one metadata block or audio frame and return, calling either the
+ * metadata callback or write callback, respectively, once. If the decoder
+ * loses sync it will return with only the error callback being called.
+ * - FLAC__stream_decoder_process_until_end_of_metadata() - Tells the decoder
+ * to process the stream from the current location and stop upon reaching
+ * the first audio frame. The client will get one metadata, write, or error
+ * callback per metadata block, audio frame, or sync error, respectively.
+ * - FLAC__stream_decoder_process_until_end_of_stream() - Tells the decoder
+ * to process the stream from the current location until the read callback
+ * returns FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM or
+ * FLAC__STREAM_DECODER_READ_STATUS_ABORT. The client will get one metadata,
+ * write, or error callback per metadata block, audio frame, or sync error,
+ * respectively.
+ *
+ * When the decoder has finished decoding (normally or through an abort),
+ * the instance is finished by calling FLAC__stream_decoder_finish(), which
+ * ensures the decoder is in the correct state and frees memory. Then the
+ * instance may be deleted with FLAC__stream_decoder_delete() or initialized
+ * again to decode another stream.
+ *
+ * Seeking is exposed through the FLAC__stream_decoder_seek_absolute() method.
+ * At any point after the stream decoder has been initialized, the client can
+ * call this function to seek to an exact sample within the stream.
+ * Subsequently, the first time the write callback is called it will be
+ * passed a (possibly partial) block starting at that sample.
+ *
+ * If the client cannot seek via the callback interface provided, but still
+ * has another way of seeking, it can flush the decoder using
+ * FLAC__stream_decoder_flush() and start feeding data from the new position
+ * through the read callback.
+ *
+ * The stream decoder also provides MD5 signature checking. If this is
+ * turned on before initialization, FLAC__stream_decoder_finish() will
+ * report when the decoded MD5 signature does not match the one stored
+ * in the STREAMINFO block. MD5 checking is automatically turned off
+ * (until the next FLAC__stream_decoder_reset()) if there is no signature
+ * in the STREAMINFO block or when a seek is attempted.
+ *
+ * The FLAC__stream_decoder_set_metadata_*() functions deserve special
+ * attention. By default, the decoder only calls the metadata_callback for
+ * the STREAMINFO block. These functions allow you to tell the decoder
+ * explicitly which blocks to parse and return via the metadata_callback
+ * and/or which to skip. Use a FLAC__stream_decoder_set_metadata_respond_all(),
+ * FLAC__stream_decoder_set_metadata_ignore() ... or FLAC__stream_decoder_set_metadata_ignore_all(),
+ * FLAC__stream_decoder_set_metadata_respond() ... sequence to exactly specify
+ * which blocks to return. Remember that metadata blocks can potentially
+ * be big (for example, cover art) so filtering out the ones you don't
+ * use can reduce the memory requirements of the decoder. Also note the
+ * special forms FLAC__stream_decoder_set_metadata_respond_application(id)
+ * and FLAC__stream_decoder_set_metadata_ignore_application(id) for
+ * filtering APPLICATION blocks based on the application ID.
+ *
+ * STREAMINFO and SEEKTABLE blocks are always parsed and used internally, but
+ * they still can legally be filtered from the metadata_callback.
+ *
+ * \note
+ * The "set" functions may only be called when the decoder is in the
+ * state FLAC__STREAM_DECODER_UNINITIALIZED, i.e. after
+ * FLAC__stream_decoder_new() or FLAC__stream_decoder_finish(), but
+ * before FLAC__stream_decoder_init_*(). If this is the case they will
+ * return \c true, otherwise \c false.
+ *
+ * \note
+ * FLAC__stream_decoder_finish() resets all settings to the constructor
+ * defaults, including the callbacks.
+ *
+ * \{
+ */
+
+
+/** State values for a FLAC__StreamDecoder
+ *
+ * The decoder's state can be obtained by calling FLAC__stream_decoder_get_state().
+ */
+typedef enum {
+
+ FLAC__STREAM_DECODER_SEARCH_FOR_METADATA = 0,
+ /**< The decoder is ready to search for metadata. */
+
+ FLAC__STREAM_DECODER_READ_METADATA,
+ /**< The decoder is ready to or is in the process of reading metadata. */
+
+ FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC,
+ /**< The decoder is ready to or is in the process of searching for the
+ * frame sync code.
+ */
+
+ FLAC__STREAM_DECODER_READ_FRAME,
+ /**< The decoder is ready to or is in the process of reading a frame. */
+
+ FLAC__STREAM_DECODER_END_OF_STREAM,
+ /**< The decoder has reached the end of the stream. */
+
+ FLAC__STREAM_DECODER_OGG_ERROR,
+ /**< An error occurred in the underlying Ogg layer. */
+
+ FLAC__STREAM_DECODER_SEEK_ERROR,
+ /**< An error occurred while seeking. The decoder must be flushed
+ * with FLAC__stream_decoder_flush() or reset with
+ * FLAC__stream_decoder_reset() before decoding can continue.
+ */
+
+ FLAC__STREAM_DECODER_ABORTED,
+ /**< The decoder was aborted by the read callback. */
+
+ FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR,
+ /**< An error occurred allocating memory. The decoder is in an invalid
+ * state and can no longer be used.
+ */
+
+ FLAC__STREAM_DECODER_UNINITIALIZED
+ /**< The decoder is in the uninitialized state; one of the
+ * FLAC__stream_decoder_init_*() functions must be called before samples
+ * can be processed.
+ */
+
+} FLAC__StreamDecoderState;
+
+/** Maps a FLAC__StreamDecoderState to a C string.
+ *
+ * Using a FLAC__StreamDecoderState as the index to this array
+ * will give the string equivalent. The contents should not be modified.
+ */
+extern FLAC_API const char * const FLAC__StreamDecoderStateString[];
+
+
+/** Possible return values for the FLAC__stream_decoder_init_*() functions.
+ */
+typedef enum {
+
+ FLAC__STREAM_DECODER_INIT_STATUS_OK = 0,
+ /**< Initialization was successful. */
+
+ FLAC__STREAM_DECODER_INIT_STATUS_UNSUPPORTED_CONTAINER,
+ /**< The library was not compiled with support for the given container
+ * format.
+ */
+
+ FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS,
+ /**< A required callback was not supplied. */
+
+ FLAC__STREAM_DECODER_INIT_STATUS_MEMORY_ALLOCATION_ERROR,
+ /**< An error occurred allocating memory. */
+
+ FLAC__STREAM_DECODER_INIT_STATUS_ERROR_OPENING_FILE,
+ /**< fopen() failed in FLAC__stream_decoder_init_file() or
+ * FLAC__stream_decoder_init_ogg_file(). */
+
+ FLAC__STREAM_DECODER_INIT_STATUS_ALREADY_INITIALIZED
+ /**< FLAC__stream_decoder_init_*() was called when the decoder was
+ * already initialized, usually because
+ * FLAC__stream_decoder_finish() was not called.
+ */
+
+} FLAC__StreamDecoderInitStatus;
+
+/** Maps a FLAC__StreamDecoderInitStatus to a C string.
+ *
+ * Using a FLAC__StreamDecoderInitStatus as the index to this array
+ * will give the string equivalent. The contents should not be modified.
+ */
+extern FLAC_API const char * const FLAC__StreamDecoderInitStatusString[];
+
+
+/** Return values for the FLAC__StreamDecoder read callback.
+ */
+typedef enum {
+
+ FLAC__STREAM_DECODER_READ_STATUS_CONTINUE,
+ /**< The read was OK and decoding can continue. */
+
+ FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM,
+ /**< The read was attempted while at the end of the stream. Note that
+ * the client must only return this value when the read callback was
+ * called when already at the end of the stream. Otherwise, if the read
+ * itself moves to the end of the stream, the client should still return
+ * the data and \c FLAC__STREAM_DECODER_READ_STATUS_CONTINUE, and then on
+ * the next read callback it should return
+ * \c FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM with a byte count
+ * of \c 0.
+ */
+
+ FLAC__STREAM_DECODER_READ_STATUS_ABORT
+ /**< An unrecoverable error occurred. The decoder will return from the process call. */
+
+} FLAC__StreamDecoderReadStatus;
+
+/** Maps a FLAC__StreamDecoderReadStatus to a C string.
+ *
+ * Using a FLAC__StreamDecoderReadStatus as the index to this array
+ * will give the string equivalent. The contents should not be modified.
+ */
+extern FLAC_API const char * const FLAC__StreamDecoderReadStatusString[];
+
+
+/** Return values for the FLAC__StreamDecoder seek callback.
+ */
+typedef enum {
+
+ FLAC__STREAM_DECODER_SEEK_STATUS_OK,
+ /**< The seek was OK and decoding can continue. */
+
+ FLAC__STREAM_DECODER_SEEK_STATUS_ERROR,
+ /**< An unrecoverable error occurred. The decoder will return from the process call. */
+
+ FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED
+ /**< Client does not support seeking. */
+
+} FLAC__StreamDecoderSeekStatus;
+
+/** Maps a FLAC__StreamDecoderSeekStatus to a C string.
+ *
+ * Using a FLAC__StreamDecoderSeekStatus as the index to this array
+ * will give the string equivalent. The contents should not be modified.
+ */
+extern FLAC_API const char * const FLAC__StreamDecoderSeekStatusString[];
+
+
+/** Return values for the FLAC__StreamDecoder tell callback.
+ */
+typedef enum {
+
+ FLAC__STREAM_DECODER_TELL_STATUS_OK,
+ /**< The tell was OK and decoding can continue. */
+
+ FLAC__STREAM_DECODER_TELL_STATUS_ERROR,
+ /**< An unrecoverable error occurred. The decoder will return from the process call. */
+
+ FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED
+ /**< Client does not support telling the position. */
+
+} FLAC__StreamDecoderTellStatus;
+
+/** Maps a FLAC__StreamDecoderTellStatus to a C string.
+ *
+ * Using a FLAC__StreamDecoderTellStatus as the index to this array
+ * will give the string equivalent. The contents should not be modified.
+ */
+extern FLAC_API const char * const FLAC__StreamDecoderTellStatusString[];
+
+
+/** Return values for the FLAC__StreamDecoder length callback.
+ */
+typedef enum {
+
+ FLAC__STREAM_DECODER_LENGTH_STATUS_OK,
+ /**< The length call was OK and decoding can continue. */
+
+ FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR,
+ /**< An unrecoverable error occurred. The decoder will return from the process call. */
+
+ FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED
+ /**< Client does not support reporting the length. */
+
+} FLAC__StreamDecoderLengthStatus;
+
+/** Maps a FLAC__StreamDecoderLengthStatus to a C string.
+ *
+ * Using a FLAC__StreamDecoderLengthStatus as the index to this array
+ * will give the string equivalent. The contents should not be modified.
+ */
+extern FLAC_API const char * const FLAC__StreamDecoderLengthStatusString[];
+
+
+/** Return values for the FLAC__StreamDecoder write callback.
+ */
+typedef enum {
+
+ FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE,
+ /**< The write was OK and decoding can continue. */
+
+ FLAC__STREAM_DECODER_WRITE_STATUS_ABORT
+ /**< An unrecoverable error occurred. The decoder will return from the process call. */
+
+} FLAC__StreamDecoderWriteStatus;
+
+/** Maps a FLAC__StreamDecoderWriteStatus to a C string.
+ *
+ * Using a FLAC__StreamDecoderWriteStatus as the index to this array
+ * will give the string equivalent. The contents should not be modified.
+ */
+extern FLAC_API const char * const FLAC__StreamDecoderWriteStatusString[];
+
+
+/** Possible values passed back to the FLAC__StreamDecoder error callback.
+ * \c FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC is the generic catch-
+ * all. The rest could be caused by bad sync (false synchronization on
+ * data that is not the start of a frame) or corrupted data. The error
+ * itself is the decoder's best guess at what happened assuming a correct
+ * sync. For example \c FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER
+ * could be caused by a correct sync on the start of a frame, but some
+ * data in the frame header was corrupted. Or it could be the result of
+ * syncing on a point the stream that looked like the starting of a frame
+ * but was not. \c FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM
+ * could be because the decoder encountered a valid frame made by a future
+ * version of the encoder which it cannot parse, or because of a false
+ * sync making it appear as though an encountered frame was generated by
+ * a future encoder.
+ */
+typedef enum {
+
+ FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC,
+ /**< An error in the stream caused the decoder to lose synchronization. */
+
+ FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER,
+ /**< The decoder encountered a corrupted frame header. */
+
+ FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH,
+ /**< The frame's data did not match the CRC in the footer. */
+
+ FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM
+ /**< The decoder encountered reserved fields in use in the stream. */
+
+} FLAC__StreamDecoderErrorStatus;
+
+/** Maps a FLAC__StreamDecoderErrorStatus to a C string.
+ *
+ * Using a FLAC__StreamDecoderErrorStatus as the index to this array
+ * will give the string equivalent. The contents should not be modified.
+ */
+extern FLAC_API const char * const FLAC__StreamDecoderErrorStatusString[];
+
+
+/***********************************************************************
+ *
+ * class FLAC__StreamDecoder
+ *
+ ***********************************************************************/
+
+struct FLAC__StreamDecoderProtected;
+struct FLAC__StreamDecoderPrivate;
+/** The opaque structure definition for the stream decoder type.
+ * See the \link flac_stream_decoder stream decoder module \endlink
+ * for a detailed description.
+ */
+typedef struct {
+ struct FLAC__StreamDecoderProtected *protected_; /* avoid the C++ keyword 'protected' */
+ struct FLAC__StreamDecoderPrivate *private_; /* avoid the C++ keyword 'private' */
+} FLAC__StreamDecoder;
+
+/** Signature for the read callback.
+ *
+ * A function pointer matching this signature must be passed to
+ * FLAC__stream_decoder_init*_stream(). The supplied function will be
+ * called when the decoder needs more input data. The address of the
+ * buffer to be filled is supplied, along with the number of bytes the
+ * buffer can hold. The callback may choose to supply less data and
+ * modify the byte count but must be careful not to overflow the buffer.
+ * The callback then returns a status code chosen from
+ * FLAC__StreamDecoderReadStatus.
+ *
+ * Here is an example of a read callback for stdio streams:
+ * \code
+ * FLAC__StreamDecoderReadStatus read_cb(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data)
+ * {
+ * FILE *file = ((MyClientData*)client_data)->file;
+ * if(*bytes > 0) {
+ * *bytes = fread(buffer, sizeof(FLAC__byte), *bytes, file);
+ * if(ferror(file))
+ * return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
+ * else if(*bytes == 0)
+ * return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
+ * else
+ * return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
+ * }
+ * else
+ * return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
+ * }
+ * \endcode
+ *
+ * \note In general, FLAC__StreamDecoder functions which change the
+ * state should not be called on the \a decoder while in the callback.
+ *
+ * \param decoder The decoder instance calling the callback.
+ * \param buffer A pointer to a location for the callee to store
+ * data to be decoded.
+ * \param bytes A pointer to the size of the buffer. On entry
+ * to the callback, it contains the maximum number
+ * of bytes that may be stored in \a buffer. The
+ * callee must set it to the actual number of bytes
+ * stored (0 in case of error or end-of-stream) before
+ * returning.
+ * \param client_data The callee's client data set through
+ * FLAC__stream_decoder_init_*().
+ * \retval FLAC__StreamDecoderReadStatus
+ * The callee's return status. Note that the callback should return
+ * \c FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM if and only if
+ * zero bytes were read and there is no more data to be read.
+ */
+typedef FLAC__StreamDecoderReadStatus (*FLAC__StreamDecoderReadCallback)(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data);
+
+/** Signature for the seek callback.
+ *
+ * A function pointer matching this signature may be passed to
+ * FLAC__stream_decoder_init*_stream(). The supplied function will be
+ * called when the decoder needs to seek the input stream. The decoder
+ * will pass the absolute byte offset to seek to, 0 meaning the
+ * beginning of the stream.
+ *
+ * Here is an example of a seek callback for stdio streams:
+ * \code
+ * FLAC__StreamDecoderSeekStatus seek_cb(const FLAC__StreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data)
+ * {
+ * FILE *file = ((MyClientData*)client_data)->file;
+ * if(file == stdin)
+ * return FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED;
+ * else if(fseeko(file, (off_t)absolute_byte_offset, SEEK_SET) < 0)
+ * return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR;
+ * else
+ * return FLAC__STREAM_DECODER_SEEK_STATUS_OK;
+ * }
+ * \endcode
+ *
+ * \note In general, FLAC__StreamDecoder functions which change the
+ * state should not be called on the \a decoder while in the callback.
+ *
+ * \param decoder The decoder instance calling the callback.
+ * \param absolute_byte_offset The offset from the beginning of the stream
+ * to seek to.
+ * \param client_data The callee's client data set through
+ * FLAC__stream_decoder_init_*().
+ * \retval FLAC__StreamDecoderSeekStatus
+ * The callee's return status.
+ */
+typedef FLAC__StreamDecoderSeekStatus (*FLAC__StreamDecoderSeekCallback)(const FLAC__StreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data);
+
+/** Signature for the tell callback.
+ *
+ * A function pointer matching this signature may be passed to
+ * FLAC__stream_decoder_init*_stream(). The supplied function will be
+ * called when the decoder wants to know the current position of the
+ * stream. The callback should return the byte offset from the
+ * beginning of the stream.
+ *
+ * Here is an example of a tell callback for stdio streams:
+ * \code
+ * FLAC__StreamDecoderTellStatus tell_cb(const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data)
+ * {
+ * FILE *file = ((MyClientData*)client_data)->file;
+ * off_t pos;
+ * if(file == stdin)
+ * return FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED;
+ * else if((pos = ftello(file)) < 0)
+ * return FLAC__STREAM_DECODER_TELL_STATUS_ERROR;
+ * else {
+ * *absolute_byte_offset = (FLAC__uint64)pos;
+ * return FLAC__STREAM_DECODER_TELL_STATUS_OK;
+ * }
+ * }
+ * \endcode
+ *
+ * \note In general, FLAC__StreamDecoder functions which change the
+ * state should not be called on the \a decoder while in the callback.
+ *
+ * \param decoder The decoder instance calling the callback.
+ * \param absolute_byte_offset A pointer to storage for the current offset
+ * from the beginning of the stream.
+ * \param client_data The callee's client data set through
+ * FLAC__stream_decoder_init_*().
+ * \retval FLAC__StreamDecoderTellStatus
+ * The callee's return status.
+ */
+typedef FLAC__StreamDecoderTellStatus (*FLAC__StreamDecoderTellCallback)(const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data);
+
+/** Signature for the length callback.
+ *
+ * A function pointer matching this signature may be passed to
+ * FLAC__stream_decoder_init*_stream(). The supplied function will be
+ * called when the decoder wants to know the total length of the stream
+ * in bytes.
+ *
+ * Here is an example of a length callback for stdio streams:
+ * \code
+ * FLAC__StreamDecoderLengthStatus length_cb(const FLAC__StreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data)
+ * {
+ * FILE *file = ((MyClientData*)client_data)->file;
+ * struct stat filestats;
+ *
+ * if(file == stdin)
+ * return FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED;
+ * else if(fstat(fileno(file), &filestats) != 0)
+ * return FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR;
+ * else {
+ * *stream_length = (FLAC__uint64)filestats.st_size;
+ * return FLAC__STREAM_DECODER_LENGTH_STATUS_OK;
+ * }
+ * }
+ * \endcode
+ *
+ * \note In general, FLAC__StreamDecoder functions which change the
+ * state should not be called on the \a decoder while in the callback.
+ *
+ * \param decoder The decoder instance calling the callback.
+ * \param stream_length A pointer to storage for the length of the stream
+ * in bytes.
+ * \param client_data The callee's client data set through
+ * FLAC__stream_decoder_init_*().
+ * \retval FLAC__StreamDecoderLengthStatus
+ * The callee's return status.
+ */
+typedef FLAC__StreamDecoderLengthStatus (*FLAC__StreamDecoderLengthCallback)(const FLAC__StreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data);
+
+/** Signature for the EOF callback.
+ *
+ * A function pointer matching this signature may be passed to
+ * FLAC__stream_decoder_init*_stream(). The supplied function will be
+ * called when the decoder needs to know if the end of the stream has
+ * been reached.
+ *
+ * Here is an example of a EOF callback for stdio streams:
+ * FLAC__bool eof_cb(const FLAC__StreamDecoder *decoder, void *client_data)
+ * \code
+ * {
+ * FILE *file = ((MyClientData*)client_data)->file;
+ * return feof(file)? true : false;
+ * }
+ * \endcode
+ *
+ * \note In general, FLAC__StreamDecoder functions which change the
+ * state should not be called on the \a decoder while in the callback.
+ *
+ * \param decoder The decoder instance calling the callback.
+ * \param client_data The callee's client data set through
+ * FLAC__stream_decoder_init_*().
+ * \retval FLAC__bool
+ * \c true if the currently at the end of the stream, else \c false.
+ */
+typedef FLAC__bool (*FLAC__StreamDecoderEofCallback)(const FLAC__StreamDecoder *decoder, void *client_data);
+
+/** Signature for the write callback.
+ *
+ * A function pointer matching this signature must be passed to one of
+ * the FLAC__stream_decoder_init_*() functions.
+ * The supplied function will be called when the decoder has decoded a
+ * single audio frame. The decoder will pass the frame metadata as well
+ * as an array of pointers (one for each channel) pointing to the
+ * decoded audio.
+ *
+ * \note In general, FLAC__StreamDecoder functions which change the
+ * state should not be called on the \a decoder while in the callback.
+ *
+ * \param decoder The decoder instance calling the callback.
+ * \param frame The description of the decoded frame. See
+ * FLAC__Frame.
+ * \param buffer An array of pointers to decoded channels of data.
+ * Each pointer will point to an array of signed
+ * samples of length \a frame->header.blocksize.
+ * Channels will be ordered according to the FLAC
+ * specification; see the documentation for the
+ * <A HREF="../format.html#frame_header">frame header</A>.
+ * \param client_data The callee's client data set through
+ * FLAC__stream_decoder_init_*().
+ * \retval FLAC__StreamDecoderWriteStatus
+ * The callee's return status.
+ */
+typedef FLAC__StreamDecoderWriteStatus (*FLAC__StreamDecoderWriteCallback)(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data);
+
+/** Signature for the metadata callback.
+ *
+ * A function pointer matching this signature must be passed to one of
+ * the FLAC__stream_decoder_init_*() functions.
+ * The supplied function will be called when the decoder has decoded a
+ * metadata block. In a valid FLAC file there will always be one
+ * \c STREAMINFO block, followed by zero or more other metadata blocks.
+ * These will be supplied by the decoder in the same order as they
+ * appear in the stream and always before the first audio frame (i.e.
+ * write callback). The metadata block that is passed in must not be
+ * modified, and it doesn't live beyond the callback, so you should make
+ * a copy of it with FLAC__metadata_object_clone() if you will need it
+ * elsewhere. Since metadata blocks can potentially be large, by
+ * default the decoder only calls the metadata callback for the
+ * \c STREAMINFO block; you can instruct the decoder to pass or filter
+ * other blocks with FLAC__stream_decoder_set_metadata_*() calls.
+ *
+ * \note In general, FLAC__StreamDecoder functions which change the
+ * state should not be called on the \a decoder while in the callback.
+ *
+ * \param decoder The decoder instance calling the callback.
+ * \param metadata The decoded metadata block.
+ * \param client_data The callee's client data set through
+ * FLAC__stream_decoder_init_*().
+ */
+typedef void (*FLAC__StreamDecoderMetadataCallback)(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data);
+
+/** Signature for the error callback.
+ *
+ * A function pointer matching this signature must be passed to one of
+ * the FLAC__stream_decoder_init_*() functions.
+ * The supplied function will be called whenever an error occurs during
+ * decoding.
+ *
+ * \note In general, FLAC__StreamDecoder functions which change the
+ * state should not be called on the \a decoder while in the callback.
+ *
+ * \param decoder The decoder instance calling the callback.
+ * \param status The error encountered by the decoder.
+ * \param client_data The callee's client data set through
+ * FLAC__stream_decoder_init_*().
+ */
+typedef void (*FLAC__StreamDecoderErrorCallback)(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data);
+
+
+/***********************************************************************
+ *
+ * Class constructor/destructor
+ *
+ ***********************************************************************/
+
+/** Create a new stream decoder instance. The instance is created with
+ * default settings; see the individual FLAC__stream_decoder_set_*()
+ * functions for each setting's default.
+ *
+ * \retval FLAC__StreamDecoder*
+ * \c NULL if there was an error allocating memory, else the new instance.
+ */
+FLAC_API FLAC__StreamDecoder *FLAC__stream_decoder_new(void);
+
+/** Free a decoder instance. Deletes the object pointed to by \a decoder.
+ *
+ * \param decoder A pointer to an existing decoder.
+ * \assert
+ * \code decoder != NULL \endcode
+ */
+FLAC_API void FLAC__stream_decoder_delete(FLAC__StreamDecoder *decoder);
+
+
+/***********************************************************************
+ *
+ * Public class method prototypes
+ *
+ ***********************************************************************/
+
+/** Set the serial number for the FLAC stream within the Ogg container.
+ * The default behavior is to use the serial number of the first Ogg
+ * page. Setting a serial number here will explicitly specify which
+ * stream is to be decoded.
+ *
+ * \note
+ * This does not need to be set for native FLAC decoding.
+ *
+ * \default \c use serial number of first page
+ * \param decoder A decoder instance to set.
+ * \param serial_number See above.
+ * \assert
+ * \code decoder != NULL \endcode
+ * \retval FLAC__bool
+ * \c false if the decoder is already initialized, else \c true.
+ */
+FLAC_API FLAC__bool FLAC__stream_decoder_set_ogg_serial_number(FLAC__StreamDecoder *decoder, long serial_number);
+
+/** Set the "MD5 signature checking" flag. If \c true, the decoder will
+ * compute the MD5 signature of the unencoded audio data while decoding
+ * and compare it to the signature from the STREAMINFO block, if it
+ * exists, during FLAC__stream_decoder_finish().
+ *
+ * MD5 signature checking will be turned off (until the next
+ * FLAC__stream_decoder_reset()) if there is no signature in the
+ * STREAMINFO block or when a seek is attempted.
+ *
+ * Clients that do not use the MD5 check should leave this off to speed
+ * up decoding.
+ *
+ * \default \c false
+ * \param decoder A decoder instance to set.
+ * \param value Flag value (see above).
+ * \assert
+ * \code decoder != NULL \endcode
+ * \retval FLAC__bool
+ * \c false if the decoder is already initialized, else \c true.
+ */
+FLAC_API FLAC__bool FLAC__stream_decoder_set_md5_checking(FLAC__StreamDecoder *decoder, FLAC__bool value);
+
+/** Direct the decoder to pass on all metadata blocks of type \a type.
+ *
+ * \default By default, only the \c STREAMINFO block is returned via the
+ * metadata callback.
+ * \param decoder A decoder instance to set.
+ * \param type See above.
+ * \assert
+ * \code decoder != NULL \endcode
+ * \a type is valid
+ * \retval FLAC__bool
+ * \c false if the decoder is already initialized, else \c true.
+ */
+FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_respond(FLAC__StreamDecoder *decoder, FLAC__MetadataType type);
+
+/** Direct the decoder to pass on all APPLICATION metadata blocks of the
+ * given \a id.
+ *
+ * \default By default, only the \c STREAMINFO block is returned via the
+ * metadata callback.
+ * \param decoder A decoder instance to set.
+ * \param id See above.
+ * \assert
+ * \code decoder != NULL \endcode
+ * \code id != NULL \endcode
+ * \retval FLAC__bool
+ * \c false if the decoder is already initialized, else \c true.
+ */
+FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_respond_application(FLAC__StreamDecoder *decoder, const FLAC__byte id[4]);
+
+/** Direct the decoder to pass on all metadata blocks of any type.
+ *
+ * \default By default, only the \c STREAMINFO block is returned via the
+ * metadata callback.
+ * \param decoder A decoder instance to set.
+ * \assert
+ * \code decoder != NULL \endcode
+ * \retval FLAC__bool
+ * \c false if the decoder is already initialized, else \c true.
+ */
+FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_respond_all(FLAC__StreamDecoder *decoder);
+
+/** Direct the decoder to filter out all metadata blocks of type \a type.
+ *
+ * \default By default, only the \c STREAMINFO block is returned via the
+ * metadata callback.
+ * \param decoder A decoder instance to set.
+ * \param type See above.
+ * \assert
+ * \code decoder != NULL \endcode
+ * \a type is valid
+ * \retval FLAC__bool
+ * \c false if the decoder is already initialized, else \c true.
+ */
+FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_ignore(FLAC__StreamDecoder *decoder, FLAC__MetadataType type);
+
+/** Direct the decoder to filter out all APPLICATION metadata blocks of
+ * the given \a id.
+ *
+ * \default By default, only the \c STREAMINFO block is returned via the
+ * metadata callback.
+ * \param decoder A decoder instance to set.
+ * \param id See above.
+ * \assert
+ * \code decoder != NULL \endcode
+ * \code id != NULL \endcode
+ * \retval FLAC__bool
+ * \c false if the decoder is already initialized, else \c true.
+ */
+FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_ignore_application(FLAC__StreamDecoder *decoder, const FLAC__byte id[4]);
+
+/** Direct the decoder to filter out all metadata blocks of any type.
+ *
+ * \default By default, only the \c STREAMINFO block is returned via the
+ * metadata callback.
+ * \param decoder A decoder instance to set.
+ * \assert
+ * \code decoder != NULL \endcode
+ * \retval FLAC__bool
+ * \c false if the decoder is already initialized, else \c true.
+ */
+FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_ignore_all(FLAC__StreamDecoder *decoder);
+
+/** Get the current decoder state.
+ *
+ * \param decoder A decoder instance to query.
+ * \assert
+ * \code decoder != NULL \endcode
+ * \retval FLAC__StreamDecoderState
+ * The current decoder state.
+ */
+FLAC_API FLAC__StreamDecoderState FLAC__stream_decoder_get_state(const FLAC__StreamDecoder *decoder);
+
+/** Get the current decoder state as a C string.
+ *
+ * \param decoder A decoder instance to query.
+ * \assert
+ * \code decoder != NULL \endcode
+ * \retval const char *
+ * The decoder state as a C string. Do not modify the contents.
+ */
+FLAC_API const char *FLAC__stream_decoder_get_resolved_state_string(const FLAC__StreamDecoder *decoder);
+
+/** Get the "MD5 signature checking" flag.
+ * This is the value of the setting, not whether or not the decoder is
+ * currently checking the MD5 (remember, it can be turned off automatically
+ * by a seek). When the decoder is reset the flag will be restored to the
+ * value returned by this function.
+ *
+ * \param decoder A decoder instance to query.
+ * \assert
+ * \code decoder != NULL \endcode
+ * \retval FLAC__bool
+ * See above.
+ */
+FLAC_API FLAC__bool FLAC__stream_decoder_get_md5_checking(const FLAC__StreamDecoder *decoder);
+
+/** Get the total number of samples in the stream being decoded.
+ * Will only be valid after decoding has started and will contain the
+ * value from the \c STREAMINFO block. A value of \c 0 means "unknown".
+ *
+ * \param decoder A decoder instance to query.
+ * \assert
+ * \code decoder != NULL \endcode
+ * \retval unsigned
+ * See above.
+ */
+FLAC_API FLAC__uint64 FLAC__stream_decoder_get_total_samples(const FLAC__StreamDecoder *decoder);
+
+/** Get the current number of channels in the stream being decoded.
+ * Will only be valid after decoding has started and will contain the
+ * value from the most recently decoded frame header.
+ *
+ * \param decoder A decoder instance to query.
+ * \assert
+ * \code decoder != NULL \endcode
+ * \retval unsigned
+ * See above.
+ */
+FLAC_API unsigned FLAC__stream_decoder_get_channels(const FLAC__StreamDecoder *decoder);
+
+/** Get the current channel assignment in the stream being decoded.
+ * Will only be valid after decoding has started and will contain the
+ * value from the most recently decoded frame header.
+ *
+ * \param decoder A decoder instance to query.
+ * \assert
+ * \code decoder != NULL \endcode
+ * \retval FLAC__ChannelAssignment
+ * See above.
+ */
+FLAC_API FLAC__ChannelAssignment FLAC__stream_decoder_get_channel_assignment(const FLAC__StreamDecoder *decoder);
+
+/** Get the current sample resolution in the stream being decoded.
+ * Will only be valid after decoding has started and will contain the
+ * value from the most recently decoded frame header.
+ *
+ * \param decoder A decoder instance to query.
+ * \assert
+ * \code decoder != NULL \endcode
+ * \retval unsigned
+ * See above.
+ */
+FLAC_API unsigned FLAC__stream_decoder_get_bits_per_sample(const FLAC__StreamDecoder *decoder);
+
+/** Get the current sample rate in Hz of the stream being decoded.
+ * Will only be valid after decoding has started and will contain the
+ * value from the most recently decoded frame header.
+ *
+ * \param decoder A decoder instance to query.
+ * \assert
+ * \code decoder != NULL \endcode
+ * \retval unsigned
+ * See above.
+ */
+FLAC_API unsigned FLAC__stream_decoder_get_sample_rate(const FLAC__StreamDecoder *decoder);
+
+/** Get the current blocksize of the stream being decoded.
+ * Will only be valid after decoding has started and will contain the
+ * value from the most recently decoded frame header.
+ *
+ * \param decoder A decoder instance to query.
+ * \assert
+ * \code decoder != NULL \endcode
+ * \retval unsigned
+ * See above.
+ */
+FLAC_API unsigned FLAC__stream_decoder_get_blocksize(const FLAC__StreamDecoder *decoder);
+
+/** Returns the decoder's current read position within the stream.
+ * The position is the byte offset from the start of the stream.
+ * Bytes before this position have been fully decoded. Note that
+ * there may still be undecoded bytes in the decoder's read FIFO.
+ * The returned position is correct even after a seek.
+ *
+ * \warning This function currently only works for native FLAC,
+ * not Ogg FLAC streams.
+ *
+ * \param decoder A decoder instance to query.
+ * \param position Address at which to return the desired position.
+ * \assert
+ * \code decoder != NULL \endcode
+ * \code position != NULL \endcode
+ * \retval FLAC__bool
+ * \c true if successful, \c false if the stream is not native FLAC,
+ * or there was an error from the 'tell' callback or it returned
+ * \c FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED.
+ */
+FLAC_API FLAC__bool FLAC__stream_decoder_get_decode_position(const FLAC__StreamDecoder *decoder, FLAC__uint64 *position);
+
+/** Initialize the decoder instance to decode native FLAC streams.
+ *
+ * This flavor of initialization sets up the decoder to decode from a
+ * native FLAC stream. I/O is performed via callbacks to the client.
+ * For decoding from a plain file via filename or open FILE*,
+ * FLAC__stream_decoder_init_file() and FLAC__stream_decoder_init_FILE()
+ * provide a simpler interface.
+ *
+ * This function should be called after FLAC__stream_decoder_new() and
+ * FLAC__stream_decoder_set_*() but before any of the
+ * FLAC__stream_decoder_process_*() functions. Will set and return the
+ * decoder state, which will be FLAC__STREAM_DECODER_SEARCH_FOR_METADATA
+ * if initialization succeeded.
+ *
+ * \param decoder An uninitialized decoder instance.
+ * \param read_callback See FLAC__StreamDecoderReadCallback. This
+ * pointer must not be \c NULL.
+ * \param seek_callback See FLAC__StreamDecoderSeekCallback. This
+ * pointer may be \c NULL if seeking is not
+ * supported. If \a seek_callback is not \c NULL then a
+ * \a tell_callback, \a length_callback, and \a eof_callback must also be supplied.
+ * Alternatively, a dummy seek callback that just
+ * returns \c FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED
+ * may also be supplied, all though this is slightly
+ * less efficient for the decoder.
+ * \param tell_callback See FLAC__StreamDecoderTellCallback. This
+ * pointer may be \c NULL if not supported by the client. If
+ * \a seek_callback is not \c NULL then a
+ * \a tell_callback must also be supplied.
+ * Alternatively, a dummy tell callback that just
+ * returns \c FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED
+ * may also be supplied, all though this is slightly
+ * less efficient for the decoder.
+ * \param length_callback See FLAC__StreamDecoderLengthCallback. This
+ * pointer may be \c NULL if not supported by the client. If
+ * \a seek_callback is not \c NULL then a
+ * \a length_callback must also be supplied.
+ * Alternatively, a dummy length callback that just
+ * returns \c FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED
+ * may also be supplied, all though this is slightly
+ * less efficient for the decoder.
+ * \param eof_callback See FLAC__StreamDecoderEofCallback. This
+ * pointer may be \c NULL if not supported by the client. If
+ * \a seek_callback is not \c NULL then a
+ * \a eof_callback must also be supplied.
+ * Alternatively, a dummy length callback that just
+ * returns \c false
+ * may also be supplied, all though this is slightly
+ * less efficient for the decoder.
+ * \param write_callback See FLAC__StreamDecoderWriteCallback. This
+ * pointer must not be \c NULL.
+ * \param metadata_callback See FLAC__StreamDecoderMetadataCallback. This
+ * pointer may be \c NULL if the callback is not
+ * desired.
+ * \param error_callback See FLAC__StreamDecoderErrorCallback. This
+ * pointer must not be \c NULL.
+ * \param client_data This value will be supplied to callbacks in their
+ * \a client_data argument.
+ * \assert
+ * \code decoder != NULL \endcode
+ * \retval FLAC__StreamDecoderInitStatus
+ * \c FLAC__STREAM_DECODER_INIT_STATUS_OK if initialization was successful;
+ * see FLAC__StreamDecoderInitStatus for the meanings of other return values.
+ */
+FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_stream(
+ FLAC__StreamDecoder *decoder,
+ FLAC__StreamDecoderReadCallback read_callback,
+ FLAC__StreamDecoderSeekCallback seek_callback,
+ FLAC__StreamDecoderTellCallback tell_callback,
+ FLAC__StreamDecoderLengthCallback length_callback,
+ FLAC__StreamDecoderEofCallback eof_callback,
+ FLAC__StreamDecoderWriteCallback write_callback,
+ FLAC__StreamDecoderMetadataCallback metadata_callback,
+ FLAC__StreamDecoderErrorCallback error_callback,
+ void *client_data
+);
+
+/** Initialize the decoder instance to decode Ogg FLAC streams.
+ *
+ * This flavor of initialization sets up the decoder to decode from a
+ * FLAC stream in an Ogg container. I/O is performed via callbacks to the
+ * client. For decoding from a plain file via filename or open FILE*,
+ * FLAC__stream_decoder_init_ogg_file() and FLAC__stream_decoder_init_ogg_FILE()
+ * provide a simpler interface.
+ *
+ * This function should be called after FLAC__stream_decoder_new() and
+ * FLAC__stream_decoder_set_*() but before any of the
+ * FLAC__stream_decoder_process_*() functions. Will set and return the
+ * decoder state, which will be FLAC__STREAM_DECODER_SEARCH_FOR_METADATA
+ * if initialization succeeded.
+ *
+ * \note Support for Ogg FLAC in the library is optional. If this
+ * library has been built without support for Ogg FLAC, this function
+ * will return \c FLAC__STREAM_DECODER_INIT_STATUS_UNSUPPORTED_CONTAINER.
+ *
+ * \param decoder An uninitialized decoder instance.
+ * \param read_callback See FLAC__StreamDecoderReadCallback. This
+ * pointer must not be \c NULL.
+ * \param seek_callback See FLAC__StreamDecoderSeekCallback. This
+ * pointer may be \c NULL if seeking is not
+ * supported. If \a seek_callback is not \c NULL then a
+ * \a tell_callback, \a length_callback, and \a eof_callback must also be supplied.
+ * Alternatively, a dummy seek callback that just
+ * returns \c FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED
+ * may also be supplied, all though this is slightly
+ * less efficient for the decoder.
+ * \param tell_callback See FLAC__StreamDecoderTellCallback. This
+ * pointer may be \c NULL if not supported by the client. If
+ * \a seek_callback is not \c NULL then a
+ * \a tell_callback must also be supplied.
+ * Alternatively, a dummy tell callback that just
+ * returns \c FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED
+ * may also be supplied, all though this is slightly
+ * less efficient for the decoder.
+ * \param length_callback See FLAC__StreamDecoderLengthCallback. This
+ * pointer may be \c NULL if not supported by the client. If
+ * \a seek_callback is not \c NULL then a
+ * \a length_callback must also be supplied.
+ * Alternatively, a dummy length callback that just
+ * returns \c FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED
+ * may also be supplied, all though this is slightly
+ * less efficient for the decoder.
+ * \param eof_callback See FLAC__StreamDecoderEofCallback. This
+ * pointer may be \c NULL if not supported by the client. If
+ * \a seek_callback is not \c NULL then a
+ * \a eof_callback must also be supplied.
+ * Alternatively, a dummy length callback that just
+ * returns \c false
+ * may also be supplied, all though this is slightly
+ * less efficient for the decoder.
+ * \param write_callback See FLAC__StreamDecoderWriteCallback. This
+ * pointer must not be \c NULL.
+ * \param metadata_callback See FLAC__StreamDecoderMetadataCallback. This
+ * pointer may be \c NULL if the callback is not
+ * desired.
+ * \param error_callback See FLAC__StreamDecoderErrorCallback. This
+ * pointer must not be \c NULL.
+ * \param client_data This value will be supplied to callbacks in their
+ * \a client_data argument.
+ * \assert
+ * \code decoder != NULL \endcode
+ * \retval FLAC__StreamDecoderInitStatus
+ * \c FLAC__STREAM_DECODER_INIT_STATUS_OK if initialization was successful;
+ * see FLAC__StreamDecoderInitStatus for the meanings of other return values.
+ */
+FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_ogg_stream(
+ FLAC__StreamDecoder *decoder,
+ FLAC__StreamDecoderReadCallback read_callback,
+ FLAC__StreamDecoderSeekCallback seek_callback,
+ FLAC__StreamDecoderTellCallback tell_callback,
+ FLAC__StreamDecoderLengthCallback length_callback,
+ FLAC__StreamDecoderEofCallback eof_callback,
+ FLAC__StreamDecoderWriteCallback write_callback,
+ FLAC__StreamDecoderMetadataCallback metadata_callback,
+ FLAC__StreamDecoderErrorCallback error_callback,
+ void *client_data
+);
+
+/** Initialize the decoder instance to decode native FLAC files.
+ *
+ * This flavor of initialization sets up the decoder to decode from a
+ * plain native FLAC file. For non-stdio streams, you must use
+ * FLAC__stream_decoder_init_stream() and provide callbacks for the I/O.
+ *
+ * This function should be called after FLAC__stream_decoder_new() and
+ * FLAC__stream_decoder_set_*() but before any of the
+ * FLAC__stream_decoder_process_*() functions. Will set and return the
+ * decoder state, which will be FLAC__STREAM_DECODER_SEARCH_FOR_METADATA
+ * if initialization succeeded.
+ *
+ * \param decoder An uninitialized decoder instance.
+ * \param file An open FLAC file. The file should have been
+ * opened with mode \c "rb" and rewound. The file
+ * becomes owned by the decoder and should not be
+ * manipulated by the client while decoding.
+ * Unless \a file is \c stdin, it will be closed
+ * when FLAC__stream_decoder_finish() is called.
+ * Note however that seeking will not work when
+ * decoding from \c stdout since it is not seekable.
+ * \param write_callback See FLAC__StreamDecoderWriteCallback. This
+ * pointer must not be \c NULL.
+ * \param metadata_callback See FLAC__StreamDecoderMetadataCallback. This
+ * pointer may be \c NULL if the callback is not
+ * desired.
+ * \param error_callback See FLAC__StreamDecoderErrorCallback. This
+ * pointer must not be \c NULL.
+ * \param client_data This value will be supplied to callbacks in their
+ * \a client_data argument.
+ * \assert
+ * \code decoder != NULL \endcode
+ * \code file != NULL \endcode
+ * \retval FLAC__StreamDecoderInitStatus
+ * \c FLAC__STREAM_DECODER_INIT_STATUS_OK if initialization was successful;
+ * see FLAC__StreamDecoderInitStatus for the meanings of other return values.
+ */
+FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_FILE(
+ FLAC__StreamDecoder *decoder,
+ FILE *file,
+ FLAC__StreamDecoderWriteCallback write_callback,
+ FLAC__StreamDecoderMetadataCallback metadata_callback,
+ FLAC__StreamDecoderErrorCallback error_callback,
+ void *client_data
+);
+
+/** Initialize the decoder instance to decode Ogg FLAC files.
+ *
+ * This flavor of initialization sets up the decoder to decode from a
+ * plain Ogg FLAC file. For non-stdio streams, you must use
+ * FLAC__stream_decoder_init_ogg_stream() and provide callbacks for the I/O.
+ *
+ * This function should be called after FLAC__stream_decoder_new() and
+ * FLAC__stream_decoder_set_*() but before any of the
+ * FLAC__stream_decoder_process_*() functions. Will set and return the
+ * decoder state, which will be FLAC__STREAM_DECODER_SEARCH_FOR_METADATA
+ * if initialization succeeded.
+ *
+ * \note Support for Ogg FLAC in the library is optional. If this
+ * library has been built without support for Ogg FLAC, this function
+ * will return \c FLAC__STREAM_DECODER_INIT_STATUS_UNSUPPORTED_CONTAINER.
+ *
+ * \param decoder An uninitialized decoder instance.
+ * \param file An open FLAC file. The file should have been
+ * opened with mode \c "rb" and rewound. The file
+ * becomes owned by the decoder and should not be
+ * manipulated by the client while decoding.
+ * Unless \a file is \c stdin, it will be closed
+ * when FLAC__stream_decoder_finish() is called.
+ * Note however that seeking will not work when
+ * decoding from \c stdout since it is not seekable.
+ * \param write_callback See FLAC__StreamDecoderWriteCallback. This
+ * pointer must not be \c NULL.
+ * \param metadata_callback See FLAC__StreamDecoderMetadataCallback. This
+ * pointer may be \c NULL if the callback is not
+ * desired.
+ * \param error_callback See FLAC__StreamDecoderErrorCallback. This
+ * pointer must not be \c NULL.
+ * \param client_data This value will be supplied to callbacks in their
+ * \a client_data argument.
+ * \assert
+ * \code decoder != NULL \endcode
+ * \code file != NULL \endcode
+ * \retval FLAC__StreamDecoderInitStatus
+ * \c FLAC__STREAM_DECODER_INIT_STATUS_OK if initialization was successful;
+ * see FLAC__StreamDecoderInitStatus for the meanings of other return values.
+ */
+FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_ogg_FILE(
+ FLAC__StreamDecoder *decoder,
+ FILE *file,
+ FLAC__StreamDecoderWriteCallback write_callback,
+ FLAC__StreamDecoderMetadataCallback metadata_callback,
+ FLAC__StreamDecoderErrorCallback error_callback,
+ void *client_data
+);
+
+/** Initialize the decoder instance to decode native FLAC files.
+ *
+ * This flavor of initialization sets up the decoder to decode from a plain
+ * native FLAC file. If POSIX fopen() semantics are not sufficient, (for
+ * example, with Unicode filenames on Windows), you must use
+ * FLAC__stream_decoder_init_FILE(), or FLAC__stream_decoder_init_stream()
+ * and provide callbacks for the I/O.
+ *
+ * This function should be called after FLAC__stream_decoder_new() and
+ * FLAC__stream_decoder_set_*() but before any of the
+ * FLAC__stream_decoder_process_*() functions. Will set and return the
+ * decoder state, which will be FLAC__STREAM_DECODER_SEARCH_FOR_METADATA
+ * if initialization succeeded.
+ *
+ * \param decoder An uninitialized decoder instance.
+ * \param filename The name of the file to decode from. The file will
+ * be opened with fopen(). Use \c NULL to decode from
+ * \c stdin. Note that \c stdin is not seekable.
+ * \param write_callback See FLAC__StreamDecoderWriteCallback. This
+ * pointer must not be \c NULL.
+ * \param metadata_callback See FLAC__StreamDecoderMetadataCallback. This
+ * pointer may be \c NULL if the callback is not
+ * desired.
+ * \param error_callback See FLAC__StreamDecoderErrorCallback. This
+ * pointer must not be \c NULL.
+ * \param client_data This value will be supplied to callbacks in their
+ * \a client_data argument.
+ * \assert
+ * \code decoder != NULL \endcode
+ * \retval FLAC__StreamDecoderInitStatus
+ * \c FLAC__STREAM_DECODER_INIT_STATUS_OK if initialization was successful;
+ * see FLAC__StreamDecoderInitStatus for the meanings of other return values.
+ */
+FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_file(
+ FLAC__StreamDecoder *decoder,
+ const char *filename,
+ FLAC__StreamDecoderWriteCallback write_callback,
+ FLAC__StreamDecoderMetadataCallback metadata_callback,
+ FLAC__StreamDecoderErrorCallback error_callback,
+ void *client_data
+);
+
+/** Initialize the decoder instance to decode Ogg FLAC files.
+ *
+ * This flavor of initialization sets up the decoder to decode from a plain
+ * Ogg FLAC file. If POSIX fopen() semantics are not sufficient, (for
+ * example, with Unicode filenames on Windows), you must use
+ * FLAC__stream_decoder_init_ogg_FILE(), or FLAC__stream_decoder_init_ogg_stream()
+ * and provide callbacks for the I/O.
+ *
+ * This function should be called after FLAC__stream_decoder_new() and
+ * FLAC__stream_decoder_set_*() but before any of the
+ * FLAC__stream_decoder_process_*() functions. Will set and return the
+ * decoder state, which will be FLAC__STREAM_DECODER_SEARCH_FOR_METADATA
+ * if initialization succeeded.
+ *
+ * \note Support for Ogg FLAC in the library is optional. If this
+ * library has been built without support for Ogg FLAC, this function
+ * will return \c FLAC__STREAM_DECODER_INIT_STATUS_UNSUPPORTED_CONTAINER.
+ *
+ * \param decoder An uninitialized decoder instance.
+ * \param filename The name of the file to decode from. The file will
+ * be opened with fopen(). Use \c NULL to decode from
+ * \c stdin. Note that \c stdin is not seekable.
+ * \param write_callback See FLAC__StreamDecoderWriteCallback. This
+ * pointer must not be \c NULL.
+ * \param metadata_callback See FLAC__StreamDecoderMetadataCallback. This
+ * pointer may be \c NULL if the callback is not
+ * desired.
+ * \param error_callback See FLAC__StreamDecoderErrorCallback. This
+ * pointer must not be \c NULL.
+ * \param client_data This value will be supplied to callbacks in their
+ * \a client_data argument.
+ * \assert
+ * \code decoder != NULL \endcode
+ * \retval FLAC__StreamDecoderInitStatus
+ * \c FLAC__STREAM_DECODER_INIT_STATUS_OK if initialization was successful;
+ * see FLAC__StreamDecoderInitStatus for the meanings of other return values.
+ */
+FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_ogg_file(
+ FLAC__StreamDecoder *decoder,
+ const char *filename,
+ FLAC__StreamDecoderWriteCallback write_callback,
+ FLAC__StreamDecoderMetadataCallback metadata_callback,
+ FLAC__StreamDecoderErrorCallback error_callback,
+ void *client_data
+);
+
+/** Finish the decoding process.
+ * Flushes the decoding buffer, releases resources, resets the decoder
+ * settings to their defaults, and returns the decoder state to
+ * FLAC__STREAM_DECODER_UNINITIALIZED.
+ *
+ * In the event of a prematurely-terminated decode, it is not strictly
+ * necessary to call this immediately before FLAC__stream_decoder_delete()
+ * but it is good practice to match every FLAC__stream_decoder_init_*()
+ * with a FLAC__stream_decoder_finish().
+ *
+ * \param decoder An uninitialized decoder instance.
+ * \assert
+ * \code decoder != NULL \endcode
+ * \retval FLAC__bool
+ * \c false if MD5 checking is on AND a STREAMINFO block was available
+ * AND the MD5 signature in the STREAMINFO block was non-zero AND the
+ * signature does not match the one computed by the decoder; else
+ * \c true.
+ */
+FLAC_API FLAC__bool FLAC__stream_decoder_finish(FLAC__StreamDecoder *decoder);
+
+/** Flush the stream input.
+ * The decoder's input buffer will be cleared and the state set to
+ * \c FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC. This will also turn
+ * off MD5 checking.
+ *
+ * \param decoder A decoder instance.
+ * \assert
+ * \code decoder != NULL \endcode
+ * \retval FLAC__bool
+ * \c true if successful, else \c false if a memory allocation
+ * error occurs (in which case the state will be set to
+ * \c FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR).
+ */
+FLAC_API FLAC__bool FLAC__stream_decoder_flush(FLAC__StreamDecoder *decoder);
+
+/** Reset the decoding process.
+ * The decoder's input buffer will be cleared and the state set to
+ * \c FLAC__STREAM_DECODER_SEARCH_FOR_METADATA. This is similar to
+ * FLAC__stream_decoder_finish() except that the settings are
+ * preserved; there is no need to call FLAC__stream_decoder_init_*()
+ * before decoding again. MD5 checking will be restored to its original
+ * setting.
+ *
+ * If the decoder is seekable, or was initialized with
+ * FLAC__stream_decoder_init*_FILE() or FLAC__stream_decoder_init*_file(),
+ * the decoder will also attempt to seek to the beginning of the file.
+ * If this rewind fails, this function will return \c false. It follows
+ * that FLAC__stream_decoder_reset() cannot be used when decoding from
+ * \c stdin.
+ *
+ * If the decoder was initialized with FLAC__stream_encoder_init*_stream()
+ * and is not seekable (i.e. no seek callback was provided or the seek
+ * callback returns \c FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED), it
+ * is the duty of the client to start feeding data from the beginning of
+ * the stream on the next FLAC__stream_decoder_process() or
+ * FLAC__stream_decoder_process_interleaved() call.
+ *
+ * \param decoder A decoder instance.
+ * \assert
+ * \code decoder != NULL \endcode
+ * \retval FLAC__bool
+ * \c true if successful, else \c false if a memory allocation occurs
+ * (in which case the state will be set to
+ * \c FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR) or a seek error
+ * occurs (the state will be unchanged).
+ */
+FLAC_API FLAC__bool FLAC__stream_decoder_reset(FLAC__StreamDecoder *decoder);
+
+/** Decode one metadata block or audio frame.
+ * This version instructs the decoder to decode a either a single metadata
+ * block or a single frame and stop, unless the callbacks return a fatal
+ * error or the read callback returns
+ * \c FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM.
+ *
+ * As the decoder needs more input it will call the read callback.
+ * Depending on what was decoded, the metadata or write callback will be
+ * called with the decoded metadata block or audio frame.
+ *
+ * Unless there is a fatal read error or end of stream, this function
+ * will return once one whole frame is decoded. In other words, if the
+ * stream is not synchronized or points to a corrupt frame header, the
+ * decoder will continue to try and resync until it gets to a valid
+ * frame, then decode one frame, then return. If the decoder points to
+ * a frame whose frame CRC in the frame footer does not match the
+ * computed frame CRC, this function will issue a
+ * FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH error to the
+ * error callback, and return, having decoded one complete, although
+ * corrupt, frame. (Such corrupted frames are sent as silence of the
+ * correct length to the write callback.)
+ *
+ * \param decoder An initialized decoder instance.
+ * \assert
+ * \code decoder != NULL \endcode
+ * \retval FLAC__bool
+ * \c false if any fatal read, write, or memory allocation error
+ * occurred (meaning decoding must stop), else \c true; for more
+ * information about the decoder, check the decoder state with
+ * FLAC__stream_decoder_get_state().
+ */
+FLAC_API FLAC__bool FLAC__stream_decoder_process_single(FLAC__StreamDecoder *decoder);
+
+/** Decode until the end of the metadata.
+ * This version instructs the decoder to decode from the current position
+ * and continue until all the metadata has been read, or until the
+ * callbacks return a fatal error or the read callback returns
+ * \c FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM.
+ *
+ * As the decoder needs more input it will call the read callback.
+ * As each metadata block is decoded, the metadata callback will be called
+ * with the decoded metadata.
+ *
+ * \param decoder An initialized decoder instance.
+ * \assert
+ * \code decoder != NULL \endcode
+ * \retval FLAC__bool
+ * \c false if any fatal read, write, or memory allocation error
+ * occurred (meaning decoding must stop), else \c true; for more
+ * information about the decoder, check the decoder state with
+ * FLAC__stream_decoder_get_state().
+ */
+FLAC_API FLAC__bool FLAC__stream_decoder_process_until_end_of_metadata(FLAC__StreamDecoder *decoder);
+
+/** Decode until the end of the stream.
+ * This version instructs the decoder to decode from the current position
+ * and continue until the end of stream (the read callback returns
+ * \c FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM), or until the
+ * callbacks return a fatal error.
+ *
+ * As the decoder needs more input it will call the read callback.
+ * As each metadata block and frame is decoded, the metadata or write
+ * callback will be called with the decoded metadata or frame.
+ *
+ * \param decoder An initialized decoder instance.
+ * \assert
+ * \code decoder != NULL \endcode
+ * \retval FLAC__bool
+ * \c false if any fatal read, write, or memory allocation error
+ * occurred (meaning decoding must stop), else \c true; for more
+ * information about the decoder, check the decoder state with
+ * FLAC__stream_decoder_get_state().
+ */
+FLAC_API FLAC__bool FLAC__stream_decoder_process_until_end_of_stream(FLAC__StreamDecoder *decoder);
+
+/** Skip one audio frame.
+ * This version instructs the decoder to 'skip' a single frame and stop,
+ * unless the callbacks return a fatal error or the read callback returns
+ * \c FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM.
+ *
+ * The decoding flow is the same as what occurs when
+ * FLAC__stream_decoder_process_single() is called to process an audio
+ * frame, except that this function does not decode the parsed data into
+ * PCM or call the write callback. The integrity of the frame is still
+ * checked the same way as in the other process functions.
+ *
+ * This function will return once one whole frame is skipped, in the
+ * same way that FLAC__stream_decoder_process_single() will return once
+ * one whole frame is decoded.
+ *
+ * This function can be used in more quickly determining FLAC frame
+ * boundaries when decoding of the actual data is not needed, for
+ * example when an application is separating a FLAC stream into frames
+ * for editing or storing in a container. To do this, the application
+ * can use FLAC__stream_decoder_skip_single_frame() to quickly advance
+ * to the next frame, then use
+ * FLAC__stream_decoder_get_decode_position() to find the new frame
+ * boundary.
+ *
+ * This function should only be called when the stream has advanced
+ * past all the metadata, otherwise it will return \c false.
+ *
+ * \param decoder An initialized decoder instance not in a metadata
+ * state.
+ * \assert
+ * \code decoder != NULL \endcode
+ * \retval FLAC__bool
+ * \c false if any fatal read, write, or memory allocation error
+ * occurred (meaning decoding must stop), or if the decoder
+ * is in the FLAC__STREAM_DECODER_SEARCH_FOR_METADATA or
+ * FLAC__STREAM_DECODER_READ_METADATA state, else \c true; for more
+ * information about the decoder, check the decoder state with
+ * FLAC__stream_decoder_get_state().
+ */
+FLAC_API FLAC__bool FLAC__stream_decoder_skip_single_frame(FLAC__StreamDecoder *decoder);
+
+/** Flush the input and seek to an absolute sample.
+ * Decoding will resume at the given sample. Note that because of
+ * this, the next write callback may contain a partial block. The
+ * client must support seeking the input or this function will fail
+ * and return \c false. Furthermore, if the decoder state is
+ * \c FLAC__STREAM_DECODER_SEEK_ERROR, then the decoder must be flushed
+ * with FLAC__stream_decoder_flush() or reset with
+ * FLAC__stream_decoder_reset() before decoding can continue.
+ *
+ * \param decoder A decoder instance.
+ * \param sample The target sample number to seek to.
+ * \assert
+ * \code decoder != NULL \endcode
+ * \retval FLAC__bool
+ * \c true if successful, else \c false.
+ */
+FLAC_API FLAC__bool FLAC__stream_decoder_seek_absolute(FLAC__StreamDecoder *decoder, FLAC__uint64 sample);
+
+/* \} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib-x86-32/include/FLAC/stream_encoder.h b/lib-x86-32/include/FLAC/stream_encoder.h
new file mode 100644
index 00000000..dbbbb23e
--- /dev/null
+++ b/lib-x86-32/include/FLAC/stream_encoder.h
@@ -0,0 +1,1768 @@
+/* libFLAC - Free Lossless Audio Codec library
+ * Copyright (C) 2000,2001,2002,2003,2004,2005,2006,2007 Josh Coalson
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of the Xiph.org Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef FLAC__STREAM_ENCODER_H
+#define FLAC__STREAM_ENCODER_H
+
+#include <stdio.h> /* for FILE */
+#include "export.h"
+#include "format.h"
+#include "stream_decoder.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/** \file include/FLAC/stream_encoder.h
+ *
+ * \brief
+ * This module contains the functions which implement the stream
+ * encoder.
+ *
+ * See the detailed documentation in the
+ * \link flac_stream_encoder stream encoder \endlink module.
+ */
+
+/** \defgroup flac_encoder FLAC/ \*_encoder.h: encoder interfaces
+ * \ingroup flac
+ *
+ * \brief
+ * This module describes the encoder layers provided by libFLAC.
+ *
+ * The stream encoder can be used to encode complete streams either to the
+ * client via callbacks, or directly to a file, depending on how it is
+ * initialized. When encoding via callbacks, the client provides a write
+ * callback which will be called whenever FLAC data is ready to be written.
+ * If the client also supplies a seek callback, the encoder will also
+ * automatically handle the writing back of metadata discovered while
+ * encoding, like stream info, seek points offsets, etc. When encoding to
+ * a file, the client needs only supply a filename or open \c FILE* and an
+ * optional progress callback for periodic notification of progress; the
+ * write and seek callbacks are supplied internally. For more info see the
+ * \link flac_stream_encoder stream encoder \endlink module.
+ */
+
+/** \defgroup flac_stream_encoder FLAC/stream_encoder.h: stream encoder interface
+ * \ingroup flac_encoder
+ *
+ * \brief
+ * This module contains the functions which implement the stream
+ * encoder.
+ *
+ * The stream encoder can encode to native FLAC, and optionally Ogg FLAC
+ * (check FLAC_API_SUPPORTS_OGG_FLAC) streams and files.
+ *
+ * The basic usage of this encoder is as follows:
+ * - The program creates an instance of an encoder using
+ * FLAC__stream_encoder_new().
+ * - The program overrides the default settings using
+ * FLAC__stream_encoder_set_*() functions. At a minimum, the following
+ * functions should be called:
+ * - FLAC__stream_encoder_set_channels()
+ * - FLAC__stream_encoder_set_bits_per_sample()
+ * - FLAC__stream_encoder_set_sample_rate()
+ * - FLAC__stream_encoder_set_ogg_serial_number() (if encoding to Ogg FLAC)
+ * - FLAC__stream_encoder_set_total_samples_estimate() (if known)
+ * - If the application wants to control the compression level or set its own
+ * metadata, then the following should also be called:
+ * - FLAC__stream_encoder_set_compression_level()
+ * - FLAC__stream_encoder_set_verify()
+ * - FLAC__stream_encoder_set_metadata()
+ * - The rest of the set functions should only be called if the client needs
+ * exact control over how the audio is compressed; thorough understanding
+ * of the FLAC format is necessary to achieve good results.
+ * - The program initializes the instance to validate the settings and
+ * prepare for encoding using
+ * - FLAC__stream_encoder_init_stream() or FLAC__stream_encoder_init_FILE()
+ * or FLAC__stream_encoder_init_file() for native FLAC
+ * - FLAC__stream_encoder_init_ogg_stream() or FLAC__stream_encoder_init_ogg_FILE()
+ * or FLAC__stream_encoder_init_ogg_file() for Ogg FLAC
+ * - The program calls FLAC__stream_encoder_process() or
+ * FLAC__stream_encoder_process_interleaved() to encode data, which
+ * subsequently calls the callbacks when there is encoder data ready
+ * to be written.
+ * - The program finishes the encoding with FLAC__stream_encoder_finish(),
+ * which causes the encoder to encode any data still in its input pipe,
+ * update the metadata with the final encoding statistics if output
+ * seeking is possible, and finally reset the encoder to the
+ * uninitialized state.
+ * - The instance may be used again or deleted with
+ * FLAC__stream_encoder_delete().
+ *
+ * In more detail, the stream encoder functions similarly to the
+ * \link flac_stream_decoder stream decoder \endlink, but has fewer
+ * callbacks and more options. Typically the client will create a new
+ * instance by calling FLAC__stream_encoder_new(), then set the necessary
+ * parameters with FLAC__stream_encoder_set_*(), and initialize it by
+ * calling one of the FLAC__stream_encoder_init_*() functions.
+ *
+ * Unlike the decoders, the stream encoder has many options that can
+ * affect the speed and compression ratio. When setting these parameters
+ * you should have some basic knowledge of the format (see the
+ * <A HREF="../documentation.html#format">user-level documentation</A>
+ * or the <A HREF="../format.html">formal description</A>). The
+ * FLAC__stream_encoder_set_*() functions themselves do not validate the
+ * values as many are interdependent. The FLAC__stream_encoder_init_*()
+ * functions will do this, so make sure to pay attention to the state
+ * returned by FLAC__stream_encoder_init_*() to make sure that it is
+ * FLAC__STREAM_ENCODER_INIT_STATUS_OK. Any parameters that are not set
+ * before FLAC__stream_encoder_init_*() will take on the defaults from
+ * the constructor.
+ *
+ * There are three initialization functions for native FLAC, one for
+ * setting up the encoder to encode FLAC data to the client via
+ * callbacks, and two for encoding directly to a file.
+ *
+ * For encoding via callbacks, use FLAC__stream_encoder_init_stream().
+ * You must also supply a write callback which will be called anytime
+ * there is raw encoded data to write. If the client can seek the output
+ * it is best to also supply seek and tell callbacks, as this allows the
+ * encoder to go back after encoding is finished to write back
+ * information that was collected while encoding, like seek point offsets,
+ * frame sizes, etc.
+ *
+ * For encoding directly to a file, use FLAC__stream_encoder_init_FILE()
+ * or FLAC__stream_encoder_init_file(). Then you must only supply a
+ * filename or open \c FILE*; the encoder will handle all the callbacks
+ * internally. You may also supply a progress callback for periodic
+ * notification of the encoding progress.
+ *
+ * There are three similarly-named init functions for encoding to Ogg
+ * FLAC streams. Check \c FLAC_API_SUPPORTS_OGG_FLAC to find out if the
+ * library has been built with Ogg support.
+ *
+ * The call to FLAC__stream_encoder_init_*() currently will also immediately
+ * call the write callback several times, once with the \c fLaC signature,
+ * and once for each encoded metadata block. Note that for Ogg FLAC
+ * encoding you will usually get at least twice the number of callbacks than
+ * with native FLAC, one for the Ogg page header and one for the page body.
+ *
+ * After initializing the instance, the client may feed audio data to the
+ * encoder in one of two ways:
+ *
+ * - Channel separate, through FLAC__stream_encoder_process() - The client
+ * will pass an array of pointers to buffers, one for each channel, to
+ * the encoder, each of the same length. The samples need not be
+ * block-aligned, but each channel should have the same number of samples.
+ * - Channel interleaved, through
+ * FLAC__stream_encoder_process_interleaved() - The client will pass a single
+ * pointer to data that is channel-interleaved (i.e. channel0_sample0,
+ * channel1_sample0, ... , channelN_sample0, channel0_sample1, ...).
+ * Again, the samples need not be block-aligned but they must be
+ * sample-aligned, i.e. the first value should be channel0_sample0 and
+ * the last value channelN_sampleM.
+ *
+ * Note that for either process call, each sample in the buffers should be a
+ * signed integer, right-justified to the resolution set by
+ * FLAC__stream_encoder_set_bits_per_sample(). For example, if the resolution
+ * is 16 bits per sample, the samples should all be in the range [-32768,32767].
+ *
+ * When the client is finished encoding data, it calls
+ * FLAC__stream_encoder_finish(), which causes the encoder to encode any
+ * data still in its input pipe, and call the metadata callback with the
+ * final encoding statistics. Then the instance may be deleted with
+ * FLAC__stream_encoder_delete() or initialized again to encode another
+ * stream.
+ *
+ * For programs that write their own metadata, but that do not know the
+ * actual metadata until after encoding, it is advantageous to instruct
+ * the encoder to write a PADDING block of the correct size, so that
+ * instead of rewriting the whole stream after encoding, the program can
+ * just overwrite the PADDING block. If only the maximum size of the
+ * metadata is known, the program can write a slightly larger padding
+ * block, then split it after encoding.
+ *
+ * Make sure you understand how lengths are calculated. All FLAC metadata
+ * blocks have a 4 byte header which contains the type and length. This
+ * length does not include the 4 bytes of the header. See the format page
+ * for the specification of metadata blocks and their lengths.
+ *
+ * \note
+ * If you are writing the FLAC data to a file via callbacks, make sure it
+ * is open for update (e.g. mode "w+" for stdio streams). This is because
+ * after the first encoding pass, the encoder will try to seek back to the
+ * beginning of the stream, to the STREAMINFO block, to write some data
+ * there. (If using FLAC__stream_encoder_init*_file() or
+ * FLAC__stream_encoder_init*_FILE(), the file is managed internally.)
+ *
+ * \note
+ * The "set" functions may only be called when the encoder is in the
+ * state FLAC__STREAM_ENCODER_UNINITIALIZED, i.e. after
+ * FLAC__stream_encoder_new() or FLAC__stream_encoder_finish(), but
+ * before FLAC__stream_encoder_init_*(). If this is the case they will
+ * return \c true, otherwise \c false.
+ *
+ * \note
+ * FLAC__stream_encoder_finish() resets all settings to the constructor
+ * defaults.
+ *
+ * \{
+ */
+
+
+/** State values for a FLAC__StreamEncoder.
+ *
+ * The encoder's state can be obtained by calling FLAC__stream_encoder_get_state().
+ *
+ * If the encoder gets into any other state besides \c FLAC__STREAM_ENCODER_OK
+ * or \c FLAC__STREAM_ENCODER_UNINITIALIZED, it becomes invalid for encoding and
+ * must be deleted with FLAC__stream_encoder_delete().
+ */
+typedef enum {
+
+ FLAC__STREAM_ENCODER_OK = 0,
+ /**< The encoder is in the normal OK state and samples can be processed. */
+
+ FLAC__STREAM_ENCODER_UNINITIALIZED,
+ /**< The encoder is in the uninitialized state; one of the
+ * FLAC__stream_encoder_init_*() functions must be called before samples
+ * can be processed.
+ */
+
+ FLAC__STREAM_ENCODER_OGG_ERROR,
+ /**< An error occurred in the underlying Ogg layer. */
+
+ FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR,
+ /**< An error occurred in the underlying verify stream decoder;
+ * check FLAC__stream_encoder_get_verify_decoder_state().
+ */
+
+ FLAC__STREAM_ENCODER_VERIFY_MISMATCH_IN_AUDIO_DATA,
+ /**< The verify decoder detected a mismatch between the original
+ * audio signal and the decoded audio signal.
+ */
+
+ FLAC__STREAM_ENCODER_CLIENT_ERROR,
+ /**< One of the callbacks returned a fatal error. */
+
+ FLAC__STREAM_ENCODER_IO_ERROR,
+ /**< An I/O error occurred while opening/reading/writing a file.
+ * Check \c errno.
+ */
+
+ FLAC__STREAM_ENCODER_FRAMING_ERROR,
+ /**< An error occurred while writing the stream; usually, the
+ * write_callback returned an error.
+ */
+
+ FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR
+ /**< Memory allocation failed. */
+
+} FLAC__StreamEncoderState;
+
+/** Maps a FLAC__StreamEncoderState to a C string.
+ *
+ * Using a FLAC__StreamEncoderState as the index to this array
+ * will give the string equivalent. The contents should not be modified.
+ */
+extern FLAC_API const char * const FLAC__StreamEncoderStateString[];
+
+
+/** Possible return values for the FLAC__stream_encoder_init_*() functions.
+ */
+typedef enum {
+
+ FLAC__STREAM_ENCODER_INIT_STATUS_OK = 0,
+ /**< Initialization was successful. */
+
+ FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR,
+ /**< General failure to set up encoder; call FLAC__stream_encoder_get_state() for cause. */
+
+ FLAC__STREAM_ENCODER_INIT_STATUS_UNSUPPORTED_CONTAINER,
+ /**< The library was not compiled with support for the given container
+ * format.
+ */
+
+ FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_CALLBACKS,
+ /**< A required callback was not supplied. */
+
+ FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_NUMBER_OF_CHANNELS,
+ /**< The encoder has an invalid setting for number of channels. */
+
+ FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_BITS_PER_SAMPLE,
+ /**< The encoder has an invalid setting for bits-per-sample.
+ * FLAC supports 4-32 bps but the reference encoder currently supports
+ * only up to 24 bps.
+ */
+
+ FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_SAMPLE_RATE,
+ /**< The encoder has an invalid setting for the input sample rate. */
+
+ FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_BLOCK_SIZE,
+ /**< The encoder has an invalid setting for the block size. */
+
+ FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_MAX_LPC_ORDER,
+ /**< The encoder has an invalid setting for the maximum LPC order. */
+
+ FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_QLP_COEFF_PRECISION,
+ /**< The encoder has an invalid setting for the precision of the quantized linear predictor coefficients. */
+
+ FLAC__STREAM_ENCODER_INIT_STATUS_BLOCK_SIZE_TOO_SMALL_FOR_LPC_ORDER,
+ /**< The specified block size is less than the maximum LPC order. */
+
+ FLAC__STREAM_ENCODER_INIT_STATUS_NOT_STREAMABLE,
+ /**< The encoder is bound to the <A HREF="../format.html#subset">Subset</A> but other settings violate it. */
+
+ FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_METADATA,
+ /**< The metadata input to the encoder is invalid, in one of the following ways:
+ * - FLAC__stream_encoder_set_metadata() was called with a null pointer but a block count > 0
+ * - One of the metadata blocks contains an undefined type
+ * - It contains an illegal CUESHEET as checked by FLAC__format_cuesheet_is_legal()
+ * - It contains an illegal SEEKTABLE as checked by FLAC__format_seektable_is_legal()
+ * - It contains more than one SEEKTABLE block or more than one VORBIS_COMMENT block
+ */
+
+ FLAC__STREAM_ENCODER_INIT_STATUS_ALREADY_INITIALIZED
+ /**< FLAC__stream_encoder_init_*() was called when the encoder was
+ * already initialized, usually because
+ * FLAC__stream_encoder_finish() was not called.
+ */
+
+} FLAC__StreamEncoderInitStatus;
+
+/** Maps a FLAC__StreamEncoderInitStatus to a C string.
+ *
+ * Using a FLAC__StreamEncoderInitStatus as the index to this array
+ * will give the string equivalent. The contents should not be modified.
+ */
+extern FLAC_API const char * const FLAC__StreamEncoderInitStatusString[];
+
+
+/** Return values for the FLAC__StreamEncoder read callback.
+ */
+typedef enum {
+
+ FLAC__STREAM_ENCODER_READ_STATUS_CONTINUE,
+ /**< The read was OK and decoding can continue. */
+
+ FLAC__STREAM_ENCODER_READ_STATUS_END_OF_STREAM,
+ /**< The read was attempted at the end of the stream. */
+
+ FLAC__STREAM_ENCODER_READ_STATUS_ABORT,
+ /**< An unrecoverable error occurred. */
+
+ FLAC__STREAM_ENCODER_READ_STATUS_UNSUPPORTED
+ /**< Client does not support reading back from the output. */
+
+} FLAC__StreamEncoderReadStatus;
+
+/** Maps a FLAC__StreamEncoderReadStatus to a C string.
+ *
+ * Using a FLAC__StreamEncoderReadStatus as the index to this array
+ * will give the string equivalent. The contents should not be modified.
+ */
+extern FLAC_API const char * const FLAC__StreamEncoderReadStatusString[];
+
+
+/** Return values for the FLAC__StreamEncoder write callback.
+ */
+typedef enum {
+
+ FLAC__STREAM_ENCODER_WRITE_STATUS_OK = 0,
+ /**< The write was OK and encoding can continue. */
+
+ FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR
+ /**< An unrecoverable error occurred. The encoder will return from the process call. */
+
+} FLAC__StreamEncoderWriteStatus;
+
+/** Maps a FLAC__StreamEncoderWriteStatus to a C string.
+ *
+ * Using a FLAC__StreamEncoderWriteStatus as the index to this array
+ * will give the string equivalent. The contents should not be modified.
+ */
+extern FLAC_API const char * const FLAC__StreamEncoderWriteStatusString[];
+
+
+/** Return values for the FLAC__StreamEncoder seek callback.
+ */
+typedef enum {
+
+ FLAC__STREAM_ENCODER_SEEK_STATUS_OK,
+ /**< The seek was OK and encoding can continue. */
+
+ FLAC__STREAM_ENCODER_SEEK_STATUS_ERROR,
+ /**< An unrecoverable error occurred. */
+
+ FLAC__STREAM_ENCODER_SEEK_STATUS_UNSUPPORTED
+ /**< Client does not support seeking. */
+
+} FLAC__StreamEncoderSeekStatus;
+
+/** Maps a FLAC__StreamEncoderSeekStatus to a C string.
+ *
+ * Using a FLAC__StreamEncoderSeekStatus as the index to this array
+ * will give the string equivalent. The contents should not be modified.
+ */
+extern FLAC_API const char * const FLAC__StreamEncoderSeekStatusString[];
+
+
+/** Return values for the FLAC__StreamEncoder tell callback.
+ */
+typedef enum {
+
+ FLAC__STREAM_ENCODER_TELL_STATUS_OK,
+ /**< The tell was OK and encoding can continue. */
+
+ FLAC__STREAM_ENCODER_TELL_STATUS_ERROR,
+ /**< An unrecoverable error occurred. */
+
+ FLAC__STREAM_ENCODER_TELL_STATUS_UNSUPPORTED
+ /**< Client does not support seeking. */
+
+} FLAC__StreamEncoderTellStatus;
+
+/** Maps a FLAC__StreamEncoderTellStatus to a C string.
+ *
+ * Using a FLAC__StreamEncoderTellStatus as the index to this array
+ * will give the string equivalent. The contents should not be modified.
+ */
+extern FLAC_API const char * const FLAC__StreamEncoderTellStatusString[];
+
+
+/***********************************************************************
+ *
+ * class FLAC__StreamEncoder
+ *
+ ***********************************************************************/
+
+struct FLAC__StreamEncoderProtected;
+struct FLAC__StreamEncoderPrivate;
+/** The opaque structure definition for the stream encoder type.
+ * See the \link flac_stream_encoder stream encoder module \endlink
+ * for a detailed description.
+ */
+typedef struct {
+ struct FLAC__StreamEncoderProtected *protected_; /* avoid the C++ keyword 'protected' */
+ struct FLAC__StreamEncoderPrivate *private_; /* avoid the C++ keyword 'private' */
+} FLAC__StreamEncoder;
+
+/** Signature for the read callback.
+ *
+ * A function pointer matching this signature must be passed to
+ * FLAC__stream_encoder_init_ogg_stream() if seeking is supported.
+ * The supplied function will be called when the encoder needs to read back
+ * encoded data. This happens during the metadata callback, when the encoder
+ * has to read, modify, and rewrite the metadata (e.g. seekpoints) gathered
+ * while encoding. The address of the buffer to be filled is supplied, along
+ * with the number of bytes the buffer can hold. The callback may choose to
+ * supply less data and modify the byte count but must be careful not to
+ * overflow the buffer. The callback then returns a status code chosen from
+ * FLAC__StreamEncoderReadStatus.
+ *
+ * Here is an example of a read callback for stdio streams:
+ * \code
+ * FLAC__StreamEncoderReadStatus read_cb(const FLAC__StreamEncoder *encoder, FLAC__byte buffer[], size_t *bytes, void *client_data)
+ * {
+ * FILE *file = ((MyClientData*)client_data)->file;
+ * if(*bytes > 0) {
+ * *bytes = fread(buffer, sizeof(FLAC__byte), *bytes, file);
+ * if(ferror(file))
+ * return FLAC__STREAM_ENCODER_READ_STATUS_ABORT;
+ * else if(*bytes == 0)
+ * return FLAC__STREAM_ENCODER_READ_STATUS_END_OF_STREAM;
+ * else
+ * return FLAC__STREAM_ENCODER_READ_STATUS_CONTINUE;
+ * }
+ * else
+ * return FLAC__STREAM_ENCODER_READ_STATUS_ABORT;
+ * }
+ * \endcode
+ *
+ * \note In general, FLAC__StreamEncoder functions which change the
+ * state should not be called on the \a encoder while in the callback.
+ *
+ * \param encoder The encoder instance calling the callback.
+ * \param buffer A pointer to a location for the callee to store
+ * data to be encoded.
+ * \param bytes A pointer to the size of the buffer. On entry
+ * to the callback, it contains the maximum number
+ * of bytes that may be stored in \a buffer. The
+ * callee must set it to the actual number of bytes
+ * stored (0 in case of error or end-of-stream) before
+ * returning.
+ * \param client_data The callee's client data set through
+ * FLAC__stream_encoder_set_client_data().
+ * \retval FLAC__StreamEncoderReadStatus
+ * The callee's return status.
+ */
+typedef FLAC__StreamEncoderReadStatus (*FLAC__StreamEncoderReadCallback)(const FLAC__StreamEncoder *encoder, FLAC__byte buffer[], size_t *bytes, void *client_data);
+
+/** Signature for the write callback.
+ *
+ * A function pointer matching this signature must be passed to
+ * FLAC__stream_encoder_init*_stream(). The supplied function will be called
+ * by the encoder anytime there is raw encoded data ready to write. It may
+ * include metadata mixed with encoded audio frames and the data is not
+ * guaranteed to be aligned on frame or metadata block boundaries.
+ *
+ * The only duty of the callback is to write out the \a bytes worth of data
+ * in \a buffer to the current position in the output stream. The arguments
+ * \a samples and \a current_frame are purely informational. If \a samples
+ * is greater than \c 0, then \a current_frame will hold the current frame
+ * number that is being written; otherwise it indicates that the write
+ * callback is being called to write metadata.
+ *
+ * \note
+ * Unlike when writing to native FLAC, when writing to Ogg FLAC the
+ * write callback will be called twice when writing each audio
+ * frame; once for the page header, and once for the page body.
+ * When writing the page header, the \a samples argument to the
+ * write callback will be \c 0.
+ *
+ * \note In general, FLAC__StreamEncoder functions which change the
+ * state should not be called on the \a encoder while in the callback.
+ *
+ * \param encoder The encoder instance calling the callback.
+ * \param buffer An array of encoded data of length \a bytes.
+ * \param bytes The byte length of \a buffer.
+ * \param samples The number of samples encoded by \a buffer.
+ * \c 0 has a special meaning; see above.
+ * \param current_frame The number of the current frame being encoded.
+ * \param client_data The callee's client data set through
+ * FLAC__stream_encoder_init_*().
+ * \retval FLAC__StreamEncoderWriteStatus
+ * The callee's return status.
+ */
+typedef FLAC__StreamEncoderWriteStatus (*FLAC__StreamEncoderWriteCallback)(const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], size_t bytes, unsigned samples, unsigned current_frame, void *client_data);
+
+/** Signature for the seek callback.
+ *
+ * A function pointer matching this signature may be passed to
+ * FLAC__stream_encoder_init*_stream(). The supplied function will be called
+ * when the encoder needs to seek the output stream. The encoder will pass
+ * the absolute byte offset to seek to, 0 meaning the beginning of the stream.
+ *
+ * Here is an example of a seek callback for stdio streams:
+ * \code
+ * FLAC__StreamEncoderSeekStatus seek_cb(const FLAC__StreamEncoder *encoder, FLAC__uint64 absolute_byte_offset, void *client_data)
+ * {
+ * FILE *file = ((MyClientData*)client_data)->file;
+ * if(file == stdin)
+ * return FLAC__STREAM_ENCODER_SEEK_STATUS_UNSUPPORTED;
+ * else if(fseeko(file, (off_t)absolute_byte_offset, SEEK_SET) < 0)
+ * return FLAC__STREAM_ENCODER_SEEK_STATUS_ERROR;
+ * else
+ * return FLAC__STREAM_ENCODER_SEEK_STATUS_OK;
+ * }
+ * \endcode
+ *
+ * \note In general, FLAC__StreamEncoder functions which change the
+ * state should not be called on the \a encoder while in the callback.
+ *
+ * \param encoder The encoder instance calling the callback.
+ * \param absolute_byte_offset The offset from the beginning of the stream
+ * to seek to.
+ * \param client_data The callee's client data set through
+ * FLAC__stream_encoder_init_*().
+ * \retval FLAC__StreamEncoderSeekStatus
+ * The callee's return status.
+ */
+typedef FLAC__StreamEncoderSeekStatus (*FLAC__StreamEncoderSeekCallback)(const FLAC__StreamEncoder *encoder, FLAC__uint64 absolute_byte_offset, void *client_data);
+
+/** Signature for the tell callback.
+ *
+ * A function pointer matching this signature may be passed to
+ * FLAC__stream_encoder_init*_stream(). The supplied function will be called
+ * when the encoder needs to know the current position of the output stream.
+ *
+ * \warning
+ * The callback must return the true current byte offset of the output to
+ * which the encoder is writing. If you are buffering the output, make
+ * sure and take this into account. If you are writing directly to a
+ * FILE* from your write callback, ftell() is sufficient. If you are
+ * writing directly to a file descriptor from your write callback, you
+ * can use lseek(fd, SEEK_CUR, 0). The encoder may later seek back to
+ * these points to rewrite metadata after encoding.
+ *
+ * Here is an example of a tell callback for stdio streams:
+ * \code
+ * FLAC__StreamEncoderTellStatus tell_cb(const FLAC__StreamEncoder *encoder, FLAC__uint64 *absolute_byte_offset, void *client_data)
+ * {
+ * FILE *file = ((MyClientData*)client_data)->file;
+ * off_t pos;
+ * if(file == stdin)
+ * return FLAC__STREAM_ENCODER_TELL_STATUS_UNSUPPORTED;
+ * else if((pos = ftello(file)) < 0)
+ * return FLAC__STREAM_ENCODER_TELL_STATUS_ERROR;
+ * else {
+ * *absolute_byte_offset = (FLAC__uint64)pos;
+ * return FLAC__STREAM_ENCODER_TELL_STATUS_OK;
+ * }
+ * }
+ * \endcode
+ *
+ * \note In general, FLAC__StreamEncoder functions which change the
+ * state should not be called on the \a encoder while in the callback.
+ *
+ * \param encoder The encoder instance calling the callback.
+ * \param absolute_byte_offset The address at which to store the current
+ * position of the output.
+ * \param client_data The callee's client data set through
+ * FLAC__stream_encoder_init_*().
+ * \retval FLAC__StreamEncoderTellStatus
+ * The callee's return status.
+ */
+typedef FLAC__StreamEncoderTellStatus (*FLAC__StreamEncoderTellCallback)(const FLAC__StreamEncoder *encoder, FLAC__uint64 *absolute_byte_offset, void *client_data);
+
+/** Signature for the metadata callback.
+ *
+ * A function pointer matching this signature may be passed to
+ * FLAC__stream_encoder_init*_stream(). The supplied function will be called
+ * once at the end of encoding with the populated STREAMINFO structure. This
+ * is so the client can seek back to the beginning of the file and write the
+ * STREAMINFO block with the correct statistics after encoding (like
+ * minimum/maximum frame size and total samples).
+ *
+ * \note In general, FLAC__StreamEncoder functions which change the
+ * state should not be called on the \a encoder while in the callback.
+ *
+ * \param encoder The encoder instance calling the callback.
+ * \param metadata The final populated STREAMINFO block.
+ * \param client_data The callee's client data set through
+ * FLAC__stream_encoder_init_*().
+ */
+typedef void (*FLAC__StreamEncoderMetadataCallback)(const FLAC__StreamEncoder *encoder, const FLAC__StreamMetadata *metadata, void *client_data);
+
+/** Signature for the progress callback.
+ *
+ * A function pointer matching this signature may be passed to
+ * FLAC__stream_encoder_init*_file() or FLAC__stream_encoder_init*_FILE().
+ * The supplied function will be called when the encoder has finished
+ * writing a frame. The \c total_frames_estimate argument to the
+ * callback will be based on the value from
+ * FLAC__stream_encoder_set_total_samples_estimate().
+ *
+ * \note In general, FLAC__StreamEncoder functions which change the
+ * state should not be called on the \a encoder while in the callback.
+ *
+ * \param encoder The encoder instance calling the callback.
+ * \param bytes_written Bytes written so far.
+ * \param samples_written Samples written so far.
+ * \param frames_written Frames written so far.
+ * \param total_frames_estimate The estimate of the total number of
+ * frames to be written.
+ * \param client_data The callee's client data set through
+ * FLAC__stream_encoder_init_*().
+ */
+typedef void (*FLAC__StreamEncoderProgressCallback)(const FLAC__StreamEncoder *encoder, FLAC__uint64 bytes_written, FLAC__uint64 samples_written, unsigned frames_written, unsigned total_frames_estimate, void *client_data);
+
+
+/***********************************************************************
+ *
+ * Class constructor/destructor
+ *
+ ***********************************************************************/
+
+/** Create a new stream encoder instance. The instance is created with
+ * default settings; see the individual FLAC__stream_encoder_set_*()
+ * functions for each setting's default.
+ *
+ * \retval FLAC__StreamEncoder*
+ * \c NULL if there was an error allocating memory, else the new instance.
+ */
+FLAC_API FLAC__StreamEncoder *FLAC__stream_encoder_new(void);
+
+/** Free an encoder instance. Deletes the object pointed to by \a encoder.
+ *
+ * \param encoder A pointer to an existing encoder.
+ * \assert
+ * \code encoder != NULL \endcode
+ */
+FLAC_API void FLAC__stream_encoder_delete(FLAC__StreamEncoder *encoder);
+
+
+/***********************************************************************
+ *
+ * Public class method prototypes
+ *
+ ***********************************************************************/
+
+/** Set the serial number for the FLAC stream to use in the Ogg container.
+ *
+ * \note
+ * This does not need to be set for native FLAC encoding.
+ *
+ * \note
+ * It is recommended to set a serial number explicitly as the default of '0'
+ * may collide with other streams.
+ *
+ * \default \c 0
+ * \param encoder An encoder instance to set.
+ * \param serial_number See above.
+ * \assert
+ * \code encoder != NULL \endcode
+ * \retval FLAC__bool
+ * \c false if the encoder is already initialized, else \c true.
+ */
+FLAC_API FLAC__bool FLAC__stream_encoder_set_ogg_serial_number(FLAC__StreamEncoder *encoder, long serial_number);
+
+/** Set the "verify" flag. If \c true, the encoder will verify it's own
+ * encoded output by feeding it through an internal decoder and comparing
+ * the original signal against the decoded signal. If a mismatch occurs,
+ * the process call will return \c false. Note that this will slow the
+ * encoding process by the extra time required for decoding and comparison.
+ *
+ * \default \c false
+ * \param encoder An encoder instance to set.
+ * \param value Flag value (see above).
+ * \assert
+ * \code encoder != NULL \endcode
+ * \retval FLAC__bool
+ * \c false if the encoder is already initialized, else \c true.
+ */
+FLAC_API FLAC__bool FLAC__stream_encoder_set_verify(FLAC__StreamEncoder *encoder, FLAC__bool value);
+
+/** Set the <A HREF="../format.html#subset">Subset</A> flag. If \c true,
+ * the encoder will comply with the Subset and will check the
+ * settings during FLAC__stream_encoder_init_*() to see if all settings
+ * comply. If \c false, the settings may take advantage of the full
+ * range that the format allows.
+ *
+ * Make sure you know what it entails before setting this to \c false.
+ *
+ * \default \c true
+ * \param encoder An encoder instance to set.
+ * \param value Flag value (see above).
+ * \assert
+ * \code encoder != NULL \endcode
+ * \retval FLAC__bool
+ * \c false if the encoder is already initialized, else \c true.
+ */
+FLAC_API FLAC__bool FLAC__stream_encoder_set_streamable_subset(FLAC__StreamEncoder *encoder, FLAC__bool value);
+
+/** Set the number of channels to be encoded.
+ *
+ * \default \c 2
+ * \param encoder An encoder instance to set.
+ * \param value See above.
+ * \assert
+ * \code encoder != NULL \endcode
+ * \retval FLAC__bool
+ * \c false if the encoder is already initialized, else \c true.
+ */
+FLAC_API FLAC__bool FLAC__stream_encoder_set_channels(FLAC__StreamEncoder *encoder, unsigned value);
+
+/** Set the sample resolution of the input to be encoded.
+ *
+ * \warning
+ * Do not feed the encoder data that is wider than the value you
+ * set here or you will generate an invalid stream.
+ *
+ * \default \c 16
+ * \param encoder An encoder instance to set.
+ * \param value See above.
+ * \assert
+ * \code encoder != NULL \endcode
+ * \retval FLAC__bool
+ * \c false if the encoder is already initialized, else \c true.
+ */
+FLAC_API FLAC__bool FLAC__stream_encoder_set_bits_per_sample(FLAC__StreamEncoder *encoder, unsigned value);
+
+/** Set the sample rate (in Hz) of the input to be encoded.
+ *
+ * \default \c 44100
+ * \param encoder An encoder instance to set.
+ * \param value See above.
+ * \assert
+ * \code encoder != NULL \endcode
+ * \retval FLAC__bool
+ * \c false if the encoder is already initialized, else \c true.
+ */
+FLAC_API FLAC__bool FLAC__stream_encoder_set_sample_rate(FLAC__StreamEncoder *encoder, unsigned value);
+
+/** Set the compression level
+ *
+ * The compression level is roughly proportional to the amount of effort
+ * the encoder expends to compress the file. A higher level usually
+ * means more computation but higher compression. The default level is
+ * suitable for most applications.
+ *
+ * Currently the levels range from \c 0 (fastest, least compression) to
+ * \c 8 (slowest, most compression). A value larger than \c 8 will be
+ * treated as \c 8.
+ *
+ * This function automatically calls the following other \c _set_
+ * functions with appropriate values, so the client does not need to
+ * unless it specifically wants to override them:
+ * - FLAC__stream_encoder_set_do_mid_side_stereo()
+ * - FLAC__stream_encoder_set_loose_mid_side_stereo()
+ * - FLAC__stream_encoder_set_apodization()
+ * - FLAC__stream_encoder_set_max_lpc_order()
+ * - FLAC__stream_encoder_set_qlp_coeff_precision()
+ * - FLAC__stream_encoder_set_do_qlp_coeff_prec_search()
+ * - FLAC__stream_encoder_set_do_escape_coding()
+ * - FLAC__stream_encoder_set_do_exhaustive_model_search()
+ * - FLAC__stream_encoder_set_min_residual_partition_order()
+ * - FLAC__stream_encoder_set_max_residual_partition_order()
+ * - FLAC__stream_encoder_set_rice_parameter_search_dist()
+ *
+ * The actual values set for each level are:
+ * <table>
+ * <tr>
+ * <td><b>level</b><td>
+ * <td>do mid-side stereo<td>
+ * <td>loose mid-side stereo<td>
+ * <td>apodization<td>
+ * <td>max lpc order<td>
+ * <td>qlp coeff precision<td>
+ * <td>qlp coeff prec search<td>
+ * <td>escape coding<td>
+ * <td>exhaustive model search<td>
+ * <td>min residual partition order<td>
+ * <td>max residual partition order<td>
+ * <td>rice parameter search dist<td>
+ * </tr>
+ * <tr> <td><b>0</b><td> <td>false<td> <td>false<td> <td>tukey(0.5)<td> <td>0<td> <td>0<td> <td>false<td> <td>false<td> <td>false<td> <td>0<td> <td>3<td> <td>0<td> </tr>
+ * <tr> <td><b>1</b><td> <td>true<td> <td>true<td> <td>tukey(0.5)<td> <td>0<td> <td>0<td> <td>false<td> <td>false<td> <td>false<td> <td>0<td> <td>3<td> <td>0<td> </tr>
+ * <tr> <td><b>2</b><td> <td>true<td> <td>false<td> <td>tukey(0.5)<td> <td>0<td> <td>0<td> <td>false<td> <td>false<td> <td>false<td> <td>0<td> <td>3<td> <td>0<td> </tr>
+ * <tr> <td><b>3</b><td> <td>false<td> <td>false<td> <td>tukey(0.5)<td> <td>6<td> <td>0<td> <td>false<td> <td>false<td> <td>false<td> <td>0<td> <td>4<td> <td>0<td> </tr>
+ * <tr> <td><b>4</b><td> <td>true<td> <td>true<td> <td>tukey(0.5)<td> <td>8<td> <td>0<td> <td>false<td> <td>false<td> <td>false<td> <td>0<td> <td>4<td> <td>0<td> </tr>
+ * <tr> <td><b>5</b><td> <td>true<td> <td>false<td> <td>tukey(0.5)<td> <td>8<td> <td>0<td> <td>false<td> <td>false<td> <td>false<td> <td>0<td> <td>5<td> <td>0<td> </tr>
+ * <tr> <td><b>6</b><td> <td>true<td> <td>false<td> <td>tukey(0.5)<td> <td>8<td> <td>0<td> <td>false<td> <td>false<td> <td>false<td> <td>0<td> <td>6<td> <td>0<td> </tr>
+ * <tr> <td><b>7</b><td> <td>true<td> <td>false<td> <td>tukey(0.5)<td> <td>8<td> <td>0<td> <td>false<td> <td>false<td> <td>true<td> <td>0<td> <td>6<td> <td>0<td> </tr>
+ * <tr> <td><b>8</b><td> <td>true<td> <td>false<td> <td>tukey(0.5)<td> <td>12<td> <td>0<td> <td>false<td> <td>false<td> <td>true<td> <td>0<td> <td>6<td> <td>0<td> </tr>
+ * </table>
+ *
+ * \default \c 5
+ * \param encoder An encoder instance to set.
+ * \param value See above.
+ * \assert
+ * \code encoder != NULL \endcode
+ * \retval FLAC__bool
+ * \c false if the encoder is already initialized, else \c true.
+ */
+FLAC_API FLAC__bool FLAC__stream_encoder_set_compression_level(FLAC__StreamEncoder *encoder, unsigned value);
+
+/** Set the blocksize to use while encoding.
+ *
+ * The number of samples to use per frame. Use \c 0 to let the encoder
+ * estimate a blocksize; this is usually best.
+ *
+ * \default \c 0
+ * \param encoder An encoder instance to set.
+ * \param value See above.
+ * \assert
+ * \code encoder != NULL \endcode
+ * \retval FLAC__bool
+ * \c false if the encoder is already initialized, else \c true.
+ */
+FLAC_API FLAC__bool FLAC__stream_encoder_set_blocksize(FLAC__StreamEncoder *encoder, unsigned value);
+
+/** Set to \c true to enable mid-side encoding on stereo input. The
+ * number of channels must be 2 for this to have any effect. Set to
+ * \c false to use only independent channel coding.
+ *
+ * \default \c false
+ * \param encoder An encoder instance to set.
+ * \param value Flag value (see above).
+ * \assert
+ * \code encoder != NULL \endcode
+ * \retval FLAC__bool
+ * \c false if the encoder is already initialized, else \c true.
+ */
+FLAC_API FLAC__bool FLAC__stream_encoder_set_do_mid_side_stereo(FLAC__StreamEncoder *encoder, FLAC__bool value);
+
+/** Set to \c true to enable adaptive switching between mid-side and
+ * left-right encoding on stereo input. Set to \c false to use
+ * exhaustive searching. Setting this to \c true requires
+ * FLAC__stream_encoder_set_do_mid_side_stereo() to also be set to
+ * \c true in order to have any effect.
+ *
+ * \default \c false
+ * \param encoder An encoder instance to set.
+ * \param value Flag value (see above).
+ * \assert
+ * \code encoder != NULL \endcode
+ * \retval FLAC__bool
+ * \c false if the encoder is already initialized, else \c true.
+ */
+FLAC_API FLAC__bool FLAC__stream_encoder_set_loose_mid_side_stereo(FLAC__StreamEncoder *encoder, FLAC__bool value);
+
+/** Sets the apodization function(s) the encoder will use when windowing
+ * audio data for LPC analysis.
+ *
+ * The \a specification is a plain ASCII string which specifies exactly
+ * which functions to use. There may be more than one (up to 32),
+ * separated by \c ';' characters. Some functions take one or more
+ * comma-separated arguments in parentheses.
+ *
+ * The available functions are \c bartlett, \c bartlett_hann,
+ * \c blackman, \c blackman_harris_4term_92db, \c connes, \c flattop,
+ * \c gauss(STDDEV), \c hamming, \c hann, \c kaiser_bessel, \c nuttall,
+ * \c rectangle, \c triangle, \c tukey(P), \c welch.
+ *
+ * For \c gauss(STDDEV), STDDEV specifies the standard deviation
+ * (0<STDDEV<=0.5).
+ *
+ * For \c tukey(P), P specifies the fraction of the window that is
+ * tapered (0<=P<=1). P=0 corresponds to \c rectangle and P=1
+ * corresponds to \c hann.
+ *
+ * Example specifications are \c "blackman" or
+ * \c "hann;triangle;tukey(0.5);tukey(0.25);tukey(0.125)"
+ *
+ * Any function that is specified erroneously is silently dropped. Up
+ * to 32 functions are kept, the rest are dropped. If the specification
+ * is empty the encoder defaults to \c "tukey(0.5)".
+ *
+ * When more than one function is specified, then for every subframe the
+ * encoder will try each of them separately and choose the window that
+ * results in the smallest compressed subframe.
+ *
+ * Note that each function specified causes the encoder to occupy a
+ * floating point array in which to store the window.
+ *
+ * \default \c "tukey(0.5)"
+ * \param encoder An encoder instance to set.
+ * \param specification See above.
+ * \assert
+ * \code encoder != NULL \endcode
+ * \code specification != NULL \endcode
+ * \retval FLAC__bool
+ * \c false if the encoder is already initialized, else \c true.
+ */
+FLAC_API FLAC__bool FLAC__stream_encoder_set_apodization(FLAC__StreamEncoder *encoder, const char *specification);
+
+/** Set the maximum LPC order, or \c 0 to use only the fixed predictors.
+ *
+ * \default \c 0
+ * \param encoder An encoder instance to set.
+ * \param value See above.
+ * \assert
+ * \code encoder != NULL \endcode
+ * \retval FLAC__bool
+ * \c false if the encoder is already initialized, else \c true.
+ */
+FLAC_API FLAC__bool FLAC__stream_encoder_set_max_lpc_order(FLAC__StreamEncoder *encoder, unsigned value);
+
+/** Set the precision, in bits, of the quantized linear predictor
+ * coefficients, or \c 0 to let the encoder select it based on the
+ * blocksize.
+ *
+ * \note
+ * In the current implementation, qlp_coeff_precision + bits_per_sample must
+ * be less than 32.
+ *
+ * \default \c 0
+ * \param encoder An encoder instance to set.
+ * \param value See above.
+ * \assert
+ * \code encoder != NULL \endcode
+ * \retval FLAC__bool
+ * \c false if the encoder is already initialized, else \c true.
+ */
+FLAC_API FLAC__bool FLAC__stream_encoder_set_qlp_coeff_precision(FLAC__StreamEncoder *encoder, unsigned value);
+
+/** Set to \c false to use only the specified quantized linear predictor
+ * coefficient precision, or \c true to search neighboring precision
+ * values and use the best one.
+ *
+ * \default \c false
+ * \param encoder An encoder instance to set.
+ * \param value See above.
+ * \assert
+ * \code encoder != NULL \endcode
+ * \retval FLAC__bool
+ * \c false if the encoder is already initialized, else \c true.
+ */
+FLAC_API FLAC__bool FLAC__stream_encoder_set_do_qlp_coeff_prec_search(FLAC__StreamEncoder *encoder, FLAC__bool value);
+
+/** Deprecated. Setting this value has no effect.
+ *
+ * \default \c false
+ * \param encoder An encoder instance to set.
+ * \param value See above.
+ * \assert
+ * \code encoder != NULL \endcode
+ * \retval FLAC__bool
+ * \c false if the encoder is already initialized, else \c true.
+ */
+FLAC_API FLAC__bool FLAC__stream_encoder_set_do_escape_coding(FLAC__StreamEncoder *encoder, FLAC__bool value);
+
+/** Set to \c false to let the encoder estimate the best model order
+ * based on the residual signal energy, or \c true to force the
+ * encoder to evaluate all order models and select the best.
+ *
+ * \default \c false
+ * \param encoder An encoder instance to set.
+ * \param value See above.
+ * \assert
+ * \code encoder != NULL \endcode
+ * \retval FLAC__bool
+ * \c false if the encoder is already initialized, else \c true.
+ */
+FLAC_API FLAC__bool FLAC__stream_encoder_set_do_exhaustive_model_search(FLAC__StreamEncoder *encoder, FLAC__bool value);
+
+/** Set the minimum partition order to search when coding the residual.
+ * This is used in tandem with
+ * FLAC__stream_encoder_set_max_residual_partition_order().
+ *
+ * The partition order determines the context size in the residual.
+ * The context size will be approximately <tt>blocksize / (2 ^ order)</tt>.
+ *
+ * Set both min and max values to \c 0 to force a single context,
+ * whose Rice parameter is based on the residual signal variance.
+ * Otherwise, set a min and max order, and the encoder will search
+ * all orders, using the mean of each context for its Rice parameter,
+ * and use the best.
+ *
+ * \default \c 0
+ * \param encoder An encoder instance to set.
+ * \param value See above.
+ * \assert
+ * \code encoder != NULL \endcode
+ * \retval FLAC__bool
+ * \c false if the encoder is already initialized, else \c true.
+ */
+FLAC_API FLAC__bool FLAC__stream_encoder_set_min_residual_partition_order(FLAC__StreamEncoder *encoder, unsigned value);
+
+/** Set the maximum partition order to search when coding the residual.
+ * This is used in tandem with
+ * FLAC__stream_encoder_set_min_residual_partition_order().
+ *
+ * The partition order determines the context size in the residual.
+ * The context size will be approximately <tt>blocksize / (2 ^ order)</tt>.
+ *
+ * Set both min and max values to \c 0 to force a single context,
+ * whose Rice parameter is based on the residual signal variance.
+ * Otherwise, set a min and max order, and the encoder will search
+ * all orders, using the mean of each context for its Rice parameter,
+ * and use the best.
+ *
+ * \default \c 0
+ * \param encoder An encoder instance to set.
+ * \param value See above.
+ * \assert
+ * \code encoder != NULL \endcode
+ * \retval FLAC__bool
+ * \c false if the encoder is already initialized, else \c true.
+ */
+FLAC_API FLAC__bool FLAC__stream_encoder_set_max_residual_partition_order(FLAC__StreamEncoder *encoder, unsigned value);
+
+/** Deprecated. Setting this value has no effect.
+ *
+ * \default \c 0
+ * \param encoder An encoder instance to set.
+ * \param value See above.
+ * \assert
+ * \code encoder != NULL \endcode
+ * \retval FLAC__bool
+ * \c false if the encoder is already initialized, else \c true.
+ */
+FLAC_API FLAC__bool FLAC__stream_encoder_set_rice_parameter_search_dist(FLAC__StreamEncoder *encoder, unsigned value);
+
+/** Set an estimate of the total samples that will be encoded.
+ * This is merely an estimate and may be set to \c 0 if unknown.
+ * This value will be written to the STREAMINFO block before encoding,
+ * and can remove the need for the caller to rewrite the value later
+ * if the value is known before encoding.
+ *
+ * \default \c 0
+ * \param encoder An encoder instance to set.
+ * \param value See above.
+ * \assert
+ * \code encoder != NULL \endcode
+ * \retval FLAC__bool
+ * \c false if the encoder is already initialized, else \c true.
+ */
+FLAC_API FLAC__bool FLAC__stream_encoder_set_total_samples_estimate(FLAC__StreamEncoder *encoder, FLAC__uint64 value);
+
+/** Set the metadata blocks to be emitted to the stream before encoding.
+ * A value of \c NULL, \c 0 implies no metadata; otherwise, supply an
+ * array of pointers to metadata blocks. The array is non-const since
+ * the encoder may need to change the \a is_last flag inside them, and
+ * in some cases update seek point offsets. Otherwise, the encoder will
+ * not modify or free the blocks. It is up to the caller to free the
+ * metadata blocks after encoding finishes.
+ *
+ * \note
+ * The encoder stores only copies of the pointers in the \a metadata array;
+ * the metadata blocks themselves must survive at least until after
+ * FLAC__stream_encoder_finish() returns. Do not free the blocks until then.
+ *
+ * \note
+ * The STREAMINFO block is always written and no STREAMINFO block may
+ * occur in the supplied array.
+ *
+ * \note
+ * By default the encoder does not create a SEEKTABLE. If one is supplied
+ * in the \a metadata array, but the client has specified that it does not
+ * support seeking, then the SEEKTABLE will be written verbatim. However
+ * by itself this is not very useful as the client will not know the stream
+ * offsets for the seekpoints ahead of time. In order to get a proper
+ * seektable the client must support seeking. See next note.
+ *
+ * \note
+ * SEEKTABLE blocks are handled specially. Since you will not know
+ * the values for the seek point stream offsets, you should pass in
+ * a SEEKTABLE 'template', that is, a SEEKTABLE object with the
+ * required sample numbers (or placeholder points), with \c 0 for the
+ * \a frame_samples and \a stream_offset fields for each point. If the
+ * client has specified that it supports seeking by providing a seek
+ * callback to FLAC__stream_encoder_init_stream() or both seek AND read
+ * callback to FLAC__stream_encoder_init_ogg_stream() (or by using
+ * FLAC__stream_encoder_init*_file() or FLAC__stream_encoder_init*_FILE()),
+ * then while it is encoding the encoder will fill the stream offsets in
+ * for you and when encoding is finished, it will seek back and write the
+ * real values into the SEEKTABLE block in the stream. There are helper
+ * routines for manipulating seektable template blocks; see metadata.h:
+ * FLAC__metadata_object_seektable_template_*(). If the client does
+ * not support seeking, the SEEKTABLE will have inaccurate offsets which
+ * will slow down or remove the ability to seek in the FLAC stream.
+ *
+ * \note
+ * The encoder instance \b will modify the first \c SEEKTABLE block
+ * as it transforms the template to a valid seektable while encoding,
+ * but it is still up to the caller to free all metadata blocks after
+ * encoding.
+ *
+ * \note
+ * A VORBIS_COMMENT block may be supplied. The vendor string in it
+ * will be ignored. libFLAC will use it's own vendor string. libFLAC
+ * will not modify the passed-in VORBIS_COMMENT's vendor string, it
+ * will simply write it's own into the stream. If no VORBIS_COMMENT
+ * block is present in the \a metadata array, libFLAC will write an
+ * empty one, containing only the vendor string.
+ *
+ * \note The Ogg FLAC mapping requires that the VORBIS_COMMENT block be
+ * the second metadata block of the stream. The encoder already supplies
+ * the STREAMINFO block automatically. If \a metadata does not contain a
+ * VORBIS_COMMENT block, the encoder will supply that too. Otherwise, if
+ * \a metadata does contain a VORBIS_COMMENT block and it is not the
+ * first, the init function will reorder \a metadata by moving the
+ * VORBIS_COMMENT block to the front; the relative ordering of the other
+ * blocks will remain as they were.
+ *
+ * \note The Ogg FLAC mapping limits the number of metadata blocks per
+ * stream to \c 65535. If \a num_blocks exceeds this the function will
+ * return \c false.
+ *
+ * \default \c NULL, 0
+ * \param encoder An encoder instance to set.
+ * \param metadata See above.
+ * \param num_blocks See above.
+ * \assert
+ * \code encoder != NULL \endcode
+ * \retval FLAC__bool
+ * \c false if the encoder is already initialized, else \c true.
+ * \c false if the encoder is already initialized, or if
+ * \a num_blocks > 65535 if encoding to Ogg FLAC, else \c true.
+ */
+FLAC_API FLAC__bool FLAC__stream_encoder_set_metadata(FLAC__StreamEncoder *encoder, FLAC__StreamMetadata **metadata, unsigned num_blocks);
+
+/** Get the current encoder state.
+ *
+ * \param encoder An encoder instance to query.
+ * \assert
+ * \code encoder != NULL \endcode
+ * \retval FLAC__StreamEncoderState
+ * The current encoder state.
+ */
+FLAC_API FLAC__StreamEncoderState FLAC__stream_encoder_get_state(const FLAC__StreamEncoder *encoder);
+
+/** Get the state of the verify stream decoder.
+ * Useful when the stream encoder state is
+ * \c FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR.
+ *
+ * \param encoder An encoder instance to query.
+ * \assert
+ * \code encoder != NULL \endcode
+ * \retval FLAC__StreamDecoderState
+ * The verify stream decoder state.
+ */
+FLAC_API FLAC__StreamDecoderState FLAC__stream_encoder_get_verify_decoder_state(const FLAC__StreamEncoder *encoder);
+
+/** Get the current encoder state as a C string.
+ * This version automatically resolves
+ * \c FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR by getting the
+ * verify decoder's state.
+ *
+ * \param encoder A encoder instance to query.
+ * \assert
+ * \code encoder != NULL \endcode
+ * \retval const char *
+ * The encoder state as a C string. Do not modify the contents.
+ */
+FLAC_API const char *FLAC__stream_encoder_get_resolved_state_string(const FLAC__StreamEncoder *encoder);
+
+/** Get relevant values about the nature of a verify decoder error.
+ * Useful when the stream encoder state is
+ * \c FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR. The arguments should
+ * be addresses in which the stats will be returned, or NULL if value
+ * is not desired.
+ *
+ * \param encoder An encoder instance to query.
+ * \param absolute_sample The absolute sample number of the mismatch.
+ * \param frame_number The number of the frame in which the mismatch occurred.
+ * \param channel The channel in which the mismatch occurred.
+ * \param sample The number of the sample (relative to the frame) in
+ * which the mismatch occurred.
+ * \param expected The expected value for the sample in question.
+ * \param got The actual value returned by the decoder.
+ * \assert
+ * \code encoder != NULL \endcode
+ */
+FLAC_API void FLAC__stream_encoder_get_verify_decoder_error_stats(const FLAC__StreamEncoder *encoder, FLAC__uint64 *absolute_sample, unsigned *frame_number, unsigned *channel, unsigned *sample, FLAC__int32 *expected, FLAC__int32 *got);
+
+/** Get the "verify" flag.
+ *
+ * \param encoder An encoder instance to query.
+ * \assert
+ * \code encoder != NULL \endcode
+ * \retval FLAC__bool
+ * See FLAC__stream_encoder_set_verify().
+ */
+FLAC_API FLAC__bool FLAC__stream_encoder_get_verify(const FLAC__StreamEncoder *encoder);
+
+/** Get the <A HREF="../format.html#subset>Subset</A> flag.
+ *
+ * \param encoder An encoder instance to query.
+ * \assert
+ * \code encoder != NULL \endcode
+ * \retval FLAC__bool
+ * See FLAC__stream_encoder_set_streamable_subset().
+ */
+FLAC_API FLAC__bool FLAC__stream_encoder_get_streamable_subset(const FLAC__StreamEncoder *encoder);
+
+/** Get the number of input channels being processed.
+ *
+ * \param encoder An encoder instance to query.
+ * \assert
+ * \code encoder != NULL \endcode
+ * \retval unsigned
+ * See FLAC__stream_encoder_set_channels().
+ */
+FLAC_API unsigned FLAC__stream_encoder_get_channels(const FLAC__StreamEncoder *encoder);
+
+/** Get the input sample resolution setting.
+ *
+ * \param encoder An encoder instance to query.
+ * \assert
+ * \code encoder != NULL \endcode
+ * \retval unsigned
+ * See FLAC__stream_encoder_set_bits_per_sample().
+ */
+FLAC_API unsigned FLAC__stream_encoder_get_bits_per_sample(const FLAC__StreamEncoder *encoder);
+
+/** Get the input sample rate setting.
+ *
+ * \param encoder An encoder instance to query.
+ * \assert
+ * \code encoder != NULL \endcode
+ * \retval unsigned
+ * See FLAC__stream_encoder_set_sample_rate().
+ */
+FLAC_API unsigned FLAC__stream_encoder_get_sample_rate(const FLAC__StreamEncoder *encoder);
+
+/** Get the blocksize setting.
+ *
+ * \param encoder An encoder instance to query.
+ * \assert
+ * \code encoder != NULL \endcode
+ * \retval unsigned
+ * See FLAC__stream_encoder_set_blocksize().
+ */
+FLAC_API unsigned FLAC__stream_encoder_get_blocksize(const FLAC__StreamEncoder *encoder);
+
+/** Get the "mid/side stereo coding" flag.
+ *
+ * \param encoder An encoder instance to query.
+ * \assert
+ * \code encoder != NULL \endcode
+ * \retval FLAC__bool
+ * See FLAC__stream_encoder_get_do_mid_side_stereo().
+ */
+FLAC_API FLAC__bool FLAC__stream_encoder_get_do_mid_side_stereo(const FLAC__StreamEncoder *encoder);
+
+/** Get the "adaptive mid/side switching" flag.
+ *
+ * \param encoder An encoder instance to query.
+ * \assert
+ * \code encoder != NULL \endcode
+ * \retval FLAC__bool
+ * See FLAC__stream_encoder_set_loose_mid_side_stereo().
+ */
+FLAC_API FLAC__bool FLAC__stream_encoder_get_loose_mid_side_stereo(const FLAC__StreamEncoder *encoder);
+
+/** Get the maximum LPC order setting.
+ *
+ * \param encoder An encoder instance to query.
+ * \assert
+ * \code encoder != NULL \endcode
+ * \retval unsigned
+ * See FLAC__stream_encoder_set_max_lpc_order().
+ */
+FLAC_API unsigned FLAC__stream_encoder_get_max_lpc_order(const FLAC__StreamEncoder *encoder);
+
+/** Get the quantized linear predictor coefficient precision setting.
+ *
+ * \param encoder An encoder instance to query.
+ * \assert
+ * \code encoder != NULL \endcode
+ * \retval unsigned
+ * See FLAC__stream_encoder_set_qlp_coeff_precision().
+ */
+FLAC_API unsigned FLAC__stream_encoder_get_qlp_coeff_precision(const FLAC__StreamEncoder *encoder);
+
+/** Get the qlp coefficient precision search flag.
+ *
+ * \param encoder An encoder instance to query.
+ * \assert
+ * \code encoder != NULL \endcode
+ * \retval FLAC__bool
+ * See FLAC__stream_encoder_set_do_qlp_coeff_prec_search().
+ */
+FLAC_API FLAC__bool FLAC__stream_encoder_get_do_qlp_coeff_prec_search(const FLAC__StreamEncoder *encoder);
+
+/** Get the "escape coding" flag.
+ *
+ * \param encoder An encoder instance to query.
+ * \assert
+ * \code encoder != NULL \endcode
+ * \retval FLAC__bool
+ * See FLAC__stream_encoder_set_do_escape_coding().
+ */
+FLAC_API FLAC__bool FLAC__stream_encoder_get_do_escape_coding(const FLAC__StreamEncoder *encoder);
+
+/** Get the exhaustive model search flag.
+ *
+ * \param encoder An encoder instance to query.
+ * \assert
+ * \code encoder != NULL \endcode
+ * \retval FLAC__bool
+ * See FLAC__stream_encoder_set_do_exhaustive_model_search().
+ */
+FLAC_API FLAC__bool FLAC__stream_encoder_get_do_exhaustive_model_search(const FLAC__StreamEncoder *encoder);
+
+/** Get the minimum residual partition order setting.
+ *
+ * \param encoder An encoder instance to query.
+ * \assert
+ * \code encoder != NULL \endcode
+ * \retval unsigned
+ * See FLAC__stream_encoder_set_min_residual_partition_order().
+ */
+FLAC_API unsigned FLAC__stream_encoder_get_min_residual_partition_order(const FLAC__StreamEncoder *encoder);
+
+/** Get maximum residual partition order setting.
+ *
+ * \param encoder An encoder instance to query.
+ * \assert
+ * \code encoder != NULL \endcode
+ * \retval unsigned
+ * See FLAC__stream_encoder_set_max_residual_partition_order().
+ */
+FLAC_API unsigned FLAC__stream_encoder_get_max_residual_partition_order(const FLAC__StreamEncoder *encoder);
+
+/** Get the Rice parameter search distance setting.
+ *
+ * \param encoder An encoder instance to query.
+ * \assert
+ * \code encoder != NULL \endcode
+ * \retval unsigned
+ * See FLAC__stream_encoder_set_rice_parameter_search_dist().
+ */
+FLAC_API unsigned FLAC__stream_encoder_get_rice_parameter_search_dist(const FLAC__StreamEncoder *encoder);
+
+/** Get the previously set estimate of the total samples to be encoded.
+ * The encoder merely mimics back the value given to
+ * FLAC__stream_encoder_set_total_samples_estimate() since it has no
+ * other way of knowing how many samples the client will encode.
+ *
+ * \param encoder An encoder instance to set.
+ * \assert
+ * \code encoder != NULL \endcode
+ * \retval FLAC__uint64
+ * See FLAC__stream_encoder_get_total_samples_estimate().
+ */
+FLAC_API FLAC__uint64 FLAC__stream_encoder_get_total_samples_estimate(const FLAC__StreamEncoder *encoder);
+
+/** Initialize the encoder instance to encode native FLAC streams.
+ *
+ * This flavor of initialization sets up the encoder to encode to a
+ * native FLAC stream. I/O is performed via callbacks to the client.
+ * For encoding to a plain file via filename or open \c FILE*,
+ * FLAC__stream_encoder_init_file() and FLAC__stream_encoder_init_FILE()
+ * provide a simpler interface.
+ *
+ * This function should be called after FLAC__stream_encoder_new() and
+ * FLAC__stream_encoder_set_*() but before FLAC__stream_encoder_process()
+ * or FLAC__stream_encoder_process_interleaved().
+ * initialization succeeded.
+ *
+ * The call to FLAC__stream_encoder_init_stream() currently will also
+ * immediately call the write callback several times, once with the \c fLaC
+ * signature, and once for each encoded metadata block.
+ *
+ * \param encoder An uninitialized encoder instance.
+ * \param write_callback See FLAC__StreamEncoderWriteCallback. This
+ * pointer must not be \c NULL.
+ * \param seek_callback See FLAC__StreamEncoderSeekCallback. This
+ * pointer may be \c NULL if seeking is not
+ * supported. The encoder uses seeking to go back
+ * and write some some stream statistics to the
+ * STREAMINFO block; this is recommended but not
+ * necessary to create a valid FLAC stream. If
+ * \a seek_callback is not \c NULL then a
+ * \a tell_callback must also be supplied.
+ * Alternatively, a dummy seek callback that just
+ * returns \c FLAC__STREAM_ENCODER_SEEK_STATUS_UNSUPPORTED
+ * may also be supplied, all though this is slightly
+ * less efficient for the encoder.
+ * \param tell_callback See FLAC__StreamEncoderTellCallback. This
+ * pointer may be \c NULL if seeking is not
+ * supported. If \a seek_callback is \c NULL then
+ * this argument will be ignored. If
+ * \a seek_callback is not \c NULL then a
+ * \a tell_callback must also be supplied.
+ * Alternatively, a dummy tell callback that just
+ * returns \c FLAC__STREAM_ENCODER_TELL_STATUS_UNSUPPORTED
+ * may also be supplied, all though this is slightly
+ * less efficient for the encoder.
+ * \param metadata_callback See FLAC__StreamEncoderMetadataCallback. This
+ * pointer may be \c NULL if the callback is not
+ * desired. If the client provides a seek callback,
+ * this function is not necessary as the encoder
+ * will automatically seek back and update the
+ * STREAMINFO block. It may also be \c NULL if the
+ * client does not support seeking, since it will
+ * have no way of going back to update the
+ * STREAMINFO. However the client can still supply
+ * a callback if it would like to know the details
+ * from the STREAMINFO.
+ * \param client_data This value will be supplied to callbacks in their
+ * \a client_data argument.
+ * \assert
+ * \code encoder != NULL \endcode
+ * \retval FLAC__StreamEncoderInitStatus
+ * \c FLAC__STREAM_ENCODER_INIT_STATUS_OK if initialization was successful;
+ * see FLAC__StreamEncoderInitStatus for the meanings of other return values.
+ */
+FLAC_API FLAC__StreamEncoderInitStatus FLAC__stream_encoder_init_stream(FLAC__StreamEncoder *encoder, FLAC__StreamEncoderWriteCallback write_callback, FLAC__StreamEncoderSeekCallback seek_callback, FLAC__StreamEncoderTellCallback tell_callback, FLAC__StreamEncoderMetadataCallback metadata_callback, void *client_data);
+
+/** Initialize the encoder instance to encode Ogg FLAC streams.
+ *
+ * This flavor of initialization sets up the encoder to encode to a FLAC
+ * stream in an Ogg container. I/O is performed via callbacks to the
+ * client. For encoding to a plain file via filename or open \c FILE*,
+ * FLAC__stream_encoder_init_ogg_file() and FLAC__stream_encoder_init_ogg_FILE()
+ * provide a simpler interface.
+ *
+ * This function should be called after FLAC__stream_encoder_new() and
+ * FLAC__stream_encoder_set_*() but before FLAC__stream_encoder_process()
+ * or FLAC__stream_encoder_process_interleaved().
+ * initialization succeeded.
+ *
+ * The call to FLAC__stream_encoder_init_ogg_stream() currently will also
+ * immediately call the write callback several times to write the metadata
+ * packets.
+ *
+ * \param encoder An uninitialized encoder instance.
+ * \param read_callback See FLAC__StreamEncoderReadCallback. This
+ * pointer must not be \c NULL if \a seek_callback
+ * is non-NULL since they are both needed to be
+ * able to write data back to the Ogg FLAC stream
+ * in the post-encode phase.
+ * \param write_callback See FLAC__StreamEncoderWriteCallback. This
+ * pointer must not be \c NULL.
+ * \param seek_callback See FLAC__StreamEncoderSeekCallback. This
+ * pointer may be \c NULL if seeking is not
+ * supported. The encoder uses seeking to go back
+ * and write some some stream statistics to the
+ * STREAMINFO block; this is recommended but not
+ * necessary to create a valid FLAC stream. If
+ * \a seek_callback is not \c NULL then a
+ * \a tell_callback must also be supplied.
+ * Alternatively, a dummy seek callback that just
+ * returns \c FLAC__STREAM_ENCODER_SEEK_STATUS_UNSUPPORTED
+ * may also be supplied, all though this is slightly
+ * less efficient for the encoder.
+ * \param tell_callback See FLAC__StreamEncoderTellCallback. This
+ * pointer may be \c NULL if seeking is not
+ * supported. If \a seek_callback is \c NULL then
+ * this argument will be ignored. If
+ * \a seek_callback is not \c NULL then a
+ * \a tell_callback must also be supplied.
+ * Alternatively, a dummy tell callback that just
+ * returns \c FLAC__STREAM_ENCODER_TELL_STATUS_UNSUPPORTED
+ * may also be supplied, all though this is slightly
+ * less efficient for the encoder.
+ * \param metadata_callback See FLAC__StreamEncoderMetadataCallback. This
+ * pointer may be \c NULL if the callback is not
+ * desired. If the client provides a seek callback,
+ * this function is not necessary as the encoder
+ * will automatically seek back and update the
+ * STREAMINFO block. It may also be \c NULL if the
+ * client does not support seeking, since it will
+ * have no way of going back to update the
+ * STREAMINFO. However the client can still supply
+ * a callback if it would like to know the details
+ * from the STREAMINFO.
+ * \param client_data This value will be supplied to callbacks in their
+ * \a client_data argument.
+ * \assert
+ * \code encoder != NULL \endcode
+ * \retval FLAC__StreamEncoderInitStatus
+ * \c FLAC__STREAM_ENCODER_INIT_STATUS_OK if initialization was successful;
+ * see FLAC__StreamEncoderInitStatus for the meanings of other return values.
+ */
+FLAC_API FLAC__StreamEncoderInitStatus FLAC__stream_encoder_init_ogg_stream(FLAC__StreamEncoder *encoder, FLAC__StreamEncoderReadCallback read_callback, FLAC__StreamEncoderWriteCallback write_callback, FLAC__StreamEncoderSeekCallback seek_callback, FLAC__StreamEncoderTellCallback tell_callback, FLAC__StreamEncoderMetadataCallback metadata_callback, void *client_data);
+
+/** Initialize the encoder instance to encode native FLAC files.
+ *
+ * This flavor of initialization sets up the encoder to encode to a
+ * plain native FLAC file. For non-stdio streams, you must use
+ * FLAC__stream_encoder_init_stream() and provide callbacks for the I/O.
+ *
+ * This function should be called after FLAC__stream_encoder_new() and
+ * FLAC__stream_encoder_set_*() but before FLAC__stream_encoder_process()
+ * or FLAC__stream_encoder_process_interleaved().
+ * initialization succeeded.
+ *
+ * \param encoder An uninitialized encoder instance.
+ * \param file An open file. The file should have been opened
+ * with mode \c "w+b" and rewound. The file
+ * becomes owned by the encoder and should not be
+ * manipulated by the client while encoding.
+ * Unless \a file is \c stdout, it will be closed
+ * when FLAC__stream_encoder_finish() is called.
+ * Note however that a proper SEEKTABLE cannot be
+ * created when encoding to \c stdout since it is
+ * not seekable.
+ * \param progress_callback See FLAC__StreamEncoderProgressCallback. This
+ * pointer may be \c NULL if the callback is not
+ * desired.
+ * \param client_data This value will be supplied to callbacks in their
+ * \a client_data argument.
+ * \assert
+ * \code encoder != NULL \endcode
+ * \code file != NULL \endcode
+ * \retval FLAC__StreamEncoderInitStatus
+ * \c FLAC__STREAM_ENCODER_INIT_STATUS_OK if initialization was successful;
+ * see FLAC__StreamEncoderInitStatus for the meanings of other return values.
+ */
+FLAC_API FLAC__StreamEncoderInitStatus FLAC__stream_encoder_init_FILE(FLAC__StreamEncoder *encoder, FILE *file, FLAC__StreamEncoderProgressCallback progress_callback, void *client_data);
+
+/** Initialize the encoder instance to encode Ogg FLAC files.
+ *
+ * This flavor of initialization sets up the encoder to encode to a
+ * plain Ogg FLAC file. For non-stdio streams, you must use
+ * FLAC__stream_encoder_init_ogg_stream() and provide callbacks for the I/O.
+ *
+ * This function should be called after FLAC__stream_encoder_new() and
+ * FLAC__stream_encoder_set_*() but before FLAC__stream_encoder_process()
+ * or FLAC__stream_encoder_process_interleaved().
+ * initialization succeeded.
+ *
+ * \param encoder An uninitialized encoder instance.
+ * \param file An open file. The file should have been opened
+ * with mode \c "w+b" and rewound. The file
+ * becomes owned by the encoder and should not be
+ * manipulated by the client while encoding.
+ * Unless \a file is \c stdout, it will be closed
+ * when FLAC__stream_encoder_finish() is called.
+ * Note however that a proper SEEKTABLE cannot be
+ * created when encoding to \c stdout since it is
+ * not seekable.
+ * \param progress_callback See FLAC__StreamEncoderProgressCallback. This
+ * pointer may be \c NULL if the callback is not
+ * desired.
+ * \param client_data This value will be supplied to callbacks in their
+ * \a client_data argument.
+ * \assert
+ * \code encoder != NULL \endcode
+ * \code file != NULL \endcode
+ * \retval FLAC__StreamEncoderInitStatus
+ * \c FLAC__STREAM_ENCODER_INIT_STATUS_OK if initialization was successful;
+ * see FLAC__StreamEncoderInitStatus for the meanings of other return values.
+ */
+FLAC_API FLAC__StreamEncoderInitStatus FLAC__stream_encoder_init_ogg_FILE(FLAC__StreamEncoder *encoder, FILE *file, FLAC__StreamEncoderProgressCallback progress_callback, void *client_data);
+
+/** Initialize the encoder instance to encode native FLAC files.
+ *
+ * This flavor of initialization sets up the encoder to encode to a plain
+ * FLAC file. If POSIX fopen() semantics are not sufficient (for example,
+ * with Unicode filenames on Windows), you must use
+ * FLAC__stream_encoder_init_FILE(), or FLAC__stream_encoder_init_stream()
+ * and provide callbacks for the I/O.
+ *
+ * This function should be called after FLAC__stream_encoder_new() and
+ * FLAC__stream_encoder_set_*() but before FLAC__stream_encoder_process()
+ * or FLAC__stream_encoder_process_interleaved().
+ * initialization succeeded.
+ *
+ * \param encoder An uninitialized encoder instance.
+ * \param filename The name of the file to encode to. The file will
+ * be opened with fopen(). Use \c NULL to encode to
+ * \c stdout. Note however that a proper SEEKTABLE
+ * cannot be created when encoding to \c stdout since
+ * it is not seekable.
+ * \param progress_callback See FLAC__StreamEncoderProgressCallback. This
+ * pointer may be \c NULL if the callback is not
+ * desired.
+ * \param client_data This value will be supplied to callbacks in their
+ * \a client_data argument.
+ * \assert
+ * \code encoder != NULL \endcode
+ * \retval FLAC__StreamEncoderInitStatus
+ * \c FLAC__STREAM_ENCODER_INIT_STATUS_OK if initialization was successful;
+ * see FLAC__StreamEncoderInitStatus for the meanings of other return values.
+ */
+FLAC_API FLAC__StreamEncoderInitStatus FLAC__stream_encoder_init_file(FLAC__StreamEncoder *encoder, const char *filename, FLAC__StreamEncoderProgressCallback progress_callback, void *client_data);
+
+/** Initialize the encoder instance to encode Ogg FLAC files.
+ *
+ * This flavor of initialization sets up the encoder to encode to a plain
+ * Ogg FLAC file. If POSIX fopen() semantics are not sufficient (for example,
+ * with Unicode filenames on Windows), you must use
+ * FLAC__stream_encoder_init_ogg_FILE(), or FLAC__stream_encoder_init_ogg_stream()
+ * and provide callbacks for the I/O.
+ *
+ * This function should be called after FLAC__stream_encoder_new() and
+ * FLAC__stream_encoder_set_*() but before FLAC__stream_encoder_process()
+ * or FLAC__stream_encoder_process_interleaved().
+ * initialization succeeded.
+ *
+ * \param encoder An uninitialized encoder instance.
+ * \param filename The name of the file to encode to. The file will
+ * be opened with fopen(). Use \c NULL to encode to
+ * \c stdout. Note however that a proper SEEKTABLE
+ * cannot be created when encoding to \c stdout since
+ * it is not seekable.
+ * \param progress_callback See FLAC__StreamEncoderProgressCallback. This
+ * pointer may be \c NULL if the callback is not
+ * desired.
+ * \param client_data This value will be supplied to callbacks in their
+ * \a client_data argument.
+ * \assert
+ * \code encoder != NULL \endcode
+ * \retval FLAC__StreamEncoderInitStatus
+ * \c FLAC__STREAM_ENCODER_INIT_STATUS_OK if initialization was successful;
+ * see FLAC__StreamEncoderInitStatus for the meanings of other return values.
+ */
+FLAC_API FLAC__StreamEncoderInitStatus FLAC__stream_encoder_init_ogg_file(FLAC__StreamEncoder *encoder, const char *filename, FLAC__StreamEncoderProgressCallback progress_callback, void *client_data);
+
+/** Finish the encoding process.
+ * Flushes the encoding buffer, releases resources, resets the encoder
+ * settings to their defaults, and returns the encoder state to
+ * FLAC__STREAM_ENCODER_UNINITIALIZED. Note that this can generate
+ * one or more write callbacks before returning, and will generate
+ * a metadata callback.
+ *
+ * Note that in the course of processing the last frame, errors can
+ * occur, so the caller should be sure to check the return value to
+ * ensure the file was encoded properly.
+ *
+ * In the event of a prematurely-terminated encode, it is not strictly
+ * necessary to call this immediately before FLAC__stream_encoder_delete()
+ * but it is good practice to match every FLAC__stream_encoder_init_*()
+ * with a FLAC__stream_encoder_finish().
+ *
+ * \param encoder An uninitialized encoder instance.
+ * \assert
+ * \code encoder != NULL \endcode
+ * \retval FLAC__bool
+ * \c false if an error occurred processing the last frame; or if verify
+ * mode is set (see FLAC__stream_encoder_set_verify()), there was a
+ * verify mismatch; else \c true. If \c false, caller should check the
+ * state with FLAC__stream_encoder_get_state() for more information
+ * about the error.
+ */
+FLAC_API FLAC__bool FLAC__stream_encoder_finish(FLAC__StreamEncoder *encoder);
+
+/** Submit data for encoding.
+ * This version allows you to supply the input data via an array of
+ * pointers, each pointer pointing to an array of \a samples samples
+ * representing one channel. The samples need not be block-aligned,
+ * but each channel should have the same number of samples. Each sample
+ * should be a signed integer, right-justified to the resolution set by
+ * FLAC__stream_encoder_set_bits_per_sample(). For example, if the
+ * resolution is 16 bits per sample, the samples should all be in the
+ * range [-32768,32767].
+ *
+ * For applications where channel order is important, channels must
+ * follow the order as described in the
+ * <A HREF="../format.html#frame_header">frame header</A>.
+ *
+ * \param encoder An initialized encoder instance in the OK state.
+ * \param buffer An array of pointers to each channel's signal.
+ * \param samples The number of samples in one channel.
+ * \assert
+ * \code encoder != NULL \endcode
+ * \code FLAC__stream_encoder_get_state(encoder) == FLAC__STREAM_ENCODER_OK \endcode
+ * \retval FLAC__bool
+ * \c true if successful, else \c false; in this case, check the
+ * encoder state with FLAC__stream_encoder_get_state() to see what
+ * went wrong.
+ */
+FLAC_API FLAC__bool FLAC__stream_encoder_process(FLAC__StreamEncoder *encoder, const FLAC__int32 * const buffer[], unsigned samples);
+
+/** Submit data for encoding.
+ * This version allows you to supply the input data where the channels
+ * are interleaved into a single array (i.e. channel0_sample0,
+ * channel1_sample0, ... , channelN_sample0, channel0_sample1, ...).
+ * The samples need not be block-aligned but they must be
+ * sample-aligned, i.e. the first value should be channel0_sample0
+ * and the last value channelN_sampleM. Each sample should be a signed
+ * integer, right-justified to the resolution set by
+ * FLAC__stream_encoder_set_bits_per_sample(). For example, if the
+ * resolution is 16 bits per sample, the samples should all be in the
+ * range [-32768,32767].
+ *
+ * For applications where channel order is important, channels must
+ * follow the order as described in the
+ * <A HREF="../format.html#frame_header">frame header</A>.
+ *
+ * \param encoder An initialized encoder instance in the OK state.
+ * \param buffer An array of channel-interleaved data (see above).
+ * \param samples The number of samples in one channel, the same as for
+ * FLAC__stream_encoder_process(). For example, if
+ * encoding two channels, \c 1000 \a samples corresponds
+ * to a \a buffer of 2000 values.
+ * \assert
+ * \code encoder != NULL \endcode
+ * \code FLAC__stream_encoder_get_state(encoder) == FLAC__STREAM_ENCODER_OK \endcode
+ * \retval FLAC__bool
+ * \c true if successful, else \c false; in this case, check the
+ * encoder state with FLAC__stream_encoder_get_state() to see what
+ * went wrong.
+ */
+FLAC_API FLAC__bool FLAC__stream_encoder_process_interleaved(FLAC__StreamEncoder *encoder, const FLAC__int32 buffer[], unsigned samples);
+
+/* \} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib-x86-32/include/cddb/Makefile.am b/lib-x86-32/include/cddb/Makefile.am
new file mode 100644
index 00000000..f6c2f70f
--- /dev/null
+++ b/lib-x86-32/include/cddb/Makefile.am
@@ -0,0 +1,9 @@
+
+pkgincludedir=$(includedir)/cddb
+pkginclude_HEADERS = cddb.h cddb_config.h cddb_disc.h cddb_track.h \
+ cddb_error.h cddb_conn.h cddb_cmd.h cddb_log.h \
+ version.h cddb_site.h
+noinst_HEADERS = cddb_ni.h cddb_regex.h cddb_conn_ni.h cddb_cmd_ni.h \
+ cddb_net.h cddb_log_ni.h ll.h
+
+EXTRA_DIST = version.h.in
diff --git a/lib-x86-32/include/cddb/cddb.h b/lib-x86-32/include/cddb/cddb.h
new file mode 100644
index 00000000..c46700a6
--- /dev/null
+++ b/lib-x86-32/include/cddb/cddb.h
@@ -0,0 +1,97 @@
+/*
+ $Id: cddb.h,v 1.14 2006/10/15 12:54:33 airborne Exp $
+
+ Copyright (C) 2003, 2004, 2005 Kris Verbeeck <airborne@advalvas.be>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef CDDB_H
+#define CDDB_H 1
+
+#include <cddb/version.h>
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+#include <cddb/cddb_config.h>
+#include <cddb/cddb_error.h>
+#include <cddb/cddb_track.h>
+#include <cddb/cddb_disc.h>
+#include <cddb/cddb_site.h>
+#include <cddb/cddb_conn.h>
+#include <cddb/cddb_cmd.h>
+#include <cddb/cddb_log.h>
+
+
+/**
+ * \mainpage libCDDB, a C API for CDDB server access
+ */
+
+
+#define BIT(n) (1 << n)
+
+/**
+ * An enumeration of flags that influence the behaviour of the
+ * library. You can set or reset these flags using the
+ * #libcddb_set_flags and #libcddb_reset_flags functions.
+ */
+typedef enum {
+ CDDB_F_EMPTY_STR = BIT(0), /**< never return NULL pointer strings
+ (default), return an empty string
+ instead */
+ CDDB_F_NO_TRACK_ARTIST = BIT(1), /**< do not return the disc artist as the
+ track artist (default), return NULL
+ instead */
+} cddb_flag_t;
+
+/**
+ * Initializes the library. This is used to setup any globally used
+ * variables. The first time you create a new CDDB connection structure
+ * the library will automatically initialize itself. So, there is no
+ * need to explicitly call this function.
+ */
+void libcddb_init(void);
+
+/**
+ * Frees up any global (cross connection) resources. You should call
+ * this function before terminating your program. Using any library
+ * calls after shutting down are bound to give problems.
+ */
+void libcddb_shutdown(void);
+
+/**
+ * Set one or more flags that influence the library behvaiour
+ *
+ * @param flags A bitwise ORed set of values from #cddb_flag_t.
+ */
+void libcddb_set_flags(unsigned int flags);
+
+/**
+ * Reset one or more flags that influence the library behvaiour
+ *
+ * @param flags A bitwise ORed set of values from #cddb_flag_t.
+ */
+void libcddb_reset_flags(unsigned int flags);
+
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* CDDB_H */
diff --git a/lib-x86-32/include/cddb/cddb_cmd.h b/lib-x86-32/include/cddb/cddb_cmd.h
new file mode 100644
index 00000000..c5a01fef
--- /dev/null
+++ b/lib-x86-32/include/cddb/cddb_cmd.h
@@ -0,0 +1,185 @@
+/*
+ $Id: cddb_cmd.h,v 1.17 2006/10/15 08:58:51 airborne Exp $
+
+ Copyright (C) 2003, 2004, 2005 Kris Verbeeck <airborne@advalvas.be>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef CDDB_CMD_H
+#define CDDB_CMD_H 1
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+/* --- accessing data on the CDDB server --- */
+
+
+/**
+ * Retrieve a disc record from the CDDB server. This function
+ * requires that the category and disc ID of the provided disc
+ * structure are valid.
+ *
+ * If nothing goes wrong, the function will return 1 and the error
+ * code will be reset to:
+ * - #CDDB_ERR_OK:
+ * If everything went as planned.
+ *
+ * If there is a problem with reading data from the CDDB server one of
+ * the following error codes will be set:
+ * - #CDDB_ERR_DATA_MISSING:
+ * If some required data is missing from the given disc
+ * structure to execute this command.
+ * - #CDDB_ERR_DISC_NOT_FOUND:
+ * If the requested disc is not known by the CDDB server.
+ * - #CDDB_ERR_SERVER_ERROR:
+ * If the server encountered an error while trying to process your
+ * request.
+ * - #CDDB_ERR_UNKNOWN:
+ * If the server specified an unknown response code. Please
+ * report this as a libcddb bug.
+ *
+ * When there are problems with the connection to the CDDB server one
+ * of the following error codes will be set:
+ * - #CDDB_ERR_UNKNOWN_HOST_NAME:
+ * If there was an error when resolving the host name of the CDDB
+ * server.
+ * - #CDDB_ERR_CONNECT:
+ * If a connection to the CDDB server could not be established.
+ * This can be due to incorrect data about the location of the
+ * server (host name, port).
+ * - #CDDB_ERR_NOT_CONNECTED:
+ * If something when wrong in the process and you got
+ * disconnected. Retrying might succeed (but no guarantees).
+ * - #CDDB_ERR_PERMISSION_DENIED:
+ * If the server is up and running but denied the connection.
+ * This can occur when the server is too highly loaded or the
+ * handshake information (user name, ...) is considered to be
+ * invalid.
+ *
+ * @param c The CDDB connection structure.
+ * @param disc A non-null CDDB disc structure.
+ * @return 1 on succes, 0 on failure
+ */
+int cddb_read(cddb_conn_t *c, cddb_disc_t *disc);
+
+/**
+ * Query the CDDB database for a list of possible disc matches. This
+ * function requires that the disc ID and disc length of the provided
+ * disc structure are valid. The disc should also contain a number of
+ * tracks and for each track its frame offset on the CD should be
+ * valid.
+ *
+ * If there are multiple matches then only the first one will be
+ * returned by this function. For other matches you will have to use
+ * the #cddb_query_next function.
+ *
+ * @param c The CDDB connection structure.
+ * @param disc A non-null CDDB disc structure.
+ *
+ * @return The number of matches found or -1 on error.
+ */
+int cddb_query(cddb_conn_t *c, cddb_disc_t *disc);
+
+/**
+ * Returns the next match in a CDDB query result set. This function
+ * should be used in conjunction with #cddb_query.
+ *
+ * @param c The CDDB connection structure.
+ * @param disc A non-null CDDB disc structure.
+ */
+int cddb_query_next(cddb_conn_t *c, cddb_disc_t *disc);
+
+/**
+ * Perform a text search in the CDDB database. Instead of actually
+ * needing information about a real disc like in #cddb_query this
+ * function accept a string that is used for searching the database.
+ *
+ * If there are multiple matches then only the first one will be
+ * returned by this function. For other matches you will have to use
+ * the #cddb_search_next function.
+ *
+ * @param c The CDDB connection structure.
+ * @param disc A non-null CDDB disc structure.
+ * @param str The search string
+ *
+ * @return The number of matches found or -1 on error.
+ */
+int cddb_search(cddb_conn_t *c, cddb_disc_t *disc, const char *str);
+
+/**
+ * Returns the next match in a CDDB search result set. This function
+ * should be used in conjunction with #cddb_search.
+ *
+ * @param c The CDDB connection structure.
+ * @param disc A non-null CDDB disc structure.
+ */
+int cddb_search_next(cddb_conn_t *c, cddb_disc_t *disc);
+
+/**
+ * Perform a text search in the CDDB database. It uses the album
+ * command implemented on the freedb2.org servers. Either the album
+ * title or artist's name should be filled in, in the disc structure.
+ *
+ * If there are multiple matches then only the first one will be
+ * returned by this function. For other matches you will have to use
+ * the #cddb_album_next function.
+ *
+ * @param c The CDDB connection structure.
+ * @param disc A non-null CDDB disc structure.
+ *
+ * @return The number of matches found or -1 on error.
+ */
+int cddb_album(cddb_conn_t *c, cddb_disc_t *disc);
+
+/**
+ * Returns the next match in a CDDB album result set. This function
+ * should be used in conjunction with #cddb_album.
+ *
+ * @param c The CDDB connection structure.
+ * @param disc A non-null CDDB disc structure.
+ */
+int cddb_album_next(cddb_conn_t *c, cddb_disc_t *disc);
+
+/**
+ * Submit a new or updated disc to the CDDB database. This function
+ * requires that the disc ID, length, category, artist and title of
+ * the provided disc structure are valid. The disc should also
+ * contain a number of tracks and for each track its frame offset on
+ * the CD and title should be valid.
+ *
+ * @param c The CDDB connection structure.
+ * @param disc A non-null CDDB disc structure.
+ */
+int cddb_write(cddb_conn_t *c, cddb_disc_t *disc);
+
+/**
+ * Query the currently configured server for a list of mirrors.
+ * Accessing the list of mirror sites is done with the iterator
+ * functions #cddb_first_site and #cddb_next_site.
+ *
+ * @param c The CDDB connection structure.
+ */
+int cddb_sites(cddb_conn_t *c);
+
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* CDDB_CMD_H */
diff --git a/lib-x86-32/include/cddb/cddb_cmd_ni.h b/lib-x86-32/include/cddb/cddb_cmd_ni.h
new file mode 100644
index 00000000..4b02190a
--- /dev/null
+++ b/lib-x86-32/include/cddb/cddb_cmd_ni.h
@@ -0,0 +1,68 @@
+/*
+ $Id: cddb_cmd_ni.h,v 1.12 2006/10/15 08:59:20 airborne Exp $
+
+ Copyright (C) 2003, 2004, 2005 Kris Verbeeck <airborne@advalvas.be>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef CDDB_CMD_NI_H
+#define CDDB_CMD_NI_H 1
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+typedef enum {
+ CMD_HELLO = 0,
+ CMD_QUIT,
+ CMD_READ,
+ CMD_QUERY,
+ CMD_WRITE,
+ CMD_PROTO,
+ CMD_SITES,
+ CMD_SEARCH,
+ CMD_ALBUM,
+ /* dummy for array size */
+ CMD_LAST
+} cddb_cmd_t;
+
+
+/* --- utility functions --- */
+
+
+/**
+ * Will read in one line from the response input stream and parse both
+ * the code and message in that line. Errors will be signaled by
+ * returning -1.
+ *
+ * @param c the CDDB connection structure
+ * @param msg the CDDB response msg
+ * @return the CDDB response code or -1 on error
+ */
+int cddb_get_response_code(cddb_conn_t *c, char **msg);
+
+/**
+ */
+int cddb_send_cmd(cddb_conn_t *c, int cmd, ...);
+
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* CDDB_CMD_H */
diff --git a/lib-x86-32/include/cddb/cddb_config.h b/lib-x86-32/include/cddb/cddb_config.h
new file mode 100644
index 00000000..fd0d3769
--- /dev/null
+++ b/lib-x86-32/include/cddb/cddb_config.h
@@ -0,0 +1,37 @@
+/*
+ $Id: cddb_config.h.in,v 1.3 2005/03/11 21:29:29 airborne Exp $
+
+ Copyright (C) 2004, 2005 Kris Verbeeck <airborne@advalvas.be>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef CDDB_CONFIG_H
+#define CDDB_CONFIG_H 1
+
+/* Define if you have <unistd.h> and need it included.
+ On MacOS, <regex.h> needs this but that header doesn't
+ include it.
+*/
+#undef CDDB_NEED_UNISTD_H
+
+/* Define if you have <sys/socket.h> and need it included.
+ On MacOS, <cddb_net.h> needs this but that header doesn't
+ include it.
+*/
+#undef CDDB_NEED_SYS_SOCKET_H
+
+#endif /* CDDB_CONFIG_H */
diff --git a/lib-x86-32/include/cddb/cddb_config.h.in b/lib-x86-32/include/cddb/cddb_config.h.in
new file mode 100644
index 00000000..fd0d3769
--- /dev/null
+++ b/lib-x86-32/include/cddb/cddb_config.h.in
@@ -0,0 +1,37 @@
+/*
+ $Id: cddb_config.h.in,v 1.3 2005/03/11 21:29:29 airborne Exp $
+
+ Copyright (C) 2004, 2005 Kris Verbeeck <airborne@advalvas.be>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef CDDB_CONFIG_H
+#define CDDB_CONFIG_H 1
+
+/* Define if you have <unistd.h> and need it included.
+ On MacOS, <regex.h> needs this but that header doesn't
+ include it.
+*/
+#undef CDDB_NEED_UNISTD_H
+
+/* Define if you have <sys/socket.h> and need it included.
+ On MacOS, <cddb_net.h> needs this but that header doesn't
+ include it.
+*/
+#undef CDDB_NEED_SYS_SOCKET_H
+
+#endif /* CDDB_CONFIG_H */
diff --git a/lib-x86-32/include/cddb/cddb_conn.h b/lib-x86-32/include/cddb/cddb_conn.h
new file mode 100644
index 00000000..ada3cdda
--- /dev/null
+++ b/lib-x86-32/include/cddb/cddb_conn.h
@@ -0,0 +1,562 @@
+/*
+ $Id: cddb_conn.h,v 1.31 2009/03/01 03:28:07 jcaratzas Exp $
+
+ Copyright (C) 2003, 2004, 2005 Kris Verbeeck <airborne@advalvas.be>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef CDDB_CONN_H
+#define CDDB_CONN_H 1
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+#include <stdio.h>
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+
+#include "cddb/cddb_site.h"
+
+
+typedef enum {
+ CACHE_OFF = 0, /**< do not use local CDDB cache, network
+ only */
+ CACHE_ON, /**< use local CDDB cache, if possible */
+ CACHE_ONLY /**< only use local CDDB cache, no network
+ access */
+} cddb_cache_mode_t;
+
+/**
+ * Forward declaration of opaque structure used for character set
+ * conversions.
+ */
+typedef struct cddb_iconv_s *cddb_iconv_t;
+
+/**
+ * An opaque structure for keeping state about the connection to a
+ * CDDB server.
+ */
+typedef struct cddb_conn_s cddb_conn_t;
+
+/**
+ * Which fields to use for the full text search is defined by one or
+ * more of the constants below.
+ */
+typedef enum {
+ SEARCH_NONE = 0, /**< no fields */
+ SEARCH_ARTIST = 1, /**< artist name field */
+ SEARCH_TITLE = 2, /**< disc title field */
+ SEARCH_TRACK = 4, /**< track title field */
+ SEARCH_OTHER = 8, /**< other fields */
+ SEARCH_ALL = ~0, /**< all fields */
+} cddb_search_t;
+
+/**
+ * Macro to be used for building the category search bit-string from
+ * the values of #cddb_cat_t.
+ */
+#define SEARCHCAT(c) (1 << (c))
+
+
+/* --- construction / destruction --- */
+
+
+/**
+ * Creates a new CDDB connection structure. This structure will have
+ * to be passed to all libcddb functions. Default values will be used
+ * for the connection parameters allowing it to contact the CDDB
+ * server at freedb.org.
+ *
+ * @return The CDDB connection structure or NULL if something went wrong.
+ */
+cddb_conn_t *cddb_new(void);
+
+/**
+ * Free all resources associated with the given CDDB connection
+ * structure.
+ */
+void cddb_destroy(cddb_conn_t *c);
+
+
+/* --- getters & setters --- */
+
+
+/**
+ * Set the character set. By default the FreeDB server uses UTF-8 when
+ * providing CD data. When a character set is defined with this function
+ * any strings retrieved from or sent to the server will automatically be
+ * converted.
+ *
+ * @param c The connection structure.
+ * @param cs The character set that will be used.
+ * @return False if the specified character set is unknown, or no conversion
+ * from/to UTF-8 is available. True otherwise.
+ */
+int cddb_set_charset(cddb_conn_t *c, const char *cs);
+
+/**
+ * Change the size of the internal buffer.
+ *
+ * @param c The connection structure.
+ * @param size The new buffer size.
+ */
+void cddb_set_buf_size(cddb_conn_t *c, unsigned int size);
+
+/**
+ * Set all server details in one go through the use of a site structure. This
+ * function initializzes the server address, port, protocol and query path in
+ * case of HTTP.
+ *
+ * @see cddb_sites
+ * @see cddb_first_site
+ * @see cddb_next_site
+ *
+ * @param c The connection structure.
+ * @param site The site to use.
+ * @return Error code: CDDB_ERR_OK or CDDB_ERR_INVALID.
+ */
+cddb_error_t cddb_set_site(cddb_conn_t *c, const cddb_site_t *site);
+
+/**
+ * Get the host name of the CDDB server that is currently being used.
+ *
+ * @see cddb_set_server_name
+ *
+ * @param c The connection structure.
+ * @return The server host name.
+ */
+const char *cddb_get_server_name(const cddb_conn_t *c);
+
+/**
+ * Set the host name of the CDDB server. The default value for the
+ * server is 'freedb.org'.
+ *
+ * @see cddb_get_server_name
+ *
+ * @param c The connection structure.
+ * @param server The server host name.
+ */
+void cddb_set_server_name(cddb_conn_t *c, const char *server);
+
+/**
+ * Get the port of the CDDB server that is currently being used.
+ *
+ * @see cddb_set_server_port
+ *
+ * @param c The connection structure.
+ * @return The server port.
+ */
+unsigned int cddb_get_server_port(const cddb_conn_t *c);
+
+/**
+ * Set the port of the CDDB server. The default value is 888.
+ *
+ * @see cddb_get_server_port
+ *
+ * @param c The connection structure.
+ * @param port The server port.
+ */
+void cddb_set_server_port(cddb_conn_t *c, int port);
+
+/**
+ * Get the network time out value (in seconds).
+ *
+ * @see cddb_set_timeout
+ *
+ * @param c The connection structure.
+ * @return The current time out in seconds.
+ */
+unsigned int cddb_get_timeout(const cddb_conn_t *c);
+
+/**
+ * Set the network time out value (in seconds). The default is 10
+ * seconds.
+ *
+ * @see cddb_get_timeout
+ *
+ * @param c The connection structure.
+ * @param t The new time out in seconds.
+ */
+void cddb_set_timeout(cddb_conn_t *c, unsigned int t);
+
+/**
+ * Get the URL path for querying a CDDB server through HTTP.
+ *
+ * @see cddb_set_http_path_query
+ *
+ * @param c The connection structure.
+ * @return The URL path.
+ */
+const char *cddb_get_http_path_query(const cddb_conn_t *c);
+
+/**
+ * Set the URL path for querying a CDDB server through HTTP. The
+ * default value is '/~cddb/cddb.cgi'.
+ *
+ * @see cddb_get_http_path_query
+ *
+ * @param c The connection structure.
+ * @param path The URL path.
+ */
+void cddb_set_http_path_query(cddb_conn_t *c, const char *path);
+
+/**
+ * Get the URL path for submitting to a CDDB server through HTTP.
+ *
+ * @see cddb_set_http_path_submit
+ *
+ * @param c The connection structure.
+ * @return The URL path.
+ */
+const char *cddb_get_http_path_submit(const cddb_conn_t *c);
+
+/**
+ * Set the URL path for submitting to a CDDB server through HTTP. The
+ * default value is '/~cddb/submit.cgi'.
+ *
+ * @see cddb_get_http_path_submit
+ *
+ * @param c The connection structure.
+ * @param path The URL path.
+ */
+void cddb_set_http_path_submit(cddb_conn_t *c, const char *path);
+
+/**
+ * Returns true if the HTTP protocol is currently enabled and false if
+ * CDDBP is enabled.
+ *
+ * @see cddb_http_enable
+ * @see cddb_http_disable
+ *
+ * @param c The CDDB connection structure.
+ * @return True or false.
+ */
+unsigned int cddb_is_http_enabled(const cddb_conn_t *c);
+
+/**
+ * Enable HTTP tunneling to connect to the CDDB server. By default
+ * this option is disabled.
+ *
+ * @see cddb_is_http_enabled
+ * @see cddb_http_disable
+ *
+ * @param c The CDDB connection structure.
+ */
+void cddb_http_enable(cddb_conn_t *c);
+
+/**
+ * Disable HTTP tunneling to connect to the CDDB server. By default this
+ * option is disabled.
+ *
+ * @see cddb_is_http_enabled
+ * @see cddb_http_enable
+ *
+ * @param c The CDDB connection structure.
+ */
+void cddb_http_disable(cddb_conn_t *c);
+
+/**
+ * Returns true if the proxy support is currently enabled and false if
+ * it is not. This fucntion does not check whether HTTP is enabled.
+ * So it is possible that true will be returned while in reality the
+ * CDDBP protocol is being used (no proxy support).
+ *
+ * @see cddb_http_proxy_enable
+ * @see cddb_http_proxy_disable
+ *
+ * @param c The CDDB connection structure.
+ * @return True or false.
+ */
+unsigned int cddb_is_http_proxy_enabled(const cddb_conn_t *c);
+
+/**
+ * Enable HTTP tunneling through an HTTP proxy server to connect to
+ * the CDDB server. The usage of an HTTP proxy implies normal HTTP
+ * tunneling instead of connecting directly to the CDDB server. By
+ * default this option is disabled.
+ *
+ * @see cddb_is_http_proxy_enabled
+ * @see cddb_http_proxy_disable
+ *
+ * @param c The CDDB connection structure.
+ */
+void cddb_http_proxy_enable(cddb_conn_t *c);
+
+/**
+ * Disable HTTP tunneling through an HTTP proxy server to connect to
+ * the CDDB server. By default this option is disabled.
+ *
+ * @see cddb_is_http_proxy_enabled
+ * @see cddb_http_proxy_enable
+ *
+ * @param c The CDDB connection structure.
+ */
+void cddb_http_proxy_disable(cddb_conn_t *c);
+
+/**
+ * Get the host name of the HTTP proxy server.
+ *
+ * @see cddb_set_http_proxy_server_name
+ *
+ * @param c The connection structure.
+ * @return The proxy server host name.
+ */
+const char *cddb_get_http_proxy_server_name(const cddb_conn_t *c);
+
+/**
+ * Set the host name of the HTTP proxy server. There is no default
+ * value.
+ *
+ * @see cddb_get_http_proxy_server_name
+ *
+ * @param c The connection structure.
+ * @param server The server host name.
+ */
+void cddb_set_http_proxy_server_name(cddb_conn_t *c, const char *server);
+
+/**
+ * Get the port of the HTTP proxy server.
+ *
+ * @see cddb_set_http_proxy_server_port
+ *
+ * @param c The connection structure.
+ * @return The proxy server port.
+ */
+unsigned int cddb_get_http_proxy_server_port(const cddb_conn_t *c);
+
+/**
+ * Set the port of the HTTP proxy server. The default value is 8080.
+ *
+ * @see cddb_get_http_proxy_server_port
+ *
+ * @param c The connection structure.
+ * @param port The server port.
+ */
+void cddb_set_http_proxy_server_port(cddb_conn_t *c, int port);
+
+/**
+ * Set the HTTP proxy user name which is used when Basic Authentication
+ * is required.
+ *
+ * @param c The connection structure.
+ * @param username The user name.
+ */
+void cddb_set_http_proxy_username(cddb_conn_t* c, const char* username);
+
+/**
+ * Get the HTTP proxy user name.
+ *
+ * @param c The connection structure.
+ * @return The user name.
+ */
+const char *cddb_get_http_proxy_username(const cddb_conn_t *c);
+
+/**
+ * Set the HTTP proxy password which is used when Basic Authentication
+ * is required.
+ *
+ * @param c The connection structure.
+ * @param passwd The password.
+ */
+void cddb_set_http_proxy_password(cddb_conn_t* c, const char* passwd);
+
+/**
+ * Get the HTTP proxy password.
+ *
+ * @param c The connection structure.
+ * @return The password.
+ */
+const char *cddb_get_http_proxy_password(const cddb_conn_t *c);
+
+/**
+ * Set the HTTP proxy user name and password in one go. These
+ * credentials are used when Basic Authentication is required. The
+ * advantage of using this function over setting the user name and
+ * password seperately is that the cleartext user name and password
+ * are not kept in memory longer than needed.
+ *
+ * @param c The connection structure.
+ * @param username The user name.
+ * @param passwd The password.
+ */
+void cddb_set_http_proxy_credentials(cddb_conn_t* c,
+ const char *username, const char* passwd);
+
+/**
+ * Get the error number returned by the last libcddb command.
+ *
+ * @param c The CDDB connection structure.
+ * @return The error number.
+ */
+cddb_error_t cddb_errno(const cddb_conn_t *c);
+
+/**
+ * Set the name and version of the client program overwriting the
+ * previous values. This function will make a copy of the provided
+ * strings. The defaults are 'libcddb' and the version number of the
+ * libcddb library in use. Both parameters must be valid strings. If
+ * any of teh strings is NULL, this fucntion will return without
+ * changing anything.
+ *
+ * @param c The connection structure.
+ * @param cname The name of the client program.
+ * @param cversion The version number of the client program.
+ */
+void cddb_set_client(cddb_conn_t *c, const char *cname, const char *cversion);
+
+/**
+ * Sets the user name and host name of the local machine. This
+ * function will parse out the user name and host name from the e-mail
+ * address.
+ *
+ * @param c The connection structure.
+ * @param email The e-mail address of the user.
+ */
+int cddb_set_email_address(cddb_conn_t *c, const char *email);
+
+/**
+ * Returns the current cache mode. This can be either on, off or
+ * cache only.
+ *
+ * @see CACHE_ON
+ * @see CACHE_ONLY
+ * @see CACHE_OFF
+ * @see cddb_cache_enable
+ * @see cddb_cache_only
+ * @see cddb_cache_disable
+ *
+ * @param c The connection structure.
+ */
+cddb_cache_mode_t cddb_cache_mode(const cddb_conn_t *c);
+
+/**
+ * Enable caching of CDDB entries locally. Caching is enabled by
+ * default. The cache directory can be changed with the
+ * cddb_cache_set_dir function.
+ *
+ * @see cddb_cache_mode
+ * @see cddb_cache_disable
+ * @see cddb_cache_only
+ *
+ * @param c The connection structure.
+ */
+void cddb_cache_enable(cddb_conn_t *c);
+
+/**
+ * Only use the local CDDB cache. Never contact a server to retrieve
+ * any data. The cache directory can be changed with the
+ * cddb_cache_set_dir function.
+ *
+ * @see cddb_cache_mode
+ * @see cddb_cache_enable
+ * @see cddb_cache_disable
+ *
+ * @param c The connection structure.
+ */
+void cddb_cache_only(cddb_conn_t *c);
+
+/**
+ * Disable caching of CDDB entries locally. All data will be fetched
+ * from a CDDB server everytime and the retrieved data will not be
+ * cached locally.
+ *
+ * @see cddb_cache_mode
+ * @see cddb_cache_enable
+ * @see cddb_cache_only
+ *
+ * @param c The connection structure.
+ */
+void cddb_cache_disable(cddb_conn_t *c);
+
+/**
+ * Return the directory currently being used for caching.
+ *
+ * @see cddb_cache_set_dir
+ *
+ * @param c The connection structure.
+ * @return The directory being used for caching.
+ */
+const char *cddb_cache_get_dir(const cddb_conn_t *c);
+
+/**
+ * Change the directory used for caching CDDB entries locally. The
+ * default location of the cached entries is a subdirectory
+ * (.cddbslave) of the user's home directory. If the first character
+ * of the directory is '~', then it will be expanded to the contents
+ * of $HOME.
+ *
+ * @see cddb_cache_get_dir
+ *
+ * @param c The connection structure.
+ * @param dir The directory to use for caching.
+ */
+int cddb_cache_set_dir(cddb_conn_t *c, const char *dir);
+
+/**
+ * Retrieve the first CDDB mirror site.
+ *
+ * @param c The connection structure.
+ * @return The first mirror site or NULL if not found.
+ */
+const cddb_site_t *cddb_first_site(cddb_conn_t *c);
+
+/**
+ * Retrieve the next CDDB mirror site.
+ *
+ * @param c The connection structure.
+ * @return The next mirror site or NULL if not found.
+ */
+const cddb_site_t *cddb_next_site(cddb_conn_t *c);
+
+/**
+ * Set the bit-string specifying which fields to examine when
+ * performing a text search. By default only the artist and disc
+ * title fields are searched.
+ *
+ * @param c The connection structure.
+ * @param fields A bitwise ORed set of values from #cddb_search_t.
+ */
+void cddb_search_set_fields(cddb_conn_t *c, unsigned int fields);
+
+/**
+ * Set the bit-string specifying which categories to examine when
+ * performing a text search. The #SEARCHCAT macro needs to be used to
+ * build the actual bit-string from individual categories. The
+ * #cddb_search_t values #SEARCH_NONE and #SEARCH_ALL are also valid.
+ * The example below shows some possible combinations. By default all
+ * categories are searched.
+ *
+ * @code
+ * unsigned int cats = SEARCHCAT(CDDB_CAT_ROCK) | SEARCHCAT(CDDB_CAT_MISC);
+ * unsigned int cats = SEARCH_ALL;
+ * unsigned int cats = SEARCH_NONE;
+ * @endcode
+ *
+ * @param c The connection structure.
+ * @param cats A bitwise ORed set of values from #SEARCHCAT(#cddb_cat_t).
+ */
+void cddb_search_set_categories(cddb_conn_t *c, unsigned int cats);
+
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* CDDB_CONN_H */
diff --git a/lib-x86-32/include/cddb/cddb_conn_ni.h b/lib-x86-32/include/cddb/cddb_conn_ni.h
new file mode 100644
index 00000000..6eddbdcf
--- /dev/null
+++ b/lib-x86-32/include/cddb/cddb_conn_ni.h
@@ -0,0 +1,178 @@
+/*
+ $Id: cddb_conn_ni.h,v 1.14 2005/08/03 18:27:19 airborne Exp $
+
+ Copyright (C) 2003, 2004, 2005 Kris Verbeeck <airborne@advalvas.be>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef CDDB_CONN_NI_H
+#define CDDB_CONN_NI_H 1
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+#include "cddb_ni.h"
+#include "ll.h"
+
+
+/* --- type definitions */
+
+
+/** Actual definition of iconv structure. */
+struct cddb_iconv_s
+{
+ iconv_t cd_to_freedb; /**< character set conversion descriptor for
+ converting from user to FreeDB format */
+ iconv_t cd_from_freedb; /**< character set conversion descriptor for
+ converting from FreeDB to user format */
+};
+
+/** Actual definition of serach parameters structure. */
+typedef struct cddb_search_params_s
+{
+ unsigned int fields; /**< fields to search (cddb_search_t
+ bit string) */
+ unsigned int cats; /**< categories to search (cddb_cat_t
+ bit string) */
+} cddb_search_params_t;
+
+/** Actual definition of connection structure. */
+struct cddb_conn_s
+{
+ unsigned int buf_size; /**< maximum line/buffer size, defaults to 1024
+ (see DEFAULT_BUF_SIZE) */
+ char *line; /**< last line read */
+
+ int is_connected; /**< are we already connected to the server? */
+ struct sockaddr_in sa; /**< the socket address structure for
+ connecting to the CDDB server */
+ int socket; /**< the socket file descriptor */
+ char *server_name; /**< host name of the CDDB server, defaults
+ to 'freedb.org' (see DEFAULT_SERVER) */
+ int server_port; /**< port of the CDDB server, defaults to 888
+ (see DEFAULT_PORT) */
+ int timeout; /**< time out interval (in seconds) used during
+ network operations, defaults to 10 seconds
+ (see DEFAULT_TIMEOUT) */
+
+ char *http_path_query; /**< URL for querying the server through HTTP,
+ defaults to /~cddb/cddb.cgi'
+ (see DEFAULT_PATH_QUERY) */
+ char *http_path_submit; /**< URL for submitting to the server through HTTP,
+ defaults to /~cddb/submit.cgi'
+ (see DEFAULT_PATH_SUBMIT) */
+ int is_http_enabled; /**< use HTTP, disabled by default */
+
+ int is_http_proxy_enabled; /**< use HTTP through a proxy server,
+ disabled by default */
+ char *http_proxy_server; /**< host name of the HTTP proxy server */
+ int http_proxy_server_port; /**< port of the HTTP proxy server,
+ defaults to 8080 (see DEFAULT_PROXY_PORT) */
+ char *http_proxy_username; /**< HTTP proxy user name */
+ char *http_proxy_password; /**< HTTP proxy password */
+ char *http_proxy_auth; /**< Base64 encoded username:password */
+
+ FILE *cache_fp; /**< a file pointer to a cached CDDB entry or
+ NULL if no cached version is available */
+ cddb_cache_mode_t use_cache;/**< field to specify local CDDB cache behaviour,
+ enabled by default (CACHE_ON) */
+ char *cache_dir; /**< CDDB slave cache, defaults to
+ '~/.cddbslave' (see DEFAULT_CACHE) */
+ int cache_read; /**< read data from cached file instead of
+ from the network */
+
+ char *cname; /**< name of the client program, 'libcddb' by
+ default */
+ char *cversion; /**< version of the client program, current
+ libcddb version by default */
+ char *user; /**< user name supplied to CDDB server, defaults
+ to the value of the 'USER' environment
+ variable or 'anonymous' if undefined */
+ char *hostname; /**< host name of the local machine, defaults
+ to the value of the 'HOSTNAME' environment
+ variable or 'localhost' if undefined */
+
+ cddb_error_t errnum; /**< error number of last CDDB command */
+
+ list_t *query_data; /**< list to keep CDDB query results */
+ list_t *sites_data; /**< list to keep FreeDB mirror sites */
+ cddb_search_params_t srch; /**< parameters for text search */
+
+ cddb_iconv_t charset; /**< character set conversion settings */
+};
+
+
+/* --- getters & setters --- */
+
+
+#define cddb_cache_file(c) (c)->cache_fp
+
+
+/* --- connecting / disconnecting --- */
+
+
+int cddb_connect(cddb_conn_t *c);
+
+void cddb_disconnect(cddb_conn_t *c);
+
+
+/* --- miscellaneous --- */
+
+
+/**
+ * Clone proxy settings from source connection to destinaton
+ * connection.
+ */
+void cddb_clone_proxy(cddb_conn_t *dst, cddb_conn_t *src);
+
+
+/* --- error handling --- */
+
+
+/**
+ * Set the error number for the last libcddb command.
+ *
+ * @param c The CDDB connection structure.
+ * @param n The error number
+ */
+#define cddb_errno_set(c, n) (c)->errnum = n
+
+/**
+ * Set the error number for the last libcddb command. If this number
+ * is different from CDDB_ERR_OK, a message is also logged with the
+ * level specified.
+ *
+ * @param c The CDDB connection structure.
+ * @param n The error number
+ * @param l The log level
+ */
+#define cddb_errno_log(c, n, l) cddb_errno_set(c, n); cddb_log(l, cddb_error_str(n))
+
+#define cddb_errno_log_debug(c, n) cddb_errno_log(c, n, CDDB_LOG_DEBUG)
+#define cddb_errno_log_info(c, n) cddb_errno_log(c, n, CDDB_LOG_INFO)
+#define cddb_errno_log_warn(c, n) cddb_errno_log(c, n, CDDB_LOG_WARN)
+#define cddb_errno_log_error(c, n) cddb_errno_log(c, n, CDDB_LOG_ERROR)
+#define cddb_errno_log_crit(c, n) cddb_errno_log(c, n, CDDB_LOG_CRITICAL)
+
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* CDDB_CONN_NI_H */
diff --git a/lib-x86-32/include/cddb/cddb_disc.h b/lib-x86-32/include/cddb/cddb_disc.h
new file mode 100644
index 00000000..7951ae96
--- /dev/null
+++ b/lib-x86-32/include/cddb/cddb_disc.h
@@ -0,0 +1,450 @@
+/*
+ $Id: cddb_disc.h,v 1.22 2007/08/07 03:12:53 jcaratzas Exp $
+
+ Copyright (C) 2003, 2004, 2005 Kris Verbeeck <airborne@advalvas.be>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef CDDB_DISC_H
+#define CDDB_DISC_H 1
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+#include <cddb/cddb_track.h>
+
+
+/**
+ * The number of frames that fit into one second.
+ */
+#define FRAMES_PER_SECOND 75
+
+/**
+ * This macro converts an amount of frames into an amount of seconds.
+ */
+#define FRAMES_TO_SECONDS(f) ((f) / FRAMES_PER_SECOND)
+
+/**
+ * This macro converts an amount of seconds into an amount of frames.
+ */
+#define SECONDS_TO_FRAMES(s) ((s) * FRAMES_PER_SECOND)
+
+/**
+ * The different CDDB categories.
+ */
+typedef enum {
+ CDDB_CAT_DATA = 0, /**< data disc */
+ CDDB_CAT_FOLK, /**< folk music */
+ CDDB_CAT_JAZZ, /**< jazz music */
+ CDDB_CAT_MISC, /**< miscellaneous, use if no other
+ category matches */
+ CDDB_CAT_ROCK, /**< rock and pop music */
+ CDDB_CAT_COUNTRY, /**< country music */
+ CDDB_CAT_BLUES, /**< blues music */
+ CDDB_CAT_NEWAGE, /**< new age music */
+ CDDB_CAT_REGGAE, /**< reggae music */
+ CDDB_CAT_CLASSICAL, /**< classical music */
+ CDDB_CAT_SOUNDTRACK, /**< soundtracks */
+ CDDB_CAT_INVALID, /**< (internal) invalid category */
+ CDDB_CAT_LAST /**< (internal) category counter */
+} cddb_cat_t;
+
+/**
+ * String values for the CDDB categories.
+ */
+extern const char *CDDB_CATEGORY[CDDB_CAT_LAST];
+
+/**
+ * The CDDB disc structure. Contains all information associated with
+ * a full CD.
+ */
+typedef struct cddb_disc_s cddb_disc_t;
+
+
+/* --- construction / destruction */
+
+
+/**
+ * Creates a new CDDB disc structure.
+ *
+ * @return The CDDB disc structure or NULL if memory allocation failed.
+ */
+cddb_disc_t *cddb_disc_new(void);
+
+/**
+ * Free all resources associated with the given CDDB disc structure.
+ * The tracks will also be freed automatically.
+ *
+ * @param disc The CDDB disc structure.
+ */
+void cddb_disc_destroy(cddb_disc_t *disc);
+
+/**
+ * Creates a clone of the given disc.
+ *
+ * @param disc The CDDB disc structure.
+ */
+cddb_disc_t *cddb_disc_clone(const cddb_disc_t *disc);
+
+
+/* --- track manipulation */
+
+
+/**
+ * Add a new track to a disc. The track is added to the end of the
+ * existing list of tracks.
+ *
+ * @param disc The CDDB disc structure.
+ * @param track The CDDB track structure.
+ */
+void cddb_disc_add_track(cddb_disc_t *disc, cddb_track_t *track);
+
+/**
+ * Retrieves a numbered track from the disc. If there is no track
+ * with the given number, then NULL will be returned.
+ *
+ * @param disc The CDDB disc structure.
+ * @param track_no The track number; starting at 0.
+ */
+cddb_track_t *cddb_disc_get_track(const cddb_disc_t *disc, int track_no);
+
+/**
+ * Returns the first track of the disc. If there is no such track
+ * then NULL will be returned. The internal track iterator will also
+ * be reset. This function should be called before the first call to
+ * cddb_disc_get_track_next.
+ *
+ * @see cddb_disc_get_track_next
+ *
+ * @param disc The CDDB disc structure.
+ */
+cddb_track_t *cddb_disc_get_track_first(cddb_disc_t *disc);
+
+/**
+ * Returns the next track on the disc and advances the internal track
+ * iterator. If there is no such track then NULL will be returned.
+ * This function should be called after calling
+ * cddb_disc_get_track_first.
+ *
+ * @see cddb_disc_get_track_first
+ *
+ * @param disc The CDDB disc structure.
+ */
+cddb_track_t *cddb_disc_get_track_next(cddb_disc_t *disc);
+
+
+/* --- setters / getters --- */
+
+
+/**
+ * Get the ID of the disc. If the disc is invalid or the disc ID is
+ * not yet initialized 0 will be returned.
+ *
+ * @param disc The CDDB disc structure.
+ */
+unsigned int cddb_disc_get_discid(const cddb_disc_t *disc);
+
+/**
+ * Set the ID of the disc. When the disc ID is not known yet, then it
+ * can be calculated with the cddb_disc_calc_discid function (which
+ * will automatically initialize the correct field in the disc
+ * structure).
+ *
+ * @see cddb_disc_calc_discid
+ *
+ * @param disc The CDDB disc structure.
+ * @param id The disc ID.
+ */
+void cddb_disc_set_discid(cddb_disc_t *disc, unsigned int id);
+
+/**
+ * Get the disc CDDB category ID. If the disc is invalid or no
+ * category is set then CDDB_CAT_INVALID will be returned. If you
+ * want a string representation of the category use the
+ * cddb_disc_get_category_str function.
+ *
+ * @see cddb_disc_set_category
+ * @see cddb_disc_get_category_str
+ * @see cddb_disc_set_category_str
+ * @see cddb_cat_t
+ * @see CDDB_CATEGORY
+ *
+ * @param disc The CDDB disc structure.
+ * @return The CDDB category ID.
+ */
+cddb_cat_t cddb_disc_get_category(const cddb_disc_t *disc);
+
+/**
+ * Set the disc CDDB category ID.
+ *
+ * @see cddb_disc_get_category
+ * @see cddb_disc_get_category_str
+ * @see cddb_disc_set_category_str
+ * @see cddb_cat_t
+ * @see CDDB_CATEGORY
+ *
+ * @param disc The CDDB disc structure.
+ * @param cat The CDDB category ID.
+ */
+void cddb_disc_set_category(cddb_disc_t *disc, cddb_cat_t cat);
+
+/**
+ * Get the disc CDDB category as a string. If no category is set for
+ * this disc then 'invalid' will be returned. If the disc structure
+ * is invalid NULL is returned. If you only want the ID of the
+ * category use the cddb_disc_get_category function.
+ *
+ * @see cddb_disc_get_category
+ * @see cddb_disc_set_category
+ * @see cddb_disc_set_category_str
+ *
+ * @param disc The CDDB disc structure.
+ * @return The CDDB category ID.
+ */
+const char *cddb_disc_get_category_str(cddb_disc_t *disc);
+
+/**
+ * Sets the category of the disc. If the specified category is
+ * an invalid CDDB category, then CDDB_CAT_MISC will be used.
+ *
+ * @see cddb_disc_get_category
+ * @see cddb_disc_set_category
+ * @see cddb_disc_get_category_str
+ * @see CDDB_CATEGORY
+ *
+ * @param disc The CDDB disc structure.
+ * @param cat The category string.
+ */
+void cddb_disc_set_category_str(cddb_disc_t *disc, const char *cat);
+
+/**
+ * Get the disc genre. If no genre is set for this disc then NULL
+ * will be returned. As opposed to the disc category, this field is
+ * not limited to a predefined set.
+ *
+ * @param disc The CDDB disc structure.
+ * @return The disc genre.
+ */
+const char *cddb_disc_get_genre(const cddb_disc_t *disc);
+
+/**
+ * Set the disc genre. As opposed to the disc category, this field is
+ * not limited to a predefined set. If the disc already had a genre,
+ * then the memory for that string will be freed. The new genre will
+ * be copied into a new chunk of memory.
+ *
+ * @see cddb_disc_get_category_str
+ *
+ * @param disc The CDDB disc structure.
+ * @param genre The disc genre.
+ */
+void cddb_disc_set_genre(cddb_disc_t *disc, const char *genre);
+
+/**
+ * Get the disc length. If no length is set for this disc then 0 will
+ * be returned.
+ *
+ * @param disc The CDDB disc structure.
+ * @return The disc length in seconds.
+ */
+unsigned int cddb_disc_get_length(const cddb_disc_t *disc);
+
+/**
+ * Set the disc length.
+ *
+ * @param disc The CDDB disc structure.
+ * @param l The disc length in seconds.
+ */
+void cddb_disc_set_length(cddb_disc_t *disc, unsigned int l);
+
+/**
+ * Get the revision number of the disc.
+ *
+ * @param disc The CDDB disc structure.
+ */
+unsigned int cddb_disc_get_revision(const cddb_disc_t *disc);
+
+/**
+ * Set the revision number of the disc.
+ *
+ * @param disc The CDDB disc structure.
+ * @param rev The revision number.
+ */
+void cddb_disc_set_revision(cddb_disc_t *disc, unsigned int rev);
+
+/**
+ * Get the year of publication for this disc. If no year is defined 0
+ * is returned.
+ *
+ * @param disc The CDDB disc structure.
+ * @return The disc year.
+ */
+unsigned int cddb_disc_get_year(const cddb_disc_t *disc);
+
+/**
+ * Set the year of publication for this disc.
+ *
+ * @param disc The CDDB disc structure.
+ * @param y The disc year.
+ */
+void cddb_disc_set_year(cddb_disc_t *disc, unsigned int y);
+
+/**
+ * Get the number of tracks on the disc. If the disc is invalid -1 is
+ * returned.
+ *
+ * @param disc The CDDB disc structure.
+ * @return The number of tracks.
+ */
+int cddb_disc_get_track_count(const cddb_disc_t *disc);
+
+/**
+ * Get the disc title. If the disc is invalid or no title is set then
+ * NULL will be returned.
+ *
+ * @param disc The CDDB disc structure.
+ * @return The disc title.
+ */
+const char *cddb_disc_get_title(const cddb_disc_t *disc);
+
+/**
+ * Set the disc title. If the disc already had a title, then the
+ * memory for that string will be freed. The new title will be copied
+ * into a new chunk of memory. If the given title is NULL, then the
+ * title of the disc will be deleted.
+ *
+ * @param disc The CDDB disc structure.
+ * @param title The new disc title.
+ */
+void cddb_disc_set_title(cddb_disc_t *disc, const char *title);
+
+/**
+ * Append to the disc title. If the disc does not have a title yet,
+ * then a new one will be created from the given string, otherwise
+ * that string will be appended to the existing title.
+ *
+ * @param disc The CDDB disc structure.
+ * @param title Part of the disc title.
+ */
+void cddb_disc_append_title(cddb_disc_t *disc, const char *title);
+
+/**
+ * Get the disc artist name. If the disc is invalid or no artist is
+ * set then NULL will be returned.
+ *
+ * @param disc The CDDB disc structure.
+ * @return The disc artist name.
+ */
+const char *cddb_disc_get_artist(const cddb_disc_t *disc);
+
+/**
+ * Set the disc artist name. If the disc already had an artist name,
+ * then the memory for that string will be freed. The new artist name
+ * will be copied into a new chunk of memory. If the given artist
+ * name is NULL, then the artist name of the disc will be deleted.
+ *
+ * @param disc The CDDB disc structure.
+ * @param artist The new disc artist name.
+ */
+void cddb_disc_set_artist(cddb_disc_t *disc, const char *artist);
+
+/**
+ * Append to the disc artist. If the disc does not have an artist
+ * yet, then a new one will be created from the given string,
+ * otherwise that string will be appended to the existing artist.
+ *
+ * @param disc The CDDB disc structure.
+ * @param artist Part of the artist name.
+ */
+void cddb_disc_append_artist(cddb_disc_t *disc, const char *artist);
+
+/**
+ * Get the extended disc data. If the disc is invalid or no extended
+ * data is set then NULL will be returned.
+ *
+ * @param disc The CDDB disc structure.
+ * @return The extended data.
+ */
+const char *cddb_disc_get_ext_data(const cddb_disc_t *disc);
+
+/**
+ * Set the extended data for the disc. If the disc already had
+ * extended data, then the memory for that string will be freed. The
+ * new extended data will be copied into a new chunk of memory. If
+ * the given extended data is NULL, then the existing data will be
+ * deleted.
+ *
+ * @param disc The CDDB disc structure.
+ * @param ext_data The new extended data.
+ */
+void cddb_disc_set_ext_data(cddb_disc_t *disc, const char *ext_data);
+
+/**
+ * Append to the extended disc data. If the disc does not have an
+ * extended data section yet, then a new one will be created from the
+ * given string, otherwise that string will be appended to the
+ * existing data.
+ *
+ * @param disc The CDDB disc structure.
+ * @param ext_data Part of the extended disc data.
+ */
+void cddb_disc_append_ext_data(cddb_disc_t *disc, const char *ext_data);
+
+
+/* --- miscellaneous */
+
+
+/**
+ * Copy all data from one disc to another. Any fields that are
+ * unavailable in the source disc structure will not result in a reset
+ * of the same field in the destination disc structure; e.g. if there
+ * is no title in the source disc, but there is one in the destination
+ * disc, then the destination's title will remain unchanged.
+ *
+ * @param dst The destination CDDB disc structure.
+ * @param src The source CDDB disc structure.
+ */
+void cddb_disc_copy(cddb_disc_t *dst, cddb_disc_t *src);
+
+/**
+ * Calculate the CDDB disc ID. To calculate a disc ID the provided
+ * disc needs to have its length set, and every track in the disc
+ * structure needs to have its frame offset initialized. The disc ID
+ * field will be set in the disc structure.
+ *
+ * @param disc The CDDB disc structure.
+ * @return A non-zero value if the calculation succeeded, zero
+ * otherwise.
+ */
+int cddb_disc_calc_discid(cddb_disc_t *disc);
+
+/**
+ * Prints information about the disc on stdout. This is just a
+ * debugging routine to display the structure's content.
+ *
+ * @param disc The CDDB disc structure.
+ */
+void cddb_disc_print(cddb_disc_t *disc);
+
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* CDDB_DISC_H */
diff --git a/lib-x86-32/include/cddb/cddb_error.h b/lib-x86-32/include/cddb/cddb_error.h
new file mode 100644
index 00000000..6e779900
--- /dev/null
+++ b/lib-x86-32/include/cddb/cddb_error.h
@@ -0,0 +1,118 @@
+/*
+ $Id: cddb_error.h,v 1.12 2005/05/29 08:11:04 airborne Exp $
+
+ Copyright (C) 2003, 2004, 2005 Kris Verbeeck <airborne@advalvas.be>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef CDDB_ERROR_H
+#define CDDB_ERROR_H 1
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+#include <stdio.h>
+
+
+/**
+ * A list of error codes returned by various libcddb functions.
+ */
+typedef enum {
+
+ CDDB_ERR_OK = 0, /**< no error occurred */
+
+ /* --- general errors --- */
+
+ CDDB_ERR_OUT_OF_MEMORY, /**< out of memory */
+ CDDB_ERR_LINE_SIZE, /**< internal buffer too small */
+ CDDB_ERR_NOT_IMPLEMENTED, /**< feature not (yet) implemented */
+ CDDB_ERR_UNKNOWN, /**< problem unknown */
+
+ /* --- connection errors --- */
+
+ CDDB_ERR_SERVER_ERROR, /**< CDDB server error */
+ CDDB_ERR_UNKNOWN_HOST_NAME, /**< unknown host name */
+ CDDB_ERR_CONNECT, /**< connection error */
+ CDDB_ERR_PERMISSION_DENIED, /**< permission denied */
+ CDDB_ERR_NOT_CONNECTED, /**< not yet connected or connection
+ has been closed */
+
+ /* --- response parsing errors --- */
+
+ CDDB_ERR_UNEXPECTED_EOF, /**< unexpected end-of-file encountered */
+ CDDB_ERR_INVALID_RESPONSE, /**< invalid response data */
+ CDDB_ERR_DISC_NOT_FOUND, /**< no results found */
+
+ /* --- library errors --- */
+
+ CDDB_ERR_DATA_MISSING, /**< some data is missing for executing
+ a certain command */
+ CDDB_ERR_TRACK_NOT_FOUND, /**< specified track is not present */
+ CDDB_ERR_REJECTED, /**< posted data rejected */
+ CDDB_ERR_EMAIL_INVALID, /**< the e-mail address used when
+ submitting is invalid */
+
+ CDDB_ERR_INVALID_CHARSET, /**< invalid character set or unsupported
+ conversion */
+ CDDB_ERR_ICONV_FAIL, /**< character set conversion failed */
+
+ /* --- new errors added to back of list for backward compatibility --- */
+
+ CDDB_ERR_PROXY_AUTH, /**< proxy authentication failed */
+ CDDB_ERR_INVALID, /**< invalid input parameter(s) */
+
+ /* --- terminator --- */
+
+ CDDB_ERR_LAST
+} cddb_error_t;
+
+
+/* --- error handling --- */
+
+
+/**
+ * Returns a string representation of the CDDB error code.
+ *
+ * @return The error string
+ */
+const char *cddb_error_str(cddb_error_t errnum);
+
+/**
+ * Prints the error message associated with the current error number
+ * on the given stream.
+ *
+ * @param stream The stream
+ * @param errnum The error number
+ */
+void cddb_error_stream_print(FILE *stream, cddb_error_t errnum);
+
+/**
+ * Prints the error message associated with the current error number
+ * to stderr.
+ *
+ * @param errnum The error number
+ */
+void cddb_error_print(cddb_error_t errnum);
+
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* CDDB_ERROR_H */
diff --git a/lib-x86-32/include/cddb/cddb_log.h b/lib-x86-32/include/cddb/cddb_log.h
new file mode 100644
index 00000000..30fe7899
--- /dev/null
+++ b/lib-x86-32/include/cddb/cddb_log.h
@@ -0,0 +1,87 @@
+/*
+ $Id: cddb_log.h,v 1.4 2005/03/11 21:29:29 airborne Exp $
+
+ Copyright (C) 2003, 2004, 2005 Kris Verbeeck <airborne@advalvas.be>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef CDDB_LOH_H
+#define CDDB_LOG_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/**
+ * The different log levels supported by libcddb.
+ */
+typedef enum {
+ CDDB_LOG_DEBUG = 1, /**< Debug-level messages. */
+ CDDB_LOG_INFO, /**< Informational. */
+ CDDB_LOG_WARN, /**< Warning conditions. */
+ CDDB_LOG_ERROR, /**< Error conditions. */
+ CDDB_LOG_CRITICAL, /**< Critical conditions. */
+ CDDB_LOG_NONE = 99 /**< No log messages. */
+} cddb_log_level_t;
+
+
+/**
+ * This type defines the signature of a libcddb log handler. For
+ * every message being logged by libcddb, the handler will receive the
+ * log level and the message string.
+ *
+ * @see cddb_log_set_handler
+ * @see cddb_log_level_t
+ *
+ * @param level The log level.
+ * @param message The log message.
+ */
+typedef void (*cddb_log_handler_t)(cddb_log_level_t level, const char *message);
+
+/**
+ * Set a custom log handler for libcddb. The return value is the log
+ * handler being replaced. If the provided parameter is NULL, then
+ * the handler will be reset to the default handler.
+ *
+ * @see cddb_log_handler_t
+ *
+ * @param new_handler The new log handler.
+ * @return The previous log handler.
+ */
+cddb_log_handler_t cddb_log_set_handler(cddb_log_handler_t new_handler);
+
+/**
+ * Set the minimum log level. This function is only useful in
+ * conjunction with the default log handler. The default log handler
+ * will print any log messages that have a log level equal or higher
+ * than this minimum log level to stderr. By default the minimum log
+ * level is set to CDDB_LOG_WARN. This means that only warning, error
+ * and critical messages will be printed. You can silence the default
+ * log handler by setting the minimum log level to CDDB_LOG_NONE.
+ *
+ * @see cddb_log_level_t
+ *
+ * @param level The minimum log level.
+ */
+void cddb_log_set_level(cddb_log_level_t level);
+
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* CDDB_LOG_H */
diff --git a/lib-x86-32/include/cddb/cddb_log_ni.h b/lib-x86-32/include/cddb/cddb_log_ni.h
new file mode 100644
index 00000000..ea7727fc
--- /dev/null
+++ b/lib-x86-32/include/cddb/cddb_log_ni.h
@@ -0,0 +1,59 @@
+/*
+ $Id: cddb_log_ni.h,v 1.3 2005/03/11 21:29:29 airborne Exp $
+
+ Copyright (C) 2003, 2004, 2005 Kris Verbeeck <airborne@advalvas.be>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef CDDB_LOH_NI_H
+#define CDDB_LOG_NI_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+/**
+ */
+void cddb_log(cddb_log_level_t level, const char *format, ...);
+
+/**
+ */
+#define cddb_log_debug(...) cddb_log(CDDB_LOG_DEBUG, __VA_ARGS__)
+
+/**
+ */
+#define cddb_log_info(...) cddb_log(CDDB_LOG_INFO, __VA_ARGS__)
+
+/**
+ */
+#define cddb_log_warn(...) cddb_log(CDDB_LOG_WARN, __VA_ARGS__)
+
+/**
+ */
+#define cddb_log_error(...) cddb_log(CDDB_LOG_ERROR, __VA_ARGS__)
+
+/**
+ */
+#define cddb_log_crit(...) cddb_log(CDDB_LOG_CRITICAL, __VA_ARGS__)
+
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* CDDB_LOG_NI_H */
diff --git a/lib-x86-32/include/cddb/cddb_net.h b/lib-x86-32/include/cddb/cddb_net.h
new file mode 100644
index 00000000..60c5464b
--- /dev/null
+++ b/lib-x86-32/include/cddb/cddb_net.h
@@ -0,0 +1,133 @@
+/*
+ $Id: cddb_net.h,v 1.11 2005/03/11 21:29:29 airborne Exp $
+
+ Copyright (C) 2003, 2004, 2005 Kris Verbeeck <airborne@advalvas.be>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef CDDB_NET_H
+#define CDDB_NET_H 1
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+#include <stdarg.h>
+
+#if defined( UNDER_CE )
+# include <winsock.h>
+#elif defined( WIN32 )
+# include <winsock2.h>
+# include <ws2tcpip.h>
+#endif
+
+#include <cddb/cddb_ni.h>
+#include <cddb/cddb_config.h>
+
+#if defined(CDDB_NEED_SYS_SOCKET_H) || defined(HAVE_SYS_SOCKET_H)
+#include <sys/socket.h>
+#endif
+
+
+/* --- socket-based work-alikes --- */
+
+
+/**
+ * This function performs the same task as the standard fgets except
+ * for the fact that it might time-out if the socket read takes too
+ * long. In case of a time out, errno will be set to ETIMEDOUT.
+ *
+ * @param s The string buffer.
+ * @param size Size of the buffer.
+ * @param c The CDDB connection structure.
+ * @return The string that was read or NULL on error or EOF when no
+ * characters were read.
+ */
+char *sock_fgets(char *s, int size, cddb_conn_t *c);
+
+/**
+ * This function performs the same task as the standard fwrite except
+ * for the fact that it might time-out if the socket write takes too
+ * long. In case of a time out, errno will be set to ETIMEDOUT.
+ *
+ * @param ptr Pointer to data record.
+ * @param size Size of data record.
+ * @param nmemb The number of data records to write.
+ * @param c The CDDB connection structure.
+ * @return The number of records written.
+ */
+size_t sock_fwrite(const void *ptr, size_t size, size_t nmemb, cddb_conn_t *c);
+
+/**
+ * This function performs the same task as the standard fprintf except
+ * for the fact that it might time-out if the socket write takes too
+ * long. In case of a time out, errno will be set to ETIMEDOUT.
+ *
+ * @param c The CDDB connection structure.
+ * @param format Pointer to data record.
+ * @return The number of characters written.
+ */
+int sock_fprintf(cddb_conn_t *c, const char *format, ...);
+
+/**
+ * This function performs the same task as the standard vfprintf
+ * except for the fact that it might time-out if the socket write
+ * takes too long. In case of a time out, errno will be set to
+ * ETIMEDOUT.
+ *
+ * @param c The CDDB connection structure.
+ * @param format Pointer to data record.
+ * @param ap Variable argument list.
+ * @return The number of characters written.
+ */
+int sock_vfprintf(cddb_conn_t *c, const char *format, va_list ap);
+
+/* --- time-out enabled work-alikes --- */
+
+/**
+ * This function performs the same task as the standard gethostbyname
+ * except for the fact that it might time-out if the query takes too
+ * long. In case of a time out, errno will be set to ETIMEDOUT.
+ *
+ * @param hostname The hostname that needs to be resolved.
+ * @param timeout Number of seconds after which to time out.
+ * @return The host entity for given host name or NULL if not found or
+ * timed out (errno will be set).
+ */
+struct hostent *timeout_gethostbyname(const char *hostname, int timeout);
+
+/**
+ * This function performs the same task as the standard connect except
+ * for the fact that it might time-out if the connect takes too long.
+ * In case of a time out, errno will be set to ETIMEDOUT.
+ *
+ * @param sockfd The socket.
+ * @param addr The address to connect to.
+ * @param len The size of the address structure.
+ * @param timeout Number of seconds after which to time out.
+ * @return Zero on success, -1 on failure (errno will be set).
+ */
+int timeout_connect(int sockfd, const struct sockaddr *addr, size_t len,
+ int timeout);
+
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* CDDB_NET_H */
diff --git a/lib-x86-32/include/cddb/cddb_ni.h b/lib-x86-32/include/cddb/cddb_ni.h
new file mode 100644
index 00000000..d32fdc13
--- /dev/null
+++ b/lib-x86-32/include/cddb/cddb_ni.h
@@ -0,0 +1,189 @@
+/*
+ $Id: cddb_ni.h,v 1.32 2009/03/01 03:28:07 jcaratzas Exp $
+
+ Copyright (C) 2003, 2004, 2005 Kris Verbeeck <airborne@advalvas.be>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef CDDB_NI_H
+#define CDDB_NI_H 1
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#ifdef HAVE_ICONV_H
+# include <iconv.h>
+#else
+ typedef void *iconv_t; /* for code uniformity */
+#endif
+
+#ifdef HAVE_WINDOWS_H
+#include <windows.h>
+#endif
+
+#ifdef HAVE_WINSOCK2_H
+#include <winsock2.h>
+#ifndef ETIMEDOUT
+#define ETIMEDOUT WSAETIMEDOUT
+#endif
+#ifndef EWOULDBLOCK
+#define EWOULDBLOCK WSAEWOULDBLOCK
+#endif
+#ifndef EINPROGRESS
+#define EINPROGRESS WSAEINPROGRESS
+#endif
+#endif
+
+#include "cddb/cddb_regex.h"
+#include "cddb/cddb.h"
+#include "cddb/cddb_conn_ni.h"
+#include "cddb/cddb_net.h"
+#include "cddb/cddb_cmd_ni.h"
+#include "cddb/cddb_log_ni.h"
+
+
+#define FALSE 0
+#define TRUE 1
+
+#define CHR_CR '\r'
+#define CHR_LF '\n'
+#define CHR_EOS '\0'
+#define CHR_SPACE ' '
+#define CHR_DOT '.'
+
+#define DEFAULT_BUF_SIZE 1024
+
+#define CLIENT_NAME PACKAGE
+#define CLIENT_VERSION VERSION
+
+#define DEFAULT_USER "anonymous"
+#define DEFAULT_HOST "localhost"
+#define DEFAULT_SERVER "freedb.org"
+#define DEFAULT_PORT 888
+#define DEFAULT_TIMEOUT 10
+#define DEFAULT_PATH_QUERY "/~cddb/cddb.cgi"
+#define DEFAULT_PATH_SUBMIT "/~cddb/submit.cgi"
+#define DEFAULT_CACHE ".cddbslave"
+#define DEFAULT_PROXY_PORT 8080
+
+#define DEFAULT_PROTOCOL_VERSION 6
+#define SERVER_CHARSET "UTF8"
+
+
+#define FREE_NOT_NULL(p) if (p) { free(p); p = NULL; }
+#define CONNECTION_OK(c) (c->socket != -1)
+#define STR_OR_NULL(s) ((s) ? s : "NULL")
+#define STR_OR_EMPTY(s) ((s) ? s : "")
+
+#define RETURN_STR_OR_EMPTY(s) \
+ return (!s && (libcddb_flags() & CDDB_F_EMPTY_STR)) ? "" : s
+
+#define ASSERT(cond, error) \
+ if (!(cond)) { return error; }
+#define ASSERT_NOT_NULL(ptr) \
+ ASSERT(ptr!=NULL, CDDB_ERR_INVALID)
+#define ASSERT_RANGE(num,lo,hi) \
+ ASSERT((num>=lo)&&(num<=hi), CDDB_ERR_INVALID)
+
+
+/* --- type definitions */
+
+
+/** Actual definition of track structure. */
+struct cddb_track_s
+{
+ int num; /**< track number on the disc */
+ int frame_offset; /**< frame offset of the track on the disc */
+ int length; /**< track length in seconds */
+ char *title; /**< track title */
+ char *artist; /**< (optional) track artist */
+ char *ext_data; /**< (optional) extended disc data */
+ struct cddb_track_s *prev; /**< pointer to previous track, or NULL */
+ struct cddb_track_s *next; /**< pointer to next track, or NULL */
+ struct cddb_disc_s *disc; /**< disc of which this is a track */
+};
+
+/** Actual definition of disc structure. */
+struct cddb_disc_s
+{
+ unsigned int revision; /**< revision number */
+ unsigned int discid; /**< four byte disc ID */
+ cddb_cat_t category; /**< CDDB category */
+ char *genre; /**< disc genre */
+ char *title; /**< disc title */
+ char *artist; /**< disc artist */
+ unsigned int length; /**< disc length in seconds */
+ unsigned int year; /**< (optional) disc year YYYY */
+ char *ext_data; /**< (optional) extended disc data */
+ int track_cnt; /**< number of tracks on the disc */
+ cddb_track_t *tracks; /**< pointer to the first track */
+ cddb_track_t *iterator; /**< track iterator */
+};
+
+
+/* --- global variables */
+
+
+/** Server connection used especially for text searches. */
+extern cddb_conn_t *cddb_search_conn;
+
+
+/* --- non-exported function prototypes */
+
+
+unsigned int libcddb_flags(void);
+
+/**
+ * Convert a string to a new character encoding according to the given
+ * conversion descriptor.
+ */
+int cddb_str_iconv(iconv_t cd, ICONV_CONST char *in, char **out);
+
+/**
+ * Converts all disc and track strings to user character encoding.
+ */
+int cddb_disc_iconv(iconv_t cd, cddb_disc_t *disc);
+
+/**
+ * Converts all track strings to user character encoding.
+ */
+int cddb_track_iconv(iconv_t cd, cddb_track_t *track);
+
+/**
+ * Converts all site strings to user character encoding.
+ */
+int cddb_site_iconv(iconv_t cd, cddb_site_t *site);
+
+/**
+ * Base64 encode the source string and write it to the destination
+ * buffer. The destination buffer should be large enough (= 4/3 of
+ * src string length).
+ */
+void cddb_b64_encode(char *dst, const char *src);
+
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* CDDB_NI_H */
diff --git a/lib-x86-32/include/cddb/cddb_regex.h b/lib-x86-32/include/cddb/cddb_regex.h
new file mode 100644
index 00000000..9b50e097
--- /dev/null
+++ b/lib-x86-32/include/cddb/cddb_regex.h
@@ -0,0 +1,74 @@
+/*
+ $Id: cddb_regex.h,v 1.14 2007/08/07 03:12:53 jcaratzas Exp $
+
+ Copyright (C) 2003, 2004, 2005 Kris Verbeeck <airborne@advalvas.be>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef CDDB_REGEX_H
+#define CDDB_REGEX_H 1
+
+#ifdef HAVE_REGEX_H
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#include <cddb/cddb_config.h>
+#include <stdlib.h>
+
+#ifdef CDDB_NEED_UNISTD_H
+#include <unistd.h>
+#endif
+#include <sys/types.h> /* need for MacOS X */
+#include <regex.h>
+
+
+extern regex_t *REGEX_TRACK_FRAME_OFFSETS;
+extern regex_t *REGEX_TRACK_FRAME_OFFSET;
+extern regex_t *REGEX_DISC_LENGTH;
+extern regex_t *REGEX_DISC_REVISION;
+extern regex_t *REGEX_DISC_TITLE;
+extern regex_t *REGEX_DISC_YEAR;
+extern regex_t *REGEX_DISC_GENRE;
+extern regex_t *REGEX_DISC_EXT;
+extern regex_t *REGEX_TRACK_TITLE;
+extern regex_t *REGEX_TRACK_EXT;
+extern regex_t *REGEX_PLAY_ORDER;
+extern regex_t *REGEX_QUERY_MATCH;
+extern regex_t *REGEX_SITE;
+extern regex_t *REGEX_TEXT_SEARCH;
+
+
+void cddb_regex_init(void);
+
+void cddb_regex_destroy(void);
+
+int cddb_regex_get_int(const char *s, regmatch_t matches[], int idx);
+
+unsigned long cddb_regex_get_hex(const char *s, regmatch_t matches[], int idx);
+
+double cddb_regex_get_float(const char *s, regmatch_t matches[], int idx);
+
+char *cddb_regex_get_string(const char *s, regmatch_t matches[], int idx);
+
+
+#ifdef __cplusplus
+ }
+#endif
+#endif /* HAVE_REGEX_H */
+
+#endif /* CDDB_REGEX_H */
diff --git a/lib-x86-32/include/cddb/cddb_site.h b/lib-x86-32/include/cddb/cddb_site.h
new file mode 100644
index 00000000..9c48ac6c
--- /dev/null
+++ b/lib-x86-32/include/cddb/cddb_site.h
@@ -0,0 +1,248 @@
+/*
+ $Id: cddb_site.h,v 1.3 2005/06/15 16:08:28 airborne Exp $
+
+ Copyright (C) 2005 Kris Verbeeck <airborne@advalvas.be>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef CDDB_SITE_H
+#define CDDB_SITE_H 1
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+#include "cddb/cddb_error.h"
+
+
+/* --- type and structure definitions */
+
+
+/**
+ * Enumeration defining the CDDB protocol supported by a specific
+ * site.
+ */
+typedef enum {
+ PROTO_UNKNOWN = 0, /**< Unknown protocol */
+ PROTO_CDDBP, /**< FreeDB custom protocol */
+ PROTO_HTTP /**< Command tunneling over HTTP */
+} cddb_protocol_t;
+
+/**
+ * The CDDB site structure. Contains all information about one
+ * particular CDDB server.
+ */
+typedef struct cddb_site_s cddb_site_t;
+
+
+/* --- construction / destruction */
+
+
+/**
+ * Creates a new CDDB site structure.
+ *
+ * @return The CDDB site structure or NULL if memory allocation failed.
+ */
+cddb_site_t *cddb_site_new(void);
+
+/**
+ * Free all resources associated with the given CDDB site structure.
+ *
+ * @param site The CDDB site structure.
+ */
+cddb_error_t cddb_site_destroy(cddb_site_t *site);
+
+/**
+ * Creates a clone of the given site.
+ *
+ * @param site The CDDB site structure.
+ */
+cddb_site_t *cddb_site_clone(cddb_site_t *site);
+
+
+/* --- setters / getters --- */
+
+
+/**
+ * Get the site's address.
+ *
+ * @param site The CDDB site structure.
+ * @param address The address of the server upon returning.
+ * @param port The port of the server upon returning.
+ * @return Error code: CDDB_ERR_OK or CDDB_ERR_INVALID.
+ */
+cddb_error_t cddb_site_get_address(const cddb_site_t *site,
+ const char **address, unsigned int *port);
+
+/**
+ * Set the site's address. A copy of the address string is made. So the caller
+ * should free any memory associated with the input parameter.
+ *
+ * @param site The CDDB site structure.
+ * @param address The address of the server.
+ * @param port The port of the server.
+ * @return Error code: CDDB_ERR_OK, CDDB_ERR_INVALID or CDDB_ERR_OUT_OF_MEMORY.
+ */
+cddb_error_t cddb_site_set_address(cddb_site_t *site,
+ const char *address, unsigned int port);
+
+/**
+ * Get the protocol used by the site.
+ *
+ * @see cddb_protocol_t
+ *
+ * @param site The CDDB site structure.
+ * @return The protocol.
+ */
+cddb_protocol_t cddb_site_get_protocol(const cddb_site_t *site);
+
+/**
+ * Set the protocol used by the site.
+ *
+ * @see cddb_protocol_t
+ *
+ * @param site The CDDB site structure.
+ * @param proto The protocol.
+ * @return Error code: CDDB_ERR_OK or CDDB_ERR_INVALID.
+ */
+cddb_error_t cddb_site_set_protocol(cddb_site_t *site, cddb_protocol_t proto);
+
+/**
+ * Get the query path in case the HTTP protocol is used.
+ *
+ * @param site The CDDB site structure.
+ * @param path The query path upon returning.
+ * @return Error code: CDDB_ERR_OK or CDDB_ERR_INVALID.
+ */
+cddb_error_t cddb_site_get_query_path(const cddb_site_t *site,
+ const char **path);
+
+/**
+ * Set the query path in case the HTTP protocol is used. A copy of the path
+ * string is made. So the caller should free any memory associated with the
+ * input parameter.
+ *
+ * @param site The CDDB site structure.
+ * @param path The query path. A value of NULL deletes the current path.
+ * @return Error code: CDDB_ERR_OK, CDDB_ERR_INVALID or CDDB_ERR_OUT_OF_MEMORY.
+ */
+cddb_error_t cddb_site_set_query_path(cddb_site_t *site, const char *path);
+
+/**
+ * Get the submit path in case the HTTP protocol is used.
+ *
+ * @param site The CDDB site structure.
+ * @param path The submit path upon returning.
+ * @return Error code: CDDB_ERR_OK or CDDB_ERR_INVALID.
+ */
+cddb_error_t cddb_site_get_submit_path(const cddb_site_t *site,
+ const char **path);
+
+/**
+ * Set the submit path in case the HTTP protocol is used. A copy of the path
+ * string is made. So the caller should free any memory associated with the
+ * input parameter.
+ *
+ * @param site The CDDB site structure.
+ * @param path The query path. A value of NULL deletes the current path.
+ * @return Error code: CDDB_ERR_OK, CDDB_ERR_INVALID or CDDB_ERR_OUT_OF_MEMORY.
+ */
+cddb_error_t cddb_site_set_submit_path(cddb_site_t *site, const char *path);
+
+/**
+ * Get the site's location.
+ *
+ * @param site The CDDB site structure.
+ * @param latitude Will contain the server's latitude upon returning.
+ * A positive number is used for the northern
+ * hemisphere, a negative one for the southern
+ * hemisphere.
+ * @param longitude Will contain the server's longitude upon returning.
+ * A positive number is used for the eastern
+ * hemisphere, a negative one for the western
+ * hemisphere.
+ * @return Error code: CDDB_ERR_OK or CDDB_ERR_INVALID.
+ */
+cddb_error_t cddb_site_get_location(const cddb_site_t *site,
+ float *latitude, float *longitude);
+
+/**
+ * Set the site's location.
+ *
+ * @param site The CDDB site structure.
+ * @param latitude The server's latitude. Use a positive number for the
+ * northern hemisphere, a negative one for the southern
+ * hemisphere.
+ * @param longitude The server's longitude. Use a positive number for the
+ * eastern hemisphere, a negative one for the western
+ * hemisphere.
+ * @return Error code: CDDB_ERR_OK or CDDB_ERR_INVALID.
+ */
+cddb_error_t cddb_site_set_location(cddb_site_t *site,
+ float latitude, float longitude);
+
+/**
+ * Get a description of the site.
+ *
+ * @param site The CDDB site structure.
+ * @param desc The description upon returning.
+ * @return Error code: CDDB_ERR_OK or CDDB_ERR_INVALID.
+ */
+cddb_error_t cddb_site_get_description(const cddb_site_t *site,
+ const char **desc);
+
+/**
+ * Set a description for the site. A copy of the description string is made.
+ * So the caller should free any memory associated with the input parameter.
+ *
+ * @param site The CDDB site structure.
+ * @param desc The description. A value of NULL deletes the current
+ * description.
+ * @return Error code: CDDB_ERR_OK, CDDB_ERR_INVALID or CDDB_ERR_OUT_OF_MEMORY.
+ */
+cddb_error_t cddb_site_set_description(cddb_site_t *site, const char *desc);
+
+
+/* --- miscellaneous */
+
+
+/**
+ * Parses one line of data as returned by the sites command and
+ * populates the given structure.
+ *
+ * @param site The CDDB site structure.
+ * @param line The result line.
+ * @return True in case of success or false on failure.
+ */
+int cddb_site_parse(cddb_site_t *site, const char *line);
+
+/**
+ * Prints information about the site on stdout. This is just a
+ * debugging routine to display the structure's content.
+ *
+ * @param site The CDDB site structure.
+ * @return Error code: CDDB_ERR_OK or CDDB_ERR_INVALID.
+ */
+cddb_error_t cddb_site_print(const cddb_site_t *site);
+
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* CDDB_SITE_H */
diff --git a/lib-x86-32/include/cddb/cddb_track.h b/lib-x86-32/include/cddb/cddb_track.h
new file mode 100644
index 00000000..0f6ee0f9
--- /dev/null
+++ b/lib-x86-32/include/cddb/cddb_track.h
@@ -0,0 +1,244 @@
+/*
+ $Id: cddb_track.h,v 1.20 2006/10/15 06:51:11 airborne Exp $
+
+ Copyright (C) 2003, 2004, 2005 Kris Verbeeck <airborne@advalvas.be>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef CDDB_TRACK_H
+#define CDDB_TRACK_H 1
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+/**
+ * The CDDB track structure. Contains all information associated with
+ * a single CD track. This structure will be used to populate the
+ * tracks linked list of the cddb_disc_s structure.
+ */
+typedef struct cddb_track_s cddb_track_t;
+
+
+/* --- construction / destruction */
+
+
+/**
+ * Creates a new CDDB track structure.
+ *
+ * @return The CDDB track structure or NULL if memory allocation failed.
+ */
+cddb_track_t *cddb_track_new(void);
+
+/**
+ * Free all resources associated with the given CDDB track structure.
+ * The linked list pointer (next) will not be touched. So you have to
+ * make sure that no other tracks are attached to this one before
+ * calling this function.
+ *
+ * @param track The CDDB track structure.
+ */
+void cddb_track_destroy(cddb_track_t *track);
+
+/**
+ * Creates a clone of the given track.
+ *
+ * @param track The CDDB track structure.
+ */
+cddb_track_t *cddb_track_clone(const cddb_track_t *track);
+
+
+/* --- getters & setters --- */
+
+
+/**
+ * Get the number of this track. This track number starts counting at
+ * 1. If the track is invalid or the track number is not defined -1
+ * will be returned.
+ *
+ * @param track The CDDB track structure.
+ * @return The track number.
+ */
+int cddb_track_get_number(const cddb_track_t *track);
+
+/**
+ * Get the frame offset of this track on the disc. If the track is
+ * invalid -1 will be returned.
+ *
+ * @param track The CDDB track structure.
+ * @return The frame offset.
+ */
+int cddb_track_get_frame_offset(const cddb_track_t *track);
+
+/**
+ * Set the frame offset of this track on the disc.
+ *
+ * @param track The CDDB track structure.
+ * @param offset The frame offset.
+ * @return The frame offset.
+ */
+void cddb_track_set_frame_offset(cddb_track_t *track, int offset);
+
+/**
+ * Get the length of the track in seconds. If the track length is not
+ * defined this routine will try to calculate it using the frame
+ * offsets of the tracks and the total disc length. These
+ * calculations will do no rounding to the nearest second. So it is
+ * possible that the sum off all track lengths does not add up to the
+ * actual disc length. If the length can not be calculated -1 will be
+ * returned.
+ *
+ * @param track The CDDB track structure.
+ * @return The track length.
+ */
+int cddb_track_get_length(cddb_track_t *track);
+
+/**
+ * Set the length of the track. If no frame offset is yet known for
+ * this track, and it is part of a disc, then the frame offset will be
+ * calculated.
+ *
+ * @param track The CDDB track structure.
+ * @param length The track length in seconds.
+ */
+void cddb_track_set_length(cddb_track_t *track, int length);
+
+/**
+ * Get the track title. If the track is invalid or no title is set
+ * for this track then NULL will be returned.
+ *
+ * @param track The CDDB track structure.
+ * @return The track title.
+ */
+const char *cddb_track_get_title(const cddb_track_t *track);
+
+/**
+ * Set the track title. If the track already had a title, then the
+ * memory for that string will be freed. The new title will be copied
+ * into a new chunk of memory. If the given title is NULL, then the
+ * title of the track will be deleted.
+ *
+ * @param track The CDDB track structure.
+ * @param title The new track title.
+ */
+void cddb_track_set_title(cddb_track_t *track, const char *title);
+
+/**
+ * Append to the track title. If the track does not have a title yet,
+ * then a new one will be created from the given string, otherwise
+ * that string will be appended to the existing title.
+ *
+ * @param track The CDDB track structure.
+ * @param title Part of the track title.
+ */
+void cddb_track_append_title(cddb_track_t *track, const char *title);
+
+/**
+ * Get the track artist name. If there is no track artist defined,
+ * the disc artist will be returned. NULL will be returned if neither
+ * is defined.
+ *
+ * @param track The CDDB track structure.
+ */
+const char *cddb_track_get_artist(cddb_track_t *track);
+
+/**
+ * Set the track artist name. If the track already had an artist
+ * name, then the memory for that string will be freed. The new
+ * artist name will be copied into a new chunk of memory. If the given artist
+ * name is NULL, then the artist name of the track will be deleted.
+ *
+ * @param track The CDDB track structure.
+ * @param artist The new track artist name.
+ */
+void cddb_track_set_artist(cddb_track_t *track, const char *artist);
+
+/**
+ * Append to the track artist. If the track does not have an artist
+ * yet, then a new one will be created from the given string,
+ * otherwise that string will be appended to the existing artist.
+ *
+ * @param track The CDDB track structure.
+ * @param artist Part of the artist name.
+ */
+void cddb_track_append_artist(cddb_track_t *track, const char *artist);
+
+/**
+ * Get the extended track data. If no extended data is set for this
+ * track then NULL will be returned.
+ *
+ * @param track The CDDB track structure.
+ * @return The extended data.
+ */
+const char *cddb_track_get_ext_data(cddb_track_t *track);
+
+/**
+ * Set the extended data for the track. If the track already had
+ * extended data, then the memory for that string will be freed. The
+ * new extended data will be copied into a new chunk of memory. If
+ * the given extended data is NULL, then the existing data will be
+ * deleted.
+ *
+ * @param track The CDDB track structure.
+ * @param ext_data The new extended data.
+ */
+void cddb_track_set_ext_data(cddb_track_t *track, const char *ext_data);
+
+/**
+ * Append to the extended track data. If the track does not have an
+ * extended data section yet, then a new one will be created from the
+ * given string, otherwise that string will be appended to the
+ * existing data.
+ *
+ * @param track The CDDB track structure.
+ * @param ext_data Part of the extended track data.
+ */
+void cddb_track_append_ext_data(cddb_track_t *track, const char *ext_data);
+
+
+/* --- miscellaneous */
+
+
+/**
+ * Copy all data from one track to another. Any fields that are
+ * unavailable in the source track structure will not result in a
+ * reset of the same field in the destination track structure; e.g. if
+ * there is no title in the source track, but there is one in the
+ * destination track, then the destination's title will remain
+ * unchanged.
+ *
+ * @param dst The destination CDDB track structure.
+ * @param src The source CDDB track structure.
+ */
+void cddb_track_copy(cddb_track_t *dst, cddb_track_t *src);
+
+/**
+ * Prints information about the track on stdout. This is just a
+ * debugging routine to display the structure's content. It is used
+ * by cddb_disc_print to print the contents of a complete disc.
+ *
+ * @param track The CDDB track structure.
+ */
+void cddb_track_print(cddb_track_t *track);
+
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* CDDB_TRACK_H */
diff --git a/lib-x86-32/include/cddb/ll.h b/lib-x86-32/include/cddb/ll.h
new file mode 100644
index 00000000..9486e59f
--- /dev/null
+++ b/lib-x86-32/include/cddb/ll.h
@@ -0,0 +1,148 @@
+/*
+ $Id: ll.h,v 1.1 2005/05/29 08:24:04 airborne Exp $
+
+ Copyright (C) 2005 Kris Verbeeck <airborne@advalvas.be>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef LL_H
+#define LL_H 1
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+/* --- type definitions */
+
+
+/**
+ * Linked list element.
+ */
+typedef struct elem_s elem_t;
+
+/**
+ * Linked list.
+ */
+typedef struct list_s list_t;
+
+/**
+ * Callback prototype for destroying element data.
+ */
+typedef void elem_destroy_cb(void *data);
+
+
+/* --- construction / destruction */
+
+
+/**
+ * Creates a new linked list.
+ *
+ * @param cb The callback used to destroy the element data or NULL if
+ * no further action is required.
+ * @return The linked list structure or NULL if memory allocation failed.
+ */
+list_t *list_new(elem_destroy_cb *cb);
+
+/**
+ * Free all resources associated with the given linked list. Embedded
+ * data will be freed by use of the callback registered at list
+ * creation.
+ *
+ * @param list The linked list.
+ */
+void list_destroy(list_t *list);
+
+/**
+ * Remove all elements from the list without destroying the list
+ * itself. Embedded data will be freed by use of the callback
+ * registered at list creation.
+ *
+ * @param list The linked list.
+ */
+void list_flush(list_t *list);
+
+
+/* --- list elements --- */
+
+/**
+ * Retrieves the data associated with a list element.
+ *
+ * @param elem The list element.
+ * @return The data associated with the element or NULL if the element
+ * was invalid.
+ */
+void *element_data(elem_t *elem);
+
+
+/* --- getters & setters --- */
+
+
+/**
+ * Append a new element to the end of the list.
+ *
+ * @param list The linked list.
+ * @param data The data to append to the list.
+ * @return The list element that was appended or NULL if memory
+ * allocation fails or the list is invalid.
+ */
+elem_t *list_append(list_t *list, void *data);
+
+/**
+ * Returns the number of elements in the list.
+ *
+ * @param list The linked list.
+ * @return The number of elements.
+ */
+int list_size(list_t *list);
+
+/**
+ * Returns the list element at the specified index or NULL if the
+ * index is invalid.
+ *
+ * @param list The linked list.
+ * @param idx The element index (first = 0).
+ * @return The element or NULL if not found.
+ */
+elem_t *list_get(list_t *list, int idx);
+
+/**
+ * Returns the first list element.
+ *
+ * @param list The linked list.
+ * @return The first element or NULL if the list is empty.
+ */
+elem_t *list_first(list_t *list);
+
+/**
+ * Returns the next list element. Before using this function you
+ * should call list_first to initialize the iterator.
+ *
+ * @param list The linked list.
+ * @return The next element or NULL if not found.
+ */
+elem_t *list_next(list_t *list);
+
+
+/* --- iteration */
+
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* LL_H */
diff --git a/lib-x86-32/include/cddb/version.h b/lib-x86-32/include/cddb/version.h
new file mode 100644
index 00000000..f72839b2
--- /dev/null
+++ b/lib-x86-32/include/cddb/version.h
@@ -0,0 +1,12 @@
+/* $Id: version.h.in,v 1.1 2005/04/08 01:49:35 rockyb Exp $ */
+/** \file version.h
+ *
+ * \brief A file containing the libcdio package version
+ * number (131) and OS build name.
+ */
+
+/*! CDDB_VERSION can as a string in programs to show what version is used. */
+#define CDDB_VERSION "1.3.2 i686-pc-linux-gnu"
+
+/*! LIBCDDB_VERSION_NUM can be used for testing in the C preprocessor */
+#define LIBCDDB_VERSION_NUM 131
diff --git a/lib-x86-32/include/cddb/version.h.in b/lib-x86-32/include/cddb/version.h.in
new file mode 100644
index 00000000..48d4c3fc
--- /dev/null
+++ b/lib-x86-32/include/cddb/version.h.in
@@ -0,0 +1,12 @@
+/* $Id: version.h.in,v 1.1 2005/04/08 01:49:35 rockyb Exp $ */
+/** \file version.h
+ *
+ * \brief A file containing the libcdio package version
+ * number (@LIBCDDB_VERSION_NUM@) and OS build name.
+ */
+
+/*! CDDB_VERSION can as a string in programs to show what version is used. */
+#define CDDB_VERSION "@VERSION@ @build@"
+
+/*! LIBCDDB_VERSION_NUM can be used for testing in the C preprocessor */
+#define LIBCDDB_VERSION_NUM @LIBCDDB_VERSION_NUM@
diff --git a/lib-x86-32/include/cdio/Makefile.am b/lib-x86-32/include/cdio/Makefile.am
new file mode 100644
index 00000000..ea695618
--- /dev/null
+++ b/lib-x86-32/include/cdio/Makefile.am
@@ -0,0 +1,62 @@
+# $Id: Makefile.am,v 1.34 2008/03/20 19:02:37 karl Exp $
+#
+# Copyright (C) 2003, 2004, 2006, 2008 Rocky Bernstein <rocky@gnu.org>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+########################################################
+# Things to make the install (public) libcdio headers
+########################################################
+#
+
+if BUILD_CD_PARANOIA
+paranoiaheaders = cdda.h cdtext.h
+endif
+
+libcdioincludedir=$(includedir)/cdio
+libcdioinclude_HEADERS = \
+ audio.h \
+ bytesex.h \
+ bytesex_asm.h \
+ cdio.h \
+ cdio_config.h \
+ cd_types.h \
+ device.h \
+ disc.h \
+ ds.h \
+ dvd.h \
+ ecma_167.h \
+ iso9660.h \
+ logging.h \
+ mmc.h \
+ paranoia.h \
+ posix.h \
+ read.h \
+ rock.h \
+ sector.h \
+ track.h \
+ types.h \
+ udf.h \
+ udf_file.h \
+ udf_time.h \
+ utf8.h \
+ util.h \
+ version.h \
+ xa.h \
+ $(paranoiaheaders)
+
+EXTRA_DIST = version.h.in
+BUILT_SOURCES = version.h
+
+DISTCLEANFILES = cdio_config.h
diff --git a/lib-x86-32/include/cdio/audio.h b/lib-x86-32/include/cdio/audio.h
new file mode 100644
index 00000000..880cd541
--- /dev/null
+++ b/lib-x86-32/include/cdio/audio.h
@@ -0,0 +1,148 @@
+/* -*- c -*-
+ $Id: audio.h,v 1.12 2008/03/25 15:59:08 karl Exp $
+
+ Copyright (C) 2005, 2007, 2008 Rocky Bernstein <rocky@gnu.org>
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/** \file audio.h
+ *
+ * \brief The top-level header for CD audio-related libcdio
+ * calls. These control playing of the CD-ROM through its
+ * line-out jack.
+ */
+#ifndef __CDIO_AUDIO_H__
+#define __CDIO_AUDIO_H__
+
+#include <cdio/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+ /*! This struct is used by the cdio_audio_read_subchannel */
+ typedef struct cdio_subchannel_s
+ {
+ uint8_t format;
+ uint8_t audio_status;
+ uint8_t address: 4;
+ uint8_t control: 4;
+ uint8_t track;
+ uint8_t index;
+ msf_t abs_addr;
+ msf_t rel_addr;
+ } cdio_subchannel_t;
+
+ /*! This struct is used by cdio_audio_get_volume and cdio_audio_set_volume */
+ typedef struct cdio_audio_volume_s
+ {
+ uint8_t level[4];
+ } cdio_audio_volume_t;
+
+
+ /*! This struct is used by the CDROMPLAYTRKIND ioctl */
+ typedef struct cdio_track_index_s
+ {
+ uint8_t i_start_track; /**< start track */
+ uint8_t i_start_index; /**< start index */
+ uint8_t i_end_track; /**< end track */
+ uint8_t i_end_index; /**< end index */
+ } cdio_track_index_t;
+
+ /*!
+ Get volume of an audio CD.
+
+ @param p_cdio the CD object to be acted upon.
+ @param p_volume place to put the list of volume outputs levels
+
+ p_volume can be NULL in which case we return only whether the driver
+ has the ability to get the volume or not.
+
+ */
+ driver_return_code_t cdio_audio_get_volume (CdIo_t *p_cdio, /*out*/
+ cdio_audio_volume_t *p_volume);
+
+ /*!
+ Return the number of seconds (discarding frame portion) of an MSF
+ */
+ uint32_t cdio_audio_get_msf_seconds(msf_t *p_msf);
+
+ /*!
+ Pause playing CD through analog output
+
+ @param p_cdio the CD object to be acted upon.
+ */
+ driver_return_code_t cdio_audio_pause (CdIo_t *p_cdio);
+
+ /*!
+ Playing CD through analog output at the given MSF.
+
+ @param p_cdio the CD object to be acted upon.
+ @param p_start_msf pointer to staring MSF
+ @param p_end_msf pointer to ending MSF
+ */
+ driver_return_code_t cdio_audio_play_msf (CdIo_t *p_cdio,
+ /*in*/msf_t *p_start_msf,
+ /*in*/ msf_t *p_end_msf);
+
+ /*!
+ Playing CD through analog output at the desired track and index
+
+ @param p_cdio the CD object to be acted upon.
+ @param p_track_index location to start/end.
+ */
+ driver_return_code_t cdio_audio_play_track_index
+ ( CdIo_t *p_cdio, cdio_track_index_t *p_track_index);
+
+ /*!
+ Get subchannel information.
+
+ @param p_cdio the CD object to be acted upon.
+ @param p_subchannel place for returned subchannel information
+ */
+ driver_return_code_t cdio_audio_read_subchannel (CdIo_t *p_cdio,
+ /*out*/ cdio_subchannel_t *p_subchannel);
+
+ /*!
+ Resume playing an audio CD.
+
+ @param p_cdio the CD object to be acted upon.
+
+ */
+ driver_return_code_t cdio_audio_resume (CdIo_t *p_cdio);
+
+ /*!
+ Set volume of an audio CD.
+
+ @param p_cdio the CD object to be acted upon.
+ @param p_volume place for returned volume-level information
+
+ */
+ driver_return_code_t cdio_audio_set_volume (CdIo_t *p_cdio, /*out*/
+ cdio_audio_volume_t *p_volume);
+
+ /*!
+ Stop playing an audio CD.
+
+ @param p_cdio the CD object to be acted upon.
+
+ */
+ driver_return_code_t cdio_audio_stop (CdIo_t *p_cdio);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __CDIO_AUDIO_H__ */
diff --git a/lib-x86-32/include/cdio/bytesex.h b/lib-x86-32/include/cdio/bytesex.h
new file mode 100644
index 00000000..e1be483e
--- /dev/null
+++ b/lib-x86-32/include/cdio/bytesex.h
@@ -0,0 +1,220 @@
+/*
+ $Id: bytesex.h,v 1.5 2008/03/25 15:59:08 karl Exp $
+
+ Copyright (C) 2000, 2004 Herbert Valerio Riedel <hvr@gnu.org>
+ Copyright (C) 2005, 2008 Rocky Bernstein <rocky@gnu.org>
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/** \file bytesex.h
+ * \brief Generic Byte-swapping routines.
+ *
+ * Note: this header will is slated to get removed and libcdio will
+ * use glib.h routines instead.
+*/
+
+#ifndef __CDIO_BYTESEX_H__
+#define __CDIO_BYTESEX_H__
+
+#include <cdio/types.h>
+#include <cdio/bytesex_asm.h>
+#include <cdio/logging.h>
+
+/** 16-bit big-endian to little-endian */
+#define UINT16_SWAP_LE_BE_C(val) ((uint16_t) ( \
+ (((uint16_t) (val) & (uint16_t) 0x00ffU) << 8) | \
+ (((uint16_t) (val) & (uint16_t) 0xff00U) >> 8)))
+
+/** 32-bit big-endian to little-endian */
+#define UINT32_SWAP_LE_BE_C(val) ((uint32_t) ( \
+ (((uint32_t) (val) & (uint32_t) 0x000000ffU) << 24) | \
+ (((uint32_t) (val) & (uint32_t) 0x0000ff00U) << 8) | \
+ (((uint32_t) (val) & (uint32_t) 0x00ff0000U) >> 8) | \
+ (((uint32_t) (val) & (uint32_t) 0xff000000U) >> 24)))
+
+/** 64-bit big-endian to little-endian */
+#define UINT64_SWAP_LE_BE_C(val) ((uint64_t) ( \
+ (((uint64_t) (val) & (uint64_t) UINT64_C(0x00000000000000ff)) << 56) | \
+ (((uint64_t) (val) & (uint64_t) UINT64_C(0x000000000000ff00)) << 40) | \
+ (((uint64_t) (val) & (uint64_t) UINT64_C(0x0000000000ff0000)) << 24) | \
+ (((uint64_t) (val) & (uint64_t) UINT64_C(0x00000000ff000000)) << 8) | \
+ (((uint64_t) (val) & (uint64_t) UINT64_C(0x000000ff00000000)) >> 8) | \
+ (((uint64_t) (val) & (uint64_t) UINT64_C(0x0000ff0000000000)) >> 24) | \
+ (((uint64_t) (val) & (uint64_t) UINT64_C(0x00ff000000000000)) >> 40) | \
+ (((uint64_t) (val) & (uint64_t) UINT64_C(0xff00000000000000)) >> 56)))
+
+#ifndef UINT16_SWAP_LE_BE
+# define UINT16_SWAP_LE_BE UINT16_SWAP_LE_BE_C
+#endif
+
+#ifndef UINT32_SWAP_LE_BE
+# define UINT32_SWAP_LE_BE UINT32_SWAP_LE_BE_C
+#endif
+
+#ifndef UINT64_SWAP_LE_BE
+# define UINT64_SWAP_LE_BE UINT64_SWAP_LE_BE_C
+#endif
+
+inline static
+uint16_t uint16_swap_le_be (const uint16_t val)
+{
+ return UINT16_SWAP_LE_BE (val);
+}
+
+inline static
+uint32_t uint32_swap_le_be (const uint32_t val)
+{
+ return UINT32_SWAP_LE_BE (val);
+}
+
+inline static
+uint64_t uint64_swap_le_be (const uint64_t val)
+{
+ return UINT64_SWAP_LE_BE (val);
+}
+
+# define UINT8_TO_BE(val) ((uint8_t) (val))
+# define UINT8_TO_LE(val) ((uint8_t) (val))
+#ifdef WORDS_BIGENDIAN
+# define UINT16_TO_BE(val) ((uint16_t) (val))
+# define UINT16_TO_LE(val) ((uint16_t) UINT16_SWAP_LE_BE(val))
+
+# define UINT32_TO_BE(val) ((uint32_t) (val))
+# define UINT32_TO_LE(val) ((uint32_t) UINT32_SWAP_LE_BE(val))
+
+# define UINT64_TO_BE(val) ((uint64_t) (val))
+# define UINT64_TO_LE(val) ((uint64_t) UINT64_SWAP_LE_BE(val))
+#else
+# define UINT16_TO_BE(val) ((uint16_t) UINT16_SWAP_LE_BE(val))
+# define UINT16_TO_LE(val) ((uint16_t) (val))
+
+# define UINT32_TO_BE(val) ((uint32_t) UINT32_SWAP_LE_BE(val))
+# define UINT32_TO_LE(val) ((uint32_t) (val))
+
+# define UINT64_TO_BE(val) ((uint64_t) UINT64_SWAP_LE_BE(val))
+# define UINT64_TO_LE(val) ((uint64_t) (val))
+#endif
+
+/** symmetric conversions */
+#define UINT8_FROM_BE(val) (UINT8_TO_BE (val))
+#define UINT8_FROM_LE(val) (UINT8_TO_LE (val))
+#define UINT16_FROM_BE(val) (UINT16_TO_BE (val))
+#define UINT16_FROM_LE(val) (UINT16_TO_LE (val))
+#define UINT32_FROM_BE(val) (UINT32_TO_BE (val))
+#define UINT32_FROM_LE(val) (UINT32_TO_LE (val))
+#define UINT64_FROM_BE(val) (UINT64_TO_BE (val))
+#define UINT64_FROM_LE(val) (UINT64_TO_LE (val))
+
+/** converter function template */
+#define CVT_TO_FUNC(bits) \
+ static inline uint ## bits ## _t \
+ uint ## bits ## _to_be (uint ## bits ## _t val) \
+ { return UINT ## bits ## _TO_BE (val); } \
+ static inline uint ## bits ## _t \
+ uint ## bits ## _to_le (uint ## bits ## _t val) \
+ { return UINT ## bits ## _TO_LE (val); } \
+
+CVT_TO_FUNC(8)
+CVT_TO_FUNC(16)
+CVT_TO_FUNC(32)
+CVT_TO_FUNC(64)
+
+#undef CVT_TO_FUNC
+
+#define uint8_from_be(val) (uint8_to_be (val))
+#define uint8_from_le(val) (uint8_to_le (val))
+#define uint16_from_be(val) (uint16_to_be (val))
+#define uint16_from_le(val) (uint16_to_le (val))
+#define uint32_from_be(val) (uint32_to_be (val))
+#define uint32_from_le(val) (uint32_to_le (val))
+#define uint64_from_be(val) (uint64_to_be (val))
+#define uint64_from_le(val) (uint64_to_le (val))
+
+/** ISO9660-related field conversion routines */
+
+/** Convert from uint8_t to ISO 9660 7.1.1 format */
+#define to_711(i) uint8_to_le(i)
+
+/** Convert from ISO 9660 7.1.1 format to uint8_t */
+#define from_711(i) uint8_from_le(i)
+
+/** Convert from uint16_t to ISO 9669 7.2.1 format */
+#define to_721(i) uint16_to_le(i)
+
+/** Convert from ISO 9660 7.2.1 format to uint16_t */
+#define from_721(i) uint16_from_le(i)
+
+/** Convert from uint16_t to ISO 9669 7.2.2 format */
+#define to_722(i) uint16_to_be(i)
+
+/** Convert from ISO 9660 7.2.2 format to uint16_t */
+#define from_722(i) uint16_from_be(i)
+
+/** Convert from uint16_t to ISO 9669 7.2.3 format */
+static inline uint32_t
+to_723(uint16_t i)
+{
+ return uint32_swap_le_be(i) | i;
+}
+
+/** Convert from ISO 9660 7.2.3 format to uint16_t */
+static inline uint16_t
+from_723 (uint32_t p)
+{
+ if (uint32_swap_le_be (p) != p)
+ cdio_warn ("from_723: broken byte order");
+
+ return (0xFFFF & p);
+}
+
+/** Convert from uint16_t to ISO 9669 7.3.1 format */
+#define to_731(i) uint32_to_le(i)
+
+/** Convert from ISO 9660 7.3.1 format to uint32_t */
+#define from_731(i) uint32_from_le(i)
+
+/** Convert from uint32_t to ISO 9669 7.3.2 format */
+#define to_732(i) uint32_to_be(i)
+
+/** Convert from ISO 9660 7.3.2 format to uint32_t */
+#define from_732(i) uint32_from_be(i)
+
+/** Convert from uint16_t to ISO 9669 7.3.3 format */
+static inline uint64_t
+to_733(uint32_t i)
+{
+ return uint64_swap_le_be(i) | i;
+}
+
+/** Convert from ISO 9660 7.3.3 format to uint32_t */
+static inline uint32_t
+from_733 (uint64_t p)
+{
+ if (uint64_swap_le_be (p) != p)
+ cdio_warn ("from_733: broken byte order");
+
+ return (UINT32_C(0xFFFFFFFF) & p);
+}
+
+#endif /* __CDIO_BYTESEX_H__ */
+
+
+/*
+ * Local variables:
+ * c-file-style: "gnu"
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/lib-x86-32/include/cdio/bytesex_asm.h b/lib-x86-32/include/cdio/bytesex_asm.h
new file mode 100644
index 00000000..7f1f131a
--- /dev/null
+++ b/lib-x86-32/include/cdio/bytesex_asm.h
@@ -0,0 +1,130 @@
+/*
+ $Id: bytesex_asm.h,v 1.3 2008/03/25 15:59:08 karl Exp $
+
+ Copyright (C) 2008 Rocky Bernstein <rocky@gnu.org>
+ 2001, 2004, 2005 Herbert Valerio Riedel <hvr@gnu.org>
+ 2001 Sven Ottemann <ac-logic@freenet.de>
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/** \file bytesex_asm.h
+ * \brief Assembly code to handle byte-swapping.
+
+ Note: this header will is slated to get removed and libcdio will use
+ glib.h routines instead.
+*/
+
+#ifndef __CDIO_BYTESEX_ASM_H__
+#define __CDIO_BYTESEX_ASM_H__
+#if !defined(DISABLE_ASM_OPTIMIZE)
+
+#include <cdio/types.h>
+
+#if defined(__powerpc__) && defined(__GNUC__)
+
+inline static
+uint32_t uint32_swap_le_be_asm(const uint32_t a)
+{
+ uint32_t b;
+
+ __asm__ ("lwbrx %0,0,%1"
+ :"=r"(b)
+ :"r"(&a), "m"(a));
+
+ return b;
+}
+
+inline static
+uint16_t uint16_swap_le_be_asm(const uint16_t a)
+{
+ uint32_t b;
+
+ __asm__ ("lhbrx %0,0,%1"
+ :"=r"(b)
+ :"r"(&a), "m"(a));
+
+ return b;
+}
+
+#define UINT16_SWAP_LE_BE uint16_swap_le_be_asm
+#define UINT32_SWAP_LE_BE uint32_swap_le_be_asm
+
+#elif defined(__mc68000__) && defined(__STORMGCC__)
+
+inline static
+uint32_t uint32_swap_le_be_asm(uint32_t a __asm__("d0"))
+{
+ /* __asm__("rolw #8,%0; swap %0; rolw #8,%0" : "=d" (val) : "0" (val)); */
+
+ __asm__("move.l %1,d0;rol.w #8,d0;swap d0;rol.w #8,d0;move.l d0,%0"
+ :"=r"(a)
+ :"r"(a));
+
+ return(a);
+}
+
+inline static
+uint16_t uint16_swap_le_be_asm(uint16_t a __asm__("d0"))
+{
+ __asm__("move.l %1,d0;rol.w #8,d0;move.l d0,%0"
+ :"=r"(a)
+ :"r"(a));
+
+ return(a);
+}
+
+#define UINT16_SWAP_LE_BE uint16_swap_le_be_asm
+#define UINT32_SWAP_LE_BE uint32_swap_le_be_asm
+
+#elif 0 && defined(__i386__) && defined(__GNUC__)
+
+inline static
+uint32_t uint32_swap_le_be_asm(uint32_t a)
+{
+ __asm__("xchgb %b0,%h0\n\t" /* swap lower bytes */
+ "rorl $16,%0\n\t" /* swap words */
+ "xchgb %b0,%h0" /* swap higher bytes */
+ :"=q" (a)
+ : "0" (a));
+
+ return(a);
+}
+
+inline static
+uint16_t uint16_swap_le_be_asm(uint16_t a)
+{
+ __asm__("xchgb %b0,%h0" /* swap bytes */
+ : "=q" (a)
+ : "0" (a));
+
+ return(a);
+}
+
+#define UINT16_SWAP_LE_BE uint16_swap_le_be_asm
+#define UINT32_SWAP_LE_BE uint32_swap_le_be_asm
+
+#endif
+
+#endif /* !defined(DISABLE_ASM_OPTIMIZE) */
+#endif /* __CDIO_BYTESEX_ASM_H__ */
+
+
+/*
+ * Local variables:
+ * c-file-style: "gnu"
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/lib-x86-32/include/cdio/cd_types.h b/lib-x86-32/include/cdio/cd_types.h
new file mode 100644
index 00000000..bc1f16c0
--- /dev/null
+++ b/lib-x86-32/include/cdio/cd_types.h
@@ -0,0 +1,175 @@
+/*
+ $Id: cd_types.h,v 1.18 2008/03/25 15:59:08 karl Exp $
+
+ Copyright (C) 2003, 2006, 2008 Rocky Bernstein <rocky@cpan.org>
+ Copyright (C) 1996,1997,1998 Gerd Knorr <kraxel@bytesex.org>
+ and Heiko Eifeldt <heiko@hexco.de>
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/** \file cd_types.h
+ * \brief Header for routines which automatically determine the Compact Disc
+ * format and possibly filesystem on the CD.
+ *
+ */
+
+#ifndef __CDIO_CD_TYPES_H__
+#define __CDIO_CD_TYPES_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * Filesystem types we understand. The highest-numbered fs type should
+ * be less than CDIO_FS_MASK defined below.
+ */
+ typedef enum {
+ CDIO_FS_AUDIO = 1, /**< audio only - not really a
+ filesystem */
+ CDIO_FS_HIGH_SIERRA = 2, /**< High-Sierra Filesystem */
+ CDIO_FS_ISO_9660 = 3, /**< ISO 9660 filesystem */
+ CDIO_FS_INTERACTIVE = 4,
+ CDIO_FS_HFS = 5, /**< file system used on the Macintosh
+ system in MacOS 6 through MacOS 9
+ and deprecated in OSX. */
+ CDIO_FS_UFS = 6, /**< Generic Unix file system derived
+ from the Berkeley fast file
+ system. */
+
+ /**<
+ * EXT2 was the GNU/Linux native filesystem for early kernels. Newer
+ * GNU/Linux OS's may use EXT3 which is EXT2 with a journal.
+ */
+ CDIO_FS_EXT2 = 7,
+
+ CDIO_FS_ISO_HFS = 8, /**< both HFS & ISO-9660 filesystem */
+ CDIO_FS_ISO_9660_INTERACTIVE = 9, /**< both CD-RTOS and ISO filesystem */
+
+
+ /**<
+ * The 3DO is, technically, a set of specifications created by the 3DO
+ * company. These specs are for making a 3DO Interactive Multiplayer
+ * which uses a CD-player. Panasonic in the early 90's was the first
+ * company to manufacture and market a 3DO player.
+ */
+ CDIO_FS_3DO = 10,
+
+
+ /**<
+ Microsoft X-BOX CD.
+ */
+ CDIO_FS_XISO = 11,
+ CDIO_FS_UDFX = 12,
+ CDIO_FS_UDF = 13,
+ CDIO_FS_ISO_UDF = 14
+ } cdio_fs_t;
+
+
+/**
+ * Macro to extract just the FS type portion defined above
+*/
+#define CDIO_FSTYPE(fs) (fs & CDIO_FS_MASK)
+
+/**
+ * Bit masks for the classes of CD-images. These are generally
+ * higher-level than the fs-type information above and may be determined
+ * based of the fs type information. This
+ */
+ typedef enum {
+ CDIO_FS_MASK = 0x000f, /**< Note: this should be 2**n-1 and
+ and greater than the highest
+ CDIO_FS number above */
+ CDIO_FS_ANAL_XA = 0x00010, /**< eXtended Architecture format */
+ CDIO_FS_ANAL_MULTISESSION = 0x00020, /**< CD has multisesion */
+ CDIO_FS_ANAL_PHOTO_CD = 0x00040, /**< Is a Kodak Photo CD */
+ CDIO_FS_ANAL_HIDDEN_TRACK = 0x00080, /**< Hidden track at the
+ beginning of the CD */
+ CDIO_FS_ANAL_CDTV = 0x00100,
+ CDIO_FS_ANAL_BOOTABLE = 0x00200, /**< CD is bootable */
+ CDIO_FS_ANAL_VIDEOCD = 0x00400, /**< VCD 1.1 */
+ CDIO_FS_ANAL_ROCKRIDGE = 0x00800, /**< Has Rock Ridge Extensions to
+ ISO 9660, */
+ CDIO_FS_ANAL_JOLIET = 0x01000, /**< Microsoft Joliet extensions
+ to ISO 9660, */
+ CDIO_FS_ANAL_SVCD = 0x02000, /**< Super VCD or Choiji Video CD */
+ CDIO_FS_ANAL_CVD = 0x04000, /**< Choiji Video CD */
+ CDIO_FS_ANAL_XISO = 0x08000, /**< XBOX CD */
+ CDIO_FS_ANAL_ISO9660_ANY = 0x10000, /**< Any sort fo ISO9660 FS */
+ CDIO_FS_ANAL_VCD_ANY = (CDIO_FS_ANAL_VIDEOCD|CDIO_FS_ANAL_SVCD|
+ CDIO_FS_ANAL_CVD),
+ CDIO_FS_MATCH_ALL = ~CDIO_FS_MASK /**< bitmask which can
+ be used by
+ cdio_get_devices to
+ specify matching any
+ sort of CD. */
+ } cdio_fs_cap_t;
+
+
+#define CDIO_FS_UNKNOWN CDIO_FS_MASK
+
+/**
+ *
+ */
+#define CDIO_FS_MATCH_ALL (cdio_fs_anal_t) (~CDIO_FS_MASK)
+
+
+/*!
+ \brief The type used to return analysis information from
+ cdio_guess_cd_type.
+
+ These fields make sense only for when an ISO-9660 filesystem is used.
+ */
+typedef struct
+{
+ unsigned int joliet_level; /**< If has Joliet extensions, this is the
+ associated level number (i.e. 1, 2, or 3). */
+ char iso_label[33]; /**< This is 32 + 1 for null byte at the end in
+ formatting the string */
+ unsigned int isofs_size;
+ uint8_t UDFVerMinor; /**< For UDF filesystems only */
+ uint8_t UDFVerMajor; /**< For UDF filesystems only */
+} cdio_iso_analysis_t;
+
+/**
+ * Try to determine what kind of CD-image and/or filesystem we
+ * have at track track_num. Return information about the CD image
+ * is returned in iso_analysis and the return value.
+ */
+cdio_fs_anal_t cdio_guess_cd_type(const CdIo_t *cdio, int start_session,
+ track_t track_num,
+ /*out*/ cdio_iso_analysis_t *iso_analysis);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+/** The below variables are trickery to force the above enum symbol
+ values to be recorded in debug symbol tables. They are used to
+ allow one to refer to the enumeration value names in the typedefs
+ above in a debugger and debugger expressions.
+*/
+extern cdio_fs_cap_t debug_cdio_fs_cap;
+extern cdio_fs_t debug_cdio_fs;
+
+#endif /* __CDIO_CD_TYPES_H__ */
+
+/*
+ * Local variables:
+ * c-file-style: "gnu"
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/lib-x86-32/include/cdio/cdda.h b/lib-x86-32/include/cdio/cdda.h
new file mode 100644
index 00000000..c30e129d
--- /dev/null
+++ b/lib-x86-32/include/cdio/cdda.h
@@ -0,0 +1,411 @@
+/*
+ $Id: cdda.h,v 1.30 2008/03/25 15:59:08 karl Exp $
+
+ Copyright (C) 2004, 2005, 2006, 2008 Rocky Bernstein <rocky@gnu.org>
+ Copyright (C) 2001 Xiph.org and Heiko Eissfeldt heiko@escape.colossus.de
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/** \file cdda.h
+ *
+ * \brief The top-level interface header for libcdio_cdda.
+ * Applications include this for paranoia access.
+ *
+ ******************************************************************/
+
+#ifndef _CDDA_INTERFACE_H_
+#define _CDDA_INTERFACE_H_
+
+#include <cdio/cdio.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+ /** cdrom_paranoia is an opaque structure which is used in all of the
+ library operations.
+ */
+ typedef struct cdrom_paranoia_s cdrom_paranoia_t;
+ typedef struct cdrom_drive_s cdrom_drive_t;
+
+ /** For compatibility. cdrom_drive_t is deprecated, use cdrom_drive_t
+ instead. */
+
+ /**
+ Flags for simulating jitter used in testing.
+
+ The enumeration type one probably wouldn't really use in a program.
+ It is here instead of defines to give symbolic names that can be
+ helpful in debuggers where wants just to say refer to
+ CDDA_TEST_JITTER_SMALL and get the correct value.
+ */
+ typedef enum {
+ CDDA_MESSAGE_FORGETIT = 0,
+ CDDA_MESSAGE_PRINTIT = 1,
+ CDDA_MESSAGE_LOGIT = 2,
+ CD_FRAMESAMPLES = CDIO_CD_FRAMESIZE_RAW / 4,
+ MAXTRK = (CDIO_CD_MAX_TRACKS+1)
+ } paranoia_cdda_enums_t;
+
+
+#include <signal.h>
+
+/** We keep MAXTRK since this header is exposed publicly and other
+ programs may have used this.
+*/
+#define MAXTRK (CDIO_CD_MAX_TRACKS+1)
+
+/** \brief Structure for cdparanoia's CD Table of Contents */
+typedef struct TOC_s {
+ unsigned char bTrack;
+ int32_t dwStartSector;
+} TOC_t;
+
+/** For compatibility. TOC is deprecated, use TOC_t instead. */
+#define TOC TOC_t
+
+/** \brief Structure for cdparanoia's CD-ROM access */
+struct cdrom_drive_s {
+
+ CdIo_t *p_cdio;
+ int opened; /**< This struct may just represent a candidate for opening */
+
+ char *cdda_device_name;
+
+ char *drive_model;
+ int drive_type;
+ int bigendianp; /**< Whether data returned on the CDDA is bigendian or
+ not. 1 if big endian, 0 if little endian and -1 if
+ we don't know.
+ */
+ int nsectors; /**< Number of sectors use in reading. Multiply by
+ CDIO_CD_FRAMESIZE_RAW to get number of bytes used in
+ the read buffer. */
+
+ int cd_extra; /**< -1 if we can't get multisession info, 0 if
+ there is one session only or the multi-session
+ LBA is less than or 100 (don't ask me why -- I
+ don't know), and 1 if the multi-session lba is
+ greater than 100. */
+
+ bool b_swap_bytes; /**< Swap bytes if Endian-ness of drive
+ mismatches the endian-ness of the
+ computer? */
+ track_t tracks;
+ TOC_t disc_toc[MAXTRK]; /**< info here starts origin 0 rather than the
+ first track number (usually 1). So to take
+ a track number and use it here, subtract
+ off cdio_get_first_track_num() beforehand.
+ */
+ lsn_t audio_first_sector;
+ lsn_t audio_last_sector;
+
+ int errordest;
+ int messagedest;
+ char *errorbuf;
+ char *messagebuf;
+
+ /* functions specific to particular drives/interfaces */
+
+ int (*enable_cdda) (cdrom_drive_t *d, int onoff);
+ int (*read_toc) (cdrom_drive_t *d);
+ long (*read_audio) (cdrom_drive_t *d, void *p, lsn_t begin,
+ long sectors);
+ int (*set_speed) (cdrom_drive_t *d, int speed);
+ int error_retry;
+ int report_all;
+
+ int is_atapi;
+ int is_mmc;
+
+ int i_test_flags; /**< Normally set 0. But if we are testing
+ paranoia operation this can be set to one of
+ the flag masks to simulate a particular kind of
+ failure. */
+
+};
+
+
+ /**
+ Flags for simulating jitter used in testing.
+
+ The enumeration type one probably wouldn't really use in a program.
+ It is here instead of defines to give symbolic names that can be
+ helpful in debuggers where wants just to say refer to
+ CDDA_TEST_JITTER_SMALL and get the correct value.
+ */
+ typedef enum {
+ CDDA_TEST_JITTER_SMALL = 1,
+ CDDA_TEST_JITTER_LARGE = 2,
+ CDDA_TEST_JITTER_MASSIVE = 3,
+ CDDA_TEST_FRAG_SMALL = (1<<3),
+ CDDA_TEST_FRAG_LARGE = (2<<3),
+ CDDA_TEST_FRAG_MASSIVE = (3<<3),
+ CDDA_TEST_UNDERRUN = 64
+ } paranoia_jitter_t;
+
+/** jitter testing. The first two bits are set to determine the
+ byte-distance we will jitter the data; 0 is no shifting.
+ */
+
+/**< jitter testing. Set the below bit to always cause jittering on reads.
+ The below bit only has any effect if the first two (above) bits are
+ nonzero. If the above bits are set, but the below bit isn't we'll
+ jitter 90% of the time.
+ */
+#define CDDA_TEST_ALWAYS_JITTER 4
+
+/** fragment testing */
+#define CDDA_TEST_FRAG_SMALL (1<<3)
+#define CDDA_TEST_FRAG_LARGE (2<<3)
+#define CDDA_TEST_FRAG_MASSIVE (3<<3)
+
+/**< under-run testing. The below bit is set for testing. */
+#define CDDA_TEST_UNDERRUN 64
+
+#if TESTING_IS_FINISHED
+
+ /** scratch testing */
+#define CDDA_TEST_SCRATCH 128
+#undef CDDA_TEST_BOGUS_BYTES 256
+#undef CDDA_TEST_DROPDUPE_BYTES 512
+#endif /* TESTING_IS_FINISHED */
+
+/** autosense functions */
+
+/** Get a CD-ROM drive with a CD-DA in it.
+ If mesagedest is 1, then any messages in the process will be stored
+ in message.
+*/
+extern cdrom_drive_t *cdio_cddap_find_a_cdrom(int messagedest,
+ char **ppsz_message);
+
+/** Returns a paranoia CD-ROM drive object with a CD-DA in it or NULL
+ if there was an error.
+ @see cdio_cddap_identify_cdio
+ */
+extern cdrom_drive_t *cdio_cddap_identify(const char *psz_device,
+ int messagedest,
+ char **ppsz_message);
+
+/** Returns a paranoia CD-ROM drive object with a CD-DA in it or NULL
+ if there was an error. In contrast to cdio_cddap_identify, we
+ start out with an initialized p_cdio object. For example you may
+ have used that for other purposes such as to get CDDB/CD-Text
+ information. @see cdio_cddap_identify
+ */
+cdrom_drive_t *cdio_cddap_identify_cdio(CdIo_t *p_cdio,
+ int messagedest, char **ppsz_messages);
+
+/** drive-oriented functions */
+
+extern int cdio_cddap_speed_set(cdrom_drive_t *d, int speed);
+extern void cdio_cddap_verbose_set(cdrom_drive_t *d, int err_action,
+ int mes_action);
+extern char *cdio_cddap_messages(cdrom_drive_t *d);
+extern char *cdio_cddap_errors(cdrom_drive_t *d);
+
+/*!
+ Closes d and releases all storage associated with it except
+ the internal p_cdio pointer.
+
+ @param d cdrom_drive_t object to be closed.
+ @return 0 if passed a null pointer and 1 if not in which case
+ some work was probably done.
+
+ @see cdio_cddap_close
+*/
+bool cdio_cddap_close_no_free_cdio(cdrom_drive_t *d);
+
+/*!
+ Closes d and releases all storage associated with it.
+ Doubles as "cdrom_drive_free()".
+
+ @param d cdrom_drive_t object to be closed.
+ @return 0 if passed a null pointer and 1 if not in which case
+ some work was probably done.
+
+ @see cdio_cddap_close_no_free_cdio
+*/
+extern int cdio_cddap_close(cdrom_drive_t *d);
+
+extern int cdio_cddap_open(cdrom_drive_t *d);
+
+extern long cdio_cddap_read(cdrom_drive_t *d, void *p_buffer,
+ lsn_t beginsector, long sectors);
+
+/*! Return the lsn for the start of track i_track */
+extern lsn_t cdio_cddap_track_firstsector(cdrom_drive_t *d,
+ track_t i_track);
+
+/*! Get last lsn of the track. This generally one less than the start
+ of the next track. -1 is returned on error. */
+extern lsn_t cdio_cddap_track_lastsector(cdrom_drive_t *d, track_t i_track);
+
+/*! Return the number of tracks on the CD. */
+extern track_t cdio_cddap_tracks(cdrom_drive_t *d);
+
+/*! Return the track containing the given LSN. If the LSN is before
+ the first track (in the pregap), 0 is returned. If there was an
+ error or the LSN after the LEADOUT (beyond the end of the CD), then
+ CDIO_INVALID_TRACK is returned.
+ */
+extern int cdio_cddap_sector_gettrack(cdrom_drive_t *d, lsn_t lsn);
+
+/*! Return the number of channels in track: 2 or 4; -2 if not
+ implemented or -1 for error.
+ Not meaningful if track is not an audio track.
+*/
+extern int cdio_cddap_track_channels(cdrom_drive_t *d, track_t i_track);
+
+/*! Return 1 is track is an audio track, 0 otherwise. */
+extern int cdio_cddap_track_audiop(cdrom_drive_t *d, track_t i_track);
+
+/*! Return 1 is track has copy permit set, 0 otherwise. */
+extern int cdio_cddap_track_copyp(cdrom_drive_t *d, track_t i_track);
+
+/*! Return 1 is audio track has linear preemphasis set, 0 otherwise.
+ Only makes sense for audio tracks.
+ */
+extern int cdio_cddap_track_preemp(cdrom_drive_t *d, track_t i_track);
+
+/*! Get first lsn of the first audio track. -1 is returned on error. */
+extern lsn_t cdio_cddap_disc_firstsector(cdrom_drive_t *d);
+
+/*! Get last lsn of the last audio track. The last lsn is generally one
+ less than the start of the next track after the audio track. -1 is
+ returned on error. */
+extern lsn_t cdio_cddap_disc_lastsector(cdrom_drive_t *d);
+
+/*! Determine Endian-ness of the CD-drive based on reading data from
+ it. Some drives return audio data Big Endian while some (most)
+ return data Little Endian. Drives known to return data bigendian are
+ SCSI drives from Kodak, Ricoh, HP, Philips, Plasmon, Grundig
+ CDR100IPW, and Mitsumi CD-R. ATAPI and MMC drives are little endian.
+
+ rocky: As someone who didn't write the code, I have to say this is
+ nothing less than brilliant. An FFT is done both ways and the the
+ transform is looked at to see which has data in the FFT (or audible)
+ portion. (Or so that's how I understand it.)
+
+ @return 1 if big-endian, 0 if little-endian, -1 if we couldn't
+ figure things out or some error.
+ */
+extern int data_bigendianp(cdrom_drive_t *d);
+
+/** transport errors: */
+
+typedef enum {
+ TR_OK = 0,
+ TR_EWRITE = 1 /**< Error writing packet command (transport) */,
+ TR_EREAD = 2 /**< Error reading packet data (transport) */,
+ TR_UNDERRUN = 3 /**< Read underrun */,
+ TR_OVERRUN = 4 /**< Read overrun */,
+ TR_ILLEGAL = 5 /**< Illegal/rejected request */,
+ TR_MEDIUM = 6 /**< Medium error */,
+ TR_BUSY = 7 /**< Device busy */,
+ TR_NOTREADY = 8 /**< Device not ready */,
+ TR_FAULT = 9 /**< Device failure */,
+ TR_UNKNOWN = 10 /**< Unspecified error */,
+ TR_STREAMING = 11 /**< loss of streaming */,
+} transport_error_t;
+
+
+#ifdef NEED_STRERROR_TR
+const char *strerror_tr[]={
+ "Success",
+ "Error writing packet command to device",
+ "Error reading command from device",
+ "SCSI packet data underrun (too little data)",
+ "SCSI packet data overrun (too much data)",
+ "Illegal SCSI request (rejected by target)",
+ "Medium reading data from medium",
+ "Device busy",
+ "Device not ready",
+ "Target hardware fault",
+ "Unspecified error",
+ "Drive lost streaming"
+};
+#endif /*NEED_STERROR_TR*/
+
+/** Errors returned by lib:
+
+\verbatim
+001: Unable to set CDROM to read audio mode
+002: Unable to read table of contents lead-out
+003: CDROM reporting illegal number of tracks
+004: Unable to read table of contents header
+005: Unable to read table of contents entry
+006: Could not read any data from drive
+007: Unknown, unrecoverable error reading data
+008: Unable to identify CDROM model
+009: CDROM reporting illegal table of contents
+010: Unaddressable sector
+
+100: Interface not supported
+101: Drive is neither a CDROM nor a WORM device
+102: Permision denied on cdrom (ioctl) device
+103: Permision denied on cdrom (data) device
+
+300: Kernel memory error
+
+400: Device not open
+401: Invalid track number
+402: Track not audio data
+403: No audio tracks on disc
+\endverbatim
+
+*/
+
+#ifndef DO_NOT_WANT_PARANOIA_COMPATIBILITY
+/** For compatibility with good ol' paranoia */
+#define cdda_find_a_cdrom cdio_cddap_find_a_cdrom
+#define cdda_identify cdio_cddap_identify
+#define cdda_speed_set cdio_cddap_speed_set
+#define cdda_verbose_set cdio_cddap_verbose_set
+#define cdda_messages cdio_cddap_messages
+#define cdda_errors cdio_cddap_errors
+#define cdda_close cdio_cddap_close
+#define cdda_open cdio_cddap_open
+#define cdda_read cdio_cddap_read
+#define cdda_track_firstsector cdio_cddap_track_firstsector
+#define cdda_track_lastsector cdio_cddap_track_lastsector
+#define cdda_tracks cdio_cddap_tracks
+#define cdda_sector_gettrack cdio_cddap_sector_gettrack
+#define cdda_track_channels cdio_cddap_track_channels
+#define cdda_track_audiop cdio_cddap_track_audiop
+#define cdda_track_copyp cdio_cddap_track_copyp
+#define cdda_track_preemp cdio_cddap_track_preemp
+#define cdda_disc_firstsector cdio_cddap_disc_firstsector
+#define cdda_disc_lastsector cdio_cddap_disc_lastsector
+#define cdrom_drive cdrom_drive_t
+
+#endif /*DO_NOT_WANT_PARANOIA_COMPATIBILITY*/
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+/** The below variables are trickery to force the above enum symbol
+ values to be recorded in debug symbol tables. They are used to
+ allow one to refer to the enumeration value names in the typedefs
+ above in a debugger and debugger expressions
+*/
+
+extern paranoia_jitter_t debug_paranoia_jitter;
+extern paranoia_cdda_enums_t debug_paranoia_cdda_enums;
+
+#endif /*_CDDA_INTERFACE_H_*/
+
diff --git a/lib-x86-32/include/cdio/cdio.h b/lib-x86-32/include/cdio/cdio.h
new file mode 100644
index 00000000..84e54b10
--- /dev/null
+++ b/lib-x86-32/include/cdio/cdio.h
@@ -0,0 +1,84 @@
+/* -*- c -*-
+ $Id: cdio.h,v 1.82 2008/03/25 15:59:08 karl Exp $
+
+ Copyright (C) 2003, 2004, 2005, 2008 Rocky Bernstein <rocky@gnu.org>
+ Copyright (C) 2001 Herbert Valerio Riedel <hvr@gnu.org>
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/** \file cdio.h
+ *
+ * \brief The top-level header for libcdio: the CD Input and Control
+ * library. Applications include this for anything regarding libcdio.
+ */
+
+
+#ifndef __CDIO_H__
+#define __CDIO_H__
+
+/** Application Interface or Protocol version number. If the public
+ * interface changes, we increase this number.
+ */
+#define CDIO_API_VERSION 5
+
+#include <cdio/version.h>
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include <cdio/types.h>
+#include <cdio/sector.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* For compatibility. */
+#define CdIo CdIo_t
+
+ /** This is an opaque structure for the CD object. */
+ typedef struct _CdIo CdIo_t;
+
+ /** This is an opaque structure for the CD-Text object. */
+ typedef struct cdtext cdtext_t;
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+/* Drive(r)/Device-related functions. Perhaps we should break out
+ Driver from device?
+*/
+#include <cdio/device.h>
+
+/* Disc-related functions. */
+#include <cdio/disc.h>
+
+/* Sector (frame, or block)-related functions. Uses driver_return_code_t
+ from <cdio/device.h> so it should come after that.
+*/
+#include <cdio/read.h>
+
+/* CD-Text-related functions. */
+#include <cdio/cdtext.h>
+
+/* Track-related functions. */
+#include <cdio/track.h>
+
+#endif /* __CDIO_H__ */
diff --git a/lib-x86-32/include/cdio/cdio_config.h b/lib-x86-32/include/cdio/cdio_config.h
new file mode 100644
index 00000000..2005b888
--- /dev/null
+++ b/lib-x86-32/include/cdio/cdio_config.h
@@ -0,0 +1,258 @@
+/** \file cdio_config.h
+ * \brief configuration-time settings useful in compilation; a run-time
+ version of config.h
+*/
+/* config.h. Generated from config.h.in by configure. */
+/* config.h.in. Generated from configure.ac by autoheader. */
+
+/* Define if building universal (internal helper macro) */
+/* #undef AC_APPLE_UNIVERSAL_BUILD */
+
+/* Define 1 if you are compiling using cygwin */
+/* #undef CYGWIN */
+
+/* what to put between the brackets for empty arrays */
+#define EMPTY_ARRAY_SIZE
+
+/* Define 1 if you have BSDI-type CD-ROM support */
+/* #undef HAVE_BSDI_CDROM */
+
+/* Define to 1 if you have the `bzero' function. */
+#define HAVE_BZERO 1
+
+/* Define this if you have libcddb installed */
+#define HAVE_CDDB /**/
+
+/* Define to 1 if you have the <CoreFoundation/CFBase.h> header file. */
+/* #undef HAVE_COREFOUNDATION_CFBASE_H */
+
+/* Define to 1 if you have the <curses.h> header file. */
+/* #undef HAVE_CURSES_H */
+
+/* Define 1 if you have Darwin OS X-type CD-ROM support */
+/* #undef HAVE_DARWIN_CDROM */
+
+/* Define if time.h defines extern long timezone and int daylight vars. */
+#define HAVE_DAYLIGHT 1
+
+/* Define to 1 if you have the Apple DiskArbitration framework */
+/* #undef HAVE_DISKARBITRATION */
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#define HAVE_DLFCN_H 1
+
+/* Define to 1 if you have the `drand48' function. */
+#define HAVE_DRAND48 1
+
+/* Define to 1 if you have the <dvd.h> header file. */
+/* #undef HAVE_DVD_H */
+
+/* Define to 1 if you have the <errno.h> header file. */
+#define HAVE_ERRNO_H 1
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#define HAVE_FCNTL_H 1
+
+/* Define 1 if you have FreeBSD CD-ROM support */
+/* #undef HAVE_FREEBSD_CDROM */
+
+/* Define to 1 if fseeko (and presumably ftello) exists and is declared. */
+/* #undef HAVE_FSEEKO */
+
+/* Define to 1 if you have the `ftruncate' function. */
+#define HAVE_FTRUNCATE 1
+
+/* Define to 1 if you have the `geteuid' function. */
+#define HAVE_GETEUID 1
+
+/* Define to 1 if you have the `getgid' function. */
+#define HAVE_GETGID 1
+
+/* Define to 1 if you have the <getopt.h> header file. */
+#define HAVE_GETOPT_H 1
+
+/* Define to 1 if you have the `getpwuid' function. */
+#define HAVE_GETPWUID 1
+
+/* Define to 1 if you have the `gettimeofday' function. */
+#define HAVE_GETTIMEOFDAY 1
+
+/* Define to 1 if you have the `getuid' function. */
+#define HAVE_GETUID 1
+
+/* Define to 1 if you have the <glob.h> header file. */
+#define HAVE_GLOB_H 1
+
+/* Define to 1 if you have the `gmtime_r' function. */
+#define HAVE_GMTIME_R 1
+
+/* Define if you have the iconv() function and it works. */
+#define HAVE_ICONV 1
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the <IOKit/IOKitLib.h> header file. */
+/* #undef HAVE_IOKIT_IOKITLIB_H */
+
+/* Supports ISO _Pragma() macro */
+#define HAVE_ISOC99_PRAGMA /**/
+
+/* Define 1 if you want ISO-9660 Joliet extension support. You must have also
+ libiconv installed to get Joliet extension support. */
+#define HAVE_JOLIET 1
+
+/* Define this if your libcurses has keypad */
+#define HAVE_KEYPAD /**/
+
+/* Define if you have <langinfo.h> and nl_langinfo(CODESET). */
+#define HAVE_LANGINFO_CODESET 1
+
+/* Define to 1 if you have the `nsl' library (-lnsl). */
+/* #undef HAVE_LIBNSL */
+
+/* Define to 1 if you have the `socket' library (-lsocket). */
+/* #undef HAVE_LIBSOCKET */
+
+/* Define to 1 if you have the <limits.h> header file. */
+#define HAVE_LIMITS_H 1
+
+/* Define 1 if you have Linux-type CD-ROM support */
+#define HAVE_LINUX_CDROM 1
+
+/* Define to 1 if you have the <linux/cdrom.h> header file. */
+#define HAVE_LINUX_CDROM_H 1
+
+/* Define 1 if timeout is in cdrom_generic_command struct */
+/* #undef HAVE_LINUX_CDROM_TIMEOUT */
+
+/* Define to 1 if you have the <linux/major.h> header file. */
+#define HAVE_LINUX_MAJOR_H 1
+
+/* Define to 1 if you have the <linux/version.h> header file. */
+#define HAVE_LINUX_VERSION_H 1
+
+/* Define to 1 if you have the `localtime_r' function. */
+#define HAVE_LOCALTIME_R 1
+
+/* Define to 1 if you have the `lstat' function. */
+#define HAVE_LSTAT 1
+
+/* Define to 1 if you have the `memcpy' function. */
+#define HAVE_MEMCPY 1
+
+/* Define to 1 if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the `memset' function. */
+#define HAVE_MEMSET 1
+
+/* Define to 1 if you have the <ncurses.h> header file. */
+#define HAVE_NCURSES_H 1
+
+/* Define 1 if you have NetBSD CD-ROM support */
+/* #undef HAVE_NETBSD_CDROM */
+
+/* Define 1 if you have OS/2 CD-ROM support */
+/* #undef HAVE_OS2_CDROM */
+
+/* Define to 1 if you have the <pwd.h> header file. */
+#define HAVE_PWD_H 1
+
+/* Define to 1 if you have the `rand' function. */
+#define HAVE_RAND 1
+
+/* Define to 1 if you have the `readlink' function. */
+#define HAVE_READLINK 1
+
+/* Define 1 if you want ISO-9660 Rock-Ridge extension support. */
+#define HAVE_ROCK 1
+
+/* Define to 1 if you have the `setegid' function. */
+#define HAVE_SETEGID 1
+
+/* Define to 1 if you have the `setenv' function. */
+#define HAVE_SETENV 1
+
+/* Define to 1 if you have the `seteuid' function. */
+#define HAVE_SETEUID 1
+
+/* Define to 1 if you have the `sleep' function. */
+#define HAVE_SLEEP 1
+
+/* Define to 1 if you have the `snprintf' function. */
+#define HAVE_SNPRINTF 1
+
+/* Define 1 if you have Solaris CD-ROM support */
+/* #undef HAVE_SOLARIS_CDROM */
+
+/* Define to 1 if you have the <stdarg.h> header file. */
+#define HAVE_STDARG_H 1
+
+/* Define to 1 if you have the <stdbool.h> header file. */
+#define HAVE_STDBOOL_H 1
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdio.h> header file. */
+#define HAVE_STDIO_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define this if you have struct timespec */
+#define HAVE_STRUCT_TIMESPEC /**/
+
+/* Define to 1 if you have the <sys/cdio.h> header file. */
+/* #undef HAVE_SYS_CDIO_H */
+
+/* Define to 1 if you have the <sys/param.h> header file. */
+#define HAVE_SYS_PARAM_H 1
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/timeb.h> header file. */
+#define HAVE_SYS_TIMEB_H 1
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#define HAVE_SYS_TIME_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <sys/utsname.h> header file. */
+#define HAVE_SYS_UTSNAME_H 1
+
+/* Define this <sys/stat.h> defines S_ISLNK() */
+#define HAVE_S_ISLNK /**/
+
+/* Define this <sys/stat.h> defines S_ISSOCK() */
+#define HAVE_S_ISSOCK /**/
+
+/* Define to 1 if timegm is available */
+#define HAVE_TIMEGM 1
+
+/* Define if you have an extern long timenzone variable. */
+#define HAVE_TIMEZONE_VAR 1
+
+/* Define if struct tm has the tm_gmtoff member. */
+#define HAVE_TM_GMTOFF 1
+
+/* Define if time.h defines extern extern char *tzname[2] variable */
+#define HAVE_TZNAME 1
+
+/* Define to 1 if you have the `tzset' function. */
+#define HAVE_TZSET 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Define to 1 if you have the `unsetenv' function. */
diff --git a/lib-x86-32/include/cdio/cdtext.h b/lib-x86-32/include/cdio/cdtext.h
new file mode 100644
index 00000000..daac733f
--- /dev/null
+++ b/lib-x86-32/include/cdio/cdtext.h
@@ -0,0 +1,125 @@
+/*
+ $Id: cdtext.h,v 1.14 2008/03/25 15:59:08 karl Exp $
+
+ Copyright (C) 2004, 2005, 2008 Rocky Bernstein <rocky@gnu.org>
+ adapted from cuetools
+ Copyright (C) 2003 Svend Sanjay Sorensen <ssorensen@fastmail.fm>
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*!
+ * \file cdtext.h
+ *
+ * \brief The top-level header for CD-Text information. Applications
+ * include this for CD-Text access.
+*/
+
+
+#ifndef __CDIO_CDTEXT_H__
+#define __CDIO_CDTEXT_H__
+
+#include <cdio/cdio.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define MAX_CDTEXT_FIELDS 13
+#define MIN_CDTEXT_FIELD 0
+
+ /*! \brief structure for holding CD-Text information
+
+ @see cdtext_init, cdtext_destroy, cdtext_get, and cdtext_set.
+ */
+ struct cdtext {
+ char *field[MAX_CDTEXT_FIELDS];
+ };
+
+ /*! \brief A list of all of the CD-Text fields. Because
+ the interval has no gaps, we can use ++ to iterate over fields.
+ */
+ typedef enum {
+ CDTEXT_ARRANGER = 0, /**< name(s) of the arranger(s) */
+ CDTEXT_COMPOSER = 1, /**< name(s) of the composer(s) */
+ CDTEXT_DISCID = 2, /**< disc identification information */
+ CDTEXT_GENRE = 3, /**< genre identification and genre information */
+ CDTEXT_MESSAGE = 4, /**< ISRC code of each track */
+ CDTEXT_ISRC = 5, /**< message(s) from the content provider or artist */
+ CDTEXT_PERFORMER = 6, /**< name(s) of the performer(s) */
+ CDTEXT_SIZE_INFO = 7, /**< size information of the block */
+ CDTEXT_SONGWRITER = 8, /**< name(s) of the songwriter(s) */
+ CDTEXT_TITLE = 9, /**< title of album name or track titles */
+ CDTEXT_TOC_INFO = 10, /**< table of contents information */
+ CDTEXT_TOC_INFO2 = 11, /**< second table of contents information */
+ CDTEXT_UPC_EAN = 12,
+ CDTEXT_INVALID = MAX_CDTEXT_FIELDS
+ } cdtext_field_t;
+
+ /*! Return string representation of the enum values above */
+ const char *cdtext_field2str (cdtext_field_t i);
+
+ /*! Initialize a new cdtext structure.
+ When the structure is no longer needed, release the
+ resources using cdtext_delete.
+ */
+ void cdtext_init (cdtext_t *cdtext);
+
+ /*! Free memory assocated with cdtext*/
+ void cdtext_destroy (cdtext_t *cdtext);
+
+ /*! returns an allocated string associated with the given field. NULL is
+ returned if key is CDTEXT_INVALID or the field is not set.
+
+ The user needs to free the string when done with it.
+
+ @see cdio_get_const to retrieve a constant string that doesn't
+ have to be freed.
+ */
+ char *cdtext_get (cdtext_field_t key, const cdtext_t *cdtext);
+
+ /*! returns a const string associated with the given field. NULL is
+ returned if key is CDTEXT_INVALID or the field is not set.
+
+ Don't use the string when the cdtext object (i.e. the CdIo_t object
+ you got it from) is no longer valid.
+
+ @see cdio_get to retrieve an allocated string that persists past
+ the cdtext object.
+ */
+ const char *cdtext_get_const (cdtext_field_t key, const cdtext_t *cdtext);
+
+ /*!
+ returns enum of keyword if key is a CD-Text keyword,
+ returns MAX_CDTEXT_FIELDS non-zero otherwise.
+ */
+ cdtext_field_t cdtext_is_keyword (const char *key);
+
+ /*!
+ sets cdtext's keyword entry to field
+ */
+ void cdtext_set (cdtext_field_t key, const char *value, cdtext_t *cdtext);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __CDIO_CDTEXT_H__ */
+
+/*
+ * Local variables:
+ * c-file-style: "gnu"
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/lib-x86-32/include/cdio/device.h b/lib-x86-32/include/cdio/device.h
new file mode 100644
index 00000000..cc84e79a
--- /dev/null
+++ b/lib-x86-32/include/cdio/device.h
@@ -0,0 +1,995 @@
+/* -*- c -*-
+ $Id: device.h,v 1.39 2008/03/28 01:28:50 rocky Exp $
+
+ Copyright (C) 2005, 2006, 2008, 2009 Rocky Bernstein <rocky@gnu.org>
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/** \file device.h
+ *
+ * \brief C header for driver- or device-related libcdio
+ * calls. ("device" includes CD-image reading devices).
+ */
+#ifndef __CDIO_DEVICE_H__
+#define __CDIO_DEVICE_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+ /*! The type of an drive capability bit mask. See below for values*/
+ typedef uint32_t cdio_drive_read_cap_t;
+ typedef uint32_t cdio_drive_write_cap_t;
+ typedef uint32_t cdio_drive_misc_cap_t;
+
+ /*!
+ \brief Drive capability bits returned by cdio_get_drive_cap()
+ NOTE: Setting a bit here means the presence of a capability.
+ */
+
+ /** Miscellaneous capabilities. */
+ typedef enum {
+ CDIO_DRIVE_CAP_ERROR = 0x40000, /**< Error */
+ CDIO_DRIVE_CAP_UNKNOWN = 0x80000, /**< Dunno. It can be on if we
+ have only partial information
+ or are not completely certain
+ */
+ CDIO_DRIVE_CAP_MISC_CLOSE_TRAY = 0x00001, /**< caddy systems can't
+ close... */
+ CDIO_DRIVE_CAP_MISC_EJECT = 0x00002, /**< but can eject. */
+ CDIO_DRIVE_CAP_MISC_LOCK = 0x00004, /**< disable manual eject */
+ CDIO_DRIVE_CAP_MISC_SELECT_SPEED = 0x00008, /**< programmable speed */
+ CDIO_DRIVE_CAP_MISC_SELECT_DISC = 0x00010, /**< select disc from
+ juke-box */
+ CDIO_DRIVE_CAP_MISC_MULTI_SESSION= 0x00020, /**< read sessions>1 */
+ CDIO_DRIVE_CAP_MISC_MEDIA_CHANGED= 0x00080, /**< media changed */
+ CDIO_DRIVE_CAP_MISC_RESET = 0x00100, /**< hard reset device */
+ CDIO_DRIVE_CAP_MISC_FILE = 0x20000 /**< drive is really a file,
+ i.e a CD file image */
+ } cdio_drive_cap_misc_t;
+
+ /*! Reading masks.. */
+ typedef enum {
+ CDIO_DRIVE_CAP_READ_AUDIO = 0x00001, /**< drive can play CD audio */
+ CDIO_DRIVE_CAP_READ_CD_DA = 0x00002, /**< drive can read CD-DA */
+ CDIO_DRIVE_CAP_READ_CD_G = 0x00004, /**< drive can read CD+G */
+ CDIO_DRIVE_CAP_READ_CD_R = 0x00008, /**< drive can read CD-R */
+ CDIO_DRIVE_CAP_READ_CD_RW = 0x00010, /**< drive can read CD-RW */
+ CDIO_DRIVE_CAP_READ_DVD_R = 0x00020, /**< drive can read DVD-R */
+ CDIO_DRIVE_CAP_READ_DVD_PR = 0x00040, /**< drive can read DVD+R */
+ CDIO_DRIVE_CAP_READ_DVD_RAM = 0x00080, /**< drive can read DVD-RAM */
+ CDIO_DRIVE_CAP_READ_DVD_ROM = 0x00100, /**< drive can read DVD-ROM */
+ CDIO_DRIVE_CAP_READ_DVD_RW = 0x00200, /**< drive can read DVD-RW */
+ CDIO_DRIVE_CAP_READ_DVD_RPW = 0x00400, /**< drive can read DVD+RW */
+ CDIO_DRIVE_CAP_READ_C2_ERRS = 0x00800, /**< has C2 error correction */
+ CDIO_DRIVE_CAP_READ_MODE2_FORM1 = 0x01000, /**< can read mode 2 form 1 */
+ CDIO_DRIVE_CAP_READ_MODE2_FORM2 = 0x02000, /**< can read mode 2 form 2 */
+ CDIO_DRIVE_CAP_READ_MCN = 0x04000, /**< can read MCN */
+ CDIO_DRIVE_CAP_READ_ISRC = 0x08000 /**< can read ISRC */
+ } cdio_drive_cap_read_t;
+
+ /*! Writing masks.. */
+ typedef enum {
+ CDIO_DRIVE_CAP_WRITE_CD_R = 0x00001, /**< drive can write CD-R */
+ CDIO_DRIVE_CAP_WRITE_CD_RW = 0x00002, /**< drive can write CD-RW */
+ CDIO_DRIVE_CAP_WRITE_DVD_R = 0x00004, /**< drive can write DVD-R */
+ CDIO_DRIVE_CAP_WRITE_DVD_PR = 0x00008, /**< drive can write DVD+R */
+ CDIO_DRIVE_CAP_WRITE_DVD_RAM = 0x00010, /**< drive can write DVD-RAM */
+ CDIO_DRIVE_CAP_WRITE_DVD_RW = 0x00020, /**< drive can write DVD-RW */
+ CDIO_DRIVE_CAP_WRITE_DVD_RPW = 0x00040, /**< drive can write DVD+RW */
+ CDIO_DRIVE_CAP_WRITE_MT_RAINIER = 0x00080, /**< Mount Rainier */
+ CDIO_DRIVE_CAP_WRITE_BURN_PROOF = 0x00100, /**< burn proof */
+ CDIO_DRIVE_CAP_WRITE_CD =
+ (CDIO_DRIVE_CAP_WRITE_CD_R | CDIO_DRIVE_CAP_WRITE_CD_RW),
+ /**< Has some sort of CD writer ability */
+
+ CDIO_DRIVE_CAP_WRITE_DVD =
+ (CDIO_DRIVE_CAP_WRITE_DVD_R | CDIO_DRIVE_CAP_WRITE_DVD_PR
+ | CDIO_DRIVE_CAP_WRITE_DVD_RAM | CDIO_DRIVE_CAP_WRITE_DVD_RW
+ | CDIO_DRIVE_CAP_WRITE_DVD_RPW ),
+ /**< Has some sort of DVD writer ability */
+
+ CDIO_DRIVE_CAP_WRITE =
+ (CDIO_DRIVE_CAP_WRITE_CD | CDIO_DRIVE_CAP_WRITE_DVD)
+ /**< Has some sort of DVD or CD writing ability */
+ } cdio_drive_cap_write_t;
+
+/*! Size of fields returned by an INQUIRY command */
+ typedef enum {
+ CDIO_MMC_HW_VENDOR_LEN = 8, /**< length of vendor field */
+ CDIO_MMC_HW_MODEL_LEN = 16, /**< length of model field */
+ CDIO_MMC_HW_REVISION_LEN = 4 /**< length of revision field */
+ } cdio_mmc_hw_len_t;
+
+
+ /*! \brief Structure to return CD vendor, model, and revision-level
+ strings obtained via the INQUIRY command */
+ typedef struct cdio_hwinfo
+ {
+ char psz_vendor [CDIO_MMC_HW_VENDOR_LEN+1];
+ char psz_model [CDIO_MMC_HW_MODEL_LEN+1];
+ char psz_revision[CDIO_MMC_HW_REVISION_LEN+1];
+ } cdio_hwinfo_t;
+
+
+ /** Flags specifying the category of device to open or is opened. */
+ typedef enum {
+ CDIO_SRC_IS_DISK_IMAGE_MASK = 0x0001, /**< Read source is a CD image. */
+ CDIO_SRC_IS_DEVICE_MASK = 0x0002, /**< Read source is a CD device. */
+ CDIO_SRC_IS_SCSI_MASK = 0x0004, /**< Read source SCSI device. */
+ CDIO_SRC_IS_NATIVE_MASK = 0x0008
+ } cdio_src_category_mask_t;
+
+
+ /** The driver_id_t enumerations may be used to tag a specific driver
+ * that is opened or is desired to be opened. Note that this is
+ * different than what is available on a given host.
+ *
+ * Order should not be changed lightly because it breaks the ABI.
+ * One is not supposed to iterate over the values, but iterate over the
+ * cdio_drivers and cdio_device_drivers arrays.
+ *
+ * NOTE: IF YOU MODIFY ENUM MAKE SURE INITIALIZATION IN CDIO.C AGREES.
+ *
+ */
+ typedef enum {
+ DRIVER_UNKNOWN, /**< Used as input when we don't care what kind
+ of driver to use. */
+ DRIVER_AIX, /**< AIX driver */
+ DRIVER_BSDI, /**< BSDI driver */
+ DRIVER_FREEBSD, /**< FreeBSD driver - includes CAM and ioctl access */
+ DRIVER_NETBSD, /**< NetBSD Driver. */
+ DRIVER_LINUX, /**< GNU/Linux Driver */
+ DRIVER_SOLARIS, /**< Sun Solaris Driver */
+ DRIVER_OS2, /**< IBM OS/2 Driver */
+ DRIVER_OSX, /**< Apple OSX Driver */
+ DRIVER_WIN32, /**< Microsoft Windows Driver. Includes ASPI and
+ ioctl access. */
+ DRIVER_CDRDAO, /**< cdrdao format CD image. This is listed
+ before BIN/CUE, to make the code prefer cdrdao
+ over BIN/CUE when both exist. */
+ DRIVER_BINCUE, /**< CDRWIN BIN/CUE format CD image. This is
+ listed before NRG, to make the code prefer
+ BIN/CUE over NRG when both exist. */
+ DRIVER_NRG, /**< Nero NRG format CD image. */
+ DRIVER_DEVICE /**< Is really a set of the above; should come last */
+ } driver_id_t;
+
+ /** A null-terminated (that is DRIVER_UNKNOWN-terminated) ordered (in
+ order of preference) array of drivers.
+ */
+ extern const driver_id_t cdio_drivers[];
+ /** A null-terminated (that is DRIVER_UNKNOWN-terminated) ordered (in
+ order of preference) array of device drivers.
+ */
+ extern const driver_id_t cdio_device_drivers[];
+
+ /** There will generally be only one hardware for a given
+ build/platform from the list above. You can use the variable
+ below to determine which you've got. If the build doesn't make an
+ hardware driver, then the value will be DRIVER_UNKNOWN.
+ */
+ extern const driver_id_t cdio_os_driver;
+
+
+/** Those are deprecated; use cdio_drivers or cdio_device_drivers to
+ iterate over all drivers or only the device drivers.
+ Make sure what's listed for CDIO_MIN_DRIVER is the last
+ enumeration in driver_id_t. Since we have a bogus (but useful) 0th
+ entry above we don't have to add one.
+*/
+#define CDIO_MIN_DRIVER DRIVER_AIX
+#define CDIO_MIN_DEVICE_DRIVER CDIO_MIN_DRIVER
+#define CDIO_MAX_DRIVER DRIVER_NRG
+#define CDIO_MAX_DEVICE_DRIVER DRIVER_WIN32
+
+ /** The following are status codes for completion of a given cdio
+ operation. By design 0 is successful completion and -1 is error
+ completion. This is compatable with ioctl so those routines that
+ call ioctl can just pass the value the get back (cast as this
+ enum). Also, by using negative numbers for errors, the
+ enumeration values below can be used in places where a positive
+ value is expected when things complete successfully. For example,
+ get_blocksize returns the blocksize, but on error uses the error
+ codes below. So note that this enumeration is often cast to an
+ integer. C seems to tolerate this.
+ */
+ typedef enum {
+ DRIVER_OP_SUCCESS = 0, /**< in cases where an int is returned,
+ like cdio_set_speed, more the negative
+ return codes are for errors and the
+ positive ones for success. */
+ DRIVER_OP_ERROR = -1, /**< operation returned an error */
+ DRIVER_OP_UNSUPPORTED = -2, /**< returned when a particular driver
+ doesn't support a particular operation.
+ For example an image driver which doesn't
+ really "eject" a CD.
+ */
+ DRIVER_OP_UNINIT = -3, /**< returned when a particular driver
+ hasn't been initialized or a null
+ pointer has been passed.
+ */
+ DRIVER_OP_NOT_PERMITTED = -4, /**< Operation not permitted.
+ For example might be a permission
+ problem.
+ */
+ DRIVER_OP_BAD_PARAMETER = -5, /**< Bad parameter passed */
+ DRIVER_OP_BAD_POINTER = -6, /**< Bad pointer to memory area */
+ DRIVER_OP_NO_DRIVER = -7, /**< Operaton called on a driver
+ not available on this OS */
+ } driver_return_code_t;
+
+ /*!
+ Close media tray in CD drive if there is a routine to do so.
+
+ @param psz_drive the name of CD-ROM to be closed. If NULL, we will
+ use the default device.
+ @param p_driver_id is the driver to be used or that got used if
+ it was DRIVER_UNKNOWN or DRIVER_DEVICE; If this is NULL, we won't
+ report back the driver used.
+ */
+ driver_return_code_t cdio_close_tray (const char *psz_drive,
+ /*in/out*/ driver_id_t *p_driver_id);
+
+ /*!
+ @param drc the return code you want interpreted.
+ @return the string information about drc
+ */
+ const char *cdio_driver_errmsg(driver_return_code_t drc);
+
+ /*!
+ Eject media in CD drive if there is a routine to do so.
+
+ @param p_cdio the CD object to be acted upon.
+ If the CD is ejected *p_cdio is free'd and p_cdio set to NULL.
+ */
+ driver_return_code_t cdio_eject_media (CdIo_t **p_cdio);
+
+ /*!
+ Eject media in CD drive if there is a routine to do so.
+
+ @param psz_drive the name of the device to be acted upon.
+ If NULL is given as the drive, we'll use the default driver device.
+ */
+ driver_return_code_t cdio_eject_media_drive (const char *psz_drive);
+
+ /*!
+ Free device list returned by cdio_get_devices or
+ cdio_get_devices_with_cap.
+
+ @param device_list list returned by cdio_get_devices or
+ cdio_get_devices_with_cap
+
+ @see cdio_get_devices, cdio_get_devices_with_cap
+
+ */
+ void cdio_free_device_list (char * device_list[]);
+
+ /*!
+ Get the default CD device.
+ if p_cdio is NULL (we haven't initialized a specific device driver),
+ then find a suitable one and return the default device for that.
+
+ @param p_cdio the CD object queried
+ @return a string containing the default CD device or NULL is
+ if we couldn't get a default device.
+
+ In some situations of drivers or OS's we can't find a CD device if
+ there is no media in it and it is possible for this routine to return
+ NULL even though there may be a hardware CD-ROM.
+ */
+ char * cdio_get_default_device (const CdIo_t *p_cdio);
+
+ /*!
+ Return a string containing the default CD device if none is specified.
+ if p_driver_id is DRIVER_UNKNOWN or DRIVER_DEVICE
+ then find a suitable one set the default device for that.
+
+ NULL is returned if we couldn't get a default device.
+ */
+ char * cdio_get_default_device_driver (/*in/out*/ driver_id_t *p_driver_id);
+
+ /*! Return an array of device names. If you want a specific
+ devices for a driver, give that device. If you want hardware
+ devices, give DRIVER_DEVICE and if you want all possible devices,
+ image drivers and hardware drivers give DRIVER_UNKNOWN.
+
+ NULL is returned if we couldn't return a list of devices.
+
+ In some situations of drivers or OS's we can't find a CD device if
+ there is no media in it and it is possible for this routine to return
+ NULL even though there may be a hardware CD-ROM.
+ */
+ char ** cdio_get_devices (driver_id_t driver_id);
+
+ /*!
+ Get an array of device names in search_devices that have at least
+ the capabilities listed by the capabities parameter. If
+ search_devices is NULL, then we'll search all possible CD drives.
+
+ Capabilities have two parts to them, a "filesystem" part and an
+ "analysis" part.
+
+ The filesystem part is mutually exclusive. For example either the
+ filesystem is at most one of the High-Sierra, UFS, or HFS, ISO9660,
+ fileystems. Valid combinations of say HFS and ISO9660 are
+ specified as a separate "filesystem".
+
+ Capabilities on the other hand are not mutually exclusive. For example
+ a filesystem may have none, either, or both of the XA or Rock-Ridge
+ extension properties.
+
+ If "b_any" is set false then every capability listed in the
+ analysis portion of capabilities (i.e. not the basic filesystem)
+ must be satisified. If no analysis capabilities are specified,
+ that's a match.
+
+ If "b_any" is set true, then if any of the analysis capabilities
+ matches, we call that a success.
+
+ In either case, in the filesystem portion different filesystem
+ either specify 0 to match any filesystem or the specific
+ filesystem type.
+
+ To find a CD-drive of any type, use the mask CDIO_FS_MATCH_ALL.
+
+ @return the array of device names or NULL if we couldn't get a
+ default device. It is also possible to return a non NULL but
+ after dereferencing the the value is NULL. This also means nothing
+ was found.
+ */
+ char ** cdio_get_devices_with_cap (/*in*/ char *ppsz_search_devices[],
+ cdio_fs_anal_t capabilities, bool b_any);
+
+ /*!
+ Like cdio_get_devices_with_cap but we return the driver we found
+ as well. This is because often one wants to search for kind of drive
+ and then *open* it afterwards. Giving the driver back facilitates this,
+ and speeds things up for libcdio as well.
+ */
+ char ** cdio_get_devices_with_cap_ret (/*in*/ char* ppsz_search_devices[],
+ cdio_fs_anal_t capabilities,
+ bool b_any,
+ /*out*/ driver_id_t *p_driver_id);
+
+ /*! Like cdio_get_devices, but we may change the p_driver_id if we
+ were given DRIVER_DEVICE or DRIVER_UNKNOWN. This is because
+ often one wants to get a drive name and then *open* it
+ afterwards. Giving the driver back facilitates this, and speeds
+ things up for libcdio as well.
+ */
+
+ char ** cdio_get_devices_ret (/*in/out*/ driver_id_t *p_driver_id);
+
+ /*!
+ Get the what kind of device we've got.
+
+ @param p_cdio the CD object queried
+ @param p_read_cap pointer to return read capabilities
+ @param p_write_cap pointer to return write capabilities
+ @param p_misc_cap pointer to return miscellaneous other capabilities
+
+ In some situations of drivers or OS's we can't find a CD device if
+ there is no media in it. In this situation capabilities will show up as
+ NULL even though there isa hardware CD-ROM.
+ */
+ void cdio_get_drive_cap (const CdIo_t *p_cdio,
+ cdio_drive_read_cap_t *p_read_cap,
+ cdio_drive_write_cap_t *p_write_cap,
+ cdio_drive_misc_cap_t *p_misc_cap);
+
+ /*!
+ Get the drive capabilities for a specified device.
+
+ Return a list of device capabilities.
+
+ In some situations of drivers or OS's we can't find a CD device if
+ there is no media in it. In this situation capabilities will show up as
+ NULL even though there isa hardware CD-ROM.
+ */
+ void cdio_get_drive_cap_dev (const char *device,
+ cdio_drive_read_cap_t *p_read_cap,
+ cdio_drive_write_cap_t *p_write_cap,
+ cdio_drive_misc_cap_t *p_misc_cap);
+
+ /*!
+ Get a string containing the name of the driver in use.
+
+ @return a string with driver name or NULL if CdIo_t is NULL (we
+ haven't initialized a specific device.
+ */
+ const char * cdio_get_driver_name (const CdIo_t *p_cdio);
+
+ /*!
+ Get the driver id.
+ if CdIo_t is NULL (we haven't initialized a specific device driver),
+ then return DRIVER_UNKNOWN.
+
+ @return the driver id..
+ */
+ driver_id_t cdio_get_driver_id (const CdIo_t *p_cdio);
+
+ /*!
+ Get the CD-ROM hardware info via a SCSI MMC INQUIRY command.
+ False is returned if we had an error getting the information.
+ */
+ bool cdio_get_hwinfo ( const CdIo_t *p_cdio,
+ /*out*/ cdio_hwinfo_t *p_hw_info );
+
+
+ /*! Get the LSN of the first track of the last session of
+ on the CD.
+
+ @param p_cdio the CD object to be acted upon.
+ @param i_last_session pointer to the session number to be returned.
+ */
+ driver_return_code_t cdio_get_last_session (CdIo_t *p_cdio,
+ /*out*/ lsn_t *i_last_session);
+
+ /*!
+ Find out if media has changed since the last call.
+ @param p_cdio the CD object to be acted upon.
+ @return 1 if media has changed since last call, 0 if not. Error
+ return codes are the same as driver_return_code_t
+ */
+ int cdio_get_media_changed(CdIo_t *p_cdio);
+
+ /*! True if CD-ROM understand ATAPI commands. */
+ bool_3way_t cdio_have_atapi (CdIo_t *p_cdio);
+
+ /*! Like cdio_have_xxx but uses an enumeration instead. */
+ bool cdio_have_driver (driver_id_t driver_id);
+
+ /*
+ Free any resources associated with p_cdio. Call this when done using p_cdio
+ and using CD reading/control operations.
+
+ @param p_cdio the CD object to eliminated.
+ */
+ void cdio_destroy (CdIo_t *p_cdio);
+
+ /*!
+ Get a string decribing driver_id.
+
+ @param driver_id the driver you want the description for
+ @return a string of driver description
+ */
+ const char *cdio_driver_describe (driver_id_t driver_id);
+
+ /*! Sets up to read from place specified by psz_source and
+ driver_id. This or cdio_open_* should be called before using any
+ other routine, except cdio_init or any routine that accesses the
+ CD-ROM drive by name. cdio_open will call cdio_init, if that hasn't
+ been done previously.
+
+ @return the cdio object or NULL on error or no device. If NULL
+ is given as the source, we'll use the default driver device.
+ */
+ CdIo_t * cdio_open (const char *psz_source, driver_id_t driver_id);
+
+ /*! Sets up to read from place specified by psz_source, driver_id
+ and access mode. This or cdio_open* should be called before using
+ any other routine, except cdio_init or any routine that accesses
+ the CD-ROM drive by name. This will call cdio_init, if that
+ hasn't been done previously.
+
+ If NULL is given as the source, we'll use the default driver device.
+
+ @return the cdio object or NULL on error or no device.
+ */
+ CdIo_t * cdio_open_am (const char *psz_source,
+ driver_id_t driver_id, const char *psz_access_mode);
+
+ /*! Set up BIN/CUE CD disk-image for reading. Source is the .bin or
+ .cue file
+
+ @return the cdio object or NULL on error or no device.
+ */
+ CdIo_t * cdio_open_bincue (const char *psz_cue_name);
+
+ /*! Set up BIN/CUE CD disk-image for reading. Source is the .bin or
+ .cue file
+
+ @return the cdio object or NULL on error or no device..
+ */
+ CdIo_t * cdio_open_am_bincue (const char *psz_cue_name,
+ const char *psz_access_mode);
+
+ /*! Set up cdrdao CD disk-image for reading. Source is the .toc file
+
+ @return the cdio object or NULL on error or no device.
+ */
+ CdIo_t * cdio_open_cdrdao (const char *psz_toc_name);
+
+ /*! Set up cdrdao CD disk-image for reading. Source is the .toc file
+
+ @return the cdio object or NULL on error or no device..
+ */
+ CdIo_t * cdio_open_am_cdrdao (const char *psz_toc_name,
+ const char *psz_access_mode);
+
+ /*! Return a string containing the default CUE file that would
+ be used when none is specified.
+
+ @return the cdio object or NULL on error or no device.
+ */
+ char * cdio_get_default_device_bincue(void);
+
+ char **cdio_get_devices_bincue(void);
+
+ /*! @return string containing the default CUE file that would be
+ used when none is specified. NULL is returned on error or there
+ is no device.
+ */
+ char * cdio_get_default_device_cdrdao(void);
+
+ char **cdio_get_devices_cdrdao(void);
+
+ /*! Set up CD-ROM for reading. The device_name is
+ the some sort of device name.
+
+ @return the cdio object for subsequent operations.
+ NULL on error or there is no driver for a some sort of hardware CD-ROM.
+ */
+ CdIo_t * cdio_open_cd (const char *device_name);
+
+ /*! Set up CD-ROM for reading. The device_name is
+ the some sort of device name.
+
+ @return the cdio object for subsequent operations.
+ NULL on error or there is no driver for a some sort of hardware CD-ROM.
+ */
+ CdIo_t * cdio_open_am_cd (const char *psz_device,
+ const char *psz_access_mode);
+
+ /*! CDRWIN BIN/CUE CD disc-image routines. Source is the .cue file
+
+ @return the cdio object for subsequent operations.
+ NULL on error.
+ */
+ CdIo_t * cdio_open_cue (const char *cue_name);
+
+ /*! Set up CD-ROM for reading using the AIX driver. The device_name is
+ the some sort of device name.
+
+ @return the cdio object for subsequent operations.
+ NULL on error or there is no AIX driver.
+
+ @see cdio_open
+ */
+ CdIo_t * cdio_open_am_aix (const char *psz_source,
+ const char *psz_access_mode);
+
+ /*! Set up CD-ROM for reading using the AIX driver. The device_name is
+ the some sort of device name.
+
+ @return the cdio object for subsequent operations.
+ NULL on error or there is no AIX driver.
+
+ @see cdio_open
+ */
+ CdIo_t * cdio_open_aix (const char *psz_source);
+
+ /*! Return a string containing the default device name that the
+ AIX driver would use when none is specified.
+
+ @return the cdio object for subsequent operations.
+ NULL on error or there is no AIX driver.
+
+ @see cdio_open_cd, cdio_open
+ */
+ char * cdio_get_default_device_aix(void);
+
+ /*! Return a list of all of the CD-ROM devices that the AIX driver
+ can find.
+
+ In some situations of drivers or OS's we can't find a CD device if
+ there is no media in it and it is possible for this routine to return
+ NULL even though there may be a hardware CD-ROM.
+ */
+ char **cdio_get_devices_aix(void);
+
+ /*! Set up CD-ROM for reading using the BSDI driver. The device_name is
+ the some sort of device name.
+
+ @param psz_source the name of the device to open
+ @return the cdio object for subsequent operations.
+ NULL on error or there is no BSDI driver.
+
+ @see cdio_open
+ */
+ CdIo_t * cdio_open_bsdi (const char *psz_source);
+
+ /*! Set up CD-ROM for reading using the BSDI driver. The device_name is
+ the some sort of device name.
+
+ @return the cdio object for subsequent operations.
+ NULL on error or there is no BSDI driver.
+
+ @see cdio_open
+ */
+ CdIo_t * cdio_open_am_bsdi (const char *psz_source,
+ const char *psz_access_mode);
+
+ /*! Return a string containing the default device name that the
+ BSDI driver would use when none is specified.
+
+ @return the cdio object for subsequent operations.
+ NULL on error or there is no BSDI driver.
+
+ @see cdio_open_cd, cdio_open
+ */
+ char * cdio_get_default_device_bsdi(void);
+
+ /*! Return a list of all of the CD-ROM devices that the BSDI driver
+ can find.
+
+ In some situations of drivers or OS's we can't find a CD device if
+ there is no media in it and it is possible for this routine to return
+ NULL even though there may be a hardware CD-ROM.
+ */
+ char **cdio_get_devices_bsdi(void);
+
+ /*! Set up CD-ROM for reading using the FreeBSD driver. The device_name is
+ the some sort of device name.
+
+ NULL is returned on error or there is no FreeBSD driver.
+
+ @see cdio_open_cd, cdio_open
+ */
+ CdIo_t * cdio_open_freebsd (const char *paz_psz_source);
+
+ /*! Set up CD-ROM for reading using the FreeBSD driver. The device_name is
+ the some sort of device name.
+
+ NULL is returned on error or there is no FreeBSD driver.
+
+ @see cdio_open_cd, cdio_open
+ */
+ CdIo_t * cdio_open_am_freebsd (const char *psz_source,
+ const char *psz_access_mode);
+
+ /*! Return a string containing the default device name that the
+ FreeBSD driver would use when none is specified.
+
+ NULL is returned on error or there is no CD-ROM device.
+ */
+ char * cdio_get_default_device_freebsd(void);
+
+ /*! Return a list of all of the CD-ROM devices that the FreeBSD driver
+ can find.
+ */
+ char **cdio_get_devices_freebsd(void);
+
+ /*! Set up CD-ROM for reading using the GNU/Linux driver. The device_name is
+ the some sort of device name.
+
+ @return the cdio object for subsequent operations.
+ NULL on error or there is no GNU/Linux driver.
+
+ In some situations of drivers or OS's we can't find a CD device if
+ there is no media in it and it is possible for this routine to return
+ NULL even though there may be a hardware CD-ROM.
+ */
+ CdIo_t * cdio_open_linux (const char *psz_source);
+
+ /*! Set up CD-ROM for reading using the GNU/Linux driver. The
+ device_name is the some sort of device name.
+
+ @return the cdio object for subsequent operations.
+ NULL on error or there is no GNU/Linux driver.
+ */
+ CdIo_t * cdio_open_am_linux (const char *psz_source,
+ const char *access_mode);
+
+ /*! Return a string containing the default device name that the
+ GNU/Linux driver would use when none is specified. A scan is made
+ for CD-ROM drives with CDs in them.
+
+ NULL is returned on error or there is no CD-ROM device.
+
+ In some situations of drivers or OS's we can't find a CD device if
+ there is no media in it and it is possible for this routine to return
+ NULL even though there may be a hardware CD-ROM.
+
+ @see cdio_open_cd, cdio_open
+ */
+ char * cdio_get_default_device_linux(void);
+
+ /*! Return a list of all of the CD-ROM devices that the GNU/Linux driver
+ can find.
+ */
+ char **cdio_get_devices_linux(void);
+
+ /*! Set up CD-ROM for reading using the Sun Solaris driver. The
+ device_name is the some sort of device name.
+
+ @return the cdio object for subsequent operations.
+ NULL on error or there is no Solaris driver.
+ */
+ CdIo_t * cdio_open_solaris (const char *psz_source);
+
+ /*! Set up CD-ROM for reading using the Sun Solaris driver. The
+ device_name is the some sort of device name.
+
+ @return the cdio object for subsequent operations.
+ NULL on error or there is no Solaris driver.
+ */
+ CdIo_t * cdio_open_am_solaris (const char *psz_source,
+ const char *psz_access_mode);
+
+ /*! Return a string containing the default device name that the
+ Solaris driver would use when none is specified. A scan is made
+ for CD-ROM drives with CDs in them.
+
+ NULL is returned on error or there is no CD-ROM device.
+
+ In some situations of drivers or OS's we can't find a CD device if
+ there is no media in it and it is possible for this routine to return
+ NULL even though there may be a hardware CD-ROM.
+
+ @see cdio_open_cd, cdio_open
+ */
+ char * cdio_get_default_device_solaris(void);
+
+ /*! Return a list of all of the CD-ROM devices that the Solaris driver
+ can find.
+ */
+ char **cdio_get_devices_solaris(void);
+
+ /*! Set up CD-ROM for reading using the Apple OSX driver. The
+ device_name is the some sort of device name.
+
+ NULL is returned on error or there is no OSX driver.
+
+ In some situations of drivers or OS's we can't find a CD device if
+ there is no media in it and it is possible for this routine to return
+ NULL even though there may be a hardware CD-ROM.
+
+ @see cdio_open_cd, cdio_open
+ */
+ CdIo_t * cdio_open_osx (const char *psz_source);
+
+ /*! Set up CD-ROM for reading using the Apple OSX driver. The
+ device_name is the some sort of device name.
+
+ NULL is returned on error or there is no OSX driver.
+
+ @see cdio_open_cd, cdio_open
+ */
+ CdIo_t * cdio_open_am_osx (const char *psz_source,
+ const char *psz_access_mode);
+
+ /*! Return a string containing the default device name that the
+ OSX driver would use when none is specified. A scan is made
+ for CD-ROM drives with CDs in them.
+
+ In some situations of drivers or OS's we can't find a CD device if
+ there is no media in it and it is possible for this routine to return
+ NULL even though there may be a hardware CD-ROM.
+ */
+ char * cdio_get_default_device_osx(void);
+
+ /*! Return a list of all of the CD-ROM devices that the OSX driver
+ can find.
+ */
+ char **cdio_get_devices_osx(void);
+
+ /*! Set up CD-ROM for reading using the Microsoft Windows driver. The
+ device_name is the some sort of device name.
+
+ In some situations of drivers or OS's we can't find a CD device if
+ there is no media in it and it is possible for this routine to return
+ NULL even though there may be a hardware CD-ROM.
+ */
+ CdIo_t * cdio_open_win32 (const char *psz_source);
+
+ /*! Set up CD-ROM for reading using the Microsoft Windows driver. The
+ device_name is the some sort of device name.
+
+ NULL is returned on error or there is no Microsof Windows driver.
+ */
+ CdIo_t * cdio_open_am_win32 (const char *psz_source,
+ const char *psz_access_mode);
+
+ /*! Return a string containing the default device name that the
+ Win32 driver would use when none is specified. A scan is made
+ for CD-ROM drives with CDs in them.
+
+ In some situations of drivers or OS's we can't find a CD device if
+ there is no media in it and it is possible for this routine to return
+ NULL even though there may be a hardware CD-ROM.
+
+ @see cdio_open_cd, cdio_open
+ */
+ char * cdio_get_default_device_win32(void);
+
+ char **cdio_get_devices_win32(void);
+
+ /*! Set up CD-ROM for reading using the IBM OS/2 driver. The
+ device_name is the some sort of device name.
+
+ NULL is returned on error or there is no OS/2 driver.
+
+ In some situations of drivers or OS's we can't find a CD device if
+ there is no media in it and it is possible for this routine to return
+ NULL even though there may be a hardware CD-ROM.
+
+ @see cdio_open_cd, cdio_open
+ */
+ CdIo_t * cdio_open_os2 (const char *psz_source);
+
+ /*! Set up CD-ROM for reading using the IBM OS/2 driver. The
+ device_name is the some sort of device name.
+
+ NULL is returned on error or there is no OS/2 driver.
+
+ @see cdio_open_cd, cdio_open
+ */
+ CdIo_t * cdio_open_am_os2 (const char *psz_source,
+ const char *psz_access_mode);
+
+ /*! Return a string containing the default device name that the
+ OS/2 driver would use when none is specified. A scan is made
+ for CD-ROM drives with CDs in them.
+
+ In some situations of drivers or OS's we can't find a CD device if
+ there is no media in it and it is possible for this routine to return
+ NULL even though there may be a hardware CD-ROM.
+ */
+ char * cdio_get_default_device_os2(void);
+
+ /*! Return a list of all of the CD-ROM devices that the OS/2 driver
+ can find.
+ */
+ char **cdio_get_devices_os2(void);
+
+ /*! Set up CD-ROM for reading using the Nero driver. The
+ device_name is the some sort of device name.
+
+ @return true on success; NULL on error or there is no Nero driver.
+ */
+ CdIo_t * cdio_open_nrg (const char *psz_source);
+
+ /*! Set up CD-ROM for reading using the Nero driver. The
+ device_name is the some sort of device name.
+
+ @return true on success; NULL on error or there is no Nero driver.
+ */
+ CdIo_t * cdio_open_am_nrg (const char *psz_source,
+ const char *psz_access_mode);
+
+ /*! Get a string containing the default device name that the NRG
+ driver would use when none is specified. A scan is made for NRG
+ disk images in the current directory.
+
+ @return string containing the default device. NULL on error or
+ there is no CD-ROM device.
+ */
+ char * cdio_get_default_device_nrg(void);
+
+ char **cdio_get_devices_nrg(void);
+
+ /*!
+
+ Determine if bin_name is the bin file part of a CDRWIN CD disk image.
+
+ @param bin_name location of presumed CDRWIN bin image file.
+ @return the corresponding CUE file if bin_name is a BIN file or
+ NULL if not a BIN file.
+ */
+ char *cdio_is_binfile(const char *bin_name);
+
+ /*!
+ Determine if cue_name is the cue sheet for a CDRWIN CD disk image.
+
+ @return corresponding BIN file if cue_name is a CDRWIN cue file or
+ NULL if not a CUE file.
+ */
+ char *cdio_is_cuefile(const char *cue_name);
+
+ /*!
+ Determine if psg_nrg is a Nero CD disc image.
+
+ @param psz_nrg location of presumed NRG image file.
+ @return true if psz_nrg is a Nero NRG image or false
+ if not a NRG image.
+ */
+ bool cdio_is_nrg(const char *psz_nrg);
+
+ /*!
+ Determine if psz_toc is a TOC file for a cdrdao CD disc image.
+
+ @param psz_toc location of presumed TOC image file.
+ @return true if toc_name is a cdrdao TOC file or false
+ if not a TOC file.
+ */
+ bool cdio_is_tocfile(const char *psz_toc);
+
+ /*!
+ Determine if psz_source refers to a real hardware CD-ROM.
+
+ @param psz_source location name of object
+ @param driver_id driver for reading object. Use DRIVER_UNKNOWN if you
+ don't know what driver to use.
+ @return true if psz_source is a device; If false is returned we
+ could have a CD disk image.
+ */
+ bool cdio_is_device(const char *psz_source, driver_id_t driver_id);
+
+ /*!
+ Set the blocksize for subsequent reads.
+ */
+ driver_return_code_t cdio_set_blocksize ( const CdIo_t *p_cdio,
+ int i_blocksize );
+
+ /*!
+ Set the drive speed.
+
+ @param p_cdio CD structure set by cdio_open().
+ @param i_drive_speed speed in CD-ROM speed units. Note this
+ not Kbs as would be used in the MMC spec or
+ in mmc_set_speed(). To convert CD-ROM speed units
+ to Kbs, multiply the number by 176 (for raw data)
+ and by 150 (for filesystem data). On many CD-ROM
+ drives, specifying a value too large will result
+ in using the fastest speed.
+
+ @see mmc_set_speed and mmc_set_drive_speed
+ */
+ driver_return_code_t cdio_set_speed ( const CdIo_t *p_cdio,
+ int i_drive_speed );
+
+ /*!
+ Get the value associatied with key.
+
+ @param p_cdio the CD object queried
+ @param key the key to retrieve
+ @return the value associatd with "key" or NULL if p_cdio is NULL
+ or "key" does not exist.
+ */
+ const char * cdio_get_arg (const CdIo_t *p_cdio, const char key[]);
+
+ /*!
+ Set the arg "key" with "value" in "p_cdio".
+
+ @param p_cdio the CD object to set
+ @param key the key to set
+ @param value the value to assocaiate with key
+ */
+ driver_return_code_t cdio_set_arg (CdIo_t *p_cdio, const char key[],
+ const char value[]);
+
+ /*!
+ Initialize CD Reading and control routines. Should be called first.
+ */
+ bool cdio_init(void);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+/** The below variables are trickery to force the above enum symbol
+ values to be recorded in debug symbol tables. They are used to
+ allow one to refer to the enumeration value names in the typedefs
+ above in a debugger and debugger expressions.
+*/
+extern cdio_drive_cap_misc_t debug_cdio_drive_cap_misc;
+extern cdio_drive_cap_read_t debug_cdio_drive_cap_read_t;
+extern cdio_drive_cap_write_t debug_drive_cap_write_t;
+extern cdio_mmc_hw_len_t debug_cdio_mmc_hw_len;
+extern cdio_src_category_mask_t debug_cdio_src_category_mask;
+
+#endif /* __CDIO_DEVICE_H__ */
diff --git a/lib-x86-32/include/cdio/disc.h b/lib-x86-32/include/cdio/disc.h
new file mode 100644
index 00000000..b5ae3c49
--- /dev/null
+++ b/lib-x86-32/include/cdio/disc.h
@@ -0,0 +1,108 @@
+/* -*- c -*-
+ $Id: disc.h,v 1.9 2008/03/25 15:59:09 karl Exp $
+
+ Copyright (C) 2004, 2005, 2006, 2008 Rocky Bernstein <rocky@gnu.org>
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/** \file disc.h
+ * \brief The top-level header for disc-related libcdio calls.
+ */
+#ifndef __CDIO_DISC_H__
+#define __CDIO_DISC_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+ /*! disc modes. The first combined from MMC-3 5.29.2.8 (Send CUESHEET)
+ and GNU/Linux /usr/include/linux/cdrom.h and we've added DVD.
+ */
+ typedef enum {
+ CDIO_DISC_MODE_CD_DA, /**< CD-DA */
+ CDIO_DISC_MODE_CD_DATA, /**< CD-ROM form 1 */
+ CDIO_DISC_MODE_CD_XA, /**< CD-ROM XA form2 */
+ CDIO_DISC_MODE_CD_MIXED, /**< Some combo of above. */
+ CDIO_DISC_MODE_DVD_ROM, /**< DVD ROM (e.g. movies) */
+ CDIO_DISC_MODE_DVD_RAM, /**< DVD-RAM */
+ CDIO_DISC_MODE_DVD_R, /**< DVD-R */
+ CDIO_DISC_MODE_DVD_RW, /**< DVD-RW */
+ CDIO_DISC_MODE_DVD_PR, /**< DVD+R */
+ CDIO_DISC_MODE_DVD_PRW, /**< DVD+RW */
+ CDIO_DISC_MODE_DVD_OTHER, /**< Unknown/unclassified DVD type */
+ CDIO_DISC_MODE_NO_INFO,
+ CDIO_DISC_MODE_ERROR,
+ CDIO_DISC_MODE_CD_I /**< CD-i. */
+ } discmode_t;
+
+ extern const char *discmode2str[];
+
+ /*!
+ Get disc mode - the kind of CD (CD-DA, CD-ROM mode 1, CD-MIXED, etc.
+ that we've got. The notion of "CD" is extended a little to include
+ DVD's.
+ */
+ discmode_t cdio_get_discmode (CdIo_t *p_cdio);
+
+ /*!
+ Get the lsn of the end of the CD
+
+ @return the lsn. On error 0 or CDIO_INVALD_LSN.
+ */
+ lsn_t cdio_get_disc_last_lsn(const CdIo_t *p_cdio);
+
+ /*!
+ Return the Joliet level recognized for p_cdio.
+ */
+ uint8_t cdio_get_joliet_level(const CdIo_t *p_cdio);
+
+ /*!
+ Get the media catalog number (MCN) from the CD.
+
+ @return the media catalog number or NULL if there is none or we
+ don't have the ability to get it.
+
+ Note: string is malloc'd so caller has to free() the returned
+ string when done with it.
+
+ */
+ char * cdio_get_mcn (const CdIo_t *p_cdio);
+
+ /*!
+ Get the number of tracks on the CD.
+
+ @return the number of tracks, or CDIO_INVALID_TRACK if there is
+ an error.
+ */
+ track_t cdio_get_num_tracks (const CdIo_t *p_cdio);
+
+ /*!
+ Return true if discmode is some sort of CD.
+ */
+ bool cdio_is_discmode_cdrom (discmode_t discmode);
+
+ /*!
+ Return true if discmode is some sort of DVD.
+ */
+ bool cdio_is_discmode_dvd (discmode_t discmode);
+
+ /*! cdio_stat_size is deprecated. @see cdio_get_disc_last_lsn */
+#define cdio_stat_size cdio_get_disc_last_lsn
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __CDIO_DISC_H__ */
diff --git a/lib-x86-32/include/cdio/ds.h b/lib-x86-32/include/cdio/ds.h
new file mode 100644
index 00000000..447e30df
--- /dev/null
+++ b/lib-x86-32/include/cdio/ds.h
@@ -0,0 +1,98 @@
+/*
+ $Id: ds.h,v 1.5 2008/03/25 15:59:09 karl Exp $
+
+ Copyright (C) 2005, 2008 Rocky Bernstein <rocky@gnu.org>
+ Copyright (C) 2000, 2004 Herbert Valerio Riedel <hvr@gnu.org>
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/** \file ds.h
+ * \brief The top-level header for list-related data structures.
+
+ Note: this header will is slated to get removed and libcdio will use
+ glib.h routines instead.
+*/
+
+
+#ifndef __CDIO_DS_H__
+#define __CDIO_DS_H__
+
+#include <cdio/types.h>
+
+/** opaque types... */
+typedef struct _CdioList CdioList_t;
+typedef struct _CdioListNode CdioListNode_t;
+
+typedef int (*_cdio_list_cmp_func_t) (void *p_data1, void *p_data2);
+typedef int (*_cdio_list_iterfunc_t) (void *p_data, void *p_user_data);
+
+/** The below are given compatibility with old code. Please use
+ the above type names, not these. */
+#define CdioList CdioList_t
+#define CdioListNode CdioListNode_t
+#define _cdio_list_cmp_func _cdio_list_cmp_func_t
+#define _cdio_list_iterfunc _cdio_list_iterfunc_t
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/** methods */
+CdioList_t *_cdio_list_new (void);
+
+void _cdio_list_free (CdioList_t *p_list, int free_data);
+
+unsigned _cdio_list_length (const CdioList_t *list);
+
+void _cdio_list_prepend (CdioList_t *p_list, void *p_data);
+
+void _cdio_list_append (CdioList_t *p_list, void *p_data);
+
+void _cdio_list_foreach (CdioList_t *p_list, _cdio_list_iterfunc_t func,
+ void *p_user_data);
+
+CdioListNode_t *_cdio_list_find (CdioList_t *p_list,
+ _cdio_list_iterfunc_t cmp_func,
+ void *p_user_data);
+
+#define _CDIO_LIST_FOREACH(node, list) \
+ for (node = _cdio_list_begin (list); node; node = _cdio_list_node_next (node))
+
+/** node operations */
+
+CdioListNode_t *_cdio_list_begin (const CdioList_t *p_list);
+
+CdioListNode_t *_cdio_list_end (CdioList_t *p_list);
+
+CdioListNode_t *_cdio_list_node_next (CdioListNode_t *p_node);
+
+void _cdio_list_node_free (CdioListNode_t *p_node, int i_free_data);
+
+void *_cdio_list_node_data (CdioListNode_t *p_node);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __CDIO_DS_H__ */
+
+/*
+ * Local variables:
+ * c-file-style: "gnu"
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ */
+
diff --git a/lib-x86-32/include/cdio/dvd.h b/lib-x86-32/include/cdio/dvd.h
new file mode 100644
index 00000000..8be8317b
--- /dev/null
+++ b/lib-x86-32/include/cdio/dvd.h
@@ -0,0 +1,112 @@
+/*
+ $Id: dvd.h,v 1.5 2008/03/25 15:59:09 karl Exp $
+
+ Copyright (C) 2004 Rocky Bernstein <rocky@gnu.org>
+ Modeled after GNU/Linux definitions in linux/cdrom.h
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*!
+ \file dvd.h
+ \brief Definitions for DVD access.
+*/
+
+#ifndef __CDIO_DVD_H__
+#define __CDIO_DVD_H__
+
+#include <cdio/types.h>
+
+/*! Values used in a READ DVD STRUCTURE */
+
+#define CDIO_DVD_STRUCT_PHYSICAL 0x00
+#define CDIO_DVD_STRUCT_COPYRIGHT 0x01
+#define CDIO_DVD_STRUCT_DISCKEY 0x02
+#define CDIO_DVD_STRUCT_BCA 0x03
+#define CDIO_DVD_STRUCT_MANUFACT 0x04
+
+/*! Media definitions for "Book Type" */
+#define CDIO_DVD_BOOK_DVD_ROM 0
+#define CDIO_DVD_BOOK_DVD_RAM 1
+#define CDIO_DVD_BOOK_DVD_R 2 /**< DVD-R */
+#define CDIO_DVD_BOOK_DVD_RW 3 /**< DVD-RW */
+#define CDIO_DVD_BOOK_DVD_PR 8 /**< DVD+R */
+#define CDIO_DVD_BOOK_DVD_PRW 9 /**< DVD+RW */
+
+typedef struct cdio_dvd_layer {
+ uint8_t book_version : 4;
+ uint8_t book_type : 4;
+ uint8_t min_rate : 4;
+ uint8_t disc_size : 4;
+ uint8_t layer_type : 4;
+ uint8_t track_path : 1;
+ uint8_t nlayers : 2;
+ uint8_t track_density : 4;
+ uint8_t linear_density: 4;
+ uint8_t bca : 1;
+ uint32_t start_sector;
+ uint32_t end_sector;
+ uint32_t end_sector_l0;
+} cdio_dvd_layer_t;
+
+/*! Maximum number of layers in a DVD. */
+#define CDIO_DVD_MAX_LAYERS 4
+
+typedef struct cdio_dvd_physical {
+ uint8_t type;
+ uint8_t layer_num;
+ cdio_dvd_layer_t layer[CDIO_DVD_MAX_LAYERS];
+} cdio_dvd_physical_t;
+
+typedef struct cdio_dvd_copyright {
+ uint8_t type;
+
+ uint8_t layer_num;
+ uint8_t cpst;
+ uint8_t rmi;
+} cdio_dvd_copyright_t;
+
+typedef struct cdio_dvd_disckey {
+ uint8_t type;
+
+ unsigned agid : 2;
+ uint8_t value[2048];
+} cdio_dvd_disckey_t;
+
+typedef struct cdio_dvd_bca {
+ uint8_t type;
+
+ int len;
+ uint8_t value[188];
+} cdio_dvd_bca_t;
+
+typedef struct cdio_dvd_manufact {
+ uint8_t type;
+
+ uint8_t layer_num;
+ int len;
+ uint8_t value[2048];
+} cdio_dvd_manufact_t;
+
+typedef union {
+ uint8_t type;
+
+ cdio_dvd_physical_t physical;
+ cdio_dvd_copyright_t copyright;
+ cdio_dvd_disckey_t disckey;
+ cdio_dvd_bca_t bca;
+ cdio_dvd_manufact_t manufact;
+} cdio_dvd_struct_t;
+
+#endif /* __SCSI_MMC_H__ */
diff --git a/lib-x86-32/include/cdio/ecma_167.h b/lib-x86-32/include/cdio/ecma_167.h
new file mode 100644
index 00000000..78da7ae0
--- /dev/null
+++ b/lib-x86-32/include/cdio/ecma_167.h
@@ -0,0 +1,1006 @@
+/*
+ Copyright (c) 2005, 2006, 2008 Rocky Bernstein <rocky@cpan.org>
+ Copyright (c) 2001-2002 Ben Fennema <bfennema@falcon.csc.calpoly.edu>
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * Some portions taken from FreeBSD ecma167-udf.h which states:
+ * Copyright (c) 2001, 2002 Scott Long <scottl@freebsd.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*!
+ * \file ecma_167.h
+ *
+ * \brief Definitions based on ECMA-167 3rd edition (June 1997)
+ * See http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-167.pdf
+*/
+
+#ifndef _ECMA_167_H
+#define _ECMA_167_H 1
+
+#include <cdio/types.h>
+
+/**
+ Imagine the below enum values as \#define'd values rather than
+ distinct values of an enum.
+*/
+typedef enum {
+ VSD_STD_ID_SIZE = 5, /** Volume Structure Descriptor (ECMA 167r3
+ 2/9.1) */
+ UDF_REGID_ID_SIZE = 23, /**< See identifier (ECMA 167r3 1/7.4) */
+ UDF_VOLID_SIZE = 32,
+ UDF_FID_SIZE = 38,
+ UDF_VOLSET_ID_SIZE = 128
+} ecma_167_enum1_t ;
+
+/** Tag Identifier (ECMA 167r3 3/7.2.1) */
+
+typedef enum {
+ TAGID_PRI_VOL = 0x0001,
+ TAGID_ANCHOR = 0x0002,
+ TAGID_VOL = 0x0003,
+ TAGID_IMP_VOL = 0x0004,
+ TAGID_PARTITION = 0x0005,
+ TAGID_LOGVOL = 0x0006,
+ TAGID_UNALLOC_SPACE = 0x0007,
+ TAGID_TERM = 0x0008,
+ TAGID_LOGVOL_INTEGRITY = 0x0009,
+ TAGID_FSD = 0x0100,
+ TAGID_FID = 0x0101,
+ TAGID_AED = 0x0102,
+ TAGID_IE = 0x0103,
+ TAGID_TE = 0x0104,
+ TAGID_FILE_ENTRY = 0x0105,
+ TAGID_EAHD = 0x0106,
+ TAGID_USE = 0x0107,
+ TAGID_SBD = 0x0108,
+ TAGID_PIE = 0x0109,
+ TAGID_EFE = 0x010A,
+} tag_id_t ;
+
+/** Character Set Type (ECMA 167r3 1/7.2.1.1) */
+typedef enum {
+ CHARSPEC_TYPE_CS0 = 0x00, /**< Section 1/7.2.2 */
+ CHARSPEC_TYPE_CS1 = 0x01, /**< Section 1/7.2.3 */
+ CHARSPEC_TYPE_CS2 = 0x02, /**< Section 1/7.2.4 */
+ CHARSPEC_TYPE_CS3 = 0x03, /**< Section 1/7.2.5 */
+ CHARSPEC_TYPE_CS4 = 0x04, /**< Section 1/7.2.6 */
+ CHARSPEC_TYPE_CS5 = 0x05, /**< Section 1/7.2.7 */
+ CHARSPEC_TYPE_CS6 = 0x06, /**< Section 1/7.2.8 */
+ CHARSPEC_TYPE_CS7 = 0x07, /**< Section 1/7.2.9 */
+
+ CHARSPEC_TYPE_CS8 = 0x08, /**< Section 1/7.2.10 */
+} udf_charspec_enum_t;
+
+typedef uint8_t udf_Uint8_t; /*! Section 1/7/1.1 */
+typedef uint16_t udf_Uint16_t; /*! Section 1/7.1.3 */
+typedef uint32_t udf_Uint32_t; /*! Section 1/7.1.5 */
+typedef uint64_t udf_Uint64_t; /*! Section 1/7.1.7 */
+typedef char udf_dstring; /*! Section 1/7.1.12 */
+
+#define UDF_LENGTH_MASK 0x3fffffff
+
+PRAGMA_BEGIN_PACKED
+
+/** Character set specification (ECMA 167r3 1/7.2.1) */
+struct udf_charspec_s
+{
+ udf_Uint8_t charset_type;
+ udf_Uint8_t charset_info[63];
+} GNUC_PACKED;
+
+typedef struct udf_charspec_s udf_charspec_t;
+
+/** Timestamp (ECMA 167r3 1/7.3) */
+struct udf_timestamp_s
+{
+ udf_Uint16_t type_tz;
+ udf_Uint16_t year;
+ udf_Uint8_t month;
+ udf_Uint8_t day;
+ udf_Uint8_t hour;
+ udf_Uint8_t minute;
+ udf_Uint8_t second;
+ udf_Uint8_t centiseconds;
+ udf_Uint8_t hundreds_of_microseconds;
+ udf_Uint8_t microseconds;
+} GNUC_PACKED;
+
+typedef struct udf_timestamp_s udf_timestamp_t;
+
+/** Type and Time Zone (ECMA 167r3 1/7.3.1)
+
+ Imagine the below enum values as \#define'd values rather than
+ distinct values of an enum.
+*/
+typedef enum {
+ TIMESTAMP_TYPE_CUT = 0x0000,
+ TIMESTAMP_TYPE_LOCAL = 0x1000,
+ TIMESTAMP_TYPE_AGREEMENT = 0x2000,
+ TIMESTAMP_TYPE_MASK = 0xF000,
+ TIMESTAMP_TIMEZONE_MASK = 0x0FFF,
+} ecma_167_timezone_enum_t ;
+
+
+#define TIMESTAMP_TYPE_MASK 0xF000
+#define TIMESTAMP_TYPE_CUT 0x0000
+#define TIMESTAMP_TYPE_LOCAL 0x1000
+#define TIMESTAMP_TYPE_AGREEMENT 0x2000
+#define TIMESTAMP_TIMEZONE_MASK 0x0FFF
+
+struct udf_id_suffix_s
+{
+ udf_Uint16_t udf_revision;
+ udf_Uint8_t os_class;
+ udf_Uint8_t os_identifier;
+ udf_Uint8_t reserved[4];
+} GNUC_PACKED;
+
+typedef struct udf_id_suffix_s udf_id_suffix_t;
+
+/** Entity identifier (ECMA 167r3 1/7.4) */
+struct udf_regid_s
+{
+ udf_Uint8_t flags;
+ udf_Uint8_t id[UDF_REGID_ID_SIZE];
+ udf_id_suffix_t id_suffix;
+} GNUC_PACKED;
+
+typedef struct udf_regid_s udf_regid_t;
+
+/** Flags (ECMA 167r3 1/7.4.1) */
+#define ENTITYID_FLAGS_DIRTY 0x00
+#define ENTITYID_FLAGS_PROTECTED 0x01
+
+/** Volume Structure Descriptor (ECMA 167r3 2/9.1) */
+struct vol_struct_desc_s
+{
+ udf_Uint8_t struct_type;
+ udf_Uint8_t std_id[VSD_STD_ID_SIZE];
+ udf_Uint8_t struct_version;
+ udf_Uint8_t struct_data[2041];
+} GNUC_PACKED;
+
+/** Standard Identifier (EMCA 167r2 2/9.1.2) */
+#define VSD_STD_ID_NSR02 "NSR02" /* (3/9.1) */
+
+/** Standard Identifier (ECMA 167r3 2/9.1.2) */
+
+/* The below const definitions are to faciltate debugging of the
+ values #define'd below. */
+extern const char VSD_STD_ID_BEA01[sizeof("BEA01")-1];
+extern const char VSD_STD_ID_BOOT2[sizeof("BOOT2")-1];
+extern const char VSD_STD_ID_CD001[sizeof("CD001")-1];
+extern const char VSD_STD_ID_CDW01[sizeof("CDW02")-1];
+extern const char VSD_STD_ID_NSR03[sizeof("NSR03")-1];
+extern const char VSD_STD_ID_TEA01[sizeof("TEA01")-1];
+
+#define VSD_STD_ID_BEA01 "BEA01" /**< ECMA-167 2/9.2 */
+#define VSD_STD_ID_BOOT2 "BOOT2" /**< ECMA-167 2/9.4 */
+#define VSD_STD_ID_CD001 "CD001" /**< ECMA-119 */
+#define VSD_STD_ID_CDW02 "CDW02" /**< ECMA-168 */
+#define VSD_STD_ID_NSR02 "NSR02" /**< ECMA-167, 3/9.1
+ NOTE: ECMA-167, 2nd edition */
+#define VSD_STD_ID_NSR03 "NSR03" /**< ECMA-167 3/9.1 */
+#define VSD_STD_ID_TEA01 "TEA01" /**< ECMA-168 2/9.3 */
+
+/** Beginning Extended Area Descriptor (ECMA 167r3 2/9.2) */
+struct beginning_extended_area_desc_s
+{
+ udf_Uint8_t struct_type;
+ udf_Uint8_t std_id[VSD_STD_ID_SIZE];
+ udf_Uint8_t struct_version;
+ udf_Uint8_t struct_data[2041];
+} GNUC_PACKED;
+
+/** Terminating Extended Area Descriptor (ECMA 167r3 2/9.3) */
+struct terminating_extended_area_desc_s
+{
+ udf_Uint8_t struct_type;
+ udf_Uint8_t std_id[VSD_STD_ID_SIZE];
+ udf_Uint8_t struct_version;
+ udf_Uint8_t struct_data[2041];
+} GNUC_PACKED;
+
+/** Boot Descriptor (ECMA 167r3 2/9.4) */
+struct boot_desc_s
+{
+ udf_Uint8_t struct_type;
+ udf_Uint8_t std_ident[VSD_STD_ID_SIZE];
+ udf_Uint8_t struct_version;
+ udf_Uint8_t reserved1;
+ udf_regid_t arch_type;
+ udf_regid_t boot_ident;
+ udf_Uint32_t bool_ext_location;
+ udf_Uint32_t bool_ext_length;
+ udf_Uint64_t load_address;
+ udf_Uint64_t start_address;
+ udf_timestamp_t desc_creation_time;
+ udf_Uint16_t flags;
+ udf_Uint8_t reserved2[32];
+ udf_Uint8_t boot_use[1906];
+} GNUC_PACKED;
+
+/** Flags (ECMA 167r3 2/9.4.12) */
+#define BOOT_FLAGS_ERASE 0x01
+
+/** Extent Descriptor (ECMA 167r3 3/7.1) */
+struct udf_extent_ad_s
+{
+ udf_Uint32_t len;
+ udf_Uint32_t loc;
+} GNUC_PACKED;
+
+typedef struct udf_extent_ad_s udf_extent_ad_t;
+
+/** Descriptor Tag (ECMA 167r3 3/7.2) */
+struct udf_tag_s
+{
+ udf_Uint16_t id;
+ udf_Uint16_t desc_version;
+ udf_Uint8_t cksum;
+ udf_Uint8_t reserved;
+ udf_Uint16_t i_serial;
+ udf_Uint16_t desc_CRC;
+ udf_Uint16_t desc_CRC_len;
+ udf_Uint32_t loc;
+} GNUC_PACKED;
+
+typedef struct udf_tag_s udf_tag_t;
+
+/** NSR Descriptor (ECMA 167r3 3/9.1) */
+struct NSR_desc_s
+{
+ udf_Uint8_t struct_type;
+ udf_Uint8_t std_id[VSD_STD_ID_SIZE];
+ udf_Uint8_t struct_version;
+ udf_Uint8_t reserved;
+ udf_Uint8_t struct_data[2040];
+} GNUC_PACKED;
+
+/** Primary Volume Descriptor (ECMA 167r3 3/10.1) */
+struct udf_pvd_s
+{
+ udf_tag_t tag;
+ udf_Uint32_t vol_desc_seq_num;
+ udf_Uint32_t primary_vol_desc_num;
+ udf_dstring vol_ident[UDF_VOLID_SIZE];
+ udf_Uint16_t vol_seq_num;
+ udf_Uint16_t max_vol_seqnum;
+ udf_Uint16_t interchange_lvl;
+ udf_Uint16_t max_interchange_lvl;
+ udf_Uint32_t charset_list;
+ udf_Uint32_t max_charset_list;
+ udf_dstring volset_id[UDF_VOLSET_ID_SIZE];
+ udf_charspec_t desc_charset;
+ udf_charspec_t explanatory_charset;
+ udf_extent_ad_t vol_abstract;
+ udf_extent_ad_t vol_copyright;
+ udf_regid_t app_ident;
+ udf_timestamp_t recording_time;
+ udf_regid_t imp_ident;
+ udf_Uint8_t imp_use[64];
+ udf_Uint32_t predecessor_vol_desc_seq_location;
+ udf_Uint16_t flags;
+ udf_Uint8_t reserved[22];
+} GNUC_PACKED;
+
+typedef struct udf_pvd_s udf_pvd_t;
+
+/** Flags (ECMA 167r3 3/10.1.21) */
+#define PVD_FLAGS_VSID_COMMON 0x0001
+
+/** Anchor Volume Descriptor Pointer (ECMA 167r3 3/10.2) */
+struct anchor_vol_desc_ptr_s
+{
+ udf_tag_t tag;
+ udf_extent_ad_t main_vol_desc_seq_ext;
+ udf_extent_ad_t reserve_vol_desc_seq_ext;
+ udf_Uint8_t reserved[480];
+} GNUC_PACKED;
+
+typedef struct anchor_vol_desc_ptr_s anchor_vol_desc_ptr_t;
+
+/** Volume Descriptor Pointer (ECMA 167r3 3/10.3) */
+struct vol_desc_ptr_s
+{
+ udf_tag_t tag;
+ udf_Uint32_t vol_desc_seq_num;
+ udf_extent_ad_t next_vol_desc_set_ext;
+ udf_Uint8_t reserved[484];
+} GNUC_PACKED;
+
+/** Implementation Use Volume Descriptor (ECMA 167r3 3/10.4) */
+struct imp_use_vol_desc_s
+{
+ udf_tag_t tag;
+ udf_Uint32_t vol_desc_seq_num;
+ udf_regid_t imp_id;
+ udf_Uint8_t imp_use[460];
+} GNUC_PACKED;
+
+/** Partition Descriptor (ECMA 167r3 3/10.5) */
+struct partition_desc_s
+{
+ udf_tag_t tag;
+ udf_Uint32_t vol_desc_seq_num;
+ udf_Uint16_t flags;
+ udf_Uint16_t number; /**< Partition number */
+ udf_regid_t contents;
+ udf_Uint8_t contents_use[128];
+ udf_Uint32_t access_type;
+ udf_Uint32_t start_loc;
+ udf_Uint32_t part_len;
+ udf_regid_t imp_id;
+ udf_Uint8_t imp_use[128];
+ udf_Uint8_t reserved[156];
+} GNUC_PACKED;
+
+typedef struct partition_desc_s partition_desc_t;
+
+/** Partition Flags (ECMA 167r3 3/10.5.3) */
+#define PD_PARTITION_FLAGS_ALLOC 0x0001
+
+/** Partition Contents (ECMA 167r2 3/10.5.3) */
+#define PD_PARTITION_CONTENTS_NSR02 "+NSR02"
+
+/** Partition Contents (ECMA 167r3 3/10.5.5) */
+#define PD_PARTITION_CONTENTS_FDC01 "+FDC01"
+#define PD_PARTITION_CONTENTS_CD001 "+CD001"
+#define PD_PARTITION_CONTENTS_CDW02 "+CDW02"
+#define PD_PARTITION_CONTENTS_NSR03 "+NSR03"
+
+/** Access Type (ECMA 167r3 3/10.5.7) */
+#define PD_ACCESS_TYPE_NONE 0x00000000
+#define PD_ACCESS_TYPE_READ_ONLY 0x00000001
+#define PD_ACCESS_TYPE_WRITE_ONCE 0x00000002
+#define PD_ACCESS_TYPE_REWRITABLE 0x00000003
+#define PD_ACCESS_TYPE_OVERWRITABLE 0x00000004
+
+/** Recorded Address (ECMA 167r3 4/7.1) */
+struct udf_lb_addr_s
+{
+ udf_Uint32_t lba;
+ udf_Uint16_t partitionReferenceNum;
+} GNUC_PACKED;
+
+typedef struct udf_lb_addr_s udf_lb_addr_t;
+
+/** Short Allocation Descriptor (ECMA 167r3 4/14.14.1) */
+struct udf_short_ad_s
+{
+ udf_Uint32_t len;
+ udf_Uint32_t pos;
+} GNUC_PACKED;
+
+typedef struct udf_short_ad_s udf_short_ad_t;
+
+/** Long Allocation Descriptor (ECMA 167r3 4/14.14.2) */
+struct udf_long_ad_s
+{
+ udf_Uint32_t len;
+ udf_lb_addr_t loc;
+ udf_Uint8_t imp_use[6];
+} GNUC_PACKED;
+
+typedef struct udf_long_ad_s udf_long_ad_t;
+
+/** Logical Volume Descriptor (ECMA 167r3 3/10.6) */
+struct logical_vol_desc_s
+{
+ udf_tag_t tag;
+ udf_Uint32_t seq_num;
+ udf_charspec_t desc_charset;
+ udf_dstring logvol_id[128];
+ udf_Uint32_t logical_blocksize;
+ udf_regid_t domain_id;
+ union {
+ udf_long_ad_t fsd_loc;
+ udf_Uint8_t logvol_content_use[16];
+ } lvd_use;
+ udf_Uint8_t logvol_contents_use[16];
+ udf_Uint32_t maptable_len;
+ udf_Uint32_t i_partition_maps;
+ udf_regid_t imp_id;
+ udf_Uint8_t imp_use[128];
+ udf_extent_ad_t integrity_seq_ext;
+ udf_Uint8_t partition_maps[0];
+} GNUC_PACKED;
+
+typedef struct logical_vol_desc_s logical_vol_desc_t;
+
+/** Generic Partition Map (ECMA 167r3 3/10.7.1) */
+struct generic_partition_map
+{
+ udf_Uint8_t partition_map_type;
+ udf_Uint8_t partition_map_length;
+ udf_Uint8_t partition_mapping[0];
+} GNUC_PACKED;
+
+/** Partition Map Type (ECMA 167r3 3/10.7.1.1) */
+#define GP_PARTITION_MAP_TYPE_UNDEF 0x00
+#define GP_PARTIITON_MAP_TYPE_1 0x01
+#define GP_PARTITION_MAP_TYPE_2 0x02
+
+/** Type 1 Partition Map (ECMA 167r3 3/10.7.2) */
+struct generic_partition_map1
+{
+ udf_Uint8_t partition_map_type;
+ udf_Uint8_t partition_map_length;
+ udf_Uint16_t vol_seq_num;
+ udf_Uint16_t i_partition;
+} GNUC_PACKED;
+
+/** Type 2 Partition Map (ECMA 167r3 3/10.7.3) */
+struct generic_partition_map2
+{
+ udf_Uint8_t partition_map_type;
+ udf_Uint8_t partition_map_length;
+ udf_Uint8_t partition_id[62];
+} GNUC_PACKED;
+
+/** Unallocated Space Descriptor (ECMA 167r3 3/10.8) */
+struct unalloc_space_desc_s
+{
+ udf_tag_t tag;
+ udf_Uint32_t vol_desc_seq_num;
+ udf_Uint32_t i_alloc_descs;
+ udf_extent_ad_t allocDescs[0];
+} GNUC_PACKED;
+
+/** Terminating Descriptor (ECMA 167r3 3/10.9) */
+struct terminating_desc_s
+{
+ udf_tag_t tag;
+ udf_Uint8_t reserved[496];
+} GNUC_PACKED;
+
+/** Logical Volume Integrity Descriptor (ECMA 167r3 3/10.10) */
+struct logvol_integrity_desc_s
+{
+ udf_tag_t tag;
+ udf_timestamp_t recording_time;
+ udf_Uint32_t integrity_type;
+ udf_extent_ad_t next_integrity_ext;
+ udf_Uint8_t logvol_contents_use[32];
+ udf_Uint32_t i_partitions;
+ udf_Uint32_t imp_use_len;
+ udf_Uint32_t freespace_table[0];
+ udf_Uint32_t size_table[0];
+ udf_Uint8_t imp_use[0];
+} GNUC_PACKED;
+
+/** Integrity Type (ECMA 167r3 3/10.10.3) */
+#define LVID_INTEGRITY_TYPE_OPEN 0x00000000
+#define LVID_INTEGRITY_TYPE_CLOSE 0x00000001
+
+/** Extended Allocation Descriptor (ECMA 167r3 4/14.14.3) */
+struct udf_ext_ad_s
+{
+ udf_Uint32_t len;
+ udf_Uint32_t recorded_len;
+ udf_Uint32_t information_len;
+ udf_lb_addr_t ext_loc;
+} GNUC_PACKED;
+
+typedef struct udf_ext_ad_s udf_ext_ad_t;
+
+/** Descriptor Tag (ECMA 167r3 4/7.2 - See 3/7.2) */
+
+/** Tag Identifier (ECMA 167r3 4/7.2.1) */
+
+/** File Set Descriptor (ECMA 167r3 4/14.1) */
+struct udf_fsd_s
+{
+ udf_tag_t tag;
+ udf_timestamp_t recording_time;
+ udf_Uint16_t interchange_lvl;
+ udf_Uint16_t maxInterchange_lvl;
+ udf_Uint32_t charset_list;
+ udf_Uint32_t max_charset_list;
+ udf_Uint32_t fileset_num;
+ udf_Uint32_t udf_fsd_num;
+ udf_charspec_t logical_vol_id_charset;
+ udf_dstring logical_vol_id[128];
+ udf_charspec_t fileset_charset;
+ udf_dstring fileSet_id[32];
+ udf_dstring copyright_file_id[32];
+ udf_dstring abstract_file_id[32];
+ udf_long_ad_t root_icb;
+ udf_regid_t domain_id;
+ udf_long_ad_t next_ext;
+ udf_long_ad_t stream_directory_ICB;
+ udf_Uint8_t reserved[32];
+} GNUC_PACKED;
+
+typedef struct udf_fsd_s udf_fsd_t;
+
+/** Partition Header Descriptor (ECMA 167r3 4/14.3) */
+struct partition_header_desc_s
+{
+ udf_short_ad_t unalloc_space_table;
+ udf_short_ad_t unalloc_space_bitmap;
+ udf_short_ad_t partition_integrity_table;
+ udf_short_ad_t freed_space_table;
+ udf_short_ad_t freed_space_bitmap;
+ udf_Uint8_t reserved[88];
+} GNUC_PACKED;
+
+typedef struct partition_header_desc_s partition_header_desc_t;
+
+/** File Identifier Descriptor (ECMA 167r3 4/14.4) */
+struct udf_fileid_desc_s
+{
+ udf_tag_t tag;
+ udf_Uint16_t file_version_num;
+ udf_Uint8_t file_characteristics;
+ udf_Uint8_t i_file_id;
+ udf_long_ad_t icb;
+ udf_Uint16_t i_imp_use;
+ udf_Uint8_t imp_use[0];
+ udf_Uint8_t file_id[0];
+ udf_Uint8_t padding[0];
+} GNUC_PACKED;
+
+typedef struct udf_fileid_desc_s udf_fileid_desc_t;
+
+/** File Characteristics (ECMA 167r3 4/14.4.3)
+
+ Imagine the below enumeration values are \#defines to be used in a
+ bitmask rather than distinct values of an enum.
+*/
+typedef enum {
+ UDF_FILE_HIDDEN = (1 << 0),
+ UDF_FILE_DIRECTORY = (1 << 1),
+ UDF_FILE_DELETED = (1 << 2),
+ UDF_FILE_PARENT = (1 << 3),
+ UDF_FILE_METADATA = (1 << 4)
+} file_characteristics_t;
+
+/** Allocation Ext Descriptor (ECMA 167r3 4/14.5) */
+struct allocExtDesc
+{
+ udf_tag_t tag;
+ udf_Uint32_t previous_alloc_ext_loc;
+ udf_Uint32_t i_alloc_descs;
+} GNUC_PACKED;
+
+/** ICB Tag (ECMA 167r3 4/14.6) */
+struct udf_icbtag_s
+{
+ udf_Uint32_t prev_num_dirs;
+ udf_Uint16_t strat_type;
+ udf_Uint16_t strat_param;
+ udf_Uint16_t max_num_entries;
+ udf_Uint8_t reserved;
+ udf_Uint8_t file_type;
+ udf_lb_addr_t parent_ICB;
+ udf_Uint16_t flags;
+} GNUC_PACKED;
+
+typedef struct udf_icbtag_s udf_icbtag_t;
+
+#define UDF_ICB_TAG_FLAGS_SETUID 0x40
+#define UDF_ICB_TAG_FLAGS_SETGID 0x80
+#define UDF_ICB_TAG_FLAGS_STICKY 0x100
+
+/** Strategy Type (ECMA 167r3 4/14.6.2) which helpfully points
+ largely to 4/A.x */
+#define ICBTAG_STRATEGY_TYPE_UNDEF 0x0000
+#define ICBTAG_STRATEGY_TYPE_1 0x0001 /**< 4/A.2 Direct entries Uint16 */
+#define ICBTAG_STRATEGY_TYPE_2 0x0002 /**< 4/A.3 List of ICB direct entries */
+#define ICBTAG_STRATEGY_TYPE_3 0x0003 /**< 4/A.4 */
+#define ICBTAG_STRATEGY_TYPE_4 0x0004 /**< 4/A.5 Hierarchy having one
+ single ICB with one direct entry.
+ This is what's most often used.
+ */
+
+/** File Type (ECMA 167r3 4/14.6.6)
+
+ Imagine the below enum values as \#define'd values rather than
+ distinct values of an enum.
+*/
+typedef enum {
+ ICBTAG_FILE_TYPE_UNDEF = 0x00,
+ ICBTAG_FILE_TYPE_USE = 0x01,
+ ICBTAG_FILE_TYPE_PIE = 0x02,
+ ICBTAG_FILE_TYPE_IE = 0x03,
+ ICBTAG_FILE_TYPE_DIRECTORY = 0x04,
+ ICBTAG_FILE_TYPE_REGULAR = 0x05,
+ ICBTAG_FILE_TYPE_BLOCK = 0x06,
+ ICBTAG_FILE_TYPE_CHAR = 0x07,
+ ICBTAG_FILE_TYPE_EA = 0x08,
+ ICBTAG_FILE_TYPE_FIFO = 0x09,
+ ICBTAG_FILE_TYPE_SOCKET = 0x0A,
+ ICBTAG_FILE_TYPE_TE = 0x0B,
+ ICBTAG_FILE_TYPE_SYMLINK = 0x0C,
+ ICBTAG_FILE_TYPE_STREAMDIR = 0x0D
+} icbtag_file_type_enum_t;
+
+/** Flags (ECMA 167r3 4/14.6.8) */
+typedef enum {
+ ICBTAG_FLAG_AD_MASK = 0x0007, /**< "&" this to get below address
+ flags */
+ ICBTAG_FLAG_AD_SHORT = 0x0000, /**< The allocation descriptor
+ field is filled with
+ short_ad's. If the
+ offset is beyond the
+ current extent, look for
+ the next extent. */
+ ICBTAG_FLAG_AD_LONG = 0x0001, /**< The allocation descriptor
+ field is filled with
+ long_ad's If the offset
+ is beyond the current
+ extent, look for the next
+ extent. */
+ ICBTAG_FLAG_AD_EXTENDED = 0x0002,
+ ICBTAG_FLAG_AD_IN_ICB = 0x0003, /**< This type means that the
+ file *data* is stored in
+ the allocation descriptor
+ field of the file entry. */
+ ICBTAG_FLAG_SORTED = 0x0008,
+ ICBTAG_FLAG_NONRELOCATABLE = 0x0010,
+ ICBTAG_FLAG_ARCHIVE = 0x0020,
+ ICBTAG_FLAG_SETUID = 0x0040,
+ ICBTAG_FLAG_SETGID = 0x0080,
+ ICBTAG_FLAG_STICKY = 0x0100,
+ ICBTAG_FLAG_CONTIGUOUS = 0x0200,
+ ICBTAG_FLAG_SYSTEM = 0x0400,
+ ICBTAG_FLAG_TRANSFORMED = 0x0800,
+ ICBTAG_FLAG_MULTIVERSIONS = 0x1000,
+ ICBTAG_FLAG_STREAM = 0x2000
+} icbtag_flag_enum_t;
+
+/** Indirect Entry (ECMA 167r3 4/14.7) */
+struct indirect_entry_s
+{
+ udf_tag_t tag;
+ udf_icbtag_t icb_tag;
+ udf_long_ad_t indirect_ICB;
+} GNUC_PACKED;
+
+/** Terminal Entry (ECMA 167r3 4/14.8) */
+struct terminal_entry_s
+{
+ udf_tag_t tag;
+ udf_icbtag_t icb_tag;
+} GNUC_PACKED;
+
+/** File Entry (ECMA 167r3 4/14.9) */
+struct udf_file_entry_s
+{
+ udf_tag_t tag;
+ udf_icbtag_t icb_tag; /**< 4/14.9.2 */
+ udf_Uint32_t uid; /**< 4/14.9.3 */
+ udf_Uint32_t gid; /**< 4/14.9.4 */
+ udf_Uint32_t permissions; /**< 4/14.9.5 */
+ udf_Uint16_t link_count; /**< 4/14.9.6 */
+ udf_Uint8_t rec_format; /**< 4/14.9.7 */
+ udf_Uint8_t rec_disp_attr; /**< 4/14.9.8 */
+ udf_Uint32_t rec_len; /**< 4/14.9.9 */
+ udf_Uint64_t info_len; /**< 4/14.9.10 */
+ udf_Uint64_t logblks_recorded; /**< 4/14.9.11 */
+ udf_timestamp_t access_time; /**< 4/14.9.12 - last access to
+ any stream of file prior to
+ recording file entry */
+ udf_timestamp_t modification_time; /**< 4/14.9.13 - last access to
+ modification to any stream of
+ file */
+ udf_timestamp_t attribute_time;
+ udf_Uint32_t checkpoint;
+ udf_long_ad_t ext_attr_ICB;
+ udf_regid_t imp_id;
+ udf_Uint64_t unique_ID;
+ udf_Uint32_t i_extended_attr;
+ udf_Uint32_t i_alloc_descs;
+ udf_Uint8_t ext_attr[0];
+ udf_Uint8_t alloc_descs[0];
+} GNUC_PACKED;
+
+typedef struct udf_file_entry_s udf_file_entry_t;
+
+#define UDF_FENTRY_SIZE 176
+#define UDF_FENTRY_PERM_USER_MASK 0x07
+#define UDF_FENTRY_PERM_GRP_MASK 0xE0
+#define UDF_FENTRY_PERM_OWNER_MASK 0x1C00
+
+/** Permissions (ECMA 167r3 4/14.9.5) */
+#define FE_PERM_O_EXEC 0x00000001U
+#define FE_PERM_O_WRITE 0x00000002U
+#define FE_PERM_O_READ 0x00000004U
+#define FE_PERM_O_CHATTR 0x00000008U
+#define FE_PERM_O_DELETE 0x00000010U
+#define FE_PERM_G_EXEC 0x00000020U
+#define FE_PERM_G_WRITE 0x00000040U
+#define FE_PERM_G_READ 0x00000080U
+#define FE_PERM_G_CHATTR 0x00000100U
+#define FE_PERM_G_DELETE 0x00000200U
+#define FE_PERM_U_EXEC 0x00000400U
+#define FE_PERM_U_WRITE 0x00000800U
+#define FE_PERM_U_READ 0x00001000U
+#define FE_PERM_U_CHATTR 0x00002000U
+#define FE_PERM_U_DELETE 0x00004000U
+
+/** Record Format (ECMA 167r3 4/14.9.7) */
+#define FE_RECORD_FMT_UNDEF 0x00
+#define FE_RECORD_FMT_FIXED_PAD 0x01
+#define FE_RECORD_FMT_FIXED 0x02
+#define FE_RECORD_FMT_VARIABLE8 0x03
+#define FE_RECORD_FMT_VARIABLE16 0x04
+#define FE_RECORD_FMT_VARIABLE16_MSB 0x05
+#define FE_RECORD_FMT_VARIABLE32 0x06
+#define FE_RECORD_FMT_PRINT 0x07
+#define FE_RECORD_FMT_LF 0x08
+#define FE_RECORD_FMT_CR 0x09
+#define FE_RECORD_FMT_CRLF 0x0A
+#define FE_RECORD_FMT_LFCR 0x0B
+
+/** Record Display Attributes (ECMA 167r3 4/14.9.8) */
+#define FE_RECORD_DISPLAY_ATTR_UNDEF 0x00
+#define FE_RECORD_DISPLAY_ATTR_1 0x01
+#define FE_RECORD_DISPLAY_ATTR_2 0x02
+#define FE_RECORD_DISPLAY_ATTR_3 0x03
+
+/** Extended Attribute Header Descriptor (ECMA 167r3 4/14.10.1) */
+struct extended_attr_header_desc_s
+{
+ udf_tag_t tag;
+ udf_Uint32_t imp_attr_location;
+ udf_Uint32_t app_attr_location;
+} GNUC_PACKED;
+
+/** Generic Format (ECMA 167r3 4/14.10.2) */
+struct generic_format_s
+{
+ udf_Uint32_t attr_type;
+ udf_Uint8_t attr_subtype;
+ udf_Uint8_t reserved[3];
+ udf_Uint32_t attrLength;
+ udf_Uint8_t attrData[0];
+} GNUC_PACKED;
+
+/** Character Set Information (ECMA 167r3 4/14.10.3) */
+struct charSet_info_s
+{
+ udf_Uint32_t attr_type;
+ udf_Uint8_t attr_subtype;
+ udf_Uint8_t reserved[3];
+ udf_Uint32_t attrLength;
+ udf_Uint32_t escapeSeqLength;
+ udf_Uint8_t charSetType;
+ udf_Uint8_t escapeSeq[0];
+} GNUC_PACKED;
+
+/* Alternate Permissions (ECMA 167r3 4/14.10.4) */
+struct alt_perms_s
+{
+ udf_Uint32_t attr_type;
+ udf_Uint8_t attr_subtype;
+ udf_Uint8_t reserved[3];
+ udf_Uint32_t attrLength;
+ udf_Uint16_t owner_id;
+ udf_Uint16_t group_id;
+ udf_Uint16_t permission;
+} GNUC_PACKED;
+
+/** File Times Extended Attribute (ECMA 167r3 4/14.10.5) */
+struct filetimes_ext_attr_s
+{
+ udf_Uint32_t attr_type;
+ udf_Uint8_t attr_subtype;
+ udf_Uint8_t reserved[3];
+ udf_Uint32_t attrLength;
+ udf_Uint32_t dataLength;
+ udf_Uint32_t fileTimeExistence;
+ udf_Uint8_t fileTimes;
+} GNUC_PACKED;
+
+/** FileTimeExistence (ECMA 167r3 4/14.10.5.6) */
+#define FTE_CREATION 0x00000001
+#define FTE_DELETION 0x00000004
+#define FTE_EFFECTIVE 0x00000008
+#define FTE_BACKUP 0x00000002
+
+/** Information Times Extended Attribute (ECMA 167r3 4/14.10.6) */
+struct infoTimesExtAttr
+{
+ udf_Uint32_t attr_type;
+ udf_Uint8_t attr_subtype;
+ udf_Uint8_t reserved[3];
+ udf_Uint32_t attrLength;
+ udf_Uint32_t dataLength;
+ udf_Uint32_t infoTimeExistence;
+ udf_Uint8_t infoTimes[0];
+} GNUC_PACKED;
+
+/** Device Specification (ECMA 167r3 4/14.10.7) */
+struct deviceSpec
+{
+ udf_Uint32_t attr_type;
+ udf_Uint8_t attr_subtype;
+ udf_Uint8_t reserved[3];
+ udf_Uint32_t attrLength;
+ udf_Uint32_t imp_useLength;
+ udf_Uint32_t majorDevice_id;
+ udf_Uint32_t minorDevice_id;
+ udf_Uint8_t imp_use[0];
+} GNUC_PACKED;
+
+/** Implementation Use Extended Attr (ECMA 167r3 4/14.10.8) */
+struct impUseExtAttr
+{
+ udf_Uint32_t attr_type;
+ udf_Uint8_t attr_subtype;
+ udf_Uint8_t reserved[3];
+ udf_Uint32_t attrLength;
+ udf_Uint32_t imp_useLength;
+ udf_regid_t imp_id;
+ udf_Uint8_t imp_use[0];
+} GNUC_PACKED;
+
+/** Application Use Extended Attribute (ECMA 167r3 4/14.10.9) */
+struct appUseExtAttr
+{
+ udf_Uint32_t attr_type;
+ udf_Uint8_t attr_subtype;
+ udf_Uint8_t reserved[3];
+ udf_Uint32_t attrLength;
+ udf_Uint32_t appUseLength;
+ udf_regid_t app_id;
+ udf_Uint8_t appUse[0];
+} GNUC_PACKED;
+
+#define EXTATTR_CHAR_SET 1
+#define EXTATTR_ALT_PERMS 3
+#define EXTATTR_FILE_TIMES 5
+#define EXTATTR_INFO_TIMES 6
+#define EXTATTR_DEV_SPEC 12
+#define EXTATTR_IMP_USE 2048
+#define EXTATTR_APP_USE 65536
+
+
+/** Unallocated Space Entry (ECMA 167r3 4/14.11) */
+struct unallocSpaceEntry
+{
+ udf_tag_t tag;
+ udf_icbtag_t icb_tag;
+ udf_Uint32_t lengthAllocDescs;
+ udf_Uint8_t allocDescs[0];
+} GNUC_PACKED;
+
+/** Space Bitmap Descriptor (ECMA 167r3 4/14.12) */
+struct spaceBitmapDesc
+{
+ udf_tag_t tag;
+ udf_Uint32_t i_bits;
+ udf_Uint32_t i_bytes;
+ udf_Uint8_t bitmap[0];
+} GNUC_PACKED;
+
+/** Partition Integrity Entry (ECMA 167r3 4/14.13) */
+struct partitionIntegrityEntry
+{
+ udf_tag_t tag;
+ udf_icbtag_t icb_tag;
+ udf_timestamp_t recording_time;
+ udf_Uint8_t integrityType;
+ udf_Uint8_t reserved[175];
+ udf_regid_t imp_id;
+ udf_Uint8_t imp_use[256];
+} GNUC_PACKED;
+
+/** Short Allocation Descriptor (ECMA 167r3 4/14.14.1) */
+
+/** Extent Length (ECMA 167r3 4/14.14.1.1) */
+#define EXT_RECORDED_ALLOCATED 0x00000000
+#define EXT_NOT_RECORDED_ALLOCATED 0x40000000
+#define EXT_NOT_RECORDED_NOT_ALLOCATED 0x80000000
+#define EXT_NEXT_EXTENT_ALLOCDECS 0xC0000000
+
+/** Long Allocation Descriptor (ECMA 167r3 4/14.14.2) */
+
+/** Extended Allocation Descriptor (ECMA 167r3 4/14.14.3) */
+
+/** Logical Volume Header Descriptor (ECMA 167r3 4/14.15) */
+struct logical_vol_header_desc_s
+{
+ udf_Uint64_t uniqueID;
+ udf_Uint8_t reserved[24];
+} GNUC_PACKED;
+
+typedef struct logical_vol_header_desc_s logical_vol_header_desc_t;
+
+/** Path Component (ECMA 167r3 4/14.16.1) */
+struct pathComponent
+{
+ udf_Uint8_t component_type;
+ udf_Uint8_t lengthComponent_id;
+ udf_Uint16_t componentFileVersionNum;
+ udf_dstring component_id[0];
+} GNUC_PACKED;
+
+/** File Entry (ECMA 167r3 4/14.17) */
+struct extended_file_entry
+{
+ udf_tag_t tag; /**< 4/14.17.1 - id = 266 */
+ udf_icbtag_t icb_tag; /**< 4/14.17.2 & 4/14.9.2 */
+ udf_Uint32_t uid; /**< 4/14.17.3 & 4/14.9.3 */
+ udf_Uint32_t gid; /**< 4/14.17.4 & 4/14.9.4 */
+ udf_Uint32_t permissions; /**< 4/14.17.5 & 4/14.9.5 */
+ udf_Uint16_t link_count; /**< 4/14.17.6 & 4/14.9.6 */
+ udf_Uint8_t rec_format; /**< 4/14.17.7 & 4/14.9.7 */
+ udf_Uint8_t rec_display_attr; /**< 4/14.17.8 & 4/14.9.8 */
+ udf_Uint32_t record_len; /**< 4/14.17.9 & 4/14.9.9 */
+ udf_Uint64_t info_len; /**< 4/14.17.10 & 4/14.9.10 */
+ udf_Uint64_t object_size; /**< 4/14.17.11 */
+ udf_Uint64_t logblks_recorded; /**< 4/14.17.12 & 4/14.9.11 */
+ udf_timestamp_t access_time; /**< 4/14.17.13 & 4/14.9.12 - last
+ access to any stream of file */
+ udf_timestamp_t modification_time; /**< 4/14.17.14 & 4/14.9.13 - last
+ modification to any stream of
+ file*/
+ udf_timestamp_t create_time; /**< 4/14.17.15 */
+ udf_timestamp_t attribute_time; /**< 4/14.17.16 & 4/14.9.14 -
+ most recent create or modify
+ time */
+ udf_Uint32_t checkpoint;
+ udf_Uint32_t reserved; /**< #00 bytes */
+ udf_long_ad_t ext_attr_ICB;
+ udf_long_ad_t stream_directory_ICB;
+ udf_regid_t imp_id;
+ udf_Uint64_t unique_ID;
+ udf_Uint32_t length_extended_attr;
+ udf_Uint32_t length_alloc_descs;
+ udf_Uint8_t ext_attr[0];
+ udf_Uint8_t alloc_descs[0];
+} GNUC_PACKED;
+
+PRAGMA_END_PACKED
+
+/** The below variables are trickery to force the above enum symbol
+ values to be recorded in debug symbol tables. They are used to
+ allow one refer to the enumeration value names in the typedefs
+ above in a debugger and in debugger expressions.
+*/
+extern tag_id_t debug_tagid;
+extern file_characteristics_t debug_file_characteristics;
+extern icbtag_file_type_enum_t debug_icbtag_file_type_enum;
+extern icbtag_flag_enum_t debug_flag_enum;
+extern ecma_167_enum1_t debug_ecma_167_enum1;
+extern ecma_167_timezone_enum_t debug_ecma_167_timezone_enum;
+
+#endif /* _ECMA_167_H */
diff --git a/lib-x86-32/include/cdio/iso9660.h b/lib-x86-32/include/cdio/iso9660.h
new file mode 100644
index 00000000..a5311c8f
--- /dev/null
+++ b/lib-x86-32/include/cdio/iso9660.h
@@ -0,0 +1,1116 @@
+/*
+ $Id: iso9660.h,v 1.102 2008/07/16 00:28:54 rocky Exp $
+
+ Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008
+ Rocky Bernstein <rocky@gnu.org>
+ Copyright (C) 2000 Herbert Valerio Riedel <hvr@gnu.org>
+
+ See also iso9660.h by Eric Youngdale (1993).
+
+ Copyright 1993 Yggdrasil Computing, Incorporated
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*!
+ * \file iso9660.h
+ *
+ * \brief The top-level interface header for libiso9660: the ISO-9660
+ * filesystem library; applications include this.
+ *
+ * See also the ISO-9660 specification. The freely available European
+ * equivalant standard is called ECMA-119.
+*/
+
+
+#ifndef __CDIO_ISO9660_H__
+#define __CDIO_ISO9660_H__
+
+#include <time.h>
+
+#include <cdio/cdio.h>
+#include <cdio/ds.h>
+#include <cdio/posix.h>
+
+/** \brief ISO 9660 Integer and Character types
+
+These are described in the section 7 of the ISO 9660 (or ECMA 119)
+specification.
+*/
+
+typedef uint8_t iso711_t; /*! See section 7.1.1 */
+typedef int8_t iso712_t; /*! See section 7.1.2 */
+typedef uint16_t iso721_t; /*! See section 7.2.1 */
+typedef uint16_t iso722_t; /*! See section 7.2.2 */
+typedef uint32_t iso723_t; /*! See section 7.2.3 */
+typedef uint32_t iso731_t; /*! See section 7.3.1 */
+typedef uint32_t iso732_t; /*! See section 7.3.2 */
+typedef uint64_t iso733_t; /*! See section 7.3.3 */
+
+typedef char achar_t; /*! See section 7.4.1 */
+typedef char dchar_t; /*! See section 7.4.1 */
+
+#ifndef EMPTY_ARRAY_SIZE
+#define EMPTY_ARRAY_SIZE 0
+#endif
+
+#include <cdio/types.h>
+#include <cdio/xa.h>
+
+#ifdef ISODCL
+#undef ISODCL
+#endif
+/* This part borrowed from the bsd386 isofs */
+#define ISODCL(from, to) ((to) - (from) + 1)
+
+#define MIN_TRACK_SIZE 4*75
+#define MIN_ISO_SIZE MIN_TRACK_SIZE
+
+/*! The below isn't really an enumeration one would really use in a
+ program; things are done this way so that in a debugger one can to
+ refer to the enumeration value names such as in a debugger
+ expression and get something. With the more common a \#define
+ mechanism, the name/value assocation is lost at run time.
+ */
+extern enum iso_enum1_s {
+ ISO_PVD_SECTOR = 16, /**< Sector of Primary Volume Descriptor. */
+ ISO_EVD_SECTOR = 17, /**< Sector of End Volume Descriptor. */
+ LEN_ISONAME = 31, /**< Size in bytes of the filename
+ portion + null byte. */
+ ISO_MAX_SYSTEM_ID = 32, /**< Maximum number of characters in a system
+ id. */
+ MAX_ISONAME = 37, /**< Size in bytes of the filename
+ portion + null byte. */
+ ISO_MAX_PREPARER_ID = 128, /**< Maximum number of characters in a
+ preparer id. */
+ MAX_ISOPATHNAME = 255, /**< Maximum number of characters in the
+ entire ISO 9660 filename. */
+ ISO_BLOCKSIZE = 2048 /**< Number of bytes in an ISO 9660 block. */
+
+} iso_enums1;
+
+/*! An enumeration for some of the ISO_* \#defines below. This isn't
+ really an enumeration one would really use in a program it is here
+ to be helpful in debuggers where wants just to refer to the
+ ISO_*_ names and get something.
+ */
+
+/*! ISO 9660 directory flags. */
+extern enum iso_flag_enum_s {
+ ISO_FILE = 0, /**< Not really a flag... */
+ ISO_EXISTENCE = 1, /**< Do not make existence known (hidden) */
+ ISO_DIRECTORY = 2, /**< This file is a directory */
+ ISO_ASSOCIATED = 4, /**< This file is an associated file */
+ ISO_RECORD = 8, /**< Record format in extended attr. != 0 */
+ ISO_PROTECTION = 16, /**< No read/execute perm. in ext. attr. */
+ ISO_DRESERVED1 = 32, /**<, Reserved bit 5 */
+ ISO_DRESERVED2 = 64, /**<, Reserved bit 6 */
+ ISO_MULTIEXTENT = 128, /**< Not final entry of a mult. ext. file */
+} iso_flag_enums;
+
+/*! Volume descriptor types */
+extern enum iso_vd_enum_s {
+ ISO_VD_BOOT_RECORD = 0, /**< CD is bootable */
+ ISO_VD_PRIMARY = 1, /**< Is in any ISO-9660 */
+ ISO_VD_SUPPLEMENTARY = 2, /**< Used by Joliet, for example */
+ ISO_VD_PARITION = 3, /**< Indicates a partition of a CD */
+ ISO_VD_END = 255
+} iso_vd_enums;
+
+
+/*!
+ An ISO filename is:
+ <em>abcd</em>.<em>eee</em> ->
+ <em>filename</em>.<em>ext</em>;<em>version#</em>
+
+ For ISO-9660 Level 1, the maximum needed string length is:
+
+@code
+ 30 chars (filename + ext)
+ + 2 chars ('.' + ';')
+ + 5 chars (strlen("32767"))
+ + 1 null byte
+ ================================
+ = 38 chars
+@endcode
+
+*/
+
+/*! \brief Maximum number of characters in a publisher id. */
+#define ISO_MAX_PUBLISHER_ID 128
+
+/*! \brief Maximum number of characters in an application id. */
+#define ISO_MAX_APPLICATION_ID 128
+
+/*! \brief Maximum number of characters in a volume id. */
+#define ISO_MAX_VOLUME_ID 32
+
+/*! \brief Maximum number of characters in a volume-set id. */
+#define ISO_MAX_VOLUMESET_ID 128
+
+/*! String inside frame which identifies an ISO 9660 filesystem. This
+ string is the "id" field of an iso9660_pvd_t or an iso9660_svd_t.
+*/
+extern const char ISO_STANDARD_ID[sizeof("CD001")-1];
+
+#define ISO_STANDARD_ID "CD001"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+typedef enum strncpy_pad_check {
+ ISO9660_NOCHECK = 0,
+ ISO9660_7BIT,
+ ISO9660_ACHARS,
+ ISO9660_DCHARS
+} strncpy_pad_check_t;
+
+PRAGMA_BEGIN_PACKED
+
+/*!
+ \brief ISO-9660 shorter-format time structure. See ECMA 9.1.5.
+
+ @see iso9660_dtime
+ */
+struct iso9660_dtime_s {
+ iso711_t dt_year; /**< Number of years since 1900 */
+ iso711_t dt_month; /**< Has value in range 1..12. Note starts
+ at 1, not 0 like a tm struct. */
+ iso711_t dt_day; /**< Day of the month from 1 to 31 */
+ iso711_t dt_hour; /**< Hour of the day from 0 to 23 */
+ iso711_t dt_minute; /**< Minute of the hour from 0 to 59 */
+ iso711_t dt_second; /**< Second of the minute from 0 to 59 */
+ iso712_t dt_gmtoff; /**< GMT values -48 .. + 52 in 15 minute
+ intervals */
+} GNUC_PACKED;
+
+typedef struct iso9660_dtime_s iso9660_dtime_t;
+
+/*!
+ \brief ISO-9660 longer-format time structure.
+
+ Section 8.4.26.1 of ECMA 119. All values are encoded as character
+ arrays, eg. '1', '9', '5', '5' for the year 1955 (no null terminated
+ byte).
+
+ @see iso9660_ltime
+ */
+struct iso9660_ltime_s {
+ char lt_year [ISODCL( 1, 4)]; /**< Add 1900 to value
+ for the Julian
+ year */
+ char lt_month [ISODCL( 5, 6)]; /**< Has value in range
+ 1..12. Note starts
+ at 1, not 0 like a
+ tm struct. */
+ char lt_day [ISODCL( 7, 8)]; /**< Day of month: 1..31 */
+ char lt_hour [ISODCL( 9, 10)]; /**< hour: 0..23 */
+ char lt_minute [ISODCL( 11, 12)]; /**< minute: 0..59 */
+ char lt_second [ISODCL( 13, 14)]; /**< second: 0..59 */
+ char lt_hsecond [ISODCL( 15, 16)]; /**< The value is in
+ units of 1/100's of
+ a second */
+ iso712_t lt_gmtoff; /**< Offset from Greenwich Mean Time in number
+ of 15 min intervals from -48 (West) to +52
+ (East) recorded according to 7.1.2 numerical
+ value */
+} GNUC_PACKED;
+
+typedef struct iso9660_ltime_s iso9660_ltime_t;
+typedef struct iso9660_dir_s iso9660_dir_t;
+typedef struct iso9660_stat_s iso9660_stat_t;
+
+#include <cdio/rock.h>
+
+/*! \brief Format of an ISO-9660 directory record
+
+ Section 9.1 of ECMA 119.
+
+ This structure may have an odd length depending on how many
+ characters there are in the filename! Some compilers (e.g. on
+ Sun3/mc68020) pad the structures to an even length. For this reason,
+ we cannot use sizeof (struct iso_path_table) or sizeof (struct
+ iso_directory_record) to compute on disk sizes. Instead, we use
+ offsetof(..., name) and add the name size. See mkisofs.h of the
+ cdrtools package.
+
+ @see iso9660_stat
+*/
+struct iso9660_dir_s {
+ iso711_t length; /*! Length of Directory record (9.1.1) */
+ iso711_t xa_length; /*! XA length if XA is used. Otherwise
+ zero. (9.1.2) */
+ iso733_t extent; /*! LBA of first local block allocated
+ to the extent */
+ iso733_t size; /*! data length of File Section. This
+ does not include the length of
+ any XA Records. (9.1.2) */
+ iso9660_dtime_t recording_time; /*! Recording date and time (9.1.3) */
+ uint8_t file_flags; /*! If no XA then zero. If a directory,
+ then bits 2,3 and 7 are zero.
+ (9.1.6) */
+ iso711_t file_unit_size; /*! File Unit size for the File
+ Section if the File Section
+ is recorded in interleaved
+ mode. Otherwise zero. (9.1.7) */
+ iso711_t interleave_gap; /*! Interleave Gap size for the
+ File Section if the File
+ Section is interleaved. Otherwise
+ zero. (9.1.8) */
+ iso723_t volume_sequence_number; /*! Ordinal number of the volume
+ in the Volume Set on which
+ the Extent described by this
+ Directory Record is
+ recorded. (9.1.9) */
+ iso711_t filename_len; /*! number of bytes in filename field */
+ char filename[EMPTY_ARRAY_SIZE];
+} GNUC_PACKED;
+
+/*!
+ \brief ISO-9660 Primary Volume Descriptor.
+ */
+struct iso9660_pvd_s {
+ iso711_t type; /**< ISO_VD_PRIMARY - 1 */
+ char id[5]; /**< ISO_STANDARD_ID "CD001"
+ */
+ iso711_t version; /**< value 1 for ECMA 119 */
+ char unused1[1]; /**< unused - value 0 */
+ achar_t system_id[ISO_MAX_SYSTEM_ID]; /**< each char is an achar */
+ dchar_t volume_id[ISO_MAX_VOLUME_ID]; /**< each char is a dchar */
+ uint8_t unused2[8]; /**< unused - value 0 */
+ iso733_t volume_space_size; /**< total number of
+ sectors */
+ uint8_t unused3[32]; /**< unused - value 0 */
+ iso723_t volume_set_size; /**< often 1 */
+ iso723_t volume_sequence_number; /**< often 1 */
+ iso723_t logical_block_size; /**< sector size, e.g. 2048 */
+ iso733_t path_table_size; /**< bytes in path table */
+ iso731_t type_l_path_table; /**< first sector of L Path
+ Table */
+ iso731_t opt_type_l_path_table; /**< first sector of optional
+ L Path Table */
+ iso732_t type_m_path_table; /**< first sector of M Path
+ table */
+ iso732_t opt_type_m_path_table; /**< first sector of optional
+ M Path table */
+ iso9660_dir_t root_directory_record; /**< See 8.4.18 and
+ section 9.1 of
+ ISO 9660 spec. */
+ char root_directory_filename; /**< Is '\\0' or root
+ directory. Also pads previous
+ field to 34 bytes */
+ dchar_t volume_set_id[ISO_MAX_VOLUMESET_ID]; /**< Volume Set of
+ which the volume is
+ a member. See
+ section 8.4.19 */
+ achar_t publisher_id[ISO_MAX_PUBLISHER_ID]; /**< Publisher of
+ volume. If the first
+ character is '_' 0x5F,
+ the remaining bytes
+ specify a file
+ containing the user.
+ If all bytes are " "
+ (0x20) no publisher
+ is specified. See
+ section 8.4.20 of
+ ECMA 119 */
+ achar_t preparer_id[ISO_MAX_PREPARER_ID]; /**< preparer of
+ volume. If the first
+ character is '_' 0x5F,
+ the remaining bytes
+ specify a file
+ containing the user.
+ If all bytes are " "
+ (0x20) no preparer
+ is specified.
+ See section 8.4.21
+ of ECMA 119 */
+ achar_t application_id[ISO_MAX_APPLICATION_ID]; /**< application
+ use to create the
+ volume. If the first
+ character is '_' 0x5F,
+ the remaining bytes
+ specify a file
+ containing the user.
+ If all bytes are " "
+ (0x20) no application
+ is specified.
+ See section of 8.4.22
+ of ECMA 119 */
+ dchar_t copyright_file_id[37]; /**< Name of file for
+ copyright info. If
+ all bytes are " "
+ (0x20), then no file
+ is identified. See
+ section 8.4.23 of ECMA 119
+ 9660 spec. */
+ dchar_t abstract_file_id[37]; /**< See section 8.4.24 of
+ ECMA 119. */
+ dchar_t bibliographic_file_id[37]; /**< See section 7.5 of
+ ISO 9660 spec. */
+ iso9660_ltime_t creation_date; /**< date and time of volume
+ creation. See section 8.4.26.1
+ of the ISO 9660 spec. */
+ iso9660_ltime_t modification_date; /**< date and time of the most
+ recent modification.
+ See section 8.4.27 of the
+ ISO 9660 spec. */
+ iso9660_ltime_t expiration_date; /**< date and time when volume
+ expires. See section 8.4.28
+ of the ISO 9660 spec. */
+ iso9660_ltime_t effective_date; /**< date and time when volume
+ is effective. See section
+ 8.4.29 of the ISO 9660
+ spec. */
+ iso711_t file_structure_version; /**< value 1 for ECMA 119 */
+ uint8_t unused4[1]; /**< unused - value 0 */
+ char application_data[512]; /**< Application can put
+ whatever it wants here. */
+ uint8_t unused5[653]; /**< Unused - value 0 */
+} GNUC_PACKED;
+
+typedef struct iso9660_pvd_s iso9660_pvd_t;
+
+/*!
+ \brief ISO-9660 Supplementary Volume Descriptor.
+
+ This is used for Joliet Extentions and is almost the same as the
+ the primary descriptor but two unused fields, "unused1" and "unused3
+ become "flags and "escape_sequences" respectively.
+*/
+struct iso9660_svd_s {
+ iso711_t type; /**< ISO_VD_SUPPLEMENTARY - 2
+ */
+ char id[5]; /**< ISO_STANDARD_ID "CD001"
+ */
+ iso711_t version; /**< value 1 */
+ char flags; /**< Section 8.5.3 */
+ achar_t system_id[ISO_MAX_SYSTEM_ID]; /**< Section 8.5.4; each char
+ is an achar */
+ dchar_t volume_id[ISO_MAX_VOLUME_ID]; /**< Section 8.5.5; each char
+ is a dchar */
+ char unused2[8];
+ iso733_t volume_space_size; /**< total number of
+ sectors */
+ char escape_sequences[32]; /**< Section 8.5.6 */
+ iso723_t volume_set_size; /**< often 1 */
+ iso723_t volume_sequence_number; /**< often 1 */
+ iso723_t logical_block_size; /**< sector size, e.g. 2048 */
+ iso733_t path_table_size; /**< 8.5.7; bytes in path
+ table */
+ iso731_t type_l_path_table; /**< 8.5.8; first sector of
+ little-endian path table */
+ iso731_t opt_type_l_path_table; /**< 8.5.9; first sector of
+ optional little-endian
+ path table */
+ iso732_t type_m_path_table; /**< 8.5.10; first sector of
+ big-endian path table */
+ iso732_t opt_type_m_path_table; /**< 8.5.11; first sector of
+ optional big-endian path
+ table */
+ iso9660_dir_t root_directory_record; /**< See section 8.5.12 and
+ 9.1 of ISO 9660 spec. */
+ char root_directory_filename; /**< Is '\\0' or root
+ directory. Also pads previous
+ field to 34 bytes */
+ dchar_t volume_set_id[ISO_MAX_VOLUMESET_ID]; /**< 8.5.13;
+ dchars */
+ achar_t publisher_id[ISO_MAX_PUBLISHER_ID]; /**<
+ Publisher of volume.
+ If the first char-
+ aracter is '_' 0x5F,
+ the remaining bytes
+ specify a file
+ containing the user.
+ If all bytes are " "
+ (0x20) no publisher
+ is specified. See
+ section 8.5.14 of
+ ECMA 119 */
+ achar_t preparer_id[ISO_MAX_PREPARER_ID]; /**<
+ Data preparer of
+ volume. If the first
+ character is '_' 0x5F,
+ the remaining bytes
+ specify a file
+ containing the user.
+ If all bytes are " "
+ (0x20) no preparer
+ is specified.
+ See section 8.5.15
+ of ECMA 119 */
+ achar_t application_id[ISO_MAX_APPLICATION_ID]; /**< application
+ use to create the
+ volume. If the first
+ character is '_' 0x5F,
+ the remaining bytes
+ specify a file
+ containing the user.
+ If all bytes are " "
+ (0x20) no application
+ is specified.
+ See section of 8.5.16
+ of ECMA 119 */
+ dchar_t copyright_file_id[37]; /**< Name of file for
+ copyright info. If
+ all bytes are " "
+ (0x20), then no file
+ is identified. See
+ section 8.5.17 of ECMA 119
+ 9660 spec. */
+ dchar_t abstract_file_id[37]; /**< See section 8.5.18 of
+ ECMA 119. */
+ dchar_t bibliographic_file_id[37]; /**< See section 8.5.19 of
+ ECMA 119. */
+ iso9660_ltime_t creation_date; /**< date and time of volume
+ creation. See section 8.4.26.1
+ of the ECMA 119 spec. */
+ iso9660_ltime_t modification_date; /**< date and time of the most
+ recent modification.
+ See section 8.4.27 of the
+ ECMA 119 spec. */
+ iso9660_ltime_t expiration_date; /**< date and time when volume
+ expires. See section 8.4.28
+ of the ECMA 119 spec. */
+ iso9660_ltime_t effective_date; /**< date and time when volume
+ is effective. See section
+ 8.4.29 of the ECMA 119
+ spec. */
+ iso711_t file_structure_version; /**< value 1 for ECMA 119 */
+ uint8_t unused4[1]; /**< unused - value 0 */
+ char application_data[512]; /**< 8.5.20 Application can put
+ whatever it wants here. */
+ uint8_t unused5[653]; /**< Unused - value 0 */
+} GNUC_PACKED;
+
+typedef struct iso9660_svd_s iso9660_svd_t;
+
+PRAGMA_END_PACKED
+
+/*! \brief Unix stat-like version of iso9660_dir
+
+ The iso9660_stat structure is not part of the ISO-9660
+ specification. We use it for our to communicate information
+ in a C-library friendly way, e.g struct tm time structures and
+ a C-style filename string.
+
+ @see iso9660_dir
+*/
+struct iso9660_stat_s { /* big endian!! */
+
+ iso_rock_statbuf_t rr; /**< Rock Ridge-specific fields */
+
+ struct tm tm; /**< time on entry - FIXME merge with
+ one of entries above, like ctime? */
+ lsn_t lsn; /**< start logical sector number */
+ uint32_t size; /**< total size in bytes */
+ uint32_t secsize; /**< number of sectors allocated */
+ iso9660_xa_t xa; /**< XA attributes */
+ enum { _STAT_FILE = 1, _STAT_DIR = 2 } type;
+ bool b_xa;
+ char filename[EMPTY_ARRAY_SIZE]; /**< filename */
+};
+
+/** A mask used in iso9660_ifs_read_vd which allows what kinds
+ of extensions we allow, eg. Joliet, Rock Ridge, etc. */
+typedef uint8_t iso_extension_mask_t;
+
+/*! An enumeration for some of the ISO_EXTENSION_* \#defines below. This isn't
+ really an enumeration one would really use in a program it is here
+ to be helpful in debuggers where wants just to refer to the
+ ISO_EXTENSION_*_ names and get something.
+ */
+extern enum iso_extension_enum_s {
+ ISO_EXTENSION_JOLIET_LEVEL1 = 0x01,
+ ISO_EXTENSION_JOLIET_LEVEL2 = 0x02,
+ ISO_EXTENSION_JOLIET_LEVEL3 = 0x04,
+ ISO_EXTENSION_ROCK_RIDGE = 0x08,
+ ISO_EXTENSION_HIGH_SIERRA = 0x10
+} iso_extension_enums;
+
+
+#define ISO_EXTENSION_ALL 0xFF
+#define ISO_EXTENSION_NONE 0x00
+#define ISO_EXTENSION_JOLIET \
+ (ISO_EXTENSION_JOLIET_LEVEL1 | \
+ ISO_EXTENSION_JOLIET_LEVEL2 | \
+ ISO_EXTENSION_JOLIET_LEVEL3 )
+
+
+/** This is an opaque structure. */
+typedef struct _iso9660_s iso9660_t;
+
+ /*! Close previously opened ISO 9660 image and free resources
+ associated with the image. Call this when done using using an ISO
+ 9660 image.
+
+ @return true is unconditionally returned. If there was an error
+ false would be returned.
+ */
+ bool iso9660_close (iso9660_t * p_iso);
+
+
+ /*!
+ Open an ISO 9660 image for reading. Maybe in the future we will have
+ a mode. NULL is returned on error.
+ */
+ iso9660_t *iso9660_open (const char *psz_path /*flags, mode */);
+
+ /*!
+ Open an ISO 9660 image for reading allowing various ISO 9660
+ extensions. Maybe in the future we will have a mode. NULL is
+ returned on error.
+
+ @see iso9660_open_fuzzy
+ */
+ iso9660_t *iso9660_open_ext (const char *psz_path,
+ iso_extension_mask_t iso_extension_mask);
+
+ /*! Open an ISO 9660 image for "fuzzy" reading. This means that we
+ will try to guess various internal offset based on internal
+ checks. This may be useful when trying to read an ISO 9660 image
+ contained in a file format that libiso9660 doesn't know natively
+ (or knows imperfectly.)
+
+ Some tolerence allowed for positioning the ISO 9660 image. We scan
+ for STANDARD_ID and use that to set the eventual offset to adjust
+ by (as long as that is <= i_fuzz).
+
+ Maybe in the future we will have a mode. NULL is returned on error.
+
+ @see iso9660_open, @see iso9660_fuzzy_ext
+ */
+ iso9660_t *iso9660_open_fuzzy (const char *psz_path /*flags, mode */,
+ uint16_t i_fuzz);
+
+ /*!
+ Open an ISO 9660 image for reading with some tolerence for positioning
+ of the ISO9660 image. We scan for ISO_STANDARD_ID and use that to set
+ the eventual offset to adjust by (as long as that is <= i_fuzz).
+
+ Maybe in the future we will have a mode. NULL is returned on error.
+
+ @see iso9660_open_ext @see iso9660_open_fuzzy
+ */
+ iso9660_t *iso9660_open_fuzzy_ext (const char *psz_path,
+ iso_extension_mask_t iso_extension_mask,
+ uint16_t i_fuzz
+ /*flags, mode */);
+
+ /*!
+ Read the Super block of an ISO 9660 image but determine framesize
+ and datastart and a possible additional offset. Generally here we are
+ not reading an ISO 9660 image but a CD-Image which contains an ISO 9660
+ filesystem.
+ */
+ bool iso9660_ifs_fuzzy_read_superblock (iso9660_t *p_iso,
+ iso_extension_mask_t iso_extension_mask,
+ uint16_t i_fuzz);
+
+ /*!
+ Seek to a position and then read i_size blocks.
+
+ @param p_iso the ISO-9660 file image to get data from
+
+ @param ptr place to put returned data. It should be able to store
+ a least i_size bytes
+
+ @param start location to start reading from
+
+ @param i_size number of blocks to read. Each block is ISO_BLOCKSIZE bytes
+ long.
+
+ @return number of bytes (not blocks) read
+
+ */
+ long int iso9660_iso_seek_read (const iso9660_t *p_iso, /*out*/ void *ptr,
+ lsn_t start, long int i_size);
+
+ /*!
+ Read the Primary Volume Descriptor for a CD.
+ True is returned if read, and false if there was an error.
+ */
+ bool iso9660_fs_read_pvd ( const CdIo_t *p_cdio,
+ /*out*/ iso9660_pvd_t *p_pvd );
+
+ /*!
+ Read the Primary Volume Descriptor for an ISO 9660 image.
+ True is returned if read, and false if there was an error.
+ */
+ bool iso9660_ifs_read_pvd (const iso9660_t *p_iso,
+ /*out*/ iso9660_pvd_t *p_pvd);
+
+/*!
+ Read the Super block of an ISO 9660 image. This is the
+ Primary Volume Descriptor (PVD) and perhaps a Supplemental Volume
+ Descriptor if (Joliet) extensions are acceptable.
+*/
+ bool iso9660_fs_read_superblock (CdIo_t *p_cdio,
+ iso_extension_mask_t iso_extension_mask);
+
+ /*!
+ Read the Super block of an ISO 9660 image. This is the
+ Primary Volume Descriptor (PVD) and perhaps a Supplemental Volume
+ Descriptor if (Joliet) extensions are acceptable.
+ */
+ bool iso9660_ifs_read_superblock (iso9660_t *p_iso,
+ iso_extension_mask_t iso_extension_mask);
+
+
+/*====================================================
+ Time conversion
+ ====================================================*/
+/*!
+ Set time in format used in ISO 9660 directory index record
+ from a Unix time structure. */
+ void iso9660_set_dtime (const struct tm *tm,
+ /*out*/ iso9660_dtime_t *idr_date);
+
+
+ /*!
+ Set "long" time in format used in ISO 9660 primary volume descriptor
+ from a Unix time structure. */
+ void iso9660_set_ltime (const struct tm *_tm,
+ /*out*/ iso9660_ltime_t *p_pvd_date);
+
+ /*!
+ Get Unix time structure from format use in an ISO 9660 directory index
+ record. Even though tm_wday and tm_yday fields are not explicitly in
+ idr_date, they are calculated from the other fields.
+
+ If tm is to reflect the localtime, set "b_localtime" true, otherwise
+ tm will reported in GMT.
+ */
+ bool iso9660_get_dtime (const iso9660_dtime_t *idr_date, bool b_localtime,
+ /*out*/ struct tm *tm);
+
+
+ /*!
+ Get "long" time in format used in ISO 9660 primary volume descriptor
+ from a Unix time structure.
+ */
+ bool iso9660_get_ltime (const iso9660_ltime_t *p_ldate,
+ /*out*/ struct tm *p_tm);
+
+ /*====================================================
+ Character Classification and String Manipulation
+ ====================================================*/
+ /*!
+ Return true if c is a DCHAR - a character that can appear in an an
+ ISO-9600 level 1 directory name. These are the ASCII capital
+ letters A-Z, the digits 0-9 and an underscore.
+ */
+ bool iso9660_is_dchar (int c);
+
+ /*!
+ Return true if c is an ACHAR -
+ These are the DCHAR's plus some ASCII symbols including the space
+ symbol.
+ */
+ bool iso9660_is_achar (int c);
+
+ /*!
+ Convert an ISO-9660 file name which is in the format usually stored
+ in a ISO 9660 directory entry into what's usually listed as the
+ file name in a listing. Lowercase name, and remove trailing ;1's
+ or .;1's and turn the other ;'s into version numbers.
+
+ @param psz_oldname the ISO-9660 filename to be translated.
+ @param psz_newname returned string. The caller allocates this and
+ it should be at least the size of psz_oldname.
+ @return length of the translated string is returned.
+ */
+ int iso9660_name_translate(const char *psz_oldname,
+ /*out*/ char *psz_newname);
+
+ /*!
+ Convert an ISO-9660 file name which is in the format usually stored
+ in a ISO 9660 directory entry into what's usually listed as the
+ file name in a listing. Lowercase name if no Joliet Extension
+ interpretation. Remove trailing ;1's or .;1's and turn the other
+ ;'s into version numbers.
+
+ @param psz_oldname the ISO-9660 filename to be translated.
+ @param psz_newname returned string. The caller allocates this and
+ it should be at least the size of psz_oldname.
+ @param i_joliet_level 0 if not using Joliet Extension. Otherwise the
+ Joliet level.
+ @return length of the translated string is returned. It will be no greater
+ than the length of psz_oldname.
+ */
+ int iso9660_name_translate_ext(const char *psz_oldname, char *psz_newname,
+ uint8_t i_joliet_level);
+
+ /*!
+ Pad string src with spaces to size len and copy this to dst. If
+ len is less than the length of src, dst will be truncated to the
+ first len characters of src.
+
+ src can also be scanned to see if it contains only ACHARs, DCHARs,
+ 7-bit ASCII chars depending on the enumeration _check.
+
+ In addition to getting changed, dst is the return value.
+ Note: this string might not be NULL terminated.
+ */
+ char *iso9660_strncpy_pad(char dst[], const char src[], size_t len,
+ enum strncpy_pad_check _check);
+
+ /*=====================================================================
+ File and Directory Names
+ ======================================================================*/
+
+ /*!
+ Check that psz_path is a valid ISO-9660 directory name.
+
+ A valid directory name should not start out with a slash (/),
+ dot (.) or null byte, should be less than 37 characters long,
+ have no more than 8 characters in a directory component
+ which is separated by a /, and consist of only DCHARs.
+
+ True is returned if psz_path is valid.
+ */
+ bool iso9660_dirname_valid_p (const char psz_path[]);
+
+ /*!
+ Take psz_path and a version number and turn that into a ISO-9660
+ pathname. (That's just the pathname followd by ";" and the version
+ number. For example, mydir/file.ext -> MYDIR/FILE.EXT;1 for version
+ 1. The resulting ISO-9660 pathname is returned.
+ */
+ char *iso9660_pathname_isofy (const char psz_path[], uint16_t i_version);
+
+ /*!
+ Check that psz_path is a valid ISO-9660 pathname.
+
+ A valid pathname contains a valid directory name, if one appears and
+ the filename portion should be no more than 8 characters for the
+ file prefix and 3 characters in the extension (or portion after a
+ dot). There should be exactly one dot somewhere in the filename
+ portion and the filename should be composed of only DCHARs.
+
+ True is returned if psz_path is valid.
+ */
+ bool iso9660_pathname_valid_p (const char psz_path[]);
+
+/*=====================================================================
+ directory tree
+======================================================================*/
+
+void
+iso9660_dir_init_new (void *dir, uint32_t self, uint32_t ssize,
+ uint32_t parent, uint32_t psize,
+ const time_t *dir_time);
+
+void
+iso9660_dir_init_new_su (void *dir, uint32_t self, uint32_t ssize,
+ const void *ssu_data, unsigned int ssu_size,
+ uint32_t parent, uint32_t psize,
+ const void *psu_data, unsigned int psu_size,
+ const time_t *dir_time);
+
+void
+iso9660_dir_add_entry_su (void *dir, const char filename[], uint32_t extent,
+ uint32_t size, uint8_t file_flags,
+ const void *su_data,
+ unsigned int su_size, const time_t *entry_time);
+
+unsigned int
+iso9660_dir_calc_record_size (unsigned int namelen, unsigned int su_len);
+
+/*!
+ Given a directory pointer, find the filesystem entry that contains
+ lsn and return information about it.
+
+ @return stat_t of entry if we found lsn, or NULL otherwise.
+ Caller must free return value.
+ */
+#define iso9660_fs_find_lsn iso9660_find_fs_lsn
+iso9660_stat_t *iso9660_fs_find_lsn(CdIo_t *p_cdio, lsn_t i_lsn);
+
+
+/*!
+ Given a directory pointer, find the filesystem entry that contains
+ lsn and return information about it.
+
+ @return stat_t of entry if we found lsn, or NULL otherwise.
+ Caller must free return value.
+ */
+iso9660_stat_t *iso9660_fs_find_lsn_with_path(CdIo_t *p_cdio, lsn_t i_lsn,
+ /*out*/ char **ppsz_path);
+
+/*!
+ Given a directory pointer, find the filesystem entry that contains
+ lsn and return information about it.
+
+ @return stat_t of entry if we found lsn, or NULL otherwise.
+ Caller must free return value.
+ */
+iso9660_stat_t *iso9660_ifs_find_lsn(iso9660_t *p_iso, lsn_t i_lsn);
+
+
+/*!
+ Given a directory pointer, find the filesystem entry that contains
+ lsn and return information about it.
+
+ @param p_iso pointer to iso_t
+ @param i_lsn LSN to find
+ @param ppsz_path full path of lsn filename. On entry *ppsz_path should be
+ NULL. On return it will be allocated an point to the full path of the
+ file at lsn or NULL if the lsn is not found. You should deallocate
+ *ppsz_path when you are done using it.
+
+ @return stat_t of entry if we found lsn, or NULL otherwise.
+ Caller must free return value.
+ */
+iso9660_stat_t *iso9660_ifs_find_lsn_with_path(iso9660_t *p_iso,
+ lsn_t i_lsn,
+ /*out*/ char **ppsz_path);
+
+
+/*!
+ Return file status for psz_path. NULL is returned on error.
+
+ @param p_cdio the CD object to read from
+
+ @param psz_path filename path to look up and get information about
+
+ @return ISO 9660 file information
+
+ Important note:
+
+ You make get different results looking up "/" versus "/." and the
+ latter may give more complete information. "/" will take information
+ from the PVD only, whereas "/." will force a directory read of "/" and
+ find "." and in that Rock-Ridge information might be found which fills
+ in more stat information. Ideally iso9660_fs_stat should be fixed.
+ Patches anyone?
+ */
+iso9660_stat_t *iso9660_fs_stat (CdIo_t *p_cdio, const char psz_path[]);
+
+
+/*!
+ Return file status for path name psz_path. NULL is returned on error.
+ pathname version numbers in the ISO 9660 name are dropped, i.e. ;1
+ is removed and if level 1 ISO-9660 names are lowercased.
+
+ b_mode2 is historical. It is not used.
+ */
+iso9660_stat_t *iso9660_fs_stat_translate (CdIo_t *p_cdio,
+ const char psz_path[],
+ bool b_mode2);
+
+/*!
+ Return file status for pathname. NULL is returned on error.
+ */
+iso9660_stat_t *iso9660_ifs_stat (iso9660_t *p_iso, const char psz_path[]);
+
+
+/*! Return file status for path name psz_path. NULL is returned on
+ error. pathname version numbers in the ISO 9660 name are dropped,
+ i.e. ;1 is removed and if level 1 ISO-9660 names are lowercased.
+ */
+iso9660_stat_t *iso9660_ifs_stat_translate (iso9660_t *p_iso,
+ const char psz_path[]);
+
+/*! Read psz_path (a directory) and return a list of iso9660_stat_t
+ pointers for the files inside that directory. The caller must free the
+ returned result.
+
+ b_mode2 is historical. It is not used.
+*/
+CdioList_t * iso9660_fs_readdir (CdIo_t *p_cdio, const char psz_path[],
+ bool b_mode2);
+
+/*! Read psz_path (a directory) and return a list of iso9660_stat_t
+ pointers for the files inside that directory. The caller must free
+ the returned result.
+*/
+CdioList_t * iso9660_ifs_readdir (iso9660_t *p_iso, const char psz_path[]);
+
+/*!
+ Return the PVD's application ID.
+ NULL is returned if there is some problem in getting this.
+*/
+char * iso9660_get_application_id(iso9660_pvd_t *p_pvd);
+
+/*!
+ Get the application ID. psz_app_id is set to NULL if there
+ is some problem in getting this and false is returned.
+*/
+bool iso9660_ifs_get_application_id(iso9660_t *p_iso,
+ /*out*/ cdio_utf8_t **p_psz_app_id);
+
+/*!
+ Return the Joliet level recognized for p_iso.
+*/
+uint8_t iso9660_ifs_get_joliet_level(iso9660_t *p_iso);
+
+uint8_t iso9660_get_dir_len(const iso9660_dir_t *p_idr);
+
+#if FIXME
+uint8_t iso9660_get_dir_size(const iso9660_dir_t *p_idr);
+
+lsn_t iso9660_get_dir_extent(const iso9660_dir_t *p_idr);
+#endif
+
+ /*!
+ Return the directory name stored in the iso9660_dir_t
+
+ A string is allocated: the caller must deallocate. This routine
+ can return NULL if memory allocation fails.
+ */
+ char * iso9660_dir_to_name (const iso9660_dir_t *p_iso9660_dir);
+
+ /*!
+ Returns a POSIX mode for a given p_iso_dirent.
+ */
+ mode_t iso9660_get_posix_filemode(const iso9660_stat_t *p_iso_dirent);
+
+ /*!
+ Return a string containing the preparer id with trailing
+ blanks removed.
+ */
+ char *iso9660_get_preparer_id(const iso9660_pvd_t *p_pvd);
+
+ /*!
+ Get the preparer ID. psz_preparer_id is set to NULL if there
+ is some problem in getting this and false is returned.
+ */
+ bool iso9660_ifs_get_preparer_id(iso9660_t *p_iso,
+ /*out*/ cdio_utf8_t **p_psz_preparer_id);
+
+ /*!
+ Return a string containing the PVD's publisher id with trailing
+ blanks removed.
+ */
+ char *iso9660_get_publisher_id(const iso9660_pvd_t *p_pvd);
+
+ /*!
+ Get the publisher ID. psz_publisher_id is set to NULL if there
+ is some problem in getting this and false is returned.
+ */
+ bool iso9660_ifs_get_publisher_id(iso9660_t *p_iso,
+ /*out*/ cdio_utf8_t **p_psz_publisher_id);
+
+ uint8_t iso9660_get_pvd_type(const iso9660_pvd_t *p_pvd);
+
+ const char * iso9660_get_pvd_id(const iso9660_pvd_t *p_pvd);
+
+ int iso9660_get_pvd_space_size(const iso9660_pvd_t *p_pvd);
+
+ int iso9660_get_pvd_block_size(const iso9660_pvd_t *p_pvd) ;
+
+ /*! Return the primary volume id version number (of pvd).
+ If there is an error 0 is returned.
+ */
+ int iso9660_get_pvd_version(const iso9660_pvd_t *pvd) ;
+
+ /*!
+ Return a string containing the PVD's system id with trailing
+ blanks removed.
+ */
+ char *iso9660_get_system_id(const iso9660_pvd_t *p_pvd);
+
+ /*!
+ Get the system ID. psz_system_id is set to NULL if there
+ is some problem in getting this and false is returned.
+ */
+ bool iso9660_ifs_get_system_id(iso9660_t *p_iso,
+ /*out*/ cdio_utf8_t **p_psz_system_id);
+
+
+ /*! Return the LSN of the root directory for pvd.
+ If there is an error CDIO_INVALID_LSN is returned.
+ */
+ lsn_t iso9660_get_root_lsn(const iso9660_pvd_t *p_pvd);
+
+ /*!
+ Get the volume ID in the PVD. psz_volume_id is set to NULL if there
+ is some problem in getting this and false is returned.
+ */
+ char *iso9660_get_volume_id(const iso9660_pvd_t *p_pvd);
+
+ /*!
+ Get the volume ID in the PVD. psz_volume_id is set to NULL if there
+ is some problem in getting this and false is returned.
+ */
+ bool iso9660_ifs_get_volume_id(iso9660_t *p_iso,
+ /*out*/ cdio_utf8_t **p_psz_volume_id);
+
+ /*!
+ Return the volumeset ID in the PVD.
+ NULL is returned if there is some problem in getting this.
+ */
+ char *iso9660_get_volumeset_id(const iso9660_pvd_t *p_pvd);
+
+ /*!
+ Get the volumeset ID. psz_systemset_id is set to NULL if there
+ is some problem in getting this and false is returned.
+ */
+ bool iso9660_ifs_get_volumeset_id(iso9660_t *p_iso,
+ /*out*/ cdio_utf8_t **p_psz_volumeset_id);
+
+ /* pathtable */
+
+ /*! Zero's out pathable. Do this first. */
+ void iso9660_pathtable_init (void *pt);
+
+ unsigned int iso9660_pathtable_get_size (const void *pt);
+
+ uint16_t iso9660_pathtable_l_add_entry (void *pt, const char name[],
+ uint32_t extent, uint16_t parent);
+
+ uint16_t iso9660_pathtable_m_add_entry (void *pt, const char name[],
+ uint32_t extent, uint16_t parent);
+
+ /**=====================================================================
+ Volume Descriptors
+ ======================================================================*/
+
+ void iso9660_set_pvd (void *pd, const char volume_id[],
+ const char application_id[],
+ const char publisher_id[], const char preparer_id[],
+ uint32_t iso_size, const void *root_dir,
+ uint32_t path_table_l_extent,
+ uint32_t path_table_m_extent,
+ uint32_t path_table_size, const time_t *pvd_time);
+
+ void iso9660_set_evd (void *pd);
+
+ /*!
+ Return true if ISO 9660 image has extended attrributes (XA).
+ */
+ bool iso9660_ifs_is_xa (const iso9660_t * p_iso);
+
+
+#ifndef DO_NOT_WANT_COMPATIBILITY
+/** For compatibility with < 0.77 */
+#define iso9660_isdchar iso9660_is_dchar
+#define iso9660_isachar iso9660_is_achar
+#endif /*DO_NOT_WANT_COMPATIBILITY*/
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#undef ISODCL
+#endif /* __CDIO_ISO9660_H__ */
+
+/*
+ * Local variables:
+ * c-file-style: "gnu"
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/lib-x86-32/include/cdio/logging.h b/lib-x86-32/include/cdio/logging.h
new file mode 100644
index 00000000..988d11c5
--- /dev/null
+++ b/lib-x86-32/include/cdio/logging.h
@@ -0,0 +1,136 @@
+/*
+ $Id: logging.h,v 1.11 2008/03/25 15:59:09 karl Exp $
+
+ Copyright (C) 2003, 2004, 2008 Rocky Bernstein <rocky@gnu.org>
+ Copyright (C) 2000 Herbert Valerio Riedel <hvr@gnu.org>
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/** \file logging.h
+ * \brief Header to control logging and level of detail of output.
+ *
+ */
+
+#ifndef __LOGGING_H__
+#define __LOGGING_H__
+
+#include <cdio/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * The different log levels supported.
+ */
+typedef enum {
+ CDIO_LOG_DEBUG = 1, /**< Debug-level messages - helps debug what's up. */
+ CDIO_LOG_INFO, /**< Informational - indicates perhaps something of
+ interest. */
+ CDIO_LOG_WARN, /**< Warning conditions - something that looks funny. */
+ CDIO_LOG_ERROR, /**< Error conditions - may terminate program. */
+ CDIO_LOG_ASSERT /**< Critical conditions - may abort program. */
+} cdio_log_level_t;
+
+/**
+ * The place to save the preference concerning how much verbosity
+ * is desired. This is used by the internal default log handler, but
+ * it could be use by applications which provide their own log handler.
+ */
+extern cdio_log_level_t cdio_loglevel_default;
+
+/**
+ * This type defines the signature of a log handler. For every
+ * message being logged, the handler will receive the log level and
+ * the message string.
+ *
+ * @see cdio_log_set_handler
+ * @see cdio_log_level_t
+ *
+ * @param level The log level.
+ * @param message The log message.
+ */
+typedef void (*cdio_log_handler_t) (cdio_log_level_t level,
+ const char message[]);
+
+/**
+ * Set a custom log handler for libcdio. The return value is the log
+ * handler being replaced. If the provided parameter is NULL, then
+ * the handler will be reset to the default handler.
+ *
+ * @see cdio_log_handler_t
+ *
+ * @param new_handler The new log handler.
+ * @return The previous log handler.
+ */
+cdio_log_handler_t cdio_log_set_handler (cdio_log_handler_t new_handler);
+
+/**
+ * Handle an message with the given log level.
+ *
+ * @see cdio_debug
+ * @see cdio_info
+ * @see cdio_warn
+ * @see cdio_error
+
+ * @param level The log level.
+ * @param format printf-style format string
+ * @param ... remaining arguments needed by format string
+ */
+void cdio_log (cdio_log_level_t level,
+ const char format[], ...) GNUC_PRINTF(2, 3);
+
+/**
+ * Handle a debugging message.
+ *
+ * @see cdio_log for a more generic routine
+ */
+void cdio_debug (const char format[], ...) GNUC_PRINTF(1,2);
+
+/**
+ * Handle an informative message.
+ *
+ * @see cdio_log for a more generic routine
+ */
+void cdio_info (const char format[], ...) GNUC_PRINTF(1,2);
+
+/**
+ * Handle a warning message.
+ *
+ * @see cdio_log for a more generic routine
+ */
+void cdio_warn (const char format[], ...) GNUC_PRINTF(1,2);
+
+/**
+ * Handle an error message. Execution is terminated.
+ *
+ * @see cdio_log for a more generic routine.
+ */
+void cdio_error (const char format[], ...) GNUC_PRINTF(1,2);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __LOGGING_H__ */
+
+
+/*
+ * Local variables:
+ * c-file-style: "gnu"
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/lib-x86-32/include/cdio/mmc.h b/lib-x86-32/include/cdio/mmc.h
new file mode 100644
index 00000000..c7a4eeaf
--- /dev/null
+++ b/lib-x86-32/include/cdio/mmc.h
@@ -0,0 +1,907 @@
+/*
+ $Id: mmc.h,v 1.32 2008/05/09 06:13:32 edsdead Exp $
+
+ Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008
+ Rocky Bernstein <rocky@gnu.org>
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * \file mmc.h
+ *
+ * \brief Common definitions for MMC (Multimedia Commands). Applications
+ * include this for direct MMC access.
+*/
+
+#ifndef __CDIO_MMC_H__
+#define __CDIO_MMC_H__
+
+#include <cdio/cdio.h>
+#include <cdio/types.h>
+#include <cdio/dvd.h>
+#include <cdio/audio.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+ /** Set this to the maximum value in milliseconds that we will
+ wait on an MMC command. */
+ extern uint32_t mmc_timeout_ms;
+
+ /** The default timeout (non-read) is 6 seconds. */
+#define MMC_TIMEOUT_DEFAULT 6000
+
+ /** Set this to the maximum value in milliseconds that we will
+ wait on an MMC read command. */
+ extern uint32_t mmc_read_timeout_ms;
+
+ /** The default read timeout is 3 minutes. */
+#define MMC_READ_TIMEOUT_DEFAULT 3*60*1000
+
+
+ /** \brief The opcode-portion (generic packet commands) of an MMC command.
+
+ In general, those opcodes that end in 6 take a 6-byte command
+ descriptor, those that end in 10 take a 10-byte
+ descriptor and those that in in 12 take a 12-byte descriptor.
+
+ (Not that you need to know that, but it seems to be a
+ big deal in the MMC specification.)
+
+ */
+ typedef enum {
+ CDIO_MMC_GPCMD_INQUIRY = 0x12, /**< Request drive
+ information. */
+ CDIO_MMC_GPCMD_MODE_SELECT_6 = 0x15, /**< Select medium
+ (6 bytes). */
+ CDIO_MMC_GPCMD_MODE_SENSE_6 = 0x1a, /**< Get medium or device
+ information. Should be issued
+ before MODE SELECT to get
+ mode support or save current
+ settings. (6 bytes). */
+ CDIO_MMC_GPCMD_START_STOP = 0x1b, /**< Enable/disable Disc
+ operations. (6 bytes). */
+ CDIO_MMC_GPCMD_ALLOW_MEDIUM_REMOVAL = 0x1e, /**< Enable/disable Disc
+ removal. (6 bytes). */
+
+ /** Group 2 Commands (CDB's here are 10-bytes)
+ */
+ CDIO_MMC_GPCMD_READ_10 = 0x28, /**< Read data from drive
+ (10 bytes). */
+ CDIO_MMC_GPCMD_READ_SUBCHANNEL = 0x42, /**< Read Sub-Channel data.
+ (10 bytes). */
+ CDIO_MMC_GPCMD_READ_TOC = 0x43, /**< READ TOC/PMA/ATIP.
+ (10 bytes). */
+ CDIO_MMC_GPCMD_READ_HEADER = 0x44,
+ CDIO_MMC_GPCMD_PLAY_AUDIO_10 = 0x45, /**< Begin audio playing at
+ current position
+ (10 bytes). */
+ CDIO_MMC_GPCMD_GET_CONFIGURATION = 0x46, /**< Get drive Capabilities
+ (10 bytes) */
+ CDIO_MMC_GPCMD_PLAY_AUDIO_MSF = 0x47, /**< Begin audio playing at
+ specified MSF (10
+ bytes). */
+ CDIO_MMC_GPCMD_PLAY_AUDIO_TI = 0x48,
+ CDIO_MMC_GPCMD_PLAY_TRACK_REL_10 = 0x49, /**< Play audio at the track
+ relative LBA. (10 bytes).
+ Doesn't seem to be part
+ of MMC standards but is
+ handled by Plextor drives.
+ */
+
+ CDIO_MMC_GPCMD_GET_EVENT_STATUS = 0x4a, /**< Report events and
+ Status. */
+ CDIO_MMC_GPCMD_PAUSE_RESUME = 0x4b, /**< Stop or restart audio
+ playback. (10 bytes).
+ Used with a PLAY command. */
+
+ CDIO_MMC_GPCMD_READ_DISC_INFO = 0x51, /**< Get CD information.
+ (10 bytes). */
+ CDIO_MMC_GPCMD_MODE_SELECT_10 = 0x55, /**< Select medium
+ (10-bytes). */
+ CDIO_MMC_GPCMD_MODE_SENSE_10 = 0x5a, /**< Get medium or device
+ information. Should be issued
+ before MODE SELECT to get
+ mode support or save current
+ settings. (6 bytes). */
+
+ /** Group 5 Commands (CDB's here are 12-bytes)
+ */
+ CDIO_MMC_GPCMD_PLAY_AUDIO_12 = 0xa5, /**< Begin audio playing at
+ current position
+ (12 bytes) */
+ CDIO_MMC_GPCMD_LOAD_UNLOAD = 0xa6, /**< Load/unload a Disc
+ (12 bytes) */
+ CDIO_MMC_GPCMD_READ_12 = 0xa8, /**< Read data from drive
+ (12 bytes). */
+ CDIO_MMC_GPCMD_PLAY_TRACK_REL_12 = 0xa9, /**< Play audio at the track
+ relative LBA. (12 bytes).
+ Doesn't seem to be part
+ of MMC standards but is
+ handled by Plextor drives.
+ */
+ CDIO_MMC_GPCMD_READ_DVD_STRUCTURE = 0xad, /**< Get DVD structure info
+ from media (12 bytes). */
+ CDIO_MMC_GPCMD_READ_MSF = 0xb9, /**< Read almost any field
+ of a CD sector at specified
+ MSF. (12 bytes). */
+ CDIO_MMC_GPCMD_SET_SPEED = 0xbb, /**< Set drive speed
+ (12 bytes). This is listed
+ as optional in ATAPI 2.6,
+ but is (curiously)
+ missing from Mt. Fuji,
+ Table 57. It is mentioned
+ in Mt. Fuji Table 377 as an
+ MMC command for SCSI
+ devices though... Most
+ ATAPI drives support it. */
+ CDIO_MMC_GPCMD_READ_CD = 0xbe, /**< Read almost any field
+ of a CD sector at current
+ location. (12 bytes). */
+ /** Vendor-unique Commands
+ */
+ CDIO_MMC_GPCMD_CD_PLAYBACK_STATUS = 0xc4 /**< SONY unique = command */,
+ CDIO_MMC_GPCMD_PLAYBACK_CONTROL = 0xc9 /**< SONY unique = command */,
+ CDIO_MMC_GPCMD_READ_CDDA = 0xd8 /**< Vendor unique = command */,
+ CDIO_MMC_GPCMD_READ_CDXA = 0xdb /**< Vendor unique = command */,
+ CDIO_MMC_GPCMD_READ_ALL_SUBCODES = 0xdf /**< Vendor unique = command */
+ } cdio_mmc_gpcmd_t;
+
+
+ /** Read Subchannel states */
+ typedef enum {
+ CDIO_MMC_READ_SUB_ST_INVALID = 0x00, /**< audio status not supported */
+ CDIO_MMC_READ_SUB_ST_PLAY = 0x11, /**< audio play operation in
+ progress */
+ CDIO_MMC_READ_SUB_ST_PAUSED = 0x12, /**< audio play operation paused */
+ CDIO_MMC_READ_SUB_ST_COMPLETED = 0x13, /**< audio play successfully
+ completed */
+ CDIO_MMC_READ_SUB_ST_ERROR = 0x14, /**< audio play stopped due to
+ error */
+ CDIO_MMC_READ_SUB_ST_NO_STATUS = 0x15, /**< no current audio status to
+ return */
+ } cdio_mmc_read_sub_state_t;
+
+ /** Level values that can go into READ_CD */
+ typedef enum {
+ CDIO_MMC_READ_TYPE_ANY = 0, /**< All types */
+ CDIO_MMC_READ_TYPE_CDDA = 1, /**< Only CD-DA sectors */
+ CDIO_MMC_READ_TYPE_MODE1 = 2, /**< mode1 sectors (user data = 2048) */
+ CDIO_MMC_READ_TYPE_MODE2 = 3, /**< mode2 sectors form1 or form2 */
+ CDIO_MMC_READ_TYPE_M2F1 = 4, /**< mode2 sectors form1 */
+ CDIO_MMC_READ_TYPE_M2F2 = 5 /**< mode2 sectors form2 */
+ } cdio_mmc_read_cd_type_t;
+
+ /** Format values for READ_TOC */
+ typedef enum {
+ CDIO_MMC_READTOC_FMT_TOC = 0,
+ CDIO_MMC_READTOC_FMT_SESSION = 1,
+ CDIO_MMC_READTOC_FMT_FULTOC = 2,
+ CDIO_MMC_READTOC_FMT_PMA = 3, /**< Q subcode data */
+ CDIO_MMC_READTOC_FMT_ATIP = 4, /**< includes media type */
+ CDIO_MMC_READTOC_FMT_CDTEXT = 5 /**< CD-TEXT info */
+ } cdio_mmc_readtoc_t;
+
+/** Page codes for MODE SENSE and MODE SET. */
+ typedef enum {
+ CDIO_MMC_R_W_ERROR_PAGE = 0x01,
+ CDIO_MMC_WRITE_PARMS_PAGE = 0x05,
+ CDIO_MMC_CDR_PARMS_PAGE = 0x0d,
+ CDIO_MMC_AUDIO_CTL_PAGE = 0x0e,
+ CDIO_MMC_POWER_PAGE = 0x1a,
+ CDIO_MMC_FAULT_FAIL_PAGE = 0x1c,
+ CDIO_MMC_TO_PROTECT_PAGE = 0x1d,
+ CDIO_MMC_CAPABILITIES_PAGE = 0x2a,
+ CDIO_MMC_ALL_PAGES = 0x3f,
+ } cdio_mmc_mode_page_t;
+
+
+PRAGMA_BEGIN_PACKED
+ struct mmc_audio_volume_entry_s
+ {
+ uint8_t selection; /* Only the lower 4 bits are used. */
+ uint8_t volume;
+ } GNUC_PACKED;
+
+ typedef struct mmc_audio_volume_entry_s mmc_audio_volume_entry_t;
+
+ /** This struct is used by cdio_audio_get_volume and cdio_audio_set_volume */
+ struct mmc_audio_volume_s
+ {
+ mmc_audio_volume_entry_t port[4];
+ } GNUC_PACKED;
+
+ typedef struct mmc_audio_volume_s mmc_audio_volume_t;
+
+PRAGMA_END_PACKED
+
+
+/** Return type codes for GET_CONFIGURATION. */
+typedef enum {
+ CDIO_MMC_GET_CONF_ALL_FEATURES = 0, /**< all features without regard
+ to currency. */
+ CDIO_MMC_GET_CONF_CURRENT_FEATURES = 1, /**< features which are currently
+ in effect (e.g. based on
+ medium inserted). */
+ CDIO_MMC_GET_CONF_NAMED_FEATURE = 2 /**< just the feature named in
+ the GET_CONFIGURATION cdb. */
+} cdio_mmc_get_conf_t;
+
+
+/** FEATURE codes used in GET CONFIGURATION. */
+
+typedef enum {
+ CDIO_MMC_FEATURE_PROFILE_LIST = 0x000, /**< Profile List Feature */
+ CDIO_MMC_FEATURE_CORE = 0x001,
+ CDIO_MMC_FEATURE_MORPHING = 0x002, /**< Report/prevent operational
+ changes */
+ CDIO_MMC_FEATURE_REMOVABLE_MEDIUM = 0x003, /**< Removable Medium Feature */
+ CDIO_MMC_FEATURE_WRITE_PROTECT = 0x004, /**< Write Protect Feature */
+ CDIO_MMC_FEATURE_RANDOM_READABLE = 0x010, /**< Random Readable Feature */
+ CDIO_MMC_FEATURE_MULTI_READ = 0x01D, /**< Multi-Read Feature */
+ CDIO_MMC_FEATURE_CD_READ = 0x01E, /**< CD Read Feature */
+ CDIO_MMC_FEATURE_DVD_READ = 0x01F, /**< DVD Read Feature */
+ CDIO_MMC_FEATURE_RANDOM_WRITABLE = 0x020, /**< Random Writable Feature */
+ CDIO_MMC_FEATURE_INCR_WRITE = 0x021, /**< Incremental Streaming
+ Writable Feature */
+ CDIO_MMC_FEATURE_SECTOR_ERASE = 0x022, /**< Sector Erasable Feature */
+ CDIO_MMC_FEATURE_FORMATABLE = 0x023, /**< Formattable Feature */
+ CDIO_MMC_FEATURE_DEFECT_MGMT = 0x024, /**< Management Ability of the
+ Logical Unit/media system to
+ provide an apparently
+ defect-free space.*/
+ CDIO_MMC_FEATURE_WRITE_ONCE = 0x025, /**< Write Once
+ Feature */
+ CDIO_MMC_FEATURE_RESTRICT_OVERW = 0x026, /**< Restricted Overwrite
+ Feature */
+ CDIO_MMC_FEATURE_CD_RW_CAV = 0x027, /**< CD-RW CAV Write Feature */
+ CDIO_MMC_FEATURE_MRW = 0x028, /**< MRW Feature */
+ CDIO_MMC_FEATURE_ENHANCED_DEFECT = 0x029, /**< Enhanced Defect Reporting */
+ CDIO_MMC_FEATURE_DVD_PRW = 0x02A, /**< DVD+RW Feature */
+ CDIO_MMC_FEATURE_DVD_PR = 0x02B, /**< DVD+R Feature */
+ CDIO_MMC_FEATURE_RIGID_RES_OVERW = 0x02C, /**< Rigid Restricted Overwrite */
+ CDIO_MMC_FEATURE_CD_TAO = 0x02D, /**< CD Track at Once */
+ CDIO_MMC_FEATURE_CD_SAO = 0x02E, /**< CD Mastering (Session at
+ Once) */
+ CDIO_MMC_FEATURE_DVD_R_RW_WRITE = 0x02F, /**< DVD-R/RW Write */
+ CDIO_MMC_FEATURE_CD_RW_MEDIA_WRITE= 0x037, /**< CD-RW Media Write Support */
+ CDIO_MMC_FEATURE_DVD_PR_2_LAYER = 0x03B, /**< DVD+R Double Layer */
+ CDIO_MMC_FEATURE_POWER_MGMT = 0x100, /**< Initiator and device directed
+ power management */
+ CDIO_MMC_FEATURE_CDDA_EXT_PLAY = 0x103, /**< Ability to play audio CDs
+ via the Logical Unit's own
+ analog output */
+ CDIO_MMC_FEATURE_MCODE_UPGRADE = 0x104, /* Ability for the device to
+ accept new microcode via
+ the interface */
+ CDIO_MMC_FEATURE_TIME_OUT = 0x105, /**< Ability to respond to all
+ commands within a specific
+ time */
+ CDIO_MMC_FEATURE_DVD_CSS = 0x106, /**< Ability to perform DVD
+ CSS/CPPM authentication and
+ RPC */
+ CDIO_MMC_FEATURE_RT_STREAMING = 0x107, /**< Ability to read and write
+ using Initiator requested
+ performance parameters */
+ CDIO_MMC_FEATURE_LU_SN = 0x108, /**< The Logical Unit has a unique
+ identifier. */
+ CDIO_MMC_FEATURE_FIRMWARE_DATE = 0x1FF, /**< Firmware creation date
+ report */
+} cdio_mmc_feature_t;
+
+/** Profile profile codes used in GET_CONFIGURATION - PROFILE LIST. */
+typedef enum {
+ CDIO_MMC_FEATURE_PROF_NON_REMOVABLE = 0x0001, /**< Re-writable disk, capable
+ of changing behavior */
+ CDIO_MMC_FEATURE_PROF_REMOVABLE = 0x0002, /**< disk Re-writable; with
+ removable media */
+ CDIO_MMC_FEATURE_PROF_MO_ERASABLE = 0x0003, /**< Erasable Magneto-Optical
+ disk with sector erase
+ capability */
+ CDIO_MMC_FEATURE_PROF_MO_WRITE_ONCE = 0x0004, /**< Write Once Magneto-Optical
+ write once */
+ CDIO_MMC_FEATURE_PROF_AS_MO = 0x0005, /**< Advance Storage
+ Magneto-Optical */
+ CDIO_MMC_FEATURE_PROF_CD_ROM = 0x0008, /**< Read only Compact Disc
+ capable */
+ CDIO_MMC_FEATURE_PROF_CD_R = 0x0009, /**< Write once Compact Disc
+ capable */
+ CDIO_MMC_FEATURE_PROF_CD_RW = 0x000A, /**< CD-RW Re-writable
+ Compact Disc capable */
+ CDIO_MMC_FEATURE_PROF_DVD_ROM = 0x0010, /**< Read only DVD */
+ CDIO_MMC_FEATURE_PROF_DVD_R_SEQ = 0x0011, /**< Re-recordable DVD using
+ Sequential recording */
+ CDIO_MMC_FEATURE_PROF_DVD_RAM = 0x0012, /**< Re-writable DVD */
+ CDIO_MMC_FEATURE_PROF_DVD_RW_RO = 0x0013, /**< Re-recordable DVD using
+ Restricted Overwrite */
+ CDIO_MMC_FEATURE_PROF_DVD_RW_SEQ = 0x0014, /**< Re-recordable DVD using
+ Sequential recording */
+ CDIO_MMC_FEATURE_PROF_DVD_PRW = 0x001A, /**< DVD+RW - DVD ReWritable */
+ CDIO_MMC_FEATURE_PROF_DVD_PR = 0x001B, /**< DVD+R - DVD Recordable */
+ CDIO_MMC_FEATURE_PROF_DDCD_ROM = 0x0020, /**< Read only DDCD */
+ CDIO_MMC_FEATURE_PROF_DDCD_R = 0x0021, /**< DDCD-R Write only DDCD */
+ CDIO_MMC_FEATURE_PROF_DDCD_RW = 0x0022, /**< Re-Write only DDCD */
+ CDIO_MMC_FEATURE_PROF_DVD_PR2 = 0x002B, /**< DVD+R - DVD Recordable
+ double layer */
+ CDIO_MMC_FEATURE_PROF_NON_CONFORM = 0xFFFF, /**< The Logical Unit does not
+ conform to any Profile. */
+} cdio_mmc_feature_profile_t;
+
+typedef enum {
+ CDIO_MMC_FEATURE_INTERFACE_UNSPECIFIED = 0,
+ CDIO_MMC_FEATURE_INTERFACE_SCSI = 1,
+ CDIO_MMC_FEATURE_INTERFACE_ATAPI = 2,
+ CDIO_MMC_FEATURE_INTERFACE_IEEE_1394 = 3,
+ CDIO_MMC_FEATURE_INTERFACE_IEEE_1394A = 4,
+ CDIO_MMC_FEATURE_INTERFACE_FIBRE_CH = 5
+} cdio_mmc_feature_interface_t;
+
+
+/** The largest Command Descriptor Block (CDB) size.
+ The possible sizes are 6, 10, and 12 bytes.
+ */
+#define MAX_CDB_LEN 12
+
+/** \brief A Command Descriptor Block (CDB) used in sending MMC
+ commands.
+ */
+typedef struct mmc_cdb_s {
+ uint8_t field[MAX_CDB_LEN];
+} mmc_cdb_t;
+
+ /** \brief Format of header block in data returned from an MMC
+ GET_CONFIGURATION command.
+ */
+ typedef struct mmc_feature_list_header_s {
+ unsigned char length_msb;
+ unsigned char length_1sb;
+ unsigned char length_2sb;
+ unsigned char length_lsb;
+ unsigned char reserved1;
+ unsigned char reserved2;
+ unsigned char profile_msb;
+ unsigned char profile_lsb;
+ } cdio_mmc_feature_list_header_t;
+
+ /** An enumeration indicating whether an MMC command is sending
+ data or getting data.
+ */
+ typedef enum mmc_direction_s {
+ SCSI_MMC_DATA_READ,
+ SCSI_MMC_DATA_WRITE
+ } cdio_mmc_direction_t;
+
+ typedef struct mmc_subchannel_s
+ {
+ uint8_t reserved;
+ uint8_t audio_status;
+ uint16_t data_length; /**< Really ISO 9660 7.2.2 */
+ uint8_t format;
+ uint8_t address: 4;
+ uint8_t control: 4;
+ uint8_t track;
+ uint8_t index;
+ uint8_t abs_addr[4];
+ uint8_t rel_addr[4];
+ } cdio_mmc_subchannel_t;
+
+#define CDIO_MMC_SET_COMMAND(cdb, command) \
+ cdb[0] = command
+
+#define CDIO_MMC_SET_READ_TYPE(cdb, sector_type) \
+ cdb[1] = (sector_type << 2)
+
+#define CDIO_MMC_GETPOS_LEN16(p, pos) \
+ (p[pos]<<8) + p[pos+1]
+
+#define CDIO_MMC_GET_LEN16(p) \
+ (p[0]<<8) + p[1]
+
+#define CDIO_MMC_GET_LEN32(p) \
+ (p[0] << 24) + (p[1] << 16) + (p[2] << 8) + p[3];
+
+#define CDIO_MMC_SET_LEN16(cdb, pos, len) \
+ cdb[pos ] = (len >> 8) & 0xff; \
+ cdb[pos+1] = (len ) & 0xff
+
+#define CDIO_MMC_SET_READ_LBA(cdb, lba) \
+ cdb[2] = (lba >> 24) & 0xff; \
+ cdb[3] = (lba >> 16) & 0xff; \
+ cdb[4] = (lba >> 8) & 0xff; \
+ cdb[5] = (lba ) & 0xff
+
+#define CDIO_MMC_SET_START_TRACK(cdb, command) \
+ cdb[6] = command
+
+#define CDIO_MMC_SET_READ_LENGTH24(cdb, len) \
+ cdb[6] = (len >> 16) & 0xff; \
+ cdb[7] = (len >> 8) & 0xff; \
+ cdb[8] = (len ) & 0xff
+
+#define CDIO_MMC_SET_READ_LENGTH16(cdb, len) \
+ CDIO_MMC_SET_LEN16(cdb, 7, len)
+
+#define CDIO_MMC_SET_READ_LENGTH8(cdb, len) \
+ cdb[8] = (len ) & 0xff
+
+#define CDIO_MMC_MCSB_ALL_HEADERS 0xf
+
+#define CDIO_MMC_SET_MAIN_CHANNEL_SELECTION_BITS(cdb, val) \
+ cdb[9] = val << 3;
+
+/**
+ Read Audio Subchannel information
+
+ @param p_cdio the CD object to be acted upon.
+ @param p_subchannel place for returned subchannel information
+*/
+driver_return_code_t
+mmc_audio_read_subchannel (CdIo_t *p_cdio,
+ /*out*/ cdio_subchannel_t *p_subchannel);
+
+ /**
+ Return a string containing the name of the audio state as returned from
+ the Q_SUBCHANNEL.
+ */
+ const char *mmc_audio_state2str( uint8_t i_audio_state );
+
+ /**
+ Eject using MMC commands. If CD-ROM is "locked" we'll unlock it.
+ Command is not "immediate" -- we'll wait for the command to complete.
+ For a more general (and lower-level) routine, @see mmc_start_stop_media.
+ */
+ driver_return_code_t mmc_eject_media( const CdIo_t *p_cdio );
+
+ /**
+ Return a string containing the name of the given feature
+ */
+ const char *mmc_feature2str( int i_feature );
+
+ /**
+ Return a string containing the name of the given feature
+ */
+ const char *mmc_feature_profile2str( int i_feature_profile );
+
+ /**
+ Return the length in bytes of the Command Descriptor
+ Buffer (CDB) for a given MMC command. The length will be
+ either 6, 10, or 12.
+ */
+ uint8_t mmc_get_cmd_len(uint8_t mmc_cmd);
+
+ /**
+ Get the block size used in read requests, via MMC.
+ @return the blocksize if > 0; error if <= 0
+ */
+ int mmc_get_blocksize ( CdIo_t *p_cdio );
+
+ /**
+ * Close tray using a MMC START STOP command.
+ */
+ driver_return_code_t mmc_close_tray( CdIo_t *p_cdio );
+
+ /**
+ Get the lsn of the end of the CD
+
+ @return the lsn. On error return CDIO_INVALID_LSN.
+ */
+ lsn_t mmc_get_disc_last_lsn( const CdIo_t *p_cdio );
+
+ /**
+ Return the discmode as reported by the MMC Read (FULL) TOC
+ command.
+
+ Information was obtained from Section 5.1.13 (Read TOC/PMA/ATIP)
+ pages 56-62 from the MMC draft specification, revision 10a
+ at http://www.t10.org/ftp/t10/drafts/mmc/mmc-r10a.pdf See
+ especially tables 72, 73 and 75.
+ */
+ discmode_t mmc_get_discmode( const CdIo_t *p_cdio );
+
+
+ /**
+ Get drive capabilities for a device.
+ @return the drive capabilities.
+ */
+ void mmc_get_drive_cap ( CdIo_t *p_cdio,
+ /*out*/ cdio_drive_read_cap_t *p_read_cap,
+ /*out*/ cdio_drive_write_cap_t *p_write_cap,
+ /*out*/ cdio_drive_misc_cap_t *p_misc_cap);
+
+ typedef enum {
+ CDIO_MMC_LEVEL_WEIRD,
+ CDIO_MMC_LEVEL_1,
+ CDIO_MMC_LEVEL_2,
+ CDIO_MMC_LEVEL_3,
+ CDIO_MMC_LEVEL_NONE
+ } cdio_mmc_level_t;
+
+ /**
+ Get the MMC level supported by the device.
+ */
+ cdio_mmc_level_t mmc_get_drive_mmc_cap(CdIo_t *p_cdio);
+
+
+ /**
+ Get the DVD type associated with cd object.
+
+ @return the DVD discmode.
+ */
+ discmode_t mmc_get_dvd_struct_physical ( const CdIo_t *p_cdio,
+ cdio_dvd_struct_t *s);
+
+ /*!
+ Return results of media status
+ @param p_cdio the CD object to be acted upon.
+ @param out_buf media status code from operation
+ @return DRIVER_OP_SUCCESS (0) if we got the status.
+ return codes are the same as driver_return_code_t
+ */
+ int mmc_get_event_status(const CdIo_t *p_cdio, uint8_t out_buf[2]);
+
+ /*!
+ Find out if media tray is open or closed.
+ @param p_cdio the CD object to be acted upon.
+ @return 1 if media is open, 0 if closed. Error
+ return codes are the same as driver_return_code_t
+ */
+ int mmc_get_tray_status ( const CdIo_t *p_cdio );
+
+ /**
+ Get the CD-ROM hardware info via an MMC INQUIRY command.
+
+ @return true if we were able to get hardware info, false if we had
+ an error.
+ */
+ bool mmc_get_hwinfo ( const CdIo_t *p_cdio,
+ /* out*/ cdio_hwinfo_t *p_hw_info );
+
+
+ /**
+ Find out if media has changed since the last call.
+ @param p_cdio the CD object to be acted upon.
+ @return 1 if media has changed since last call, 0 if not. Error
+ return codes are the same as driver_return_code_t
+ */
+ int mmc_get_media_changed(const CdIo_t *p_cdio);
+
+ /**
+ Get the media catalog number (MCN) from the CD via MMC.
+
+ @return the media catalog number r NULL if there is none or we
+ don't have the ability to get it.
+
+ Note: string is malloc'd so caller has to free() the returned
+ string when done with it.
+
+ */
+ char * mmc_get_mcn ( const CdIo_t *p_cdio );
+
+ /** Get the output port volumes and port selections used on AUDIO PLAY
+ commands via a MMC MODE SENSE command using the CD Audio Control
+ Page.
+ */
+ driver_return_code_t mmc_audio_get_volume (CdIo_t *p_cdio, /*out*/
+ mmc_audio_volume_t *p_volume);
+
+ /**
+ Report if CD-ROM has a praticular kind of interface (ATAPI, SCSCI, ...)
+ Is it possible for an interface to have serveral? If not this
+ routine could probably return the single mmc_feature_interface_t.
+ @return true if we have the interface and false if not.
+ */
+ bool_3way_t mmc_have_interface( CdIo_t *p_cdio,
+ cdio_mmc_feature_interface_t e_interface );
+
+ /** Run a MODE_SENSE command (6- or 10-byte version)
+ and put the results in p_buf
+ @return DRIVER_OP_SUCCESS if we ran the command ok.
+ */
+ int mmc_mode_sense( CdIo_t *p_cdio, /*out*/ void *p_buf, int i_size,
+ int page);
+
+
+ /** Run a MODE_SENSE command (10-byte version)
+ and put the results in p_buf
+ @return DRIVER_OP_SUCCESS if we ran the command ok.
+ */
+ int mmc_mode_sense_10( CdIo_t *p_cdio, /*out*/ void *p_buf, int i_size,
+ int page);
+
+ /** Run a MODE_SENSE command (6-byte version)
+ and put the results in p_buf
+ @return DRIVER_OP_SUCCESS if we ran the command ok.
+ */
+ int mmc_mode_sense_6( CdIo_t *p_cdio, /*out*/ void *p_buf, int i_size,
+ int page);
+
+ /** Issue a MMC READ_CD command.
+
+ @param p_cdio object to read from
+
+ @param p_buf Place to store data. The caller should ensure that
+ p_buf can hold at least i_blocksize * i_blocks bytes.
+
+ @param i_lsn sector to read
+
+ @param expected_sector_type restricts reading to a specific CD
+ sector type. Only 3 bits with values 1-5 are used:
+ 0 all sector types
+ 1 CD-DA sectors only
+ 2 Mode 1 sectors only
+ 3 Mode 2 formless sectors only. Note in contrast to all other
+ values an MMC CD-ROM is not required to support this mode.
+ 4 Mode 2 Form 1 sectors only
+ 5 Mode 2 Form 2 sectors only
+
+ @param b_digital_audio_play Control error concealment when the
+ data being read is CD-DA. If the data being read is not CD-DA,
+ this parameter is ignored. If the data being read is CD-DA and
+ DAP is false zero, then the user data returned should not be
+ modified by flaw obscuring mechanisms such as audio data mute and
+ interpolate. If the data being read is CD-DA and DAP is true,
+ then the user data returned should be modified by flaw obscuring
+ mechanisms such as audio data mute and interpolate.
+
+ b_sync_header return the sync header (which will probably have
+ the same value as CDIO_SECTOR_SYNC_HEADER of size
+ CDIO_CD_SYNC_SIZE).
+
+ @param header_codes Header Codes refer to the sector header and
+ the sub-header that is present in mode 2 formed sectors:
+
+ 0 No header information is returned.
+ 1 The 4-byte sector header of data sectors is be returned,
+ 2 The 8-byte sector sub-header of mode 2 formed sectors is
+ returned.
+ 3 Both sector header and sub-header (12 bytes) is returned.
+ The Header preceeds the rest of the bytes (e.g. user-data bytes)
+ that might get returned.
+
+ @param b_user_data Return user data if true.
+
+ For CD-DA, the User Data is CDIO_CD_FRAMESIZE_RAW bytes.
+
+ For Mode 1, The User Data is ISO_BLOCKSIZE bytes beginning at
+ offset CDIO_CD_HEADER_SIZE+CDIO_CD_SUBHEADER_SIZE.
+
+ For Mode 2 formless, The User Data is M2RAW_SECTOR_SIZE bytes
+ beginning at offset CDIO_CD_HEADER_SIZE+CDIO_CD_SUBHEADER_SIZE.
+
+ For data Mode 2, form 1, User Data is ISO_BLOCKSIZE bytes beginning at
+ offset CDIO_CD_XA_SYNC_HEADER.
+
+ For data Mode 2, form 2, User Data is 2 324 bytes beginning at
+ offset CDIO_CD_XA_SYNC_HEADER.
+
+ @param b_sync
+
+ @param b_edc_ecc true if we return EDC/ECC error detection/correction bits.
+
+ The presence and size of EDC redundancy or ECC parity is defined
+ according to sector type:
+
+ CD-DA sectors have neither EDC redundancy nor ECC parity.
+
+ Data Mode 1 sectors have 288 bytes of EDC redundancy, Pad, and
+ ECC parity beginning at offset 2064.
+
+ Data Mode 2 formless sectors have neither EDC redundancy nor ECC
+ parity
+
+ Data Mode 2 form 1 sectors have 280 bytes of EDC redundancy and
+ ECC parity beginning at offset 2072
+
+ Data Mode 2 form 2 sectors optionally have 4 bytes of EDC
+ redundancy beginning at offset 2348.
+
+
+ @param c2_error_information If true associate a bit with each
+ sector for C2 error The resulting bit field is ordered exactly as
+ the main channel bytes. Each 8-bit boundary defines a byte of
+ flag bits.
+
+ @param subchannel_selection subchannel-selection bits
+
+ 0 No Sub-channel data shall be returned. (0 bytes)
+ 1 RAW P-W Sub-channel data shall be returned. (96 byte)
+ 2 Formatted Q sub-channel data shall be transferred (16 bytes)
+ 3 Reserved
+ 4 Corrected and de-interleaved R-W sub-channel (96 bytes)
+ 5-7 Reserved
+
+ @param i_blocksize size of the a block expected to be returned
+
+ @param i_blocks number of blocks expected to be returned.
+
+ */
+ driver_return_code_t
+ mmc_read_cd ( const CdIo_t *p_cdio, void *p_buf, lsn_t i_lsn,
+ int expected_sector_type, bool b_digital_audio_play,
+ bool b_sync, uint8_t header_codes, bool b_user_data,
+ bool b_edc_ecc, uint8_t c2_error_information,
+ uint8_t subchannel_selection, uint16_t i_blocksize,
+ uint32_t i_blocks );
+
+ /** Read just the user data part of some sort of data sector (via
+ mmc_read_cd).
+
+ @param p_cdio object to read from
+
+ @param p_buf place to read data into. The caller should make sure
+ this location can store at least CDIO_CD_FRAMESIZE,
+ M2RAW_SECTOR_SIZE, or M2F2_SECTOR_SIZE depending on
+ the kind of sector getting read. If you don't know
+ whether you have a Mode 1/2, Form 1/ Form 2/Formless
+ sector best to reserve space for the maximum,
+ M2RAW_SECTOR_SIZE.
+
+ @param i_lsn sector to read
+ @param i_blocksize size of each block
+ @param i_blocks number of blocks to read
+
+ */
+ driver_return_code_t mmc_read_data_sectors ( CdIo_t *p_cdio, void *p_buf,
+ lsn_t i_lsn,
+ uint16_t i_blocksize,
+ uint32_t i_blocks );
+
+ /** Read sectors using SCSI-MMC GPCMD_READ_CD.
+ Can read only up to 25 blocks.
+ */
+ driver_return_code_t mmc_read_sectors ( const CdIo_t *p_cdio, void *p_buf,
+ lsn_t i_lsn, int read_sector_type,
+ uint32_t i_blocks);
+
+ /**
+ Run a Multimedia command (MMC).
+
+ @param p_cdio CD structure set by cdio_open().
+ @param i_timeout_ms time in milliseconds we will wait for the command
+ to complete.
+ @param p_cdb CDB bytes. All values that are needed should be set
+ on input. We'll figure out what the right CDB length
+ should be.
+ @param e_direction direction the transfer is to go.
+ @param i_buf Size of buffer
+ @param p_buf Buffer for data, both sending and receiving.
+
+ @return 0 if command completed successfully.
+ */
+ driver_return_code_t
+ mmc_run_cmd( const CdIo_t *p_cdio, unsigned int i_timeout_ms,
+ const mmc_cdb_t *p_cdb,
+ cdio_mmc_direction_t e_direction, unsigned int i_buf,
+ /*in/out*/ void *p_buf );
+
+ /**
+ Run a Multimedia command (MMC) specifying the CDB length.
+ The motivation here is for example ot use in is an undocumented
+ debug command for LG drives (namely E7), whose length is being
+ miscalculated by mmc_get_cmd_len(); it doesn't follow the usual
+ code number to length conventions. Patch supplied by SukkoPera.
+
+ @param p_cdio CD structure set by cdio_open().
+ @param i_timeout_ms time in milliseconds we will wait for the command
+ to complete.
+ @param p_cdb CDB bytes. All values that are needed should be set
+ on input.
+ @param i_cdb number of CDB bytes.
+ @param e_direction direction the transfer is to go.
+ @param i_buf Size of buffer
+ @param p_buf Buffer for data, both sending and receiving.
+
+ @return 0 if command completed successfully.
+ */
+ driver_return_code_t
+ mmc_run_cmd_len( const CdIo_t *p_cdio, unsigned int i_timeout_ms,
+ const mmc_cdb_t *p_cdb, unsigned int i_cdb,
+ cdio_mmc_direction_t e_direction, unsigned int i_buf,
+ /*in/out*/ void *p_buf );
+
+ /**
+ Set the block size for subsequest read requests, via MMC.
+ */
+ driver_return_code_t mmc_set_blocksize ( const CdIo_t *p_cdio,
+ uint16_t i_blocksize);
+
+ /**
+ Set the drive speed in CD-ROM speed units.
+
+ @param p_cdio CD structure set by cdio_open().
+ @param i_drive_speed speed in CD-ROM speed units. Note this
+ not Kbs as would be used in the MMC spec or
+ in mmc_set_speed(). To convert CD-ROM speed units
+ to Kbs, multiply the number by 176 (for raw data)
+ and by 150 (for filesystem data). On many CD-ROM
+ drives, specifying a value too large will result
+ in using the fastest speed.
+
+ @return the drive speed if greater than 0. -1 if we had an error. is -2
+ returned if this is not implemented for the current driver.
+
+ @see cdio_set_speed and mmc_set_speed
+ */
+ driver_return_code_t mmc_set_drive_speed( const CdIo_t *p_cdio,
+ int i_drive_speed );
+
+ /**
+ Set the drive speed in K bytes per second.
+
+ @param p_cdio CD structure set by cdio_open().
+ @param i_Kbs_speed speed in K bytes per second. Note this is
+ not in standard CD-ROM speed units, e.g.
+ 1x, 4x, 16x as it is in cdio_set_speed.
+ To convert CD-ROM speed units to Kbs,
+ multiply the number by 176 (for raw data)
+ and by 150 (for filesystem data).
+ Also note that ATAPI specs say that a value
+ less than 176 will result in an error.
+ On many CD-ROM drives,
+ specifying a value too large will result in using
+ the fastest speed.
+
+ @return the drive speed if greater than 0. -1 if we had an error. is -2
+ returned if this is not implemented for the current driver.
+
+ @see cdio_set_speed and mmc_set_drive_speed
+ */
+ driver_return_code_t mmc_set_speed( const CdIo_t *p_cdio,
+ int i_Kbs_speed );
+
+ /**
+ Load or Unload media using a MMC START STOP command.
+
+ @param p_cdio the CD object to be acted upon.
+ @param b_eject eject if true and close tray if false
+ @param b_immediate wait or don't wait for operation to complete
+ @param power_condition Set CD-ROM to idle/standby/sleep. If nonzero
+ eject/load is ignored, so set to 0 if you want to eject or load.
+
+ @see mmc_eject_media or mmc_close_tray
+ */
+ driver_return_code_t
+ mmc_start_stop_media(const CdIo_t *p_cdio, bool b_eject, bool b_immediate,
+ uint8_t power_condition);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+/** The below variables are trickery to force the above enum symbol
+ values to be recorded in debug symbol tables. They are used to
+ allow one to refer to the enumeration value names in the typedefs
+ above in a debugger and debugger expressions
+*/
+extern cdio_mmc_feature_t debug_cdio_mmc_feature;
+extern cdio_mmc_feature_interface_t debug_cdio_mmc_feature_interface;
+extern cdio_mmc_feature_profile_t debug_cdio_mmc_feature_profile;
+extern cdio_mmc_get_conf_t debug_cdio_mmc_get_conf;
+extern cdio_mmc_gpcmd_t debug_cdio_mmc_gpcmd;
+extern cdio_mmc_read_sub_state_t debug_cdio_mmc_read_sub_state;
+extern cdio_mmc_read_cd_type_t debug_cdio_mmc_read_cd_type;
+extern cdio_mmc_readtoc_t debug_cdio_mmc_readtoc;
+extern cdio_mmc_mode_page_t debug_cdio_mmc_mode_page;
+
+#endif /* __MMC_H__ */
+
+/*
+ * Local variables:
+ * c-file-style: "gnu"
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/lib-x86-32/include/cdio/paranoia.h b/lib-x86-32/include/cdio/paranoia.h
new file mode 100644
index 00000000..02b50002
--- /dev/null
+++ b/lib-x86-32/include/cdio/paranoia.h
@@ -0,0 +1,202 @@
+/*
+ $Id: paranoia.h,v 1.15 2008/03/25 15:59:09 karl Exp $
+
+ Copyright (C) 2004, 2005, 2006, 2007, 2008 Rocky Bernstein <rocky@gnu.org>
+ Copyright (C) 1998 Monty xiphmont@mit.edu
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/** \file paranoia.h
+ *
+ * \brief The top-level header for libcdda_paranoia: a device- and OS-
+ * independent library for reading CD-DA with error tolerance and
+ * repair. Applications include this for paranoia access.
+ */
+
+#ifndef _CDIO_PARANOIA_H_
+#define _CDIO_PARANOIA_H_
+
+#include <cdio/cdda.h>
+
+/*! Paranoia likes to work with 16-bit numbers rather than
+ (possibly byte-swapped) bytes. So there are this many
+ 16-bit numbers block (frame, or sector) read.
+*/
+#define CD_FRAMEWORDS (CDIO_CD_FRAMESIZE_RAW/2)
+
+/**
+ Flags used in paranoia_modeset.
+
+ The enumeration type one probably wouldn't really use in a program.
+ It is here instead of defines to give symbolic names that can be
+ helpful in debuggers where wants just to say refer to
+ PARANOIA_MODE_DISABLE and get the correct value.
+*/
+
+typedef enum {
+ PARANOIA_MODE_DISABLE = 0x00, /**< No fixups */
+ PARANOIA_MODE_VERIFY = 0x01, /**< Verify data integrety in overlap area*/
+ PARANOIA_MODE_FRAGMENT = 0x02, /**< unsupported */
+ PARANOIA_MODE_OVERLAP = 0x04, /**< Perform overlapped reads */
+ PARANOIA_MODE_SCRATCH = 0x08, /**< unsupported */
+ PARANOIA_MODE_REPAIR = 0x10, /**< unsupported */
+ PARANOIA_MODE_NEVERSKIP = 0x20, /**< Do not skip failed reads (retry
+ maxretries) */
+ PARANOIA_MODE_FULL = 0xff, /**< Maximum paranoia - all of the above
+ (except disable) */
+} paranoia_mode_t;
+
+
+/**
+ Flags set in a callback.
+
+ The enumeration type one probably wouldn't really use in a program.
+ It is here instead of defines to give symbolic names that can be
+ helpful in debuggers where wants just to say refer to
+ PARANOIA_CB_READ and get the correct value.
+*/
+typedef enum {
+ PARANOIA_CB_READ, /**< Read off adjust ??? */
+ PARANOIA_CB_VERIFY, /**< Verifying jitter */
+ PARANOIA_CB_FIXUP_EDGE, /**< Fixed edge jitter */
+ PARANOIA_CB_FIXUP_ATOM, /**< Fixed atom jitter */
+ PARANOIA_CB_SCRATCH, /**< Unsupported */
+ PARANOIA_CB_REPAIR, /**< Unsupported */
+ PARANOIA_CB_SKIP, /**< Skip exhausted retry */
+ PARANOIA_CB_DRIFT, /**< Skip exhausted retry */
+ PARANOIA_CB_BACKOFF, /**< Unsupported */
+ PARANOIA_CB_OVERLAP, /**< Dynamic overlap adjust */
+ PARANOIA_CB_FIXUP_DROPPED, /**< Fixed dropped bytes */
+ PARANOIA_CB_FIXUP_DUPED, /**< Fixed duplicate bytes */
+ PARANOIA_CB_READERR /**< Hard read error */
+} paranoia_cb_mode_t;
+
+ extern const char *paranoia_cb_mode2str[];
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ /*!
+ Get and initialize a new cdrom_paranoia object from cdrom_drive.
+ Run this before calling any of the other paranoia routines below.
+
+ @return new cdrom_paranoia object Call paranoia_free() when you are
+ done with it
+ */
+ extern cdrom_paranoia_t *cdio_paranoia_init(cdrom_drive_t *d);
+
+ /*!
+ Free any resources associated with p.
+
+ @param p paranoia object to for which resources are to be freed.
+
+ @see paranoia_init.
+ */
+ extern void cdio_paranoia_free(cdrom_paranoia_t *p);
+
+ /*!
+ Set the kind of repair you want to on for reading.
+ The modes are listed above
+
+ @param p paranoia type
+ @param mode_flags paranoia mode flags built from values in
+ paranoia_mode_t, e.g.
+ PARANOIA_MODE_FULL^PARANOIA_MODE_NEVERSKIP
+ */
+ extern void cdio_paranoia_modeset(cdrom_paranoia_t *p, int mode_flags);
+
+ /*!
+ reposition reading offset.
+
+ @param p paranoia type
+ @param seek byte offset to seek to
+ @param whence like corresponding parameter in libc's lseek, e.g.
+ SEEK_SET or SEEK_END.
+ */
+ extern lsn_t cdio_paranoia_seek(cdrom_paranoia_t *p, off_t seek, int whence);
+
+ /*!
+ Reads the next sector of audio data and returns a pointer to a full
+ sector of verified samples.
+
+ @param p paranoia object.
+
+ @param callback callback routine which gets called with the status
+ on each read.
+
+ @return the audio data read, CDIO_CD_FRAMESIZE_RAW (2352)
+ bytes. This data is not to be freed by the caller. It will persist
+ only until the next call to paranoia_read() for this p.
+ */
+ extern int16_t *cdio_paranoia_read(cdrom_paranoia_t *p,
+ void(*callback)(long int,
+ paranoia_cb_mode_t));
+
+ /*! The same as cdio_paranoia_read but the number of retries is set.
+ @param p paranoia object.
+
+ @param callback callback routine which gets called with the status
+ on each read.
+
+ @param max_retries number of times to try re-reading a block before
+ failing.
+
+ @return the block of CDIO_FRAMEIZE_RAW bytes (or
+ CDIO_FRAMESIZE_RAW / 2 16-bit integers). Unless byte-swapping has
+ been turned off the 16-bit integers Endian independent order.
+
+ @see cdio_paranoia_read.
+
+ */
+ extern int16_t *cdio_paranoia_read_limited(cdrom_paranoia_t *p,
+ void(*callback)(long int,
+ paranoia_cb_mode_t),
+ int max_retries);
+
+
+/*! a temporary hack */
+ extern void cdio_paranoia_overlapset(cdrom_paranoia_t *p,long overlap);
+
+ extern void cdio_paranoia_set_range(cdrom_paranoia_t *p, long int start,
+ long int end);
+
+#ifndef DO_NOT_WANT_PARANOIA_COMPATIBILITY
+/** For compatibility with good ol' paranoia */
+#define cdrom_paranoia cdrom_paranoia_t
+#define paranoia_init cdio_paranoia_init
+#define paranoia_free cdio_paranoia_free
+#define paranoia_modeset cdio_paranoia_modeset
+#define paranoia_seek cdio_paranoia_seek
+#define paranoia_read cdio_paranoia_read
+#define paranoia_read_limited cdio_paranoia_read_limited
+#define paranoia_overlapset cdio_paranoia_overlapset
+#define paranoia_set_range cdio_paranoia_set_range
+#endif /*DO_NOT_WANT_PARANOIA_COMPATIBILITY*/
+
+#ifdef __cplusplus
+}
+#endif
+
+/** The below variables are trickery to force the above enum symbol
+ values to be recorded in debug symbol tables. They are used to
+ allow one to refer to the enumeration value names in the typedefs
+ above in a debugger and debugger expressions
+*/
+
+extern paranoia_mode_t debug_paranoia_mode;
+extern paranoia_cb_mode_t debug_paranoia_cb_mode;
+
+#endif /*_CDIO_PARANOIA_H_*/
diff --git a/lib-x86-32/include/cdio/posix.h b/lib-x86-32/include/cdio/posix.h
new file mode 100644
index 00000000..89e0ad37
--- /dev/null
+++ b/lib-x86-32/include/cdio/posix.h
@@ -0,0 +1,43 @@
+/*
+ $Id: posix.h,v 1.2 2008/03/25 15:59:09 karl Exp $
+
+ Copyright (C) 2005, 2008 Rocky Bernstein <rocky@gnu.org>
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*!
+ * \file posix.h
+ *
+ * \brief various POSIX definitions.
+*/
+
+#ifndef __CDIO_POSIX_H__
+#define __CDIO_POSIX_H__
+
+typedef uint32_t posix_mode_t;
+typedef uint32_t posix_nlink_t;
+typedef uint32_t posix_uid_t;
+typedef uint32_t posix_gid_t;
+typedef uint16_t unicode16_t;
+
+#endif /* __CDIO_POSIX_H__ */
+
+
+/*
+ * Local variables:
+ * c-file-style: "gnu"
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/lib-x86-32/include/cdio/read.h b/lib-x86-32/include/cdio/read.h
new file mode 100644
index 00000000..81e5148a
--- /dev/null
+++ b/lib-x86-32/include/cdio/read.h
@@ -0,0 +1,235 @@
+/*
+ $Id: read.h,v 1.15 2008/03/25 15:59:09 karl Exp $
+
+ Copyright (C) 2005, 2006, 2007, 2008 Rocky Bernstein <rocky@gnu.org>
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/** \file read.h
+ *
+ * \brief The top-level header for sector (block, frame)-related
+ * libcdio calls.
+ */
+
+#ifndef __CDIO_READ_H__
+#define __CDIO_READ_H__
+
+#ifndef EXTERNAL_LIBCDIO_CONFIG_H
+#define EXTERNAL_LIBCDIO_CONFIG_H
+/* Need for HAVE_SYS_TYPES_H */
+#include <cdio/cdio_config.h>
+#endif
+
+#ifdef HAVE_SYS_TYPES_H
+/* Some systems need this for off_t and ssize. */
+#include <sys/types.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+ /** All the different ways a block/sector can be read. */
+ typedef enum {
+ CDIO_READ_MODE_AUDIO, /**< CD-DA, audio, Red Book */
+ CDIO_READ_MODE_M1F1, /**< Mode 1 Form 1 */
+ CDIO_READ_MODE_M1F2, /**< Mode 1 Form 2 */
+ CDIO_READ_MODE_M2F1, /**< Mode 2 Form 1 */
+ CDIO_READ_MODE_M2F2 /**< Mode 2 Form 2 */
+ } cdio_read_mode_t;
+
+ /*!
+ Reposition read offset
+ Similar to (if not the same as) libc's fseek()
+
+ @param p_cdio object which gets adjusted
+ @param offset amount to seek
+ @param whence like corresponding parameter in libc's fseek, e.g.
+ SEEK_SET or SEEK_END.
+ @return (off_t) -1 on error.
+ */
+
+ off_t cdio_lseek(const CdIo_t *p_cdio, off_t offset, int whence);
+
+ /*! Reads into buf the next size bytes. Similar to (if not the
+ same as) libc's read(). This is a "cooked" read, or one handled by
+ the OS. It probably won't work on audio data. For that use
+ cdio_read_audio_sector(s).
+
+ @param p_cdio object to read from
+ @param p_buf place to read data into. The caller should make sure
+ this location can store at least i_size bytes.
+ @param i_size number of bytes to read
+
+ @return (ssize_t) -1 on error.
+ */
+ ssize_t cdio_read(const CdIo_t *p_cdio, void *p_buf, size_t i_size);
+
+ /*!
+ Read an audio sector
+
+ @param p_cdio object to read from
+ @param p_buf place to read data into. The caller should make sure
+ this location can store at least CDIO_FRAMESIZE_RAW
+ bytes.
+ @param i_lsn sector to read
+ */
+ driver_return_code_t cdio_read_audio_sector (const CdIo_t *p_cdio,
+ void *p_buf, lsn_t i_lsn);
+
+ /*!
+ Reads audio sectors
+
+ @param p_cdio object to read from
+ @param p_buf place to read data into. The caller should make sure
+ this location can store at least CDIO_FRAMESIZE_RAW
+ * i_blocks bytes.
+ @param i_lsn sector to read
+ @param i_blocks number of sectors to read
+ */
+ driver_return_code_t cdio_read_audio_sectors (const CdIo_t *p_cdio,
+ void *p_buf, lsn_t i_lsn,
+ uint32_t i_blocks);
+
+ /*!
+ Read data sectors
+
+ @param p_cdio object to read from
+ @param p_buf place to read data into. The caller should make sure
+ this location can store at least ISO_BLOCKSIZE,
+ M2RAW_SECTOR_SIZE, or M2F2_SECTOR_SIZE depending
+ on the kind of sector getting read. If you don't
+ know whether you have a Mode 1/2, Form 1/ Form 2/Formless
+ sector best to reserve space for the maximum,
+ M2RAW_SECTOR_SIZE.
+ @param i_lsn sector to read
+ @param i_blocksize size of block. Should be either CDIO_CD_FRAMESIZE,
+ M2RAW_SECTOR_SIZE, or M2F2_SECTOR_SIZE. See comment above under p_buf.
+
+ @param i_blocks number of blocks to read
+ */
+ driver_return_code_t cdio_read_data_sectors ( const CdIo_t *p_cdio,
+ void *p_buf, lsn_t i_lsn,
+ uint16_t i_blocksize,
+ uint32_t i_blocks );
+ /*!
+ Reads a mode 1 sector
+
+ @param p_cdio object to read from
+ @param p_buf place to read data into.
+ @param i_lsn sector to read
+ @param b_form2 true for reading mode 1 form 2 sectors or false for
+ mode 1 form 1 sectors.
+ */
+ driver_return_code_t cdio_read_mode1_sector (const CdIo_t *p_cdio,
+ void *p_buf, lsn_t i_lsn,
+ bool b_form2);
+ /*!
+ Reads mode 1 sectors
+
+ @param p_cdio object to read from
+ @param p_buf place to read data into
+ @param i_lsn sector to read
+ @param b_form2 true for reading mode 1 form 2 sectors or false for
+ mode 1 form 1 sectors.
+ @param i_blocks number of sectors to read
+ */
+ driver_return_code_t cdio_read_mode1_sectors (const CdIo_t *p_cdio,
+ void *p_buf, lsn_t i_lsn,
+ bool b_form2,
+ uint32_t i_blocks);
+ /*!
+ Reads a mode 2 sector
+
+ @param p_cdio object to read from
+ @param p_buf place to read data into. The caller should make sure
+ this location can store at least
+ M2RAW_SECTOR_SIZE (for form 1) or CDIO_CD_FRAMESIZE (for
+ form 2) bytes.
+ @param i_lsn sector to read
+ @param b_form2 true for reading mode 2 form 2 sectors or false for
+ mode 2 form 1 sectors.
+
+ @return 0 if no error, nonzero otherwise.
+ */
+ driver_return_code_t cdio_read_mode2_sector (const CdIo_t *p_cdio,
+ void *p_buf, lsn_t i_lsn,
+ bool b_form2);
+
+ /** The special case of reading a single block is a common one so we
+ provide a routine for that as a convenience.
+ */
+ driver_return_code_t cdio_read_sector(const CdIo_t *p_cdio, void *p_buf,
+ lsn_t i_lsn,
+ cdio_read_mode_t read_mode);
+ /*!
+ Reads mode 2 sectors
+
+ @param p_cdio object to read from
+ @param p_buf place to read data into. The caller should make sure
+ this location can store at least
+ M2RAW_SECTOR_SIZE (for form 1) or CDIO_CD_FRAMESIZE (for
+ form 2) * i_blocks bytes.
+ @param i_lsn sector to read
+ @param b_form2 true for reading mode2 form 2 sectors or false for
+ mode 2 form 1 sectors.
+ @param i_blocks number of sectors to read
+
+ @return 0 if no error, nonzero otherwise.
+ */
+ driver_return_code_t cdio_read_mode2_sectors (const CdIo_t *p_cdio,
+ void *p_buf, lsn_t i_lsn,
+ bool b_form2,
+ uint32_t i_blocks);
+
+ /*!
+ Reads a number of sectors (AKA blocks).
+
+ @param p_cdio cdio object
+ @param p_buf place to read data into. The caller should make sure
+ this location is large enough. See below for size information.
+ @param read_mode the kind of "mode" to use in reading.
+ @param i_lsn sector to read
+ @param i_blocks number of sectors to read
+ @return DRIVER_OP_SUCCESS (0) if no error, other (negative) enumerations
+ are returned on error.
+
+ If read_mode is CDIO_MODE_AUDIO,
+ *p_buf should hold at least CDIO_FRAMESIZE_RAW * i_blocks bytes.
+
+ If read_mode is CDIO_MODE_DATA,
+ *p_buf should hold at least i_blocks times either ISO_BLOCKSIZE,
+ M1RAW_SECTOR_SIZE or M2F2_SECTOR_SIZE depending on the kind of
+ sector getting read. If you don't know whether you have a Mode 1/2,
+ Form 1/ Form 2/Formless sector best to reserve space for the maximum
+ which is M2RAW_SECTOR_SIZE.
+
+ If read_mode is CDIO_MODE_M2F1,
+ *p_buf should hold at least M2RAW_SECTOR_SIZE * i_blocks bytes.
+
+ If read_mode is CDIO_MODE_M2F2,
+ *p_buf should hold at least CDIO_CD_FRAMESIZE * i_blocks bytes.
+
+ */
+ driver_return_code_t cdio_read_sectors(const CdIo_t *p_cdio, void *p_buf,
+ lsn_t i_lsn,
+ cdio_read_mode_t read_mode,
+ uint32_t i_blocks);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __CDIO_TRACK_H__ */
diff --git a/lib-x86-32/include/cdio/rock.h b/lib-x86-32/include/cdio/rock.h
new file mode 100644
index 00000000..57003276
--- /dev/null
+++ b/lib-x86-32/include/cdio/rock.h
@@ -0,0 +1,396 @@
+/*
+ $Id: rock.h,v 1.15 2008/03/25 15:59:09 karl Exp $
+
+ Copyright (C) 2005, 2006 2008 Rocky Bernstein <rocky@panix.com>
+
+ See also rock.c by Eric Youngdale (1993) from GNU/Linux
+ This is Copyright 1993 Yggdrasil Computing, Incorporated
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*!
+ \file rock.h
+ \brief Things related to the Rock Ridge Interchange Protocol (RRIP)
+
+ Applications will probably not include this directly but via
+ the iso9660.h header.
+*/
+
+
+#ifndef __CDIO_ROCK_H__
+#define __CDIO_ROCK_H__
+
+#include <cdio/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* MSYS 1.0.10 with MinGW 3.4.2 (and perhaps others) don't have
+ S_ISSOCK() or S_ISLNK() macros, so we'll roll our own. */
+#if !defined(HAVE_S_ISSOCK) && !defined(S_ISSOCK)
+#define S_ISSOCK(st_mode) ((((st_mode)) & 0170000) == (0140000))
+#endif
+
+#if !defined(HAVE_S_ISLNK) && !defined(S_ISLNK)
+#define S_ISLNK(st_mode) ((((st_mode)) & 0170000) == (0010000))
+#endif
+
+/*! An enumeration for some of the ISO_ROCK_* \#defines below. This isn't
+ really an enumeration one would really use in a program it is to
+ be helpful in debuggers where wants just to refer to the ISO_ROCK_*
+ names and get something.
+*/
+extern enum iso_rock_enums {
+ ISO_ROCK_IRUSR = 000400, /**< read permission (owner) */
+ ISO_ROCK_IWUSR = 000200, /**< write permission (owner) */
+ ISO_ROCK_IXUSR = 000100, /**< execute permission (owner) */
+ ISO_ROCK_IRGRP = 000040, /**< read permission (group) */
+ ISO_ROCK_IWGRP = 000020, /**< write permission (group) */
+ ISO_ROCK_IXGRP = 000010, /**< execute permission (group) */
+ ISO_ROCK_IROTH = 000004, /**< read permission (other) */
+ ISO_ROCK_IWOTH = 000002, /**< write permission (other) */
+ ISO_ROCK_IXOTH = 000001, /**< execute permission (other) */
+
+ ISO_ROCK_ISUID = 004000, /**< set user ID on execution */
+ ISO_ROCK_ISGID = 002000, /**< set group ID on execution */
+ ISO_ROCK_ISVTX = 001000, /**< save swapped text even after use */
+
+ ISO_ROCK_ISSOCK = 0140000, /**< socket */
+ ISO_ROCK_ISLNK = 0120000, /**< symbolic link */
+ ISO_ROCK_ISREG = 0100000, /**< regular */
+ ISO_ROCK_ISBLK = 060000, /**< block special */
+ ISO_ROCK_ISCHR = 020000, /**< character special */
+ ISO_ROCK_ISDIR = 040000, /**< directory */
+ ISO_ROCK_ISFIFO = 010000 /**< pipe or FIFO */
+} iso_rock_enums;
+
+#define ISO_ROCK_IRUSR 000400 /** read permission (owner) */
+#define ISO_ROCK_IWUSR 000200 /** write permission (owner) */
+#define ISO_ROCK_IXUSR 000100 /** execute permission (owner) */
+#define ISO_ROCK_IRGRP 000040 /** read permission (group) */
+#define ISO_ROCK_IWGRP 000020 /** write permission (group) */
+#define ISO_ROCK_IXGRP 000010 /** execute permission (group) */
+#define ISO_ROCK_IROTH 000004 /** read permission (other) */
+#define ISO_ROCK_IWOTH 000002 /** write permission (other) */
+#define ISO_ROCK_IXOTH 000001 /** execute permission (other) */
+
+#define ISO_ROCK_ISUID 004000 /** set user ID on execution */
+#define ISO_ROCK_ISGID 002000 /** set group ID on execution */
+#define ISO_ROCK_ISVTX 001000 /** save swapped text even after use */
+
+#define ISO_ROCK_ISSOCK 0140000 /** socket */
+#define ISO_ROCK_ISLNK 0120000 /** symbolic link */
+#define ISO_ROCK_ISREG 0100000 /** regular */
+#define ISO_ROCK_ISBLK 060000 /** block special */
+#define ISO_ROCK_ISCHR 020000 /** character special */
+#define ISO_ROCK_ISDIR 040000 /** directory */
+#define ISO_ROCK_ISFIFO 010000 /** pipe or FIFO */
+
+/** Enforced file locking (shared w/set group ID) */
+#define ISO_ROCK_ENFMT ISO_ROCK_ISGID
+
+PRAGMA_BEGIN_PACKED
+
+/*! The next two structs are used by the system-use-sharing protocol
+ (SUSP), in which the Rock Ridge extensions are embedded. It is
+ quite possible that other extensions are present on the disk, and
+ this is fine as long as they all use SUSP. */
+
+/*! system-use-sharing protocol */
+typedef struct iso_su_sp_s{
+ unsigned char magic[2];
+ uint8_t skip;
+} GNUC_PACKED iso_su_sp_t;
+
+/*! system-use extension record */
+typedef struct iso_su_er_s {
+ iso711_t len_id; /**< Identifier length. Value 10?. */
+ unsigned char len_des;
+ unsigned char len_src;
+ iso711_t ext_ver; /**< Extension version. Value 1? */
+ char data[EMPTY_ARRAY_SIZE];
+} GNUC_PACKED iso_su_er_t;
+
+typedef struct iso_su_ce_s {
+ char extent[8];
+ char offset[8];
+ char size[8];
+} iso_su_ce_t;
+
+/*! POSIX file attributes, PX. See Rock Ridge Section 4.1.2 */
+typedef struct iso_rock_px_s {
+ iso733_t st_mode; /*! file mode permissions; same as st_mode
+ of POSIX:5.6.1 */
+ iso733_t st_nlinks; /*! number of links to file; same as st_nlinks
+ of POSIX:5.6.1 */
+ iso733_t st_uid; /*! user id owner of file; same as st_uid
+ of POSIX:5.6.1 */
+ iso733_t st_gid; /*! group id of file; same as st_gid of
+ of POSIX:5.6.1 */
+} GNUC_PACKED iso_rock_px_t ;
+
+/*! POSIX device number, PN. A PN is mandatory if the file type
+ recorded in the "PX" File Mode field for a Directory Record
+ indicates a character or block device (ISO_ROCK_ISCHR |
+ ISO_ROCK_ISBLK). This entry is ignored for other (non-Direcotry)
+ file types. No more than one "PN" is recorded in the System Use Area
+ of a Directory Record.
+
+ See Rock Ridge Section 4.1.2 */
+typedef struct iso_rock_pn_s {
+ iso733_t dev_high; /**< high-order 32 bits of the 64 bit device number.
+ 7.2.3 encoded */
+ iso733_t dev_low; /**< low-order 32 bits of the 64 bit device number.
+ 7.2.3 encoded */
+} GNUC_PACKED iso_rock_pn_t ;
+
+/*! These are the bits and their meanings for flags in the SL structure. */
+typedef enum {
+ ISO_ROCK_SL_CONTINUE = 1,
+ ISO_ROCK_SL_CURRENT = 2,
+ ISO_ROCK_SL_PARENT = 4,
+ ISO_ROCK_SL_ROOT = 8
+} iso_rock_sl_flag_t;
+
+#define ISO_ROCK_SL_CONTINUE 1
+#define ISO_ROCK_SL_CURRENT 2
+#define ISO_ROCK_SL_PARENT 4
+#define ISO_ROCK_SL_ROOT 8
+
+typedef struct iso_rock_sl_part_s {
+ uint8_t flags;
+ uint8_t len;
+ char text[EMPTY_ARRAY_SIZE];
+} GNUC_PACKED iso_rock_sl_part_t ;
+
+/*! Symbolic link. See Rock Ridge Section 4.1.3 */
+typedef struct iso_rock_sl_s {
+ unsigned char flags;
+ iso_rock_sl_part_t link;
+} GNUC_PACKED iso_rock_sl_t ;
+
+/*! Alternate name. See Rock Ridge Section 4.1.4 */
+
+/*! These are the bits and their meanings for flags in the NM structure. */
+typedef enum {
+ ISO_ROCK_NM_CONTINUE = 1,
+ ISO_ROCK_NM_CURRENT = 2,
+ ISO_ROCK_NM_PARENT = 4,
+} iso_rock_nm_flag_t;
+
+#define ISO_ROCK_NM_CONTINUE 1
+#define ISO_ROCK_NM_CURRENT 2
+#define ISO_ROCK_NM_PARENT 4
+
+
+typedef struct iso_rock_nm_s {
+ unsigned char flags;
+ char name[EMPTY_ARRAY_SIZE];
+} GNUC_PACKED iso_rock_nm_t ;
+
+/*! Child link. See Section 4.1.5.1 */
+typedef struct iso_rock_cl_s {
+ char location[1];
+} GNUC_PACKED iso_rock_cl_t ;
+
+/*! Parent link. See Section 4.1.5.2 */
+typedef struct iso_rock_pl_s {
+ char location[1];
+} GNUC_PACKED iso_rock_pl_t ;
+
+/*! These are the bits and their meanings for flags in the TF structure. */
+typedef enum {
+ ISO_ROCK_TF_CREATE = 1,
+ ISO_ROCK_TF_MODIFY = 2,
+ ISO_ROCK_TF_ACCESS = 4,
+ ISO_ROCK_TF_ATTRIBUTES = 8,
+ ISO_ROCK_TF_BACKUP = 16,
+ ISO_ROCK_TF_EXPIRATION = 32,
+ ISO_ROCK_TF_EFFECTIVE = 64,
+ ISO_ROCK_TF_LONG_FORM = 128
+} iso_rock_tf_flag_t;
+
+/* These are the bits and their meanings for flags in the TF structure. */
+#define ISO_ROCK_TF_CREATE 1
+#define ISO_ROCK_TF_MODIFY 2
+#define ISO_ROCK_TF_ACCESS 4
+#define ISO_ROCK_TF_ATTRIBUTES 8
+#define ISO_ROCK_TF_BACKUP 16
+#define ISO_ROCK_TF_EXPIRATION 32
+#define ISO_ROCK_TF_EFFECTIVE 64
+#define ISO_ROCK_TF_LONG_FORM 128
+
+/*! Time stamp(s) for a file. See Rock Ridge Section 4.1.6 */
+typedef struct iso_rock_tf_s {
+ uint8_t flags; /**< See ISO_ROCK_TF_* bits above. */
+ uint8_t time_bytes[EMPTY_ARRAY_SIZE]; /**< A homogenious array of
+ iso9660_ltime_t or
+ iso9660_dtime_t entries
+ depending on flags &
+ ISO_ROCK_TF_LONG_FORM. Lacking
+ a better method, we store
+ this as an array of bytes
+ and a cast to the
+ appropriate type will have
+ to be made before
+ extraction. */
+} GNUC_PACKED iso_rock_tf_t ;
+
+/*! File data in sparse format. See Rock Ridge Section 4.1.7 */
+typedef struct iso_rock_sf_s {
+ iso733_t virtual_size_high; /**< high-order 32 bits of virtual size */
+ iso733_t virtual_size_low; /**< low-order 32 bits of virtual size */
+ uint8_t table_depth;
+} GNUC_PACKED iso_rock_sf_t ;
+
+typedef struct iso_extension_record_s {
+ char signature[2]; /**< signature word; either 'SP', 'CE', 'ER', 'RR',
+ 'PX', 'PN', 'SL', 'NM', 'CL', 'PL', 'TF', or
+ 'ZF' */
+ iso711_t len; /**< length of system-user area - 44 for PX
+ 20 for PN, 5+strlen(text) for SL, 21 for
+ SF, etc. */
+ iso711_t version; /**< version number - value 1 */
+ union {
+ iso_su_sp_t SP; /**< system-use-sharing protocol - not
+ strictly part of Rock Ridge */
+ iso_su_er_t ER; /**< system-use extension packet - not
+ strictly part of Rock Ridge */
+ iso_su_ce_t CE; /**< system-use - strictly part of Rock Ridge */
+ iso_rock_px_t PX; /**< Rock Ridge POSIX file attributes */
+ iso_rock_pn_t PN; /**< Rock Ridge POSIX device number */
+ iso_rock_sl_t SL; /**< Rock Ridge symbolic link */
+ iso_rock_nm_t NM; /**< Rock Ridge alternate name */
+ iso_rock_cl_t CL; /**< Rock Ridge child link */
+ iso_rock_pl_t PL; /**< Rock Ridge parent link */
+ iso_rock_tf_t TF; /**< Rock Ridge timestamp(s) for a file */
+ } u;
+} GNUC_PACKED iso_extension_record_t;
+
+typedef struct iso_rock_time_s {
+ bool b_used; /**< If true, field has been set and is valid.
+ Otherwise remaning fields are meaningless. */
+ bool b_longdate; /**< If true date format is a iso9660_ltime_t.
+ Otherwise date is iso9660_dtime_t */
+ union
+ {
+ iso9660_ltime_t ltime;
+ iso9660_dtime_t dtime;
+ } t;
+} GNUC_PACKED iso_rock_time_t;
+
+typedef struct iso_rock_statbuf_s {
+ bool_3way_t b3_rock; /**< has Rock Ridge extension.
+ If "yep", then the fields
+ are used.
+ */
+ posix_mode_t st_mode; /**< protection */
+ posix_nlink_t st_nlinks; /**< number of hard links */
+ posix_uid_t st_uid; /**< user ID of owner */
+ posix_gid_t st_gid; /**< group ID of owner */
+ uint8_t s_rock_offset;
+ int i_symlink; /**< size of psz_symlink */
+ int i_symlink_max; /**< max allocated to psz_symlink */
+ char *psz_symlink; /**< if symbolic link, name
+ of pointed to file. */
+ iso_rock_time_t create; /**< create time See ISO 9660:9.5.4. */
+ iso_rock_time_t modify; /**< time of last modification
+ ISO 9660:9.5.5. st_mtime field of
+ POSIX:5.6.1. */
+ iso_rock_time_t access; /**< time of last file access st_atime
+ field of POSIX:5.6.1. */
+ iso_rock_time_t attributes; /**< time of last attribute change.
+ st_ctime field of POSIX:5.6.1. */
+ iso_rock_time_t backup; /**< time of last backup. */
+ iso_rock_time_t expiration; /**< time of expiration; See ISO
+ 9660:9.5.6. */
+ iso_rock_time_t effective; /**< Effective time; See ISO 9660:9.5.7.
+ */
+ uint32_t i_rdev; /**< the upper 16-bits is major device
+ number, the lower 16-bits is the
+ minor device number */
+
+} iso_rock_statbuf_t;
+
+PRAGMA_END_PACKED
+
+/*! return length of name field; 0: not found, -1: to be ignored */
+int get_rock_ridge_filename(iso9660_dir_t * de, /*out*/ char * retname,
+ /*out*/ iso9660_stat_t *p_stat);
+
+ int parse_rock_ridge_stat(iso9660_dir_t *de, /*out*/ iso9660_stat_t *p_stat);
+
+ /*!
+ Returns POSIX mode bitstring for a given file.
+ */
+ mode_t
+ iso9660_get_posix_filemode_from_rock(const iso_rock_statbuf_t *rr);
+
+/*!
+ Returns a string which interpreting the POSIX mode st_mode.
+ For example:
+ \verbatim
+ drwxrws---
+ -rw---Sr--
+ lrwxrwxrwx
+ \endverbatim
+
+ A description of the characters in the string follows
+ The 1st character is either "d" if the entry is a directory, "l" is
+ a symbolic link or "-" if neither.
+
+ The 2nd to 4th characters refer to permissions for a user while the
+ the 5th to 7th characters refer to permissions for a group while, and
+ the 8th to 10h characters refer to permissions for everyone.
+
+ In each of these triplets the first character (2, 5, 8) is "r" if
+ the entry is allowed to be read.
+
+ The second character of a triplet (3, 6, 9) is "w" if the entry is
+ allowed to be written.
+
+ The third character of a triplet (4, 7, 10) is "x" if the entry is
+ executable but not user (for character 4) or group (for characters
+ 6) settable and "s" if the item has the corresponding user/group set.
+
+ For a directory having an executable property on ("x" or "s") means
+ the directory is allowed to be listed or "searched". If the execute
+ property is not allowed for a group or user but the corresponding
+ group/user is set "S" indicates this. If none of these properties
+ holds the "-" indicates this.
+*/
+const char *iso9660_get_rock_attr_str(posix_mode_t st_mode);
+
+/** These variables are not used, but are defined to facilatate debugging
+ by letting us use enumerations values (which also correspond to
+ \#define's inside a debugged program.
+ */
+extern iso_rock_nm_flag_t iso_rock_nm_flag;
+extern iso_rock_sl_flag_t iso_rock_sl_flag;
+extern iso_rock_tf_flag_t iso_rock_tf_flag;
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __ISO_ROCK_H__ */
+
+/*
+ * Local variables:
+ * c-file-style: "gnu"
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/lib-x86-32/include/cdio/sector.h b/lib-x86-32/include/cdio/sector.h
new file mode 100644
index 00000000..6e308338
--- /dev/null
+++ b/lib-x86-32/include/cdio/sector.h
@@ -0,0 +1,286 @@
+/*
+ $Id: sector.h,v 1.38 2008/03/25 15:59:09 karl Exp $
+
+ Copyright (C) 2003, 2004, 2005, 2006, 2008 Rocky Bernstein <rocky@gnu.org>
+ Copyright (C) 2000 Herbert Valerio Riedel <hvr@gnu.org>
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*!
+ \file sector.h
+ \brief Things related to CD-ROM layout: tracks, sector sizes, MSFs, LBAs.
+
+ A CD-ROM physical sector size is 2048, 2052, 2056, 2324, 2332, 2336,
+ 2340, or 2352 bytes long.
+
+ Sector types of the standard CD-ROM data formats:
+
+\verbatim
+ format sector type user data size (bytes)
+ -----------------------------------------------------------------------------
+ 1 (Red Book) CD-DA 2352 (CDIO_CD_FRAMESIZE_RAW)
+ 2 (Yellow Book) Mode1 Form1 2048 (CDIO_CD_FRAMESIZE)
+ 3 (Yellow Book) Mode1 Form2 2336 (M2RAW_SECTOR_SIZE)
+ 4 (Green Book) Mode2 Form1 2048 (CDIO_CD_FRAMESIZE)
+ 5 (Green Book) Mode2 Form2 2328 (2324+4 spare bytes)
+
+
+ The layout of the standard CD-ROM data formats:
+ -----------------------------------------------------------------------------
+ - audio (red): | audio_sample_bytes |
+ | 2352 |
+
+ - data (yellow, mode1): | sync - head - data - EDC - zero - ECC |
+ | 12 - 4 - 2048 - 4 - 8 - 276 |
+
+ - data (yellow, mode2): | sync - head - data |
+ | 12 - 4 - 2336 |
+
+ - XA data (green, mode2 form1): | sync - head - sub - data - EDC - ECC |
+ | 12 - 4 - 8 - 2048 - 4 - 276 |
+
+ - XA data (green, mode2 form2): | sync - head - sub - data - Spare |
+ | 12 - 4 - 8 - 2324 - 4 |
+\endverbatim
+
+
+*/
+
+#ifndef _CDIO_SECTOR_H_
+#define _CDIO_SECTOR_H_
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#include <cdio/types.h>
+
+ /*! Information that can be obtained through a Read Subchannel
+ command.
+ */
+#define CDIO_SUBCHANNEL_SUBQ_DATA 0
+#define CDIO_SUBCHANNEL_CURRENT_POSITION 1
+#define CDIO_SUBCHANNEL_MEDIA_CATALOG 2
+#define CDIO_SUBCHANNEL_TRACK_ISRC 3
+
+ /*! track flags
+ * Q Sub-channel Control Field (4.2.3.3)
+ */
+ typedef enum {
+ NONE = 0x00, /* no flags set */
+ PRE_EMPHASIS = 0x01, /* audio track recorded with pre-emphasis */
+ COPY_PERMITTED = 0x02, /* digital copy permitted */
+ DATA = 0x04, /* data track */
+ FOUR_CHANNEL_AUDIO = 0x08, /* 4 audio channels */
+ SCMS = 0x10 /* SCMS (5.29.2.7) */
+ } flag_t;
+
+#define CDIO_PREGAP_SECTORS 150
+#define CDIO_POSTGAP_SECTORS 150
+
+ /*! An enumeration for some of the CDIO_CD \#defines below. This isn't
+ really an enumeration one would really use in a program it is to
+ be helpful in debuggers where wants just to refer to the CDIO_CD_
+ names and get something.
+ */
+ extern enum cdio_cd_enums {
+ CDIO_CD_MINS = 74, /**< max. minutes per CD, not really
+ a limit */
+ CDIO_CD_SECS_PER_MIN = 60, /**< seconds per minute */
+ CDIO_CD_FRAMES_PER_SEC = 75, /**< frames per second */
+ CDIO_CD_SYNC_SIZE = 12, /**< 12 sync bytes per raw data
+ frame */
+ CDIO_CD_CHUNK_SIZE = 24, /**< lowest-level "data bytes
+ piece" */
+ CDIO_CD_NUM_OF_CHUNKS = 98, /**< chunks per frame */
+ CDIO_CD_FRAMESIZE_SUB = 96, /**< subchannel data "frame" size */
+ CDIO_CD_HEADER_SIZE = 4, /**< header (address) bytes per raw
+ frame */
+ CDIO_CD_SUBHEADER_SIZE = 8, /**< subheader bytes per raw XA data
+ frame */
+ CDIO_CD_ECC_SIZE = 276, /**< bytes ECC per most raw data
+ frame types */
+ CDIO_CD_FRAMESIZE = 2048, /**< bytes per frame, "cooked"
+ mode */
+ CDIO_CD_FRAMESIZE_RAW = 2352, /**< bytes per frame, "raw" mode */
+ CDIO_CD_FRAMESIZE_RAWER = 2646, /**< The maximum possible
+ returned */
+ CDIO_CD_FRAMESIZE_RAW1 = 2340,
+ CDIO_CD_FRAMESIZE_RAW0 = 2336,
+ CDIO_CD_MAX_SESSIONS = 99,
+ CDIO_CD_MIN_SESSION_NO = 1, /**<, Smallest CD session number */
+ CDIO_CD_MAX_LSN = 450150, /**< Largest LSN in a CD */
+ CDIO_CD_MIN_LSN = -450150, /**< Smallest LSN in a CD */
+ } cdio_cd_enums;
+
+ /*!
+ Some generally useful CD-ROM information -- mostly based on the above.
+ This is from linux.h - not to slight other OS's. This was the first
+ place I came across such useful stuff.
+ */
+#define CDIO_CD_MINS 74 /**< max. minutes per CD, not really
+ a limit */
+#define CDIO_CD_SECS_PER_MIN 60 /**< seconds per minute */
+#define CDIO_CD_FRAMES_PER_SEC 75 /**< frames per second */
+#define CDIO_CD_SYNC_SIZE 12 /**< 12 sync bytes per raw data frame */
+#define CDIO_CD_CHUNK_SIZE 24 /**< lowest-level "data bytes piece" */
+#define CDIO_CD_NUM_OF_CHUNKS 98 /**< chunks per frame */
+#define CDIO_CD_FRAMESIZE_SUB 96 /**< subchannel data "frame" size */
+#define CDIO_CD_HEADER_SIZE 4 /**< header (address) bytes per raw
+ data frame */
+#define CDIO_CD_SUBHEADER_SIZE 8 /**< subheader bytes per raw XA data
+ frame */
+#define CDIO_CD_EDC_SIZE 4 /**< bytes EDC per most raw data
+ frame types */
+#define CDIO_CD_M1F1_ZERO_SIZE 8 /**< bytes zero per yellow book mode
+ 1 frame */
+#define CDIO_CD_ECC_SIZE 276 /**< bytes ECC per most raw data frame
+ types */
+#define CDIO_CD_FRAMESIZE 2048 /**< bytes per frame, "cooked" mode */
+#define CDIO_CD_FRAMESIZE_RAW 2352 /**< bytes per frame, "raw" mode */
+#define CDIO_CD_FRAMESIZE_RAWER 2646 /**< The maximum possible returned
+ bytes */
+#define CDIO_CD_FRAMESIZE_RAW1 (CDIO_CD_CD_FRAMESIZE_RAW-CDIO_CD_SYNC_SIZE) /*2340*/
+#define CDIO_CD_FRAMESIZE_RAW0 (CDIO_CD_FRAMESIZE_RAW-CDIO_CD_SYNC_SIZE-CDIO_CD_HEADER_SIZE) /*2336*/
+
+ /*! "before data" part of raw XA (green, mode2) frame */
+#define CDIO_CD_XA_HEADER (CDIO_CD_HEADER_SIZE+CDIO_CD_SUBHEADER_SIZE)
+
+ /*! "after data" part of raw XA (green, mode2 form1) frame */
+#define CDIO_CD_XA_TAIL (CDIO_CD_EDC_SIZE+CDIO_CD_ECC_SIZE)
+
+ /*! "before data" sync bytes + header of XA (green, mode2) frame */
+#define CDIO_CD_XA_SYNC_HEADER (CDIO_CD_SYNC_SIZE+CDIO_CD_XA_HEADER)
+
+ /*! String of bytes used to identify the beginning of a Mode 1 or
+ Mode 2 sector. */
+ extern const uint8_t CDIO_SECTOR_SYNC_HEADER[CDIO_CD_SYNC_SIZE];
+ /**<
+ {0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0};
+ */
+
+ /*! An enumeration for some of the M2*_SECTOR_SIZE \#defines
+ below. This isn't really an enumeration one would really use in a
+ program it is to be helpful in debuggers where wants just to refer
+ to the M2*_SECTOR_SIZE names and get something.
+ */
+ extern enum m2_sector_enums {
+ M2F2_SECTOR_SIZE = 2324,
+ M2SUB_SECTOR_SIZE = 2332,
+ M2RAW_SECTOR_SIZE = 2336
+ } m2_sector_enums;
+
+#define M2F2_SECTOR_SIZE 2324
+#define M2SUB_SECTOR_SIZE 2332
+#define M2RAW_SECTOR_SIZE 2336
+
+ /*! Largest CD session number */
+#define CDIO_CD_MAX_SESSIONS 99
+ /*! Smallest CD session number */
+#define CDIO_CD_MIN_SESSION_NO 1
+
+ /*! Largest LSN in a CD */
+#define CDIO_CD_MAX_LSN 450150
+ /*! Smallest LSN in a CD */
+#define CDIO_CD_MIN_LSN -450150
+
+
+#define CDIO_CD_FRAMES_PER_MIN \
+ (CDIO_CD_FRAMES_PER_SEC*CDIO_CD_SECS_PER_MIN)
+
+#define CDIO_CD_74MIN_SECTORS (UINT32_C(74)*CDIO_CD_FRAMES_PER_MIN)
+#define CDIO_CD_80MIN_SECTORS (UINT32_C(80)*CDIO_CD_FRAMES_PER_MIN)
+#define CDIO_CD_90MIN_SECTORS (UINT32_C(90)*CDIO_CD_FRAMES_PER_MIN)
+
+#define CDIO_CD_MAX_SECTORS \
+ (UINT32_C(100)*CDIO_CD_FRAMES_PER_MIN-CDIO_PREGAP_SECTORS)
+
+#define msf_t_SIZEOF 3
+
+ /*!
+ Convert an LBA into a string representation of the MSF.
+ \warning cdio_lba_to_msf_str returns new allocated string */
+ char *cdio_lba_to_msf_str (lba_t i_lba);
+
+ /*!
+ Convert an MSF into a string representation of the MSF.
+ \warning cdio_msf_to_msf_str returns new allocated string */
+ char *cdio_msf_to_str (const msf_t *p_msf);
+
+ /*!
+ Convert an LBA into the corresponding LSN.
+ */
+ lba_t cdio_lba_to_lsn (lba_t i_lba);
+
+ /*!
+ Convert an LBA into the corresponding MSF.
+ */
+ void cdio_lba_to_msf(lba_t i_lba, msf_t *p_msf);
+
+ /*!
+ Convert an LSN into the corresponding LBA.
+ CDIO_INVALID_LBA is returned if there is an error.
+ */
+ lba_t cdio_lsn_to_lba (lsn_t i_lsn);
+
+ /*!
+ Convert an LSN into the corresponding MSF.
+ */
+ void cdio_lsn_to_msf (lsn_t i_lsn, msf_t *p_msf);
+
+ /*!
+ Convert a MSF into the corresponding LBA.
+ CDIO_INVALID_LBA is returned if there is an error.
+ */
+ lba_t cdio_msf_to_lba (const msf_t *p_msf);
+
+ /*!
+ Convert a MSF into the corresponding LSN.
+ CDIO_INVALID_LSN is returned if there is an error.
+ */
+ lsn_t cdio_msf_to_lsn (const msf_t *p_msf);
+
+ /*!
+ Convert a MSF - broken out as 3 integer components into the
+ corresponding LBA.
+ CDIO_INVALID_LBA is returned if there is an error.
+ */
+ lba_t cdio_msf3_to_lba (unsigned int minutes, unsigned int seconds,
+ unsigned int frames);
+
+ /*!
+ Convert a string of the form MM:SS:FF into the corresponding LBA.
+ CDIO_INVALID_LBA is returned if there is an error.
+ */
+ lba_t cdio_mmssff_to_lba (const char *psz_mmssff);
+
+#ifdef __cplusplus
+ }
+#endif
+
+#ifndef DO_NOT_WANT_PARANOIA_COMPATIBILITY
+/** For compatibility with good ol' paranoia */
+#define CD_FRAMESIZE_RAW CDIO_CD_FRAMESIZE_RAW
+#endif /*DO_NOT_WANT_PARANOIA_COMPATIBILITY*/
+
+#endif /* _CDIO_SECTOR_H_ */
+
+
+/*
+ * Local variables:
+ * c-file-style: "gnu"
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/lib-x86-32/include/cdio/track.h b/lib-x86-32/include/cdio/track.h
new file mode 100644
index 00000000..9deb942b
--- /dev/null
+++ b/lib-x86-32/include/cdio/track.h
@@ -0,0 +1,269 @@
+/*
+ $Id: track.h,v 1.14 2008/03/25 15:59:09 karl Exp $
+
+ Copyright (C) 2005, 2006, 2008 Rocky Bernstein <rocky@gnu.org>
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/** \file track.h
+ * \brief The top-level header for track-related libcdio calls.
+ */
+#ifndef __CDIO_TRACK_H__
+#define __CDIO_TRACK_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+ /*! Printable tags for track_format_t enumeration. */
+ extern const char *track_format2str[6];
+
+ typedef enum {
+ TRACK_FORMAT_AUDIO, /**< Audio track, e.g. CD-DA */
+ TRACK_FORMAT_CDI, /**< CD-i. How this is different from DATA below? */
+ TRACK_FORMAT_XA, /**< Mode2 of some sort */
+ TRACK_FORMAT_DATA, /**< Mode1 of some sort */
+ TRACK_FORMAT_PSX, /**< Playstation CD. Like audio but only 2336 bytes
+ * of user data.
+ */
+ TRACK_FORMAT_ERROR /**< Dunno what is, or some other error. */
+ } track_format_t;
+
+ typedef enum {
+ CDIO_TRACK_FLAG_FALSE,
+ CDIO_TRACK_FLAG_TRUE,
+ CDIO_TRACK_FLAG_ERROR,
+ CDIO_TRACK_FLAG_UNKNOWN
+ } track_flag_t;
+
+ /*! \brief Structure containing attributes associated with a track */
+ typedef struct {
+ track_flag_t preemphasis; /**< Linear preemphasis on an audio track */
+ track_flag_t copy_permit; /**< Whether copying is permitted */
+ int channels; /**< Number of audio channels, 2, 4. -2 if not
+ implemented or -1 for error.
+ */
+ } track_flags_t;
+
+ /*! The leadout track is always 0xAA, regardless of # of tracks on
+ disc, or what value may be used internally. For example although
+ OS X uses a different value for the lead-out track internally than
+ given below, programmers should use CDIO_CDROM_LEADOUT_TRACK and
+ not worry about this.
+ */
+
+ /*! An enumeration for some of the CDIO_CDROM_* \#defines below. This
+ isn't really an enumeration one would really use in a program; it
+ is to be helpful in debuggers where wants just to refer to the
+ CDIO_CDROM_* names and get something.
+ */
+ extern enum cdio_track_enums {
+ CDIO_CDROM_LBA = 0x01, /**< "logical block": first frame is #0 */
+ CDIO_CDROM_MSF = 0x02, /**< "minute-second-frame": binary, not
+ BCD here! */
+ CDIO_CDROM_DATA_TRACK = 0x04,
+ CDIO_CDROM_CDI_TRACK = 0x10,
+ CDIO_CDROM_XA_TRACK = 0x20,
+ CDIO_CD_MAX_TRACKS = 99, /**< Largest CD track number */
+ CDIO_CDROM_LEADOUT_TRACK = 0xAA, /**< Lead-out track number */
+ CDIO_INVALID_TRACK = 0xFF, /**< Constant for invalid track number */
+
+ } cdio_track_enums;
+
+#define CDIO_CD_MIN_TRACK_NO 1 /**< Smallest CD track number */
+
+ /*! track modes (Table 350)
+ reference: MMC-3 draft revsion - 10g
+ */
+ typedef enum {
+ AUDIO, /**< 2352 byte block length */
+ MODE1, /**< 2048 byte block length */
+ MODE1_RAW, /**< 2352 byte block length */
+ MODE2, /**< 2336 byte block length */
+ MODE2_FORM1, /**< 2048 byte block length */
+ MODE2_FORM2, /**< 2324 byte block length */
+ MODE2_FORM_MIX, /**< 2336 byte block length */
+ MODE2_RAW /**< 2352 byte block length */
+ } trackmode_t;
+
+ /*!
+ Get CD-Text information for a CdIo_t object.
+
+ @param p_cdio the CD object that may contain CD-Text information.
+ @param i_track track for which we are requesting CD-Text information.
+ @return the CD-Text object or NULL if obj is NULL
+ or CD-Text information does not exist.
+
+ If i_track is 0 or CDIO_CDROM_LEADOUT_TRACK the track returned
+ is the information assocated with the CD.
+ */
+ cdtext_t *cdio_get_cdtext (CdIo_t *p_cdio, track_t i_track);
+
+ /*!
+ Get the number of the first track.
+
+ @return the track number or CDIO_INVALID_TRACK
+ on error.
+ */
+ track_t cdio_get_first_track_num(const CdIo_t *p_cdio);
+
+ /*!
+ Return the last track number.
+ CDIO_INVALID_TRACK is returned on error.
+ */
+ track_t cdio_get_last_track_num (const CdIo_t *p_cdio);
+
+
+ /*! Find the track which contains lsn.
+ CDIO_INVALID_TRACK is returned if the lsn outside of the CD or
+ if there was some error.
+
+ If the lsn is before the pregap of the first track 0 is returned.
+ Otherwise we return the track that spans the lsn.
+ */
+ track_t cdio_get_track(const CdIo_t *p_cdio, lsn_t lsn);
+
+ /*! Return number of channels in track: 2 or 4; -2 if not
+ implemented or -1 for error.
+ Not meaningful if track is not an audio track.
+ */
+ int cdio_get_track_channels(const CdIo_t *p_cdio, track_t i_track);
+
+ /*! Return copy protection status on a track. Is this meaningful
+ if not an audio track?
+ */
+ track_flag_t cdio_get_track_copy_permit(const CdIo_t *p_cdio,
+ track_t i_track);
+
+ /*!
+ Get the format (audio, mode2, mode1) of track.
+ */
+ track_format_t cdio_get_track_format(const CdIo_t *p_cdio, track_t i_track);
+
+ /*!
+ Return true if we have XA data (green, mode2 form1) or
+ XA data (green, mode2 form2). That is track begins:
+ sync - header - subheader
+ 12 4 - 8
+
+ FIXME: there's gotta be a better design for this and get_track_format?
+ */
+ bool cdio_get_track_green(const CdIo_t *p_cdio, track_t i_track);
+
+ /*!
+ Return the ending LSN for track number
+ i_track in cdio. CDIO_INVALID_LSN is returned on error.
+ */
+ lsn_t cdio_get_track_last_lsn(const CdIo_t *p_cdio, track_t i_track);
+
+ /*!
+ Get the starting LBA for track number
+ i_track in p_cdio. Track numbers usually start at something
+ greater than 0, usually 1.
+
+ The "leadout" track is specified either by
+ using i_track CDIO_CDROM_LEADOUT_TRACK or the total tracks+1.
+
+ @param p_cdio object to get information from
+ @param i_track the track number we want the LSN for
+ @return the starting LBA or CDIO_INVALID_LBA on error.
+ */
+ lba_t cdio_get_track_lba(const CdIo_t *p_cdio, track_t i_track);
+
+ /*!
+ Return the starting LSN for track number
+ i_track in p_cdio. Track numbers usually start at something
+ greater than 0, usually 1.
+
+ The "leadout" track is specified either by
+ using i_track CDIO_CDROM_LEADOUT_TRACK or the total tracks+1.
+
+ @param p_cdio object to get information from
+ @param i_track the track number we want the LSN for
+ @return the starting LSN or CDIO_INVALID_LSN on error.
+ */
+ lsn_t cdio_get_track_lsn(const CdIo_t *p_cdio, track_t i_track);
+
+ /*!
+ Return the starting LBA for the pregap for track number
+ i_track in p_cdio. Track numbers usually start at something
+ greater than 0, usually 1.
+
+ @param p_cdio object to get information from
+ @param i_track the track number we want the LBA for
+ @return the starting LBA or CDIO_INVALID_LBA on error.
+ */
+ lba_t cdio_get_track_pregap_lba(const CdIo_t *p_cdio, track_t i_track);
+
+ /*!
+ Return the starting LSN for the pregap for track number
+ i_track in p_cdio. Track numbers usually start at something
+ greater than 0, usually 1.
+
+ @param p_cdio object to get information from
+ @param i_track the track number we want the LSN for
+ @return the starting LSN or CDIO_INVALID_LSN on error.
+ */
+ lsn_t cdio_get_track_pregap_lsn(const CdIo_t *p_cdio, track_t i_track);
+
+ /*!
+ Get the International Standard Recording Code (ISRC) for track number
+ i_track in p_cdio. Track numbers usually start at something
+ greater than 0, usually 1.
+
+ @return the International Standard Recording Code (ISRC) or NULL
+ if there is none or we don't have the ability to get it.
+
+ Note: string is malloc'd so caller has to free() the returned
+ string when done with it.
+
+ */
+ char * cdio_get_track_isrc (const CdIo_t *p_cdio, track_t i_track);
+
+ /*!
+ Return the starting MSF (minutes/secs/frames) for track number
+ i_track in p_cdio. Track numbers usually start at something
+ greater than 0, usually 1.
+
+ The "leadout" track is specified either by
+ using i_track CDIO_CDROM_LEADOUT_TRACK or the total tracks+1.
+
+ @return true if things worked or false if there is no track entry.
+ */
+ bool cdio_get_track_msf(const CdIo_t *p_cdio, track_t i_track,
+ /*out*/ msf_t *msf);
+
+ /*! Get linear preemphasis status on an audio track
+ This is not meaningful if not an audio track?
+ */
+ track_flag_t cdio_get_track_preemphasis(const CdIo_t *p_cdio,
+ track_t i_track);
+
+ /*!
+ Get the number of sectors between this track an the next. This
+ includes any pregap sectors before the start of the next track.
+ Track numbers usually start at something
+ greater than 0, usually 1.
+
+ @return the number of sectors or 0 if there is an error.
+ */
+ unsigned int cdio_get_track_sec_count(const CdIo_t *p_cdio, track_t i_track);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __CDIO_TRACK_H__ */
+
diff --git a/lib-x86-32/include/cdio/types.h b/lib-x86-32/include/cdio/types.h
new file mode 100644
index 00000000..347bf5a7
--- /dev/null
+++ b/lib-x86-32/include/cdio/types.h
@@ -0,0 +1,327 @@
+/*
+ $Id: types.h,v 1.37 2008/03/25 15:59:09 karl Exp $
+
+ Copyright (C) 2002, 2003, 2004, 2005, 2006, 2008
+ Rocky Bernstein <rocky@gnu.org>
+ Copyright (C) 2000 Herbert Valerio Riedel <hvr@gnu.org>
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/** \file types.h
+ * \brief Common type definitions used pervasively in libcdio.
+ */
+
+
+#ifndef __CDIO_TYPES_H__
+#define __CDIO_TYPES_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#ifndef EXTERNAL_LIBCDIO_CONFIG_H
+#define EXTERNAL_LIBCDIO_CONFIG_H
+#include <cdio/cdio_config.h>
+#endif
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+ /* provide some C99 definitions */
+
+#if defined(HAVE_SYS_TYPES_H)
+#include <sys/types.h>
+#endif
+
+#if defined(HAVE_STDINT_H)
+# include <stdint.h>
+#elif defined(HAVE_INTTYPES_H)
+# include <inttypes.h>
+#elif defined(AMIGA) || defined(__linux__)
+ typedef u_int8_t uint8_t;
+ typedef u_int16_t uint16_t;
+ typedef u_int32_t uint32_t;
+ typedef u_int64_t uint64_t;
+#else
+ /* warning ISO/IEC 9899:1999 <stdint.h> was missing and even <inttypes.h> */
+ /* fixme */
+#endif /* HAVE_STDINT_H */
+
+typedef uint8_t ubyte;
+
+ /* default HP/UX macros are broken */
+#if defined(__hpux__)
+# undef UINT16_C
+# undef UINT32_C
+# undef UINT64_C
+# undef INT64_C
+#endif
+
+ /* if it's still not defined, take a good guess... should work for
+ most 32bit and 64bit archs */
+
+#ifndef UINT16_C
+# define UINT16_C(c) c ## U
+#endif
+
+#ifndef UINT32_C
+# if defined (SIZEOF_INT) && SIZEOF_INT == 4
+# define UINT32_C(c) c ## U
+# elif defined (SIZEOF_LONG) && SIZEOF_LONG == 4
+# define UINT32_C(c) c ## UL
+# else
+# define UINT32_C(c) c ## U
+# endif
+#endif
+
+#ifndef UINT64_C
+# if defined (SIZEOF_LONG) && SIZEOF_LONG == 8
+# define UINT64_C(c) c ## UL
+# elif defined (SIZEOF_INT) && SIZEOF_INT == 8
+# define UINT64_C(c) c ## U
+# else
+# define UINT64_C(c) c ## ULL
+# endif
+#endif
+
+#ifndef INT64_C
+# if defined (SIZEOF_LONG) && SIZEOF_LONG == 8
+# define INT64_C(c) c ## L
+# elif defined (SIZEOF_INT) && SIZEOF_INT == 8
+# define INT64_C(c) c
+# else
+# define INT64_C(c) c ## LL
+# endif
+#endif
+
+#ifndef __cplusplus
+# if defined(HAVE_STDBOOL_H)
+# include <stdbool.h>
+# else
+ /* ISO/IEC 9899:1999 <stdbool.h> missing -- enabling workaround */
+
+# define false 0
+# define true 1
+# define bool uint8_t
+# endif /*HAVE_STDBOOL_H*/
+#endif /*C++*/
+
+ /* some GCC optimizations -- gcc 2.5+ */
+
+#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4)
+#define GNUC_PRINTF( format_idx, arg_idx ) \
+ __attribute__((format (printf, format_idx, arg_idx)))
+#define GNUC_SCANF( format_idx, arg_idx ) \
+ __attribute__((format (scanf, format_idx, arg_idx)))
+#define GNUC_FORMAT( arg_idx ) \
+ __attribute__((format_arg (arg_idx)))
+#define GNUC_NORETURN \
+ __attribute__((noreturn))
+#define GNUC_CONST \
+ __attribute__((const))
+#define GNUC_UNUSED \
+ __attribute__((unused))
+#define GNUC_PACKED \
+ __attribute__((packed))
+#else /* !__GNUC__ */
+#define GNUC_PRINTF( format_idx, arg_idx )
+#define GNUC_SCANF( format_idx, arg_idx )
+#define GNUC_FORMAT( arg_idx )
+#define GNUC_NORETURN
+#define GNUC_CONST
+#define GNUC_UNUSED
+#define GNUC_PACKED
+#endif /* !__GNUC__ */
+
+#if defined(__GNUC__)
+ /* for GCC we try to use GNUC_PACKED */
+# define PRAGMA_BEGIN_PACKED
+# define PRAGMA_END_PACKED
+#elif defined(HAVE_ISOC99_PRAGMA)
+ /* should work with most EDG-frontend based compilers */
+# define PRAGMA_BEGIN_PACKED _Pragma("pack(1)")
+# define PRAGMA_END_PACKED _Pragma("pack()")
+#else /* neither gcc nor _Pragma() available... */
+ /* ...so let's be naive and hope the regression testsuite is run... */
+# define PRAGMA_BEGIN_PACKED
+# define PRAGMA_END_PACKED
+#endif
+
+ /*
+ * user directed static branch prediction gcc 2.96+
+ */
+#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 95)
+# define GNUC_LIKELY(x) __builtin_expect((x),true)
+# define GNUC_UNLIKELY(x) __builtin_expect((x),false)
+#else
+# define GNUC_LIKELY(x) (x)
+# define GNUC_UNLIKELY(x) (x)
+#endif
+
+#ifndef NULL
+# define NULL ((void*) 0)
+#endif
+
+ /* our own offsetof()-like macro */
+#define __cd_offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
+
+ /*!
+ \brief MSF (minute/second/frame) structure
+
+ One CD-ROMs addressing scheme especially used in audio formats
+ (Red Book) is an address by minute, sector and frame which
+ BCD-encoded in three bytes. An alternative format is an lba_t.
+
+ Note: the fields in this structure are BCD encoded. Use
+ cdio_to_bcd8() or cdio_from_bcd8() to convert an integer into or
+ out of this format. The format specifier %x (not %d) can be used
+ if you need to format or print values in this structure.
+
+ @see lba_t
+ */
+ PRAGMA_BEGIN_PACKED
+ struct msf_s {
+ uint8_t m, s, f; /* BCD encoded! */
+ } GNUC_PACKED;
+ PRAGMA_END_PACKED
+
+ typedef struct msf_s msf_t;
+
+#define msf_t_SIZEOF 3
+
+ /*!
+ \brief UTF-8 char definition
+
+ Type to denote UTF-8 strings.
+ */
+
+ typedef char cdio_utf8_t;
+
+ typedef enum {
+ nope = 0,
+ yep = 1,
+ dunno = 2
+ } bool_3way_t;
+
+ /* type used for bit-fields in structs (1 <= bits <= 8) */
+#if defined(__GNUC__)
+ /* this is strict ISO C99 which allows only 'unsigned int', 'signed
+ int' and '_Bool' explicitly as bit-field type */
+ typedef unsigned int bitfield_t;
+#else
+ /* other compilers might increase alignment requirements to match the
+ 'unsigned int' type -- fixme: find out how unalignment accesses can
+ be pragma'ed on non-gcc compilers */
+ typedef uint8_t bitfield_t;
+#endif
+
+ /*! The type of a Logical Block Address. We allow for an lba to be
+ negative to be consistent with an lba, although I'm not sure this
+ this is possible.
+
+ */
+ typedef int32_t lba_t;
+
+ /*! The type of a Logical Sector Number. Note that an lba can be negative
+ and the MMC3 specs allow for a conversion of a negative lba.
+
+ @see msf_t
+ */
+ typedef int32_t lsn_t;
+
+ /* Address in either MSF or logical format */
+ union cdio_cdrom_addr
+ {
+ msf_t msf;
+ lba_t lba;
+ };
+
+ /*! The type of a track number 0..99. */
+ typedef uint8_t track_t;
+
+ /*! The type of a session number 0..99. */
+ typedef uint8_t session_t;
+
+ /*!
+ Constant for invalid session number
+ */
+#define CDIO_INVALID_SESSION 0xFF
+
+ /*!
+ Constant for invalid LBA. It is 151 less than the most negative
+ LBA -45150. This provide slack for the 150-frame offset in
+ LBA to LSN 150 conversions
+ */
+#define CDIO_INVALID_LBA -45301
+
+ /*!
+ Constant for invalid LSN
+ */
+#define CDIO_INVALID_LSN CDIO_INVALID_LBA
+
+ /*!
+ Number of ASCII bytes in a media catalog number (MCN).
+ */
+#define CDIO_MCN_SIZE 13
+
+ /*!
+ Type to hold ASCII bytes in a media catalog number (MCN).
+ We include an extra 0 byte so these can be used as C strings.
+ */
+ typedef char cdio_mcn_t[CDIO_MCN_SIZE+1];
+
+
+ /*!
+ Number of ASCII bytes in International Standard Recording Codes (ISRC)
+ */
+#define CDIO_ISRC_SIZE 12
+
+ /*!
+ Type to hold ASCII bytes in a media catalog number (MCN).
+ We include an extra 0 byte so these can be used as C strings.
+ */
+ typedef char cdio_isrc_t[CDIO_ISRC_SIZE+1];
+
+ typedef int cdio_fs_anal_t;
+
+ /*!
+ track flags
+ Q Sub-channel Control Field (4.2.3.3)
+ */
+ typedef enum {
+ CDIO_TRACK_FLAG_NONE = 0x00, /**< no flags set */
+ CDIO_TRACK_FLAG_PRE_EMPHASIS = 0x01, /**< audio track recorded with
+ pre-emphasis */
+ CDIO_TRACK_FLAG_COPY_PERMITTED = 0x02, /**< digital copy permitted */
+ CDIO_TRACK_FLAG_DATA = 0x04, /**< data track */
+ CDIO_TRACK_FLAG_FOUR_CHANNEL_AUDIO = 0x08, /**< 4 audio channels */
+ CDIO_TRACK_FLAG_SCMS = 0x10 /**< SCMS (5.29.2.7) */
+} cdio_track_flag;
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __CDIO_TYPES_H__ */
+
+
+/*
+ * Local variables:
+ * c-file-style: "gnu"
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/lib-x86-32/include/cdio/udf.h b/lib-x86-32/include/cdio/udf.h
new file mode 100644
index 00000000..e35d74d1
--- /dev/null
+++ b/lib-x86-32/include/cdio/udf.h
@@ -0,0 +1,171 @@
+/*
+ $Id: udf.h,v 1.22 2008/03/25 15:59:09 karl Exp $
+
+ Copyright (C) 2005, 2006, 2008 Rocky Bernstein <rocky@gnu.org>
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*!
+ * \file udf.h
+ *
+ * \brief The top-level interface header for libudf: UDF filesystem
+ * library; applications include this.
+ *
+*/
+
+#ifndef UDF_H
+#define UDF_H
+
+#include <cdio/cdio.h>
+#include <cdio/ecma_167.h>
+#include <cdio/posix.h>
+
+typedef uint16_t partition_num_t;
+
+/** Opaque structures. */
+typedef struct udf_s udf_t;
+typedef struct udf_file_s udf_file_t;
+typedef struct udf_dirent_s udf_dirent_t;
+
+/**
+ Imagine the below a \#define'd value rather than distinct values of
+ an enum.
+*/
+typedef enum {
+ UDF_BLOCKSIZE = 2048
+} udf_enum1_t;
+
+/** This variable is trickery to force the above enum symbol value to
+ be recorded in debug symbol tables. It is used to allow one refer
+ to above enumeration values in a debugger and debugger
+ expressions */
+extern udf_enum1_t debug_udf_enum1;
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+ /*!
+ Close UDF and free resources associated with p_udf.
+ */
+ bool udf_close (udf_t *p_udf);
+
+ /*!
+ Seek to a position i_start and then read i_blocks. Number of
+ blocks read is returned. One normally expects the return to be
+ equal to i_blocks.
+ */
+
+ driver_return_code_t udf_read_sectors (const udf_t *p_udf, void *ptr,
+ lsn_t i_start, long int i_blocks);
+
+ /*!
+ Open an UDF for reading. Maybe in the future we will have
+ a mode. NULL is returned on error.
+
+ Caller must free result - use udf_close for that.
+ */
+ udf_t *udf_open (const char *psz_path);
+
+ /*!
+ Return the partition number of the the opened udf handle. -1
+ Is returned if we have an error.
+ */
+ int16_t udf_get_part_number(const udf_t *p_udf);
+
+ /*!
+ Get the root in p_udf. If b_any_partition is false then
+ the root must be in the given partition.
+ NULL is returned if the partition is not found or a root is not found or
+ there is on error.
+
+ Caller must free result - use udf_file_free for that.
+ */
+ udf_dirent_t *udf_get_root (udf_t *p_udf, bool b_any_partition,
+ partition_num_t i_partition);
+
+ /**
+ * Gets the Volume Identifier string, in 8bit unicode (latin-1)
+ * psz_volid, place to put the string
+ * i_volid_size, size of the buffer volid points to
+ * returns the size of buffer needed for all data
+ */
+ int udf_get_volume_id(udf_t *p_udf, /*out*/ char *psz_volid,
+ unsigned int i_volid);
+
+ /**
+ * Gets the Volume Set Identifier, as a 128-byte dstring (not decoded)
+ * WARNING This is not a null terminated string
+ * volsetid, place to put the data
+ * volsetid_size, size of the buffer volsetid points to
+ * the buffer should be >=128 bytes to store the whole volumesetidentifier
+ * returns the size of the available volsetid information (128)
+ * or 0 on error
+ */
+ int udf_get_volumeset_id(udf_t *p_udf, /*out*/ uint8_t *volsetid,
+ unsigned int i_volsetid);
+
+ /*!
+ Return a file pointer matching pzz_name.
+ */
+ udf_dirent_t *udf_fopen(udf_dirent_t *p_udf_root, const char *psz_name);
+
+ /*! udf_mode_string - fill in string PSZ_STR with an ls-style ASCII
+ representation of the i_mode. PSZ_STR is returned.
+
+ 10 characters are stored in PSZ_STR; a terminating null byte is added.
+ The characters stored in PSZ_STR are:
+
+ 0 File type. 'd' for directory, 'c' for character
+ special, 'b' for block special, 'm' for multiplex,
+ 'l' for symbolic link, 's' for socket, 'p' for fifo,
+ '-' for regular, '?' for any other file type
+
+ 1 'r' if the owner may read, '-' otherwise.
+
+ 2 'w' if the owner may write, '-' otherwise.
+
+ 3 'x' if the owner may execute, 's' if the file is
+ set-user-id, '-' otherwise.
+ 'S' if the file is set-user-id, but the execute
+ bit isn't set.
+
+ 4 'r' if group members may read, '-' otherwise.
+
+ 5 'w' if group members may write, '-' otherwise.
+
+ 6 'x' if group members may execute, 's' if the file is
+ set-group-id, '-' otherwise.
+ 'S' if it is set-group-id but not executable.
+
+ 7 'r' if any user may read, '-' otherwise.
+
+ 8 'w' if any user may write, '-' otherwise.
+
+ 9 'x' if any user may execute, 't' if the file is "sticky"
+ (will be retained in swap space after execution), '-'
+ otherwise.
+ 'T' if the file is sticky but not executable. */
+
+ char *udf_mode_string (mode_t i_mode, char *psz_str);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#include <cdio/udf_time.h>
+#include <cdio/udf_file.h>
+
+#endif /*UDF_H*/
diff --git a/lib-x86-32/include/cdio/udf_file.h b/lib-x86-32/include/cdio/udf_file.h
new file mode 100644
index 00000000..0b8fe99e
--- /dev/null
+++ b/lib-x86-32/include/cdio/udf_file.h
@@ -0,0 +1,117 @@
+/*
+ $Id: udf_file.h,v 1.12 2008/03/25 15:59:09 karl Exp $
+
+ Copyright (C) 2005, 2006, 2008 Rocky Bernstein <rocky@gnu.org>
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * \file udf_file.h
+ *
+ * \brief Routines involving UDF file operations
+ *
+*/
+
+#ifndef UDF_FILE_H
+#define UDF_FILE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+ /**
+ Return the file id descriptor of the given file.
+ */
+ bool udf_get_fileid_descriptor(const udf_dirent_t *p_udf_dirent,
+ /*out*/ udf_fileid_desc_t *p_udf_fid);
+
+ /**
+ Return the name of the file
+ */
+ const char *udf_get_filename(const udf_dirent_t *p_udf_dirent);
+
+ /**
+ Return the name of the file
+ */
+ bool udf_get_file_entry(const udf_dirent_t *p_udf_dirent,
+ /*out*/ udf_file_entry_t *p_udf_fe);
+
+ /**
+ Return the number of hard links of the file. Return 0 if error.
+ */
+ uint16_t udf_get_link_count(const udf_dirent_t *p_udf_dirent);
+
+ /**
+ Return the file length the file. Return 2147483647L if error.
+ */
+ uint64_t udf_get_file_length(const udf_dirent_t *p_udf_dirent);
+
+ /**
+ Returns a POSIX mode for a given p_udf_dirent.
+ */
+ mode_t udf_get_posix_filemode(const udf_dirent_t *p_udf_dirent);
+
+ /**
+ Return the next subdirectory.
+ */
+ udf_dirent_t *udf_opendir(const udf_dirent_t *p_udf_dirent);
+
+ /**
+ Attempts to read up to count bytes from UDF directory entry
+ p_udf_dirent into the buffer starting at buf. buf should be a
+ multiple of UDF_BLOCKSIZE bytes. Reading continues after the
+ point at which we last read or from the beginning the first time.
+
+ If count is zero, read() returns zero and has no other results. If
+ count is greater than SSIZE_MAX, the result is unspecified.
+
+ If there is an error, cast the result to driver_return_code_t for
+ the specific error code.
+ */
+ /**
+ Attempts to read up to count bytes from file descriptor fd into
+ the buffer starting at buf.
+
+ If count is zero, read() returns zero and has no other results. If
+ count is greater than SSIZE_MAX, the result is unspecified.
+ */
+ ssize_t udf_read_block(const udf_dirent_t *p_udf_dirent,
+ void * buf, size_t count);
+
+ /**
+ Advances p_udf_direct to the the next directory entry in the
+ pointed to by p_udf_dir. It also returns this as the value. NULL
+ is returned on reaching the end-of-file or if an error. Also
+ p_udf_dirent is free'd. If the end of is not reached the caller
+ must call udf_dirent_free() with p_udf_dirent when done with it to
+ release resources.
+ */
+ udf_dirent_t *udf_readdir(udf_dirent_t *p_udf_dirent);
+
+ /**
+ free free resources associated with p_udf_dirent.
+ */
+ bool udf_dirent_free(udf_dirent_t *p_udf_dirent);
+
+ /**
+ Return true if the file is a directory.
+ */
+ bool udf_is_dir(const udf_dirent_t *p_udf_dirent);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /*UDF_FILE_H*/
diff --git a/lib-x86-32/include/cdio/udf_time.h b/lib-x86-32/include/cdio/udf_time.h
new file mode 100644
index 00000000..791fcdd9
--- /dev/null
+++ b/lib-x86-32/include/cdio/udf_time.h
@@ -0,0 +1,80 @@
+/*
+ $Id: udf_time.h,v 1.5 2008/03/25 15:59:09 karl Exp $
+
+ Copyright (C) 2005, 2008 Rocky Bernstein <rocky@gnu.org>
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*!
+ * \file udf_time.h
+ *
+ * \brief UDF time conversion and access files.
+ *
+*/
+
+#ifndef UDF_TIME_H
+#define UDF_TIME_H
+
+#include <time.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+ /*!
+ Return the access time of the file.
+ */
+ time_t udf_get_access_time(const udf_dirent_t *p_udf_dirent);
+
+ /*!
+ Return the attribute (most recent create or access) time of the file
+ */
+ time_t udf_get_attribute_time(const udf_dirent_t *p_udf_dirent);
+
+ /*!
+ Return the modification time of the file.
+ */
+ time_t udf_get_modification_time(const udf_dirent_t *p_udf_dirent);
+
+ /*!
+ Return the access timestamp of the file
+ */
+ udf_timestamp_t *udf_get_access_timestamp(const udf_dirent_t *p_udf_dirent);
+
+ /*!
+ Return the modification timestamp of the file
+ */
+ udf_timestamp_t *udf_get_modification_timestamp(const udf_dirent_t
+ *p_udf_dirent);
+
+ /*!
+ Return the attr timestamp of the file
+ */
+ udf_timestamp_t *udf_get_attr_timestamp(const udf_dirent_t *p_udf_dirent);
+
+ /*!
+ Convert a UDF timestamp to a time_t. If microseconds are desired,
+ use dest_usec. The return value is the same as dest. */
+ time_t *udf_stamp_to_time(time_t *dest, long int *dest_usec,
+ const udf_timestamp_t src);
+
+ udf_timestamp_t *udf_timespec_to_stamp(const struct timespec ts,
+ udf_timestamp_t *dest);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /*UDF_TIME_H*/
diff --git a/lib-x86-32/include/cdio/utf8.h b/lib-x86-32/include/cdio/utf8.h
new file mode 100644
index 00000000..236105e9
--- /dev/null
+++ b/lib-x86-32/include/cdio/utf8.h
@@ -0,0 +1,92 @@
+/*
+ $Id: utf8.h,v 1.2 2008/03/25 15:59:09 karl Exp $
+
+ Copyright (C) 2008 Rocky Bernstein <rocky@gnu.org>
+ Copyright (C) 2006 Burkhard Plaum <plaum@ipf.uni-stuttgart.de>
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/* UTF-8 support */
+
+
+#include <cdio/types.h>
+
+/** \brief Opaque characterset converter
+ */
+
+typedef struct cdio_charset_coverter_s cdio_charset_coverter_t;
+
+/** \brief Create a charset converter
+ * \param src_charset Source charset
+ * \param dst_charset Destination charset
+ * \returns A newly allocated charset converter
+ */
+
+cdio_charset_coverter_t *
+cdio_charset_converter_create(const char * src_charset,
+ const char * dst_charset);
+
+/** \brief Destroy a characterset converter
+ * \param cnv A characterset converter
+ */
+
+void cdio_charset_converter_destroy(cdio_charset_coverter_t*cnv);
+
+/** \brief Convert a string from one character set to another
+ * \param cnv A charset converter
+ * \param src Source string
+ * \param src_len Length of source string
+ * \param dst Returns destination string
+ * \param dst_len If non NULL, returns the length of the destination string
+ * \returns true if conversion was sucessful, false else.
+ *
+ * The destination string must be freed by the caller with free().
+ * If you pass -1 for src_len, strlen() will be used.
+ */
+
+bool cdio_charset_convert(cdio_charset_coverter_t*cnv,
+ char * src, int src_len,
+ char ** dst, int * dst_len);
+
+/** \brief Convert a string from UTF-8 to another charset
+ * \param src Source string (0 terminated)
+ * \param dst Returns destination string
+ * \param dst_len If non NULL, returns the length of the destination string
+ * \param dst_charset The characterset to convert to
+ * \returns true if conversion was sucessful, false else.
+ *
+ * This is a convenience function, which creates a charset converter,
+ * converts one string and destroys the charset converter.
+ */
+
+
+bool cdio_charset_from_utf8(cdio_utf8_t * src, char ** dst,
+ int * dst_len, const char * dst_charset);
+
+/** \brief Convert a string from another charset to UTF-8
+ * \param src Source string
+ * \param src_len Length of the source string
+ * \param dst Returns destination string (0 terminated)
+ * \param src_charset The characterset to convert from
+ * \returns true if conversion was sucessful, false else.
+ *
+ * This is a convenience function, which creates a charset converter,
+ * converts one string and destroys the charset converter. If you pass -1
+ * for src_len, strlen() will be used.
+ */
+
+
+bool cdio_charset_to_utf8(char *src, size_t src_len, cdio_utf8_t **dst,
+ const char * src_charset);
+
diff --git a/lib-x86-32/include/cdio/util.h b/lib-x86-32/include/cdio/util.h
new file mode 100644
index 00000000..81557dc7
--- /dev/null
+++ b/lib-x86-32/include/cdio/util.h
@@ -0,0 +1,117 @@
+/*
+ $Id: util.h,v 1.12 2008/03/25 15:59:10 karl Exp $
+
+ Copyright (C) 2004, 2005, 2006, 2008 Rocky Bernstein <rocky@gnu.org>
+ Copyright (C) 2000 Herbert Valerio Riedel <hvr@gnu.org>
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __CDIO_UTIL_H__
+#define __CDIO_UTIL_H__
+
+/*!
+ \file util.h
+ \brief Miscellaneous utility functions.
+
+ Warning: this will probably get removed/replaced by using glib.h
+*/
+#include <stdlib.h>
+
+#undef MAX
+#define MAX(a, b) (((a) > (b)) ? (a) : (b))
+
+#undef MIN
+#define MIN(a, b) (((a) < (b)) ? (a) : (b))
+
+#undef IN
+#define IN(x, low, high) ((x) >= (low) && (x) <= (high))
+
+#undef CLAMP
+#define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x)))
+
+static inline uint32_t
+_cdio_len2blocks (uint32_t i_len, uint16_t i_blocksize)
+{
+ uint32_t i_blocks;
+
+ i_blocks = i_len / (uint32_t) i_blocksize;
+ if (i_len % i_blocksize)
+ i_blocks++;
+
+ return i_blocks;
+}
+
+/* round up to next block boundary */
+static inline unsigned
+_cdio_ceil2block (unsigned offset, uint16_t i_blocksize)
+{
+ return _cdio_len2blocks (offset, i_blocksize) * i_blocksize;
+}
+
+static inline unsigned int
+_cdio_ofs_add (unsigned offset, unsigned length, uint16_t i_blocksize)
+{
+ if (i_blocksize - (offset % i_blocksize) < length)
+ offset = _cdio_ceil2block (offset, i_blocksize);
+
+ offset += length;
+
+ return offset;
+}
+
+static inline const char *
+_cdio_bool_str (bool b)
+{
+ return b ? "yes" : "no";
+}
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void *
+_cdio_memdup (const void *mem, size_t count);
+
+char *
+_cdio_strdup_upper (const char str[]);
+
+void
+_cdio_strfreev(char **strv);
+
+size_t
+_cdio_strlenv(char **str_array);
+
+char **
+_cdio_strsplit(const char str[], char delim);
+
+uint8_t cdio_to_bcd8(uint8_t n);
+uint8_t cdio_from_bcd8(uint8_t p);
+
+void cdio_follow_symlink (const char * src, char * dst);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CDIO_UTIL_H__ */
+
+
+/*
+ * Local variables:
+ * c-file-style: "gnu"
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/lib-x86-32/include/cdio/version.h b/lib-x86-32/include/cdio/version.h
new file mode 100644
index 00000000..8eb564dc
--- /dev/null
+++ b/lib-x86-32/include/cdio/version.h
@@ -0,0 +1,12 @@
+/* $Id: version.h.in,v 1.6 2005/01/29 20:54:20 rocky Exp $ */
+/** \file version.h
+ *
+ * \brief A file containing the libcdio package version
+ * number (82) and OS build name.
+ */
+
+/*! CDIO_VERSION can as a string in programs to show what version is used. */
+#define CDIO_VERSION "0.82 i686-pc-linux-gnu"
+
+/*! LIBCDIO_VERSION_NUM can be used for testing in the C preprocessor */
+#define LIBCDIO_VERSION_NUM 82
diff --git a/lib-x86-32/include/cdio/version.h.in b/lib-x86-32/include/cdio/version.h.in
new file mode 100644
index 00000000..17d199e7
--- /dev/null
+++ b/lib-x86-32/include/cdio/version.h.in
@@ -0,0 +1,12 @@
+/* $Id: version.h.in,v 1.6 2005/01/29 20:54:20 rocky Exp $ */
+/** \file version.h
+ *
+ * \brief A file containing the libcdio package version
+ * number (@LIBCDIO_VERSION_NUM@) and OS build name.
+ */
+
+/*! CDIO_VERSION can as a string in programs to show what version is used. */
+#define CDIO_VERSION "@VERSION@ @build@"
+
+/*! LIBCDIO_VERSION_NUM can be used for testing in the C preprocessor */
+#define LIBCDIO_VERSION_NUM @LIBCDIO_VERSION_NUM@
diff --git a/lib-x86-32/include/cdio/xa.h b/lib-x86-32/include/cdio/xa.h
new file mode 100644
index 00000000..13b21c8f
--- /dev/null
+++ b/lib-x86-32/include/cdio/xa.h
@@ -0,0 +1,179 @@
+/*
+ $Id: xa.h,v 1.19 2008/03/25 15:59:10 karl Exp $
+
+ Copyright (C) 2003, 2004, 2005, 2006, 2008 Rocky Bernstein <rocky@gnu.org>
+ Copyright (C) 2000 Herbert Valerio Riedel <hvr@gnu.org>
+
+ See also iso9660.h by Eric Youngdale (1993) and in cdrtools. These are
+
+ Copyright 1993 Yggdrasil Computing, Incorporated
+ Copyright (c) 1999,2000 J. Schilling
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*!
+ \file xa.h
+ \brief Things related to the ISO-9660 XA (Extended Attributes) format
+
+ Applications will probably not include this directly but via
+ the iso9660.h header.
+*/
+
+
+#ifndef __CDIO_XA_H__
+#define __CDIO_XA_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+ /*! An enumeration for some of the XA_* \#defines below. This isn't
+ really an enumeration one would really use in a program it is to
+ be helpful in debuggers where wants just to refer to the XA_*
+ names and get something.
+ */
+ typedef enum {
+ ISO_XA_MARKER_OFFSET = 1024,
+ XA_PERM_RSYS = 0x0001, /**< System Group Read */
+ XA_PERM_XSYS = 0x0004, /**< System Group Execute */
+
+ XA_PERM_RUSR = 0x0010, /**< User (owner) Read */
+ XA_PERM_XUSR = 0x0040, /**< User (owner) Execute */
+
+ XA_PERM_RGRP = 0x0100, /**< Group Read */
+ XA_PERM_XGRP = 0x0400, /**< Group Execute */
+
+ XA_PERM_ROTH = 0x1000, /**< Other (world) Read */
+ XA_PERM_XOTH = 0x4000, /**< Other (world) Execute */
+
+ XA_ATTR_MODE2FORM1 = (1 << 11),
+ XA_ATTR_MODE2FORM2 = (1 << 12),
+ XA_ATTR_INTERLEAVED = (1 << 13),
+ XA_ATTR_CDDA = (1 << 14),
+ XA_ATTR_DIRECTORY = (1 << 15),
+
+ XA_PERM_ALL_READ = (XA_PERM_RUSR | XA_PERM_RSYS | XA_PERM_RGRP),
+ XA_PERM_ALL_EXEC = (XA_PERM_XUSR | XA_PERM_XSYS | XA_PERM_XGRP),
+ XA_PERM_ALL_ALL = (XA_PERM_ALL_READ | XA_PERM_ALL_EXEC),
+
+ XA_FORM1_DIR = (XA_ATTR_DIRECTORY | XA_ATTR_MODE2FORM1 | XA_PERM_ALL_ALL),
+ XA_FORM1_FILE = (XA_ATTR_MODE2FORM1 | XA_PERM_ALL_ALL),
+ XA_FORM2_FILE = (XA_ATTR_MODE2FORM2 | XA_PERM_ALL_ALL)
+ } xa_misc_enum_t;
+
+extern const char ISO_XA_MARKER_STRING[sizeof("CD-XA001")-1];
+
+#define ISO_XA_MARKER_STRING "CD-XA001"
+
+/*! \brief "Extended Architecture" according to the Philips Yellow Book.
+
+CD-ROM EXtended Architecture is a modification to the CD-ROM
+specification that defines two new types of sectors. CD-ROM XA was
+developed jointly by Sony, Philips, and Microsoft, and announced in
+August 1988. Its specifications were published in an extension to the
+Yellow Book. CD-i, Photo CD, Video CD and CD-EXTRA have all
+subsequently been based on CD-ROM XA.
+
+CD-XA defines another way of formatting sectors on a CD-ROM, including
+headers in the sectors that describe the type (audio, video, data) and
+some additional info (markers, resolution in case of a video or audio
+sector, file numbers, etc).
+
+The data written on a CD-XA is consistent with and can be in ISO-9660
+file system format and therefore be readable by ISO-9660 file system
+translators. But also a CD-I player can also read CD-XA discs even if
+its own `Green Book' file system only resembles ISO 9660 and isn't
+fully compatible.
+
+ Note structure is big-endian.
+*/
+typedef struct iso9660_xa_s
+{
+ uint16_t group_id; /**< 0 */
+ uint16_t user_id; /**< 0 */
+ uint16_t attributes; /**< XA_ATTR_ */
+ char signature[2]; /**< { 'X', 'A' } */
+ uint8_t filenum; /**< file number, see also XA subheader */
+ uint8_t reserved[5]; /**< zero */
+} GNUC_PACKED iso9660_xa_t;
+
+
+ /*!
+ Returns POSIX mode bitstring for a given file.
+ */
+ posix_mode_t iso9660_get_posix_filemode_from_xa(uint16_t i_perms);
+
+/*!
+ Returns a string interpreting the extended attribute xa_attr.
+ For example:
+ \verbatim
+ d---1xrxrxr
+ ---2--r-r-r
+ -a--1xrxrxr
+ \endverbatim
+
+ A description of the characters in the string follows.
+ The 1st character is either "d" if the entry is a directory, or "-" if not
+ The 2nd character is either "a" if the entry is CDDA (audio), or "-" if not
+ The 3rd character is either "i" if the entry is interleaved, or "-" if not
+ The 4th character is either "2" if the entry is mode2 form2 or "-" if not
+ The 5th character is either "1" if the entry is mode2 form1 or "-" if not
+ Note that an entry will either be in mode2 form1 or mode form2. That
+ is you will either see "2-" or "-1" in the 4th & 5th positions.
+
+ The 6th and 7th characters refer to permissions for a user while the
+ the 8th and 9th characters refer to permissions for a group while, and
+ the 10th and 11th characters refer to permissions for everyone.
+
+ In each of these pairs the first character (6, 8, 10) is "x" if the
+ entry is executable. For a directory this means the directory is
+ allowed to be listed or "searched".
+ The second character of a pair (7, 9, 11) is "r" if the entry is allowed
+ to be read.
+*/
+const char *
+iso9660_get_xa_attr_str (uint16_t xa_attr);
+
+/*!
+ Allocates and initalizes a new iso9600_xa_t variable and returns
+ it. The caller should free the returned result.
+
+ @see iso9660_xa
+*/
+iso9660_xa_t *
+iso9660_xa_init (iso9660_xa_t *_xa, uint16_t uid, uint16_t gid, uint16_t attr,
+ uint8_t filenum);
+
+#ifdef __cplusplus
+}
+
+/** The below variables are trickery to force the above enum symbol
+ values to be recorded in debug symbol tables. They are used to
+ allow one to refer to the enumeration value names in the typedefs
+ above in a debugger and debugger expressions.
+*/
+extern xa_misc_enum_t debugger_xa_misc_enum;
+
+
+#endif /* __cplusplus */
+
+#endif /* __CDIO_XA_H__ */
+
+/*
+ * Local variables:
+ * c-file-style: "gnu"
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/lib-x86-32/include/curl/Makefile.am b/lib-x86-32/include/curl/Makefile.am
new file mode 100644
index 00000000..a3b44438
--- /dev/null
+++ b/lib-x86-32/include/curl/Makefile.am
@@ -0,0 +1,25 @@
+pkginclude_HEADERS = \
+ curl.h curlver.h easy.h mprintf.h stdcheaders.h types.h multi.h \
+ typecheck-gcc.h curlbuild.h curlrules.h
+
+pkgincludedir= $(includedir)/curl
+
+# curlbuild.h does not exist in the git tree. When the original libcurl
+# source code distribution archive file is created, curlbuild.h.dist is
+# renamed to curlbuild.h and included in the tarball so that it can be
+# used directly on non-configure systems.
+#
+# The distributed curlbuild.h will be overwritten on configure systems
+# when the configure script runs, with one that is suitable and specific
+# to the library being configured and built.
+#
+# curlbuild.h.in is the distributed template file from which the configure
+# script creates curlbuild.h at library configuration time, overwiting the
+# one included in the distribution archive.
+#
+# curlbuild.h.dist is not included in the source code distribution archive.
+
+EXTRA_DIST = curlbuild.h.in
+
+DISTCLEANFILES = curlbuild.h
+
diff --git a/lib-x86-32/include/curl/curl.h b/lib-x86-32/include/curl/curl.h
new file mode 100644
index 00000000..cb9d0fbf
--- /dev/null
+++ b/lib-x86-32/include/curl/curl.h
@@ -0,0 +1,2119 @@
+#ifndef __CURL_CURL_H
+#define __CURL_CURL_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/*
+ * If you have libcurl problems, all docs and details are found here:
+ * http://curl.haxx.se/libcurl/
+ *
+ * curl-library mailing list subscription and unsubscription web interface:
+ * http://cool.haxx.se/mailman/listinfo/curl-library/
+ */
+
+#include "curlver.h" /* libcurl version defines */
+#include "curlbuild.h" /* libcurl build definitions */
+#include "curlrules.h" /* libcurl rules enforcement */
+
+/*
+ * Define WIN32 when build target is Win32 API
+ */
+
+#if (defined(_WIN32) || defined(__WIN32__)) && \
+ !defined(WIN32) && !defined(__SYMBIAN32__)
+#define WIN32
+#endif
+
+#include <stdio.h>
+#include <limits.h>
+
+#if defined(__FreeBSD__) && (__FreeBSD__ >= 2)
+/* Needed for __FreeBSD_version symbol definition */
+#include <osreldate.h>
+#endif
+
+/* The include stuff here below is mainly for time_t! */
+#include <sys/types.h>
+#include <time.h>
+
+#if defined(WIN32) && !defined(_WIN32_WCE) && !defined(__GNUC__) && \
+ !defined(__CYGWIN__) || defined(__MINGW32__)
+#if !(defined(_WINSOCKAPI_) || defined(_WINSOCK_H))
+/* The check above prevents the winsock2 inclusion if winsock.h already was
+ included, since they can't co-exist without problems */
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#endif
+#else
+
+/* HP-UX systems version 9, 10 and 11 lack sys/select.h and so does oldish
+ libc5-based Linux systems. Only include it on system that are known to
+ require it! */
+#if defined(_AIX) || defined(__NOVELL_LIBC__) || defined(__NetBSD__) || \
+ defined(__minix) || defined(__SYMBIAN32__) || defined(__INTEGRITY) || \
+ defined(ANDROID) || \
+ (defined(__FreeBSD_version) && (__FreeBSD_version < 800000))
+#include <sys/select.h>
+#endif
+
+#ifndef _WIN32_WCE
+#include <sys/socket.h>
+#endif
+#if !defined(WIN32) && !defined(__WATCOMC__) && !defined(__VXWORKS__)
+#include <sys/time.h>
+#endif
+#include <sys/types.h>
+#endif
+
+#ifdef __BEOS__
+#include <support/SupportDefs.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void CURL;
+
+/*
+ * Decorate exportable functions for Win32 and Symbian OS DLL linking.
+ * This avoids using a .def file for building libcurl.dll.
+ */
+#if (defined(WIN32) || defined(_WIN32) || defined(__SYMBIAN32__)) && \
+ !defined(CURL_STATICLIB)
+#if defined(BUILDING_LIBCURL)
+#define CURL_EXTERN __declspec(dllexport)
+#else
+#define CURL_EXTERN __declspec(dllimport)
+#endif
+#else
+
+#ifdef CURL_HIDDEN_SYMBOLS
+/*
+ * This definition is used to make external definitions visible in the
+ * shared library when symbols are hidden by default. It makes no
+ * difference when compiling applications whether this is set or not,
+ * only when compiling the library.
+ */
+#define CURL_EXTERN CURL_EXTERN_SYMBOL
+#else
+#define CURL_EXTERN
+#endif
+#endif
+
+#ifndef curl_socket_typedef
+/* socket typedef */
+#ifdef WIN32
+typedef SOCKET curl_socket_t;
+#define CURL_SOCKET_BAD INVALID_SOCKET
+#else
+typedef int curl_socket_t;
+#define CURL_SOCKET_BAD -1
+#endif
+#define curl_socket_typedef
+#endif /* curl_socket_typedef */
+
+struct curl_httppost {
+ struct curl_httppost *next; /* next entry in the list */
+ char *name; /* pointer to allocated name */
+ long namelength; /* length of name length */
+ char *contents; /* pointer to allocated data contents */
+ long contentslength; /* length of contents field */
+ char *buffer; /* pointer to allocated buffer contents */
+ long bufferlength; /* length of buffer field */
+ char *contenttype; /* Content-Type */
+ struct curl_slist* contentheader; /* list of extra headers for this form */
+ struct curl_httppost *more; /* if one field name has more than one
+ file, this link should link to following
+ files */
+ long flags; /* as defined below */
+#define HTTPPOST_FILENAME (1<<0) /* specified content is a file name */
+#define HTTPPOST_READFILE (1<<1) /* specified content is a file name */
+#define HTTPPOST_PTRNAME (1<<2) /* name is only stored pointer
+ do not free in formfree */
+#define HTTPPOST_PTRCONTENTS (1<<3) /* contents is only stored pointer
+ do not free in formfree */
+#define HTTPPOST_BUFFER (1<<4) /* upload file from buffer */
+#define HTTPPOST_PTRBUFFER (1<<5) /* upload file from pointer contents */
+#define HTTPPOST_CALLBACK (1<<6) /* upload file contents by using the
+ regular read callback to get the data
+ and pass the given pointer as custom
+ pointer */
+
+ char *showfilename; /* The file name to show. If not set, the
+ actual file name will be used (if this
+ is a file part) */
+ void *userp; /* custom pointer used for
+ HTTPPOST_CALLBACK posts */
+};
+
+typedef int (*curl_progress_callback)(void *clientp,
+ double dltotal,
+ double dlnow,
+ double ultotal,
+ double ulnow);
+
+#ifndef CURL_MAX_WRITE_SIZE
+ /* Tests have proven that 20K is a very bad buffer size for uploads on
+ Windows, while 16K for some odd reason performed a lot better.
+ We do the ifndef check to allow this value to easier be changed at build
+ time for those who feel adventurous. The practical minimum is about
+ 400 bytes since libcurl uses a buffer of this size as a scratch area
+ (unrelated to network send operations). */
+#define CURL_MAX_WRITE_SIZE 16384
+#endif
+
+#ifndef CURL_MAX_HTTP_HEADER
+/* The only reason to have a max limit for this is to avoid the risk of a bad
+ server feeding libcurl with a never-ending header that will cause reallocs
+ infinitely */
+#define CURL_MAX_HTTP_HEADER (100*1024)
+#endif
+
+
+/* This is a magic return code for the write callback that, when returned,
+ will signal libcurl to pause receiving on the current transfer. */
+#define CURL_WRITEFUNC_PAUSE 0x10000001
+typedef size_t (*curl_write_callback)(char *buffer,
+ size_t size,
+ size_t nitems,
+ void *outstream);
+
+
+
+/* enumeration of file types */
+typedef enum {
+ CURLFILETYPE_FILE = 0,
+ CURLFILETYPE_DIRECTORY,
+ CURLFILETYPE_SYMLINK,
+ CURLFILETYPE_DEVICE_BLOCK,
+ CURLFILETYPE_DEVICE_CHAR,
+ CURLFILETYPE_NAMEDPIPE,
+ CURLFILETYPE_SOCKET,
+ CURLFILETYPE_DOOR, /* is possible only on Sun Solaris now */
+
+ CURLFILETYPE_UNKNOWN /* should never occur */
+} curlfiletype;
+
+#define CURLFINFOFLAG_KNOWN_FILENAME (1<<0)
+#define CURLFINFOFLAG_KNOWN_FILETYPE (1<<1)
+#define CURLFINFOFLAG_KNOWN_TIME (1<<2)
+#define CURLFINFOFLAG_KNOWN_PERM (1<<3)
+#define CURLFINFOFLAG_KNOWN_UID (1<<4)
+#define CURLFINFOFLAG_KNOWN_GID (1<<5)
+#define CURLFINFOFLAG_KNOWN_SIZE (1<<6)
+#define CURLFINFOFLAG_KNOWN_HLINKCOUNT (1<<7)
+
+/* Content of this structure depends on information which is known and is
+ achievable (e.g. by FTP LIST parsing). Please see the url_easy_setopt(3) man
+ page for callbacks returning this structure -- some fields are mandatory,
+ some others are optional. The FLAG field has special meaning. */
+struct curl_fileinfo {
+ char *filename;
+ curlfiletype filetype;
+ time_t time;
+ unsigned int perm;
+ int uid;
+ int gid;
+ curl_off_t size;
+ long int hardlinks;
+
+ struct {
+ /* If some of these fields is not NULL, it is a pointer to b_data. */
+ char *time;
+ char *perm;
+ char *user;
+ char *group;
+ char *target; /* pointer to the target filename of a symlink */
+ } strings;
+
+ unsigned int flags;
+
+ /* used internally */
+ char * b_data;
+ size_t b_size;
+ size_t b_used;
+};
+
+/* return codes for CURLOPT_CHUNK_BGN_FUNCTION */
+#define CURL_CHUNK_BGN_FUNC_OK 0
+#define CURL_CHUNK_BGN_FUNC_FAIL 1 /* tell the lib to end the task */
+#define CURL_CHUNK_BGN_FUNC_SKIP 2 /* skip this chunk over */
+
+/* if splitting of data transfer is enabled, this callback is called before
+ download of an individual chunk started. Note that parameter "remains" works
+ only for FTP wildcard downloading (for now), otherwise is not used */
+typedef long (*curl_chunk_bgn_callback)(const void *transfer_info,
+ void *ptr,
+ int remains);
+
+/* return codes for CURLOPT_CHUNK_END_FUNCTION */
+#define CURL_CHUNK_END_FUNC_OK 0
+#define CURL_CHUNK_END_FUNC_FAIL 1 /* tell the lib to end the task */
+
+/* If splitting of data transfer is enabled this callback is called after
+ download of an individual chunk finished.
+ Note! After this callback was set then it have to be called FOR ALL chunks.
+ Even if downloading of this chunk was skipped in CHUNK_BGN_FUNC.
+ This is the reason why we don't need "transfer_info" parameter in this
+ callback and we are not interested in "remains" parameter too. */
+typedef long (*curl_chunk_end_callback)(void *ptr);
+
+/* return codes for FNMATCHFUNCTION */
+#define CURL_FNMATCHFUNC_MATCH 0 /* string corresponds to the pattern */
+#define CURL_FNMATCHFUNC_NOMATCH 1 /* pattern doesn't match the string */
+#define CURL_FNMATCHFUNC_FAIL 2 /* an error occurred */
+
+/* callback type for wildcard downloading pattern matching. If the
+ string matches the pattern, return CURL_FNMATCHFUNC_MATCH value, etc. */
+typedef int (*curl_fnmatch_callback)(void *ptr,
+ const char *pattern,
+ const char *string);
+
+/* These are the return codes for the seek callbacks */
+#define CURL_SEEKFUNC_OK 0
+#define CURL_SEEKFUNC_FAIL 1 /* fail the entire transfer */
+#define CURL_SEEKFUNC_CANTSEEK 2 /* tell libcurl seeking can't be done, so
+ libcurl might try other means instead */
+typedef int (*curl_seek_callback)(void *instream,
+ curl_off_t offset,
+ int origin); /* 'whence' */
+
+/* This is a return code for the read callback that, when returned, will
+ signal libcurl to immediately abort the current transfer. */
+#define CURL_READFUNC_ABORT 0x10000000
+/* This is a return code for the read callback that, when returned, will
+ signal libcurl to pause sending data on the current transfer. */
+#define CURL_READFUNC_PAUSE 0x10000001
+
+typedef size_t (*curl_read_callback)(char *buffer,
+ size_t size,
+ size_t nitems,
+ void *instream);
+
+typedef enum {
+ CURLSOCKTYPE_IPCXN, /* socket created for a specific IP connection */
+ CURLSOCKTYPE_LAST /* never use */
+} curlsocktype;
+
+typedef int (*curl_sockopt_callback)(void *clientp,
+ curl_socket_t curlfd,
+ curlsocktype purpose);
+
+struct curl_sockaddr {
+ int family;
+ int socktype;
+ int protocol;
+ unsigned int addrlen; /* addrlen was a socklen_t type before 7.18.0 but it
+ turned really ugly and painful on the systems that
+ lack this type */
+ struct sockaddr addr;
+};
+
+typedef curl_socket_t
+(*curl_opensocket_callback)(void *clientp,
+ curlsocktype purpose,
+ struct curl_sockaddr *address);
+
+typedef enum {
+ CURLIOE_OK, /* I/O operation successful */
+ CURLIOE_UNKNOWNCMD, /* command was unknown to callback */
+ CURLIOE_FAILRESTART, /* failed to restart the read */
+ CURLIOE_LAST /* never use */
+} curlioerr;
+
+typedef enum {
+ CURLIOCMD_NOP, /* no operation */
+ CURLIOCMD_RESTARTREAD, /* restart the read stream from start */
+ CURLIOCMD_LAST /* never use */
+} curliocmd;
+
+typedef curlioerr (*curl_ioctl_callback)(CURL *handle,
+ int cmd,
+ void *clientp);
+
+/*
+ * The following typedef's are signatures of malloc, free, realloc, strdup and
+ * calloc respectively. Function pointers of these types can be passed to the
+ * curl_global_init_mem() function to set user defined memory management
+ * callback routines.
+ */
+typedef void *(*curl_malloc_callback)(size_t size);
+typedef void (*curl_free_callback)(void *ptr);
+typedef void *(*curl_realloc_callback)(void *ptr, size_t size);
+typedef char *(*curl_strdup_callback)(const char *str);
+typedef void *(*curl_calloc_callback)(size_t nmemb, size_t size);
+
+/* the kind of data that is passed to information_callback*/
+typedef enum {
+ CURLINFO_TEXT = 0,
+ CURLINFO_HEADER_IN, /* 1 */
+ CURLINFO_HEADER_OUT, /* 2 */
+ CURLINFO_DATA_IN, /* 3 */
+ CURLINFO_DATA_OUT, /* 4 */
+ CURLINFO_SSL_DATA_IN, /* 5 */
+ CURLINFO_SSL_DATA_OUT, /* 6 */
+ CURLINFO_END
+} curl_infotype;
+
+typedef int (*curl_debug_callback)
+ (CURL *handle, /* the handle/transfer this concerns */
+ curl_infotype type, /* what kind of data */
+ char *data, /* points to the data */
+ size_t size, /* size of the data pointed to */
+ void *userptr); /* whatever the user please */
+
+/* All possible error codes from all sorts of curl functions. Future versions
+ may return other values, stay prepared.
+
+ Always add new return codes last. Never *EVER* remove any. The return
+ codes must remain the same!
+ */
+
+typedef enum {
+ CURLE_OK = 0,
+ CURLE_UNSUPPORTED_PROTOCOL, /* 1 */
+ CURLE_FAILED_INIT, /* 2 */
+ CURLE_URL_MALFORMAT, /* 3 */
+ CURLE_OBSOLETE4, /* 4 - NOT USED */
+ CURLE_COULDNT_RESOLVE_PROXY, /* 5 */
+ CURLE_COULDNT_RESOLVE_HOST, /* 6 */
+ CURLE_COULDNT_CONNECT, /* 7 */
+ CURLE_FTP_WEIRD_SERVER_REPLY, /* 8 */
+ CURLE_REMOTE_ACCESS_DENIED, /* 9 a service was denied by the server
+ due to lack of access - when login fails
+ this is not returned. */
+ CURLE_OBSOLETE10, /* 10 - NOT USED */
+ CURLE_FTP_WEIRD_PASS_REPLY, /* 11 */
+ CURLE_OBSOLETE12, /* 12 - NOT USED */
+ CURLE_FTP_WEIRD_PASV_REPLY, /* 13 */
+ CURLE_FTP_WEIRD_227_FORMAT, /* 14 */
+ CURLE_FTP_CANT_GET_HOST, /* 15 */
+ CURLE_OBSOLETE16, /* 16 - NOT USED */
+ CURLE_FTP_COULDNT_SET_TYPE, /* 17 */
+ CURLE_PARTIAL_FILE, /* 18 */
+ CURLE_FTP_COULDNT_RETR_FILE, /* 19 */
+ CURLE_OBSOLETE20, /* 20 - NOT USED */
+ CURLE_QUOTE_ERROR, /* 21 - quote command failure */
+ CURLE_HTTP_RETURNED_ERROR, /* 22 */
+ CURLE_WRITE_ERROR, /* 23 */
+ CURLE_OBSOLETE24, /* 24 - NOT USED */
+ CURLE_UPLOAD_FAILED, /* 25 - failed upload "command" */
+ CURLE_READ_ERROR, /* 26 - couldn't open/read from file */
+ CURLE_OUT_OF_MEMORY, /* 27 */
+ /* Note: CURLE_OUT_OF_MEMORY may sometimes indicate a conversion error
+ instead of a memory allocation error if CURL_DOES_CONVERSIONS
+ is defined
+ */
+ CURLE_OPERATION_TIMEDOUT, /* 28 - the timeout time was reached */
+ CURLE_OBSOLETE29, /* 29 - NOT USED */
+ CURLE_FTP_PORT_FAILED, /* 30 - FTP PORT operation failed */
+ CURLE_FTP_COULDNT_USE_REST, /* 31 - the REST command failed */
+ CURLE_OBSOLETE32, /* 32 - NOT USED */
+ CURLE_RANGE_ERROR, /* 33 - RANGE "command" didn't work */
+ CURLE_HTTP_POST_ERROR, /* 34 */
+ CURLE_SSL_CONNECT_ERROR, /* 35 - wrong when connecting with SSL */
+ CURLE_BAD_DOWNLOAD_RESUME, /* 36 - couldn't resume download */
+ CURLE_FILE_COULDNT_READ_FILE, /* 37 */
+ CURLE_LDAP_CANNOT_BIND, /* 38 */
+ CURLE_LDAP_SEARCH_FAILED, /* 39 */
+ CURLE_OBSOLETE40, /* 40 - NOT USED */
+ CURLE_FUNCTION_NOT_FOUND, /* 41 */
+ CURLE_ABORTED_BY_CALLBACK, /* 42 */
+ CURLE_BAD_FUNCTION_ARGUMENT, /* 43 */
+ CURLE_OBSOLETE44, /* 44 - NOT USED */
+ CURLE_INTERFACE_FAILED, /* 45 - CURLOPT_INTERFACE failed */
+ CURLE_OBSOLETE46, /* 46 - NOT USED */
+ CURLE_TOO_MANY_REDIRECTS , /* 47 - catch endless re-direct loops */
+ CURLE_UNKNOWN_TELNET_OPTION, /* 48 - User specified an unknown option */
+ CURLE_TELNET_OPTION_SYNTAX , /* 49 - Malformed telnet option */
+ CURLE_OBSOLETE50, /* 50 - NOT USED */
+ CURLE_PEER_FAILED_VERIFICATION, /* 51 - peer's certificate or fingerprint
+ wasn't verified fine */
+ CURLE_GOT_NOTHING, /* 52 - when this is a specific error */
+ CURLE_SSL_ENGINE_NOTFOUND, /* 53 - SSL crypto engine not found */
+ CURLE_SSL_ENGINE_SETFAILED, /* 54 - can not set SSL crypto engine as
+ default */
+ CURLE_SEND_ERROR, /* 55 - failed sending network data */
+ CURLE_RECV_ERROR, /* 56 - failure in receiving network data */
+ CURLE_OBSOLETE57, /* 57 - NOT IN USE */
+ CURLE_SSL_CERTPROBLEM, /* 58 - problem with the local certificate */
+ CURLE_SSL_CIPHER, /* 59 - couldn't use specified cipher */
+ CURLE_SSL_CACERT, /* 60 - problem with the CA cert (path?) */
+ CURLE_BAD_CONTENT_ENCODING, /* 61 - Unrecognized transfer encoding */
+ CURLE_LDAP_INVALID_URL, /* 62 - Invalid LDAP URL */
+ CURLE_FILESIZE_EXCEEDED, /* 63 - Maximum file size exceeded */
+ CURLE_USE_SSL_FAILED, /* 64 - Requested FTP SSL level failed */
+ CURLE_SEND_FAIL_REWIND, /* 65 - Sending the data requires a rewind
+ that failed */
+ CURLE_SSL_ENGINE_INITFAILED, /* 66 - failed to initialise ENGINE */
+ CURLE_LOGIN_DENIED, /* 67 - user, password or similar was not
+ accepted and we failed to login */
+ CURLE_TFTP_NOTFOUND, /* 68 - file not found on server */
+ CURLE_TFTP_PERM, /* 69 - permission problem on server */
+ CURLE_REMOTE_DISK_FULL, /* 70 - out of disk space on server */
+ CURLE_TFTP_ILLEGAL, /* 71 - Illegal TFTP operation */
+ CURLE_TFTP_UNKNOWNID, /* 72 - Unknown transfer ID */
+ CURLE_REMOTE_FILE_EXISTS, /* 73 - File already exists */
+ CURLE_TFTP_NOSUCHUSER, /* 74 - No such user */
+ CURLE_CONV_FAILED, /* 75 - conversion failed */
+ CURLE_CONV_REQD, /* 76 - caller must register conversion
+ callbacks using curl_easy_setopt options
+ CURLOPT_CONV_FROM_NETWORK_FUNCTION,
+ CURLOPT_CONV_TO_NETWORK_FUNCTION, and
+ CURLOPT_CONV_FROM_UTF8_FUNCTION */
+ CURLE_SSL_CACERT_BADFILE, /* 77 - could not load CACERT file, missing
+ or wrong format */
+ CURLE_REMOTE_FILE_NOT_FOUND, /* 78 - remote file not found */
+ CURLE_SSH, /* 79 - error from the SSH layer, somewhat
+ generic so the error message will be of
+ interest when this has happened */
+
+ CURLE_SSL_SHUTDOWN_FAILED, /* 80 - Failed to shut down the SSL
+ connection */
+ CURLE_AGAIN, /* 81 - socket is not ready for send/recv,
+ wait till it's ready and try again (Added
+ in 7.18.2) */
+ CURLE_SSL_CRL_BADFILE, /* 82 - could not load CRL file, missing or
+ wrong format (Added in 7.19.0) */
+ CURLE_SSL_ISSUER_ERROR, /* 83 - Issuer check failed. (Added in
+ 7.19.0) */
+ CURLE_FTP_PRET_FAILED, /* 84 - a PRET command failed */
+ CURLE_RTSP_CSEQ_ERROR, /* 85 - mismatch of RTSP CSeq numbers */
+ CURLE_RTSP_SESSION_ERROR, /* 86 - mismatch of RTSP Session Identifiers */
+ CURLE_FTP_BAD_FILE_LIST, /* 87 - unable to parse FTP file list */
+ CURLE_CHUNK_FAILED, /* 88 - chunk callback reported error */
+
+ CURL_LAST /* never use! */
+} CURLcode;
+
+#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all
+ the obsolete stuff removed! */
+
+/* Backwards compatibility with older names */
+
+/* The following were added in 7.17.1 */
+/* These are scheduled to disappear by 2009 */
+#define CURLE_SSL_PEER_CERTIFICATE CURLE_PEER_FAILED_VERIFICATION
+
+/* The following were added in 7.17.0 */
+/* These are scheduled to disappear by 2009 */
+#define CURLE_OBSOLETE CURLE_OBSOLETE50 /* noone should be using this! */
+#define CURLE_BAD_PASSWORD_ENTERED CURLE_OBSOLETE46
+#define CURLE_BAD_CALLING_ORDER CURLE_OBSOLETE44
+#define CURLE_FTP_USER_PASSWORD_INCORRECT CURLE_OBSOLETE10
+#define CURLE_FTP_CANT_RECONNECT CURLE_OBSOLETE16
+#define CURLE_FTP_COULDNT_GET_SIZE CURLE_OBSOLETE32
+#define CURLE_FTP_COULDNT_SET_ASCII CURLE_OBSOLETE29
+#define CURLE_FTP_WEIRD_USER_REPLY CURLE_OBSOLETE12
+#define CURLE_FTP_WRITE_ERROR CURLE_OBSOLETE20
+#define CURLE_LIBRARY_NOT_FOUND CURLE_OBSOLETE40
+#define CURLE_MALFORMAT_USER CURLE_OBSOLETE24
+#define CURLE_SHARE_IN_USE CURLE_OBSOLETE57
+#define CURLE_URL_MALFORMAT_USER CURLE_OBSOLETE4
+
+#define CURLE_FTP_ACCESS_DENIED CURLE_REMOTE_ACCESS_DENIED
+#define CURLE_FTP_COULDNT_SET_BINARY CURLE_FTP_COULDNT_SET_TYPE
+#define CURLE_FTP_QUOTE_ERROR CURLE_QUOTE_ERROR
+#define CURLE_TFTP_DISKFULL CURLE_REMOTE_DISK_FULL
+#define CURLE_TFTP_EXISTS CURLE_REMOTE_FILE_EXISTS
+#define CURLE_HTTP_RANGE_ERROR CURLE_RANGE_ERROR
+#define CURLE_FTP_SSL_FAILED CURLE_USE_SSL_FAILED
+
+/* The following were added earlier */
+
+#define CURLE_OPERATION_TIMEOUTED CURLE_OPERATION_TIMEDOUT
+
+#define CURLE_HTTP_NOT_FOUND CURLE_HTTP_RETURNED_ERROR
+#define CURLE_HTTP_PORT_FAILED CURLE_INTERFACE_FAILED
+#define CURLE_FTP_COULDNT_STOR_FILE CURLE_UPLOAD_FAILED
+
+#define CURLE_FTP_PARTIAL_FILE CURLE_PARTIAL_FILE
+#define CURLE_FTP_BAD_DOWNLOAD_RESUME CURLE_BAD_DOWNLOAD_RESUME
+
+/* This was the error code 50 in 7.7.3 and a few earlier versions, this
+ is no longer used by libcurl but is instead #defined here only to not
+ make programs break */
+#define CURLE_ALREADY_COMPLETE 99999
+
+#endif /*!CURL_NO_OLDIES*/
+
+/* This prototype applies to all conversion callbacks */
+typedef CURLcode (*curl_conv_callback)(char *buffer, size_t length);
+
+typedef CURLcode (*curl_ssl_ctx_callback)(CURL *curl, /* easy handle */
+ void *ssl_ctx, /* actually an
+ OpenSSL SSL_CTX */
+ void *userptr);
+
+typedef enum {
+ CURLPROXY_HTTP = 0, /* added in 7.10, new in 7.19.4 default is to use
+ CONNECT HTTP/1.1 */
+ CURLPROXY_HTTP_1_0 = 1, /* added in 7.19.4, force to use CONNECT
+ HTTP/1.0 */
+ CURLPROXY_SOCKS4 = 4, /* support added in 7.15.2, enum existed already
+ in 7.10 */
+ CURLPROXY_SOCKS5 = 5, /* added in 7.10 */
+ CURLPROXY_SOCKS4A = 6, /* added in 7.18.0 */
+ CURLPROXY_SOCKS5_HOSTNAME = 7 /* Use the SOCKS5 protocol but pass along the
+ host name rather than the IP address. added
+ in 7.18.0 */
+} curl_proxytype; /* this enum was added in 7.10 */
+
+#define CURLAUTH_NONE 0 /* nothing */
+#define CURLAUTH_BASIC (1<<0) /* Basic (default) */
+#define CURLAUTH_DIGEST (1<<1) /* Digest */
+#define CURLAUTH_GSSNEGOTIATE (1<<2) /* GSS-Negotiate */
+#define CURLAUTH_NTLM (1<<3) /* NTLM */
+#define CURLAUTH_DIGEST_IE (1<<4) /* Digest with IE flavour */
+#define CURLAUTH_ANY (~CURLAUTH_DIGEST_IE) /* all fine types set */
+#define CURLAUTH_ANYSAFE (~(CURLAUTH_BASIC|CURLAUTH_DIGEST_IE))
+
+#define CURLSSH_AUTH_ANY ~0 /* all types supported by the server */
+#define CURLSSH_AUTH_NONE 0 /* none allowed, silly but complete */
+#define CURLSSH_AUTH_PUBLICKEY (1<<0) /* public/private key files */
+#define CURLSSH_AUTH_PASSWORD (1<<1) /* password */
+#define CURLSSH_AUTH_HOST (1<<2) /* host key files */
+#define CURLSSH_AUTH_KEYBOARD (1<<3) /* keyboard interactive */
+#define CURLSSH_AUTH_DEFAULT CURLSSH_AUTH_ANY
+
+#define CURL_ERROR_SIZE 256
+
+struct curl_khkey {
+ const char *key; /* points to a zero-terminated string encoded with base64
+ if len is zero, otherwise to the "raw" data */
+ size_t len;
+ enum type {
+ CURLKHTYPE_UNKNOWN,
+ CURLKHTYPE_RSA1,
+ CURLKHTYPE_RSA,
+ CURLKHTYPE_DSS
+ } keytype;
+};
+
+/* this is the set of return values expected from the curl_sshkeycallback
+ callback */
+enum curl_khstat {
+ CURLKHSTAT_FINE_ADD_TO_FILE,
+ CURLKHSTAT_FINE,
+ CURLKHSTAT_REJECT, /* reject the connection, return an error */
+ CURLKHSTAT_DEFER, /* do not accept it, but we can't answer right now so
+ this causes a CURLE_DEFER error but otherwise the
+ connection will be left intact etc */
+ CURLKHSTAT_LAST /* not for use, only a marker for last-in-list */
+};
+
+/* this is the set of status codes pass in to the callback */
+enum curl_khmatch {
+ CURLKHMATCH_OK, /* match */
+ CURLKHMATCH_MISMATCH, /* host found, key mismatch! */
+ CURLKHMATCH_MISSING, /* no matching host/key found */
+ CURLKHMATCH_LAST /* not for use, only a marker for last-in-list */
+};
+
+typedef int
+ (*curl_sshkeycallback) (CURL *easy, /* easy handle */
+ const struct curl_khkey *knownkey, /* known */
+ const struct curl_khkey *foundkey, /* found */
+ enum curl_khmatch, /* libcurl's view on the keys */
+ void *clientp); /* custom pointer passed from app */
+
+/* parameter for the CURLOPT_USE_SSL option */
+typedef enum {
+ CURLUSESSL_NONE, /* do not attempt to use SSL */
+ CURLUSESSL_TRY, /* try using SSL, proceed anyway otherwise */
+ CURLUSESSL_CONTROL, /* SSL for the control connection or fail */
+ CURLUSESSL_ALL, /* SSL for all communication or fail */
+ CURLUSESSL_LAST /* not an option, never use */
+} curl_usessl;
+
+#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all
+ the obsolete stuff removed! */
+
+/* Backwards compatibility with older names */
+/* These are scheduled to disappear by 2009 */
+
+#define CURLFTPSSL_NONE CURLUSESSL_NONE
+#define CURLFTPSSL_TRY CURLUSESSL_TRY
+#define CURLFTPSSL_CONTROL CURLUSESSL_CONTROL
+#define CURLFTPSSL_ALL CURLUSESSL_ALL
+#define CURLFTPSSL_LAST CURLUSESSL_LAST
+#define curl_ftpssl curl_usessl
+#endif /*!CURL_NO_OLDIES*/
+
+/* parameter for the CURLOPT_FTP_SSL_CCC option */
+typedef enum {
+ CURLFTPSSL_CCC_NONE, /* do not send CCC */
+ CURLFTPSSL_CCC_PASSIVE, /* Let the server initiate the shutdown */
+ CURLFTPSSL_CCC_ACTIVE, /* Initiate the shutdown */
+ CURLFTPSSL_CCC_LAST /* not an option, never use */
+} curl_ftpccc;
+
+/* parameter for the CURLOPT_FTPSSLAUTH option */
+typedef enum {
+ CURLFTPAUTH_DEFAULT, /* let libcurl decide */
+ CURLFTPAUTH_SSL, /* use "AUTH SSL" */
+ CURLFTPAUTH_TLS, /* use "AUTH TLS" */
+ CURLFTPAUTH_LAST /* not an option, never use */
+} curl_ftpauth;
+
+/* parameter for the CURLOPT_FTP_CREATE_MISSING_DIRS option */
+typedef enum {
+ CURLFTP_CREATE_DIR_NONE, /* do NOT create missing dirs! */
+ CURLFTP_CREATE_DIR, /* (FTP/SFTP) if CWD fails, try MKD and then CWD
+ again if MKD succeeded, for SFTP this does
+ similar magic */
+ CURLFTP_CREATE_DIR_RETRY, /* (FTP only) if CWD fails, try MKD and then CWD
+ again even if MKD failed! */
+ CURLFTP_CREATE_DIR_LAST /* not an option, never use */
+} curl_ftpcreatedir;
+
+/* parameter for the CURLOPT_FTP_FILEMETHOD option */
+typedef enum {
+ CURLFTPMETHOD_DEFAULT, /* let libcurl pick */
+ CURLFTPMETHOD_MULTICWD, /* single CWD operation for each path part */
+ CURLFTPMETHOD_NOCWD, /* no CWD at all */
+ CURLFTPMETHOD_SINGLECWD, /* one CWD to full dir, then work on file */
+ CURLFTPMETHOD_LAST /* not an option, never use */
+} curl_ftpmethod;
+
+/* CURLPROTO_ defines are for the CURLOPT_*PROTOCOLS options */
+#define CURLPROTO_HTTP (1<<0)
+#define CURLPROTO_HTTPS (1<<1)
+#define CURLPROTO_FTP (1<<2)
+#define CURLPROTO_FTPS (1<<3)
+#define CURLPROTO_SCP (1<<4)
+#define CURLPROTO_SFTP (1<<5)
+#define CURLPROTO_TELNET (1<<6)
+#define CURLPROTO_LDAP (1<<7)
+#define CURLPROTO_LDAPS (1<<8)
+#define CURLPROTO_DICT (1<<9)
+#define CURLPROTO_FILE (1<<10)
+#define CURLPROTO_TFTP (1<<11)
+#define CURLPROTO_IMAP (1<<12)
+#define CURLPROTO_IMAPS (1<<13)
+#define CURLPROTO_POP3 (1<<14)
+#define CURLPROTO_POP3S (1<<15)
+#define CURLPROTO_SMTP (1<<16)
+#define CURLPROTO_SMTPS (1<<17)
+#define CURLPROTO_RTSP (1<<18)
+#define CURLPROTO_RTMP (1<<19)
+#define CURLPROTO_RTMPT (1<<20)
+#define CURLPROTO_RTMPE (1<<21)
+#define CURLPROTO_RTMPTE (1<<22)
+#define CURLPROTO_RTMPS (1<<23)
+#define CURLPROTO_RTMPTS (1<<24)
+#define CURLPROTO_GOPHER (1<<25)
+#define CURLPROTO_ALL (~0) /* enable everything */
+
+/* long may be 32 or 64 bits, but we should never depend on anything else
+ but 32 */
+#define CURLOPTTYPE_LONG 0
+#define CURLOPTTYPE_OBJECTPOINT 10000
+#define CURLOPTTYPE_FUNCTIONPOINT 20000
+#define CURLOPTTYPE_OFF_T 30000
+
+/* name is uppercase CURLOPT_<name>,
+ type is one of the defined CURLOPTTYPE_<type>
+ number is unique identifier */
+#ifdef CINIT
+#undef CINIT
+#endif
+
+#ifdef CURL_ISOCPP
+#define CINIT(name,type,number) CURLOPT_ ## name = CURLOPTTYPE_ ## type + number
+#else
+/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */
+#define LONG CURLOPTTYPE_LONG
+#define OBJECTPOINT CURLOPTTYPE_OBJECTPOINT
+#define FUNCTIONPOINT CURLOPTTYPE_FUNCTIONPOINT
+#define OFF_T CURLOPTTYPE_OFF_T
+#define CINIT(name,type,number) CURLOPT_/**/name = type + number
+#endif
+
+/*
+ * This macro-mania below setups the CURLOPT_[what] enum, to be used with
+ * curl_easy_setopt(). The first argument in the CINIT() macro is the [what]
+ * word.
+ */
+
+typedef enum {
+ /* This is the FILE * or void * the regular output should be written to. */
+ CINIT(FILE, OBJECTPOINT, 1),
+
+ /* The full URL to get/put */
+ CINIT(URL, OBJECTPOINT, 2),
+
+ /* Port number to connect to, if other than default. */
+ CINIT(PORT, LONG, 3),
+
+ /* Name of proxy to use. */
+ CINIT(PROXY, OBJECTPOINT, 4),
+
+ /* "name:password" to use when fetching. */
+ CINIT(USERPWD, OBJECTPOINT, 5),
+
+ /* "name:password" to use with proxy. */
+ CINIT(PROXYUSERPWD, OBJECTPOINT, 6),
+
+ /* Range to get, specified as an ASCII string. */
+ CINIT(RANGE, OBJECTPOINT, 7),
+
+ /* not used */
+
+ /* Specified file stream to upload from (use as input): */
+ CINIT(INFILE, OBJECTPOINT, 9),
+
+ /* Buffer to receive error messages in, must be at least CURL_ERROR_SIZE
+ * bytes big. If this is not used, error messages go to stderr instead: */
+ CINIT(ERRORBUFFER, OBJECTPOINT, 10),
+
+ /* Function that will be called to store the output (instead of fwrite). The
+ * parameters will use fwrite() syntax, make sure to follow them. */
+ CINIT(WRITEFUNCTION, FUNCTIONPOINT, 11),
+
+ /* Function that will be called to read the input (instead of fread). The
+ * parameters will use fread() syntax, make sure to follow them. */
+ CINIT(READFUNCTION, FUNCTIONPOINT, 12),
+
+ /* Time-out the read operation after this amount of seconds */
+ CINIT(TIMEOUT, LONG, 13),
+
+ /* If the CURLOPT_INFILE is used, this can be used to inform libcurl about
+ * how large the file being sent really is. That allows better error
+ * checking and better verifies that the upload was successful. -1 means
+ * unknown size.
+ *
+ * For large file support, there is also a _LARGE version of the key
+ * which takes an off_t type, allowing platforms with larger off_t
+ * sizes to handle larger files. See below for INFILESIZE_LARGE.
+ */
+ CINIT(INFILESIZE, LONG, 14),
+
+ /* POST static input fields. */
+ CINIT(POSTFIELDS, OBJECTPOINT, 15),
+
+ /* Set the referrer page (needed by some CGIs) */
+ CINIT(REFERER, OBJECTPOINT, 16),
+
+ /* Set the FTP PORT string (interface name, named or numerical IP address)
+ Use i.e '-' to use default address. */
+ CINIT(FTPPORT, OBJECTPOINT, 17),
+
+ /* Set the User-Agent string (examined by some CGIs) */
+ CINIT(USERAGENT, OBJECTPOINT, 18),
+
+ /* If the download receives less than "low speed limit" bytes/second
+ * during "low speed time" seconds, the operations is aborted.
+ * You could i.e if you have a pretty high speed connection, abort if
+ * it is less than 2000 bytes/sec during 20 seconds.
+ */
+
+ /* Set the "low speed limit" */
+ CINIT(LOW_SPEED_LIMIT, LONG, 19),
+
+ /* Set the "low speed time" */
+ CINIT(LOW_SPEED_TIME, LONG, 20),
+
+ /* Set the continuation offset.
+ *
+ * Note there is also a _LARGE version of this key which uses
+ * off_t types, allowing for large file offsets on platforms which
+ * use larger-than-32-bit off_t's. Look below for RESUME_FROM_LARGE.
+ */
+ CINIT(RESUME_FROM, LONG, 21),
+
+ /* Set cookie in request: */
+ CINIT(COOKIE, OBJECTPOINT, 22),
+
+ /* This points to a linked list of headers, struct curl_slist kind */
+ CINIT(HTTPHEADER, OBJECTPOINT, 23),
+
+ /* This points to a linked list of post entries, struct curl_httppost */
+ CINIT(HTTPPOST, OBJECTPOINT, 24),
+
+ /* name of the file keeping your private SSL-certificate */
+ CINIT(SSLCERT, OBJECTPOINT, 25),
+
+ /* password for the SSL or SSH private key */
+ CINIT(KEYPASSWD, OBJECTPOINT, 26),
+
+ /* send TYPE parameter? */
+ CINIT(CRLF, LONG, 27),
+
+ /* send linked-list of QUOTE commands */
+ CINIT(QUOTE, OBJECTPOINT, 28),
+
+ /* send FILE * or void * to store headers to, if you use a callback it
+ is simply passed to the callback unmodified */
+ CINIT(WRITEHEADER, OBJECTPOINT, 29),
+
+ /* point to a file to read the initial cookies from, also enables
+ "cookie awareness" */
+ CINIT(COOKIEFILE, OBJECTPOINT, 31),
+
+ /* What version to specifically try to use.
+ See CURL_SSLVERSION defines below. */
+ CINIT(SSLVERSION, LONG, 32),
+
+ /* What kind of HTTP time condition to use, see defines */
+ CINIT(TIMECONDITION, LONG, 33),
+
+ /* Time to use with the above condition. Specified in number of seconds
+ since 1 Jan 1970 */
+ CINIT(TIMEVALUE, LONG, 34),
+
+ /* 35 = OBSOLETE */
+
+ /* Custom request, for customizing the get command like
+ HTTP: DELETE, TRACE and others
+ FTP: to use a different list command
+ */
+ CINIT(CUSTOMREQUEST, OBJECTPOINT, 36),
+
+ /* HTTP request, for odd commands like DELETE, TRACE and others */
+ CINIT(STDERR, OBJECTPOINT, 37),
+
+ /* 38 is not used */
+
+ /* send linked-list of post-transfer QUOTE commands */
+ CINIT(POSTQUOTE, OBJECTPOINT, 39),
+
+ /* Pass a pointer to string of the output using full variable-replacement
+ as described elsewhere. */
+ CINIT(WRITEINFO, OBJECTPOINT, 40),
+
+ CINIT(VERBOSE, LONG, 41), /* talk a lot */
+ CINIT(HEADER, LONG, 42), /* throw the header out too */
+ CINIT(NOPROGRESS, LONG, 43), /* shut off the progress meter */
+ CINIT(NOBODY, LONG, 44), /* use HEAD to get http document */
+ CINIT(FAILONERROR, LONG, 45), /* no output on http error codes >= 300 */
+ CINIT(UPLOAD, LONG, 46), /* this is an upload */
+ CINIT(POST, LONG, 47), /* HTTP POST method */
+ CINIT(DIRLISTONLY, LONG, 48), /* return bare names when listing directories */
+
+ CINIT(APPEND, LONG, 50), /* Append instead of overwrite on upload! */
+
+ /* Specify whether to read the user+password from the .netrc or the URL.
+ * This must be one of the CURL_NETRC_* enums below. */
+ CINIT(NETRC, LONG, 51),
+
+ CINIT(FOLLOWLOCATION, LONG, 52), /* use Location: Luke! */
+
+ CINIT(TRANSFERTEXT, LONG, 53), /* transfer data in text/ASCII format */
+ CINIT(PUT, LONG, 54), /* HTTP PUT */
+
+ /* 55 = OBSOLETE */
+
+ /* Function that will be called instead of the internal progress display
+ * function. This function should be defined as the curl_progress_callback
+ * prototype defines. */
+ CINIT(PROGRESSFUNCTION, FUNCTIONPOINT, 56),
+
+ /* Data passed to the progress callback */
+ CINIT(PROGRESSDATA, OBJECTPOINT, 57),
+
+ /* We want the referrer field set automatically when following locations */
+ CINIT(AUTOREFERER, LONG, 58),
+
+ /* Port of the proxy, can be set in the proxy string as well with:
+ "[host]:[port]" */
+ CINIT(PROXYPORT, LONG, 59),
+
+ /* size of the POST input data, if strlen() is not good to use */
+ CINIT(POSTFIELDSIZE, LONG, 60),
+
+ /* tunnel non-http operations through a HTTP proxy */
+ CINIT(HTTPPROXYTUNNEL, LONG, 61),
+
+ /* Set the interface string to use as outgoing network interface */
+ CINIT(INTERFACE, OBJECTPOINT, 62),
+
+ /* Set the krb4/5 security level, this also enables krb4/5 awareness. This
+ * is a string, 'clear', 'safe', 'confidential' or 'private'. If the string
+ * is set but doesn't match one of these, 'private' will be used. */
+ CINIT(KRBLEVEL, OBJECTPOINT, 63),
+
+ /* Set if we should verify the peer in ssl handshake, set 1 to verify. */
+ CINIT(SSL_VERIFYPEER, LONG, 64),
+
+ /* The CApath or CAfile used to validate the peer certificate
+ this option is used only if SSL_VERIFYPEER is true */
+ CINIT(CAINFO, OBJECTPOINT, 65),
+
+ /* 66 = OBSOLETE */
+ /* 67 = OBSOLETE */
+
+ /* Maximum number of http redirects to follow */
+ CINIT(MAXREDIRS, LONG, 68),
+
+ /* Pass a long set to 1 to get the date of the requested document (if
+ possible)! Pass a zero to shut it off. */
+ CINIT(FILETIME, LONG, 69),
+
+ /* This points to a linked list of telnet options */
+ CINIT(TELNETOPTIONS, OBJECTPOINT, 70),
+
+ /* Max amount of cached alive connections */
+ CINIT(MAXCONNECTS, LONG, 71),
+
+ /* What policy to use when closing connections when the cache is filled
+ up */
+ CINIT(CLOSEPOLICY, LONG, 72),
+
+ /* 73 = OBSOLETE */
+
+ /* Set to explicitly use a new connection for the upcoming transfer.
+ Do not use this unless you're absolutely sure of this, as it makes the
+ operation slower and is less friendly for the network. */
+ CINIT(FRESH_CONNECT, LONG, 74),
+
+ /* Set to explicitly forbid the upcoming transfer's connection to be re-used
+ when done. Do not use this unless you're absolutely sure of this, as it
+ makes the operation slower and is less friendly for the network. */
+ CINIT(FORBID_REUSE, LONG, 75),
+
+ /* Set to a file name that contains random data for libcurl to use to
+ seed the random engine when doing SSL connects. */
+ CINIT(RANDOM_FILE, OBJECTPOINT, 76),
+
+ /* Set to the Entropy Gathering Daemon socket pathname */
+ CINIT(EGDSOCKET, OBJECTPOINT, 77),
+
+ /* Time-out connect operations after this amount of seconds, if connects
+ are OK within this time, then fine... This only aborts the connect
+ phase. [Only works on unix-style/SIGALRM operating systems] */
+ CINIT(CONNECTTIMEOUT, LONG, 78),
+
+ /* Function that will be called to store headers (instead of fwrite). The
+ * parameters will use fwrite() syntax, make sure to follow them. */
+ CINIT(HEADERFUNCTION, FUNCTIONPOINT, 79),
+
+ /* Set this to force the HTTP request to get back to GET. Only really usable
+ if POST, PUT or a custom request have been used first.
+ */
+ CINIT(HTTPGET, LONG, 80),
+
+ /* Set if we should verify the Common name from the peer certificate in ssl
+ * handshake, set 1 to check existence, 2 to ensure that it matches the
+ * provided hostname. */
+ CINIT(SSL_VERIFYHOST, LONG, 81),
+
+ /* Specify which file name to write all known cookies in after completed
+ operation. Set file name to "-" (dash) to make it go to stdout. */
+ CINIT(COOKIEJAR, OBJECTPOINT, 82),
+
+ /* Specify which SSL ciphers to use */
+ CINIT(SSL_CIPHER_LIST, OBJECTPOINT, 83),
+
+ /* Specify which HTTP version to use! This must be set to one of the
+ CURL_HTTP_VERSION* enums set below. */
+ CINIT(HTTP_VERSION, LONG, 84),
+
+ /* Specifically switch on or off the FTP engine's use of the EPSV command. By
+ default, that one will always be attempted before the more traditional
+ PASV command. */
+ CINIT(FTP_USE_EPSV, LONG, 85),
+
+ /* type of the file keeping your SSL-certificate ("DER", "PEM", "ENG") */
+ CINIT(SSLCERTTYPE, OBJECTPOINT, 86),
+
+ /* name of the file keeping your private SSL-key */
+ CINIT(SSLKEY, OBJECTPOINT, 87),
+
+ /* type of the file keeping your private SSL-key ("DER", "PEM", "ENG") */
+ CINIT(SSLKEYTYPE, OBJECTPOINT, 88),
+
+ /* crypto engine for the SSL-sub system */
+ CINIT(SSLENGINE, OBJECTPOINT, 89),
+
+ /* set the crypto engine for the SSL-sub system as default
+ the param has no meaning...
+ */
+ CINIT(SSLENGINE_DEFAULT, LONG, 90),
+
+ /* Non-zero value means to use the global dns cache */
+ CINIT(DNS_USE_GLOBAL_CACHE, LONG, 91), /* To become OBSOLETE soon */
+
+ /* DNS cache timeout */
+ CINIT(DNS_CACHE_TIMEOUT, LONG, 92),
+
+ /* send linked-list of pre-transfer QUOTE commands */
+ CINIT(PREQUOTE, OBJECTPOINT, 93),
+
+ /* set the debug function */
+ CINIT(DEBUGFUNCTION, FUNCTIONPOINT, 94),
+
+ /* set the data for the debug function */
+ CINIT(DEBUGDATA, OBJECTPOINT, 95),
+
+ /* mark this as start of a cookie session */
+ CINIT(COOKIESESSION, LONG, 96),
+
+ /* The CApath directory used to validate the peer certificate
+ this option is used only if SSL_VERIFYPEER is true */
+ CINIT(CAPATH, OBJECTPOINT, 97),
+
+ /* Instruct libcurl to use a smaller receive buffer */
+ CINIT(BUFFERSIZE, LONG, 98),
+
+ /* Instruct libcurl to not use any signal/alarm handlers, even when using
+ timeouts. This option is useful for multi-threaded applications.
+ See libcurl-the-guide for more background information. */
+ CINIT(NOSIGNAL, LONG, 99),
+
+ /* Provide a CURLShare for mutexing non-ts data */
+ CINIT(SHARE, OBJECTPOINT, 100),
+
+ /* indicates type of proxy. accepted values are CURLPROXY_HTTP (default),
+ CURLPROXY_SOCKS4, CURLPROXY_SOCKS4A and CURLPROXY_SOCKS5. */
+ CINIT(PROXYTYPE, LONG, 101),
+
+ /* Set the Accept-Encoding string. Use this to tell a server you would like
+ the response to be compressed. */
+ CINIT(ENCODING, OBJECTPOINT, 102),
+
+ /* Set pointer to private data */
+ CINIT(PRIVATE, OBJECTPOINT, 103),
+
+ /* Set aliases for HTTP 200 in the HTTP Response header */
+ CINIT(HTTP200ALIASES, OBJECTPOINT, 104),
+
+ /* Continue to send authentication (user+password) when following locations,
+ even when hostname changed. This can potentially send off the name
+ and password to whatever host the server decides. */
+ CINIT(UNRESTRICTED_AUTH, LONG, 105),
+
+ /* Specifically switch on or off the FTP engine's use of the EPRT command ( it
+ also disables the LPRT attempt). By default, those ones will always be
+ attempted before the good old traditional PORT command. */
+ CINIT(FTP_USE_EPRT, LONG, 106),
+
+ /* Set this to a bitmask value to enable the particular authentications
+ methods you like. Use this in combination with CURLOPT_USERPWD.
+ Note that setting multiple bits may cause extra network round-trips. */
+ CINIT(HTTPAUTH, LONG, 107),
+
+ /* Set the ssl context callback function, currently only for OpenSSL ssl_ctx
+ in second argument. The function must be matching the
+ curl_ssl_ctx_callback proto. */
+ CINIT(SSL_CTX_FUNCTION, FUNCTIONPOINT, 108),
+
+ /* Set the userdata for the ssl context callback function's third
+ argument */
+ CINIT(SSL_CTX_DATA, OBJECTPOINT, 109),
+
+ /* FTP Option that causes missing dirs to be created on the remote server.
+ In 7.19.4 we introduced the convenience enums for this option using the
+ CURLFTP_CREATE_DIR prefix.
+ */
+ CINIT(FTP_CREATE_MISSING_DIRS, LONG, 110),
+
+ /* Set this to a bitmask value to enable the particular authentications
+ methods you like. Use this in combination with CURLOPT_PROXYUSERPWD.
+ Note that setting multiple bits may cause extra network round-trips. */
+ CINIT(PROXYAUTH, LONG, 111),
+
+ /* FTP option that changes the timeout, in seconds, associated with
+ getting a response. This is different from transfer timeout time and
+ essentially places a demand on the FTP server to acknowledge commands
+ in a timely manner. */
+ CINIT(FTP_RESPONSE_TIMEOUT, LONG, 112),
+#define CURLOPT_SERVER_RESPONSE_TIMEOUT CURLOPT_FTP_RESPONSE_TIMEOUT
+
+ /* Set this option to one of the CURL_IPRESOLVE_* defines (see below) to
+ tell libcurl to resolve names to those IP versions only. This only has
+ affect on systems with support for more than one, i.e IPv4 _and_ IPv6. */
+ CINIT(IPRESOLVE, LONG, 113),
+
+ /* Set this option to limit the size of a file that will be downloaded from
+ an HTTP or FTP server.
+
+ Note there is also _LARGE version which adds large file support for
+ platforms which have larger off_t sizes. See MAXFILESIZE_LARGE below. */
+ CINIT(MAXFILESIZE, LONG, 114),
+
+ /* See the comment for INFILESIZE above, but in short, specifies
+ * the size of the file being uploaded. -1 means unknown.
+ */
+ CINIT(INFILESIZE_LARGE, OFF_T, 115),
+
+ /* Sets the continuation offset. There is also a LONG version of this;
+ * look above for RESUME_FROM.
+ */
+ CINIT(RESUME_FROM_LARGE, OFF_T, 116),
+
+ /* Sets the maximum size of data that will be downloaded from
+ * an HTTP or FTP server. See MAXFILESIZE above for the LONG version.
+ */
+ CINIT(MAXFILESIZE_LARGE, OFF_T, 117),
+
+ /* Set this option to the file name of your .netrc file you want libcurl
+ to parse (using the CURLOPT_NETRC option). If not set, libcurl will do
+ a poor attempt to find the user's home directory and check for a .netrc
+ file in there. */
+ CINIT(NETRC_FILE, OBJECTPOINT, 118),
+
+ /* Enable SSL/TLS for FTP, pick one of:
+ CURLFTPSSL_TRY - try using SSL, proceed anyway otherwise
+ CURLFTPSSL_CONTROL - SSL for the control connection or fail
+ CURLFTPSSL_ALL - SSL for all communication or fail
+ */
+ CINIT(USE_SSL, LONG, 119),
+
+ /* The _LARGE version of the standard POSTFIELDSIZE option */
+ CINIT(POSTFIELDSIZE_LARGE, OFF_T, 120),
+
+ /* Enable/disable the TCP Nagle algorithm */
+ CINIT(TCP_NODELAY, LONG, 121),
+
+ /* 122 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */
+ /* 123 OBSOLETE. Gone in 7.16.0 */
+ /* 124 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */
+ /* 125 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */
+ /* 126 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */
+ /* 127 OBSOLETE. Gone in 7.16.0 */
+ /* 128 OBSOLETE. Gone in 7.16.0 */
+
+ /* When FTP over SSL/TLS is selected (with CURLOPT_USE_SSL), this option
+ can be used to change libcurl's default action which is to first try
+ "AUTH SSL" and then "AUTH TLS" in this order, and proceed when a OK
+ response has been received.
+
+ Available parameters are:
+ CURLFTPAUTH_DEFAULT - let libcurl decide
+ CURLFTPAUTH_SSL - try "AUTH SSL" first, then TLS
+ CURLFTPAUTH_TLS - try "AUTH TLS" first, then SSL
+ */
+ CINIT(FTPSSLAUTH, LONG, 129),
+
+ CINIT(IOCTLFUNCTION, FUNCTIONPOINT, 130),
+ CINIT(IOCTLDATA, OBJECTPOINT, 131),
+
+ /* 132 OBSOLETE. Gone in 7.16.0 */
+ /* 133 OBSOLETE. Gone in 7.16.0 */
+
+ /* zero terminated string for pass on to the FTP server when asked for
+ "account" info */
+ CINIT(FTP_ACCOUNT, OBJECTPOINT, 134),
+
+ /* feed cookies into cookie engine */
+ CINIT(COOKIELIST, OBJECTPOINT, 135),
+
+ /* ignore Content-Length */
+ CINIT(IGNORE_CONTENT_LENGTH, LONG, 136),
+
+ /* Set to non-zero to skip the IP address received in a 227 PASV FTP server
+ response. Typically used for FTP-SSL purposes but is not restricted to
+ that. libcurl will then instead use the same IP address it used for the
+ control connection. */
+ CINIT(FTP_SKIP_PASV_IP, LONG, 137),
+
+ /* Select "file method" to use when doing FTP, see the curl_ftpmethod
+ above. */
+ CINIT(FTP_FILEMETHOD, LONG, 138),
+
+ /* Local port number to bind the socket to */
+ CINIT(LOCALPORT, LONG, 139),
+
+ /* Number of ports to try, including the first one set with LOCALPORT.
+ Thus, setting it to 1 will make no additional attempts but the first.
+ */
+ CINIT(LOCALPORTRANGE, LONG, 140),
+
+ /* no transfer, set up connection and let application use the socket by
+ extracting it with CURLINFO_LASTSOCKET */
+ CINIT(CONNECT_ONLY, LONG, 141),
+
+ /* Function that will be called to convert from the
+ network encoding (instead of using the iconv calls in libcurl) */
+ CINIT(CONV_FROM_NETWORK_FUNCTION, FUNCTIONPOINT, 142),
+
+ /* Function that will be called to convert to the
+ network encoding (instead of using the iconv calls in libcurl) */
+ CINIT(CONV_TO_NETWORK_FUNCTION, FUNCTIONPOINT, 143),
+
+ /* Function that will be called to convert from UTF8
+ (instead of using the iconv calls in libcurl)
+ Note that this is used only for SSL certificate processing */
+ CINIT(CONV_FROM_UTF8_FUNCTION, FUNCTIONPOINT, 144),
+
+ /* if the connection proceeds too quickly then need to slow it down */
+ /* limit-rate: maximum number of bytes per second to send or receive */
+ CINIT(MAX_SEND_SPEED_LARGE, OFF_T, 145),
+ CINIT(MAX_RECV_SPEED_LARGE, OFF_T, 146),
+
+ /* Pointer to command string to send if USER/PASS fails. */
+ CINIT(FTP_ALTERNATIVE_TO_USER, OBJECTPOINT, 147),
+
+ /* callback function for setting socket options */
+ CINIT(SOCKOPTFUNCTION, FUNCTIONPOINT, 148),
+ CINIT(SOCKOPTDATA, OBJECTPOINT, 149),
+
+ /* set to 0 to disable session ID re-use for this transfer, default is
+ enabled (== 1) */
+ CINIT(SSL_SESSIONID_CACHE, LONG, 150),
+
+ /* allowed SSH authentication methods */
+ CINIT(SSH_AUTH_TYPES, LONG, 151),
+
+ /* Used by scp/sftp to do public/private key authentication */
+ CINIT(SSH_PUBLIC_KEYFILE, OBJECTPOINT, 152),
+ CINIT(SSH_PRIVATE_KEYFILE, OBJECTPOINT, 153),
+
+ /* Send CCC (Clear Command Channel) after authentication */
+ CINIT(FTP_SSL_CCC, LONG, 154),
+
+ /* Same as TIMEOUT and CONNECTTIMEOUT, but with ms resolution */
+ CINIT(TIMEOUT_MS, LONG, 155),
+ CINIT(CONNECTTIMEOUT_MS, LONG, 156),
+
+ /* set to zero to disable the libcurl's decoding and thus pass the raw body
+ data to the application even when it is encoded/compressed */
+ CINIT(HTTP_TRANSFER_DECODING, LONG, 157),
+ CINIT(HTTP_CONTENT_DECODING, LONG, 158),
+
+ /* Permission used when creating new files and directories on the remote
+ server for protocols that support it, SFTP/SCP/FILE */
+ CINIT(NEW_FILE_PERMS, LONG, 159),
+ CINIT(NEW_DIRECTORY_PERMS, LONG, 160),
+
+ /* Set the behaviour of POST when redirecting. Values must be set to one
+ of CURL_REDIR* defines below. This used to be called CURLOPT_POST301 */
+ CINIT(POSTREDIR, LONG, 161),
+
+ /* used by scp/sftp to verify the host's public key */
+ CINIT(SSH_HOST_PUBLIC_KEY_MD5, OBJECTPOINT, 162),
+
+ /* Callback function for opening socket (instead of socket(2)). Optionally,
+ callback is able change the address or refuse to connect returning
+ CURL_SOCKET_BAD. The callback should have type
+ curl_opensocket_callback */
+ CINIT(OPENSOCKETFUNCTION, FUNCTIONPOINT, 163),
+ CINIT(OPENSOCKETDATA, OBJECTPOINT, 164),
+
+ /* POST volatile input fields. */
+ CINIT(COPYPOSTFIELDS, OBJECTPOINT, 165),
+
+ /* set transfer mode (;type=<a|i>) when doing FTP via an HTTP proxy */
+ CINIT(PROXY_TRANSFER_MODE, LONG, 166),
+
+ /* Callback function for seeking in the input stream */
+ CINIT(SEEKFUNCTION, FUNCTIONPOINT, 167),
+ CINIT(SEEKDATA, OBJECTPOINT, 168),
+
+ /* CRL file */
+ CINIT(CRLFILE, OBJECTPOINT, 169),
+
+ /* Issuer certificate */
+ CINIT(ISSUERCERT, OBJECTPOINT, 170),
+
+ /* (IPv6) Address scope */
+ CINIT(ADDRESS_SCOPE, LONG, 171),
+
+ /* Collect certificate chain info and allow it to get retrievable with
+ CURLINFO_CERTINFO after the transfer is complete. (Unfortunately) only
+ working with OpenSSL-powered builds. */
+ CINIT(CERTINFO, LONG, 172),
+
+ /* "name" and "pwd" to use when fetching. */
+ CINIT(USERNAME, OBJECTPOINT, 173),
+ CINIT(PASSWORD, OBJECTPOINT, 174),
+
+ /* "name" and "pwd" to use with Proxy when fetching. */
+ CINIT(PROXYUSERNAME, OBJECTPOINT, 175),
+ CINIT(PROXYPASSWORD, OBJECTPOINT, 176),
+
+ /* Comma separated list of hostnames defining no-proxy zones. These should
+ match both hostnames directly, and hostnames within a domain. For
+ example, local.com will match local.com and www.local.com, but NOT
+ notlocal.com or www.notlocal.com. For compatibility with other
+ implementations of this, .local.com will be considered to be the same as
+ local.com. A single * is the only valid wildcard, and effectively
+ disables the use of proxy. */
+ CINIT(NOPROXY, OBJECTPOINT, 177),
+
+ /* block size for TFTP transfers */
+ CINIT(TFTP_BLKSIZE, LONG, 178),
+
+ /* Socks Service */
+ CINIT(SOCKS5_GSSAPI_SERVICE, OBJECTPOINT, 179),
+
+ /* Socks Service */
+ CINIT(SOCKS5_GSSAPI_NEC, LONG, 180),
+
+ /* set the bitmask for the protocols that are allowed to be used for the
+ transfer, which thus helps the app which takes URLs from users or other
+ external inputs and want to restrict what protocol(s) to deal
+ with. Defaults to CURLPROTO_ALL. */
+ CINIT(PROTOCOLS, LONG, 181),
+
+ /* set the bitmask for the protocols that libcurl is allowed to follow to,
+ as a subset of the CURLOPT_PROTOCOLS ones. That means the protocol needs
+ to be set in both bitmasks to be allowed to get redirected to. Defaults
+ to all protocols except FILE and SCP. */
+ CINIT(REDIR_PROTOCOLS, LONG, 182),
+
+ /* set the SSH knownhost file name to use */
+ CINIT(SSH_KNOWNHOSTS, OBJECTPOINT, 183),
+
+ /* set the SSH host key callback, must point to a curl_sshkeycallback
+ function */
+ CINIT(SSH_KEYFUNCTION, FUNCTIONPOINT, 184),
+
+ /* set the SSH host key callback custom pointer */
+ CINIT(SSH_KEYDATA, OBJECTPOINT, 185),
+
+ /* set the SMTP mail originator */
+ CINIT(MAIL_FROM, OBJECTPOINT, 186),
+
+ /* set the SMTP mail receiver(s) */
+ CINIT(MAIL_RCPT, OBJECTPOINT, 187),
+
+ /* FTP: send PRET before PASV */
+ CINIT(FTP_USE_PRET, LONG, 188),
+
+ /* RTSP request method (OPTIONS, SETUP, PLAY, etc...) */
+ CINIT(RTSP_REQUEST, LONG, 189),
+
+ /* The RTSP session identifier */
+ CINIT(RTSP_SESSION_ID, OBJECTPOINT, 190),
+
+ /* The RTSP stream URI */
+ CINIT(RTSP_STREAM_URI, OBJECTPOINT, 191),
+
+ /* The Transport: header to use in RTSP requests */
+ CINIT(RTSP_TRANSPORT, OBJECTPOINT, 192),
+
+ /* Manually initialize the client RTSP CSeq for this handle */
+ CINIT(RTSP_CLIENT_CSEQ, LONG, 193),
+
+ /* Manually initialize the server RTSP CSeq for this handle */
+ CINIT(RTSP_SERVER_CSEQ, LONG, 194),
+
+ /* The stream to pass to INTERLEAVEFUNCTION. */
+ CINIT(INTERLEAVEDATA, OBJECTPOINT, 195),
+
+ /* Let the application define a custom write method for RTP data */
+ CINIT(INTERLEAVEFUNCTION, FUNCTIONPOINT, 196),
+
+ /* Turn on wildcard matching */
+ CINIT(WILDCARDMATCH, LONG, 197),
+
+ /* Directory matching callback called before downloading of an
+ individual file (chunk) started */
+ CINIT(CHUNK_BGN_FUNCTION, FUNCTIONPOINT, 198),
+
+ /* Directory matching callback called after the file (chunk)
+ was downloaded, or skipped */
+ CINIT(CHUNK_END_FUNCTION, FUNCTIONPOINT, 199),
+
+ /* Change match (fnmatch-like) callback for wildcard matching */
+ CINIT(FNMATCH_FUNCTION, FUNCTIONPOINT, 200),
+
+ /* Let the application define custom chunk data pointer */
+ CINIT(CHUNK_DATA, OBJECTPOINT, 201),
+
+ /* FNMATCH_FUNCTION user pointer */
+ CINIT(FNMATCH_DATA, OBJECTPOINT, 202),
+
+ CURLOPT_LASTENTRY /* the last unused */
+} CURLoption;
+
+#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all
+ the obsolete stuff removed! */
+
+/* Backwards compatibility with older names */
+/* These are scheduled to disappear by 2011 */
+
+/* This was added in version 7.19.1 */
+#define CURLOPT_POST301 CURLOPT_POSTREDIR
+
+/* These are scheduled to disappear by 2009 */
+
+/* The following were added in 7.17.0 */
+#define CURLOPT_SSLKEYPASSWD CURLOPT_KEYPASSWD
+#define CURLOPT_FTPAPPEND CURLOPT_APPEND
+#define CURLOPT_FTPLISTONLY CURLOPT_DIRLISTONLY
+#define CURLOPT_FTP_SSL CURLOPT_USE_SSL
+
+/* The following were added earlier */
+
+#define CURLOPT_SSLCERTPASSWD CURLOPT_KEYPASSWD
+#define CURLOPT_KRB4LEVEL CURLOPT_KRBLEVEL
+
+#else
+/* This is set if CURL_NO_OLDIES is defined at compile-time */
+#undef CURLOPT_DNS_USE_GLOBAL_CACHE /* soon obsolete */
+#endif
+
+
+ /* Below here follows defines for the CURLOPT_IPRESOLVE option. If a host
+ name resolves addresses using more than one IP protocol version, this
+ option might be handy to force libcurl to use a specific IP version. */
+#define CURL_IPRESOLVE_WHATEVER 0 /* default, resolves addresses to all IP
+ versions that your system allows */
+#define CURL_IPRESOLVE_V4 1 /* resolve to ipv4 addresses */
+#define CURL_IPRESOLVE_V6 2 /* resolve to ipv6 addresses */
+
+ /* three convenient "aliases" that follow the name scheme better */
+#define CURLOPT_WRITEDATA CURLOPT_FILE
+#define CURLOPT_READDATA CURLOPT_INFILE
+#define CURLOPT_HEADERDATA CURLOPT_WRITEHEADER
+#define CURLOPT_RTSPHEADER CURLOPT_HTTPHEADER
+
+ /* These enums are for use with the CURLOPT_HTTP_VERSION option. */
+enum {
+ CURL_HTTP_VERSION_NONE, /* setting this means we don't care, and that we'd
+ like the library to choose the best possible
+ for us! */
+ CURL_HTTP_VERSION_1_0, /* please use HTTP 1.0 in the request */
+ CURL_HTTP_VERSION_1_1, /* please use HTTP 1.1 in the request */
+
+ CURL_HTTP_VERSION_LAST /* *ILLEGAL* http version */
+};
+
+/*
+ * Public API enums for RTSP requests
+ */
+enum {
+ CURL_RTSPREQ_NONE, /* first in list */
+ CURL_RTSPREQ_OPTIONS,
+ CURL_RTSPREQ_DESCRIBE,
+ CURL_RTSPREQ_ANNOUNCE,
+ CURL_RTSPREQ_SETUP,
+ CURL_RTSPREQ_PLAY,
+ CURL_RTSPREQ_PAUSE,
+ CURL_RTSPREQ_TEARDOWN,
+ CURL_RTSPREQ_GET_PARAMETER,
+ CURL_RTSPREQ_SET_PARAMETER,
+ CURL_RTSPREQ_RECORD,
+ CURL_RTSPREQ_RECEIVE,
+ CURL_RTSPREQ_LAST /* last in list */
+};
+
+ /* These enums are for use with the CURLOPT_NETRC option. */
+enum CURL_NETRC_OPTION {
+ CURL_NETRC_IGNORED, /* The .netrc will never be read.
+ * This is the default. */
+ CURL_NETRC_OPTIONAL, /* A user:password in the URL will be preferred
+ * to one in the .netrc. */
+ CURL_NETRC_REQUIRED, /* A user:password in the URL will be ignored.
+ * Unless one is set programmatically, the .netrc
+ * will be queried. */
+ CURL_NETRC_LAST
+};
+
+enum {
+ CURL_SSLVERSION_DEFAULT,
+ CURL_SSLVERSION_TLSv1,
+ CURL_SSLVERSION_SSLv2,
+ CURL_SSLVERSION_SSLv3,
+
+ CURL_SSLVERSION_LAST /* never use, keep last */
+};
+
+/* symbols to use with CURLOPT_POSTREDIR.
+ CURL_REDIR_POST_301 and CURL_REDIR_POST_302 can be bitwise ORed so that
+ CURL_REDIR_POST_301 | CURL_REDIR_POST_302 == CURL_REDIR_POST_ALL */
+
+#define CURL_REDIR_GET_ALL 0
+#define CURL_REDIR_POST_301 1
+#define CURL_REDIR_POST_302 2
+#define CURL_REDIR_POST_ALL (CURL_REDIR_POST_301|CURL_REDIR_POST_302)
+
+typedef enum {
+ CURL_TIMECOND_NONE,
+
+ CURL_TIMECOND_IFMODSINCE,
+ CURL_TIMECOND_IFUNMODSINCE,
+ CURL_TIMECOND_LASTMOD,
+
+ CURL_TIMECOND_LAST
+} curl_TimeCond;
+
+
+/* curl_strequal() and curl_strnequal() are subject for removal in a future
+ libcurl, see lib/README.curlx for details */
+CURL_EXTERN int (curl_strequal)(const char *s1, const char *s2);
+CURL_EXTERN int (curl_strnequal)(const char *s1, const char *s2, size_t n);
+
+/* name is uppercase CURLFORM_<name> */
+#ifdef CFINIT
+#undef CFINIT
+#endif
+
+#ifdef CURL_ISOCPP
+#define CFINIT(name) CURLFORM_ ## name
+#else
+/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */
+#define CFINIT(name) CURLFORM_/**/name
+#endif
+
+typedef enum {
+ CFINIT(NOTHING), /********* the first one is unused ************/
+
+ /* */
+ CFINIT(COPYNAME),
+ CFINIT(PTRNAME),
+ CFINIT(NAMELENGTH),
+ CFINIT(COPYCONTENTS),
+ CFINIT(PTRCONTENTS),
+ CFINIT(CONTENTSLENGTH),
+ CFINIT(FILECONTENT),
+ CFINIT(ARRAY),
+ CFINIT(OBSOLETE),
+ CFINIT(FILE),
+
+ CFINIT(BUFFER),
+ CFINIT(BUFFERPTR),
+ CFINIT(BUFFERLENGTH),
+
+ CFINIT(CONTENTTYPE),
+ CFINIT(CONTENTHEADER),
+ CFINIT(FILENAME),
+ CFINIT(END),
+ CFINIT(OBSOLETE2),
+
+ CFINIT(STREAM),
+
+ CURLFORM_LASTENTRY /* the last unused */
+} CURLformoption;
+
+#undef CFINIT /* done */
+
+/* structure to be used as parameter for CURLFORM_ARRAY */
+struct curl_forms {
+ CURLformoption option;
+ const char *value;
+};
+
+/* use this for multipart formpost building */
+/* Returns code for curl_formadd()
+ *
+ * Returns:
+ * CURL_FORMADD_OK on success
+ * CURL_FORMADD_MEMORY if the FormInfo allocation fails
+ * CURL_FORMADD_OPTION_TWICE if one option is given twice for one Form
+ * CURL_FORMADD_NULL if a null pointer was given for a char
+ * CURL_FORMADD_MEMORY if the allocation of a FormInfo struct failed
+ * CURL_FORMADD_UNKNOWN_OPTION if an unknown option was used
+ * CURL_FORMADD_INCOMPLETE if the some FormInfo is not complete (or error)
+ * CURL_FORMADD_MEMORY if a curl_httppost struct cannot be allocated
+ * CURL_FORMADD_MEMORY if some allocation for string copying failed.
+ * CURL_FORMADD_ILLEGAL_ARRAY if an illegal option is used in an array
+ *
+ ***************************************************************************/
+typedef enum {
+ CURL_FORMADD_OK, /* first, no error */
+
+ CURL_FORMADD_MEMORY,
+ CURL_FORMADD_OPTION_TWICE,
+ CURL_FORMADD_NULL,
+ CURL_FORMADD_UNKNOWN_OPTION,
+ CURL_FORMADD_INCOMPLETE,
+ CURL_FORMADD_ILLEGAL_ARRAY,
+ CURL_FORMADD_DISABLED, /* libcurl was built with this disabled */
+
+ CURL_FORMADD_LAST /* last */
+} CURLFORMcode;
+
+/*
+ * NAME curl_formadd()
+ *
+ * DESCRIPTION
+ *
+ * Pretty advanced function for building multi-part formposts. Each invoke
+ * adds one part that together construct a full post. Then use
+ * CURLOPT_HTTPPOST to send it off to libcurl.
+ */
+CURL_EXTERN CURLFORMcode curl_formadd(struct curl_httppost **httppost,
+ struct curl_httppost **last_post,
+ ...);
+
+/*
+ * callback function for curl_formget()
+ * The void *arg pointer will be the one passed as second argument to
+ * curl_formget().
+ * The character buffer passed to it must not be freed.
+ * Should return the buffer length passed to it as the argument "len" on
+ * success.
+ */
+typedef size_t (*curl_formget_callback)(void *arg, const char *buf, size_t len);
+
+/*
+ * NAME curl_formget()
+ *
+ * DESCRIPTION
+ *
+ * Serialize a curl_httppost struct built with curl_formadd().
+ * Accepts a void pointer as second argument which will be passed to
+ * the curl_formget_callback function.
+ * Returns 0 on success.
+ */
+CURL_EXTERN int curl_formget(struct curl_httppost *form, void *arg,
+ curl_formget_callback append);
+/*
+ * NAME curl_formfree()
+ *
+ * DESCRIPTION
+ *
+ * Free a multipart formpost previously built with curl_formadd().
+ */
+CURL_EXTERN void curl_formfree(struct curl_httppost *form);
+
+/*
+ * NAME curl_getenv()
+ *
+ * DESCRIPTION
+ *
+ * Returns a malloc()'ed string that MUST be curl_free()ed after usage is
+ * complete. DEPRECATED - see lib/README.curlx
+ */
+CURL_EXTERN char *curl_getenv(const char *variable);
+
+/*
+ * NAME curl_version()
+ *
+ * DESCRIPTION
+ *
+ * Returns a static ascii string of the libcurl version.
+ */
+CURL_EXTERN char *curl_version(void);
+
+/*
+ * NAME curl_easy_escape()
+ *
+ * DESCRIPTION
+ *
+ * Escapes URL strings (converts all letters consider illegal in URLs to their
+ * %XX versions). This function returns a new allocated string or NULL if an
+ * error occurred.
+ */
+CURL_EXTERN char *curl_easy_escape(CURL *handle,
+ const char *string,
+ int length);
+
+/* the previous version: */
+CURL_EXTERN char *curl_escape(const char *string,
+ int length);
+
+
+/*
+ * NAME curl_easy_unescape()
+ *
+ * DESCRIPTION
+ *
+ * Unescapes URL encoding in strings (converts all %XX codes to their 8bit
+ * versions). This function returns a new allocated string or NULL if an error
+ * occurred.
+ * Conversion Note: On non-ASCII platforms the ASCII %XX codes are
+ * converted into the host encoding.
+ */
+CURL_EXTERN char *curl_easy_unescape(CURL *handle,
+ const char *string,
+ int length,
+ int *outlength);
+
+/* the previous version */
+CURL_EXTERN char *curl_unescape(const char *string,
+ int length);
+
+/*
+ * NAME curl_free()
+ *
+ * DESCRIPTION
+ *
+ * Provided for de-allocation in the same translation unit that did the
+ * allocation. Added in libcurl 7.10
+ */
+CURL_EXTERN void curl_free(void *p);
+
+/*
+ * NAME curl_global_init()
+ *
+ * DESCRIPTION
+ *
+ * curl_global_init() should be invoked exactly once for each application that
+ * uses libcurl and before any call of other libcurl functions.
+ *
+ * This function is not thread-safe!
+ */
+CURL_EXTERN CURLcode curl_global_init(long flags);
+
+/*
+ * NAME curl_global_init_mem()
+ *
+ * DESCRIPTION
+ *
+ * curl_global_init() or curl_global_init_mem() should be invoked exactly once
+ * for each application that uses libcurl. This function can be used to
+ * initialize libcurl and set user defined memory management callback
+ * functions. Users can implement memory management routines to check for
+ * memory leaks, check for mis-use of the curl library etc. User registered
+ * callback routines with be invoked by this library instead of the system
+ * memory management routines like malloc, free etc.
+ */
+CURL_EXTERN CURLcode curl_global_init_mem(long flags,
+ curl_malloc_callback m,
+ curl_free_callback f,
+ curl_realloc_callback r,
+ curl_strdup_callback s,
+ curl_calloc_callback c);
+
+/*
+ * NAME curl_global_cleanup()
+ *
+ * DESCRIPTION
+ *
+ * curl_global_cleanup() should be invoked exactly once for each application
+ * that uses libcurl
+ */
+CURL_EXTERN void curl_global_cleanup(void);
+
+/* linked-list structure for the CURLOPT_QUOTE option (and other) */
+struct curl_slist {
+ char *data;
+ struct curl_slist *next;
+};
+
+/*
+ * NAME curl_slist_append()
+ *
+ * DESCRIPTION
+ *
+ * Appends a string to a linked list. If no list exists, it will be created
+ * first. Returns the new list, after appending.
+ */
+CURL_EXTERN struct curl_slist *curl_slist_append(struct curl_slist *,
+ const char *);
+
+/*
+ * NAME curl_slist_free_all()
+ *
+ * DESCRIPTION
+ *
+ * free a previously built curl_slist.
+ */
+CURL_EXTERN void curl_slist_free_all(struct curl_slist *);
+
+/*
+ * NAME curl_getdate()
+ *
+ * DESCRIPTION
+ *
+ * Returns the time, in seconds since 1 Jan 1970 of the time string given in
+ * the first argument. The time argument in the second parameter is unused
+ * and should be set to NULL.
+ */
+CURL_EXTERN time_t curl_getdate(const char *p, const time_t *unused);
+
+/* info about the certificate chain, only for OpenSSL builds. Asked
+ for with CURLOPT_CERTINFO / CURLINFO_CERTINFO */
+struct curl_certinfo {
+ int num_of_certs; /* number of certificates with information */
+ struct curl_slist **certinfo; /* for each index in this array, there's a
+ linked list with textual information in the
+ format "name: value" */
+};
+
+#define CURLINFO_STRING 0x100000
+#define CURLINFO_LONG 0x200000
+#define CURLINFO_DOUBLE 0x300000
+#define CURLINFO_SLIST 0x400000
+#define CURLINFO_MASK 0x0fffff
+#define CURLINFO_TYPEMASK 0xf00000
+
+typedef enum {
+ CURLINFO_NONE, /* first, never use this */
+ CURLINFO_EFFECTIVE_URL = CURLINFO_STRING + 1,
+ CURLINFO_RESPONSE_CODE = CURLINFO_LONG + 2,
+ CURLINFO_TOTAL_TIME = CURLINFO_DOUBLE + 3,
+ CURLINFO_NAMELOOKUP_TIME = CURLINFO_DOUBLE + 4,
+ CURLINFO_CONNECT_TIME = CURLINFO_DOUBLE + 5,
+ CURLINFO_PRETRANSFER_TIME = CURLINFO_DOUBLE + 6,
+ CURLINFO_SIZE_UPLOAD = CURLINFO_DOUBLE + 7,
+ CURLINFO_SIZE_DOWNLOAD = CURLINFO_DOUBLE + 8,
+ CURLINFO_SPEED_DOWNLOAD = CURLINFO_DOUBLE + 9,
+ CURLINFO_SPEED_UPLOAD = CURLINFO_DOUBLE + 10,
+ CURLINFO_HEADER_SIZE = CURLINFO_LONG + 11,
+ CURLINFO_REQUEST_SIZE = CURLINFO_LONG + 12,
+ CURLINFO_SSL_VERIFYRESULT = CURLINFO_LONG + 13,
+ CURLINFO_FILETIME = CURLINFO_LONG + 14,
+ CURLINFO_CONTENT_LENGTH_DOWNLOAD = CURLINFO_DOUBLE + 15,
+ CURLINFO_CONTENT_LENGTH_UPLOAD = CURLINFO_DOUBLE + 16,
+ CURLINFO_STARTTRANSFER_TIME = CURLINFO_DOUBLE + 17,
+ CURLINFO_CONTENT_TYPE = CURLINFO_STRING + 18,
+ CURLINFO_REDIRECT_TIME = CURLINFO_DOUBLE + 19,
+ CURLINFO_REDIRECT_COUNT = CURLINFO_LONG + 20,
+ CURLINFO_PRIVATE = CURLINFO_STRING + 21,
+ CURLINFO_HTTP_CONNECTCODE = CURLINFO_LONG + 22,
+ CURLINFO_HTTPAUTH_AVAIL = CURLINFO_LONG + 23,
+ CURLINFO_PROXYAUTH_AVAIL = CURLINFO_LONG + 24,
+ CURLINFO_OS_ERRNO = CURLINFO_LONG + 25,
+ CURLINFO_NUM_CONNECTS = CURLINFO_LONG + 26,
+ CURLINFO_SSL_ENGINES = CURLINFO_SLIST + 27,
+ CURLINFO_COOKIELIST = CURLINFO_SLIST + 28,
+ CURLINFO_LASTSOCKET = CURLINFO_LONG + 29,
+ CURLINFO_FTP_ENTRY_PATH = CURLINFO_STRING + 30,
+ CURLINFO_REDIRECT_URL = CURLINFO_STRING + 31,
+ CURLINFO_PRIMARY_IP = CURLINFO_STRING + 32,
+ CURLINFO_APPCONNECT_TIME = CURLINFO_DOUBLE + 33,
+ CURLINFO_CERTINFO = CURLINFO_SLIST + 34,
+ CURLINFO_CONDITION_UNMET = CURLINFO_LONG + 35,
+ CURLINFO_RTSP_SESSION_ID = CURLINFO_STRING + 36,
+ CURLINFO_RTSP_CLIENT_CSEQ = CURLINFO_LONG + 37,
+ CURLINFO_RTSP_SERVER_CSEQ = CURLINFO_LONG + 38,
+ CURLINFO_RTSP_CSEQ_RECV = CURLINFO_LONG + 39,
+ CURLINFO_PRIMARY_PORT = CURLINFO_LONG + 40,
+ CURLINFO_LOCAL_IP = CURLINFO_STRING + 41,
+ CURLINFO_LOCAL_PORT = CURLINFO_LONG + 42,
+ /* Fill in new entries below here! */
+
+ CURLINFO_LASTONE = 42
+} CURLINFO;
+
+/* CURLINFO_RESPONSE_CODE is the new name for the option previously known as
+ CURLINFO_HTTP_CODE */
+#define CURLINFO_HTTP_CODE CURLINFO_RESPONSE_CODE
+
+typedef enum {
+ CURLCLOSEPOLICY_NONE, /* first, never use this */
+
+ CURLCLOSEPOLICY_OLDEST,
+ CURLCLOSEPOLICY_LEAST_RECENTLY_USED,
+ CURLCLOSEPOLICY_LEAST_TRAFFIC,
+ CURLCLOSEPOLICY_SLOWEST,
+ CURLCLOSEPOLICY_CALLBACK,
+
+ CURLCLOSEPOLICY_LAST /* last, never use this */
+} curl_closepolicy;
+
+#define CURL_GLOBAL_SSL (1<<0)
+#define CURL_GLOBAL_WIN32 (1<<1)
+#define CURL_GLOBAL_ALL (CURL_GLOBAL_SSL|CURL_GLOBAL_WIN32)
+#define CURL_GLOBAL_NOTHING 0
+#define CURL_GLOBAL_DEFAULT CURL_GLOBAL_ALL
+
+
+/*****************************************************************************
+ * Setup defines, protos etc for the sharing stuff.
+ */
+
+/* Different data locks for a single share */
+typedef enum {
+ CURL_LOCK_DATA_NONE = 0,
+ /* CURL_LOCK_DATA_SHARE is used internally to say that
+ * the locking is just made to change the internal state of the share
+ * itself.
+ */
+ CURL_LOCK_DATA_SHARE,
+ CURL_LOCK_DATA_COOKIE,
+ CURL_LOCK_DATA_DNS,
+ CURL_LOCK_DATA_SSL_SESSION,
+ CURL_LOCK_DATA_CONNECT,
+ CURL_LOCK_DATA_LAST
+} curl_lock_data;
+
+/* Different lock access types */
+typedef enum {
+ CURL_LOCK_ACCESS_NONE = 0, /* unspecified action */
+ CURL_LOCK_ACCESS_SHARED = 1, /* for read perhaps */
+ CURL_LOCK_ACCESS_SINGLE = 2, /* for write perhaps */
+ CURL_LOCK_ACCESS_LAST /* never use */
+} curl_lock_access;
+
+typedef void (*curl_lock_function)(CURL *handle,
+ curl_lock_data data,
+ curl_lock_access locktype,
+ void *userptr);
+typedef void (*curl_unlock_function)(CURL *handle,
+ curl_lock_data data,
+ void *userptr);
+
+typedef void CURLSH;
+
+typedef enum {
+ CURLSHE_OK, /* all is fine */
+ CURLSHE_BAD_OPTION, /* 1 */
+ CURLSHE_IN_USE, /* 2 */
+ CURLSHE_INVALID, /* 3 */
+ CURLSHE_NOMEM, /* out of memory */
+ CURLSHE_LAST /* never use */
+} CURLSHcode;
+
+typedef enum {
+ CURLSHOPT_NONE, /* don't use */
+ CURLSHOPT_SHARE, /* specify a data type to share */
+ CURLSHOPT_UNSHARE, /* specify which data type to stop sharing */
+ CURLSHOPT_LOCKFUNC, /* pass in a 'curl_lock_function' pointer */
+ CURLSHOPT_UNLOCKFUNC, /* pass in a 'curl_unlock_function' pointer */
+ CURLSHOPT_USERDATA, /* pass in a user data pointer used in the lock/unlock
+ callback functions */
+ CURLSHOPT_LAST /* never use */
+} CURLSHoption;
+
+CURL_EXTERN CURLSH *curl_share_init(void);
+CURL_EXTERN CURLSHcode curl_share_setopt(CURLSH *, CURLSHoption option, ...);
+CURL_EXTERN CURLSHcode curl_share_cleanup(CURLSH *);
+
+/****************************************************************************
+ * Structures for querying information about the curl library at runtime.
+ */
+
+typedef enum {
+ CURLVERSION_FIRST,
+ CURLVERSION_SECOND,
+ CURLVERSION_THIRD,
+ CURLVERSION_FOURTH,
+ CURLVERSION_LAST /* never actually use this */
+} CURLversion;
+
+/* The 'CURLVERSION_NOW' is the symbolic name meant to be used by
+ basically all programs ever that want to get version information. It is
+ meant to be a built-in version number for what kind of struct the caller
+ expects. If the struct ever changes, we redefine the NOW to another enum
+ from above. */
+#define CURLVERSION_NOW CURLVERSION_FOURTH
+
+typedef struct {
+ CURLversion age; /* age of the returned struct */
+ const char *version; /* LIBCURL_VERSION */
+ unsigned int version_num; /* LIBCURL_VERSION_NUM */
+ const char *host; /* OS/host/cpu/machine when configured */
+ int features; /* bitmask, see defines below */
+ const char *ssl_version; /* human readable string */
+ long ssl_version_num; /* not used anymore, always 0 */
+ const char *libz_version; /* human readable string */
+ /* protocols is terminated by an entry with a NULL protoname */
+ const char * const *protocols;
+
+ /* The fields below this were added in CURLVERSION_SECOND */
+ const char *ares;
+ int ares_num;
+
+ /* This field was added in CURLVERSION_THIRD */
+ const char *libidn;
+
+ /* These field were added in CURLVERSION_FOURTH */
+
+ /* Same as '_libiconv_version' if built with HAVE_ICONV */
+ int iconv_ver_num;
+
+ const char *libssh_version; /* human readable string */
+
+} curl_version_info_data;
+
+#define CURL_VERSION_IPV6 (1<<0) /* IPv6-enabled */
+#define CURL_VERSION_KERBEROS4 (1<<1) /* kerberos auth is supported */
+#define CURL_VERSION_SSL (1<<2) /* SSL options are present */
+#define CURL_VERSION_LIBZ (1<<3) /* libz features are present */
+#define CURL_VERSION_NTLM (1<<4) /* NTLM auth is supported */
+#define CURL_VERSION_GSSNEGOTIATE (1<<5) /* Negotiate auth support */
+#define CURL_VERSION_DEBUG (1<<6) /* built with debug capabilities */
+#define CURL_VERSION_ASYNCHDNS (1<<7) /* asynchronous dns resolves */
+#define CURL_VERSION_SPNEGO (1<<8) /* SPNEGO auth */
+#define CURL_VERSION_LARGEFILE (1<<9) /* supports files bigger than 2GB */
+#define CURL_VERSION_IDN (1<<10) /* International Domain Names support */
+#define CURL_VERSION_SSPI (1<<11) /* SSPI is supported */
+#define CURL_VERSION_CONV (1<<12) /* character conversions supported */
+#define CURL_VERSION_CURLDEBUG (1<<13) /* debug memory tracking supported */
+
+/*
+ * NAME curl_version_info()
+ *
+ * DESCRIPTION
+ *
+ * This function returns a pointer to a static copy of the version info
+ * struct. See above.
+ */
+CURL_EXTERN curl_version_info_data *curl_version_info(CURLversion);
+
+/*
+ * NAME curl_easy_strerror()
+ *
+ * DESCRIPTION
+ *
+ * The curl_easy_strerror function may be used to turn a CURLcode value
+ * into the equivalent human readable error string. This is useful
+ * for printing meaningful error messages.
+ */
+CURL_EXTERN const char *curl_easy_strerror(CURLcode);
+
+/*
+ * NAME curl_share_strerror()
+ *
+ * DESCRIPTION
+ *
+ * The curl_share_strerror function may be used to turn a CURLSHcode value
+ * into the equivalent human readable error string. This is useful
+ * for printing meaningful error messages.
+ */
+CURL_EXTERN const char *curl_share_strerror(CURLSHcode);
+
+/*
+ * NAME curl_easy_pause()
+ *
+ * DESCRIPTION
+ *
+ * The curl_easy_pause function pauses or unpauses transfers. Select the new
+ * state by setting the bitmask, use the convenience defines below.
+ *
+ */
+CURL_EXTERN CURLcode curl_easy_pause(CURL *handle, int bitmask);
+
+#define CURLPAUSE_RECV (1<<0)
+#define CURLPAUSE_RECV_CONT (0)
+
+#define CURLPAUSE_SEND (1<<2)
+#define CURLPAUSE_SEND_CONT (0)
+
+#define CURLPAUSE_ALL (CURLPAUSE_RECV|CURLPAUSE_SEND)
+#define CURLPAUSE_CONT (CURLPAUSE_RECV_CONT|CURLPAUSE_SEND_CONT)
+
+#ifdef __cplusplus
+}
+#endif
+
+/* unfortunately, the easy.h and multi.h include files need options and info
+ stuff before they can be included! */
+#include "easy.h" /* nothing in curl is fun without the easy stuff */
+#include "multi.h"
+
+/* the typechecker doesn't work in C++ (yet) */
+#if defined(__GNUC__) && defined(__GNUC_MINOR__) && \
+ ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) && \
+ !defined(__cplusplus) && !defined(CURL_DISABLE_TYPECHECK)
+#include "typecheck-gcc.h"
+#else
+#if defined(__STDC__) && (__STDC__ >= 1)
+/* This preprocessor magic that replaces a call with the exact same call is
+ only done to make sure application authors pass exactly three arguments
+ to these functions. */
+#define curl_easy_setopt(handle,opt,param) curl_easy_setopt(handle,opt,param)
+#define curl_easy_getinfo(handle,info,arg) curl_easy_getinfo(handle,info,arg)
+#define curl_share_setopt(share,opt,param) curl_share_setopt(share,opt,param)
+#define curl_multi_setopt(handle,opt,param) curl_multi_setopt(handle,opt,param)
+#endif /* __STDC__ >= 1 */
+#endif /* gcc >= 4.3 && !__cplusplus */
+
+#endif /* __CURL_CURL_H */
diff --git a/lib-x86-32/include/curl/curlbuild.h b/lib-x86-32/include/curl/curlbuild.h
new file mode 100644
index 00000000..81f4a285
--- /dev/null
+++ b/lib-x86-32/include/curl/curlbuild.h
@@ -0,0 +1,191 @@
+/* include/curl/curlbuild.h. Generated from curlbuild.h.in by configure. */
+#ifndef __CURL_CURLBUILD_H
+#define __CURL_CURLBUILD_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/* ================================================================ */
+/* NOTES FOR CONFIGURE CAPABLE SYSTEMS */
+/* ================================================================ */
+
+/*
+ * NOTE 1:
+ * -------
+ *
+ * Nothing in this file is intended to be modified or adjusted by the
+ * curl library user nor by the curl library builder.
+ *
+ * If you think that something actually needs to be changed, adjusted
+ * or fixed in this file, then, report it on the libcurl development
+ * mailing list: http://cool.haxx.se/mailman/listinfo/curl-library/
+ *
+ * This header file shall only export symbols which are 'curl' or 'CURL'
+ * prefixed, otherwise public name space would be polluted.
+ *
+ * NOTE 2:
+ * -------
+ *
+ * Right now you might be staring at file include/curl/curlbuild.h.in or
+ * at file include/curl/curlbuild.h, this is due to the following reason:
+ *
+ * On systems capable of running the configure script, the configure process
+ * will overwrite the distributed include/curl/curlbuild.h file with one that
+ * is suitable and specific to the library being configured and built, which
+ * is generated from the include/curl/curlbuild.h.in template file.
+ *
+ */
+
+/* ================================================================ */
+/* DEFINITION OF THESE SYMBOLS SHALL NOT TAKE PLACE ANYWHERE ELSE */
+/* ================================================================ */
+
+#ifdef CURL_SIZEOF_LONG
+# error "CURL_SIZEOF_LONG shall not be defined except in curlbuild.h"
+ Error Compilation_aborted_CURL_SIZEOF_LONG_already_defined
+#endif
+
+#ifdef CURL_TYPEOF_CURL_SOCKLEN_T
+# error "CURL_TYPEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h"
+ Error Compilation_aborted_CURL_TYPEOF_CURL_SOCKLEN_T_already_defined
+#endif
+
+#ifdef CURL_SIZEOF_CURL_SOCKLEN_T
+# error "CURL_SIZEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h"
+ Error Compilation_aborted_CURL_SIZEOF_CURL_SOCKLEN_T_already_defined
+#endif
+
+#ifdef CURL_TYPEOF_CURL_OFF_T
+# error "CURL_TYPEOF_CURL_OFF_T shall not be defined except in curlbuild.h"
+ Error Compilation_aborted_CURL_TYPEOF_CURL_OFF_T_already_defined
+#endif
+
+#ifdef CURL_FORMAT_CURL_OFF_T
+# error "CURL_FORMAT_CURL_OFF_T shall not be defined except in curlbuild.h"
+ Error Compilation_aborted_CURL_FORMAT_CURL_OFF_T_already_defined
+#endif
+
+#ifdef CURL_FORMAT_CURL_OFF_TU
+# error "CURL_FORMAT_CURL_OFF_TU shall not be defined except in curlbuild.h"
+ Error Compilation_aborted_CURL_FORMAT_CURL_OFF_TU_already_defined
+#endif
+
+#ifdef CURL_FORMAT_OFF_T
+# error "CURL_FORMAT_OFF_T shall not be defined except in curlbuild.h"
+ Error Compilation_aborted_CURL_FORMAT_OFF_T_already_defined
+#endif
+
+#ifdef CURL_SIZEOF_CURL_OFF_T
+# error "CURL_SIZEOF_CURL_OFF_T shall not be defined except in curlbuild.h"
+ Error Compilation_aborted_CURL_SIZEOF_CURL_OFF_T_already_defined
+#endif
+
+#ifdef CURL_SUFFIX_CURL_OFF_T
+# error "CURL_SUFFIX_CURL_OFF_T shall not be defined except in curlbuild.h"
+ Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_T_already_defined
+#endif
+
+#ifdef CURL_SUFFIX_CURL_OFF_TU
+# error "CURL_SUFFIX_CURL_OFF_TU shall not be defined except in curlbuild.h"
+ Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_TU_already_defined
+#endif
+
+/* ================================================================ */
+/* EXTERNAL INTERFACE SETTINGS FOR CONFIGURE CAPABLE SYSTEMS ONLY */
+/* ================================================================ */
+
+/* Configure process defines this to 1 when it finds out that system */
+/* header file ws2tcpip.h must be included by the external interface. */
+/* #undef CURL_PULL_WS2TCPIP_H */
+#ifdef CURL_PULL_WS2TCPIP_H
+# ifndef WIN32_LEAN_AND_MEAN
+# define WIN32_LEAN_AND_MEAN
+# endif
+# include <windows.h>
+# include <winsock2.h>
+# include <ws2tcpip.h>
+#endif
+
+/* Configure process defines this to 1 when it finds out that system */
+/* header file sys/types.h must be included by the external interface. */
+#define CURL_PULL_SYS_TYPES_H 1
+#ifdef CURL_PULL_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+
+/* Configure process defines this to 1 when it finds out that system */
+/* header file stdint.h must be included by the external interface. */
+#define CURL_PULL_STDINT_H 1
+#ifdef CURL_PULL_STDINT_H
+# include <stdint.h>
+#endif
+
+/* Configure process defines this to 1 when it finds out that system */
+/* header file inttypes.h must be included by the external interface. */
+#define CURL_PULL_INTTYPES_H 1
+#ifdef CURL_PULL_INTTYPES_H
+# include <inttypes.h>
+#endif
+
+/* Configure process defines this to 1 when it finds out that system */
+/* header file sys/socket.h must be included by the external interface. */
+#define CURL_PULL_SYS_SOCKET_H 1
+#ifdef CURL_PULL_SYS_SOCKET_H
+# include <sys/socket.h>
+#endif
+
+/* The size of `long', as computed by sizeof. */
+#define CURL_SIZEOF_LONG 4
+
+/* Integral data type used for curl_socklen_t. */
+#define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
+
+/* The size of `curl_socklen_t', as computed by sizeof. */
+#define CURL_SIZEOF_CURL_SOCKLEN_T 4
+
+/* Data type definition of curl_socklen_t. */
+typedef CURL_TYPEOF_CURL_SOCKLEN_T curl_socklen_t;
+
+/* Signed integral data type used for curl_off_t. */
+#define CURL_TYPEOF_CURL_OFF_T int64_t
+
+/* Data type definition of curl_off_t. */
+typedef CURL_TYPEOF_CURL_OFF_T curl_off_t;
+
+/* curl_off_t formatting string directive without "%" conversion specifier. */
+#define CURL_FORMAT_CURL_OFF_T "lld"
+
+/* unsigned curl_off_t formatting string without "%" conversion specifier. */
+#define CURL_FORMAT_CURL_OFF_TU "llu"
+
+/* curl_off_t formatting string directive with "%" conversion specifier. */
+#define CURL_FORMAT_OFF_T "%lld"
+
+/* The size of `curl_off_t', as computed by sizeof. */
+#define CURL_SIZEOF_CURL_OFF_T 8
+
+/* curl_off_t constant suffix. */
+#define CURL_SUFFIX_CURL_OFF_T LL
+
+/* unsigned curl_off_t constant suffix. */
+#define CURL_SUFFIX_CURL_OFF_TU ULL
+
+#endif /* __CURL_CURLBUILD_H */
diff --git a/lib-x86-32/include/curl/curlbuild.h.cmake b/lib-x86-32/include/curl/curlbuild.h.cmake
new file mode 100644
index 00000000..3aa772fc
--- /dev/null
+++ b/lib-x86-32/include/curl/curlbuild.h.cmake
@@ -0,0 +1,180 @@
+#ifndef __CURL_CURLBUILD_H
+#define __CURL_CURLBUILD_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/* ================================================================ */
+/* NOTES FOR CONFIGURE CAPABLE SYSTEMS */
+/* ================================================================ */
+
+/*
+ * NOTE 1:
+ * -------
+ *
+ * Nothing in this file is intended to be modified or adjusted by the
+ * curl library user nor by the curl library builder.
+ *
+ * If you think that something actually needs to be changed, adjusted
+ * or fixed in this file, then, report it on the libcurl development
+ * mailing list: http://cool.haxx.se/mailman/listinfo/curl-library/
+ *
+ * This header file shall only export symbols which are 'curl' or 'CURL'
+ * prefixed, otherwise public name space would be polluted.
+ *
+ * NOTE 2:
+ * -------
+ *
+ * Right now you might be staring at file include/curl/curlbuild.h.in or
+ * at file include/curl/curlbuild.h, this is due to the following reason:
+ *
+ * On systems capable of running the configure script, the configure process
+ * will overwrite the distributed include/curl/curlbuild.h file with one that
+ * is suitable and specific to the library being configured and built, which
+ * is generated from the include/curl/curlbuild.h.in template file.
+ *
+ */
+
+/* ================================================================ */
+/* DEFINITION OF THESE SYMBOLS SHALL NOT TAKE PLACE ANYWHERE ELSE */
+/* ================================================================ */
+
+#ifdef CURL_SIZEOF_LONG
+# error "CURL_SIZEOF_LONG shall not be defined except in curlbuild.h"
+ Error Compilation_aborted_CURL_SIZEOF_LONG_already_defined
+#endif
+
+#ifdef CURL_TYPEOF_CURL_SOCKLEN_T
+# error "CURL_TYPEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h"
+ Error Compilation_aborted_CURL_TYPEOF_CURL_SOCKLEN_T_already_defined
+#endif
+
+#ifdef CURL_SIZEOF_CURL_SOCKLEN_T
+# error "CURL_SIZEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h"
+ Error Compilation_aborted_CURL_SIZEOF_CURL_SOCKLEN_T_already_defined
+#endif
+#ifdef CURL_TYPEOF_CURL_OFF_T
+# error "CURL_TYPEOF_CURL_OFF_T shall not be defined except in curlbuild.h"
+ Error Compilation_aborted_CURL_TYPEOF_CURL_OFF_T_already_defined
+#endif
+
+#ifdef CURL_FORMAT_CURL_OFF_T
+# error "CURL_FORMAT_CURL_OFF_T shall not be defined except in curlbuild.h"
+ Error Compilation_aborted_CURL_FORMAT_CURL_OFF_T_already_defined
+#endif
+
+#ifdef CURL_FORMAT_CURL_OFF_TU
+# error "CURL_FORMAT_CURL_OFF_TU shall not be defined except in curlbuild.h"
+ Error Compilation_aborted_CURL_FORMAT_CURL_OFF_TU_already_defined
+#endif
+
+#ifdef CURL_FORMAT_OFF_T
+# error "CURL_FORMAT_OFF_T shall not be defined except in curlbuild.h"
+ Error Compilation_aborted_CURL_FORMAT_OFF_T_already_defined
+#endif
+
+#ifdef CURL_SIZEOF_CURL_OFF_T
+# error "CURL_SIZEOF_CURL_OFF_T shall not be defined except in curlbuild.h"
+ Error Compilation_aborted_CURL_SIZEOF_CURL_OFF_T_already_defined
+#endif
+
+#ifdef CURL_SUFFIX_CURL_OFF_T
+# error "CURL_SUFFIX_CURL_OFF_T shall not be defined except in curlbuild.h"
+ Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_T_already_defined
+#endif
+
+#ifdef CURL_SUFFIX_CURL_OFF_TU
+# error "CURL_SUFFIX_CURL_OFF_TU shall not be defined except in curlbuild.h"
+ Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_TU_already_defined
+#endif
+
+/* ================================================================ */
+/* EXTERNAL INTERFACE SETTINGS FOR CONFIGURE CAPABLE SYSTEMS ONLY */
+/* ================================================================ */
+
+/* Configure process defines this to 1 when it finds out that system */
+/* header file sys/types.h must be included by the external interface. */
+#cmakedefine CURL_PULL_SYS_TYPES_H ${CURL_PULL_SYS_TYPES_H}
+#ifdef CURL_PULL_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+
+/* Configure process defines this to 1 when it finds out that system */
+/* header file stdint.h must be included by the external interface. */
+#cmakedefine CURL_PULL_STDINT_H ${CURL_PULL_STDINT_H}
+#ifdef CURL_PULL_STDINT_H
+# include <stdint.h>
+#endif
+
+/* Configure process defines this to 1 when it finds out that system */
+/* header file inttypes.h must be included by the external interface. */
+#cmakedefine CURL_PULL_INTTYPES_H ${CURL_PULL_INTTYPES_H}
+#ifdef CURL_PULL_INTTYPES_H
+# include <inttypes.h>
+#endif
+
+/* The size of `long', as computed by sizeof. */
+#cmakedefine CURL_SIZEOF_LONG ${CURL_SIZEOF_LONG}
+
+/* Integral data type used for curl_socklen_t. */
+#cmakedefine CURL_TYPEOF_CURL_SOCKLEN_T ${CURL_TYPEOF_CURL_SOCKLEN_T}
+
+/* on windows socklen_t is in here */
+#ifdef _WIN32
+# include <winsock2.h>
+# include <ws2tcpip.h>
+#endif
+
+#ifdef HAVE_SYS_SOCKET_H
+# include <sys/socket.h>
+#endif
+
+/* Data type definition of curl_socklen_t. */
+typedef CURL_TYPEOF_CURL_SOCKLEN_T curl_socklen_t;
+
+/* The size of `curl_socklen_t', as computed by sizeof. */
+#cmakedefine CURL_SIZEOF_CURL_SOCKLEN_T ${CURL_SIZEOF_CURL_SOCKLEN_T}
+
+/* Signed integral data type used for curl_off_t. */
+#cmakedefine CURL_TYPEOF_CURL_OFF_T ${CURL_TYPEOF_CURL_OFF_T}
+
+/* Data type definition of curl_off_t. */
+typedef CURL_TYPEOF_CURL_OFF_T curl_off_t;
+
+/* curl_off_t formatting string directive without "%" conversion specifier. */
+#cmakedefine CURL_FORMAT_CURL_OFF_T "${CURL_FORMAT_CURL_OFF_T}"
+
+/* unsigned curl_off_t formatting string without "%" conversion specifier. */
+#cmakedefine CURL_FORMAT_CURL_OFF_TU "${CURL_FORMAT_CURL_OFF_TU}"
+
+/* curl_off_t formatting string directive with "%" conversion specifier. */
+#cmakedefine CURL_FORMAT_OFF_T "${CURL_FORMAT_OFF_T}"
+
+/* The size of `curl_off_t', as computed by sizeof. */
+#cmakedefine CURL_SIZEOF_CURL_OFF_T ${CURL_SIZEOF_CURL_OFF_T}
+
+/* curl_off_t constant suffix. */
+#cmakedefine CURL_SUFFIX_CURL_OFF_T ${CURL_SUFFIX_CURL_OFF_T}
+
+/* unsigned curl_off_t constant suffix. */
+#cmakedefine CURL_SUFFIX_CURL_OFF_TU ${CURL_SUFFIX_CURL_OFF_TU}
+
+#endif /* __CURL_CURLBUILD_H */
diff --git a/lib-x86-32/include/curl/curlbuild.h.in b/lib-x86-32/include/curl/curlbuild.h.in
new file mode 100644
index 00000000..cb1de80a
--- /dev/null
+++ b/lib-x86-32/include/curl/curlbuild.h.in
@@ -0,0 +1,190 @@
+#ifndef __CURL_CURLBUILD_H
+#define __CURL_CURLBUILD_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/* ================================================================ */
+/* NOTES FOR CONFIGURE CAPABLE SYSTEMS */
+/* ================================================================ */
+
+/*
+ * NOTE 1:
+ * -------
+ *
+ * Nothing in this file is intended to be modified or adjusted by the
+ * curl library user nor by the curl library builder.
+ *
+ * If you think that something actually needs to be changed, adjusted
+ * or fixed in this file, then, report it on the libcurl development
+ * mailing list: http://cool.haxx.se/mailman/listinfo/curl-library/
+ *
+ * This header file shall only export symbols which are 'curl' or 'CURL'
+ * prefixed, otherwise public name space would be polluted.
+ *
+ * NOTE 2:
+ * -------
+ *
+ * Right now you might be staring at file include/curl/curlbuild.h.in or
+ * at file include/curl/curlbuild.h, this is due to the following reason:
+ *
+ * On systems capable of running the configure script, the configure process
+ * will overwrite the distributed include/curl/curlbuild.h file with one that
+ * is suitable and specific to the library being configured and built, which
+ * is generated from the include/curl/curlbuild.h.in template file.
+ *
+ */
+
+/* ================================================================ */
+/* DEFINITION OF THESE SYMBOLS SHALL NOT TAKE PLACE ANYWHERE ELSE */
+/* ================================================================ */
+
+#ifdef CURL_SIZEOF_LONG
+# error "CURL_SIZEOF_LONG shall not be defined except in curlbuild.h"
+ Error Compilation_aborted_CURL_SIZEOF_LONG_already_defined
+#endif
+
+#ifdef CURL_TYPEOF_CURL_SOCKLEN_T
+# error "CURL_TYPEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h"
+ Error Compilation_aborted_CURL_TYPEOF_CURL_SOCKLEN_T_already_defined
+#endif
+
+#ifdef CURL_SIZEOF_CURL_SOCKLEN_T
+# error "CURL_SIZEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h"
+ Error Compilation_aborted_CURL_SIZEOF_CURL_SOCKLEN_T_already_defined
+#endif
+
+#ifdef CURL_TYPEOF_CURL_OFF_T
+# error "CURL_TYPEOF_CURL_OFF_T shall not be defined except in curlbuild.h"
+ Error Compilation_aborted_CURL_TYPEOF_CURL_OFF_T_already_defined
+#endif
+
+#ifdef CURL_FORMAT_CURL_OFF_T
+# error "CURL_FORMAT_CURL_OFF_T shall not be defined except in curlbuild.h"
+ Error Compilation_aborted_CURL_FORMAT_CURL_OFF_T_already_defined
+#endif
+
+#ifdef CURL_FORMAT_CURL_OFF_TU
+# error "CURL_FORMAT_CURL_OFF_TU shall not be defined except in curlbuild.h"
+ Error Compilation_aborted_CURL_FORMAT_CURL_OFF_TU_already_defined
+#endif
+
+#ifdef CURL_FORMAT_OFF_T
+# error "CURL_FORMAT_OFF_T shall not be defined except in curlbuild.h"
+ Error Compilation_aborted_CURL_FORMAT_OFF_T_already_defined
+#endif
+
+#ifdef CURL_SIZEOF_CURL_OFF_T
+# error "CURL_SIZEOF_CURL_OFF_T shall not be defined except in curlbuild.h"
+ Error Compilation_aborted_CURL_SIZEOF_CURL_OFF_T_already_defined
+#endif
+
+#ifdef CURL_SUFFIX_CURL_OFF_T
+# error "CURL_SUFFIX_CURL_OFF_T shall not be defined except in curlbuild.h"
+ Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_T_already_defined
+#endif
+
+#ifdef CURL_SUFFIX_CURL_OFF_TU
+# error "CURL_SUFFIX_CURL_OFF_TU shall not be defined except in curlbuild.h"
+ Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_TU_already_defined
+#endif
+
+/* ================================================================ */
+/* EXTERNAL INTERFACE SETTINGS FOR CONFIGURE CAPABLE SYSTEMS ONLY */
+/* ================================================================ */
+
+/* Configure process defines this to 1 when it finds out that system */
+/* header file ws2tcpip.h must be included by the external interface. */
+#undef CURL_PULL_WS2TCPIP_H
+#ifdef CURL_PULL_WS2TCPIP_H
+# ifndef WIN32_LEAN_AND_MEAN
+# define WIN32_LEAN_AND_MEAN
+# endif
+# include <windows.h>
+# include <winsock2.h>
+# include <ws2tcpip.h>
+#endif
+
+/* Configure process defines this to 1 when it finds out that system */
+/* header file sys/types.h must be included by the external interface. */
+#undef CURL_PULL_SYS_TYPES_H
+#ifdef CURL_PULL_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+
+/* Configure process defines this to 1 when it finds out that system */
+/* header file stdint.h must be included by the external interface. */
+#undef CURL_PULL_STDINT_H
+#ifdef CURL_PULL_STDINT_H
+# include <stdint.h>
+#endif
+
+/* Configure process defines this to 1 when it finds out that system */
+/* header file inttypes.h must be included by the external interface. */
+#undef CURL_PULL_INTTYPES_H
+#ifdef CURL_PULL_INTTYPES_H
+# include <inttypes.h>
+#endif
+
+/* Configure process defines this to 1 when it finds out that system */
+/* header file sys/socket.h must be included by the external interface. */
+#undef CURL_PULL_SYS_SOCKET_H
+#ifdef CURL_PULL_SYS_SOCKET_H
+# include <sys/socket.h>
+#endif
+
+/* The size of `long', as computed by sizeof. */
+#undef CURL_SIZEOF_LONG
+
+/* Integral data type used for curl_socklen_t. */
+#undef CURL_TYPEOF_CURL_SOCKLEN_T
+
+/* The size of `curl_socklen_t', as computed by sizeof. */
+#undef CURL_SIZEOF_CURL_SOCKLEN_T
+
+/* Data type definition of curl_socklen_t. */
+typedef CURL_TYPEOF_CURL_SOCKLEN_T curl_socklen_t;
+
+/* Signed integral data type used for curl_off_t. */
+#undef CURL_TYPEOF_CURL_OFF_T
+
+/* Data type definition of curl_off_t. */
+typedef CURL_TYPEOF_CURL_OFF_T curl_off_t;
+
+/* curl_off_t formatting string directive without "%" conversion specifier. */
+#undef CURL_FORMAT_CURL_OFF_T
+
+/* unsigned curl_off_t formatting string without "%" conversion specifier. */
+#undef CURL_FORMAT_CURL_OFF_TU
+
+/* curl_off_t formatting string directive with "%" conversion specifier. */
+#undef CURL_FORMAT_OFF_T
+
+/* The size of `curl_off_t', as computed by sizeof. */
+#undef CURL_SIZEOF_CURL_OFF_T
+
+/* curl_off_t constant suffix. */
+#undef CURL_SUFFIX_CURL_OFF_T
+
+/* unsigned curl_off_t constant suffix. */
+#undef CURL_SUFFIX_CURL_OFF_TU
+
+#endif /* __CURL_CURLBUILD_H */
diff --git a/lib-x86-32/include/curl/curlrules.h b/lib-x86-32/include/curl/curlrules.h
new file mode 100644
index 00000000..8aad1df6
--- /dev/null
+++ b/lib-x86-32/include/curl/curlrules.h
@@ -0,0 +1,252 @@
+#ifndef __CURL_CURLRULES_H
+#define __CURL_CURLRULES_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/* ================================================================ */
+/* COMPILE TIME SANITY CHECKS */
+/* ================================================================ */
+
+/*
+ * NOTE 1:
+ * -------
+ *
+ * All checks done in this file are intentionally placed in a public
+ * header file which is pulled by curl/curl.h when an application is
+ * being built using an already built libcurl library. Additionally
+ * this file is also included and used when building the library.
+ *
+ * If compilation fails on this file it is certainly sure that the
+ * problem is elsewhere. It could be a problem in the curlbuild.h
+ * header file, or simply that you are using different compilation
+ * settings than those used to build the library.
+ *
+ * Nothing in this file is intended to be modified or adjusted by the
+ * curl library user nor by the curl library builder.
+ *
+ * Do not deactivate any check, these are done to make sure that the
+ * library is properly built and used.
+ *
+ * You can find further help on the libcurl development mailing list:
+ * http://cool.haxx.se/mailman/listinfo/curl-library/
+ *
+ * NOTE 2
+ * ------
+ *
+ * Some of the following compile time checks are based on the fact
+ * that the dimension of a constant array can not be a negative one.
+ * In this way if the compile time verification fails, the compilation
+ * will fail issuing an error. The error description wording is compiler
+ * dependent but it will be quite similar to one of the following:
+ *
+ * "negative subscript or subscript is too large"
+ * "array must have at least one element"
+ * "-1 is an illegal array size"
+ * "size of array is negative"
+ *
+ * If you are building an application which tries to use an already
+ * built libcurl library and you are getting this kind of errors on
+ * this file, it is a clear indication that there is a mismatch between
+ * how the library was built and how you are trying to use it for your
+ * application. Your already compiled or binary library provider is the
+ * only one who can give you the details you need to properly use it.
+ */
+
+/*
+ * Verify that some macros are actually defined.
+ */
+
+#ifndef CURL_SIZEOF_LONG
+# error "CURL_SIZEOF_LONG definition is missing!"
+ Error Compilation_aborted_CURL_SIZEOF_LONG_is_missing
+#endif
+
+#ifndef CURL_TYPEOF_CURL_SOCKLEN_T
+# error "CURL_TYPEOF_CURL_SOCKLEN_T definition is missing!"
+ Error Compilation_aborted_CURL_TYPEOF_CURL_SOCKLEN_T_is_missing
+#endif
+
+#ifndef CURL_SIZEOF_CURL_SOCKLEN_T
+# error "CURL_SIZEOF_CURL_SOCKLEN_T definition is missing!"
+ Error Compilation_aborted_CURL_SIZEOF_CURL_SOCKLEN_T_is_missing
+#endif
+
+#ifndef CURL_TYPEOF_CURL_OFF_T
+# error "CURL_TYPEOF_CURL_OFF_T definition is missing!"
+ Error Compilation_aborted_CURL_TYPEOF_CURL_OFF_T_is_missing
+#endif
+
+#ifndef CURL_FORMAT_CURL_OFF_T
+# error "CURL_FORMAT_CURL_OFF_T definition is missing!"
+ Error Compilation_aborted_CURL_FORMAT_CURL_OFF_T_is_missing
+#endif
+
+#ifndef CURL_FORMAT_CURL_OFF_TU
+# error "CURL_FORMAT_CURL_OFF_TU definition is missing!"
+ Error Compilation_aborted_CURL_FORMAT_CURL_OFF_TU_is_missing
+#endif
+
+#ifndef CURL_FORMAT_OFF_T
+# error "CURL_FORMAT_OFF_T definition is missing!"
+ Error Compilation_aborted_CURL_FORMAT_OFF_T_is_missing
+#endif
+
+#ifndef CURL_SIZEOF_CURL_OFF_T
+# error "CURL_SIZEOF_CURL_OFF_T definition is missing!"
+ Error Compilation_aborted_CURL_SIZEOF_CURL_OFF_T_is_missing
+#endif
+
+#ifndef CURL_SUFFIX_CURL_OFF_T
+# error "CURL_SUFFIX_CURL_OFF_T definition is missing!"
+ Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_T_is_missing
+#endif
+
+#ifndef CURL_SUFFIX_CURL_OFF_TU
+# error "CURL_SUFFIX_CURL_OFF_TU definition is missing!"
+ Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_TU_is_missing
+#endif
+
+/*
+ * Macros private to this header file.
+ */
+
+#define CurlchkszEQ(t, s) sizeof(t) == s ? 1 : -1
+
+#define CurlchkszGE(t1, t2) sizeof(t1) >= sizeof(t2) ? 1 : -1
+
+/*
+ * Verify that the size previously defined and expected for long
+ * is the same as the one reported by sizeof() at compile time.
+ */
+
+typedef char
+ __curl_rule_01__
+ [CurlchkszEQ(long, CURL_SIZEOF_LONG)];
+
+/*
+ * Verify that the size previously defined and expected for
+ * curl_off_t is actually the the same as the one reported
+ * by sizeof() at compile time.
+ */
+
+typedef char
+ __curl_rule_02__
+ [CurlchkszEQ(curl_off_t, CURL_SIZEOF_CURL_OFF_T)];
+
+/*
+ * Verify at compile time that the size of curl_off_t as reported
+ * by sizeof() is greater or equal than the one reported for long
+ * for the current compilation.
+ */
+
+typedef char
+ __curl_rule_03__
+ [CurlchkszGE(curl_off_t, long)];
+
+/*
+ * Verify that the size previously defined and expected for
+ * curl_socklen_t is actually the the same as the one reported
+ * by sizeof() at compile time.
+ */
+
+typedef char
+ __curl_rule_04__
+ [CurlchkszEQ(curl_socklen_t, CURL_SIZEOF_CURL_SOCKLEN_T)];
+
+/*
+ * Verify at compile time that the size of curl_socklen_t as reported
+ * by sizeof() is greater or equal than the one reported for int for
+ * the current compilation.
+ */
+
+typedef char
+ __curl_rule_05__
+ [CurlchkszGE(curl_socklen_t, int)];
+
+/* ================================================================ */
+/* EXTERNALLY AND INTERNALLY VISIBLE DEFINITIONS */
+/* ================================================================ */
+
+/*
+ * CURL_ISOCPP and CURL_OFF_T_C definitions are done here in order to allow
+ * these to be visible and exported by the external libcurl interface API,
+ * while also making them visible to the library internals, simply including
+ * setup.h, without actually needing to include curl.h internally.
+ * If some day this section would grow big enough, all this should be moved
+ * to its own header file.
+ */
+
+/*
+ * Figure out if we can use the ## preprocessor operator, which is supported
+ * by ISO/ANSI C and C++. Some compilers support it without setting __STDC__
+ * or __cplusplus so we need to carefully check for them too.
+ */
+
+#if defined(__STDC__) || defined(_MSC_VER) || defined(__cplusplus) || \
+ defined(__HP_aCC) || defined(__BORLANDC__) || defined(__LCC__) || \
+ defined(__POCC__) || defined(__SALFORDC__) || defined(__HIGHC__) || \
+ defined(__ILEC400__)
+ /* This compiler is believed to have an ISO compatible preprocessor */
+#define CURL_ISOCPP
+#else
+ /* This compiler is believed NOT to have an ISO compatible preprocessor */
+#undef CURL_ISOCPP
+#endif
+
+/*
+ * Macros for minimum-width signed and unsigned curl_off_t integer constants.
+ */
+
+#ifdef CURL_ISOCPP
+# define __CURL_OFF_T_C_HELPER2(Val,Suffix) Val ## Suffix
+#else
+# define __CURL_OFF_T_C_HELPER2(Val,Suffix) Val/**/Suffix
+#endif
+#define __CURL_OFF_T_C_HELPER1(Val,Suffix) __CURL_OFF_T_C_HELPER2(Val,Suffix)
+#define CURL_OFF_T_C(Val) __CURL_OFF_T_C_HELPER1(Val,CURL_SUFFIX_CURL_OFF_T)
+#define CURL_OFF_TU_C(Val) __CURL_OFF_T_C_HELPER1(Val,CURL_SUFFIX_CURL_OFF_TU)
+
+/*
+ * Get rid of macros private to this header file.
+ */
+
+#undef CurlchkszEQ
+#undef CurlchkszGE
+
+/*
+ * Get rid of macros not intended to exist beyond this point.
+ */
+
+#undef CURL_PULL_WS2TCPIP_H
+#undef CURL_PULL_SYS_TYPES_H
+#undef CURL_PULL_SYS_SOCKET_H
+#undef CURL_PULL_STDINT_H
+#undef CURL_PULL_INTTYPES_H
+
+#undef CURL_TYPEOF_CURL_SOCKLEN_T
+#undef CURL_TYPEOF_CURL_OFF_T
+
+#ifdef CURL_NO_OLDIES
+#undef CURL_FORMAT_OFF_T /* not required since 7.19.0 - obsoleted in 7.20.0 */
+#endif
+
+#endif /* __CURL_CURLRULES_H */
diff --git a/lib-x86-32/include/curl/curlver.h b/lib-x86-32/include/curl/curlver.h
new file mode 100644
index 00000000..e345f56d
--- /dev/null
+++ b/lib-x86-32/include/curl/curlver.h
@@ -0,0 +1,69 @@
+#ifndef __CURL_CURLVER_H
+#define __CURL_CURLVER_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/* This header file contains nothing but libcurl version info, generated by
+ a script at release-time. This was made its own header file in 7.11.2 */
+
+/* This is the global package copyright */
+#define LIBCURL_COPYRIGHT "1996 - 2010 Daniel Stenberg, <daniel@haxx.se>."
+
+/* This is the version number of the libcurl package from which this header
+ file origins: */
+#define LIBCURL_VERSION "7.21.2"
+
+/* The numeric version number is also available "in parts" by using these
+ defines: */
+#define LIBCURL_VERSION_MAJOR 7
+#define LIBCURL_VERSION_MINOR 21
+#define LIBCURL_VERSION_PATCH 2
+
+/* This is the numeric version of the libcurl version number, meant for easier
+ parsing and comparions by programs. The LIBCURL_VERSION_NUM define will
+ always follow this syntax:
+
+ 0xXXYYZZ
+
+ Where XX, YY and ZZ are the main version, release and patch numbers in
+ hexadecimal (using 8 bits each). All three numbers are always represented
+ using two digits. 1.2 would appear as "0x010200" while version 9.11.7
+ appears as "0x090b07".
+
+ This 6-digit (24 bits) hexadecimal number does not show pre-release number,
+ and it is always a greater number in a more recent release. It makes
+ comparisons with greater than and less than work.
+*/
+#define LIBCURL_VERSION_NUM 0x071502
+
+/*
+ * This is the date and time when the full source package was created. The
+ * timestamp is not stored in git, as the timestamp is properly set in the
+ * tarballs by the maketgz script.
+ *
+ * The format of the date should follow this template:
+ *
+ * "Mon Feb 12 11:35:33 UTC 2007"
+ */
+#define LIBCURL_TIMESTAMP "Tue Oct 12 22:03:31 UTC 2010"
+
+#endif /* __CURL_CURLVER_H */
diff --git a/lib-x86-32/include/curl/easy.h b/lib-x86-32/include/curl/easy.h
new file mode 100644
index 00000000..1ddb4fe5
--- /dev/null
+++ b/lib-x86-32/include/curl/easy.h
@@ -0,0 +1,102 @@
+#ifndef __CURL_EASY_H
+#define __CURL_EASY_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+CURL_EXTERN CURL *curl_easy_init(void);
+CURL_EXTERN CURLcode curl_easy_setopt(CURL *curl, CURLoption option, ...);
+CURL_EXTERN CURLcode curl_easy_perform(CURL *curl);
+CURL_EXTERN void curl_easy_cleanup(CURL *curl);
+
+/*
+ * NAME curl_easy_getinfo()
+ *
+ * DESCRIPTION
+ *
+ * Request internal information from the curl session with this function. The
+ * third argument MUST be a pointer to a long, a pointer to a char * or a
+ * pointer to a double (as the documentation describes elsewhere). The data
+ * pointed to will be filled in accordingly and can be relied upon only if the
+ * function returns CURLE_OK. This function is intended to get used *AFTER* a
+ * performed transfer, all results from this function are undefined until the
+ * transfer is completed.
+ */
+CURL_EXTERN CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...);
+
+
+/*
+ * NAME curl_easy_duphandle()
+ *
+ * DESCRIPTION
+ *
+ * Creates a new curl session handle with the same options set for the handle
+ * passed in. Duplicating a handle could only be a matter of cloning data and
+ * options, internal state info and things like persistant connections cannot
+ * be transfered. It is useful in multithreaded applications when you can run
+ * curl_easy_duphandle() for each new thread to avoid a series of identical
+ * curl_easy_setopt() invokes in every thread.
+ */
+CURL_EXTERN CURL* curl_easy_duphandle(CURL *curl);
+
+/*
+ * NAME curl_easy_reset()
+ *
+ * DESCRIPTION
+ *
+ * Re-initializes a CURL handle to the default values. This puts back the
+ * handle to the same state as it was in when it was just created.
+ *
+ * It does keep: live connections, the Session ID cache, the DNS cache and the
+ * cookies.
+ */
+CURL_EXTERN void curl_easy_reset(CURL *curl);
+
+/*
+ * NAME curl_easy_recv()
+ *
+ * DESCRIPTION
+ *
+ * Receives data from the connected socket. Use after successful
+ * curl_easy_perform() with CURLOPT_CONNECT_ONLY option.
+ */
+CURL_EXTERN CURLcode curl_easy_recv(CURL *curl, void *buffer, size_t buflen,
+ size_t *n);
+
+/*
+ * NAME curl_easy_send()
+ *
+ * DESCRIPTION
+ *
+ * Sends data over the connected socket. Use after successful
+ * curl_easy_perform() with CURLOPT_CONNECT_ONLY option.
+ */
+CURL_EXTERN CURLcode curl_easy_send(CURL *curl, const void *buffer,
+ size_t buflen, size_t *n);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib-x86-32/include/curl/mprintf.h b/lib-x86-32/include/curl/mprintf.h
new file mode 100644
index 00000000..de7dd2f3
--- /dev/null
+++ b/lib-x86-32/include/curl/mprintf.h
@@ -0,0 +1,81 @@
+#ifndef __CURL_MPRINTF_H
+#define __CURL_MPRINTF_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include <stdarg.h>
+#include <stdio.h> /* needed for FILE */
+
+#include "curl.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+CURL_EXTERN int curl_mprintf(const char *format, ...);
+CURL_EXTERN int curl_mfprintf(FILE *fd, const char *format, ...);
+CURL_EXTERN int curl_msprintf(char *buffer, const char *format, ...);
+CURL_EXTERN int curl_msnprintf(char *buffer, size_t maxlength,
+ const char *format, ...);
+CURL_EXTERN int curl_mvprintf(const char *format, va_list args);
+CURL_EXTERN int curl_mvfprintf(FILE *fd, const char *format, va_list args);
+CURL_EXTERN int curl_mvsprintf(char *buffer, const char *format, va_list args);
+CURL_EXTERN int curl_mvsnprintf(char *buffer, size_t maxlength,
+ const char *format, va_list args);
+CURL_EXTERN char *curl_maprintf(const char *format, ...);
+CURL_EXTERN char *curl_mvaprintf(const char *format, va_list args);
+
+#ifdef _MPRINTF_REPLACE
+# undef printf
+# undef fprintf
+# undef sprintf
+# undef vsprintf
+# undef snprintf
+# undef vprintf
+# undef vfprintf
+# undef vsnprintf
+# undef aprintf
+# undef vaprintf
+# define printf curl_mprintf
+# define fprintf curl_mfprintf
+#ifdef CURLDEBUG
+/* When built with CURLDEBUG we define away the sprintf() functions since we
+ don't want internal code to be using them */
+# define sprintf sprintf_was_used
+# define vsprintf vsprintf_was_used
+#else
+# define sprintf curl_msprintf
+# define vsprintf curl_mvsprintf
+#endif
+# define snprintf curl_msnprintf
+# define vprintf curl_mvprintf
+# define vfprintf curl_mvfprintf
+# define vsnprintf curl_mvsnprintf
+# define aprintf curl_maprintf
+# define vaprintf curl_mvaprintf
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CURL_MPRINTF_H */
diff --git a/lib-x86-32/include/curl/multi.h b/lib-x86-32/include/curl/multi.h
new file mode 100644
index 00000000..f9656666
--- /dev/null
+++ b/lib-x86-32/include/curl/multi.h
@@ -0,0 +1,345 @@
+#ifndef __CURL_MULTI_H
+#define __CURL_MULTI_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+/*
+ This is an "external" header file. Don't give away any internals here!
+
+ GOALS
+
+ o Enable a "pull" interface. The application that uses libcurl decides where
+ and when to ask libcurl to get/send data.
+
+ o Enable multiple simultaneous transfers in the same thread without making it
+ complicated for the application.
+
+ o Enable the application to select() on its own file descriptors and curl's
+ file descriptors simultaneous easily.
+
+*/
+
+/*
+ * This header file should not really need to include "curl.h" since curl.h
+ * itself includes this file and we expect user applications to do #include
+ * <curl/curl.h> without the need for especially including multi.h.
+ *
+ * For some reason we added this include here at one point, and rather than to
+ * break existing (wrongly written) libcurl applications, we leave it as-is
+ * but with this warning attached.
+ */
+#include "curl.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void CURLM;
+
+typedef enum {
+ CURLM_CALL_MULTI_PERFORM = -1, /* please call curl_multi_perform() or
+ curl_multi_socket*() soon */
+ CURLM_OK,
+ CURLM_BAD_HANDLE, /* the passed-in handle is not a valid CURLM handle */
+ CURLM_BAD_EASY_HANDLE, /* an easy handle was not good/valid */
+ CURLM_OUT_OF_MEMORY, /* if you ever get this, you're in deep sh*t */
+ CURLM_INTERNAL_ERROR, /* this is a libcurl bug */
+ CURLM_BAD_SOCKET, /* the passed in socket argument did not match */
+ CURLM_UNKNOWN_OPTION, /* curl_multi_setopt() with unsupported option */
+ CURLM_LAST
+} CURLMcode;
+
+/* just to make code nicer when using curl_multi_socket() you can now check
+ for CURLM_CALL_MULTI_SOCKET too in the same style it works for
+ curl_multi_perform() and CURLM_CALL_MULTI_PERFORM */
+#define CURLM_CALL_MULTI_SOCKET CURLM_CALL_MULTI_PERFORM
+
+typedef enum {
+ CURLMSG_NONE, /* first, not used */
+ CURLMSG_DONE, /* This easy handle has completed. 'result' contains
+ the CURLcode of the transfer */
+ CURLMSG_LAST /* last, not used */
+} CURLMSG;
+
+struct CURLMsg {
+ CURLMSG msg; /* what this message means */
+ CURL *easy_handle; /* the handle it concerns */
+ union {
+ void *whatever; /* message-specific data */
+ CURLcode result; /* return code for transfer */
+ } data;
+};
+typedef struct CURLMsg CURLMsg;
+
+/*
+ * Name: curl_multi_init()
+ *
+ * Desc: inititalize multi-style curl usage
+ *
+ * Returns: a new CURLM handle to use in all 'curl_multi' functions.
+ */
+CURL_EXTERN CURLM *curl_multi_init(void);
+
+/*
+ * Name: curl_multi_add_handle()
+ *
+ * Desc: add a standard curl handle to the multi stack
+ *
+ * Returns: CURLMcode type, general multi error code.
+ */
+CURL_EXTERN CURLMcode curl_multi_add_handle(CURLM *multi_handle,
+ CURL *curl_handle);
+
+ /*
+ * Name: curl_multi_remove_handle()
+ *
+ * Desc: removes a curl handle from the multi stack again
+ *
+ * Returns: CURLMcode type, general multi error code.
+ */
+CURL_EXTERN CURLMcode curl_multi_remove_handle(CURLM *multi_handle,
+ CURL *curl_handle);
+
+ /*
+ * Name: curl_multi_fdset()
+ *
+ * Desc: Ask curl for its fd_set sets. The app can use these to select() or
+ * poll() on. We want curl_multi_perform() called as soon as one of
+ * them are ready.
+ *
+ * Returns: CURLMcode type, general multi error code.
+ */
+CURL_EXTERN CURLMcode curl_multi_fdset(CURLM *multi_handle,
+ fd_set *read_fd_set,
+ fd_set *write_fd_set,
+ fd_set *exc_fd_set,
+ int *max_fd);
+
+ /*
+ * Name: curl_multi_perform()
+ *
+ * Desc: When the app thinks there's data available for curl it calls this
+ * function to read/write whatever there is right now. This returns
+ * as soon as the reads and writes are done. This function does not
+ * require that there actually is data available for reading or that
+ * data can be written, it can be called just in case. It returns
+ * the number of handles that still transfer data in the second
+ * argument's integer-pointer.
+ *
+ * Returns: CURLMcode type, general multi error code. *NOTE* that this only
+ * returns errors etc regarding the whole multi stack. There might
+ * still have occurred problems on invidual transfers even when this
+ * returns OK.
+ */
+CURL_EXTERN CURLMcode curl_multi_perform(CURLM *multi_handle,
+ int *running_handles);
+
+ /*
+ * Name: curl_multi_cleanup()
+ *
+ * Desc: Cleans up and removes a whole multi stack. It does not free or
+ * touch any individual easy handles in any way. We need to define
+ * in what state those handles will be if this function is called
+ * in the middle of a transfer.
+ *
+ * Returns: CURLMcode type, general multi error code.
+ */
+CURL_EXTERN CURLMcode curl_multi_cleanup(CURLM *multi_handle);
+
+/*
+ * Name: curl_multi_info_read()
+ *
+ * Desc: Ask the multi handle if there's any messages/informationals from
+ * the individual transfers. Messages include informationals such as
+ * error code from the transfer or just the fact that a transfer is
+ * completed. More details on these should be written down as well.
+ *
+ * Repeated calls to this function will return a new struct each
+ * time, until a special "end of msgs" struct is returned as a signal
+ * that there is no more to get at this point.
+ *
+ * The data the returned pointer points to will not survive calling
+ * curl_multi_cleanup().
+ *
+ * The 'CURLMsg' struct is meant to be very simple and only contain
+ * very basic informations. If more involved information is wanted,
+ * we will provide the particular "transfer handle" in that struct
+ * and that should/could/would be used in subsequent
+ * curl_easy_getinfo() calls (or similar). The point being that we
+ * must never expose complex structs to applications, as then we'll
+ * undoubtably get backwards compatibility problems in the future.
+ *
+ * Returns: A pointer to a filled-in struct, or NULL if it failed or ran out
+ * of structs. It also writes the number of messages left in the
+ * queue (after this read) in the integer the second argument points
+ * to.
+ */
+CURL_EXTERN CURLMsg *curl_multi_info_read(CURLM *multi_handle,
+ int *msgs_in_queue);
+
+/*
+ * Name: curl_multi_strerror()
+ *
+ * Desc: The curl_multi_strerror function may be used to turn a CURLMcode
+ * value into the equivalent human readable error string. This is
+ * useful for printing meaningful error messages.
+ *
+ * Returns: A pointer to a zero-terminated error message.
+ */
+CURL_EXTERN const char *curl_multi_strerror(CURLMcode);
+
+/*
+ * Name: curl_multi_socket() and
+ * curl_multi_socket_all()
+ *
+ * Desc: An alternative version of curl_multi_perform() that allows the
+ * application to pass in one of the file descriptors that have been
+ * detected to have "action" on them and let libcurl perform.
+ * See man page for details.
+ */
+#define CURL_POLL_NONE 0
+#define CURL_POLL_IN 1
+#define CURL_POLL_OUT 2
+#define CURL_POLL_INOUT 3
+#define CURL_POLL_REMOVE 4
+
+#define CURL_SOCKET_TIMEOUT CURL_SOCKET_BAD
+
+#define CURL_CSELECT_IN 0x01
+#define CURL_CSELECT_OUT 0x02
+#define CURL_CSELECT_ERR 0x04
+
+typedef int (*curl_socket_callback)(CURL *easy, /* easy handle */
+ curl_socket_t s, /* socket */
+ int what, /* see above */
+ void *userp, /* private callback
+ pointer */
+ void *socketp); /* private socket
+ pointer */
+/*
+ * Name: curl_multi_timer_callback
+ *
+ * Desc: Called by libcurl whenever the library detects a change in the
+ * maximum number of milliseconds the app is allowed to wait before
+ * curl_multi_socket() or curl_multi_perform() must be called
+ * (to allow libcurl's timed events to take place).
+ *
+ * Returns: The callback should return zero.
+ */
+typedef int (*curl_multi_timer_callback)(CURLM *multi, /* multi handle */
+ long timeout_ms, /* see above */
+ void *userp); /* private callback
+ pointer */
+
+CURL_EXTERN CURLMcode curl_multi_socket(CURLM *multi_handle, curl_socket_t s,
+ int *running_handles);
+
+CURL_EXTERN CURLMcode curl_multi_socket_action(CURLM *multi_handle,
+ curl_socket_t s,
+ int ev_bitmask,
+ int *running_handles);
+
+CURL_EXTERN CURLMcode curl_multi_socket_all(CURLM *multi_handle,
+ int *running_handles);
+
+#ifndef CURL_ALLOW_OLD_MULTI_SOCKET
+/* This macro below was added in 7.16.3 to push users who recompile to use
+ the new curl_multi_socket_action() instead of the old curl_multi_socket()
+*/
+#define curl_multi_socket(x,y,z) curl_multi_socket_action(x,y,0,z)
+#endif
+
+/*
+ * Name: curl_multi_timeout()
+ *
+ * Desc: Returns the maximum number of milliseconds the app is allowed to
+ * wait before curl_multi_socket() or curl_multi_perform() must be
+ * called (to allow libcurl's timed events to take place).
+ *
+ * Returns: CURLM error code.
+ */
+CURL_EXTERN CURLMcode curl_multi_timeout(CURLM *multi_handle,
+ long *milliseconds);
+
+#undef CINIT /* re-using the same name as in curl.h */
+
+#ifdef CURL_ISOCPP
+#define CINIT(name,type,num) CURLMOPT_ ## name = CURLOPTTYPE_ ## type + num
+#else
+/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */
+#define LONG CURLOPTTYPE_LONG
+#define OBJECTPOINT CURLOPTTYPE_OBJECTPOINT
+#define FUNCTIONPOINT CURLOPTTYPE_FUNCTIONPOINT
+#define OFF_T CURLOPTTYPE_OFF_T
+#define CINIT(name,type,number) CURLMOPT_/**/name = type + number
+#endif
+
+typedef enum {
+ /* This is the socket callback function pointer */
+ CINIT(SOCKETFUNCTION, FUNCTIONPOINT, 1),
+
+ /* This is the argument passed to the socket callback */
+ CINIT(SOCKETDATA, OBJECTPOINT, 2),
+
+ /* set to 1 to enable pipelining for this multi handle */
+ CINIT(PIPELINING, LONG, 3),
+
+ /* This is the timer callback function pointer */
+ CINIT(TIMERFUNCTION, FUNCTIONPOINT, 4),
+
+ /* This is the argument passed to the timer callback */
+ CINIT(TIMERDATA, OBJECTPOINT, 5),
+
+ /* maximum number of entries in the connection cache */
+ CINIT(MAXCONNECTS, LONG, 6),
+
+ CURLMOPT_LASTENTRY /* the last unused */
+} CURLMoption;
+
+
+/*
+ * Name: curl_multi_setopt()
+ *
+ * Desc: Sets options for the multi handle.
+ *
+ * Returns: CURLM error code.
+ */
+CURL_EXTERN CURLMcode curl_multi_setopt(CURLM *multi_handle,
+ CURLMoption option, ...);
+
+
+/*
+ * Name: curl_multi_assign()
+ *
+ * Desc: This function sets an association in the multi handle between the
+ * given socket and a private pointer of the application. This is
+ * (only) useful for curl_multi_socket uses.
+ *
+ * Returns: CURLM error code.
+ */
+CURL_EXTERN CURLMcode curl_multi_assign(CURLM *multi_handle,
+ curl_socket_t sockfd, void *sockp);
+
+#ifdef __cplusplus
+} /* end of extern "C" */
+#endif
+
+#endif
diff --git a/lib-x86-32/include/curl/stdcheaders.h b/lib-x86-32/include/curl/stdcheaders.h
new file mode 100644
index 00000000..ad82ef63
--- /dev/null
+++ b/lib-x86-32/include/curl/stdcheaders.h
@@ -0,0 +1,33 @@
+#ifndef __STDC_HEADERS_H
+#define __STDC_HEADERS_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include <sys/types.h>
+
+size_t fread (void *, size_t, size_t, FILE *);
+size_t fwrite (const void *, size_t, size_t, FILE *);
+
+int strcasecmp(const char *, const char *);
+int strncasecmp(const char *, const char *, size_t);
+
+#endif /* __STDC_HEADERS_H */
diff --git a/lib-x86-32/include/curl/typecheck-gcc.h b/lib-x86-32/include/curl/typecheck-gcc.h
new file mode 100644
index 00000000..e6f74a95
--- /dev/null
+++ b/lib-x86-32/include/curl/typecheck-gcc.h
@@ -0,0 +1,584 @@
+#ifndef __CURL_TYPECHECK_GCC_H
+#define __CURL_TYPECHECK_GCC_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/* wraps curl_easy_setopt() with typechecking */
+
+/* To add a new kind of warning, add an
+ * if(_curl_is_sometype_option(_curl_opt))
+ * if(!_curl_is_sometype(value))
+ * _curl_easy_setopt_err_sometype();
+ * block and define _curl_is_sometype_option, _curl_is_sometype and
+ * _curl_easy_setopt_err_sometype below
+ *
+ * NOTE: We use two nested 'if' statements here instead of the && operator, in
+ * order to work around gcc bug #32061. It affects only gcc 4.3.x/4.4.x
+ * when compiling with -Wlogical-op.
+ *
+ * To add an option that uses the same type as an existing option, you'll just
+ * need to extend the appropriate _curl_*_option macro
+ */
+#define curl_easy_setopt(handle, option, value) \
+__extension__ ({ \
+ __typeof__ (option) _curl_opt = option; \
+ if (__builtin_constant_p(_curl_opt)) { \
+ if (_curl_is_long_option(_curl_opt)) \
+ if (!_curl_is_long(value)) \
+ _curl_easy_setopt_err_long(); \
+ if (_curl_is_off_t_option(_curl_opt)) \
+ if (!_curl_is_off_t(value)) \
+ _curl_easy_setopt_err_curl_off_t(); \
+ if (_curl_is_string_option(_curl_opt)) \
+ if (!_curl_is_string(value)) \
+ _curl_easy_setopt_err_string(); \
+ if (_curl_is_write_cb_option(_curl_opt)) \
+ if (!_curl_is_write_cb(value)) \
+ _curl_easy_setopt_err_write_callback(); \
+ if ((_curl_opt) == CURLOPT_READFUNCTION) \
+ if (!_curl_is_read_cb(value)) \
+ _curl_easy_setopt_err_read_cb(); \
+ if ((_curl_opt) == CURLOPT_IOCTLFUNCTION) \
+ if (!_curl_is_ioctl_cb(value)) \
+ _curl_easy_setopt_err_ioctl_cb(); \
+ if ((_curl_opt) == CURLOPT_SOCKOPTFUNCTION) \
+ if (!_curl_is_sockopt_cb(value)) \
+ _curl_easy_setopt_err_sockopt_cb(); \
+ if ((_curl_opt) == CURLOPT_OPENSOCKETFUNCTION) \
+ if (!_curl_is_opensocket_cb(value)) \
+ _curl_easy_setopt_err_opensocket_cb(); \
+ if ((_curl_opt) == CURLOPT_PROGRESSFUNCTION) \
+ if (!_curl_is_progress_cb(value)) \
+ _curl_easy_setopt_err_progress_cb(); \
+ if ((_curl_opt) == CURLOPT_DEBUGFUNCTION) \
+ if (!_curl_is_debug_cb(value)) \
+ _curl_easy_setopt_err_debug_cb(); \
+ if ((_curl_opt) == CURLOPT_SSL_CTX_FUNCTION) \
+ if (!_curl_is_ssl_ctx_cb(value)) \
+ _curl_easy_setopt_err_ssl_ctx_cb(); \
+ if (_curl_is_conv_cb_option(_curl_opt)) \
+ if (!_curl_is_conv_cb(value)) \
+ _curl_easy_setopt_err_conv_cb(); \
+ if ((_curl_opt) == CURLOPT_SEEKFUNCTION) \
+ if (!_curl_is_seek_cb(value)) \
+ _curl_easy_setopt_err_seek_cb(); \
+ if (_curl_is_cb_data_option(_curl_opt)) \
+ if (!_curl_is_cb_data(value)) \
+ _curl_easy_setopt_err_cb_data(); \
+ if ((_curl_opt) == CURLOPT_ERRORBUFFER) \
+ if (!_curl_is_error_buffer(value)) \
+ _curl_easy_setopt_err_error_buffer(); \
+ if ((_curl_opt) == CURLOPT_STDERR) \
+ if (!_curl_is_FILE(value)) \
+ _curl_easy_setopt_err_FILE(); \
+ if (_curl_is_postfields_option(_curl_opt)) \
+ if (!_curl_is_postfields(value)) \
+ _curl_easy_setopt_err_postfields(); \
+ if ((_curl_opt) == CURLOPT_HTTPPOST) \
+ if (!_curl_is_arr((value), struct curl_httppost)) \
+ _curl_easy_setopt_err_curl_httpost(); \
+ if (_curl_is_slist_option(_curl_opt)) \
+ if (!_curl_is_arr((value), struct curl_slist)) \
+ _curl_easy_setopt_err_curl_slist(); \
+ if ((_curl_opt) == CURLOPT_SHARE) \
+ if (!_curl_is_ptr((value), CURLSH)) \
+ _curl_easy_setopt_err_CURLSH(); \
+ } \
+ curl_easy_setopt(handle, _curl_opt, value); \
+})
+
+/* wraps curl_easy_getinfo() with typechecking */
+/* FIXME: don't allow const pointers */
+#define curl_easy_getinfo(handle, info, arg) \
+__extension__ ({ \
+ __typeof__ (info) _curl_info = info; \
+ if (__builtin_constant_p(_curl_info)) { \
+ if (_curl_is_string_info(_curl_info)) \
+ if (!_curl_is_arr((arg), char *)) \
+ _curl_easy_getinfo_err_string(); \
+ if (_curl_is_long_info(_curl_info)) \
+ if (!_curl_is_arr((arg), long)) \
+ _curl_easy_getinfo_err_long(); \
+ if (_curl_is_double_info(_curl_info)) \
+ if (!_curl_is_arr((arg), double)) \
+ _curl_easy_getinfo_err_double(); \
+ if (_curl_is_slist_info(_curl_info)) \
+ if (!_curl_is_arr((arg), struct curl_slist *)) \
+ _curl_easy_getinfo_err_curl_slist(); \
+ } \
+ curl_easy_getinfo(handle, _curl_info, arg); \
+})
+
+/* TODO: typechecking for curl_share_setopt() and curl_multi_setopt(),
+ * for now just make sure that the functions are called with three
+ * arguments
+ */
+#define curl_share_setopt(share,opt,param) curl_share_setopt(share,opt,param)
+#define curl_multi_setopt(handle,opt,param) curl_multi_setopt(handle,opt,param)
+
+
+/* the actual warnings, triggered by calling the _curl_easy_setopt_err*
+ * functions */
+
+/* To define a new warning, use _CURL_WARNING(identifier, "message") */
+#define _CURL_WARNING(id, message) \
+ static void __attribute__((warning(message))) __attribute__((unused)) \
+ __attribute__((noinline)) id(void) { __asm__(""); }
+
+_CURL_WARNING(_curl_easy_setopt_err_long,
+ "curl_easy_setopt expects a long argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_curl_off_t,
+ "curl_easy_setopt expects a curl_off_t argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_string,
+ "curl_easy_setopt expects a string (char* or char[]) argument for this option"
+ )
+_CURL_WARNING(_curl_easy_setopt_err_write_callback,
+ "curl_easy_setopt expects a curl_write_callback argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_read_cb,
+ "curl_easy_setopt expects a curl_read_callback argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_ioctl_cb,
+ "curl_easy_setopt expects a curl_ioctl_callback argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_sockopt_cb,
+ "curl_easy_setopt expects a curl_sockopt_callback argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_opensocket_cb,
+ "curl_easy_setopt expects a curl_opensocket_callback argument for this option"
+ )
+_CURL_WARNING(_curl_easy_setopt_err_progress_cb,
+ "curl_easy_setopt expects a curl_progress_callback argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_debug_cb,
+ "curl_easy_setopt expects a curl_debug_callback argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_ssl_ctx_cb,
+ "curl_easy_setopt expects a curl_ssl_ctx_callback argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_conv_cb,
+ "curl_easy_setopt expects a curl_conv_callback argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_seek_cb,
+ "curl_easy_setopt expects a curl_seek_callback argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_cb_data,
+ "curl_easy_setopt expects a private data pointer as argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_error_buffer,
+ "curl_easy_setopt expects a char buffer of CURL_ERROR_SIZE as argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_FILE,
+ "curl_easy_setopt expects a FILE* argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_postfields,
+ "curl_easy_setopt expects a void* or char* argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_curl_httpost,
+ "curl_easy_setopt expects a struct curl_httppost* argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_curl_slist,
+ "curl_easy_setopt expects a struct curl_slist* argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_CURLSH,
+ "curl_easy_setopt expects a CURLSH* argument for this option")
+
+_CURL_WARNING(_curl_easy_getinfo_err_string,
+ "curl_easy_getinfo expects a pointer to char * for this info")
+_CURL_WARNING(_curl_easy_getinfo_err_long,
+ "curl_easy_getinfo expects a pointer to long for this info")
+_CURL_WARNING(_curl_easy_getinfo_err_double,
+ "curl_easy_getinfo expects a pointer to double for this info")
+_CURL_WARNING(_curl_easy_getinfo_err_curl_slist,
+ "curl_easy_getinfo expects a pointer to struct curl_slist * for this info")
+
+/* groups of curl_easy_setops options that take the same type of argument */
+
+/* To add a new option to one of the groups, just add
+ * (option) == CURLOPT_SOMETHING
+ * to the or-expression. If the option takes a long or curl_off_t, you don't
+ * have to do anything
+ */
+
+/* evaluates to true if option takes a long argument */
+#define _curl_is_long_option(option) \
+ (0 < (option) && (option) < CURLOPTTYPE_OBJECTPOINT)
+
+#define _curl_is_off_t_option(option) \
+ ((option) > CURLOPTTYPE_OFF_T)
+
+/* evaluates to true if option takes a char* argument */
+#define _curl_is_string_option(option) \
+ ((option) == CURLOPT_URL || \
+ (option) == CURLOPT_PROXY || \
+ (option) == CURLOPT_INTERFACE || \
+ (option) == CURLOPT_NETRC_FILE || \
+ (option) == CURLOPT_USERPWD || \
+ (option) == CURLOPT_USERNAME || \
+ (option) == CURLOPT_PASSWORD || \
+ (option) == CURLOPT_PROXYUSERPWD || \
+ (option) == CURLOPT_PROXYUSERNAME || \
+ (option) == CURLOPT_PROXYPASSWORD || \
+ (option) == CURLOPT_NOPROXY || \
+ (option) == CURLOPT_ENCODING || \
+ (option) == CURLOPT_REFERER || \
+ (option) == CURLOPT_USERAGENT || \
+ (option) == CURLOPT_COOKIE || \
+ (option) == CURLOPT_COOKIEFILE || \
+ (option) == CURLOPT_COOKIEJAR || \
+ (option) == CURLOPT_COOKIELIST || \
+ (option) == CURLOPT_FTPPORT || \
+ (option) == CURLOPT_FTP_ALTERNATIVE_TO_USER || \
+ (option) == CURLOPT_FTP_ACCOUNT || \
+ (option) == CURLOPT_RANGE || \
+ (option) == CURLOPT_CUSTOMREQUEST || \
+ (option) == CURLOPT_SSLCERT || \
+ (option) == CURLOPT_SSLCERTTYPE || \
+ (option) == CURLOPT_SSLKEY || \
+ (option) == CURLOPT_SSLKEYTYPE || \
+ (option) == CURLOPT_KEYPASSWD || \
+ (option) == CURLOPT_SSLENGINE || \
+ (option) == CURLOPT_CAINFO || \
+ (option) == CURLOPT_CAPATH || \
+ (option) == CURLOPT_RANDOM_FILE || \
+ (option) == CURLOPT_EGDSOCKET || \
+ (option) == CURLOPT_SSL_CIPHER_LIST || \
+ (option) == CURLOPT_KRBLEVEL || \
+ (option) == CURLOPT_SSH_HOST_PUBLIC_KEY_MD5 || \
+ (option) == CURLOPT_SSH_PUBLIC_KEYFILE || \
+ (option) == CURLOPT_SSH_PRIVATE_KEYFILE || \
+ (option) == CURLOPT_CRLFILE || \
+ (option) == CURLOPT_ISSUERCERT || \
+ (option) == CURLOPT_SOCKS5_GSSAPI_SERVICE || \
+ (option) == CURLOPT_SSH_KNOWNHOSTS || \
+ (option) == CURLOPT_MAIL_FROM || \
+ (option) == CURLOPT_RTSP_SESSION_ID || \
+ (option) == CURLOPT_RTSP_STREAM_URI || \
+ (option) == CURLOPT_RTSP_TRANSPORT || \
+ 0)
+
+/* evaluates to true if option takes a curl_write_callback argument */
+#define _curl_is_write_cb_option(option) \
+ ((option) == CURLOPT_HEADERFUNCTION || \
+ (option) == CURLOPT_WRITEFUNCTION)
+
+/* evaluates to true if option takes a curl_conv_callback argument */
+#define _curl_is_conv_cb_option(option) \
+ ((option) == CURLOPT_CONV_TO_NETWORK_FUNCTION || \
+ (option) == CURLOPT_CONV_FROM_NETWORK_FUNCTION || \
+ (option) == CURLOPT_CONV_FROM_UTF8_FUNCTION)
+
+/* evaluates to true if option takes a data argument to pass to a callback */
+#define _curl_is_cb_data_option(option) \
+ ((option) == CURLOPT_WRITEDATA || \
+ (option) == CURLOPT_READDATA || \
+ (option) == CURLOPT_IOCTLDATA || \
+ (option) == CURLOPT_SOCKOPTDATA || \
+ (option) == CURLOPT_OPENSOCKETDATA || \
+ (option) == CURLOPT_PROGRESSDATA || \
+ (option) == CURLOPT_WRITEHEADER || \
+ (option) == CURLOPT_DEBUGDATA || \
+ (option) == CURLOPT_SSL_CTX_DATA || \
+ (option) == CURLOPT_SEEKDATA || \
+ (option) == CURLOPT_PRIVATE || \
+ (option) == CURLOPT_SSH_KEYDATA || \
+ (option) == CURLOPT_INTERLEAVEDATA || \
+ (option) == CURLOPT_CHUNK_DATA || \
+ (option) == CURLOPT_FNMATCH_DATA || \
+ 0)
+
+/* evaluates to true if option takes a POST data argument (void* or char*) */
+#define _curl_is_postfields_option(option) \
+ ((option) == CURLOPT_POSTFIELDS || \
+ (option) == CURLOPT_COPYPOSTFIELDS || \
+ 0)
+
+/* evaluates to true if option takes a struct curl_slist * argument */
+#define _curl_is_slist_option(option) \
+ ((option) == CURLOPT_HTTPHEADER || \
+ (option) == CURLOPT_HTTP200ALIASES || \
+ (option) == CURLOPT_QUOTE || \
+ (option) == CURLOPT_POSTQUOTE || \
+ (option) == CURLOPT_PREQUOTE || \
+ (option) == CURLOPT_TELNETOPTIONS || \
+ (option) == CURLOPT_MAIL_RCPT || \
+ 0)
+
+/* groups of curl_easy_getinfo infos that take the same type of argument */
+
+/* evaluates to true if info expects a pointer to char * argument */
+#define _curl_is_string_info(info) \
+ (CURLINFO_STRING < (info) && (info) < CURLINFO_LONG)
+
+/* evaluates to true if info expects a pointer to long argument */
+#define _curl_is_long_info(info) \
+ (CURLINFO_LONG < (info) && (info) < CURLINFO_DOUBLE)
+
+/* evaluates to true if info expects a pointer to double argument */
+#define _curl_is_double_info(info) \
+ (CURLINFO_DOUBLE < (info) && (info) < CURLINFO_SLIST)
+
+/* true if info expects a pointer to struct curl_slist * argument */
+#define _curl_is_slist_info(info) \
+ (CURLINFO_SLIST < (info))
+
+
+/* typecheck helpers -- check whether given expression has requested type*/
+
+/* For pointers, you can use the _curl_is_ptr/_curl_is_arr macros,
+ * otherwise define a new macro. Search for __builtin_types_compatible_p
+ * in the GCC manual.
+ * NOTE: these macros MUST NOT EVALUATE their arguments! The argument is
+ * the actual expression passed to the curl_easy_setopt macro. This
+ * means that you can only apply the sizeof and __typeof__ operators, no
+ * == or whatsoever.
+ */
+
+/* XXX: should evaluate to true iff expr is a pointer */
+#define _curl_is_any_ptr(expr) \
+ (sizeof(expr) == sizeof(void*))
+
+/* evaluates to true if expr is NULL */
+/* XXX: must not evaluate expr, so this check is not accurate */
+#define _curl_is_NULL(expr) \
+ (__builtin_types_compatible_p(__typeof__(expr), __typeof__(NULL)))
+
+/* evaluates to true if expr is type*, const type* or NULL */
+#define _curl_is_ptr(expr, type) \
+ (_curl_is_NULL(expr) || \
+ __builtin_types_compatible_p(__typeof__(expr), type *) || \
+ __builtin_types_compatible_p(__typeof__(expr), const type *))
+
+/* evaluates to true if expr is one of type[], type*, NULL or const type* */
+#define _curl_is_arr(expr, type) \
+ (_curl_is_ptr((expr), type) || \
+ __builtin_types_compatible_p(__typeof__(expr), type []))
+
+/* evaluates to true if expr is a string */
+#define _curl_is_string(expr) \
+ (_curl_is_arr((expr), char) || \
+ _curl_is_arr((expr), signed char) || \
+ _curl_is_arr((expr), unsigned char))
+
+/* evaluates to true if expr is a long (no matter the signedness)
+ * XXX: for now, int is also accepted (and therefore short and char, which
+ * are promoted to int when passed to a variadic function) */
+#define _curl_is_long(expr) \
+ (__builtin_types_compatible_p(__typeof__(expr), long) || \
+ __builtin_types_compatible_p(__typeof__(expr), signed long) || \
+ __builtin_types_compatible_p(__typeof__(expr), unsigned long) || \
+ __builtin_types_compatible_p(__typeof__(expr), int) || \
+ __builtin_types_compatible_p(__typeof__(expr), signed int) || \
+ __builtin_types_compatible_p(__typeof__(expr), unsigned int) || \
+ __builtin_types_compatible_p(__typeof__(expr), short) || \
+ __builtin_types_compatible_p(__typeof__(expr), signed short) || \
+ __builtin_types_compatible_p(__typeof__(expr), unsigned short) || \
+ __builtin_types_compatible_p(__typeof__(expr), char) || \
+ __builtin_types_compatible_p(__typeof__(expr), signed char) || \
+ __builtin_types_compatible_p(__typeof__(expr), unsigned char))
+
+/* evaluates to true if expr is of type curl_off_t */
+#define _curl_is_off_t(expr) \
+ (__builtin_types_compatible_p(__typeof__(expr), curl_off_t))
+
+/* evaluates to true if expr is abuffer suitable for CURLOPT_ERRORBUFFER */
+/* XXX: also check size of an char[] array? */
+#define _curl_is_error_buffer(expr) \
+ (__builtin_types_compatible_p(__typeof__(expr), char *) || \
+ __builtin_types_compatible_p(__typeof__(expr), char[]))
+
+/* evaluates to true if expr is of type (const) void* or (const) FILE* */
+#if 0
+#define _curl_is_cb_data(expr) \
+ (_curl_is_ptr((expr), void) || \
+ _curl_is_ptr((expr), FILE))
+#else /* be less strict */
+#define _curl_is_cb_data(expr) \
+ _curl_is_any_ptr(expr)
+#endif
+
+/* evaluates to true if expr is of type FILE* */
+#define _curl_is_FILE(expr) \
+ (__builtin_types_compatible_p(__typeof__(expr), FILE *))
+
+/* evaluates to true if expr can be passed as POST data (void* or char*) */
+#define _curl_is_postfields(expr) \
+ (_curl_is_ptr((expr), void) || \
+ _curl_is_arr((expr), char))
+
+/* FIXME: the whole callback checking is messy...
+ * The idea is to tolerate char vs. void and const vs. not const
+ * pointers in arguments at least
+ */
+/* helper: __builtin_types_compatible_p distinguishes between functions and
+ * function pointers, hide it */
+#define _curl_callback_compatible(func, type) \
+ (__builtin_types_compatible_p(__typeof__(func), type) || \
+ __builtin_types_compatible_p(__typeof__(func), type*))
+
+/* evaluates to true if expr is of type curl_read_callback or "similar" */
+#define _curl_is_read_cb(expr) \
+ (_curl_is_NULL(expr) || \
+ __builtin_types_compatible_p(__typeof__(expr), __typeof__(fread)) || \
+ __builtin_types_compatible_p(__typeof__(expr), curl_read_callback) || \
+ _curl_callback_compatible((expr), _curl_read_callback1) || \
+ _curl_callback_compatible((expr), _curl_read_callback2) || \
+ _curl_callback_compatible((expr), _curl_read_callback3) || \
+ _curl_callback_compatible((expr), _curl_read_callback4) || \
+ _curl_callback_compatible((expr), _curl_read_callback5) || \
+ _curl_callback_compatible((expr), _curl_read_callback6))
+typedef size_t (_curl_read_callback1)(char *, size_t, size_t, void*);
+typedef size_t (_curl_read_callback2)(char *, size_t, size_t, const void*);
+typedef size_t (_curl_read_callback3)(char *, size_t, size_t, FILE*);
+typedef size_t (_curl_read_callback4)(void *, size_t, size_t, void*);
+typedef size_t (_curl_read_callback5)(void *, size_t, size_t, const void*);
+typedef size_t (_curl_read_callback6)(void *, size_t, size_t, FILE*);
+
+/* evaluates to true if expr is of type curl_write_callback or "similar" */
+#define _curl_is_write_cb(expr) \
+ (_curl_is_read_cb(expr) || \
+ __builtin_types_compatible_p(__typeof__(expr), __typeof__(fwrite)) || \
+ __builtin_types_compatible_p(__typeof__(expr), curl_write_callback) || \
+ _curl_callback_compatible((expr), _curl_write_callback1) || \
+ _curl_callback_compatible((expr), _curl_write_callback2) || \
+ _curl_callback_compatible((expr), _curl_write_callback3) || \
+ _curl_callback_compatible((expr), _curl_write_callback4) || \
+ _curl_callback_compatible((expr), _curl_write_callback5) || \
+ _curl_callback_compatible((expr), _curl_write_callback6))
+typedef size_t (_curl_write_callback1)(const char *, size_t, size_t, void*);
+typedef size_t (_curl_write_callback2)(const char *, size_t, size_t,
+ const void*);
+typedef size_t (_curl_write_callback3)(const char *, size_t, size_t, FILE*);
+typedef size_t (_curl_write_callback4)(const void *, size_t, size_t, void*);
+typedef size_t (_curl_write_callback5)(const void *, size_t, size_t,
+ const void*);
+typedef size_t (_curl_write_callback6)(const void *, size_t, size_t, FILE*);
+
+/* evaluates to true if expr is of type curl_ioctl_callback or "similar" */
+#define _curl_is_ioctl_cb(expr) \
+ (_curl_is_NULL(expr) || \
+ __builtin_types_compatible_p(__typeof__(expr), curl_ioctl_callback) || \
+ _curl_callback_compatible((expr), _curl_ioctl_callback1) || \
+ _curl_callback_compatible((expr), _curl_ioctl_callback2) || \
+ _curl_callback_compatible((expr), _curl_ioctl_callback3) || \
+ _curl_callback_compatible((expr), _curl_ioctl_callback4))
+typedef curlioerr (_curl_ioctl_callback1)(CURL *, int, void*);
+typedef curlioerr (_curl_ioctl_callback2)(CURL *, int, const void*);
+typedef curlioerr (_curl_ioctl_callback3)(CURL *, curliocmd, void*);
+typedef curlioerr (_curl_ioctl_callback4)(CURL *, curliocmd, const void*);
+
+/* evaluates to true if expr is of type curl_sockopt_callback or "similar" */
+#define _curl_is_sockopt_cb(expr) \
+ (_curl_is_NULL(expr) || \
+ __builtin_types_compatible_p(__typeof__(expr), curl_sockopt_callback) || \
+ _curl_callback_compatible((expr), _curl_sockopt_callback1) || \
+ _curl_callback_compatible((expr), _curl_sockopt_callback2))
+typedef int (_curl_sockopt_callback1)(void *, curl_socket_t, curlsocktype);
+typedef int (_curl_sockopt_callback2)(const void *, curl_socket_t,
+ curlsocktype);
+
+/* evaluates to true if expr is of type curl_opensocket_callback or "similar" */
+#define _curl_is_opensocket_cb(expr) \
+ (_curl_is_NULL(expr) || \
+ __builtin_types_compatible_p(__typeof__(expr), curl_opensocket_callback) ||\
+ _curl_callback_compatible((expr), _curl_opensocket_callback1) || \
+ _curl_callback_compatible((expr), _curl_opensocket_callback2) || \
+ _curl_callback_compatible((expr), _curl_opensocket_callback3) || \
+ _curl_callback_compatible((expr), _curl_opensocket_callback4))
+typedef curl_socket_t (_curl_opensocket_callback1)
+ (void *, curlsocktype, struct curl_sockaddr *);
+typedef curl_socket_t (_curl_opensocket_callback2)
+ (void *, curlsocktype, const struct curl_sockaddr *);
+typedef curl_socket_t (_curl_opensocket_callback3)
+ (const void *, curlsocktype, struct curl_sockaddr *);
+typedef curl_socket_t (_curl_opensocket_callback4)
+ (const void *, curlsocktype, const struct curl_sockaddr *);
+
+/* evaluates to true if expr is of type curl_progress_callback or "similar" */
+#define _curl_is_progress_cb(expr) \
+ (_curl_is_NULL(expr) || \
+ __builtin_types_compatible_p(__typeof__(expr), curl_progress_callback) || \
+ _curl_callback_compatible((expr), _curl_progress_callback1) || \
+ _curl_callback_compatible((expr), _curl_progress_callback2))
+typedef int (_curl_progress_callback1)(void *,
+ double, double, double, double);
+typedef int (_curl_progress_callback2)(const void *,
+ double, double, double, double);
+
+/* evaluates to true if expr is of type curl_debug_callback or "similar" */
+#define _curl_is_debug_cb(expr) \
+ (_curl_is_NULL(expr) || \
+ __builtin_types_compatible_p(__typeof__(expr), curl_debug_callback) || \
+ _curl_callback_compatible((expr), _curl_debug_callback1) || \
+ _curl_callback_compatible((expr), _curl_debug_callback2) || \
+ _curl_callback_compatible((expr), _curl_debug_callback3) || \
+ _curl_callback_compatible((expr), _curl_debug_callback4))
+typedef int (_curl_debug_callback1) (CURL *,
+ curl_infotype, char *, size_t, void *);
+typedef int (_curl_debug_callback2) (CURL *,
+ curl_infotype, char *, size_t, const void *);
+typedef int (_curl_debug_callback3) (CURL *,
+ curl_infotype, const char *, size_t, void *);
+typedef int (_curl_debug_callback4) (CURL *,
+ curl_infotype, const char *, size_t, const void *);
+
+/* evaluates to true if expr is of type curl_ssl_ctx_callback or "similar" */
+/* this is getting even messier... */
+#define _curl_is_ssl_ctx_cb(expr) \
+ (_curl_is_NULL(expr) || \
+ __builtin_types_compatible_p(__typeof__(expr), curl_ssl_ctx_callback) || \
+ _curl_callback_compatible((expr), _curl_ssl_ctx_callback1) || \
+ _curl_callback_compatible((expr), _curl_ssl_ctx_callback2) || \
+ _curl_callback_compatible((expr), _curl_ssl_ctx_callback3) || \
+ _curl_callback_compatible((expr), _curl_ssl_ctx_callback4) || \
+ _curl_callback_compatible((expr), _curl_ssl_ctx_callback5) || \
+ _curl_callback_compatible((expr), _curl_ssl_ctx_callback6) || \
+ _curl_callback_compatible((expr), _curl_ssl_ctx_callback7) || \
+ _curl_callback_compatible((expr), _curl_ssl_ctx_callback8))
+typedef CURLcode (_curl_ssl_ctx_callback1)(CURL *, void *, void *);
+typedef CURLcode (_curl_ssl_ctx_callback2)(CURL *, void *, const void *);
+typedef CURLcode (_curl_ssl_ctx_callback3)(CURL *, const void *, void *);
+typedef CURLcode (_curl_ssl_ctx_callback4)(CURL *, const void *, const void *);
+#ifdef HEADER_SSL_H
+/* hack: if we included OpenSSL's ssl.h, we know about SSL_CTX
+ * this will of course break if we're included before OpenSSL headers...
+ */
+typedef CURLcode (_curl_ssl_ctx_callback5)(CURL *, SSL_CTX, void *);
+typedef CURLcode (_curl_ssl_ctx_callback6)(CURL *, SSL_CTX, const void *);
+typedef CURLcode (_curl_ssl_ctx_callback7)(CURL *, const SSL_CTX, void *);
+typedef CURLcode (_curl_ssl_ctx_callback8)(CURL *, const SSL_CTX, const void *);
+#else
+typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback5;
+typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback6;
+typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback7;
+typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback8;
+#endif
+
+/* evaluates to true if expr is of type curl_conv_callback or "similar" */
+#define _curl_is_conv_cb(expr) \
+ (_curl_is_NULL(expr) || \
+ __builtin_types_compatible_p(__typeof__(expr), curl_conv_callback) || \
+ _curl_callback_compatible((expr), _curl_conv_callback1) || \
+ _curl_callback_compatible((expr), _curl_conv_callback2) || \
+ _curl_callback_compatible((expr), _curl_conv_callback3) || \
+ _curl_callback_compatible((expr), _curl_conv_callback4))
+typedef CURLcode (*_curl_conv_callback1)(char *, size_t length);
+typedef CURLcode (*_curl_conv_callback2)(const char *, size_t length);
+typedef CURLcode (*_curl_conv_callback3)(void *, size_t length);
+typedef CURLcode (*_curl_conv_callback4)(const void *, size_t length);
+
+/* evaluates to true if expr is of type curl_seek_callback or "similar" */
+#define _curl_is_seek_cb(expr) \
+ (_curl_is_NULL(expr) || \
+ __builtin_types_compatible_p(__typeof__(expr), curl_seek_callback) || \
+ _curl_callback_compatible((expr), _curl_seek_callback1) || \
+ _curl_callback_compatible((expr), _curl_seek_callback2))
+typedef CURLcode (*_curl_seek_callback1)(void *, curl_off_t, int);
+typedef CURLcode (*_curl_seek_callback2)(const void *, curl_off_t, int);
+
+
+#endif /* __CURL_TYPECHECK_GCC_H */
diff --git a/lib-x86-32/include/curl/types.h b/lib-x86-32/include/curl/types.h
new file mode 100644
index 00000000..d37d6ae9
--- /dev/null
+++ b/lib-x86-32/include/curl/types.h
@@ -0,0 +1 @@
+/* not used */
diff --git a/lib-x86-32/include/dbus-1/dbus/dbus-address.h b/lib-x86-32/include/dbus-1/dbus/dbus-address.h
new file mode 100644
index 00000000..e51ef0ae
--- /dev/null
+++ b/lib-x86-32/include/dbus-1/dbus/dbus-address.h
@@ -0,0 +1,67 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-address.h Server address parser.
+ *
+ * Copyright (C) 2003 CodeFactory AB
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+#if !defined (DBUS_INSIDE_DBUS_H) && !defined (DBUS_COMPILATION)
+#error "Only <dbus/dbus.h> can be included directly, this file may disappear or change contents."
+#endif
+
+#ifndef DBUS_ADDRESS_H
+#define DBUS_ADDRESS_H
+
+#include <dbus/dbus-types.h>
+#include <dbus/dbus-errors.h>
+
+DBUS_BEGIN_DECLS
+
+/**
+ * @addtogroup DBusAddress
+ * @{
+ */
+
+/** Opaque type representing one of the semicolon-separated items in an address */
+typedef struct DBusAddressEntry DBusAddressEntry;
+
+DBUS_EXPORT
+dbus_bool_t dbus_parse_address (const char *address,
+ DBusAddressEntry ***entry,
+ int *array_len,
+ DBusError *error);
+DBUS_EXPORT
+const char *dbus_address_entry_get_value (DBusAddressEntry *entry,
+ const char *key);
+DBUS_EXPORT
+const char *dbus_address_entry_get_method (DBusAddressEntry *entry);
+DBUS_EXPORT
+void dbus_address_entries_free (DBusAddressEntry **entries);
+
+DBUS_EXPORT
+char* dbus_address_escape_value (const char *value);
+DBUS_EXPORT
+char* dbus_address_unescape_value (const char *value,
+ DBusError *error);
+
+/** @} */
+
+DBUS_END_DECLS
+
+#endif /* DBUS_ADDRESS_H */
+
diff --git a/lib-x86-32/include/dbus-1/dbus/dbus-arch-deps.h b/lib-x86-32/include/dbus-1/dbus/dbus-arch-deps.h
new file mode 100644
index 00000000..c8359c8c
--- /dev/null
+++ b/lib-x86-32/include/dbus-1/dbus/dbus-arch-deps.h
@@ -0,0 +1,67 @@
+/* -*- mode: C; c-file-style: "gnu" -*- */
+/* dbus-arch-deps.h Header with architecture/compiler specific information, installed to libdir
+ *
+ * Copyright (C) 2003 Red Hat, Inc.
+ *
+ * Licensed under the Academic Free License version 2.0
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+#if !defined (DBUS_INSIDE_DBUS_H) && !defined (DBUS_COMPILATION)
+#error "Only <dbus/dbus.h> can be included directly, this file may disappear or change contents."
+#endif
+
+#ifndef DBUS_ARCH_DEPS_H
+#define DBUS_ARCH_DEPS_H
+
+#include <dbus/dbus-macros.h>
+
+DBUS_BEGIN_DECLS
+
+#if 1
+#define DBUS_HAVE_INT64 1
+_DBUS_GNUC_EXTENSION typedef long long dbus_int64_t;
+_DBUS_GNUC_EXTENSION typedef unsigned long long dbus_uint64_t;
+
+#define DBUS_INT64_CONSTANT(val) (_DBUS_GNUC_EXTENSION (val##LL))
+#define DBUS_UINT64_CONSTANT(val) (_DBUS_GNUC_EXTENSION (val##ULL))
+
+#else
+#undef DBUS_HAVE_INT64
+#undef DBUS_INT64_CONSTANT
+#undef DBUS_UINT64_CONSTANT
+#endif
+
+typedef int dbus_int32_t;
+typedef unsigned int dbus_uint32_t;
+
+typedef short dbus_int16_t;
+typedef unsigned short dbus_uint16_t;
+
+/* This is not really arch-dependent, but it's not worth
+ * creating an additional generated header just for this
+ */
+#define DBUS_MAJOR_VERSION 1
+#define DBUS_MINOR_VERSION 4
+#define DBUS_MICRO_VERSION 0
+
+#define DBUS_VERSION_STRING "1.4.0"
+
+#define DBUS_VERSION ((1 << 16) | (4 << 8) | (0))
+
+DBUS_END_DECLS
+
+#endif /* DBUS_ARCH_DEPS_H */
diff --git a/lib-x86-32/include/dbus-1/dbus/dbus-auth-script.h b/lib-x86-32/include/dbus-1/dbus/dbus-auth-script.h
new file mode 100644
index 00000000..39e6c7c4
--- /dev/null
+++ b/lib-x86-32/include/dbus-1/dbus/dbus-auth-script.h
@@ -0,0 +1,37 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-auth-script.h Test DBusAuth using a special script file (internal to D-Bus implementation)
+ *
+ * Copyright (C) 2003 Red Hat, Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef DBUS_AUTH_SCRIPT_H
+#define DBUS_AUTH_SCRIPT_H
+
+#include <dbus/dbus-memory.h>
+#include <dbus/dbus-types.h>
+#include <dbus/dbus-string.h>
+
+DBUS_BEGIN_DECLS
+
+dbus_bool_t _dbus_auth_script_run (const DBusString *filename);
+
+DBUS_END_DECLS
+
+#endif /* DBUS_AUTH_SCRIPT_H */
diff --git a/lib-x86-32/include/dbus-1/dbus/dbus-auth.h b/lib-x86-32/include/dbus-1/dbus/dbus-auth.h
new file mode 100644
index 00000000..ae3f3647
--- /dev/null
+++ b/lib-x86-32/include/dbus-1/dbus/dbus-auth.h
@@ -0,0 +1,83 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-auth.h Authentication
+ *
+ * Copyright (C) 2002 Red Hat Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+#ifndef DBUS_AUTH_H
+#define DBUS_AUTH_H
+
+#include <dbus/dbus-macros.h>
+#include <dbus/dbus-errors.h>
+#include <dbus/dbus-string.h>
+#include <dbus/dbus-sysdeps.h>
+
+DBUS_BEGIN_DECLS
+
+typedef struct DBusAuth DBusAuth;
+
+typedef enum
+{
+ DBUS_AUTH_STATE_WAITING_FOR_INPUT,
+ DBUS_AUTH_STATE_WAITING_FOR_MEMORY,
+ DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND,
+ DBUS_AUTH_STATE_NEED_DISCONNECT,
+ DBUS_AUTH_STATE_AUTHENTICATED
+} DBusAuthState;
+
+DBusAuth* _dbus_auth_server_new (const DBusString *guid);
+DBusAuth* _dbus_auth_client_new (void);
+DBusAuth* _dbus_auth_ref (DBusAuth *auth);
+void _dbus_auth_unref (DBusAuth *auth);
+dbus_bool_t _dbus_auth_set_mechanisms (DBusAuth *auth,
+ const char **mechanisms);
+DBusAuthState _dbus_auth_do_work (DBusAuth *auth);
+dbus_bool_t _dbus_auth_get_bytes_to_send (DBusAuth *auth,
+ const DBusString **str);
+void _dbus_auth_bytes_sent (DBusAuth *auth,
+ int bytes_sent);
+void _dbus_auth_get_buffer (DBusAuth *auth,
+ DBusString **buffer);
+void _dbus_auth_return_buffer (DBusAuth *auth,
+ DBusString *buffer,
+ int bytes_read);
+void _dbus_auth_get_unused_bytes (DBusAuth *auth,
+ const DBusString **str);
+void _dbus_auth_delete_unused_bytes (DBusAuth *auth);
+dbus_bool_t _dbus_auth_needs_encoding (DBusAuth *auth);
+dbus_bool_t _dbus_auth_encode_data (DBusAuth *auth,
+ const DBusString *plaintext,
+ DBusString *encoded);
+dbus_bool_t _dbus_auth_needs_decoding (DBusAuth *auth);
+dbus_bool_t _dbus_auth_decode_data (DBusAuth *auth,
+ const DBusString *encoded,
+ DBusString *plaintext);
+dbus_bool_t _dbus_auth_set_credentials (DBusAuth *auth,
+ DBusCredentials *credentials);
+DBusCredentials* _dbus_auth_get_identity (DBusAuth *auth);
+dbus_bool_t _dbus_auth_set_context (DBusAuth *auth,
+ const DBusString *context);
+const char* _dbus_auth_get_guid_from_server(DBusAuth *auth);
+
+void _dbus_auth_set_unix_fd_possible(DBusAuth *auth, dbus_bool_t b);
+dbus_bool_t _dbus_auth_get_unix_fd_negotiated(DBusAuth *auth);
+
+DBUS_END_DECLS
+
+#endif /* DBUS_AUTH_H */
diff --git a/lib-x86-32/include/dbus-1/dbus/dbus-bus.h b/lib-x86-32/include/dbus-1/dbus/dbus-bus.h
new file mode 100644
index 00000000..02a95711
--- /dev/null
+++ b/lib-x86-32/include/dbus-1/dbus/dbus-bus.h
@@ -0,0 +1,95 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-bus.h Convenience functions for communicating with the bus.
+ *
+ * Copyright (C) 2003 CodeFactory AB
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+#if !defined (DBUS_INSIDE_DBUS_H) && !defined (DBUS_COMPILATION)
+#error "Only <dbus/dbus.h> can be included directly, this file may disappear or change contents."
+#endif
+
+#ifndef DBUS_BUS_H
+#define DBUS_BUS_H
+
+#include <dbus/dbus-connection.h>
+
+DBUS_BEGIN_DECLS
+
+/**
+ * @addtogroup DBusBus
+ * @{
+ */
+
+DBUS_EXPORT
+DBusConnection *dbus_bus_get (DBusBusType type,
+ DBusError *error);
+DBUS_EXPORT
+DBusConnection *dbus_bus_get_private (DBusBusType type,
+ DBusError *error);
+
+DBUS_EXPORT
+dbus_bool_t dbus_bus_register (DBusConnection *connection,
+ DBusError *error);
+DBUS_EXPORT
+dbus_bool_t dbus_bus_set_unique_name (DBusConnection *connection,
+ const char *unique_name);
+DBUS_EXPORT
+const char* dbus_bus_get_unique_name (DBusConnection *connection);
+DBUS_EXPORT
+unsigned long dbus_bus_get_unix_user (DBusConnection *connection,
+ const char *name,
+ DBusError *error);
+DBUS_EXPORT
+char* dbus_bus_get_id (DBusConnection *connection,
+ DBusError *error);
+DBUS_EXPORT
+int dbus_bus_request_name (DBusConnection *connection,
+ const char *name,
+ unsigned int flags,
+ DBusError *error);
+DBUS_EXPORT
+int dbus_bus_release_name (DBusConnection *connection,
+ const char *name,
+ DBusError *error);
+DBUS_EXPORT
+dbus_bool_t dbus_bus_name_has_owner (DBusConnection *connection,
+ const char *name,
+ DBusError *error);
+
+DBUS_EXPORT
+dbus_bool_t dbus_bus_start_service_by_name (DBusConnection *connection,
+ const char *name,
+ dbus_uint32_t flags,
+ dbus_uint32_t *reply,
+ DBusError *error);
+
+DBUS_EXPORT
+void dbus_bus_add_match (DBusConnection *connection,
+ const char *rule,
+ DBusError *error);
+DBUS_EXPORT
+void dbus_bus_remove_match (DBusConnection *connection,
+ const char *rule,
+ DBusError *error);
+
+/** @} */
+
+DBUS_END_DECLS
+
+#endif /* DBUS_BUS_H */
diff --git a/lib-x86-32/include/dbus-1/dbus/dbus-connection-internal.h b/lib-x86-32/include/dbus-1/dbus/dbus-connection-internal.h
new file mode 100644
index 00000000..cdf3f59d
--- /dev/null
+++ b/lib-x86-32/include/dbus-1/dbus/dbus-connection-internal.h
@@ -0,0 +1,121 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-connection-internal.h DBusConnection internal interfaces
+ *
+ * Copyright (C) 2002 Red Hat Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+#ifndef DBUS_CONNECTION_INTERNAL_H
+#define DBUS_CONNECTION_INTERNAL_H
+
+#include <dbus/dbus-internals.h>
+#include <dbus/dbus-connection.h>
+#include <dbus/dbus-message.h>
+#include <dbus/dbus-transport.h>
+#include <dbus/dbus-resources.h>
+#include <dbus/dbus-list.h>
+#include <dbus/dbus-timeout.h>
+#include <dbus/dbus-dataslot.h>
+
+DBUS_BEGIN_DECLS
+
+typedef enum
+{
+ DBUS_ITERATION_DO_WRITING = 1 << 0, /**< Write messages out. */
+ DBUS_ITERATION_DO_READING = 1 << 1, /**< Read messages in. */
+ DBUS_ITERATION_BLOCK = 1 << 2 /**< Block if nothing to do. */
+} DBusIterationFlags;
+
+/** default timeout value when waiting for a message reply, 25 seconds */
+#define _DBUS_DEFAULT_TIMEOUT_VALUE (25 * 1000)
+
+void _dbus_connection_lock (DBusConnection *connection);
+void _dbus_connection_unlock (DBusConnection *connection);
+DBusConnection * _dbus_connection_ref_unlocked (DBusConnection *connection);
+void _dbus_connection_unref_unlocked (DBusConnection *connection);
+dbus_bool_t _dbus_connection_queue_received_message (DBusConnection *connection,
+ DBusMessage *message);
+void _dbus_connection_queue_received_message_link (DBusConnection *connection,
+ DBusList *link);
+dbus_bool_t _dbus_connection_has_messages_to_send_unlocked (DBusConnection *connection);
+DBusMessage* _dbus_connection_get_message_to_send (DBusConnection *connection);
+void _dbus_connection_message_sent (DBusConnection *connection,
+ DBusMessage *message);
+dbus_bool_t _dbus_connection_add_watch_unlocked (DBusConnection *connection,
+ DBusWatch *watch);
+void _dbus_connection_remove_watch_unlocked (DBusConnection *connection,
+ DBusWatch *watch);
+void _dbus_connection_toggle_watch_unlocked (DBusConnection *connection,
+ DBusWatch *watch,
+ dbus_bool_t enabled);
+dbus_bool_t _dbus_connection_handle_watch (DBusWatch *watch,
+ unsigned int condition,
+ void *data);
+dbus_bool_t _dbus_connection_add_timeout_unlocked (DBusConnection *connection,
+ DBusTimeout *timeout);
+void _dbus_connection_remove_timeout_unlocked (DBusConnection *connection,
+ DBusTimeout *timeout);
+void _dbus_connection_toggle_timeout_unlocked (DBusConnection *connection,
+ DBusTimeout *timeout,
+ dbus_bool_t enabled);
+DBusConnection* _dbus_connection_new_for_transport (DBusTransport *transport);
+void _dbus_connection_do_iteration_unlocked (DBusConnection *connection,
+ DBusPendingCall *pending,
+ unsigned int flags,
+ int timeout_milliseconds);
+void _dbus_connection_close_possibly_shared (DBusConnection *connection);
+void _dbus_connection_close_if_only_one_ref (DBusConnection *connection);
+
+DBusPendingCall* _dbus_pending_call_new (DBusConnection *connection,
+ int timeout_milliseconds,
+ DBusTimeoutHandler timeout_handler);
+void _dbus_pending_call_notify (DBusPendingCall *pending);
+void _dbus_connection_remove_pending_call (DBusConnection *connection,
+ DBusPendingCall *pending);
+void _dbus_connection_block_pending_call (DBusPendingCall *pending);
+void _dbus_pending_call_complete_and_unlock (DBusPendingCall *pending,
+ DBusMessage *message);
+dbus_bool_t _dbus_connection_send_and_unlock (DBusConnection *connection,
+ DBusMessage *message,
+ dbus_uint32_t *client_serial);
+
+void _dbus_connection_queue_synthesized_message_link (DBusConnection *connection,
+ DBusList *link);
+void _dbus_connection_test_get_locks (DBusConnection *conn,
+ DBusMutex **mutex_loc,
+ DBusMutex **dispatch_mutex_loc,
+ DBusMutex **io_path_mutex_loc,
+ DBusCondVar **dispatch_cond_loc,
+ DBusCondVar **io_path_cond_loc);
+
+/* This _dbus_bus_* stuff doesn't really belong here, but dbus-bus-internal.h seems
+ * silly for one function
+ */
+/**
+ * @addtogroup DBusBusInternals
+ * @{
+ */
+
+void _dbus_bus_notify_shared_connection_disconnected_unlocked (DBusConnection *connection);
+
+/** @} */
+
+
+DBUS_END_DECLS
+
+#endif /* DBUS_CONNECTION_INTERNAL_H */
diff --git a/lib-x86-32/include/dbus-1/dbus/dbus-connection.h b/lib-x86-32/include/dbus-1/dbus/dbus-connection.h
new file mode 100644
index 00000000..3e2a7d8d
--- /dev/null
+++ b/lib-x86-32/include/dbus-1/dbus/dbus-connection.h
@@ -0,0 +1,495 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-connection.h DBusConnection object
+ *
+ * Copyright (C) 2002, 2003 Red Hat Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+#if !defined (DBUS_INSIDE_DBUS_H) && !defined (DBUS_COMPILATION)
+#error "Only <dbus/dbus.h> can be included directly, this file may disappear or change contents."
+#endif
+
+#ifndef DBUS_CONNECTION_H
+#define DBUS_CONNECTION_H
+
+#include <dbus/dbus-errors.h>
+#include <dbus/dbus-memory.h>
+#include <dbus/dbus-message.h>
+#include <dbus/dbus-shared.h>
+
+DBUS_BEGIN_DECLS
+
+/**
+ * @addtogroup DBusConnection
+ * @{
+ */
+
+/* documented in dbus-watch.c */
+typedef struct DBusWatch DBusWatch;
+/* documented in dbus-timeout.c */
+typedef struct DBusTimeout DBusTimeout;
+/** Opaque type representing preallocated resources so a message can be sent without further memory allocation. */
+typedef struct DBusPreallocatedSend DBusPreallocatedSend;
+/** Opaque type representing a method call that has not yet received a reply. */
+typedef struct DBusPendingCall DBusPendingCall;
+/** Opaque type representing a connection to a remote application and associated incoming/outgoing message queues. */
+typedef struct DBusConnection DBusConnection;
+/** Set of functions that must be implemented to handle messages sent to a particular object path. */
+typedef struct DBusObjectPathVTable DBusObjectPathVTable;
+
+/**
+ * Indicates the status of a #DBusWatch.
+ */
+typedef enum
+{
+ DBUS_WATCH_READABLE = 1 << 0, /**< As in POLLIN */
+ DBUS_WATCH_WRITABLE = 1 << 1, /**< As in POLLOUT */
+ DBUS_WATCH_ERROR = 1 << 2, /**< As in POLLERR (can't watch for
+ * this, but can be present in
+ * current state passed to
+ * dbus_watch_handle()).
+ */
+ DBUS_WATCH_HANGUP = 1 << 3 /**< As in POLLHUP (can't watch for
+ * it, but can be present in current
+ * state passed to
+ * dbus_watch_handle()).
+ */
+} DBusWatchFlags;
+
+/**
+ * Indicates the status of incoming data on a #DBusConnection. This determines whether
+ * dbus_connection_dispatch() needs to be called.
+ */
+typedef enum
+{
+ DBUS_DISPATCH_DATA_REMAINS, /**< There is more data to potentially convert to messages. */
+ DBUS_DISPATCH_COMPLETE, /**< All currently available data has been processed. */
+ DBUS_DISPATCH_NEED_MEMORY /**< More memory is needed to continue. */
+} DBusDispatchStatus;
+
+/** Called when libdbus needs a new watch to be monitored by the main
+ * loop. Returns #FALSE if it lacks enough memory to add the
+ * watch. Set by dbus_connection_set_watch_functions() or
+ * dbus_server_set_watch_functions().
+ */
+typedef dbus_bool_t (* DBusAddWatchFunction) (DBusWatch *watch,
+ void *data);
+/** Called when dbus_watch_get_enabled() may return a different value
+ * than it did before. Set by dbus_connection_set_watch_functions()
+ * or dbus_server_set_watch_functions().
+ */
+typedef void (* DBusWatchToggledFunction) (DBusWatch *watch,
+ void *data);
+/** Called when libdbus no longer needs a watch to be monitored by the
+ * main loop. Set by dbus_connection_set_watch_functions() or
+ * dbus_server_set_watch_functions().
+ */
+typedef void (* DBusRemoveWatchFunction) (DBusWatch *watch,
+ void *data);
+/** Called when libdbus needs a new timeout to be monitored by the main
+ * loop. Returns #FALSE if it lacks enough memory to add the
+ * watch. Set by dbus_connection_set_timeout_functions() or
+ * dbus_server_set_timeout_functions().
+ */
+typedef dbus_bool_t (* DBusAddTimeoutFunction) (DBusTimeout *timeout,
+ void *data);
+/** Called when dbus_timeout_get_enabled() may return a different
+ * value than it did before.
+ * Set by dbus_connection_set_timeout_functions() or
+ * dbus_server_set_timeout_functions().
+ */
+typedef void (* DBusTimeoutToggledFunction) (DBusTimeout *timeout,
+ void *data);
+/** Called when libdbus no longer needs a timeout to be monitored by the
+ * main loop. Set by dbus_connection_set_timeout_functions() or
+ * dbus_server_set_timeout_functions().
+ */
+typedef void (* DBusRemoveTimeoutFunction) (DBusTimeout *timeout,
+ void *data);
+/** Called when the return value of dbus_connection_get_dispatch_status()
+ * may have changed. Set with dbus_connection_set_dispatch_status_function().
+ */
+typedef void (* DBusDispatchStatusFunction) (DBusConnection *connection,
+ DBusDispatchStatus new_status,
+ void *data);
+/**
+ * Called when the main loop's thread should be notified that there's now work
+ * to do. Set with dbus_connection_set_wakeup_main_function().
+ */
+typedef void (* DBusWakeupMainFunction) (void *data);
+
+/**
+ * Called during authentication to check whether the given UNIX user
+ * ID is allowed to connect, if the client tried to auth as a UNIX
+ * user ID. Normally on Windows this would never happen. Set with
+ * dbus_connection_set_unix_user_function().
+ */
+typedef dbus_bool_t (* DBusAllowUnixUserFunction) (DBusConnection *connection,
+ unsigned long uid,
+ void *data);
+
+/**
+ * Called during authentication to check whether the given Windows user
+ * ID is allowed to connect, if the client tried to auth as a Windows
+ * user ID. Normally on UNIX this would never happen. Set with
+ * dbus_connection_set_windows_user_function().
+ */
+typedef dbus_bool_t (* DBusAllowWindowsUserFunction) (DBusConnection *connection,
+ const char *user_sid,
+ void *data);
+
+
+/**
+ * Called when a pending call now has a reply available. Set with
+ * dbus_pending_call_set_notify().
+ */
+typedef void (* DBusPendingCallNotifyFunction) (DBusPendingCall *pending,
+ void *user_data);
+
+/**
+ * Called when a message needs to be handled. The result indicates whether or
+ * not more handlers should be run. Set with dbus_connection_add_filter().
+ */
+typedef DBusHandlerResult (* DBusHandleMessageFunction) (DBusConnection *connection,
+ DBusMessage *message,
+ void *user_data);
+DBUS_EXPORT
+DBusConnection* dbus_connection_open (const char *address,
+ DBusError *error);
+DBUS_EXPORT
+DBusConnection* dbus_connection_open_private (const char *address,
+ DBusError *error);
+DBUS_EXPORT
+DBusConnection* dbus_connection_ref (DBusConnection *connection);
+DBUS_EXPORT
+void dbus_connection_unref (DBusConnection *connection);
+DBUS_EXPORT
+void dbus_connection_close (DBusConnection *connection);
+DBUS_EXPORT
+dbus_bool_t dbus_connection_get_is_connected (DBusConnection *connection);
+DBUS_EXPORT
+dbus_bool_t dbus_connection_get_is_authenticated (DBusConnection *connection);
+DBUS_EXPORT
+dbus_bool_t dbus_connection_get_is_anonymous (DBusConnection *connection);
+DBUS_EXPORT
+char* dbus_connection_get_server_id (DBusConnection *connection);
+DBUS_EXPORT
+dbus_bool_t dbus_connection_can_send_type (DBusConnection *connection,
+ int type);
+
+DBUS_EXPORT
+void dbus_connection_set_exit_on_disconnect (DBusConnection *connection,
+ dbus_bool_t exit_on_disconnect);
+DBUS_EXPORT
+void dbus_connection_flush (DBusConnection *connection);
+DBUS_EXPORT
+dbus_bool_t dbus_connection_read_write_dispatch (DBusConnection *connection,
+ int timeout_milliseconds);
+DBUS_EXPORT
+dbus_bool_t dbus_connection_read_write (DBusConnection *connection,
+ int timeout_milliseconds);
+DBUS_EXPORT
+DBusMessage* dbus_connection_borrow_message (DBusConnection *connection);
+DBUS_EXPORT
+void dbus_connection_return_message (DBusConnection *connection,
+ DBusMessage *message);
+DBUS_EXPORT
+void dbus_connection_steal_borrowed_message (DBusConnection *connection,
+ DBusMessage *message);
+DBUS_EXPORT
+DBusMessage* dbus_connection_pop_message (DBusConnection *connection);
+DBUS_EXPORT
+DBusDispatchStatus dbus_connection_get_dispatch_status (DBusConnection *connection);
+DBUS_EXPORT
+DBusDispatchStatus dbus_connection_dispatch (DBusConnection *connection);
+DBUS_EXPORT
+dbus_bool_t dbus_connection_has_messages_to_send (DBusConnection *connection);
+DBUS_EXPORT
+dbus_bool_t dbus_connection_send (DBusConnection *connection,
+ DBusMessage *message,
+ dbus_uint32_t *client_serial);
+DBUS_EXPORT
+dbus_bool_t dbus_connection_send_with_reply (DBusConnection *connection,
+ DBusMessage *message,
+ DBusPendingCall **pending_return,
+ int timeout_milliseconds);
+DBUS_EXPORT
+DBusMessage * dbus_connection_send_with_reply_and_block (DBusConnection *connection,
+ DBusMessage *message,
+ int timeout_milliseconds,
+ DBusError *error);
+DBUS_EXPORT
+dbus_bool_t dbus_connection_set_watch_functions (DBusConnection *connection,
+ DBusAddWatchFunction add_function,
+ DBusRemoveWatchFunction remove_function,
+ DBusWatchToggledFunction toggled_function,
+ void *data,
+ DBusFreeFunction free_data_function);
+DBUS_EXPORT
+dbus_bool_t dbus_connection_set_timeout_functions (DBusConnection *connection,
+ DBusAddTimeoutFunction add_function,
+ DBusRemoveTimeoutFunction remove_function,
+ DBusTimeoutToggledFunction toggled_function,
+ void *data,
+ DBusFreeFunction free_data_function);
+DBUS_EXPORT
+void dbus_connection_set_wakeup_main_function (DBusConnection *connection,
+ DBusWakeupMainFunction wakeup_main_function,
+ void *data,
+ DBusFreeFunction free_data_function);
+DBUS_EXPORT
+void dbus_connection_set_dispatch_status_function (DBusConnection *connection,
+ DBusDispatchStatusFunction function,
+ void *data,
+ DBusFreeFunction free_data_function);
+DBUS_EXPORT
+dbus_bool_t dbus_connection_get_unix_user (DBusConnection *connection,
+ unsigned long *uid);
+DBUS_EXPORT
+dbus_bool_t dbus_connection_get_unix_process_id (DBusConnection *connection,
+ unsigned long *pid);
+DBUS_EXPORT
+dbus_bool_t dbus_connection_get_adt_audit_session_data (DBusConnection *connection,
+ void **data,
+ dbus_int32_t *data_size);
+DBUS_EXPORT
+void dbus_connection_set_unix_user_function (DBusConnection *connection,
+ DBusAllowUnixUserFunction function,
+ void *data,
+ DBusFreeFunction free_data_function);
+DBUS_EXPORT
+dbus_bool_t dbus_connection_get_windows_user (DBusConnection *connection,
+ char **windows_sid_p);
+DBUS_EXPORT
+void dbus_connection_set_windows_user_function (DBusConnection *connection,
+ DBusAllowWindowsUserFunction function,
+ void *data,
+ DBusFreeFunction free_data_function);
+DBUS_EXPORT
+void dbus_connection_set_allow_anonymous (DBusConnection *connection,
+ dbus_bool_t value);
+DBUS_EXPORT
+void dbus_connection_set_route_peer_messages (DBusConnection *connection,
+ dbus_bool_t value);
+
+
+/* Filters */
+
+DBUS_EXPORT
+dbus_bool_t dbus_connection_add_filter (DBusConnection *connection,
+ DBusHandleMessageFunction function,
+ void *user_data,
+ DBusFreeFunction free_data_function);
+DBUS_EXPORT
+void dbus_connection_remove_filter (DBusConnection *connection,
+ DBusHandleMessageFunction function,
+ void *user_data);
+
+
+/* Other */
+DBUS_EXPORT
+dbus_bool_t dbus_connection_allocate_data_slot (dbus_int32_t *slot_p);
+DBUS_EXPORT
+void dbus_connection_free_data_slot (dbus_int32_t *slot_p);
+DBUS_EXPORT
+dbus_bool_t dbus_connection_set_data (DBusConnection *connection,
+ dbus_int32_t slot,
+ void *data,
+ DBusFreeFunction free_data_func);
+DBUS_EXPORT
+void* dbus_connection_get_data (DBusConnection *connection,
+ dbus_int32_t slot);
+
+DBUS_EXPORT
+void dbus_connection_set_change_sigpipe (dbus_bool_t will_modify_sigpipe);
+
+DBUS_EXPORT
+void dbus_connection_set_max_message_size (DBusConnection *connection,
+ long size);
+DBUS_EXPORT
+long dbus_connection_get_max_message_size (DBusConnection *connection);
+DBUS_EXPORT
+void dbus_connection_set_max_received_size (DBusConnection *connection,
+ long size);
+DBUS_EXPORT
+long dbus_connection_get_max_received_size (DBusConnection *connection);
+
+DBUS_EXPORT
+void dbus_connection_set_max_message_unix_fds (DBusConnection *connection,
+ long n);
+DBUS_EXPORT
+long dbus_connection_get_max_message_unix_fds (DBusConnection *connection);
+DBUS_EXPORT
+void dbus_connection_set_max_received_unix_fds(DBusConnection *connection,
+ long n);
+DBUS_EXPORT
+long dbus_connection_get_max_received_unix_fds(DBusConnection *connection);
+
+DBUS_EXPORT
+long dbus_connection_get_outgoing_size (DBusConnection *connection);
+DBUS_EXPORT
+long dbus_connection_get_outgoing_unix_fds (DBusConnection *connection);
+
+DBUS_EXPORT
+DBusPreallocatedSend* dbus_connection_preallocate_send (DBusConnection *connection);
+DBUS_EXPORT
+void dbus_connection_free_preallocated_send (DBusConnection *connection,
+ DBusPreallocatedSend *preallocated);
+DBUS_EXPORT
+void dbus_connection_send_preallocated (DBusConnection *connection,
+ DBusPreallocatedSend *preallocated,
+ DBusMessage *message,
+ dbus_uint32_t *client_serial);
+
+
+/* Object tree functionality */
+
+/**
+ * Called when a #DBusObjectPathVTable is unregistered (or its connection is freed).
+ * Found in #DBusObjectPathVTable.
+ */
+typedef void (* DBusObjectPathUnregisterFunction) (DBusConnection *connection,
+ void *user_data);
+/**
+ * Called when a message is sent to a registered object path. Found in
+ * #DBusObjectPathVTable which is registered with dbus_connection_register_object_path()
+ * or dbus_connection_register_fallback().
+ */
+typedef DBusHandlerResult (* DBusObjectPathMessageFunction) (DBusConnection *connection,
+ DBusMessage *message,
+ void *user_data);
+
+/**
+ * Virtual table that must be implemented to handle a portion of the
+ * object path hierarchy. Attach the vtable to a particular path using
+ * dbus_connection_register_object_path() or
+ * dbus_connection_register_fallback().
+ */
+struct DBusObjectPathVTable
+{
+ DBusObjectPathUnregisterFunction unregister_function; /**< Function to unregister this handler */
+ DBusObjectPathMessageFunction message_function; /**< Function to handle messages */
+
+ void (* dbus_internal_pad1) (void *); /**< Reserved for future expansion */
+ void (* dbus_internal_pad2) (void *); /**< Reserved for future expansion */
+ void (* dbus_internal_pad3) (void *); /**< Reserved for future expansion */
+ void (* dbus_internal_pad4) (void *); /**< Reserved for future expansion */
+};
+
+DBUS_EXPORT
+dbus_bool_t dbus_connection_try_register_object_path (DBusConnection *connection,
+ const char *path,
+ const DBusObjectPathVTable *vtable,
+ void *user_data,
+ DBusError *error);
+
+DBUS_EXPORT
+dbus_bool_t dbus_connection_register_object_path (DBusConnection *connection,
+ const char *path,
+ const DBusObjectPathVTable *vtable,
+ void *user_data);
+
+DBUS_EXPORT
+dbus_bool_t dbus_connection_try_register_fallback (DBusConnection *connection,
+ const char *path,
+ const DBusObjectPathVTable *vtable,
+ void *user_data,
+ DBusError *error);
+
+DBUS_EXPORT
+dbus_bool_t dbus_connection_register_fallback (DBusConnection *connection,
+ const char *path,
+ const DBusObjectPathVTable *vtable,
+ void *user_data);
+DBUS_EXPORT
+dbus_bool_t dbus_connection_unregister_object_path (DBusConnection *connection,
+ const char *path);
+
+DBUS_EXPORT
+dbus_bool_t dbus_connection_get_object_path_data (DBusConnection *connection,
+ const char *path,
+ void **data_p);
+
+DBUS_EXPORT
+dbus_bool_t dbus_connection_list_registered (DBusConnection *connection,
+ const char *parent_path,
+ char ***child_entries);
+
+DBUS_EXPORT
+dbus_bool_t dbus_connection_get_unix_fd (DBusConnection *connection,
+ int *fd);
+DBUS_EXPORT
+dbus_bool_t dbus_connection_get_socket (DBusConnection *connection,
+ int *fd);
+
+/** @} */
+
+
+/**
+ * @addtogroup DBusWatch
+ * @{
+ */
+
+#ifndef DBUS_DISABLE_DEPRECATED
+DBUS_EXPORT
+DBUS_DEPRECATED int dbus_watch_get_fd (DBusWatch *watch);
+#endif
+
+DBUS_EXPORT
+int dbus_watch_get_unix_fd (DBusWatch *watch);
+DBUS_EXPORT
+int dbus_watch_get_socket (DBusWatch *watch);
+DBUS_EXPORT
+unsigned int dbus_watch_get_flags (DBusWatch *watch);
+DBUS_EXPORT
+void* dbus_watch_get_data (DBusWatch *watch);
+DBUS_EXPORT
+void dbus_watch_set_data (DBusWatch *watch,
+ void *data,
+ DBusFreeFunction free_data_function);
+DBUS_EXPORT
+dbus_bool_t dbus_watch_handle (DBusWatch *watch,
+ unsigned int flags);
+DBUS_EXPORT
+dbus_bool_t dbus_watch_get_enabled (DBusWatch *watch);
+
+/** @} */
+
+/**
+ * @addtogroup DBusTimeout
+ * @{
+ */
+
+DBUS_EXPORT
+int dbus_timeout_get_interval (DBusTimeout *timeout);
+DBUS_EXPORT
+void* dbus_timeout_get_data (DBusTimeout *timeout);
+DBUS_EXPORT
+void dbus_timeout_set_data (DBusTimeout *timeout,
+ void *data,
+ DBusFreeFunction free_data_function);
+DBUS_EXPORT
+dbus_bool_t dbus_timeout_handle (DBusTimeout *timeout);
+DBUS_EXPORT
+dbus_bool_t dbus_timeout_get_enabled (DBusTimeout *timeout);
+
+/** @} */
+
+DBUS_END_DECLS
+
+#endif /* DBUS_CONNECTION_H */
diff --git a/lib-x86-32/include/dbus-1/dbus/dbus-credentials.h b/lib-x86-32/include/dbus-1/dbus/dbus-credentials.h
new file mode 100644
index 00000000..ef6124fd
--- /dev/null
+++ b/lib-x86-32/include/dbus-1/dbus/dbus-credentials.h
@@ -0,0 +1,79 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-credentials.h Credentials provable through authentication
+ *
+ * Copyright (C) 2007 Red Hat Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+#ifndef DBUS_CREDENTIALS_H
+#define DBUS_CREDENTIALS_H
+
+#include <dbus/dbus-macros.h>
+#include <dbus/dbus-errors.h>
+#include <dbus/dbus-string.h>
+#include <dbus/dbus-sysdeps.h>
+
+DBUS_BEGIN_DECLS
+
+typedef enum {
+ DBUS_CREDENTIAL_UNIX_PROCESS_ID,
+ DBUS_CREDENTIAL_UNIX_USER_ID,
+ DBUS_CREDENTIAL_ADT_AUDIT_DATA_ID,
+ DBUS_CREDENTIAL_WINDOWS_SID
+} DBusCredentialType;
+
+DBusCredentials* _dbus_credentials_new_from_current_process (void);
+DBusCredentials* _dbus_credentials_new (void);
+void _dbus_credentials_ref (DBusCredentials *credentials);
+void _dbus_credentials_unref (DBusCredentials *credentials);
+dbus_bool_t _dbus_credentials_add_unix_pid (DBusCredentials *credentials,
+ dbus_pid_t pid);
+dbus_bool_t _dbus_credentials_add_unix_uid (DBusCredentials *credentials,
+ dbus_uid_t uid);
+dbus_bool_t _dbus_credentials_add_windows_sid (DBusCredentials *credentials,
+ const char *windows_sid);
+dbus_bool_t _dbus_credentials_add_adt_audit_data (DBusCredentials *credentials,
+ void *audit_data,
+ dbus_int32_t size);
+dbus_bool_t _dbus_credentials_include (DBusCredentials *credentials,
+ DBusCredentialType type);
+dbus_pid_t _dbus_credentials_get_unix_pid (DBusCredentials *credentials);
+dbus_uid_t _dbus_credentials_get_unix_uid (DBusCredentials *credentials);
+const char* _dbus_credentials_get_windows_sid (DBusCredentials *credentials);
+void * _dbus_credentials_get_adt_audit_data (DBusCredentials *credentials);
+dbus_int32_t _dbus_credentials_get_adt_audit_data_size (DBusCredentials *credentials);
+dbus_bool_t _dbus_credentials_are_superset (DBusCredentials *credentials,
+ DBusCredentials *possible_subset);
+dbus_bool_t _dbus_credentials_are_empty (DBusCredentials *credentials);
+dbus_bool_t _dbus_credentials_are_anonymous (DBusCredentials *credentials);
+dbus_bool_t _dbus_credentials_add_credentials (DBusCredentials *credentials,
+ DBusCredentials *other_credentials);
+/* must silently allow 'which' to not exist */
+dbus_bool_t _dbus_credentials_add_credential (DBusCredentials *credentials,
+ DBusCredentialType which,
+ DBusCredentials *other_credentials);
+void _dbus_credentials_clear (DBusCredentials *credentials);
+DBusCredentials* _dbus_credentials_copy (DBusCredentials *credentials);
+dbus_bool_t _dbus_credentials_same_user (DBusCredentials *credentials,
+ DBusCredentials *other_credentials);
+dbus_bool_t _dbus_credentials_to_string_append (DBusCredentials *credentials,
+ DBusString *string);
+
+DBUS_END_DECLS
+
+#endif /* DBUS_CREDENTIALS_H */
diff --git a/lib-x86-32/include/dbus-1/dbus/dbus-dataslot.h b/lib-x86-32/include/dbus-1/dbus/dbus-dataslot.h
new file mode 100644
index 00000000..2e706f72
--- /dev/null
+++ b/lib-x86-32/include/dbus-1/dbus/dbus-dataslot.h
@@ -0,0 +1,96 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-dataslot.h storing data on objects
+ *
+ * Copyright (C) 2003 Red Hat, Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+#ifndef DBUS_DATASLOT_H
+#define DBUS_DATASLOT_H
+
+#include <dbus/dbus-internals.h>
+
+DBUS_BEGIN_DECLS
+
+typedef struct DBusDataSlotAllocator DBusDataSlotAllocator;
+typedef struct DBusDataSlotList DBusDataSlotList;
+
+/** Opaque typedef for DBusDataSlot */
+typedef struct DBusDataSlot DBusDataSlot;
+/** DBusDataSlot is used to store application data on the connection */
+struct DBusDataSlot
+{
+ void *data; /**< The application data */
+ DBusFreeFunction free_data_func; /**< Free the application data */
+};
+
+typedef struct DBusAllocatedSlot DBusAllocatedSlot;
+
+/** An allocated slot for storing data
+ */
+struct DBusAllocatedSlot
+{
+ dbus_int32_t slot_id; /**< ID of this slot */
+ int refcount; /**< Number of uses of the slot */
+};
+
+/**
+ * An allocator that tracks a set of slot IDs.
+ */
+struct DBusDataSlotAllocator
+{
+ DBusAllocatedSlot *allocated_slots; /**< Allocated slots */
+ int n_allocated_slots; /**< number of slots malloc'd */
+ int n_used_slots; /**< number of slots used */
+ DBusMutex **lock_loc; /**< location of thread lock */
+};
+
+/**
+ * Data structure that stores the actual user data set at a given
+ * slot.
+ */
+struct DBusDataSlotList
+{
+ DBusDataSlot *slots; /**< Data slots */
+ int n_slots; /**< Slots we have storage for in data_slots */
+};
+
+dbus_bool_t _dbus_data_slot_allocator_init (DBusDataSlotAllocator *allocator);
+dbus_bool_t _dbus_data_slot_allocator_alloc (DBusDataSlotAllocator *allocator,
+ DBusMutex **mutex_loc,
+ int *slot_id_p);
+void _dbus_data_slot_allocator_free (DBusDataSlotAllocator *allocator,
+ int *slot_id_p);
+void _dbus_data_slot_list_init (DBusDataSlotList *list);
+dbus_bool_t _dbus_data_slot_list_set (DBusDataSlotAllocator *allocator,
+ DBusDataSlotList *list,
+ int slot,
+ void *data,
+ DBusFreeFunction free_data_func,
+ DBusFreeFunction *old_free_func,
+ void **old_data);
+void* _dbus_data_slot_list_get (DBusDataSlotAllocator *allocator,
+ DBusDataSlotList *list,
+ int slot);
+void _dbus_data_slot_list_clear (DBusDataSlotList *list);
+void _dbus_data_slot_list_free (DBusDataSlotList *list);
+
+
+DBUS_END_DECLS
+
+#endif /* DBUS_DATASLOT_H */
diff --git a/lib-x86-32/include/dbus-1/dbus/dbus-errors.h b/lib-x86-32/include/dbus-1/dbus/dbus-errors.h
new file mode 100644
index 00000000..e63139a0
--- /dev/null
+++ b/lib-x86-32/include/dbus-1/dbus/dbus-errors.h
@@ -0,0 +1,90 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-errors.h Error reporting
+ *
+ * Copyright (C) 2002 Red Hat Inc.
+ * Copyright (C) 2003 CodeFactory AB
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+#if !defined (DBUS_INSIDE_DBUS_H) && !defined (DBUS_COMPILATION)
+#error "Only <dbus/dbus.h> can be included directly, this file may disappear or change contents."
+#endif
+
+#ifndef DBUS_ERROR_H
+#define DBUS_ERROR_H
+
+#include <dbus/dbus-macros.h>
+#include <dbus/dbus-types.h>
+#include <dbus/dbus-protocol.h>
+
+DBUS_BEGIN_DECLS
+
+/**
+ * @addtogroup DBusErrors
+ * @{
+ */
+
+/** Mostly-opaque type representing an error that occurred */
+typedef struct DBusError DBusError;
+
+/**
+ * Object representing an exception.
+ */
+struct DBusError
+{
+ const char *name; /**< public error name field */
+ const char *message; /**< public error message field */
+
+ unsigned int dummy1 : 1; /**< placeholder */
+ unsigned int dummy2 : 1; /**< placeholder */
+ unsigned int dummy3 : 1; /**< placeholder */
+ unsigned int dummy4 : 1; /**< placeholder */
+ unsigned int dummy5 : 1; /**< placeholder */
+
+ void *padding1; /**< placeholder */
+};
+
+#define DBUS_ERROR_INIT { NULL, NULL, TRUE, 0, 0, 0, 0, NULL }
+
+DBUS_EXPORT
+void dbus_error_init (DBusError *error);
+DBUS_EXPORT
+void dbus_error_free (DBusError *error);
+DBUS_EXPORT
+void dbus_set_error (DBusError *error,
+ const char *name,
+ const char *message,
+ ...);
+DBUS_EXPORT
+void dbus_set_error_const (DBusError *error,
+ const char *name,
+ const char *message);
+DBUS_EXPORT
+void dbus_move_error (DBusError *src,
+ DBusError *dest);
+DBUS_EXPORT
+dbus_bool_t dbus_error_has_name (const DBusError *error,
+ const char *name);
+DBUS_EXPORT
+dbus_bool_t dbus_error_is_set (const DBusError *error);
+
+/** @} */
+
+DBUS_END_DECLS
+
+#endif /* DBUS_ERROR_H */
diff --git a/lib-x86-32/include/dbus-1/dbus/dbus-file.h b/lib-x86-32/include/dbus-1/dbus/dbus-file.h
new file mode 100644
index 00000000..24837f47
--- /dev/null
+++ b/lib-x86-32/include/dbus-1/dbus/dbus-file.h
@@ -0,0 +1,63 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-file.h dbus file related stuff (internal to D-Bus implementation)
+ *
+ * Copyright (C) 2002, 2003 Red Hat, Inc.
+ * Copyright (C) 2003 CodeFactory AB
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef DBUS_FILE_H
+#define DBUS_FILE_H
+
+//#include <dbus/dbus-types.h>
+#include <dbus/dbus-string.h>
+#include <dbus/dbus-errors.h>
+
+DBUS_BEGIN_DECLS
+
+/**
+ * @addtogroup DBusFile
+ * @{
+ */
+
+/**
+ * File interface
+ */
+dbus_bool_t _dbus_file_exists (const char *file);
+dbus_bool_t _dbus_file_get_contents (DBusString *str,
+ const DBusString *filename,
+ DBusError *error);
+dbus_bool_t _dbus_string_save_to_file (const DBusString *str,
+ const DBusString *filename,
+ dbus_bool_t world_readable,
+ DBusError *error);
+
+dbus_bool_t _dbus_make_file_world_readable (const DBusString *filename,
+ DBusError *error);
+
+dbus_bool_t _dbus_create_file_exclusively (const DBusString *filename,
+ DBusError *error);
+dbus_bool_t _dbus_delete_file (const DBusString *filename,
+ DBusError *error);
+
+/** @} */
+
+DBUS_END_DECLS
+
+#endif
diff --git a/lib-x86-32/include/dbus-1/dbus/dbus-hash.h b/lib-x86-32/include/dbus-1/dbus/dbus-hash.h
new file mode 100644
index 00000000..d1ca246c
--- /dev/null
+++ b/lib-x86-32/include/dbus-1/dbus/dbus-hash.h
@@ -0,0 +1,151 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-hash.h Generic hash table utility (internal to D-Bus implementation)
+ *
+ * Copyright (C) 2002 Red Hat, Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef DBUS_HASH_H
+#define DBUS_HASH_H
+
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
+
+#ifdef HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+
+#include <dbus/dbus-memory.h>
+#include <dbus/dbus-types.h>
+#include <dbus/dbus-sysdeps.h>
+
+DBUS_BEGIN_DECLS
+
+/**
+ * @addtogroup DBusHashTable
+ * @{
+ */
+
+/** Hash iterator object. The iterator is on the stack, but its real
+ * fields are hidden privately.
+ */
+struct DBusHashIter
+{
+ void *dummy1; /**< Do not use. */
+ void *dummy2; /**< Do not use. */
+ void *dummy3; /**< Do not use. */
+ void *dummy4; /**< Do not use. */
+ int dummy5; /**< Do not use. */
+ int dummy6; /**< Do not use. */
+};
+
+typedef struct DBusHashTable DBusHashTable;
+typedef struct DBusHashIter DBusHashIter;
+
+/* Allowing an arbitrary function as with GLib
+ * would be nicer for a public API, but for
+ * an internal API this saves typing, we can add
+ * more whenever we feel like it.
+ */
+typedef enum
+{
+ DBUS_HASH_STRING, /**< Hash keys are strings. */
+ DBUS_HASH_TWO_STRINGS, /**< Hash key is two strings in one memory block, i.e. foo\\0bar\\0 */
+ DBUS_HASH_INT, /**< Hash keys are integers. */
+ DBUS_HASH_POINTER, /**< Hash keys are pointers. */
+ DBUS_HASH_UINTPTR /**< Hash keys are integer capable to hold a pointer. */
+} DBusHashType;
+
+DBusHashTable* _dbus_hash_table_new (DBusHashType type,
+ DBusFreeFunction key_free_function,
+ DBusFreeFunction value_free_function);
+DBusHashTable* _dbus_hash_table_ref (DBusHashTable *table);
+void _dbus_hash_table_unref (DBusHashTable *table);
+void _dbus_hash_table_remove_all (DBusHashTable *table);
+void _dbus_hash_iter_init (DBusHashTable *table,
+ DBusHashIter *iter);
+dbus_bool_t _dbus_hash_iter_next (DBusHashIter *iter);
+void _dbus_hash_iter_remove_entry (DBusHashIter *iter);
+void* _dbus_hash_iter_get_value (DBusHashIter *iter);
+void _dbus_hash_iter_set_value (DBusHashIter *iter,
+ void *value);
+int _dbus_hash_iter_get_int_key (DBusHashIter *iter);
+const char* _dbus_hash_iter_get_string_key (DBusHashIter *iter);
+const char* _dbus_hash_iter_get_two_strings_key (DBusHashIter *iter);
+uintptr_t _dbus_hash_iter_get_uintptr_key (DBusHashIter *iter);
+dbus_bool_t _dbus_hash_iter_lookup (DBusHashTable *table,
+ void *key,
+ dbus_bool_t create_if_not_found,
+ DBusHashIter *iter);
+void* _dbus_hash_table_lookup_string (DBusHashTable *table,
+ const char *key);
+void* _dbus_hash_table_lookup_two_strings (DBusHashTable *table,
+ const char *key);
+void* _dbus_hash_table_lookup_int (DBusHashTable *table,
+ int key);
+void* _dbus_hash_table_lookup_pointer (DBusHashTable *table,
+ void *key);
+void* _dbus_hash_table_lookup_uintptr (DBusHashTable *table,
+ uintptr_t key);
+dbus_bool_t _dbus_hash_table_remove_string (DBusHashTable *table,
+ const char *key);
+dbus_bool_t _dbus_hash_table_remove_two_strings (DBusHashTable *table,
+ const char *key);
+dbus_bool_t _dbus_hash_table_remove_int (DBusHashTable *table,
+ int key);
+dbus_bool_t _dbus_hash_table_remove_pointer (DBusHashTable *table,
+ void *key);
+dbus_bool_t _dbus_hash_table_remove_uintptr (DBusHashTable *table,
+ uintptr_t key);
+dbus_bool_t _dbus_hash_table_insert_string (DBusHashTable *table,
+ char *key,
+ void *value);
+dbus_bool_t _dbus_hash_table_insert_two_strings (DBusHashTable *table,
+ char *key,
+ void *value);
+dbus_bool_t _dbus_hash_table_insert_int (DBusHashTable *table,
+ int key,
+ void *value);
+dbus_bool_t _dbus_hash_table_insert_pointer (DBusHashTable *table,
+ void *key,
+ void *value);
+dbus_bool_t _dbus_hash_table_insert_uintptr (DBusHashTable *table,
+ uintptr_t key,
+ void *value);
+int _dbus_hash_table_get_n_entries (DBusHashTable *table);
+
+/* Preallocation */
+
+/** A preallocated hash entry */
+typedef struct DBusPreallocatedHash DBusPreallocatedHash;
+
+DBusPreallocatedHash *_dbus_hash_table_preallocate_entry (DBusHashTable *table);
+void _dbus_hash_table_free_preallocated_entry (DBusHashTable *table,
+ DBusPreallocatedHash *preallocated);
+void _dbus_hash_table_insert_string_preallocated (DBusHashTable *table,
+ DBusPreallocatedHash *preallocated,
+ char *key,
+ void *value);
+
+/** @} */
+
+DBUS_END_DECLS
+
+#endif /* DBUS_HASH_H */
diff --git a/lib-x86-32/include/dbus-1/dbus/dbus-internals.h b/lib-x86-32/include/dbus-1/dbus/dbus-internals.h
new file mode 100644
index 00000000..dcef7d7f
--- /dev/null
+++ b/lib-x86-32/include/dbus-1/dbus/dbus-internals.h
@@ -0,0 +1,367 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-internals.h random utility stuff (internal to D-Bus implementation)
+ *
+ * Copyright (C) 2002, 2003 Red Hat, Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+#ifdef DBUS_INSIDE_DBUS_H
+#error "You can't include dbus-internals.h in the public header dbus.h"
+#endif
+
+#ifndef DBUS_INTERNALS_H
+#define DBUS_INTERNALS_H
+
+#include <dbus/dbus-memory.h>
+#include <dbus/dbus-types.h>
+#include <dbus/dbus-errors.h>
+#include <dbus/dbus-sysdeps.h>
+#include <dbus/dbus-threads-internal.h>
+
+DBUS_BEGIN_DECLS
+
+#ifndef DBUS_SESSION_BUS_DEFAULT_ADDRESS
+#define DBUS_SESSION_BUS_DEFAULT_ADDRESS "autolaunch:"
+#endif
+
+void _dbus_warn (const char *format,
+ ...) _DBUS_GNUC_PRINTF (1, 2);
+
+void _dbus_warn_check_failed (const char *format,
+ ...) _DBUS_GNUC_PRINTF (1, 2);
+
+
+#if defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
+#define _DBUS_FUNCTION_NAME __func__
+#elif defined(__GNUC__) || defined(_MSC_VER)
+#define _DBUS_FUNCTION_NAME __FUNCTION__
+#else
+#define _DBUS_FUNCTION_NAME "unknown function"
+#endif
+
+/*
+ * (code from GLib)
+ *
+ * The _DBUS_LIKELY and _DBUS_UNLIKELY macros let the programmer give hints to
+ * the compiler about the expected result of an expression. Some compilers
+ * can use this information for optimizations.
+ *
+ * The _DBUS_BOOLEAN_EXPR macro is intended to trigger a gcc warning when
+ * putting assignments in the macro arg
+ */
+#if defined(__GNUC__) && (__GNUC__ > 2) && defined(__OPTIMIZE__)
+#define _DBUS_BOOLEAN_EXPR(expr) \
+ __extension__ ({ \
+ int _dbus_boolean_var_; \
+ if (expr) \
+ _dbus_boolean_var_ = 1; \
+ else \
+ _dbus_boolean_var_ = 0; \
+ _dbus_boolean_var_; \
+})
+#define _DBUS_LIKELY(expr) (__builtin_expect (_DBUS_BOOLEAN_EXPR(expr), 1))
+#define _DBUS_UNLIKELY(expr) (__builtin_expect (_DBUS_BOOLEAN_EXPR(expr), 0))
+#else
+#define _DBUS_LIKELY(expr) (expr)
+#define _DBUS_UNLIKELY(expr) (expr)
+#endif
+
+#ifdef DBUS_ENABLE_VERBOSE_MODE
+
+/*
+ at least gnu cc and msvc compiler are known to
+ have support for variable macro argument lists
+ add other compilers is required
+*/
+#if defined(__GNUC__) || defined(_MSC_VER)
+#define DBUS_CPP_SUPPORTS_VARIABLE_MACRO_ARGUMENTS
+#endif
+
+#ifdef DBUS_CPP_SUPPORTS_VARIABLE_MACRO_ARGUMENTS
+void _dbus_verbose_real (const char *file, const int line, const char *function,
+ const char *format,...) _DBUS_GNUC_PRINTF (4, 5);
+# define _dbus_verbose(fmt,...) _dbus_verbose_real( __FILE__,__LINE__,__FUNCTION__,fmt, ## __VA_ARGS__)
+#else
+void _dbus_verbose_real (const char *format,
+ ...) _DBUS_GNUC_PRINTF (1, 2);
+# define _dbus_verbose _dbus_verbose_real
+#endif
+void _dbus_verbose_reset_real (void);
+dbus_bool_t _dbus_is_verbose_real (void);
+
+# define _dbus_verbose_reset _dbus_verbose_reset_real
+# define _dbus_is_verbose _dbus_is_verbose_real
+#else
+# ifdef HAVE_ISO_VARARGS
+# define _dbus_verbose(...)
+# elif defined (HAVE_GNUC_VARARGS)
+# define _dbus_verbose(format...)
+# else
+static void _dbus_verbose(const char * x,...) {;}
+# endif
+# define _dbus_verbose_reset()
+# define _dbus_is_verbose() FALSE
+#endif /* !DBUS_ENABLE_VERBOSE_MODE */
+
+const char* _dbus_strerror (int error_number);
+
+#ifdef DBUS_DISABLE_ASSERT
+#define _dbus_assert(condition)
+#else
+void _dbus_real_assert (dbus_bool_t condition,
+ const char *condition_text,
+ const char *file,
+ int line,
+ const char *func);
+#define _dbus_assert(condition) \
+ _dbus_real_assert ((condition) != 0, #condition, __FILE__, __LINE__, _DBUS_FUNCTION_NAME)
+#endif /* !DBUS_DISABLE_ASSERT */
+
+#ifdef DBUS_DISABLE_ASSERT
+#define _dbus_assert_not_reached(explanation)
+#else
+void _dbus_real_assert_not_reached (const char *explanation,
+ const char *file,
+ int line) _DBUS_GNUC_NORETURN;
+#define _dbus_assert_not_reached(explanation) \
+ _dbus_real_assert_not_reached (explanation, __FILE__, __LINE__)
+#endif /* !DBUS_DISABLE_ASSERT */
+
+#ifdef DBUS_DISABLE_CHECKS
+#define _dbus_return_if_fail(condition)
+#define _dbus_return_val_if_fail(condition, val)
+#else
+
+extern const char *_dbus_return_if_fail_warning_format;
+
+#define _dbus_return_if_fail(condition) do { \
+ _dbus_assert ((*(const char*)_DBUS_FUNCTION_NAME) != '_'); \
+ if (!(condition)) { \
+ _dbus_warn_check_failed (_dbus_return_if_fail_warning_format, \
+ _DBUS_FUNCTION_NAME, #condition, __FILE__, __LINE__); \
+ return; \
+ } } while (0)
+
+#define _dbus_return_val_if_fail(condition, val) do { \
+ _dbus_assert ((*(const char*)_DBUS_FUNCTION_NAME) != '_'); \
+ if (!(condition)) { \
+ _dbus_warn_check_failed (_dbus_return_if_fail_warning_format, \
+ _DBUS_FUNCTION_NAME, #condition, __FILE__, __LINE__); \
+ return (val); \
+ } } while (0)
+
+#endif /* !DBUS_DISABLE_ASSERT */
+
+#define _DBUS_N_ELEMENTS(array) ((int) (sizeof ((array)) / sizeof ((array)[0])))
+
+#define _DBUS_POINTER_TO_INT(pointer) ((intptr_t)(pointer))
+#define _DBUS_INT_TO_POINTER(integer) ((void*)((intptr_t)(integer)))
+
+#define _DBUS_ZERO(object) (memset (&(object), '\0', sizeof ((object))))
+
+#define _DBUS_STRUCT_OFFSET(struct_type, member) \
+ ((intptr_t) ((unsigned char*) &((struct_type*) 0)->member))
+
+#ifdef DBUS_DISABLE_CHECKS
+/* this is an assert and not an error, but in the typical --disable-checks case (you're trying
+ * to really minimize code size), disabling these assertions makes sense.
+ */
+#define _DBUS_ASSERT_ERROR_IS_SET(error)
+#define _DBUS_ASSERT_ERROR_IS_CLEAR(error)
+#else
+#define _DBUS_ASSERT_ERROR_IS_SET(error) _dbus_assert ((error) == NULL || dbus_error_is_set ((error)))
+#define _DBUS_ASSERT_ERROR_IS_CLEAR(error) _dbus_assert ((error) == NULL || !dbus_error_is_set ((error)))
+#endif
+
+#define _dbus_return_if_error_is_set(error) _dbus_return_if_fail ((error) == NULL || !dbus_error_is_set ((error)))
+#define _dbus_return_val_if_error_is_set(error, val) _dbus_return_val_if_fail ((error) == NULL || !dbus_error_is_set ((error)), (val))
+
+/* This alignment thing is from ORBit2 */
+/* Align a value upward to a boundary, expressed as a number of bytes.
+ * E.g. align to an 8-byte boundary with argument of 8.
+ */
+
+/*
+ * (this + boundary - 1)
+ * &
+ * ~(boundary - 1)
+ */
+
+#define _DBUS_ALIGN_VALUE(this, boundary) \
+ (( ((uintptr_t)(this)) + (((uintptr_t)(boundary)) -1)) & (~(((uintptr_t)(boundary))-1)))
+
+#define _DBUS_ALIGN_ADDRESS(this, boundary) \
+ ((void*)_DBUS_ALIGN_VALUE(this, boundary))
+
+
+char* _dbus_strdup (const char *str);
+void* _dbus_memdup (const void *mem,
+ size_t n_bytes);
+dbus_bool_t _dbus_string_array_contains (const char **array,
+ const char *str);
+char** _dbus_dup_string_array (const char **array);
+
+#define _DBUS_INT16_MIN ((dbus_int16_t) 0x8000)
+#define _DBUS_INT16_MAX ((dbus_int16_t) 0x7fff)
+#define _DBUS_UINT16_MAX ((dbus_uint16_t)0xffff)
+#define _DBUS_INT32_MIN ((dbus_int32_t) 0x80000000)
+#define _DBUS_INT32_MAX ((dbus_int32_t) 0x7fffffff)
+#define _DBUS_UINT32_MAX ((dbus_uint32_t)0xffffffff)
+/* using 32-bit here is sort of bogus */
+#define _DBUS_INT_MIN _DBUS_INT32_MIN
+#define _DBUS_INT_MAX _DBUS_INT32_MAX
+#define _DBUS_UINT_MAX _DBUS_UINT32_MAX
+#ifdef DBUS_HAVE_INT64
+#define _DBUS_INT64_MAX DBUS_INT64_CONSTANT (0x7fffffffffffffff)
+#define _DBUS_UINT64_MAX DBUS_UINT64_CONSTANT (0xffffffffffffffff)
+#endif
+#define _DBUS_ONE_KILOBYTE 1024
+#define _DBUS_ONE_MEGABYTE 1024 * _DBUS_ONE_KILOBYTE
+#define _DBUS_ONE_HOUR_IN_MILLISECONDS (1000 * 60 * 60)
+#define _DBUS_USEC_PER_SECOND (1000000)
+
+#undef MAX
+#define MAX(a, b) (((a) > (b)) ? (a) : (b))
+
+#undef MIN
+#define MIN(a, b) (((a) < (b)) ? (a) : (b))
+
+#undef ABS
+#define ABS(a) (((a) < 0) ? -(a) : (a))
+
+#define _DBUS_ISASCII(c) ((c) != '\0' && (((c) & ~0x7f) == 0))
+
+typedef void (* DBusForeachFunction) (void *element,
+ void *data);
+
+dbus_bool_t _dbus_set_fd_nonblocking (int fd,
+ DBusError *error);
+
+void _dbus_verbose_bytes (const unsigned char *data,
+ int len,
+ int offset);
+void _dbus_verbose_bytes_of_string (const DBusString *str,
+ int start,
+ int len);
+
+const char* _dbus_header_field_to_string (int header_field);
+
+extern const char *_dbus_no_memory_message;
+#define _DBUS_SET_OOM(error) dbus_set_error_const ((error), DBUS_ERROR_NO_MEMORY, _dbus_no_memory_message)
+
+#ifdef DBUS_BUILD_TESTS
+/* Memory debugging */
+void _dbus_set_fail_alloc_counter (int until_next_fail);
+int _dbus_get_fail_alloc_counter (void);
+void _dbus_set_fail_alloc_failures (int failures_per_failure);
+int _dbus_get_fail_alloc_failures (void);
+dbus_bool_t _dbus_decrement_fail_alloc_counter (void);
+dbus_bool_t _dbus_disable_mem_pools (void);
+int _dbus_get_malloc_blocks_outstanding (void);
+
+typedef dbus_bool_t (* DBusTestMemoryFunction) (void *data);
+dbus_bool_t _dbus_test_oom_handling (const char *description,
+ DBusTestMemoryFunction func,
+ void *data);
+#else
+#define _dbus_set_fail_alloc_counter(n)
+#define _dbus_get_fail_alloc_counter _DBUS_INT_MAX
+
+/* These are constant expressions so that blocks
+ * they protect should be optimized away
+ */
+#define _dbus_decrement_fail_alloc_counter() (FALSE)
+#define _dbus_disable_mem_pools() (FALSE)
+#define _dbus_get_malloc_blocks_outstanding (0)
+#endif /* !DBUS_BUILD_TESTS */
+
+typedef void (* DBusShutdownFunction) (void *data);
+dbus_bool_t _dbus_register_shutdown_func (DBusShutdownFunction function,
+ void *data);
+
+extern int _dbus_current_generation;
+
+/* Thread initializers */
+#define _DBUS_LOCK_NAME(name) _dbus_lock_##name
+#define _DBUS_DECLARE_GLOBAL_LOCK(name) extern DBusMutex *_dbus_lock_##name
+#define _DBUS_DEFINE_GLOBAL_LOCK(name) DBusMutex *_dbus_lock_##name
+#define _DBUS_LOCK(name) _dbus_mutex_lock (_dbus_lock_##name)
+#define _DBUS_UNLOCK(name) _dbus_mutex_unlock (_dbus_lock_##name)
+
+/* 1-5 */
+_DBUS_DECLARE_GLOBAL_LOCK (list);
+_DBUS_DECLARE_GLOBAL_LOCK (connection_slots);
+_DBUS_DECLARE_GLOBAL_LOCK (pending_call_slots);
+_DBUS_DECLARE_GLOBAL_LOCK (server_slots);
+_DBUS_DECLARE_GLOBAL_LOCK (message_slots);
+/* 5-10 */
+_DBUS_DECLARE_GLOBAL_LOCK (bus);
+_DBUS_DECLARE_GLOBAL_LOCK (bus_datas);
+_DBUS_DECLARE_GLOBAL_LOCK (shutdown_funcs);
+_DBUS_DECLARE_GLOBAL_LOCK (system_users);
+_DBUS_DECLARE_GLOBAL_LOCK (message_cache);
+/* 10-14 */
+_DBUS_DECLARE_GLOBAL_LOCK (shared_connections);
+_DBUS_DECLARE_GLOBAL_LOCK (win_fds);
+_DBUS_DECLARE_GLOBAL_LOCK (sid_atom_cache);
+_DBUS_DECLARE_GLOBAL_LOCK (machine_uuid);
+
+#if !DBUS_USE_SYNC
+_DBUS_DECLARE_GLOBAL_LOCK (atomic);
+#define _DBUS_N_GLOBAL_LOCKS (15)
+#else
+#define _DBUS_N_GLOBAL_LOCKS (14)
+#endif
+
+dbus_bool_t _dbus_threads_init_debug (void);
+
+dbus_bool_t _dbus_address_append_escaped (DBusString *escaped,
+ const DBusString *unescaped);
+
+void _dbus_set_bad_address (DBusError *error,
+ const char *address_problem_type,
+ const char *address_problem_field,
+ const char *address_problem_other);
+
+#define DBUS_UUID_LENGTH_BYTES 16
+#define DBUS_UUID_LENGTH_WORDS (DBUS_UUID_LENGTH_BYTES / 4)
+#define DBUS_UUID_LENGTH_HEX (DBUS_UUID_LENGTH_BYTES * 2)
+
+/**
+ * A globally unique ID ; we have one for each DBusServer, and also one for each
+ * machine with libdbus installed on it.
+ */
+union DBusGUID
+{
+ dbus_uint32_t as_uint32s[DBUS_UUID_LENGTH_WORDS]; /**< guid as four uint32 values */
+ char as_bytes[DBUS_UUID_LENGTH_BYTES]; /**< guid as 16 single-byte values */
+};
+
+void _dbus_generate_uuid (DBusGUID *uuid);
+dbus_bool_t _dbus_uuid_encode (const DBusGUID *uuid,
+ DBusString *encoded);
+dbus_bool_t _dbus_read_uuid_file (const DBusString *filename,
+ DBusGUID *uuid,
+ dbus_bool_t create_if_not_found,
+ DBusError *error);
+
+dbus_bool_t _dbus_get_local_machine_uuid_encoded (DBusString *uuid_str);
+
+DBUS_END_DECLS
+
+#endif /* DBUS_INTERNALS_H */
diff --git a/lib-x86-32/include/dbus-1/dbus/dbus-keyring.h b/lib-x86-32/include/dbus-1/dbus/dbus-keyring.h
new file mode 100644
index 00000000..200e31bc
--- /dev/null
+++ b/lib-x86-32/include/dbus-1/dbus/dbus-keyring.h
@@ -0,0 +1,52 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-keyring.h Store secret cookies in your homedir
+ *
+ * Copyright (C) 2003 Red Hat Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+#ifndef DBUS_KEYRING_H
+#define DBUS_KEYRING_H
+
+#include <dbus/dbus-macros.h>
+#include <dbus/dbus-errors.h>
+#include <dbus/dbus-string.h>
+#include <dbus/dbus-credentials.h>
+
+DBUS_BEGIN_DECLS
+
+typedef struct DBusKeyring DBusKeyring;
+
+DBusKeyring* _dbus_keyring_new_for_credentials (DBusCredentials *credentials,
+ const DBusString *context,
+ DBusError *error);
+DBusKeyring* _dbus_keyring_ref (DBusKeyring *keyring);
+void _dbus_keyring_unref (DBusKeyring *keyring);
+dbus_bool_t _dbus_keyring_validate_context (const DBusString *context);
+int _dbus_keyring_get_best_key (DBusKeyring *keyring,
+ DBusError *error);
+dbus_bool_t _dbus_keyring_is_for_credentials (DBusKeyring *keyring,
+ DBusCredentials *credentials);
+dbus_bool_t _dbus_keyring_get_hex_key (DBusKeyring *keyring,
+ int key_id,
+ DBusString *hex_key);
+
+
+DBUS_END_DECLS
+
+#endif /* DBUS_KEYRING_H */
diff --git a/lib-x86-32/include/dbus-1/dbus/dbus-list.h b/lib-x86-32/include/dbus-1/dbus/dbus-list.h
new file mode 100644
index 00000000..663ad257
--- /dev/null
+++ b/lib-x86-32/include/dbus-1/dbus/dbus-list.h
@@ -0,0 +1,98 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-list.h Generic linked list utility (internal to D-Bus implementation)
+ *
+ * Copyright (C) 2002, 2003 Red Hat, Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef DBUS_LIST_H
+#define DBUS_LIST_H
+
+#include <dbus/dbus-internals.h>
+#include <dbus/dbus-memory.h>
+#include <dbus/dbus-types.h>
+#include <dbus/dbus-sysdeps.h>
+
+DBUS_BEGIN_DECLS
+
+struct DBusList
+{
+ DBusList *prev; /**< Previous list node. */
+ DBusList *next; /**< Next list node. */
+ void *data; /**< Data stored at this element. */
+};
+dbus_bool_t _dbus_list_append (DBusList **list,
+ void *data);
+dbus_bool_t _dbus_list_prepend (DBusList **list,
+ void *data);
+dbus_bool_t _dbus_list_insert_before (DBusList **list,
+ DBusList *before_this_link,
+ void *data);
+dbus_bool_t _dbus_list_insert_after (DBusList **list,
+ DBusList *after_this_link,
+ void *data);
+void _dbus_list_insert_before_link (DBusList **list,
+ DBusList *before_this_link,
+ DBusList *link);
+void _dbus_list_insert_after_link (DBusList **list,
+ DBusList *after_this_link,
+ DBusList *link);
+dbus_bool_t _dbus_list_remove (DBusList **list,
+ void *data);
+dbus_bool_t _dbus_list_remove_last (DBusList **list,
+ void *data);
+void _dbus_list_remove_link (DBusList **list,
+ DBusList *link);
+DBusList* _dbus_list_find_last (DBusList **list,
+ void *data);
+void _dbus_list_clear (DBusList **list);
+DBusList* _dbus_list_get_first_link (DBusList **list);
+DBusList* _dbus_list_get_last_link (DBusList **list);
+void* _dbus_list_get_last (DBusList **list);
+void* _dbus_list_get_first (DBusList **list);
+void* _dbus_list_pop_first (DBusList **list);
+void* _dbus_list_pop_last (DBusList **list);
+DBusList* _dbus_list_pop_first_link (DBusList **list);
+DBusList* _dbus_list_pop_last_link (DBusList **list);
+dbus_bool_t _dbus_list_copy (DBusList **list,
+ DBusList **dest);
+int _dbus_list_get_length (DBusList **list);
+DBusList* _dbus_list_alloc_link (void *data);
+void _dbus_list_free_link (DBusList *link);
+void _dbus_list_unlink (DBusList **list,
+ DBusList *link);
+void _dbus_list_append_link (DBusList **list,
+ DBusList *link);
+void _dbus_list_prepend_link (DBusList **list,
+ DBusList *link);
+dbus_bool_t _dbus_list_length_is_one (DBusList **list);
+
+
+
+
+void _dbus_list_foreach (DBusList **list,
+ DBusForeachFunction function,
+ void *data);
+
+#define _dbus_list_get_next_link(list, link) ((link)->next == *(list) ? NULL : (link)->next)
+#define _dbus_list_get_prev_link(list, link) ((link) == *(list) ? NULL : (link)->prev)
+
+DBUS_END_DECLS
+
+#endif /* DBUS_LIST_H */
diff --git a/lib-x86-32/include/dbus-1/dbus/dbus-macros.h b/lib-x86-32/include/dbus-1/dbus/dbus-macros.h
new file mode 100644
index 00000000..d1e40ecb
--- /dev/null
+++ b/lib-x86-32/include/dbus-1/dbus/dbus-macros.h
@@ -0,0 +1,174 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-macros.h generic macros
+ *
+ * Copyright (C) 2002 Red Hat Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+#if !defined (DBUS_INSIDE_DBUS_H) && !defined (DBUS_COMPILATION)
+#error "Only <dbus/dbus.h> can be included directly, this file may disappear or change contents."
+#endif
+
+#ifndef DBUS_MACROS_H
+#define DBUS_MACROS_H
+
+#ifdef __cplusplus
+# define DBUS_BEGIN_DECLS extern "C" {
+# define DBUS_END_DECLS }
+#else
+# define DBUS_BEGIN_DECLS
+# define DBUS_END_DECLS
+#endif
+
+#ifndef TRUE
+# define TRUE 1
+#endif
+#ifndef FALSE
+# define FALSE 0
+#endif
+
+#ifndef NULL
+# ifdef __cplusplus
+# define NULL (0L)
+# else /* !__cplusplus */
+# define NULL ((void*) 0)
+# endif /* !__cplusplus */
+#endif
+
+#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)
+# define DBUS_DEPRECATED __attribute__ ((__deprecated__))
+#elif defined(_MSC_VER) && (_MSC_VER >= 1300)
+# define DBUS_DEPRECATED __declspec(deprecated)
+#else
+# define DBUS_DEPRECATED
+#endif
+
+#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 8)
+# define _DBUS_GNUC_EXTENSION __extension__
+#else
+# define _DBUS_GNUC_EXTENSION
+#endif
+
+#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4)
+#define _DBUS_GNUC_PRINTF( format_idx, arg_idx ) \
+ __attribute__((__format__ (__printf__, format_idx, arg_idx)))
+#define _DBUS_GNUC_NORETURN \
+ __attribute__((__noreturn__))
+#else /* !__GNUC__ */
+#define _DBUS_GNUC_PRINTF( format_idx, arg_idx )
+#define _DBUS_GNUC_NORETURN
+#endif /* !__GNUC__ */
+
+/** @def _DBUS_GNUC_PRINTF
+ * used to tell gcc about printf format strings
+ */
+/** @def _DBUS_GNUC_NORETURN
+ * used to tell gcc about functions that never return, such as _dbus_abort()
+ */
+
+
+/* Normally docs are in .c files, but there isn't a .c file for this. */
+/**
+ * @defgroup DBusMacros Utility macros
+ * @ingroup DBus
+ * @brief #TRUE, #FALSE, #NULL, and so on
+ *
+ * Utility macros.
+ *
+ * @{
+ */
+
+/**
+ * @def DBUS_BEGIN_DECLS
+ *
+ * Macro used prior to declaring functions in the D-Bus header
+ * files. Expands to "extern "C"" when using a C++ compiler,
+ * and expands to nothing when using a C compiler.
+ *
+ * Please don't use this in your own code, consider it
+ * D-Bus internal.
+ */
+/**
+ * @def DBUS_END_DECLS
+ *
+ * Macro used after declaring functions in the D-Bus header
+ * files. Expands to "}" when using a C++ compiler,
+ * and expands to nothing when using a C compiler.
+ *
+ * Please don't use this in your own code, consider it
+ * D-Bus internal.
+ */
+/**
+ * @def TRUE
+ *
+ * Expands to "1"
+ */
+/**
+ * @def FALSE
+ *
+ * Expands to "0"
+ */
+/**
+ * @def NULL
+ *
+ * A null pointer, defined appropriately for C or C++.
+ */
+/**
+ * @def DBUS_DEPRECATED
+ *
+ * Tells the compiler to warn about a function or type if it's used.
+ * Code marked in this way should also be enclosed in
+ * @code
+ * #ifndef DBUS_DISABLE_DEPRECATED
+ * deprecated stuff here
+ * #endif
+ * @endcode
+ *
+ * Please don't use this in your own code, consider it
+ * D-Bus internal.
+ */
+/**
+ * @def _DBUS_GNUC_EXTENSION
+ *
+ * Tells gcc not to warn about extensions to the C standard in the
+ * following expression, even if compiling with -pedantic. Do not use
+ * this macro in your own code; please consider it to be internal to libdbus.
+ */
+
+/*
+ * @def DBUS_EXPORT
+ *
+ * Declare the following symbol as public. This is currently a noop on
+ * platforms other than Windows.
+ */
+
+#if defined(_WIN32)
+# if defined(DBUS_STATIC_BUILD)
+# define DBUS_EXPORT
+# elif defined(dbus_1_EXPORTS)
+# define DBUS_EXPORT __declspec(dllexport)
+# else
+# define DBUS_EXPORT __declspec(dllimport)
+# endif
+#else
+#define DBUS_EXPORT
+#endif
+
+/** @} */
+
+#endif /* DBUS_MACROS_H */
diff --git a/lib-x86-32/include/dbus-1/dbus/dbus-mainloop.h b/lib-x86-32/include/dbus-1/dbus/dbus-mainloop.h
new file mode 100644
index 00000000..656f8231
--- /dev/null
+++ b/lib-x86-32/include/dbus-1/dbus/dbus-mainloop.h
@@ -0,0 +1,76 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-mainloop.h Main loop utility
+ *
+ * Copyright (C) 2003 Red Hat, Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef DBUS_MAINLOOP_H
+#define DBUS_MAINLOOP_H
+
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+
+#include <dbus/dbus.h>
+
+typedef struct DBusLoop DBusLoop;
+
+typedef dbus_bool_t (* DBusWatchFunction) (DBusWatch *watch,
+ unsigned int condition,
+ void *data);
+typedef void (* DBusTimeoutFunction) (DBusTimeout *timeout,
+ void *data);
+
+DBusLoop* _dbus_loop_new (void);
+DBusLoop* _dbus_loop_ref (DBusLoop *loop);
+void _dbus_loop_unref (DBusLoop *loop);
+dbus_bool_t _dbus_loop_add_watch (DBusLoop *loop,
+ DBusWatch *watch,
+ DBusWatchFunction function,
+ void *data,
+ DBusFreeFunction free_data_func);
+void _dbus_loop_remove_watch (DBusLoop *loop,
+ DBusWatch *watch,
+ DBusWatchFunction function,
+ void *data);
+dbus_bool_t _dbus_loop_add_timeout (DBusLoop *loop,
+ DBusTimeout *timeout,
+ DBusTimeoutFunction function,
+ void *data,
+ DBusFreeFunction free_data_func);
+void _dbus_loop_remove_timeout (DBusLoop *loop,
+ DBusTimeout *timeout,
+ DBusTimeoutFunction function,
+ void *data);
+
+dbus_bool_t _dbus_loop_queue_dispatch (DBusLoop *loop,
+ DBusConnection *connection);
+
+void _dbus_loop_run (DBusLoop *loop);
+void _dbus_loop_quit (DBusLoop *loop);
+dbus_bool_t _dbus_loop_iterate (DBusLoop *loop,
+ dbus_bool_t block);
+dbus_bool_t _dbus_loop_dispatch (DBusLoop *loop);
+
+int _dbus_get_oom_wait (void);
+void _dbus_wait_for_memory (void);
+
+#endif /* !DOXYGEN_SHOULD_SKIP_THIS */
+
+#endif /* DBUS_MAINLOOP_H */
+
diff --git a/lib-x86-32/include/dbus-1/dbus/dbus-marshal-basic.h b/lib-x86-32/include/dbus-1/dbus/dbus-marshal-basic.h
new file mode 100644
index 00000000..0c27fc9e
--- /dev/null
+++ b/lib-x86-32/include/dbus-1/dbus/dbus-marshal-basic.h
@@ -0,0 +1,273 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-marshal-basic.h Marshalling routines for basic (primitive) types
+ *
+ * Copyright (C) 2002 CodeFactory AB
+ * Copyright (C) 2004, 2005 Red Hat, Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef DBUS_MARSHAL_BASIC_H
+#define DBUS_MARSHAL_BASIC_H
+
+#ifdef HAVE_BYTESWAP_H
+#include <byteswap.h>
+#endif
+
+#include <dbus/dbus-protocol.h>
+#include <dbus/dbus-types.h>
+#include <dbus/dbus-arch-deps.h>
+#include <dbus/dbus-string.h>
+
+#ifdef WORDS_BIGENDIAN
+#define DBUS_COMPILER_BYTE_ORDER DBUS_BIG_ENDIAN
+#else
+#define DBUS_COMPILER_BYTE_ORDER DBUS_LITTLE_ENDIAN
+#endif
+
+#ifdef HAVE_BYTESWAP_H
+#define DBUS_UINT16_SWAP_LE_BE_CONSTANT(val) bswap_16(val)
+#define DBUS_UINT32_SWAP_LE_BE_CONSTANT(val) bswap_32(val)
+#else /* HAVE_BYTESWAP_H */
+
+#define DBUS_UINT16_SWAP_LE_BE_CONSTANT(val) ((dbus_uint16_t) ( \
+ (dbus_uint16_t) ((dbus_uint16_t) (val) >> 8) | \
+ (dbus_uint16_t) ((dbus_uint16_t) (val) << 8)))
+
+#define DBUS_UINT32_SWAP_LE_BE_CONSTANT(val) ((dbus_uint32_t) ( \
+ (((dbus_uint32_t) (val) & (dbus_uint32_t) 0x000000ffU) << 24) | \
+ (((dbus_uint32_t) (val) & (dbus_uint32_t) 0x0000ff00U) << 8) | \
+ (((dbus_uint32_t) (val) & (dbus_uint32_t) 0x00ff0000U) >> 8) | \
+ (((dbus_uint32_t) (val) & (dbus_uint32_t) 0xff000000U) >> 24)))
+
+#endif /* HAVE_BYTESWAP_H */
+
+#ifdef DBUS_HAVE_INT64
+
+#ifdef HAVE_BYTESWAP_H
+#define DBUS_UINT64_SWAP_LE_BE_CONSTANT(val) bswap_64(val)
+#else /* HAVE_BYTESWAP_H */
+
+#define DBUS_UINT64_SWAP_LE_BE_CONSTANT(val) ((dbus_uint64_t) ( \
+ (((dbus_uint64_t) (val) & \
+ (dbus_uint64_t) DBUS_UINT64_CONSTANT (0x00000000000000ff)) << 56) | \
+ (((dbus_uint64_t) (val) & \
+ (dbus_uint64_t) DBUS_UINT64_CONSTANT (0x000000000000ff00)) << 40) | \
+ (((dbus_uint64_t) (val) & \
+ (dbus_uint64_t) DBUS_UINT64_CONSTANT (0x0000000000ff0000)) << 24) | \
+ (((dbus_uint64_t) (val) & \
+ (dbus_uint64_t) DBUS_UINT64_CONSTANT (0x00000000ff000000)) << 8) | \
+ (((dbus_uint64_t) (val) & \
+ (dbus_uint64_t) DBUS_UINT64_CONSTANT (0x000000ff00000000)) >> 8) | \
+ (((dbus_uint64_t) (val) & \
+ (dbus_uint64_t) DBUS_UINT64_CONSTANT (0x0000ff0000000000)) >> 24) | \
+ (((dbus_uint64_t) (val) & \
+ (dbus_uint64_t) DBUS_UINT64_CONSTANT (0x00ff000000000000)) >> 40) | \
+ (((dbus_uint64_t) (val) & \
+ (dbus_uint64_t) DBUS_UINT64_CONSTANT (0xff00000000000000)) >> 56)))
+#endif /* DBUS_HAVE_INT64 */
+
+#endif /* HAVE_BYTESWAP_H */
+
+#define DBUS_UINT16_SWAP_LE_BE(val) (DBUS_UINT16_SWAP_LE_BE_CONSTANT (val))
+#define DBUS_INT16_SWAP_LE_BE(val) ((dbus_int16_t)DBUS_UINT16_SWAP_LE_BE_CONSTANT (val))
+
+#define DBUS_UINT32_SWAP_LE_BE(val) (DBUS_UINT32_SWAP_LE_BE_CONSTANT (val))
+#define DBUS_INT32_SWAP_LE_BE(val) ((dbus_int32_t)DBUS_UINT32_SWAP_LE_BE_CONSTANT (val))
+
+#ifdef DBUS_HAVE_INT64
+# define DBUS_UINT64_SWAP_LE_BE(val) (DBUS_UINT64_SWAP_LE_BE_CONSTANT (val))
+# define DBUS_INT64_SWAP_LE_BE(val) ((dbus_int64_t)DBUS_UINT64_SWAP_LE_BE_CONSTANT (val))
+#endif /* DBUS_HAVE_INT64 */
+
+#ifdef WORDS_BIGENDIAN
+
+# define DBUS_INT16_TO_BE(val) ((dbus_int16_t) (val))
+# define DBUS_UINT16_TO_BE(val) ((dbus_uint16_t) (val))
+# define DBUS_INT16_TO_LE(val) (DBUS_INT16_SWAP_LE_BE (val))
+# define DBUS_UINT16_TO_LE(val) (DBUS_UINT16_SWAP_LE_BE (val))
+# define DBUS_INT32_TO_BE(val) ((dbus_int32_t) (val))
+# define DBUS_UINT32_TO_BE(val) ((dbus_uint32_t) (val))
+# define DBUS_INT32_TO_LE(val) (DBUS_INT32_SWAP_LE_BE (val))
+# define DBUS_UINT32_TO_LE(val) (DBUS_UINT32_SWAP_LE_BE (val))
+# ifdef DBUS_HAVE_INT64
+# define DBUS_INT64_TO_BE(val) ((dbus_int64_t) (val))
+# define DBUS_UINT64_TO_BE(val) ((dbus_uint64_t) (val))
+# define DBUS_INT64_TO_LE(val) (DBUS_INT64_SWAP_LE_BE (val))
+# define DBUS_UINT64_TO_LE(val) (DBUS_UINT64_SWAP_LE_BE (val))
+# endif /* DBUS_HAVE_INT64 */
+
+#else /* WORDS_BIGENDIAN */
+
+# define DBUS_INT16_TO_LE(val) ((dbus_int16_t) (val))
+# define DBUS_UINT16_TO_LE(val) ((dbus_uint16_t) (val))
+# define DBUS_INT16_TO_BE(val) ((dbus_int16_t) DBUS_UINT16_SWAP_LE_BE (val))
+# define DBUS_UINT16_TO_BE(val) (DBUS_UINT16_SWAP_LE_BE (val))
+# define DBUS_INT32_TO_LE(val) ((dbus_int32_t) (val))
+# define DBUS_UINT32_TO_LE(val) ((dbus_uint32_t) (val))
+# define DBUS_INT32_TO_BE(val) ((dbus_int32_t) DBUS_UINT32_SWAP_LE_BE (val))
+# define DBUS_UINT32_TO_BE(val) (DBUS_UINT32_SWAP_LE_BE (val))
+# ifdef DBUS_HAVE_INT64
+# define DBUS_INT64_TO_LE(val) ((dbus_int64_t) (val))
+# define DBUS_UINT64_TO_LE(val) ((dbus_uint64_t) (val))
+# define DBUS_INT64_TO_BE(val) ((dbus_int64_t) DBUS_UINT64_SWAP_LE_BE (val))
+# define DBUS_UINT64_TO_BE(val) (DBUS_UINT64_SWAP_LE_BE (val))
+# endif /* DBUS_HAVE_INT64 */
+#endif
+
+/* The transformation is symmetric, so the FROM just maps to the TO. */
+#define DBUS_INT16_FROM_LE(val) (DBUS_INT16_TO_LE (val))
+#define DBUS_UINT16_FROM_LE(val) (DBUS_UINT16_TO_LE (val))
+#define DBUS_INT16_FROM_BE(val) (DBUS_INT16_TO_BE (val))
+#define DBUS_UINT16_FROM_BE(val) (DBUS_UINT16_TO_BE (val))
+#define DBUS_INT32_FROM_LE(val) (DBUS_INT32_TO_LE (val))
+#define DBUS_UINT32_FROM_LE(val) (DBUS_UINT32_TO_LE (val))
+#define DBUS_INT32_FROM_BE(val) (DBUS_INT32_TO_BE (val))
+#define DBUS_UINT32_FROM_BE(val) (DBUS_UINT32_TO_BE (val))
+#ifdef DBUS_HAVE_INT64
+# define DBUS_INT64_FROM_LE(val) (DBUS_INT64_TO_LE (val))
+# define DBUS_UINT64_FROM_LE(val) (DBUS_UINT64_TO_LE (val))
+# define DBUS_INT64_FROM_BE(val) (DBUS_INT64_TO_BE (val))
+# define DBUS_UINT64_FROM_BE(val) (DBUS_UINT64_TO_BE (val))
+#endif /* DBUS_HAVE_INT64 */
+
+#ifndef DBUS_HAVE_INT64
+/**
+ * An 8-byte struct you could use to access int64 without having
+ * int64 support
+ */
+typedef struct
+{
+ dbus_uint32_t first32; /**< first 32 bits in the 8 bytes (beware endian issues) */
+ dbus_uint32_t second32; /**< second 32 bits in the 8 bytes (beware endian issues) */
+} DBus8ByteStruct;
+#endif /* DBUS_HAVE_INT64 */
+
+/**
+ * A simple 8-byte value union that lets you access 8 bytes as if they
+ * were various types; useful when dealing with basic types via
+ * void pointers and varargs.
+ */
+typedef union
+{
+ dbus_int16_t i16; /**< as int16 */
+ dbus_uint16_t u16; /**< as int16 */
+ dbus_int32_t i32; /**< as int32 */
+ dbus_uint32_t u32; /**< as int32 */
+#ifdef DBUS_HAVE_INT64
+ dbus_int64_t i64; /**< as int64 */
+ dbus_uint64_t u64; /**< as int64 */
+#else
+ DBus8ByteStruct u64; /**< as 8-byte-struct */
+#endif
+ double dbl; /**< as double */
+ unsigned char byt; /**< as byte */
+ char *str; /**< as char* */
+} DBusBasicValue;
+
+#ifdef DBUS_DISABLE_ASSERT
+#define _dbus_unpack_uint16(byte_order, data) \
+ (((byte_order) == DBUS_LITTLE_ENDIAN) ? \
+ DBUS_UINT16_FROM_LE (*(dbus_uint16_t*)(data)) : \
+ DBUS_UINT16_FROM_BE (*(dbus_uint16_t*)(data)))
+
+#define _dbus_unpack_uint32(byte_order, data) \
+ (((byte_order) == DBUS_LITTLE_ENDIAN) ? \
+ DBUS_UINT32_FROM_LE (*(dbus_uint32_t*)(data)) : \
+ DBUS_UINT32_FROM_BE (*(dbus_uint32_t*)(data)))
+#endif
+
+#ifndef _dbus_unpack_uint16
+dbus_uint16_t _dbus_unpack_uint16 (int byte_order,
+ const unsigned char *data);
+#endif
+
+void _dbus_pack_uint32 (dbus_uint32_t value,
+ int byte_order,
+ unsigned char *data);
+#ifndef _dbus_unpack_uint32
+dbus_uint32_t _dbus_unpack_uint32 (int byte_order,
+ const unsigned char *data);
+#endif
+
+dbus_bool_t _dbus_marshal_set_basic (DBusString *str,
+ int pos,
+ int type,
+ const void *value,
+ int byte_order,
+ int *old_end_pos,
+ int *new_end_pos);
+dbus_bool_t _dbus_marshal_write_basic (DBusString *str,
+ int insert_at,
+ int type,
+ const void *value,
+ int byte_order,
+ int *pos_after);
+dbus_bool_t _dbus_marshal_write_fixed_multi (DBusString *str,
+ int insert_at,
+ int element_type,
+ const void *value,
+ int n_elements,
+ int byte_order,
+ int *pos_after);
+void _dbus_marshal_read_basic (const DBusString *str,
+ int pos,
+ int type,
+ void *value,
+ int byte_order,
+ int *new_pos);
+void _dbus_marshal_read_fixed_multi (const DBusString *str,
+ int pos,
+ int element_type,
+ void *value,
+ int n_elements,
+ int byte_order,
+ int *new_pos);
+void _dbus_marshal_skip_basic (const DBusString *str,
+ int type,
+ int byte_order,
+ int *pos);
+void _dbus_marshal_skip_array (const DBusString *str,
+ int element_type,
+ int byte_order,
+ int *pos);
+void _dbus_marshal_set_uint32 (DBusString *str,
+ int pos,
+ dbus_uint32_t value,
+ int byte_order);
+dbus_uint32_t _dbus_marshal_read_uint32 (const DBusString *str,
+ int pos,
+ int byte_order,
+ int *new_pos);
+dbus_bool_t _dbus_type_is_valid (int typecode);
+int _dbus_type_get_alignment (int typecode);
+dbus_bool_t _dbus_type_is_fixed (int typecode);
+int _dbus_type_get_alignment (int typecode);
+const char* _dbus_type_to_string (int typecode);
+
+int _dbus_first_type_in_signature (const DBusString *str,
+ int pos);
+
+int _dbus_first_type_in_signature_c_str (const char *str,
+ int pos);
+
+void _dbus_swap_array (unsigned char *data,
+ int n_elements,
+ int alignment);
+
+#endif /* DBUS_MARSHAL_BASIC_H */
diff --git a/lib-x86-32/include/dbus-1/dbus/dbus-marshal-byteswap.h b/lib-x86-32/include/dbus-1/dbus/dbus-marshal-byteswap.h
new file mode 100644
index 00000000..be2dd758
--- /dev/null
+++ b/lib-x86-32/include/dbus-1/dbus/dbus-marshal-byteswap.h
@@ -0,0 +1,37 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-marshal-byteswap.h Swap a block of marshaled data
+ *
+ * Copyright (C) 2005 Red Hat, Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef DBUS_MARSHAL_BYTESWAP_H
+#define DBUS_MARSHAL_BYTESWAP_H
+
+#include <dbus/dbus-protocol.h>
+#include <dbus/dbus-marshal-recursive.h>
+
+void _dbus_marshal_byteswap (const DBusString *signature,
+ int signature_start,
+ int old_byte_order,
+ int new_byte_order,
+ DBusString *value_str,
+ int value_pos);
+
+#endif /* DBUS_MARSHAL_BYTESWAP_H */
diff --git a/lib-x86-32/include/dbus-1/dbus/dbus-marshal-header.h b/lib-x86-32/include/dbus-1/dbus/dbus-marshal-header.h
new file mode 100644
index 00000000..fd16c5f0
--- /dev/null
+++ b/lib-x86-32/include/dbus-1/dbus/dbus-marshal-header.h
@@ -0,0 +1,128 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-marshal-header.h Managing marshaling/demarshaling of message headers
+ *
+ * Copyright (C) 2005 Red Hat, Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef DBUS_MARSHAL_HEADER_H
+#define DBUS_MARSHAL_HEADER_H
+
+#include <dbus/dbus-marshal-basic.h>
+#include <dbus/dbus-marshal-validate.h>
+
+typedef struct DBusHeader DBusHeader;
+typedef struct DBusHeaderField DBusHeaderField;
+
+#define _DBUS_HEADER_FIELD_VALUE_UNKNOWN -1
+#define _DBUS_HEADER_FIELD_VALUE_NONEXISTENT -2
+
+/**
+ * Cached information about a header field in the message
+ */
+struct DBusHeaderField
+{
+ int value_pos; /**< Position of field value, or -1/-2 */
+};
+
+/**
+ * Message header data and some cached details of it.
+ */
+struct DBusHeader
+{
+ DBusString data; /**< Header network data, stored
+ * separately from body so we can
+ * independently realloc it.
+ */
+
+ DBusHeaderField fields[DBUS_HEADER_FIELD_LAST + 1]; /**< Track the location
+ * of each field in header
+ */
+
+ dbus_uint32_t padding : 3; /**< bytes of alignment in header */
+ dbus_uint32_t byte_order : 8; /**< byte order of header */
+};
+
+dbus_bool_t _dbus_header_init (DBusHeader *header,
+ int byte_order);
+void _dbus_header_free (DBusHeader *header);
+void _dbus_header_reinit (DBusHeader *header,
+ int byte_order);
+dbus_bool_t _dbus_header_create (DBusHeader *header,
+ int type,
+ const char *destination,
+ const char *path,
+ const char *interface,
+ const char *member,
+ const char *error_name);
+dbus_bool_t _dbus_header_copy (const DBusHeader *header,
+ DBusHeader *dest);
+int _dbus_header_get_message_type (DBusHeader *header);
+void _dbus_header_set_serial (DBusHeader *header,
+ dbus_uint32_t serial);
+dbus_uint32_t _dbus_header_get_serial (DBusHeader *header);
+void _dbus_header_update_lengths (DBusHeader *header,
+ int body_len);
+dbus_bool_t _dbus_header_set_field_basic (DBusHeader *header,
+ int field,
+ int type,
+ const void *value);
+dbus_bool_t _dbus_header_get_field_basic (DBusHeader *header,
+ int field,
+ int type,
+ void *value);
+dbus_bool_t _dbus_header_get_field_raw (DBusHeader *header,
+ int field,
+ const DBusString **str,
+ int *pos);
+dbus_bool_t _dbus_header_delete_field (DBusHeader *header,
+ int field);
+void _dbus_header_toggle_flag (DBusHeader *header,
+ dbus_uint32_t flag,
+ dbus_bool_t value);
+dbus_bool_t _dbus_header_get_flag (DBusHeader *header,
+ dbus_uint32_t flag);
+dbus_bool_t _dbus_header_ensure_signature (DBusHeader *header,
+ DBusString **type_str,
+ int *type_pos);
+dbus_bool_t _dbus_header_have_message_untrusted (int max_message_length,
+ DBusValidity *validity,
+ int *byte_order,
+ int *fields_array_len,
+ int *header_len,
+ int *body_len,
+ const DBusString *str,
+ int start,
+ int len);
+dbus_bool_t _dbus_header_load (DBusHeader *header,
+ DBusValidationMode mode,
+ DBusValidity *validity,
+ int byte_order,
+ int fields_array_len,
+ int header_len,
+ int body_len,
+ const DBusString *str,
+ int start,
+ int len);
+void _dbus_header_byteswap (DBusHeader *header,
+ int new_order);
+
+
+
+#endif /* DBUS_MARSHAL_HEADER_H */
diff --git a/lib-x86-32/include/dbus-1/dbus/dbus-marshal-recursive.h b/lib-x86-32/include/dbus-1/dbus/dbus-marshal-recursive.h
new file mode 100644
index 00000000..97e5466b
--- /dev/null
+++ b/lib-x86-32/include/dbus-1/dbus/dbus-marshal-recursive.h
@@ -0,0 +1,191 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-marshal-recursive.h Marshalling routines for recursive types
+ *
+ * Copyright (C) 2004, 2005 Red Hat, Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef DBUS_MARSHAL_RECURSIVE_H
+#define DBUS_MARSHAL_RECURSIVE_H
+
+#include <dbus/dbus-protocol.h>
+#include <dbus/dbus-list.h>
+
+typedef struct DBusTypeReader DBusTypeReader;
+typedef struct DBusTypeWriter DBusTypeWriter;
+typedef struct DBusTypeReaderClass DBusTypeReaderClass;
+typedef struct DBusArrayLenFixup DBusArrayLenFixup;
+
+/**
+ * The type reader is an iterator for reading values from a block of
+ * values.
+ */
+struct DBusTypeReader
+{
+ dbus_uint32_t byte_order : 8; /**< byte order of the block */
+
+ dbus_uint32_t finished : 1; /**< marks we're at end iterator for cases
+ * where we don't have another way to tell
+ */
+ dbus_uint32_t array_len_offset : 3; /**< bytes back from start_pos that len ends */
+ const DBusString *type_str; /**< string containing signature of block */
+ int type_pos; /**< current position in signature */
+ const DBusString *value_str; /**< string containing values of block */
+ int value_pos; /**< current position in values */
+
+ const DBusTypeReaderClass *klass; /**< the vtable for the reader */
+ union
+ {
+ struct {
+ int start_pos; /**< for array readers, the start of the array values */
+ } array;
+ } u; /**< class-specific data */
+};
+
+/**
+ * The type writer is an iterator for writing to a block of values.
+ */
+struct DBusTypeWriter
+{
+ dbus_uint32_t byte_order : 8; /**< byte order to write values with */
+
+ dbus_uint32_t container_type : 8; /**< what are we inside? (e.g. struct, variant, array) */
+
+ dbus_uint32_t type_pos_is_expectation : 1; /**< type_pos can be either an insertion point for or an expected next type */
+
+ dbus_uint32_t enabled : 1; /**< whether to write values */
+
+ DBusString *type_str; /**< where to write typecodes (or read type expectations) */
+ int type_pos; /**< current pos in type_str */
+ DBusString *value_str; /**< where to write values */
+ int value_pos; /**< next position to write */
+
+ union
+ {
+ struct {
+ int start_pos; /**< position of first element in the array */
+ int len_pos; /**< position of length of the array */
+ int element_type_pos; /**< position of array element type in type_str */
+ } array;
+ } u; /**< class-specific data */
+};
+
+/**
+ * When modifying an existing block of values, array lengths may need
+ * to be adjusted; those adjustments are described by this struct.
+ */
+struct DBusArrayLenFixup
+{
+ int len_pos_in_reader; /**< where the length was in the original block */
+ int new_len; /**< the new value of the length in the written-out block */
+};
+
+void _dbus_type_reader_init (DBusTypeReader *reader,
+ int byte_order,
+ const DBusString *type_str,
+ int type_pos,
+ const DBusString *value_str,
+ int value_pos);
+void _dbus_type_reader_init_types_only (DBusTypeReader *reader,
+ const DBusString *type_str,
+ int type_pos);
+int _dbus_type_reader_get_current_type (const DBusTypeReader *reader);
+int _dbus_type_reader_get_element_type (const DBusTypeReader *reader);
+int _dbus_type_reader_get_value_pos (const DBusTypeReader *reader);
+void _dbus_type_reader_read_basic (const DBusTypeReader *reader,
+ void *value);
+int _dbus_type_reader_get_array_length (const DBusTypeReader *reader);
+void _dbus_type_reader_read_fixed_multi (const DBusTypeReader *reader,
+ void *value,
+ int *n_elements);
+void _dbus_type_reader_read_raw (const DBusTypeReader *reader,
+ const unsigned char **value_location);
+void _dbus_type_reader_recurse (DBusTypeReader *reader,
+ DBusTypeReader *subreader);
+dbus_bool_t _dbus_type_reader_next (DBusTypeReader *reader);
+dbus_bool_t _dbus_type_reader_has_next (const DBusTypeReader *reader);
+void _dbus_type_reader_get_signature (const DBusTypeReader *reader,
+ const DBusString **str_p,
+ int *start_p,
+ int *len_p);
+dbus_bool_t _dbus_type_reader_set_basic (DBusTypeReader *reader,
+ const void *value,
+ const DBusTypeReader *realign_root);
+dbus_bool_t _dbus_type_reader_delete (DBusTypeReader *reader,
+ const DBusTypeReader *realign_root);
+dbus_bool_t _dbus_type_reader_greater_than (const DBusTypeReader *lhs,
+ const DBusTypeReader *rhs);
+
+dbus_bool_t _dbus_type_reader_equal_values (const DBusTypeReader *lhs,
+ const DBusTypeReader *rhs);
+
+void _dbus_type_signature_next (const char *signature,
+ int *type_pos);
+
+void _dbus_type_writer_init (DBusTypeWriter *writer,
+ int byte_order,
+ DBusString *type_str,
+ int type_pos,
+ DBusString *value_str,
+ int value_pos);
+void _dbus_type_writer_init_types_delayed (DBusTypeWriter *writer,
+ int byte_order,
+ DBusString *value_str,
+ int value_pos);
+void _dbus_type_writer_add_types (DBusTypeWriter *writer,
+ DBusString *type_str,
+ int type_pos);
+void _dbus_type_writer_remove_types (DBusTypeWriter *writer);
+void _dbus_type_writer_init_values_only (DBusTypeWriter *writer,
+ int byte_order,
+ const DBusString *type_str,
+ int type_pos,
+ DBusString *value_str,
+ int value_pos);
+dbus_bool_t _dbus_type_writer_write_basic (DBusTypeWriter *writer,
+ int type,
+ const void *value);
+dbus_bool_t _dbus_type_writer_write_fixed_multi (DBusTypeWriter *writer,
+ int element_type,
+ const void *value,
+ int n_elements);
+dbus_bool_t _dbus_type_writer_recurse (DBusTypeWriter *writer,
+ int container_type,
+ const DBusString *contained_type,
+ int contained_type_start,
+ DBusTypeWriter *sub);
+dbus_bool_t _dbus_type_writer_unrecurse (DBusTypeWriter *writer,
+ DBusTypeWriter *sub);
+dbus_bool_t _dbus_type_writer_append_array (DBusTypeWriter *writer,
+ const DBusString *contained_type,
+ int contained_type_start,
+ DBusTypeWriter *sub);
+dbus_bool_t _dbus_type_writer_write_reader (DBusTypeWriter *writer,
+ DBusTypeReader *reader);
+dbus_bool_t _dbus_type_writer_write_reader_partial (DBusTypeWriter *writer,
+ DBusTypeReader *reader,
+ const DBusTypeReader *start_after,
+ int start_after_new_pos,
+ int start_after_new_len,
+ DBusList **fixups);
+void _dbus_type_writer_set_enabled (DBusTypeWriter *writer,
+ dbus_bool_t enabled);
+
+
+#endif /* DBUS_MARSHAL_RECURSIVE_H */
diff --git a/lib-x86-32/include/dbus-1/dbus/dbus-marshal-validate.h b/lib-x86-32/include/dbus-1/dbus/dbus-marshal-validate.h
new file mode 100644
index 00000000..5817de32
--- /dev/null
+++ b/lib-x86-32/include/dbus-1/dbus/dbus-marshal-validate.h
@@ -0,0 +1,198 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-marshal-validate.h Validation routines for marshaled data
+ *
+ * Copyright (C) 2005 Red Hat, Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef DBUS_MARSHAL_VALIDATE_H
+#define DBUS_MARSHAL_VALIDATE_H
+
+/**
+ * @addtogroup DBusMarshal
+ *
+ * @{
+ */
+
+/**
+ * This is used rather than a bool for high visibility
+ */
+typedef enum
+{
+ DBUS_VALIDATION_MODE_WE_TRUST_THIS_DATA_ABSOLUTELY,
+ DBUS_VALIDATION_MODE_DATA_IS_UNTRUSTED
+} DBusValidationMode;
+
+/**
+ * This is primarily used in unit testing, so we can verify that each
+ * invalid message is invalid for the expected reasons. Thus we really
+ * want a distinct enum value for every codepath leaving the validator
+ * functions. Enum values are specified manually for ease of debugging
+ * (so you can see the enum value given a printf)
+ */
+typedef enum
+{
+#define _DBUS_NEGATIVE_VALIDITY_COUNT 4
+ DBUS_VALIDITY_UNKNOWN_OOM_ERROR = -4, /**< can't determine validity due to OOM */
+ DBUS_INVALID_FOR_UNKNOWN_REASON = -3,
+ DBUS_VALID_BUT_INCOMPLETE = -2,
+ DBUS_VALIDITY_UNKNOWN = -1,
+ DBUS_VALID = 0, /**< the data is valid */
+ DBUS_INVALID_UNKNOWN_TYPECODE = 1,
+ DBUS_INVALID_MISSING_ARRAY_ELEMENT_TYPE = 2,
+ DBUS_INVALID_SIGNATURE_TOO_LONG = 3, /* this one is impossible right now since
+ * you can't put a too-long value in a byte
+ */
+ DBUS_INVALID_EXCEEDED_MAXIMUM_ARRAY_RECURSION = 4,
+ DBUS_INVALID_EXCEEDED_MAXIMUM_STRUCT_RECURSION = 5,
+ DBUS_INVALID_STRUCT_ENDED_BUT_NOT_STARTED = 6,
+ DBUS_INVALID_STRUCT_STARTED_BUT_NOT_ENDED = 7,
+ DBUS_INVALID_STRUCT_HAS_NO_FIELDS = 8,
+ DBUS_INVALID_ALIGNMENT_PADDING_NOT_NUL = 9,
+ DBUS_INVALID_BOOLEAN_NOT_ZERO_OR_ONE = 10,
+ DBUS_INVALID_NOT_ENOUGH_DATA = 11,
+ DBUS_INVALID_TOO_MUCH_DATA = 12, /**< trailing junk makes it invalid */
+ DBUS_INVALID_BAD_BYTE_ORDER = 13,
+ DBUS_INVALID_BAD_PROTOCOL_VERSION = 14,
+ DBUS_INVALID_BAD_MESSAGE_TYPE = 15,
+ DBUS_INVALID_BAD_SERIAL = 16,
+ DBUS_INVALID_INSANE_FIELDS_ARRAY_LENGTH = 17,
+ DBUS_INVALID_INSANE_BODY_LENGTH = 18,
+ DBUS_INVALID_MESSAGE_TOO_LONG = 19,
+ DBUS_INVALID_HEADER_FIELD_CODE = 20,
+ DBUS_INVALID_HEADER_FIELD_HAS_WRONG_TYPE = 21,
+ DBUS_INVALID_USES_LOCAL_INTERFACE = 22,
+ DBUS_INVALID_USES_LOCAL_PATH = 23,
+ DBUS_INVALID_HEADER_FIELD_APPEARS_TWICE = 24,
+ DBUS_INVALID_BAD_DESTINATION = 25,
+ DBUS_INVALID_BAD_INTERFACE = 26,
+ DBUS_INVALID_BAD_MEMBER = 27,
+ DBUS_INVALID_BAD_ERROR_NAME = 28,
+ DBUS_INVALID_BAD_SENDER = 29,
+ DBUS_INVALID_MISSING_PATH = 30,
+ DBUS_INVALID_MISSING_INTERFACE = 31,
+ DBUS_INVALID_MISSING_MEMBER = 32,
+ DBUS_INVALID_MISSING_ERROR_NAME = 33,
+ DBUS_INVALID_MISSING_REPLY_SERIAL = 34,
+ DBUS_INVALID_LENGTH_OUT_OF_BOUNDS = 35,
+ DBUS_INVALID_ARRAY_LENGTH_EXCEEDS_MAXIMUM = 36,
+ DBUS_INVALID_BAD_PATH = 37,
+ DBUS_INVALID_SIGNATURE_LENGTH_OUT_OF_BOUNDS = 38,
+ DBUS_INVALID_BAD_UTF8_IN_STRING = 39,
+ DBUS_INVALID_ARRAY_LENGTH_INCORRECT = 40,
+ DBUS_INVALID_VARIANT_SIGNATURE_LENGTH_OUT_OF_BOUNDS = 41,
+ DBUS_INVALID_VARIANT_SIGNATURE_BAD = 42,
+ DBUS_INVALID_VARIANT_SIGNATURE_EMPTY = 43,
+ DBUS_INVALID_VARIANT_SIGNATURE_SPECIFIES_MULTIPLE_VALUES = 44,
+ DBUS_INVALID_VARIANT_SIGNATURE_MISSING_NUL = 45,
+ DBUS_INVALID_STRING_MISSING_NUL = 46,
+ DBUS_INVALID_SIGNATURE_MISSING_NUL = 47,
+ DBUS_INVALID_EXCEEDED_MAXIMUM_DICT_ENTRY_RECURSION = 48,
+ DBUS_INVALID_DICT_ENTRY_ENDED_BUT_NOT_STARTED = 49,
+ DBUS_INVALID_DICT_ENTRY_STARTED_BUT_NOT_ENDED = 50,
+ DBUS_INVALID_DICT_ENTRY_HAS_NO_FIELDS = 51,
+ DBUS_INVALID_DICT_ENTRY_HAS_ONLY_ONE_FIELD = 52,
+ DBUS_INVALID_DICT_ENTRY_HAS_TOO_MANY_FIELDS = 53,
+ DBUS_INVALID_DICT_ENTRY_NOT_INSIDE_ARRAY = 54,
+ DBUS_INVALID_DICT_KEY_MUST_BE_BASIC_TYPE = 55,
+ DBUS_INVALID_MISSING_UNIX_FDS = 56,
+ DBUS_VALIDITY_LAST
+} DBusValidity;
+
+DBusValidity _dbus_validate_signature_with_reason (const DBusString *type_str,
+ int type_pos,
+ int len);
+DBusValidity _dbus_validate_body_with_reason (const DBusString *expected_signature,
+ int expected_signature_start,
+ int byte_order,
+ int *bytes_remaining,
+ const DBusString *value_str,
+ int value_pos,
+ int len);
+
+const char *_dbus_validity_to_error_message (DBusValidity validity);
+
+dbus_bool_t _dbus_validate_path (const DBusString *str,
+ int start,
+ int len);
+dbus_bool_t _dbus_validate_interface (const DBusString *str,
+ int start,
+ int len);
+dbus_bool_t _dbus_validate_member (const DBusString *str,
+ int start,
+ int len);
+dbus_bool_t _dbus_validate_error_name (const DBusString *str,
+ int start,
+ int len);
+dbus_bool_t _dbus_validate_bus_name (const DBusString *str,
+ int start,
+ int len);
+dbus_bool_t _dbus_validate_signature (const DBusString *str,
+ int start,
+ int len);
+
+#ifdef DBUS_DISABLE_CHECKS
+
+/* Be sure they don't exist, since we don't want to use them outside of checks
+ * and so we want the compile failure.
+ */
+#define DECLARE_DBUS_NAME_CHECK(what)
+#define DEFINE_DBUS_NAME_CHECK(what)
+
+#else /* !DBUS_DISABLE_CHECKS */
+
+/** A name check is used in _dbus_return_if_fail(), it's not suitable
+ * for validating untrusted data. use _dbus_validate_whatever for that.
+ */
+#define DECLARE_DBUS_NAME_CHECK(what) \
+dbus_bool_t _dbus_check_is_valid_##what (const char *name)
+
+/** Define a name check to be used in _dbus_return_if_fail() statements.
+ */
+#define DEFINE_DBUS_NAME_CHECK(what) \
+dbus_bool_t \
+_dbus_check_is_valid_##what (const char *name) \
+{ \
+ DBusString str; \
+ \
+ if (name == NULL) \
+ return FALSE; \
+ \
+ _dbus_string_init_const (&str, name); \
+ return _dbus_validate_##what (&str, 0, \
+ _dbus_string_get_length (&str)); \
+}
+#endif /* !DBUS_DISABLE_CHECKS */
+
+/** defines _dbus_check_is_valid_path() */
+DECLARE_DBUS_NAME_CHECK(path);
+/** defines _dbus_check_is_valid_interface() */
+DECLARE_DBUS_NAME_CHECK(interface);
+/** defines _dbus_check_is_valid_member() */
+DECLARE_DBUS_NAME_CHECK(member);
+/** defines _dbus_check_is_valid_error_name() */
+DECLARE_DBUS_NAME_CHECK(error_name);
+/** defines _dbus_check_is_valid_bus_name() */
+DECLARE_DBUS_NAME_CHECK(bus_name);
+/** defines _dbus_check_is_valid_signature() */
+DECLARE_DBUS_NAME_CHECK(signature);
+
+/** @} */
+
+#endif /* DBUS_MARSHAL_VALIDATE_H */
diff --git a/lib-x86-32/include/dbus-1/dbus/dbus-memory.h b/lib-x86-32/include/dbus-1/dbus/dbus-memory.h
new file mode 100644
index 00000000..ea28423c
--- /dev/null
+++ b/lib-x86-32/include/dbus-1/dbus/dbus-memory.h
@@ -0,0 +1,65 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-memory.h D-Bus memory handling
+ *
+ * Copyright (C) 2002 Red Hat Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+#if !defined (DBUS_INSIDE_DBUS_H) && !defined (DBUS_COMPILATION)
+#error "Only <dbus/dbus.h> can be included directly, this file may disappear or change contents."
+#endif
+
+#ifndef DBUS_MEMORY_H
+#define DBUS_MEMORY_H
+
+#include <dbus/dbus-macros.h>
+#include <stddef.h>
+
+DBUS_BEGIN_DECLS
+
+/**
+ * @addtogroup DBusMemory
+ * @{
+ */
+
+DBUS_EXPORT
+void* dbus_malloc (size_t bytes);
+DBUS_EXPORT
+void* dbus_malloc0 (size_t bytes);
+DBUS_EXPORT
+void* dbus_realloc (void *memory,
+ size_t bytes);
+DBUS_EXPORT
+void dbus_free (void *memory);
+
+#define dbus_new(type, count) ((type*)dbus_malloc (sizeof (type) * (count)))
+#define dbus_new0(type, count) ((type*)dbus_malloc0 (sizeof (type) * (count)))
+
+DBUS_EXPORT
+void dbus_free_string_array (char **str_array);
+
+typedef void (* DBusFreeFunction) (void *memory);
+
+DBUS_EXPORT
+void dbus_shutdown (void);
+
+/** @} */
+
+DBUS_END_DECLS
+
+#endif /* DBUS_MEMORY_H */
diff --git a/lib-x86-32/include/dbus-1/dbus/dbus-mempool.h b/lib-x86-32/include/dbus-1/dbus/dbus-mempool.h
new file mode 100644
index 00000000..afe52472
--- /dev/null
+++ b/lib-x86-32/include/dbus-1/dbus/dbus-mempool.h
@@ -0,0 +1,44 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-mempool.h Memory pools
+ *
+ * Copyright (C) 2002 Red Hat, Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef DBUS_MEMPOOL_H
+#define DBUS_MEMPOOL_H
+
+#include <dbus/dbus-internals.h>
+#include <dbus/dbus-memory.h>
+#include <dbus/dbus-types.h>
+
+DBUS_BEGIN_DECLS
+
+typedef struct DBusMemPool DBusMemPool;
+
+DBusMemPool* _dbus_mem_pool_new (int element_size,
+ dbus_bool_t zero_elements);
+void _dbus_mem_pool_free (DBusMemPool *pool);
+void* _dbus_mem_pool_alloc (DBusMemPool *pool);
+dbus_bool_t _dbus_mem_pool_dealloc (DBusMemPool *pool,
+ void *element);
+
+DBUS_END_DECLS
+
+#endif /* DBUS_MEMPOOL_H */
diff --git a/lib-x86-32/include/dbus-1/dbus/dbus-message-factory.h b/lib-x86-32/include/dbus-1/dbus/dbus-message-factory.h
new file mode 100644
index 00000000..b0747504
--- /dev/null
+++ b/lib-x86-32/include/dbus-1/dbus/dbus-message-factory.h
@@ -0,0 +1,61 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-message-factory.h Generator of valid and invalid message data for test suite
+ *
+ * Copyright (C) 2005 Red Hat Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef DBUS_MESSAGE_FACTORY_H
+#define DBUS_MESSAGE_FACTORY_H
+
+#ifdef DBUS_BUILD_TESTS
+
+#include <dbus/dbus-string.h>
+#include <dbus/dbus-marshal-basic.h>
+#include <dbus/dbus-marshal-validate.h>
+
+DBUS_BEGIN_DECLS
+
+typedef struct
+{
+ DBusValidity expected_validity;
+
+ DBusString data;
+
+} DBusMessageData;
+
+#define _DBUS_MESSAGE_DATA_MAX_NESTING 10
+typedef struct
+{
+ int sequence_nos[_DBUS_MESSAGE_DATA_MAX_NESTING];
+ int depth;
+ int count;
+} DBusMessageDataIter;
+
+void _dbus_message_data_free (DBusMessageData *data);
+void _dbus_message_data_iter_init (DBusMessageDataIter *iter);
+dbus_bool_t _dbus_message_data_iter_get_and_next (DBusMessageDataIter *iter,
+ DBusMessageData *data);
+
+
+DBUS_END_DECLS
+
+#endif /* DBUS_BUILD_TESTS */
+
+#endif /* DBUS_MESSAGE_FACTORY_H */
diff --git a/lib-x86-32/include/dbus-1/dbus/dbus-message-internal.h b/lib-x86-32/include/dbus-1/dbus/dbus-message-internal.h
new file mode 100644
index 00000000..870934b9
--- /dev/null
+++ b/lib-x86-32/include/dbus-1/dbus/dbus-message-internal.h
@@ -0,0 +1,89 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-message-internal.h DBusMessage object internal interfaces
+ *
+ * Copyright (C) 2002 Red Hat Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+#ifndef DBUS_MESSAGE_INTERNAL_H
+#define DBUS_MESSAGE_INTERNAL_H
+
+#include <dbus/dbus-marshal-validate.h>
+#include <dbus/dbus-message.h>
+#include <dbus/dbus-resources.h>
+#include <dbus/dbus-list.h>
+
+DBUS_BEGIN_DECLS
+
+typedef struct DBusMessageLoader DBusMessageLoader;
+
+void _dbus_message_get_network_data (DBusMessage *message,
+ const DBusString **header,
+ const DBusString **body);
+void _dbus_message_get_unix_fds (DBusMessage *message,
+ const int **fds,
+ unsigned *n_fds);
+
+void _dbus_message_lock (DBusMessage *message);
+void _dbus_message_unlock (DBusMessage *message);
+dbus_bool_t _dbus_message_add_counter (DBusMessage *message,
+ DBusCounter *counter);
+void _dbus_message_add_counter_link (DBusMessage *message,
+ DBusList *link);
+void _dbus_message_remove_counter (DBusMessage *message,
+ DBusCounter *counter,
+ DBusList **link_return);
+
+DBusMessageLoader* _dbus_message_loader_new (void);
+DBusMessageLoader* _dbus_message_loader_ref (DBusMessageLoader *loader);
+void _dbus_message_loader_unref (DBusMessageLoader *loader);
+
+void _dbus_message_loader_get_buffer (DBusMessageLoader *loader,
+ DBusString **buffer);
+void _dbus_message_loader_return_buffer (DBusMessageLoader *loader,
+ DBusString *buffer,
+ int bytes_read);
+
+dbus_bool_t _dbus_message_loader_get_unix_fds (DBusMessageLoader *loader,
+ int **fds,
+ unsigned *max_n_fds);
+void _dbus_message_loader_return_unix_fds (DBusMessageLoader *loader,
+ int *fds,
+ unsigned n_fds);
+
+dbus_bool_t _dbus_message_loader_queue_messages (DBusMessageLoader *loader);
+DBusMessage* _dbus_message_loader_peek_message (DBusMessageLoader *loader);
+DBusMessage* _dbus_message_loader_pop_message (DBusMessageLoader *loader);
+DBusList* _dbus_message_loader_pop_message_link (DBusMessageLoader *loader);
+void _dbus_message_loader_putback_message_link (DBusMessageLoader *loader,
+ DBusList *link);
+
+dbus_bool_t _dbus_message_loader_get_is_corrupted (DBusMessageLoader *loader);
+DBusValidity _dbus_message_loader_get_corruption_reason (DBusMessageLoader *loader);
+
+void _dbus_message_loader_set_max_message_size (DBusMessageLoader *loader,
+ long size);
+long _dbus_message_loader_get_max_message_size (DBusMessageLoader *loader);
+
+void _dbus_message_loader_set_max_message_unix_fds(DBusMessageLoader *loader,
+ long n);
+long _dbus_message_loader_get_max_message_unix_fds(DBusMessageLoader *loader);
+
+DBUS_END_DECLS
+
+#endif /* DBUS_MESSAGE_INTERNAL_H */
diff --git a/lib-x86-32/include/dbus-1/dbus/dbus-message-private.h b/lib-x86-32/include/dbus-1/dbus/dbus-message-private.h
new file mode 100644
index 00000000..57888fa5
--- /dev/null
+++ b/lib-x86-32/include/dbus-1/dbus/dbus-message-private.h
@@ -0,0 +1,148 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-message-private.h header shared between dbus-message.c and dbus-message-util.c
+ *
+ * Copyright (C) 2005 Red Hat Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+#ifndef DBUS_MESSAGE_PRIVATE_H
+#define DBUS_MESSAGE_PRIVATE_H
+
+#include <dbus/dbus-message.h>
+#include <dbus/dbus-message-internal.h>
+#include <dbus/dbus-string.h>
+#include <dbus/dbus-dataslot.h>
+#include <dbus/dbus-marshal-header.h>
+
+DBUS_BEGIN_DECLS
+
+/**
+ * @addtogroup DBusMessageInternals
+ * @{
+ */
+
+/**
+ * @typedef DBusMessageLoader
+ *
+ * The DBusMessageLoader object encapsulates the process of converting
+ * a byte stream into a series of DBusMessage. It buffers the incoming
+ * bytes as efficiently as possible, and generates a queue of
+ * messages. DBusMessageLoader is typically used as part of a
+ * DBusTransport implementation. The DBusTransport then hands off
+ * the loaded messages to a DBusConnection, making the messages
+ * visible to the application.
+ *
+ * @todo write tests for break-loader that a) randomly delete header
+ * fields and b) set string fields to zero-length and other funky
+ * values.
+ *
+ */
+
+/**
+ * Implementation details of DBusMessageLoader.
+ * All members are private.
+ */
+struct DBusMessageLoader
+{
+ int refcount; /**< Reference count. */
+
+ DBusString data; /**< Buffered data */
+
+ DBusList *messages; /**< Complete messages. */
+
+ long max_message_size; /**< Maximum size of a message */
+ long max_message_unix_fds; /**< Maximum unix fds in a message */
+
+ DBusValidity corruption_reason; /**< why we were corrupted */
+
+ unsigned int corrupted : 1; /**< We got broken data, and are no longer working */
+
+ unsigned int buffer_outstanding : 1; /**< Someone is using the buffer to read */
+
+#ifdef HAVE_UNIX_FD_PASSING
+ unsigned int unix_fds_outstanding : 1; /**< Someone is using the unix fd array to read */
+
+ int *unix_fds; /**< File descriptors that have been read from the transport but not yet been handed to any message. Array will be allocated at first use. */
+ unsigned n_unix_fds_allocated; /**< Number of file descriptors this array has space for */
+ unsigned n_unix_fds; /**< Number of valid file descriptors in array */
+#endif
+};
+
+
+/** How many bits are in the changed_stamp used to validate iterators */
+#define CHANGED_STAMP_BITS 21
+
+/**
+ * @brief Internals of DBusMessage
+ *
+ * Object representing a message received from or to be sent to
+ * another application. This is an opaque object, all members
+ * are private.
+ */
+struct DBusMessage
+{
+ DBusAtomic refcount; /**< Reference count */
+
+ DBusHeader header; /**< Header network data and associated cache */
+
+ DBusString body; /**< Body network data. */
+
+ char byte_order; /**< Message byte order. */
+
+ unsigned int locked : 1; /**< Message being sent, no modifications allowed. */
+
+#ifndef DBUS_DISABLE_CHECKS
+ unsigned int in_cache : 1; /**< Has been "freed" since it's in the cache (this is a debug feature) */
+#endif
+
+ DBusList *counters; /**< 0-N DBusCounter used to track message size/unix fds. */
+ long size_counter_delta; /**< Size we incremented the size counters by. */
+
+ dbus_uint32_t changed_stamp : CHANGED_STAMP_BITS; /**< Incremented when iterators are invalidated. */
+
+ DBusDataSlotList slot_list; /**< Data stored by allocated integer ID */
+
+#ifndef DBUS_DISABLE_CHECKS
+ int generation; /**< _dbus_current_generation when message was created */
+#endif
+
+#ifdef HAVE_UNIX_FD_PASSING
+ int *unix_fds;
+ /**< Unix file descriptors associated with this message. These are
+ closed when the message is destroyed, hence make sure to dup()
+ them when adding or removing them here. */
+ unsigned n_unix_fds; /**< Number of valid fds in the array */
+ unsigned n_unix_fds_allocated; /**< Allocated size of the array */
+
+ long unix_fd_counter_delta; /**< Size we incremented the unix fd counter by */
+#endif
+};
+
+dbus_bool_t _dbus_message_iter_get_args_valist (DBusMessageIter *iter,
+ DBusError *error,
+ int first_arg_type,
+ va_list var_args);
+
+
+void _dbus_check_fdleaks(void);
+
+/** @} */
+
+DBUS_END_DECLS
+
+#endif /* DBUS_MESSAGE_H */
diff --git a/lib-x86-32/include/dbus-1/dbus/dbus-message.h b/lib-x86-32/include/dbus-1/dbus/dbus-message.h
new file mode 100644
index 00000000..5500492d
--- /dev/null
+++ b/lib-x86-32/include/dbus-1/dbus/dbus-message.h
@@ -0,0 +1,309 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-message.h DBusMessage object
+ *
+ * Copyright (C) 2002, 2003, 2005 Red Hat Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+#if !defined (DBUS_INSIDE_DBUS_H) && !defined (DBUS_COMPILATION)
+#error "Only <dbus/dbus.h> can be included directly, this file may disappear or change contents."
+#endif
+
+#ifndef DBUS_MESSAGE_H
+#define DBUS_MESSAGE_H
+
+#include <dbus/dbus-macros.h>
+#include <dbus/dbus-types.h>
+#include <dbus/dbus-arch-deps.h>
+#include <dbus/dbus-memory.h>
+#include <dbus/dbus-errors.h>
+#include <stdarg.h>
+
+DBUS_BEGIN_DECLS
+
+/**
+ * @addtogroup DBusMessage
+ * @{
+ */
+
+typedef struct DBusMessage DBusMessage;
+/** Opaque type representing a message iterator. Can be copied by value, and contains no allocated memory so never needs to be freed and can be allocated on the stack. */
+typedef struct DBusMessageIter DBusMessageIter;
+
+/**
+ * DBusMessageIter struct; contains no public fields.
+ */
+struct DBusMessageIter
+{
+ void *dummy1; /**< Don't use this */
+ void *dummy2; /**< Don't use this */
+ dbus_uint32_t dummy3; /**< Don't use this */
+ int dummy4; /**< Don't use this */
+ int dummy5; /**< Don't use this */
+ int dummy6; /**< Don't use this */
+ int dummy7; /**< Don't use this */
+ int dummy8; /**< Don't use this */
+ int dummy9; /**< Don't use this */
+ int dummy10; /**< Don't use this */
+ int dummy11; /**< Don't use this */
+ int pad1; /**< Don't use this */
+ int pad2; /**< Don't use this */
+ void *pad3; /**< Don't use this */
+};
+
+DBUS_EXPORT
+DBusMessage* dbus_message_new (int message_type);
+DBUS_EXPORT
+DBusMessage* dbus_message_new_method_call (const char *bus_name,
+ const char *path,
+ const char *interface,
+ const char *method);
+DBUS_EXPORT
+DBusMessage* dbus_message_new_method_return (DBusMessage *method_call);
+DBUS_EXPORT
+DBusMessage* dbus_message_new_signal (const char *path,
+ const char *interface,
+ const char *name);
+DBUS_EXPORT
+DBusMessage* dbus_message_new_error (DBusMessage *reply_to,
+ const char *error_name,
+ const char *error_message);
+DBUS_EXPORT
+DBusMessage* dbus_message_new_error_printf (DBusMessage *reply_to,
+ const char *error_name,
+ const char *error_format,
+ ...);
+
+DBUS_EXPORT
+DBusMessage* dbus_message_copy (const DBusMessage *message);
+
+DBUS_EXPORT
+DBusMessage* dbus_message_ref (DBusMessage *message);
+DBUS_EXPORT
+void dbus_message_unref (DBusMessage *message);
+DBUS_EXPORT
+int dbus_message_get_type (DBusMessage *message);
+DBUS_EXPORT
+dbus_bool_t dbus_message_set_path (DBusMessage *message,
+ const char *object_path);
+DBUS_EXPORT
+const char* dbus_message_get_path (DBusMessage *message);
+DBUS_EXPORT
+dbus_bool_t dbus_message_has_path (DBusMessage *message,
+ const char *object_path);
+DBUS_EXPORT
+dbus_bool_t dbus_message_set_interface (DBusMessage *message,
+ const char *interface);
+DBUS_EXPORT
+const char* dbus_message_get_interface (DBusMessage *message);
+DBUS_EXPORT
+dbus_bool_t dbus_message_has_interface (DBusMessage *message,
+ const char *interface);
+DBUS_EXPORT
+dbus_bool_t dbus_message_set_member (DBusMessage *message,
+ const char *member);
+DBUS_EXPORT
+const char* dbus_message_get_member (DBusMessage *message);
+DBUS_EXPORT
+dbus_bool_t dbus_message_has_member (DBusMessage *message,
+ const char *member);
+DBUS_EXPORT
+dbus_bool_t dbus_message_set_error_name (DBusMessage *message,
+ const char *name);
+DBUS_EXPORT
+const char* dbus_message_get_error_name (DBusMessage *message);
+DBUS_EXPORT
+dbus_bool_t dbus_message_set_destination (DBusMessage *message,
+ const char *destination);
+DBUS_EXPORT
+const char* dbus_message_get_destination (DBusMessage *message);
+DBUS_EXPORT
+dbus_bool_t dbus_message_set_sender (DBusMessage *message,
+ const char *sender);
+DBUS_EXPORT
+const char* dbus_message_get_sender (DBusMessage *message);
+DBUS_EXPORT
+const char* dbus_message_get_signature (DBusMessage *message);
+DBUS_EXPORT
+void dbus_message_set_no_reply (DBusMessage *message,
+ dbus_bool_t no_reply);
+DBUS_EXPORT
+dbus_bool_t dbus_message_get_no_reply (DBusMessage *message);
+DBUS_EXPORT
+dbus_bool_t dbus_message_is_method_call (DBusMessage *message,
+ const char *interface,
+ const char *method);
+DBUS_EXPORT
+dbus_bool_t dbus_message_is_signal (DBusMessage *message,
+ const char *interface,
+ const char *signal_name);
+DBUS_EXPORT
+dbus_bool_t dbus_message_is_error (DBusMessage *message,
+ const char *error_name);
+DBUS_EXPORT
+dbus_bool_t dbus_message_has_destination (DBusMessage *message,
+ const char *bus_name);
+DBUS_EXPORT
+dbus_bool_t dbus_message_has_sender (DBusMessage *message,
+ const char *unique_bus_name);
+DBUS_EXPORT
+dbus_bool_t dbus_message_has_signature (DBusMessage *message,
+ const char *signature);
+DBUS_EXPORT
+dbus_uint32_t dbus_message_get_serial (DBusMessage *message);
+DBUS_EXPORT
+void dbus_message_set_serial (DBusMessage *message,
+ dbus_uint32_t serial);
+DBUS_EXPORT
+dbus_bool_t dbus_message_set_reply_serial (DBusMessage *message,
+ dbus_uint32_t reply_serial);
+DBUS_EXPORT
+dbus_uint32_t dbus_message_get_reply_serial (DBusMessage *message);
+
+DBUS_EXPORT
+void dbus_message_set_auto_start (DBusMessage *message,
+ dbus_bool_t auto_start);
+DBUS_EXPORT
+dbus_bool_t dbus_message_get_auto_start (DBusMessage *message);
+
+DBUS_EXPORT
+dbus_bool_t dbus_message_get_path_decomposed (DBusMessage *message,
+ char ***path);
+
+DBUS_EXPORT
+dbus_bool_t dbus_message_append_args (DBusMessage *message,
+ int first_arg_type,
+ ...);
+DBUS_EXPORT
+dbus_bool_t dbus_message_append_args_valist (DBusMessage *message,
+ int first_arg_type,
+ va_list var_args);
+DBUS_EXPORT
+dbus_bool_t dbus_message_get_args (DBusMessage *message,
+ DBusError *error,
+ int first_arg_type,
+ ...);
+DBUS_EXPORT
+dbus_bool_t dbus_message_get_args_valist (DBusMessage *message,
+ DBusError *error,
+ int first_arg_type,
+ va_list var_args);
+
+DBUS_EXPORT
+dbus_bool_t dbus_message_contains_unix_fds (DBusMessage *message);
+
+DBUS_EXPORT
+dbus_bool_t dbus_message_iter_init (DBusMessage *message,
+ DBusMessageIter *iter);
+DBUS_EXPORT
+dbus_bool_t dbus_message_iter_has_next (DBusMessageIter *iter);
+DBUS_EXPORT
+dbus_bool_t dbus_message_iter_next (DBusMessageIter *iter);
+DBUS_EXPORT
+char* dbus_message_iter_get_signature (DBusMessageIter *iter);
+DBUS_EXPORT
+int dbus_message_iter_get_arg_type (DBusMessageIter *iter);
+DBUS_EXPORT
+int dbus_message_iter_get_element_type (DBusMessageIter *iter);
+DBUS_EXPORT
+void dbus_message_iter_recurse (DBusMessageIter *iter,
+ DBusMessageIter *sub);
+DBUS_EXPORT
+void dbus_message_iter_get_basic (DBusMessageIter *iter,
+ void *value);
+#ifndef DBUS_DISABLE_DEPRECATED
+/* This function returns the wire protocol size of the array in bytes,
+ * you do not want to know that probably
+ */
+DBUS_EXPORT
+DBUS_DEPRECATED int dbus_message_iter_get_array_len (DBusMessageIter *iter);
+#endif
+DBUS_EXPORT
+void dbus_message_iter_get_fixed_array (DBusMessageIter *iter,
+ void *value,
+ int *n_elements);
+
+
+DBUS_EXPORT
+void dbus_message_iter_init_append (DBusMessage *message,
+ DBusMessageIter *iter);
+DBUS_EXPORT
+dbus_bool_t dbus_message_iter_append_basic (DBusMessageIter *iter,
+ int type,
+ const void *value);
+DBUS_EXPORT
+dbus_bool_t dbus_message_iter_append_fixed_array (DBusMessageIter *iter,
+ int element_type,
+ const void *value,
+ int n_elements);
+DBUS_EXPORT
+dbus_bool_t dbus_message_iter_open_container (DBusMessageIter *iter,
+ int type,
+ const char *contained_signature,
+ DBusMessageIter *sub);
+DBUS_EXPORT
+dbus_bool_t dbus_message_iter_close_container (DBusMessageIter *iter,
+ DBusMessageIter *sub);
+DBUS_EXPORT
+void dbus_message_iter_abandon_container (DBusMessageIter *iter,
+ DBusMessageIter *sub);
+
+DBUS_EXPORT
+void dbus_message_lock (DBusMessage *message);
+
+DBUS_EXPORT
+dbus_bool_t dbus_set_error_from_message (DBusError *error,
+ DBusMessage *message);
+
+
+DBUS_EXPORT
+dbus_bool_t dbus_message_allocate_data_slot (dbus_int32_t *slot_p);
+DBUS_EXPORT
+void dbus_message_free_data_slot (dbus_int32_t *slot_p);
+DBUS_EXPORT
+dbus_bool_t dbus_message_set_data (DBusMessage *message,
+ dbus_int32_t slot,
+ void *data,
+ DBusFreeFunction free_data_func);
+DBUS_EXPORT
+void* dbus_message_get_data (DBusMessage *message,
+ dbus_int32_t slot);
+
+DBUS_EXPORT
+int dbus_message_type_from_string (const char *type_str);
+DBUS_EXPORT
+const char* dbus_message_type_to_string (int type);
+
+DBUS_EXPORT
+dbus_bool_t dbus_message_marshal (DBusMessage *msg,
+ char **marshalled_data_p,
+ int *len_p);
+DBUS_EXPORT
+DBusMessage* dbus_message_demarshal (const char *str,
+ int len,
+ DBusError *error);
+
+DBUS_EXPORT
+int dbus_message_demarshal_bytes_needed (const char *str,
+ int len);
+
+/** @} */
+
+DBUS_END_DECLS
+
+#endif /* DBUS_MESSAGE_H */
diff --git a/lib-x86-32/include/dbus-1/dbus/dbus-misc.h b/lib-x86-32/include/dbus-1/dbus/dbus-misc.h
new file mode 100644
index 00000000..3504bcaa
--- /dev/null
+++ b/lib-x86-32/include/dbus-1/dbus/dbus-misc.h
@@ -0,0 +1,52 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-misc.h A few assorted public functions that don't fit elsewhere
+ *
+ * Copyright (C) 2006 Red Hat, Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+#if !defined (DBUS_INSIDE_DBUS_H) && !defined (DBUS_COMPILATION)
+#error "Only <dbus/dbus.h> can be included directly, this file may disappear or change contents."
+#endif
+
+#ifndef DBUS_MISC_H
+#define DBUS_MISC_H
+
+#include <dbus/dbus-types.h>
+#include <dbus/dbus-errors.h>
+
+DBUS_BEGIN_DECLS
+
+/**
+ * @addtogroup DBusMisc
+ * @{
+ */
+DBUS_EXPORT
+char* dbus_get_local_machine_id (void);
+
+DBUS_EXPORT
+void dbus_get_version (int *major_version_p,
+ int *minor_version_p,
+ int *micro_version_p);
+
+/** @} */
+
+DBUS_END_DECLS
+
+#endif /* DBUS_MISC_H */
+
diff --git a/lib-x86-32/include/dbus-1/dbus/dbus-nonce.h b/lib-x86-32/include/dbus-1/dbus/dbus-nonce.h
new file mode 100644
index 00000000..474ea728
--- /dev/null
+++ b/lib-x86-32/include/dbus-1/dbus/dbus-nonce.h
@@ -0,0 +1,72 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-nonce.h Nonce handling functions used by nonce-tcp (internal to D-Bus implementation)
+ *
+ * Copyright (C) 2009 Klaralvdalens Datakonsult AB, a KDAB Group company, info@kdab.net
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+#ifndef DBUS_NONCE_H
+#define DBUS_NONCE_H
+
+#include <dbus/dbus-macros.h>
+#include <dbus/dbus-types.h>
+#include <dbus/dbus-errors.h>
+#include <dbus/dbus-string.h>
+
+DBUS_BEGIN_DECLS
+
+typedef struct DBusNonceFile DBusNonceFile;
+
+struct DBusNonceFile
+{
+ DBusString path;
+ DBusString dir;
+};
+
+// server
+
+dbus_bool_t _dbus_noncefile_create (DBusNonceFile *noncefile,
+ DBusError *error);
+
+dbus_bool_t _dbus_noncefile_delete (DBusNonceFile *noncefile,
+ DBusError *error);
+
+dbus_bool_t _dbus_noncefile_check_nonce (int fd,
+ const DBusNonceFile *noncefile,
+ DBusError *error);
+
+const DBusString* _dbus_noncefile_get_path (const DBusNonceFile *noncefile);
+
+int _dbus_accept_with_noncefile (int listen_fd,
+ const DBusNonceFile *noncefile);
+
+// shared
+
+dbus_bool_t _dbus_read_nonce (const DBusString *fname,
+ DBusString *nonce,
+ DBusError *error);
+
+// client
+
+dbus_bool_t _dbus_send_nonce (int fd,
+ const DBusString *noncefile,
+ DBusError *error);
+
+DBUS_END_DECLS
+
+#endif /* DBUS_NONCE_H */
diff --git a/lib-x86-32/include/dbus-1/dbus/dbus-object-tree.h b/lib-x86-32/include/dbus-1/dbus/dbus-object-tree.h
new file mode 100644
index 00000000..022dd93f
--- /dev/null
+++ b/lib-x86-32/include/dbus-1/dbus/dbus-object-tree.h
@@ -0,0 +1,62 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-object-tree.h DBusObjectTree (internals of DBusConnection)
+ *
+ * Copyright (C) 2003 Red Hat Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+#ifndef DBUS_OBJECT_TREE_H
+#define DBUS_OBJECT_TREE_H
+
+#include <dbus/dbus-connection.h>
+
+DBUS_BEGIN_DECLS
+
+typedef struct DBusObjectTree DBusObjectTree;
+
+DBusObjectTree* _dbus_object_tree_new (DBusConnection *connection);
+DBusObjectTree* _dbus_object_tree_ref (DBusObjectTree *tree);
+void _dbus_object_tree_unref (DBusObjectTree *tree);
+
+dbus_bool_t _dbus_object_tree_register (DBusObjectTree *tree,
+ dbus_bool_t fallback,
+ const char **path,
+ const DBusObjectPathVTable *vtable,
+ void *user_data,
+ DBusError *error);
+void _dbus_object_tree_unregister_and_unlock (DBusObjectTree *tree,
+ const char **path);
+DBusHandlerResult _dbus_object_tree_dispatch_and_unlock (DBusObjectTree *tree,
+ DBusMessage *message);
+void* _dbus_object_tree_get_user_data_unlocked (DBusObjectTree *tree,
+ const char **path);
+void _dbus_object_tree_free_all_unlocked (DBusObjectTree *tree);
+
+
+dbus_bool_t _dbus_object_tree_list_registered_and_unlock (DBusObjectTree *tree,
+ const char **parent_path,
+ char ***child_entries);
+
+dbus_bool_t _dbus_decompose_path (const char *data,
+ int len,
+ char ***path,
+ int *path_len);
+
+DBUS_END_DECLS
+
+#endif /* DBUS_OBJECT_TREE_H */
diff --git a/lib-x86-32/include/dbus-1/dbus/dbus-pending-call-internal.h b/lib-x86-32/include/dbus-1/dbus/dbus-pending-call-internal.h
new file mode 100644
index 00000000..1875eea8
--- /dev/null
+++ b/lib-x86-32/include/dbus-1/dbus/dbus-pending-call-internal.h
@@ -0,0 +1,67 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-pending-call-internal.h DBusPendingCall internal interfaces
+ *
+ * Copyright (C) 2002 Red Hat Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+#ifndef DBUS_PENDING_CALL_INTERNAL_H
+#define DBUS_PENDING_CALL_INTERNAL_H
+
+
+#include <dbus/dbus-internals.h>
+#include <dbus/dbus-message.h>
+#include <dbus/dbus-connection.h>
+#include <dbus/dbus-list.h>
+
+DBUS_BEGIN_DECLS
+
+dbus_bool_t _dbus_pending_call_is_timeout_added_unlocked (DBusPendingCall *pending);
+void _dbus_pending_call_set_timeout_added_unlocked (DBusPendingCall *pending,
+ dbus_bool_t is_added);
+DBusTimeout * _dbus_pending_call_get_timeout_unlocked (DBusPendingCall *pending);
+dbus_uint32_t _dbus_pending_call_get_reply_serial_unlocked (DBusPendingCall *pending);
+void _dbus_pending_call_set_reply_serial_unlocked (DBusPendingCall *pending,
+ dbus_uint32_t serial);
+DBusConnection * _dbus_pending_call_get_connection_and_lock (DBusPendingCall *pending);
+DBusConnection * _dbus_pending_call_get_connection_unlocked (DBusPendingCall *pending);
+dbus_bool_t _dbus_pending_call_get_completed_unlocked (DBusPendingCall *pending);
+void _dbus_pending_call_complete (DBusPendingCall *pending);
+void _dbus_pending_call_set_reply_unlocked (DBusPendingCall *pending,
+ DBusMessage *message);
+void _dbus_pending_call_queue_timeout_error_unlocked (DBusPendingCall *pending,
+ DBusConnection *connection);
+void _dbus_pending_call_set_reply_serial_unlocked (DBusPendingCall *pending,
+ dbus_uint32_t serial);
+dbus_bool_t _dbus_pending_call_set_timeout_error_unlocked (DBusPendingCall *pending,
+ DBusMessage *message,
+ dbus_uint32_t serial);
+DBusPendingCall* _dbus_pending_call_new_unlocked (DBusConnection *connection,
+ int timeout_milliseconds,
+ DBusTimeoutHandler timeout_handler);
+DBusPendingCall* _dbus_pending_call_ref_unlocked (DBusPendingCall *pending);
+void _dbus_pending_call_unref_and_unlock (DBusPendingCall *pending);
+dbus_bool_t _dbus_pending_call_set_data_unlocked (DBusPendingCall *pending,
+ dbus_int32_t slot,
+ void *data,
+ DBusFreeFunction free_data_func);
+
+
+DBUS_END_DECLS
+
+#endif /* DBUS_PENDING_CALL_INTERNAL_H */
diff --git a/lib-x86-32/include/dbus-1/dbus/dbus-pending-call.h b/lib-x86-32/include/dbus-1/dbus/dbus-pending-call.h
new file mode 100644
index 00000000..8f64b8be
--- /dev/null
+++ b/lib-x86-32/include/dbus-1/dbus/dbus-pending-call.h
@@ -0,0 +1,76 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-pending-call.h Object representing a call in progress.
+ *
+ * Copyright (C) 2002, 2003 Red Hat Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+#if !defined (DBUS_INSIDE_DBUS_H) && !defined (DBUS_COMPILATION)
+#error "Only <dbus/dbus.h> can be included directly, this file may disappear or change contents."
+#endif
+
+#ifndef DBUS_PENDING_CALL_H
+#define DBUS_PENDING_CALL_H
+
+#include <dbus/dbus-macros.h>
+#include <dbus/dbus-types.h>
+#include <dbus/dbus-connection.h>
+
+DBUS_BEGIN_DECLS
+
+/**
+ * @addtogroup DBusPendingCall
+ * @{
+ */
+
+DBUS_EXPORT
+DBusPendingCall* dbus_pending_call_ref (DBusPendingCall *pending);
+DBUS_EXPORT
+void dbus_pending_call_unref (DBusPendingCall *pending);
+DBUS_EXPORT
+dbus_bool_t dbus_pending_call_set_notify (DBusPendingCall *pending,
+ DBusPendingCallNotifyFunction function,
+ void *user_data,
+ DBusFreeFunction free_user_data);
+DBUS_EXPORT
+void dbus_pending_call_cancel (DBusPendingCall *pending);
+DBUS_EXPORT
+dbus_bool_t dbus_pending_call_get_completed (DBusPendingCall *pending);
+DBUS_EXPORT
+DBusMessage* dbus_pending_call_steal_reply (DBusPendingCall *pending);
+DBUS_EXPORT
+void dbus_pending_call_block (DBusPendingCall *pending);
+
+DBUS_EXPORT
+dbus_bool_t dbus_pending_call_allocate_data_slot (dbus_int32_t *slot_p);
+DBUS_EXPORT
+void dbus_pending_call_free_data_slot (dbus_int32_t *slot_p);
+DBUS_EXPORT
+dbus_bool_t dbus_pending_call_set_data (DBusPendingCall *pending,
+ dbus_int32_t slot,
+ void *data,
+ DBusFreeFunction free_data_func);
+DBUS_EXPORT
+void* dbus_pending_call_get_data (DBusPendingCall *pending,
+ dbus_int32_t slot);
+
+/** @} */
+
+DBUS_END_DECLS
+
+#endif /* DBUS_PENDING_CALL_H */
diff --git a/lib-x86-32/include/dbus-1/dbus/dbus-pipe.h b/lib-x86-32/include/dbus-1/dbus/dbus-pipe.h
new file mode 100644
index 00000000..f6eac5f9
--- /dev/null
+++ b/lib-x86-32/include/dbus-1/dbus/dbus-pipe.h
@@ -0,0 +1,59 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-sysdeps.h Wrappers around system/libc features (internal to D-Bus implementation)
+ *
+ * Copyright (C) 2002, 2003 Red Hat, Inc.
+ * Copyright (C) 2003 CodeFactory AB
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef DBUS_PIPE_H
+#define DBUS_PIPE_H
+
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
+
+#ifdef HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+
+#include <dbus/dbus-types.h>
+#include <dbus/dbus-errors.h>
+#include <dbus/dbus-string.h>
+#include <dbus/dbus-sysdeps.h>
+
+struct DBusPipe {
+ intptr_t fd_or_handle;
+};
+
+void _dbus_pipe_init (DBusPipe *pipe,
+ intptr_t fd);
+void _dbus_pipe_init_stdout (DBusPipe *pipe);
+int _dbus_pipe_write (DBusPipe *pipe,
+ const DBusString *buffer,
+ int start,
+ int len,
+ DBusError *error);
+int _dbus_pipe_close (DBusPipe *pipe,
+ DBusError *error);
+dbus_bool_t _dbus_pipe_is_valid (DBusPipe *pipe);
+void _dbus_pipe_invalidate (DBusPipe *pipe);
+dbus_bool_t _dbus_pipe_is_stdout_or_stderr (DBusPipe *pipe);
+
+#endif
diff --git a/lib-x86-32/include/dbus-1/dbus/dbus-protocol.h b/lib-x86-32/include/dbus-1/dbus/dbus-protocol.h
new file mode 100644
index 00000000..17798e94
--- /dev/null
+++ b/lib-x86-32/include/dbus-1/dbus/dbus-protocol.h
@@ -0,0 +1,462 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-protocol.h D-Bus protocol constants
+ *
+ * Copyright (C) 2002, 2003 CodeFactory AB
+ * Copyright (C) 2004, 2005 Red Hat, Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef DBUS_PROTOCOL_H
+#define DBUS_PROTOCOL_H
+
+/* Don't include anything in here from anywhere else. It's
+ * intended for use by any random library.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#if 0
+} /* avoids confusing emacs indentation */
+#endif
+#endif
+
+/* Normally docs are in .c files, but there isn't a .c file for this. */
+/**
+ * @defgroup DBusProtocol Protocol constants
+ * @ingroup DBus
+ *
+ * @brief Defines constants which are part of the D-Bus protocol
+ *
+ * This header is intended for use by any library, not only libdbus.
+ *
+ * @{
+ */
+
+
+/* Message byte order */
+#define DBUS_LITTLE_ENDIAN ('l') /**< Code marking LSB-first byte order in the wire protocol. */
+#define DBUS_BIG_ENDIAN ('B') /**< Code marking MSB-first byte order in the wire protocol. */
+
+/** Protocol version. */
+#define DBUS_MAJOR_PROTOCOL_VERSION 1
+
+/** Type code that is never equal to a legitimate type code */
+#define DBUS_TYPE_INVALID ((int) '\0')
+/** #DBUS_TYPE_INVALID as a string literal instead of a int literal */
+#define DBUS_TYPE_INVALID_AS_STRING "\0"
+
+/* Primitive types */
+/** Type code marking an 8-bit unsigned integer */
+#define DBUS_TYPE_BYTE ((int) 'y')
+/** #DBUS_TYPE_BYTE as a string literal instead of a int literal */
+#define DBUS_TYPE_BYTE_AS_STRING "y"
+/** Type code marking a boolean */
+#define DBUS_TYPE_BOOLEAN ((int) 'b')
+/** #DBUS_TYPE_BOOLEAN as a string literal instead of a int literal */
+#define DBUS_TYPE_BOOLEAN_AS_STRING "b"
+/** Type code marking a 16-bit signed integer */
+#define DBUS_TYPE_INT16 ((int) 'n')
+/** #DBUS_TYPE_INT16 as a string literal instead of a int literal */
+#define DBUS_TYPE_INT16_AS_STRING "n"
+/** Type code marking a 16-bit unsigned integer */
+#define DBUS_TYPE_UINT16 ((int) 'q')
+/** #DBUS_TYPE_UINT16 as a string literal instead of a int literal */
+#define DBUS_TYPE_UINT16_AS_STRING "q"
+/** Type code marking a 32-bit signed integer */
+#define DBUS_TYPE_INT32 ((int) 'i')
+/** #DBUS_TYPE_INT32 as a string literal instead of a int literal */
+#define DBUS_TYPE_INT32_AS_STRING "i"
+/** Type code marking a 32-bit unsigned integer */
+#define DBUS_TYPE_UINT32 ((int) 'u')
+/** #DBUS_TYPE_UINT32 as a string literal instead of a int literal */
+#define DBUS_TYPE_UINT32_AS_STRING "u"
+/** Type code marking a 64-bit signed integer */
+#define DBUS_TYPE_INT64 ((int) 'x')
+/** #DBUS_TYPE_INT64 as a string literal instead of a int literal */
+#define DBUS_TYPE_INT64_AS_STRING "x"
+/** Type code marking a 64-bit unsigned integer */
+#define DBUS_TYPE_UINT64 ((int) 't')
+/** #DBUS_TYPE_UINT64 as a string literal instead of a int literal */
+#define DBUS_TYPE_UINT64_AS_STRING "t"
+/** Type code marking an 8-byte double in IEEE 754 format */
+#define DBUS_TYPE_DOUBLE ((int) 'd')
+/** #DBUS_TYPE_DOUBLE as a string literal instead of a int literal */
+#define DBUS_TYPE_DOUBLE_AS_STRING "d"
+/** Type code marking a UTF-8 encoded, nul-terminated Unicode string */
+#define DBUS_TYPE_STRING ((int) 's')
+/** #DBUS_TYPE_STRING as a string literal instead of a int literal */
+#define DBUS_TYPE_STRING_AS_STRING "s"
+/** Type code marking a D-Bus object path */
+#define DBUS_TYPE_OBJECT_PATH ((int) 'o')
+/** #DBUS_TYPE_OBJECT_PATH as a string literal instead of a int literal */
+#define DBUS_TYPE_OBJECT_PATH_AS_STRING "o"
+/** Type code marking a D-Bus type signature */
+#define DBUS_TYPE_SIGNATURE ((int) 'g')
+/** #DBUS_TYPE_SIGNATURE as a string literal instead of a int literal */
+#define DBUS_TYPE_SIGNATURE_AS_STRING "g"
+/** Type code marking a unix file descriptor */
+#define DBUS_TYPE_UNIX_FD ((int) 'h')
+/** #DBUS_TYPE_UNIX_FD as a string literal instead of a int literal */
+#define DBUS_TYPE_UNIX_FD_AS_STRING "h"
+
+/* Compound types */
+/** Type code marking a D-Bus array type */
+#define DBUS_TYPE_ARRAY ((int) 'a')
+/** #DBUS_TYPE_ARRAY as a string literal instead of a int literal */
+#define DBUS_TYPE_ARRAY_AS_STRING "a"
+/** Type code marking a D-Bus variant type */
+#define DBUS_TYPE_VARIANT ((int) 'v')
+/** #DBUS_TYPE_VARIANT as a string literal instead of a int literal */
+#define DBUS_TYPE_VARIANT_AS_STRING "v"
+
+/** STRUCT and DICT_ENTRY are sort of special since their codes can't
+ * appear in a type string, instead
+ * DBUS_STRUCT_BEGIN_CHAR/DBUS_DICT_ENTRY_BEGIN_CHAR have to appear
+ */
+/** Type code used to represent a struct; however, this type code does not appear
+ * in type signatures, instead #DBUS_STRUCT_BEGIN_CHAR and #DBUS_STRUCT_END_CHAR will
+ * appear in a signature.
+ */
+#define DBUS_TYPE_STRUCT ((int) 'r')
+/** #DBUS_TYPE_STRUCT as a string literal instead of a int literal */
+#define DBUS_TYPE_STRUCT_AS_STRING "r"
+/** Type code used to represent a dict entry; however, this type code does not appear
+ * in type signatures, instead #DBUS_DICT_ENTRY_BEGIN_CHAR and #DBUS_DICT_ENTRY_END_CHAR will
+ * appear in a signature.
+ */
+#define DBUS_TYPE_DICT_ENTRY ((int) 'e')
+/** #DBUS_TYPE_DICT_ENTRY as a string literal instead of a int literal */
+#define DBUS_TYPE_DICT_ENTRY_AS_STRING "e"
+
+/** Does not include #DBUS_TYPE_INVALID, #DBUS_STRUCT_BEGIN_CHAR, #DBUS_STRUCT_END_CHAR,
+ * #DBUS_DICT_ENTRY_BEGIN_CHAR, or #DBUS_DICT_ENTRY_END_CHAR - i.e. it is the number of
+ * valid types, not the number of distinct characters that may appear in a type signature.
+ */
+#define DBUS_NUMBER_OF_TYPES (16)
+
+/* characters other than typecodes that appear in type signatures */
+
+/** Code marking the start of a struct type in a type signature */
+#define DBUS_STRUCT_BEGIN_CHAR ((int) '(')
+/** #DBUS_STRUCT_BEGIN_CHAR as a string literal instead of a int literal */
+#define DBUS_STRUCT_BEGIN_CHAR_AS_STRING "("
+/** Code marking the end of a struct type in a type signature */
+#define DBUS_STRUCT_END_CHAR ((int) ')')
+/** #DBUS_STRUCT_END_CHAR a string literal instead of a int literal */
+#define DBUS_STRUCT_END_CHAR_AS_STRING ")"
+/** Code marking the start of a dict entry type in a type signature */
+#define DBUS_DICT_ENTRY_BEGIN_CHAR ((int) '{')
+/** #DBUS_DICT_ENTRY_BEGIN_CHAR as a string literal instead of a int literal */
+#define DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING "{"
+/** Code marking the end of a dict entry type in a type signature */
+#define DBUS_DICT_ENTRY_END_CHAR ((int) '}')
+/** #DBUS_DICT_ENTRY_END_CHAR as a string literal instead of a int literal */
+#define DBUS_DICT_ENTRY_END_CHAR_AS_STRING "}"
+
+/** Max length in bytes of a bus name, interface, or member (not object
+ * path, paths are unlimited). This is limited because lots of stuff
+ * is O(n) in this number, plus it would be obnoxious to type in a
+ * paragraph-long method name so most likely something like that would
+ * be an exploit.
+ */
+#define DBUS_MAXIMUM_NAME_LENGTH 255
+
+/** This one is 255 so it fits in a byte */
+#define DBUS_MAXIMUM_SIGNATURE_LENGTH 255
+
+/** Max length of a match rule string; to keep people from hosing the
+ * daemon with some huge rule
+ */
+#define DBUS_MAXIMUM_MATCH_RULE_LENGTH 1024
+
+/** Max arg number you can match on in a match rule, e.g.
+ * arg0='hello' is OK, arg3489720987='hello' is not
+ */
+#define DBUS_MAXIMUM_MATCH_RULE_ARG_NUMBER 63
+
+/** Max length of a marshaled array in bytes (64M, 2^26) We use signed
+ * int for lengths so must be INT_MAX or less. We need something a
+ * bit smaller than INT_MAX because the array is inside a message with
+ * header info, etc. so an INT_MAX array wouldn't allow the message
+ * overhead. The 64M number is an attempt at a larger number than
+ * we'd reasonably ever use, but small enough that your bus would chew
+ * through it fairly quickly without locking up forever. If you have
+ * data that's likely to be larger than this, you should probably be
+ * sending it in multiple incremental messages anyhow.
+ */
+#define DBUS_MAXIMUM_ARRAY_LENGTH (67108864)
+/** Number of bits you need in an unsigned to store the max array size */
+#define DBUS_MAXIMUM_ARRAY_LENGTH_BITS 26
+
+/** The maximum total message size including header and body; similar
+ * rationale to max array size.
+ */
+#define DBUS_MAXIMUM_MESSAGE_LENGTH (DBUS_MAXIMUM_ARRAY_LENGTH * 2)
+/** Number of bits you need in an unsigned to store the max message size */
+#define DBUS_MAXIMUM_MESSAGE_LENGTH_BITS 27
+
+/** The maximum total number of unix fds in a message. Similar
+ * rationale as DBUS_MAXIMUM_MESSAGE_LENGTH. However we divide by four
+ * given that one fd is an int and hence at least 32 bits.
+ */
+#define DBUS_MAXIMUM_MESSAGE_UNIX_FDS (DBUS_MAXIMUM_MESSAGE_LENGTH/4)
+/** Number of bits you need in an unsigned to store the max message unix fds */
+#define DBUS_MAXIMUM_MESSAGE_UNIX_FDS_BITS (DBUS_MAXIMUM_MESSAGE_LENGTH_BITS-2)
+
+/** Depth of recursion in the type tree. This is automatically limited
+ * to DBUS_MAXIMUM_SIGNATURE_LENGTH since you could only have an array
+ * of array of array of ... that fit in the max signature. But that's
+ * probably a bit too large.
+ */
+#define DBUS_MAXIMUM_TYPE_RECURSION_DEPTH 32
+
+/* Types of message */
+
+/** This value is never a valid message type, see dbus_message_get_type() */
+#define DBUS_MESSAGE_TYPE_INVALID 0
+/** Message type of a method call message, see dbus_message_get_type() */
+#define DBUS_MESSAGE_TYPE_METHOD_CALL 1
+/** Message type of a method return message, see dbus_message_get_type() */
+#define DBUS_MESSAGE_TYPE_METHOD_RETURN 2
+/** Message type of an error reply message, see dbus_message_get_type() */
+#define DBUS_MESSAGE_TYPE_ERROR 3
+/** Message type of a signal message, see dbus_message_get_type() */
+#define DBUS_MESSAGE_TYPE_SIGNAL 4
+
+#define DBUS_NUM_MESSAGE_TYPES 5
+
+/* Header flags */
+
+/** If set, this flag means that the sender of a message does not care about getting
+ * a reply, so the recipient need not send one. See dbus_message_set_no_reply().
+ */
+#define DBUS_HEADER_FLAG_NO_REPLY_EXPECTED 0x1
+/**
+ * If set, this flag means that even if the message bus knows how to start an owner for
+ * the destination bus name (see dbus_message_set_destination()), it should not
+ * do so. If this flag is not set, the bus may launch a program to process the
+ * message.
+ */
+#define DBUS_HEADER_FLAG_NO_AUTO_START 0x2
+
+/* Header fields */
+
+/** Not equal to any valid header field code */
+#define DBUS_HEADER_FIELD_INVALID 0
+/** Header field code for the path - the path is the object emitting a signal or the object receiving a method call.
+ * See dbus_message_set_path().
+ */
+#define DBUS_HEADER_FIELD_PATH 1
+/** Header field code for the interface containing a member (method or signal).
+ * See dbus_message_set_interface().
+ */
+#define DBUS_HEADER_FIELD_INTERFACE 2
+/** Header field code for a member (method or signal). See dbus_message_set_member(). */
+#define DBUS_HEADER_FIELD_MEMBER 3
+/** Header field code for an error name (found in #DBUS_MESSAGE_TYPE_ERROR messages).
+ * See dbus_message_set_error_name().
+ */
+#define DBUS_HEADER_FIELD_ERROR_NAME 4
+/** Header field code for a reply serial, used to match a #DBUS_MESSAGE_TYPE_METHOD_RETURN message with the
+ * message that it's a reply to. See dbus_message_set_reply_serial().
+ */
+#define DBUS_HEADER_FIELD_REPLY_SERIAL 5
+/**
+ * Header field code for the destination bus name of a message. See dbus_message_set_destination().
+ */
+#define DBUS_HEADER_FIELD_DESTINATION 6
+/**
+ * Header field code for the sender of a message; usually initialized by the message bus.
+ * See dbus_message_set_sender().
+ */
+#define DBUS_HEADER_FIELD_SENDER 7
+/**
+ * Header field code for the type signature of a message.
+ */
+#define DBUS_HEADER_FIELD_SIGNATURE 8
+/**
+ * Header field code for the number of unix file descriptors associated
+ * with this message.
+ */
+#define DBUS_HEADER_FIELD_UNIX_FDS 9
+
+
+/**
+ * Value of the highest-numbered header field code, can be used to determine
+ * the size of an array indexed by header field code. Remember though
+ * that unknown codes must be ignored, so check for that before
+ * indexing the array.
+ */
+#define DBUS_HEADER_FIELD_LAST DBUS_HEADER_FIELD_UNIX_FDS
+
+/** Header format is defined as a signature:
+ * byte byte order
+ * byte message type ID
+ * byte flags
+ * byte protocol version
+ * uint32 body length
+ * uint32 serial
+ * array of struct (byte,variant) (field name, value)
+ *
+ * The length of the header can be computed as the
+ * fixed size of the initial data, plus the length of
+ * the array at the end, plus padding to an 8-boundary.
+ */
+#define DBUS_HEADER_SIGNATURE \
+ DBUS_TYPE_BYTE_AS_STRING \
+ DBUS_TYPE_BYTE_AS_STRING \
+ DBUS_TYPE_BYTE_AS_STRING \
+ DBUS_TYPE_BYTE_AS_STRING \
+ DBUS_TYPE_UINT32_AS_STRING \
+ DBUS_TYPE_UINT32_AS_STRING \
+ DBUS_TYPE_ARRAY_AS_STRING \
+ DBUS_STRUCT_BEGIN_CHAR_AS_STRING \
+ DBUS_TYPE_BYTE_AS_STRING \
+ DBUS_TYPE_VARIANT_AS_STRING \
+ DBUS_STRUCT_END_CHAR_AS_STRING
+
+
+/**
+ * The smallest header size that can occur. (It won't be valid due to
+ * missing required header fields.) This is 4 bytes, two uint32, an
+ * array length. This isn't any kind of resource limit, just the
+ * necessary/logical outcome of the header signature.
+ */
+#define DBUS_MINIMUM_HEADER_SIZE 16
+
+/* Errors */
+/* WARNING these get autoconverted to an enum in dbus-glib.h. Thus,
+ * if you change the order it breaks the ABI. Keep them in order.
+ * Also, don't change the formatting since that will break the sed
+ * script.
+ */
+/** A generic error; "something went wrong" - see the error message for more. */
+#define DBUS_ERROR_FAILED "org.freedesktop.DBus.Error.Failed"
+/** There was not enough memory to complete an operation. */
+#define DBUS_ERROR_NO_MEMORY "org.freedesktop.DBus.Error.NoMemory"
+/** The bus doesn't know how to launch a service to supply the bus name you wanted. */
+#define DBUS_ERROR_SERVICE_UNKNOWN "org.freedesktop.DBus.Error.ServiceUnknown"
+/** The bus name you referenced doesn't exist (i.e. no application owns it). */
+#define DBUS_ERROR_NAME_HAS_NO_OWNER "org.freedesktop.DBus.Error.NameHasNoOwner"
+/** No reply to a message expecting one, usually means a timeout occurred. */
+#define DBUS_ERROR_NO_REPLY "org.freedesktop.DBus.Error.NoReply"
+/** Something went wrong reading or writing to a socket, for example. */
+#define DBUS_ERROR_IO_ERROR "org.freedesktop.DBus.Error.IOError"
+/** A D-Bus bus address was malformed. */
+#define DBUS_ERROR_BAD_ADDRESS "org.freedesktop.DBus.Error.BadAddress"
+/** Requested operation isn't supported (like ENOSYS on UNIX). */
+#define DBUS_ERROR_NOT_SUPPORTED "org.freedesktop.DBus.Error.NotSupported"
+/** Some limited resource is exhausted. */
+#define DBUS_ERROR_LIMITS_EXCEEDED "org.freedesktop.DBus.Error.LimitsExceeded"
+/** Security restrictions don't allow doing what you're trying to do. */
+#define DBUS_ERROR_ACCESS_DENIED "org.freedesktop.DBus.Error.AccessDenied"
+/** Authentication didn't work. */
+#define DBUS_ERROR_AUTH_FAILED "org.freedesktop.DBus.Error.AuthFailed"
+/** Unable to connect to server (probably caused by ECONNREFUSED on a socket). */
+#define DBUS_ERROR_NO_SERVER "org.freedesktop.DBus.Error.NoServer"
+/** Certain timeout errors, possibly ETIMEDOUT on a socket.
+ * Note that #DBUS_ERROR_NO_REPLY is used for message reply timeouts.
+ * @warning this is confusingly-named given that #DBUS_ERROR_TIMED_OUT also exists. We can't fix
+ * it for compatibility reasons so just be careful.
+ */
+#define DBUS_ERROR_TIMEOUT "org.freedesktop.DBus.Error.Timeout"
+/** No network access (probably ENETUNREACH on a socket). */
+#define DBUS_ERROR_NO_NETWORK "org.freedesktop.DBus.Error.NoNetwork"
+/** Can't bind a socket since its address is in use (i.e. EADDRINUSE). */
+#define DBUS_ERROR_ADDRESS_IN_USE "org.freedesktop.DBus.Error.AddressInUse"
+/** The connection is disconnected and you're trying to use it. */
+#define DBUS_ERROR_DISCONNECTED "org.freedesktop.DBus.Error.Disconnected"
+/** Invalid arguments passed to a method call. */
+#define DBUS_ERROR_INVALID_ARGS "org.freedesktop.DBus.Error.InvalidArgs"
+/** Missing file. */
+#define DBUS_ERROR_FILE_NOT_FOUND "org.freedesktop.DBus.Error.FileNotFound"
+/** Existing file and the operation you're using does not silently overwrite. */
+#define DBUS_ERROR_FILE_EXISTS "org.freedesktop.DBus.Error.FileExists"
+/** Method name you invoked isn't known by the object you invoked it on. */
+#define DBUS_ERROR_UNKNOWN_METHOD "org.freedesktop.DBus.Error.UnknownMethod"
+/** Certain timeout errors, e.g. while starting a service.
+ * @warning this is confusingly-named given that #DBUS_ERROR_TIMEOUT also exists. We can't fix
+ * it for compatibility reasons so just be careful.
+ */
+#define DBUS_ERROR_TIMED_OUT "org.freedesktop.DBus.Error.TimedOut"
+/** Tried to remove or modify a match rule that didn't exist. */
+#define DBUS_ERROR_MATCH_RULE_NOT_FOUND "org.freedesktop.DBus.Error.MatchRuleNotFound"
+/** The match rule isn't syntactically valid. */
+#define DBUS_ERROR_MATCH_RULE_INVALID "org.freedesktop.DBus.Error.MatchRuleInvalid"
+/** While starting a new process, the exec() call failed. */
+#define DBUS_ERROR_SPAWN_EXEC_FAILED "org.freedesktop.DBus.Error.Spawn.ExecFailed"
+/** While starting a new process, the fork() call failed. */
+#define DBUS_ERROR_SPAWN_FORK_FAILED "org.freedesktop.DBus.Error.Spawn.ForkFailed"
+/** While starting a new process, the child exited with a status code. */
+#define DBUS_ERROR_SPAWN_CHILD_EXITED "org.freedesktop.DBus.Error.Spawn.ChildExited"
+/** While starting a new process, the child exited on a signal. */
+#define DBUS_ERROR_SPAWN_CHILD_SIGNALED "org.freedesktop.DBus.Error.Spawn.ChildSignaled"
+/** While starting a new process, something went wrong. */
+#define DBUS_ERROR_SPAWN_FAILED "org.freedesktop.DBus.Error.Spawn.Failed"
+/** We failed to setup the environment correctly. */
+#define DBUS_ERROR_SPAWN_SETUP_FAILED "org.freedesktop.DBus.Error.Spawn.FailedToSetup"
+/** We failed to setup the config parser correctly. */
+#define DBUS_ERROR_SPAWN_CONFIG_INVALID "org.freedesktop.DBus.Error.Spawn.ConfigInvalid"
+/** Bus name was not valid. */
+#define DBUS_ERROR_SPAWN_SERVICE_INVALID "org.freedesktop.DBus.Error.Spawn.ServiceNotValid"
+/** Service file not found in system-services directory. */
+#define DBUS_ERROR_SPAWN_SERVICE_NOT_FOUND "org.freedesktop.DBus.Error.Spawn.ServiceNotFound"
+/** Permissions are incorrect on the setuid helper. */
+#define DBUS_ERROR_SPAWN_PERMISSIONS_INVALID "org.freedesktop.DBus.Error.Spawn.PermissionsInvalid"
+/** Service file invalid (Name, User or Exec missing). */
+#define DBUS_ERROR_SPAWN_FILE_INVALID "org.freedesktop.DBus.Error.Spawn.FileInvalid"
+/** Tried to get a UNIX process ID and it wasn't available. */
+#define DBUS_ERROR_SPAWN_NO_MEMORY "org.freedesktop.DBus.Error.Spawn.NoMemory"
+/** Tried to get a UNIX process ID and it wasn't available. */
+#define DBUS_ERROR_UNIX_PROCESS_ID_UNKNOWN "org.freedesktop.DBus.Error.UnixProcessIdUnknown"
+/** A type signature is not valid. */
+#define DBUS_ERROR_INVALID_SIGNATURE "org.freedesktop.DBus.Error.InvalidSignature"
+/** A file contains invalid syntax or is otherwise broken. */
+#define DBUS_ERROR_INVALID_FILE_CONTENT "org.freedesktop.DBus.Error.InvalidFileContent"
+/** Asked for SELinux security context and it wasn't available. */
+#define DBUS_ERROR_SELINUX_SECURITY_CONTEXT_UNKNOWN "org.freedesktop.DBus.Error.SELinuxSecurityContextUnknown"
+/** Asked for ADT audit data and it wasn't available. */
+#define DBUS_ERROR_ADT_AUDIT_DATA_UNKNOWN "org.freedesktop.DBus.Error.AdtAuditDataUnknown"
+/** There's already an object with the requested object path. */
+#define DBUS_ERROR_OBJECT_PATH_IN_USE "org.freedesktop.DBus.Error.ObjectPathInUse"
+/** The message meta data does not match the payload. e.g. expected
+ number of file descriptors were not sent over the socket this message was received on. */
+#define DBUS_ERROR_INCONSISTENT_MESSAGE "org.freedesktop.DBus.Error.InconsistentMessage"
+
+/* XML introspection format */
+
+/** XML namespace of the introspection format version 1.0 */
+#define DBUS_INTROSPECT_1_0_XML_NAMESPACE "http://www.freedesktop.org/standards/dbus"
+/** XML public identifier of the introspection format version 1.0 */
+#define DBUS_INTROSPECT_1_0_XML_PUBLIC_IDENTIFIER "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
+/** XML system identifier of the introspection format version 1.0 */
+#define DBUS_INTROSPECT_1_0_XML_SYSTEM_IDENTIFIER "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"
+/** XML document type declaration of the introspection format version 1.0 */
+#define DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE "<!DOCTYPE node PUBLIC \""DBUS_INTROSPECT_1_0_XML_PUBLIC_IDENTIFIER"\"\n\""DBUS_INTROSPECT_1_0_XML_SYSTEM_IDENTIFIER"\">\n"
+
+/** @} */
+
+#ifdef __cplusplus
+#if 0
+{ /* avoids confusing emacs indentation */
+#endif
+}
+#endif
+
+#endif /* DBUS_PROTOCOL_H */
diff --git a/lib-x86-32/include/dbus-1/dbus/dbus-resources.h b/lib-x86-32/include/dbus-1/dbus/dbus-resources.h
new file mode 100644
index 00000000..4763a97f
--- /dev/null
+++ b/lib-x86-32/include/dbus-1/dbus/dbus-resources.h
@@ -0,0 +1,57 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-resources.h Resource tracking/limits
+ *
+ * Copyright (C) 2003 Red Hat Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+#ifndef DBUS_RESOURCES_H
+#define DBUS_RESOURCES_H
+
+#include <dbus/dbus-macros.h>
+#include <dbus/dbus-errors.h>
+#include <dbus/dbus-connection.h>
+
+DBUS_BEGIN_DECLS
+
+typedef struct DBusCounter DBusCounter;
+
+typedef void (* DBusCounterNotifyFunction) (DBusCounter *counter,
+ void *user_data);
+
+DBusCounter* _dbus_counter_new (void);
+DBusCounter* _dbus_counter_ref (DBusCounter *counter);
+void _dbus_counter_unref (DBusCounter *counter);
+
+void _dbus_counter_adjust_size (DBusCounter *counter,
+ long delta);
+void _dbus_counter_adjust_unix_fd (DBusCounter *counter,
+ long delta);
+long _dbus_counter_get_size_value (DBusCounter *counter);
+long _dbus_counter_get_unix_fd_value (DBusCounter *counter);
+
+void _dbus_counter_set_notify (DBusCounter *counter,
+ long size_guard_value,
+ long unix_fd_guard_value,
+ DBusCounterNotifyFunction function,
+ void *user_data);
+
+
+DBUS_END_DECLS
+
+#endif /* DBUS_RESOURCES_H */
diff --git a/lib-x86-32/include/dbus-1/dbus/dbus-server-debug-pipe.h b/lib-x86-32/include/dbus-1/dbus/dbus-server-debug-pipe.h
new file mode 100644
index 00000000..4574311d
--- /dev/null
+++ b/lib-x86-32/include/dbus-1/dbus/dbus-server-debug-pipe.h
@@ -0,0 +1,47 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-server-debug-pipe.h In-proc debug server implementation
+ *
+ * Copyright (C) 2003 CodeFactory AB
+ * Copyright (C) 2003 Red Hat, Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+#ifndef DBUS_SERVER_DEBUG_PIPE_H
+#define DBUS_SERVER_DEBUG_PIPE_H
+
+#include <dbus/dbus-internals.h>
+#include <dbus/dbus-server-protected.h>
+#include <dbus/dbus-transport-protected.h>
+
+DBUS_BEGIN_DECLS
+
+DBusServer* _dbus_server_debug_pipe_new (const char *server_name,
+ DBusError *error);
+DBusTransport* _dbus_transport_debug_pipe_new (const char *server_name,
+ DBusError *error);
+DBusServerListenResult _dbus_server_listen_debug_pipe (DBusAddressEntry *entry,
+ DBusServer **server_p,
+ DBusError *error);
+DBusTransportOpenResult _dbus_transport_open_debug_pipe (DBusAddressEntry *entry,
+ DBusTransport **transport_p,
+ DBusError *error);
+
+
+DBUS_END_DECLS
+
+#endif /* DBUS_SERVER_DEBUG_PIPE_H */
diff --git a/lib-x86-32/include/dbus-1/dbus/dbus-server-protected.h b/lib-x86-32/include/dbus-1/dbus/dbus-server-protected.h
new file mode 100644
index 00000000..cc2de8dd
--- /dev/null
+++ b/lib-x86-32/include/dbus-1/dbus/dbus-server-protected.h
@@ -0,0 +1,159 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-server-protected.h Used by subclasses of DBusServer object (internal to D-Bus implementation)
+ *
+ * Copyright (C) 2002 Red Hat Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+#ifndef DBUS_SERVER_PROTECTED_H
+#define DBUS_SERVER_PROTECTED_H
+
+#include <dbus/dbus-internals.h>
+#include <dbus/dbus-threads-internal.h>
+#include <dbus/dbus-server.h>
+#include <dbus/dbus-address.h>
+#include <dbus/dbus-timeout.h>
+#include <dbus/dbus-watch.h>
+#include <dbus/dbus-resources.h>
+#include <dbus/dbus-dataslot.h>
+#include <dbus/dbus-string.h>
+
+DBUS_BEGIN_DECLS
+
+typedef struct DBusServerVTable DBusServerVTable;
+
+/**
+ * Virtual table to be implemented by all server "subclasses"
+ */
+struct DBusServerVTable
+{
+ void (* finalize) (DBusServer *server);
+ /**< The finalize method must free the server. */
+
+ void (* disconnect) (DBusServer *server);
+ /**< Disconnect this server. */
+};
+
+/**
+ * Internals of DBusServer object
+ */
+struct DBusServer
+{
+ DBusAtomic refcount; /**< Reference count. */
+ const DBusServerVTable *vtable; /**< Virtual methods for this instance. */
+ DBusMutex *mutex; /**< Lock on the server object */
+
+ DBusGUID guid; /**< Globally unique ID of server */
+
+ DBusString guid_hex; /**< Hex-encoded version of GUID */
+
+ DBusWatchList *watches; /**< Our watches */
+ DBusTimeoutList *timeouts; /**< Our timeouts */
+
+ char *address; /**< Address this server is listening on. */
+
+ int max_connections; /**< Max number of connections allowed at once. */
+
+ DBusDataSlotList slot_list; /**< Data stored by allocated integer ID */
+
+ DBusNewConnectionFunction new_connection_function;
+ /**< Callback to invoke when a new connection is created. */
+ void *new_connection_data;
+ /**< Data for new connection callback */
+ DBusFreeFunction new_connection_free_data_function;
+ /**< Callback to invoke to free new_connection_data
+ * when server is finalized or data is replaced.
+ */
+
+ char **auth_mechanisms; /**< Array of allowed authentication mechanisms */
+
+ unsigned int disconnected : 1; /**< TRUE if we are disconnected. */
+
+#ifndef DBUS_DISABLE_CHECKS
+ unsigned int have_server_lock : 1; /**< Does someone have the server mutex locked */
+#endif
+};
+
+dbus_bool_t _dbus_server_init_base (DBusServer *server,
+ const DBusServerVTable *vtable,
+ const DBusString *address);
+void _dbus_server_finalize_base (DBusServer *server);
+dbus_bool_t _dbus_server_add_watch (DBusServer *server,
+ DBusWatch *watch);
+void _dbus_server_remove_watch (DBusServer *server,
+ DBusWatch *watch);
+void _dbus_server_toggle_watch (DBusServer *server,
+ DBusWatch *watch,
+ dbus_bool_t enabled);
+dbus_bool_t _dbus_server_add_timeout (DBusServer *server,
+ DBusTimeout *timeout);
+void _dbus_server_remove_timeout (DBusServer *server,
+ DBusTimeout *timeout);
+void _dbus_server_toggle_timeout (DBusServer *server,
+ DBusTimeout *timeout,
+ dbus_bool_t enabled);
+
+void _dbus_server_ref_unlocked (DBusServer *server);
+void _dbus_server_unref_unlocked (DBusServer *server);
+
+typedef enum
+{
+ DBUS_SERVER_LISTEN_NOT_HANDLED, /**< we aren't in charge of this address type */
+ DBUS_SERVER_LISTEN_OK, /**< we set up the listen */
+ DBUS_SERVER_LISTEN_BAD_ADDRESS, /**< malformed address */
+ DBUS_SERVER_LISTEN_DID_NOT_CONNECT /**< well-formed address but failed to set it up */
+} DBusServerListenResult;
+
+DBusServerListenResult _dbus_server_listen_platform_specific (DBusAddressEntry *entry,
+ DBusServer **server_p,
+ DBusError *error);
+
+#ifdef DBUS_DISABLE_CHECKS
+#define TOOK_LOCK_CHECK(server)
+#define RELEASING_LOCK_CHECK(server)
+#define HAVE_LOCK_CHECK(server)
+#else
+#define TOOK_LOCK_CHECK(server) do { \
+ _dbus_assert (!(server)->have_server_lock); \
+ (server)->have_server_lock = TRUE; \
+ } while (0)
+#define RELEASING_LOCK_CHECK(server) do { \
+ _dbus_assert ((server)->have_server_lock); \
+ (server)->have_server_lock = FALSE; \
+ } while (0)
+#define HAVE_LOCK_CHECK(server) _dbus_assert ((server)->have_server_lock)
+/* A "DO_NOT_HAVE_LOCK_CHECK" is impossible since we need the lock to check the flag */
+#endif
+
+#define TRACE_LOCKS 0
+
+#define SERVER_LOCK(server) do { \
+ if (TRACE_LOCKS) { _dbus_verbose ("LOCK\n"); } \
+ _dbus_mutex_lock ((server)->mutex); \
+ TOOK_LOCK_CHECK (server); \
+ } while (0)
+
+#define SERVER_UNLOCK(server) do { \
+ if (TRACE_LOCKS) { _dbus_verbose ("UNLOCK\n"); } \
+ RELEASING_LOCK_CHECK (server); \
+ _dbus_mutex_unlock ((server)->mutex); \
+ } while (0)
+
+DBUS_END_DECLS
+
+#endif /* DBUS_SERVER_PROTECTED_H */
diff --git a/lib-x86-32/include/dbus-1/dbus/dbus-server-socket.h b/lib-x86-32/include/dbus-1/dbus/dbus-server-socket.h
new file mode 100644
index 00000000..0a7c7891
--- /dev/null
+++ b/lib-x86-32/include/dbus-1/dbus/dbus-server-socket.h
@@ -0,0 +1,52 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-server-socket.h Server implementation for sockets
+ *
+ * Copyright (C) 2002, 2006 Red Hat Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+#ifndef DBUS_SERVER_SOCKET_H
+#define DBUS_SERVER_SOCKET_H
+
+#include <dbus/dbus-internals.h>
+#include <dbus/dbus-server-protected.h>
+#include <dbus/dbus-nonce.h>
+
+DBUS_BEGIN_DECLS
+
+DBusServer* _dbus_server_new_for_socket (int *fds,
+ int n_fds,
+ const DBusString *address,
+ DBusNonceFile *noncefile);
+DBusServer* _dbus_server_new_for_tcp_socket (const char *host,
+ const char *bind,
+ const char *port,
+ const char *family,
+ DBusError *error,
+ dbus_bool_t use_nonce);
+DBusServerListenResult _dbus_server_listen_socket (DBusAddressEntry *entry,
+ DBusServer **server_p,
+ DBusError *error);
+
+
+void _dbus_server_socket_own_filename (DBusServer *server,
+ char *filename);
+
+DBUS_END_DECLS
+
+#endif /* DBUS_SERVER_SOCKET_H */
diff --git a/lib-x86-32/include/dbus-1/dbus/dbus-server-unix.h b/lib-x86-32/include/dbus-1/dbus/dbus-server-unix.h
new file mode 100644
index 00000000..92b996ca
--- /dev/null
+++ b/lib-x86-32/include/dbus-1/dbus/dbus-server-unix.h
@@ -0,0 +1,37 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-server-unix.h Server implementation for Unix network protocols.
+ *
+ * Copyright (C) 2002 Red Hat Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+#ifndef DBUS_SERVER_UNIX_H
+#define DBUS_SERVER_UNIX_H
+
+#include <dbus/dbus-internals.h>
+#include <dbus/dbus-server-protected.h>
+
+DBUS_BEGIN_DECLS
+
+DBusServer* _dbus_server_new_for_domain_socket (const char *path,
+ dbus_bool_t abstract,
+ DBusError *error);
+
+DBUS_END_DECLS
+
+#endif /* DBUS_SERVER_UNIX_H */
diff --git a/lib-x86-32/include/dbus-1/dbus/dbus-server-win.h b/lib-x86-32/include/dbus-1/dbus/dbus-server-win.h
new file mode 100644
index 00000000..65c27568
--- /dev/null
+++ b/lib-x86-32/include/dbus-1/dbus/dbus-server-win.h
@@ -0,0 +1,36 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-server-win.h Server implementation for windows network protocols.
+ *
+ * Copyright (C) 2002 Red Hat Inc.
+ * Copyright (C) 2007 Ralf Habacker <ralf.habacker@freenet.de>
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+#ifndef DBUS_SERVER_WIN_H
+#define DBUS_SERVER_WIN_H
+
+#include <dbus/dbus-internals.h>
+#include <dbus/dbus-server-protected.h>
+
+DBUS_BEGIN_DECLS
+
+/* add definitions here */
+
+DBUS_END_DECLS
+
+#endif /* DBUS_SERVER_WIN_H */
diff --git a/lib-x86-32/include/dbus-1/dbus/dbus-server.h b/lib-x86-32/include/dbus-1/dbus/dbus-server.h
new file mode 100644
index 00000000..bdbefa0f
--- /dev/null
+++ b/lib-x86-32/include/dbus-1/dbus/dbus-server.h
@@ -0,0 +1,106 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-server.h DBusServer object
+ *
+ * Copyright (C) 2002, 2003 Red Hat Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+#if !defined (DBUS_INSIDE_DBUS_H) && !defined (DBUS_COMPILATION)
+#error "Only <dbus/dbus.h> can be included directly, this file may disappear or change contents."
+#endif
+
+#ifndef DBUS_SERVER_H
+#define DBUS_SERVER_H
+
+#include <dbus/dbus-errors.h>
+#include <dbus/dbus-message.h>
+#include <dbus/dbus-connection.h>
+#include <dbus/dbus-protocol.h>
+
+DBUS_BEGIN_DECLS
+
+/**
+ * @addtogroup DBusServer
+ * @{
+ */
+
+typedef struct DBusServer DBusServer;
+
+/** Called when a new connection to the server is available. Must reference and save the new
+ * connection, or close the new connection. Set with dbus_server_set_new_connection_function().
+ */
+typedef void (* DBusNewConnectionFunction) (DBusServer *server,
+ DBusConnection *new_connection,
+ void *data);
+
+DBUS_EXPORT
+DBusServer* dbus_server_listen (const char *address,
+ DBusError *error);
+DBUS_EXPORT
+DBusServer* dbus_server_ref (DBusServer *server);
+DBUS_EXPORT
+void dbus_server_unref (DBusServer *server);
+DBUS_EXPORT
+void dbus_server_disconnect (DBusServer *server);
+DBUS_EXPORT
+dbus_bool_t dbus_server_get_is_connected (DBusServer *server);
+DBUS_EXPORT
+char* dbus_server_get_address (DBusServer *server);
+DBUS_EXPORT
+char* dbus_server_get_id (DBusServer *server);
+DBUS_EXPORT
+void dbus_server_set_new_connection_function (DBusServer *server,
+ DBusNewConnectionFunction function,
+ void *data,
+ DBusFreeFunction free_data_function);
+DBUS_EXPORT
+dbus_bool_t dbus_server_set_watch_functions (DBusServer *server,
+ DBusAddWatchFunction add_function,
+ DBusRemoveWatchFunction remove_function,
+ DBusWatchToggledFunction toggled_function,
+ void *data,
+ DBusFreeFunction free_data_function);
+DBUS_EXPORT
+dbus_bool_t dbus_server_set_timeout_functions (DBusServer *server,
+ DBusAddTimeoutFunction add_function,
+ DBusRemoveTimeoutFunction remove_function,
+ DBusTimeoutToggledFunction toggled_function,
+ void *data,
+ DBusFreeFunction free_data_function);
+DBUS_EXPORT
+dbus_bool_t dbus_server_set_auth_mechanisms (DBusServer *server,
+ const char **mechanisms);
+
+DBUS_EXPORT
+dbus_bool_t dbus_server_allocate_data_slot (dbus_int32_t *slot_p);
+DBUS_EXPORT
+void dbus_server_free_data_slot (dbus_int32_t *slot_p);
+DBUS_EXPORT
+dbus_bool_t dbus_server_set_data (DBusServer *server,
+ int slot,
+ void *data,
+ DBusFreeFunction free_data_func);
+DBUS_EXPORT
+void* dbus_server_get_data (DBusServer *server,
+ int slot);
+
+/** @} */
+
+DBUS_END_DECLS
+
+#endif /* DBUS_SERVER_H */
diff --git a/lib-x86-32/include/dbus-1/dbus/dbus-sha.h b/lib-x86-32/include/dbus-1/dbus/dbus-sha.h
new file mode 100644
index 00000000..c48035b9
--- /dev/null
+++ b/lib-x86-32/include/dbus-1/dbus/dbus-sha.h
@@ -0,0 +1,55 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-sha.h SHA-1 implementation
+ *
+ * Copyright (C) 2003 Red Hat Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+#ifndef DBUS_SHA_H
+#define DBUS_SHA_H
+
+#include <dbus/dbus-macros.h>
+#include <dbus/dbus-errors.h>
+#include <dbus/dbus-string.h>
+
+DBUS_BEGIN_DECLS
+
+typedef struct DBusSHAContext DBusSHAContext;
+
+/**
+ * Struct storing state of the SHA algorithm
+ */
+struct DBusSHAContext
+{
+ dbus_uint32_t digest[5]; /**< Message digest */
+ dbus_uint32_t count_lo; /**< 64-bit bit count */
+ dbus_uint32_t count_hi; /**< No clue */
+ dbus_uint32_t data[16]; /**< SHA data buffer */
+};
+
+void _dbus_sha_init (DBusSHAContext *context);
+void _dbus_sha_update (DBusSHAContext *context,
+ const DBusString *data);
+dbus_bool_t _dbus_sha_final (DBusSHAContext *context,
+ DBusString *results);
+dbus_bool_t _dbus_sha_compute (const DBusString *data,
+ DBusString *ascii_output);
+
+DBUS_END_DECLS
+
+#endif /* DBUS_SHA_H */
diff --git a/lib-x86-32/include/dbus-1/dbus/dbus-shared.h b/lib-x86-32/include/dbus-1/dbus/dbus-shared.h
new file mode 100644
index 00000000..6a576704
--- /dev/null
+++ b/lib-x86-32/include/dbus-1/dbus/dbus-shared.h
@@ -0,0 +1,131 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-shared.h Stuff used by both dbus/dbus.h low-level and C/C++ binding APIs
+ *
+ * Copyright (C) 2004 Red Hat, Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef DBUS_SHARED_H
+#define DBUS_SHARED_H
+
+/* Don't include anything in here from anywhere else. It's
+ * intended for use by any random library.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#if 0
+} /* avoids confusing emacs indentation */
+#endif
+#endif
+
+/* Normally docs are in .c files, but there isn't a .c file for this. */
+/**
+ * @defgroup DBusShared Shared constants
+ * @ingroup DBus
+ *
+ * @brief Shared header included by both libdbus and C/C++ bindings such as the GLib bindings.
+ *
+ * Usually a C/C++ binding such as the GLib or Qt binding won't want to include dbus.h in its
+ * public headers. However, a few constants and macros may be useful to include; those are
+ * found here and in dbus-protocol.h
+ *
+ * @{
+ */
+
+
+/**
+ * Well-known bus types. See dbus_bus_get().
+ */
+typedef enum
+{
+ DBUS_BUS_SESSION, /**< The login session bus */
+ DBUS_BUS_SYSTEM, /**< The systemwide bus */
+ DBUS_BUS_STARTER /**< The bus that started us, if any */
+} DBusBusType;
+
+/**
+ * Results that a message handler can return.
+ */
+typedef enum
+{
+ DBUS_HANDLER_RESULT_HANDLED, /**< Message has had its effect - no need to run more handlers. */
+ DBUS_HANDLER_RESULT_NOT_YET_HANDLED, /**< Message has not had any effect - see if other handlers want it. */
+ DBUS_HANDLER_RESULT_NEED_MEMORY /**< Need more memory in order to return #DBUS_HANDLER_RESULT_HANDLED or #DBUS_HANDLER_RESULT_NOT_YET_HANDLED. Please try again later with more memory. */
+} DBusHandlerResult;
+
+/* Bus names */
+
+/** The bus name used to talk to the bus itself. */
+#define DBUS_SERVICE_DBUS "org.freedesktop.DBus"
+
+/* Paths */
+/** The object path used to talk to the bus itself. */
+#define DBUS_PATH_DBUS "/org/freedesktop/DBus"
+/** The object path used in local/in-process-generated messages. */
+#define DBUS_PATH_LOCAL "/org/freedesktop/DBus/Local"
+
+/* Interfaces, these #define don't do much other than
+ * catch typos at compile time
+ */
+/** The interface exported by the object with #DBUS_SERVICE_DBUS and #DBUS_PATH_DBUS */
+#define DBUS_INTERFACE_DBUS "org.freedesktop.DBus"
+/** The interface supported by introspectable objects */
+#define DBUS_INTERFACE_INTROSPECTABLE "org.freedesktop.DBus.Introspectable"
+/** The interface supported by objects with properties */
+#define DBUS_INTERFACE_PROPERTIES "org.freedesktop.DBus.Properties"
+/** The interface supported by most dbus peers */
+#define DBUS_INTERFACE_PEER "org.freedesktop.DBus.Peer"
+
+/** This is a special interface whose methods can only be invoked
+ * by the local implementation (messages from remote apps aren't
+ * allowed to specify this interface).
+ */
+#define DBUS_INTERFACE_LOCAL "org.freedesktop.DBus.Local"
+
+/* Owner flags */
+#define DBUS_NAME_FLAG_ALLOW_REPLACEMENT 0x1 /**< Allow another service to become the primary owner if requested */
+#define DBUS_NAME_FLAG_REPLACE_EXISTING 0x2 /**< Request to replace the current primary owner */
+#define DBUS_NAME_FLAG_DO_NOT_QUEUE 0x4 /**< If we can not become the primary owner do not place us in the queue */
+
+/* Replies to request for a name */
+#define DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER 1 /**< Service has become the primary owner of the requested name */
+#define DBUS_REQUEST_NAME_REPLY_IN_QUEUE 2 /**< Service could not become the primary owner and has been placed in the queue */
+#define DBUS_REQUEST_NAME_REPLY_EXISTS 3 /**< Service is already in the queue */
+#define DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER 4 /**< Service is already the primary owner */
+
+/* Replies to releasing a name */
+#define DBUS_RELEASE_NAME_REPLY_RELEASED 1 /**< Service was released from the given name */
+#define DBUS_RELEASE_NAME_REPLY_NON_EXISTENT 2 /**< The given name does not exist on the bus */
+#define DBUS_RELEASE_NAME_REPLY_NOT_OWNER 3 /**< Service is not an owner of the given name */
+
+/* Replies to service starts */
+#define DBUS_START_REPLY_SUCCESS 1 /**< Service was auto started */
+#define DBUS_START_REPLY_ALREADY_RUNNING 2 /**< Service was already running */
+
+/** @} */
+
+#ifdef __cplusplus
+#if 0
+{ /* avoids confusing emacs indentation */
+#endif
+}
+#endif
+
+#endif /* DBUS_SHARED_H */
diff --git a/lib-x86-32/include/dbus-1/dbus/dbus-shell.h b/lib-x86-32/include/dbus-1/dbus/dbus-shell.h
new file mode 100644
index 00000000..06da274e
--- /dev/null
+++ b/lib-x86-32/include/dbus-1/dbus/dbus-shell.h
@@ -0,0 +1,41 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-shell.h Shell command line utility functions.
+ *
+ * Copyright (C) 2002, 2003 Red Hat, Inc.
+ * Copyright (C) 2003 CodeFactory AB
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+
+#ifndef DBUS_SHELL_H
+#define DBUS_SHELL_H
+
+DBUS_BEGIN_DECLS
+
+char* _dbus_shell_unquote (const char *quoted_string);
+dbus_bool_t _dbus_shell_parse_argv (const char *command_line,
+ int *argcp,
+ char ***argvp,
+ DBusError *error);
+
+DBUS_END_DECLS
+
+#endif /* DBUS_SHELL_H */
+
+
diff --git a/lib-x86-32/include/dbus-1/dbus/dbus-signature.h b/lib-x86-32/include/dbus-1/dbus/dbus-signature.h
new file mode 100644
index 00000000..ebf00c1e
--- /dev/null
+++ b/lib-x86-32/include/dbus-1/dbus/dbus-signature.h
@@ -0,0 +1,92 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-signatures.h utility functions for D-Bus types
+ *
+ * Copyright (C) 2005 Red Hat Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+#if !defined (DBUS_INSIDE_DBUS_H) && !defined (DBUS_COMPILATION)
+#error "Only <dbus/dbus.h> can be included directly, this file may disappear or change contents."
+#endif
+
+#ifndef DBUS_SIGNATURES_H
+#define DBUS_SIGNATURES_H
+
+#include <dbus/dbus-macros.h>
+#include <dbus/dbus-types.h>
+#include <dbus/dbus-errors.h>
+
+DBUS_BEGIN_DECLS
+
+/**
+ * @addtogroup DBusSignature
+ * @{
+ */
+
+/**
+ * DBusSignatureIter struct; contains no public fields
+ */
+typedef struct
+{
+ void *dummy1; /**< Don't use this */
+ void *dummy2; /**< Don't use this */
+ dbus_uint32_t dummy8; /**< Don't use this */
+ int dummy12; /**< Don't use this */
+ int dummy17; /**< Don't use this */
+} DBusSignatureIter;
+
+DBUS_EXPORT
+void dbus_signature_iter_init (DBusSignatureIter *iter,
+ const char *signature);
+
+DBUS_EXPORT
+int dbus_signature_iter_get_current_type (const DBusSignatureIter *iter);
+
+DBUS_EXPORT
+char * dbus_signature_iter_get_signature (const DBusSignatureIter *iter);
+
+DBUS_EXPORT
+int dbus_signature_iter_get_element_type (const DBusSignatureIter *iter);
+
+DBUS_EXPORT
+dbus_bool_t dbus_signature_iter_next (DBusSignatureIter *iter);
+
+DBUS_EXPORT
+void dbus_signature_iter_recurse (const DBusSignatureIter *iter,
+ DBusSignatureIter *subiter);
+
+DBUS_EXPORT
+dbus_bool_t dbus_signature_validate (const char *signature,
+ DBusError *error);
+
+DBUS_EXPORT
+dbus_bool_t dbus_signature_validate_single (const char *signature,
+ DBusError *error);
+
+DBUS_EXPORT
+dbus_bool_t dbus_type_is_basic (int typecode);
+DBUS_EXPORT
+dbus_bool_t dbus_type_is_container (int typecode);
+DBUS_EXPORT
+dbus_bool_t dbus_type_is_fixed (int typecode);
+
+/** @} */
+
+DBUS_END_DECLS
+
+#endif /* DBUS_SIGNATURE_H */
diff --git a/lib-x86-32/include/dbus-1/dbus/dbus-sockets-win.h b/lib-x86-32/include/dbus-1/dbus/dbus-sockets-win.h
new file mode 100644
index 00000000..5dead058
--- /dev/null
+++ b/lib-x86-32/include/dbus-1/dbus/dbus-sockets-win.h
@@ -0,0 +1,76 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-sockets.h Wrappers around socket features (internal to D-BUS implementation)
+ *
+ * Copyright (C) 2005 Novell, Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef DBUS_SOCKETS_H
+#define DBUS_SOCKETS_H
+
+#if defined(DBUS_WIN) || defined(DBUS_WINCE)
+
+
+
+#ifndef STRICT
+#define STRICT
+#include <winsock2.h>
+#undef STRICT
+#endif
+#include <winsock2.h>
+
+#undef interface
+
+#if HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
+/* Make use of the fact that the WSAE* error codes don't
+ * overlap with errno E* codes. Wrapper functions store
+ * the return value from WSAGetLastError() in errno.
+ */
+#if defined(EPROTONOSUPPORT) || \
+ defined(EAFNOSUPPORT) || \
+ defined(EWOULDBLOCK)
+#error This does not look like Win32 and the Microsoft C library
+#endif
+
+#define DBUS_SOCKET_IS_INVALID(s) ((SOCKET)(s) == INVALID_SOCKET)
+#define DBUS_SOCKET_API_RETURNS_ERROR(n) ((n) == SOCKET_ERROR)
+#define DBUS_SOCKET_SET_ERRNO() (_dbus_win_set_errno (WSAGetLastError()))
+
+#define DBUS_CLOSE_SOCKET(s) closesocket(s)
+
+#else
+
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <errno.h>
+
+#define DBUS_SOCKET_IS_INVALID(s) ((s) < 0)
+#define DBUS_SOCKET_API_RETURNS_ERROR(n) ((n) < 0)
+#define DBUS_SOCKET_SET_ERRNO() /* empty */
+
+#define DBUS_CLOSE_SOCKET(s) close(s)
+
+#endif /* !Win32 */
+
+#endif /* DBUS_SOCKETS_H */
diff --git a/lib-x86-32/include/dbus-1/dbus/dbus-spawn.h b/lib-x86-32/include/dbus-1/dbus/dbus-spawn.h
new file mode 100644
index 00000000..5af54b72
--- /dev/null
+++ b/lib-x86-32/include/dbus-1/dbus/dbus-spawn.h
@@ -0,0 +1,61 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-spawn.h Wrapper around fork/exec
+ *
+ * Copyright (C) 2002, 2003 Red Hat, Inc.
+ * Copyright (C) 2003 CodeFactory AB
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef DBUS_SPAWN_H
+#define DBUS_SPAWN_H
+
+#include <dbus/dbus-string.h>
+#include <dbus/dbus-errors.h>
+#include <dbus/dbus-watch.h>
+
+DBUS_BEGIN_DECLS
+
+typedef void (* DBusSpawnChildSetupFunc) (void *user_data);
+
+typedef struct DBusBabysitter DBusBabysitter;
+
+dbus_bool_t _dbus_spawn_async_with_babysitter (DBusBabysitter **sitter_p,
+ char **argv,
+ char **env,
+ DBusSpawnChildSetupFunc child_setup,
+ void *user_data,
+ DBusError *error);
+DBusBabysitter* _dbus_babysitter_ref (DBusBabysitter *sitter);
+void _dbus_babysitter_unref (DBusBabysitter *sitter);
+void _dbus_babysitter_kill_child (DBusBabysitter *sitter);
+dbus_bool_t _dbus_babysitter_get_child_exited (DBusBabysitter *sitter);
+void _dbus_babysitter_set_child_exit_error (DBusBabysitter *sitter,
+ DBusError *error);
+dbus_bool_t _dbus_babysitter_get_child_exit_status (DBusBabysitter *sitter,
+ int *status);
+dbus_bool_t _dbus_babysitter_set_watch_functions (DBusBabysitter *sitter,
+ DBusAddWatchFunction add_function,
+ DBusRemoveWatchFunction remove_function,
+ DBusWatchToggledFunction toggled_function,
+ void *data,
+ DBusFreeFunction free_data_function);
+
+DBUS_END_DECLS
+
+#endif /* DBUS_SPAWN_H */
diff --git a/lib-x86-32/include/dbus-1/dbus/dbus-string-private.h b/lib-x86-32/include/dbus-1/dbus/dbus-string-private.h
new file mode 100644
index 00000000..365d89a3
--- /dev/null
+++ b/lib-x86-32/include/dbus-1/dbus/dbus-string-private.h
@@ -0,0 +1,124 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-string-private.h String utility class (internal to D-Bus implementation)
+ *
+ * Copyright (C) 2002, 2003 Red Hat, Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef DBUS_STRING_PRIVATE_H
+#define DBUS_STRING_PRIVATE_H
+
+#include <dbus/dbus-memory.h>
+#include <dbus/dbus-types.h>
+
+#ifndef DBUS_CAN_USE_DBUS_STRING_PRIVATE
+#error "Don't go including dbus-string-private.h for no good reason"
+#endif
+
+DBUS_BEGIN_DECLS
+
+/**
+ * @brief Internals of DBusString.
+ *
+ * DBusString internals. DBusString is an opaque objects, it must be
+ * used via accessor functions.
+ */
+typedef struct
+{
+ unsigned char *str; /**< String data, plus nul termination */
+ int len; /**< Length without nul */
+ int allocated; /**< Allocated size of data */
+ int max_length; /**< Max length of this string, without nul byte */
+ unsigned int constant : 1; /**< String data is not owned by DBusString */
+ unsigned int locked : 1; /**< DBusString has been locked and can't be changed */
+ unsigned int invalid : 1; /**< DBusString is invalid (e.g. already freed) */
+ unsigned int align_offset : 3; /**< str - align_offset is the actual malloc block */
+} DBusRealString;
+
+
+/**
+ * @defgroup DBusStringInternals DBusString implementation details
+ * @ingroup DBusInternals
+ * @brief DBusString implementation details
+ *
+ * The guts of DBusString.
+ *
+ * @{
+ */
+
+/**
+ * This is the maximum max length (and thus also the maximum length)
+ * of a DBusString
+ */
+#define _DBUS_STRING_MAX_MAX_LENGTH (_DBUS_INT32_MAX - _DBUS_STRING_ALLOCATION_PADDING)
+
+/**
+ * Checks a bunch of assertions about a string object
+ *
+ * @param real the DBusRealString
+ */
+#define DBUS_GENERIC_STRING_PREAMBLE(real) _dbus_assert ((real) != NULL); _dbus_assert (!(real)->invalid); _dbus_assert ((real)->len >= 0); _dbus_assert ((real)->allocated >= 0); _dbus_assert ((real)->max_length >= 0); _dbus_assert ((real)->len <= ((real)->allocated - _DBUS_STRING_ALLOCATION_PADDING)); _dbus_assert ((real)->len <= (real)->max_length)
+
+/**
+ * Checks assertions about a string object that needs to be
+ * modifiable - may not be locked or const. Also declares
+ * the "real" variable pointing to DBusRealString.
+ * @param str the string
+ */
+#define DBUS_STRING_PREAMBLE(str) DBusRealString *real = (DBusRealString*) str; \
+ DBUS_GENERIC_STRING_PREAMBLE (real); \
+ _dbus_assert (!(real)->constant); \
+ _dbus_assert (!(real)->locked)
+
+/**
+ * Checks assertions about a string object that may be locked but
+ * can't be const. i.e. a string object that we can free. Also
+ * declares the "real" variable pointing to DBusRealString.
+ *
+ * @param str the string
+ */
+#define DBUS_LOCKED_STRING_PREAMBLE(str) DBusRealString *real = (DBusRealString*) str; \
+ DBUS_GENERIC_STRING_PREAMBLE (real); \
+ _dbus_assert (!(real)->constant)
+
+/**
+ * Checks assertions about a string that may be const or locked. Also
+ * declares the "real" variable pointing to DBusRealString.
+ * @param str the string.
+ */
+#define DBUS_CONST_STRING_PREAMBLE(str) const DBusRealString *real = (DBusRealString*) str; \
+ DBUS_GENERIC_STRING_PREAMBLE (real)
+
+/**
+ * Checks for ASCII blank byte
+ * @param c the byte
+ */
+#define DBUS_IS_ASCII_BLANK(c) ((c) == ' ' || (c) == '\t')
+
+/**
+ * Checks for ASCII whitespace byte
+ * @param c the byte
+ */
+#define DBUS_IS_ASCII_WHITE(c) ((c) == ' ' || (c) == '\t' || (c) == '\n' || (c) == '\r')
+
+/** @} */
+
+DBUS_END_DECLS
+
+#endif /* DBUS_STRING_PRIVATE_H */
diff --git a/lib-x86-32/include/dbus-1/dbus/dbus-string.h b/lib-x86-32/include/dbus-1/dbus/dbus-string.h
new file mode 100644
index 00000000..2f1ed31c
--- /dev/null
+++ b/lib-x86-32/include/dbus-1/dbus/dbus-string.h
@@ -0,0 +1,332 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-string.h String utility class (internal to D-Bus implementation)
+ *
+ * Copyright (C) 2002, 2003 Red Hat, Inc.
+ * Copyright (C) 2006 Ralf Habacker <ralf.habacker@freenet.de>
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef DBUS_STRING_H
+#define DBUS_STRING_H
+
+#include <dbus/dbus-macros.h>
+#include <dbus/dbus-types.h>
+#include <dbus/dbus-memory.h>
+
+#include <stdarg.h>
+
+DBUS_BEGIN_DECLS
+
+/**
+ * DBusString object
+ */
+
+typedef struct DBusString DBusString;
+
+struct DBusString
+{
+#if defined(DBUS_WIN) && defined(_DEBUG)
+ const char *dummy1; /**< placeholder */
+#else
+ const void *dummy1; /**< placeholder */
+#endif
+ int dummy2; /**< placeholder */
+ int dummy3; /**< placeholder */
+ int dummy4; /**< placeholder */
+ unsigned int dummy5 : 1; /**< placeholder */
+ unsigned int dummy6 : 1; /**< placeholder */
+ unsigned int dummy7 : 1; /**< placeholder */
+ unsigned int dummy8 : 3; /**< placeholder */
+};
+
+#ifdef DBUS_DISABLE_ASSERT
+/* Some simple inlining hacks; the current linker is not smart enough
+ * to inline non-exported symbols across files in the library.
+ * Note that these break type safety (due to the casts)
+ */
+#define _dbus_string_get_data(s) ((char*)(((DBusString*)(s))->dummy1))
+#define _dbus_string_get_length(s) (((DBusString*)(s))->dummy2)
+#define _dbus_string_set_byte(s, i, b) ((((unsigned char*)(((DBusString*)(s))->dummy1))[(i)]) = (unsigned char) (b))
+#define _dbus_string_get_byte(s, i) (((const unsigned char*)(((DBusString*)(s))->dummy1))[(i)])
+#define _dbus_string_get_const_data(s) ((const char*)(((DBusString*)(s))->dummy1))
+#define _dbus_string_get_const_data_len(s,start,len) (((const char*)(((DBusString*)(s))->dummy1)) + (start))
+#endif
+
+dbus_bool_t _dbus_string_init (DBusString *str);
+void _dbus_string_init_const (DBusString *str,
+ const char *value);
+void _dbus_string_init_const_len (DBusString *str,
+ const char *value,
+ int len);
+dbus_bool_t _dbus_string_init_preallocated (DBusString *str,
+ int allocate_size);
+void _dbus_string_free (DBusString *str);
+void _dbus_string_lock (DBusString *str);
+dbus_bool_t _dbus_string_compact (DBusString *str,
+ int max_waste);
+#ifndef _dbus_string_get_data
+char* _dbus_string_get_data (DBusString *str);
+#endif /* _dbus_string_get_data */
+#ifndef _dbus_string_get_const_data
+const char* _dbus_string_get_const_data (const DBusString *str);
+#endif /* _dbus_string_get_const_data */
+char* _dbus_string_get_data_len (DBusString *str,
+ int start,
+ int len);
+#ifndef _dbus_string_get_const_data_len
+const char* _dbus_string_get_const_data_len (const DBusString *str,
+ int start,
+ int len);
+#endif
+#ifndef _dbus_string_set_byte
+void _dbus_string_set_byte (DBusString *str,
+ int i,
+ unsigned char byte);
+#endif
+#ifndef _dbus_string_get_byte
+unsigned char _dbus_string_get_byte (const DBusString *str,
+ int start);
+#endif /* _dbus_string_get_byte */
+dbus_bool_t _dbus_string_insert_bytes (DBusString *str,
+ int i,
+ int n_bytes,
+ unsigned char byte);
+dbus_bool_t _dbus_string_insert_byte (DBusString *str,
+ int i,
+ unsigned char byte);
+dbus_bool_t _dbus_string_steal_data (DBusString *str,
+ char **data_return);
+dbus_bool_t _dbus_string_steal_data_len (DBusString *str,
+ char **data_return,
+ int start,
+ int len);
+dbus_bool_t _dbus_string_copy_data (const DBusString *str,
+ char **data_return);
+dbus_bool_t _dbus_string_copy_data_len (const DBusString *str,
+ char **data_return,
+ int start,
+ int len);
+void _dbus_string_copy_to_buffer (const DBusString *str,
+ char *buffer,
+ int len);
+void _dbus_string_copy_to_buffer_with_nul (const DBusString *str,
+ char *buffer,
+ int avail_len);
+#ifndef _dbus_string_get_length
+int _dbus_string_get_length (const DBusString *str);
+#endif /* !_dbus_string_get_length */
+
+dbus_bool_t _dbus_string_lengthen (DBusString *str,
+ int additional_length);
+void _dbus_string_shorten (DBusString *str,
+ int length_to_remove);
+dbus_bool_t _dbus_string_set_length (DBusString *str,
+ int length);
+dbus_bool_t _dbus_string_align_length (DBusString *str,
+ int alignment);
+dbus_bool_t _dbus_string_alloc_space (DBusString *str,
+ int extra_bytes);
+dbus_bool_t _dbus_string_append (DBusString *str,
+ const char *buffer);
+dbus_bool_t _dbus_string_append_len (DBusString *str,
+ const char *buffer,
+ int len);
+dbus_bool_t _dbus_string_append_int (DBusString *str,
+ long value);
+dbus_bool_t _dbus_string_append_uint (DBusString *str,
+ unsigned long value);
+dbus_bool_t _dbus_string_append_double (DBusString *str,
+ double value);
+dbus_bool_t _dbus_string_append_byte (DBusString *str,
+ unsigned char byte);
+dbus_bool_t _dbus_string_append_unichar (DBusString *str,
+ dbus_unichar_t ch);
+dbus_bool_t _dbus_string_append_4_aligned (DBusString *str,
+ const unsigned char octets[4]);
+dbus_bool_t _dbus_string_append_8_aligned (DBusString *str,
+ const unsigned char octets[8]);
+dbus_bool_t _dbus_string_append_printf (DBusString *str,
+ const char *format,
+ ...) _DBUS_GNUC_PRINTF (2, 3);
+dbus_bool_t _dbus_string_append_printf_valist (DBusString *str,
+ const char *format,
+ va_list args);
+dbus_bool_t _dbus_string_insert_2_aligned (DBusString *str,
+ int insert_at,
+ const unsigned char octets[2]);
+dbus_bool_t _dbus_string_insert_4_aligned (DBusString *str,
+ int insert_at,
+ const unsigned char octets[4]);
+dbus_bool_t _dbus_string_insert_8_aligned (DBusString *str,
+ int insert_at,
+ const unsigned char octets[8]);
+dbus_bool_t _dbus_string_insert_alignment (DBusString *str,
+ int *insert_at,
+ int alignment);
+void _dbus_string_delete (DBusString *str,
+ int start,
+ int len);
+dbus_bool_t _dbus_string_move (DBusString *source,
+ int start,
+ DBusString *dest,
+ int insert_at);
+dbus_bool_t _dbus_string_copy (const DBusString *source,
+ int start,
+ DBusString *dest,
+ int insert_at);
+dbus_bool_t _dbus_string_move_len (DBusString *source,
+ int start,
+ int len,
+ DBusString *dest,
+ int insert_at);
+dbus_bool_t _dbus_string_copy_len (const DBusString *source,
+ int start,
+ int len,
+ DBusString *dest,
+ int insert_at);
+dbus_bool_t _dbus_string_replace_len (const DBusString *source,
+ int start,
+ int len,
+ DBusString *dest,
+ int replace_at,
+ int replace_len);
+dbus_bool_t _dbus_string_split_on_byte (DBusString *source,
+ unsigned char byte,
+ DBusString *tail);
+void _dbus_string_get_unichar (const DBusString *str,
+ int start,
+ dbus_unichar_t *ch_return,
+ int *end_return);
+dbus_bool_t _dbus_string_parse_int (const DBusString *str,
+ int start,
+ long *value_return,
+ int *end_return);
+dbus_bool_t _dbus_string_parse_uint (const DBusString *str,
+ int start,
+ unsigned long *value_return,
+ int *end_return);
+dbus_bool_t _dbus_string_parse_double (const DBusString *str,
+ int start,
+ double *value,
+ int *end_return);
+dbus_bool_t _dbus_string_find (const DBusString *str,
+ int start,
+ const char *substr,
+ int *found);
+dbus_bool_t _dbus_string_find_eol (const DBusString *str,
+ int start,
+ int *found,
+ int *found_len);
+dbus_bool_t _dbus_string_find_to (const DBusString *str,
+ int start,
+ int end,
+ const char *substr,
+ int *found);
+dbus_bool_t _dbus_string_find_byte_backward (const DBusString *str,
+ int start,
+ unsigned char byte,
+ int *found);
+dbus_bool_t _dbus_string_find_blank (const DBusString *str,
+ int start,
+ int *found);
+void _dbus_string_skip_blank (const DBusString *str,
+ int start,
+ int *end);
+void _dbus_string_skip_white (const DBusString *str,
+ int start,
+ int *end);
+void _dbus_string_skip_white_reverse (const DBusString *str,
+ int end,
+ int *start);
+dbus_bool_t _dbus_string_equal (const DBusString *a,
+ const DBusString *b);
+dbus_bool_t _dbus_string_equal_c_str (const DBusString *a,
+ const char *c_str);
+dbus_bool_t _dbus_string_equal_len (const DBusString *a,
+ const DBusString *b,
+ int len);
+dbus_bool_t _dbus_string_equal_substring (const DBusString *a,
+ int a_start,
+ int a_len,
+ const DBusString *b,
+ int b_start);
+dbus_bool_t _dbus_string_starts_with_c_str (const DBusString *a,
+ const char *c_str);
+dbus_bool_t _dbus_string_ends_with_c_str (const DBusString *a,
+ const char *c_str);
+dbus_bool_t _dbus_string_pop_line (DBusString *source,
+ DBusString *dest);
+void _dbus_string_delete_first_word (DBusString *str);
+void _dbus_string_delete_leading_blanks (DBusString *str);
+void _dbus_string_chop_white (DBusString *str);
+dbus_bool_t _dbus_string_append_byte_as_hex (DBusString *str,
+ int byte);
+dbus_bool_t _dbus_string_hex_encode (const DBusString *source,
+ int start,
+ DBusString *dest,
+ int insert_at);
+dbus_bool_t _dbus_string_hex_decode (const DBusString *source,
+ int start,
+ int *end_return,
+ DBusString *dest,
+ int insert_at);
+void _dbus_string_tolower_ascii (const DBusString *str,
+ int start,
+ int len);
+void _dbus_string_toupper_ascii (const DBusString *str,
+ int start,
+ int len);
+dbus_bool_t _dbus_string_validate_ascii (const DBusString *str,
+ int start,
+ int len);
+dbus_bool_t _dbus_string_validate_utf8 (const DBusString *str,
+ int start,
+ int len);
+dbus_bool_t _dbus_string_validate_nul (const DBusString *str,
+ int start,
+ int len);
+void _dbus_string_zero (DBusString *str);
+
+
+/**
+ * We allocate 1 byte for nul termination, plus 7 bytes for possible
+ * align_offset, so we always need 8 bytes on top of the string's
+ * length to be in the allocated block.
+ */
+#define _DBUS_STRING_ALLOCATION_PADDING 8
+
+/**
+ * Defines a static const variable with type #DBusString called "name"
+ * containing the given string literal.
+ *
+ * @param name the name of the variable
+ * @param str the string value
+ */
+#define _DBUS_STRING_DEFINE_STATIC(name, str) \
+ static const char _dbus_static_string_##name[] = str; \
+ static const DBusString name = { _dbus_static_string_##name, \
+ sizeof(_dbus_static_string_##name), \
+ sizeof(_dbus_static_string_##name) + \
+ _DBUS_STRING_ALLOCATION_PADDING, \
+ sizeof(_dbus_static_string_##name), \
+ TRUE, TRUE, FALSE, 0 }
+
+DBUS_END_DECLS
+
+#endif /* DBUS_STRING_H */
diff --git a/lib-x86-32/include/dbus-1/dbus/dbus-sysdeps-unix.h b/lib-x86-32/include/dbus-1/dbus/dbus-sysdeps-unix.h
new file mode 100644
index 00000000..807d2cf5
--- /dev/null
+++ b/lib-x86-32/include/dbus-1/dbus/dbus-sysdeps-unix.h
@@ -0,0 +1,138 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-sysdeps-unix.h UNIX-specific wrappers around system/libc features (internal to D-Bus implementation)
+ *
+ * Copyright (C) 2002, 2003, 2006 Red Hat, Inc.
+ * Copyright (C) 2003 CodeFactory AB
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef DBUS_SYSDEPS_UNIX_H
+#define DBUS_SYSDEPS_UNIX_H
+
+#include <dbus/dbus-sysdeps.h>
+
+#ifdef DBUS_WIN
+#error "Don't include this on Windows"
+#endif
+
+DBUS_BEGIN_DECLS
+
+/**
+ * @defgroup DBusSysdepsUnix UNIX-specific internal API
+ * @ingroup DBusInternals
+ * @brief Internal system-dependent API available on UNIX only
+ * @{
+ */
+
+dbus_bool_t
+_dbus_close (int fd,
+ DBusError *error);
+int _dbus_dup (int fd,
+ DBusError *error);
+int
+_dbus_read (int fd,
+ DBusString *buffer,
+ int count);
+int
+_dbus_write (int fd,
+ const DBusString *buffer,
+ int start,
+ int len);
+int
+_dbus_write_two (int fd,
+ const DBusString *buffer1,
+ int start1,
+ int len1,
+ const DBusString *buffer2,
+ int start2,
+ int len2);
+
+dbus_bool_t _dbus_open_unix_socket (int *fd,
+ DBusError *error);
+int _dbus_connect_unix_socket (const char *path,
+ dbus_bool_t abstract,
+ DBusError *error);
+int _dbus_listen_unix_socket (const char *path,
+ dbus_bool_t abstract,
+ DBusError *error);
+
+int _dbus_listen_systemd_sockets (int **fd,
+ DBusError *error);
+
+dbus_bool_t _dbus_read_credentials (int client_fd,
+ DBusCredentials *credentials,
+ DBusError *error);
+dbus_bool_t _dbus_send_credentials (int server_fd,
+ DBusError *error);
+
+/** Information about a UNIX user */
+typedef struct DBusUserInfo DBusUserInfo;
+/** Information about a UNIX group */
+typedef struct DBusGroupInfo DBusGroupInfo;
+
+/**
+ * Information about a UNIX user
+ */
+struct DBusUserInfo
+{
+ dbus_uid_t uid; /**< UID */
+ dbus_gid_t primary_gid; /**< GID */
+ dbus_gid_t *group_ids; /**< Groups IDs, *including* above primary group */
+ int n_group_ids; /**< Size of group IDs array */
+ char *username; /**< Username */
+ char *homedir; /**< Home directory */
+};
+
+/**
+ * Information about a UNIX group
+ */
+struct DBusGroupInfo
+{
+ dbus_gid_t gid; /**< GID */
+ char *groupname; /**< Group name */
+};
+
+dbus_bool_t _dbus_user_info_fill (DBusUserInfo *info,
+ const DBusString *username,
+ DBusError *error);
+dbus_bool_t _dbus_user_info_fill_uid (DBusUserInfo *info,
+ dbus_uid_t uid,
+ DBusError *error);
+void _dbus_user_info_free (DBusUserInfo *info);
+
+dbus_bool_t _dbus_group_info_fill (DBusGroupInfo *info,
+ const DBusString *groupname,
+ DBusError *error);
+dbus_bool_t _dbus_group_info_fill_gid (DBusGroupInfo *info,
+ dbus_gid_t gid,
+ DBusError *error);
+void _dbus_group_info_free (DBusGroupInfo *info);
+
+dbus_uid_t _dbus_getuid (void);
+dbus_uid_t _dbus_geteuid (void);
+dbus_gid_t _dbus_getgid (void);
+
+dbus_bool_t _dbus_parse_uid (const DBusString *uid_str,
+ dbus_uid_t *uid);
+
+/** @} */
+
+DBUS_END_DECLS
+
+#endif /* DBUS_SYSDEPS_UNIX_H */
diff --git a/lib-x86-32/include/dbus-1/dbus/dbus-sysdeps-win.h b/lib-x86-32/include/dbus-1/dbus/dbus-sysdeps-win.h
new file mode 100644
index 00000000..a8ff9433
--- /dev/null
+++ b/lib-x86-32/include/dbus-1/dbus/dbus-sysdeps-win.h
@@ -0,0 +1,88 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-sysdeps.c Wrappers around system/libc features (internal to D-BUS implementation)
+ *
+ * Copyright (C) 2002, 2003 Red Hat, Inc.
+ * Copyright (C) 2003 CodeFactory AB
+ * Copyright (C) 2005 Novell, Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef DBUS_SYSDEPS_WIN_H
+#define DBUS_SYSDEPS_WIN_H
+
+extern void *_dbus_win_get_dll_hmodule (void);
+#define _WINSOCKAPI_
+
+#include "dbus-hash.h"
+#include "dbus-string.h"
+#include <ctype.h>
+#include <malloc.h>
+#include <windows.h>
+#undef interface
+
+#define DBUS_CONSOLE_DIR "/var/run/console/"
+
+
+void _dbus_win_set_errno (int err);
+const char* _dbus_win_error_from_last_error (void);
+
+void _dbus_win_startup_winsock (void);
+void _dbus_win_warn_win_error (const char *message,
+ int code);
+
+char * _dbus_win_error_string (int error_number);
+void _dbus_win_free_error_string (char *string);
+
+extern const char* _dbus_lm_strerror (int error_number);
+
+
+dbus_bool_t _dbus_win_account_to_sid (const wchar_t *waccount,
+ void **ppsid,
+ DBusError *error);
+
+dbus_bool_t
+_dbus_win32_sid_to_name_and_domain (dbus_uid_t uid,
+ wchar_t **wname,
+ wchar_t **wdomain,
+ DBusError *error);
+
+
+/* Don't define DBUS_CONSOLE_DIR on Win32 */
+
+wchar_t *_dbus_win_utf8_to_utf16 (const char *str,
+ DBusError *error);
+char *_dbus_win_utf16_to_utf8 (const wchar_t *str,
+ DBusError *error);
+
+void _dbus_win_set_error_from_win_error (DBusError *error, int code);
+
+dbus_bool_t
+_dbus_win_sid_to_name_and_domain (dbus_uid_t uid,
+ wchar_t **wname,
+ wchar_t **wdomain,
+ DBusError *error);
+
+dbus_bool_t _dbus_file_exists (const char *filename);
+
+dbus_bool_t _dbus_get_config_file_name(DBusString *config_file,
+ char *s);
+
+#endif
+
+/** @} end of sysdeps-win.h */
diff --git a/lib-x86-32/include/dbus-1/dbus/dbus-sysdeps-wince-glue.h b/lib-x86-32/include/dbus-1/dbus/dbus-sysdeps-wince-glue.h
new file mode 100644
index 00000000..f5ac6c8a
--- /dev/null
+++ b/lib-x86-32/include/dbus-1/dbus/dbus-sysdeps-wince-glue.h
@@ -0,0 +1,246 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-sysdeps-wince-glue.h Emulation of system/libc features for Windows CE (internal to D-Bus implementation)
+ *
+ * Copyright (C) 2002, 2003 Red Hat, Inc.
+ * Copyright (C) 2003 CodeFactory AB
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef DBUS_SYSDEPS_WINCE_GLUE_H
+#define DBUS_SYSDEPS_WINCE_GLUE_H
+
+#include <time.h>
+#include <stdarg.h>
+
+/* For getaddrinfo, configure/cmake defined _WIN32_WCE to something >= 0x0401. */
+#include <windows.h>
+#undef interface
+
+DBUS_BEGIN_DECLS
+
+/* shlobj.h declares these only for _WIN32_IE that we don't want to define.
+ In any case, with mingw32ce we only get a SHGetSpecialFolderPath. */
+#define SHGetSpecialFolderPathW SHGetSpecialFolderPath
+BOOL WINAPI SHGetSpecialFolderPathA(HWND,LPSTR,int,BOOL);
+BOOL WINAPI SHGetSpecialFolderPathW(HWND,LPWSTR,int,BOOL);
+
+#ifndef TLS_OUT_OF_INDEXES
+#define TLS_OUT_OF_INDEXES 0xffffffff
+#endif
+
+
+/* Seriously. Windows CE does not have errno. Don't you hate it when
+ that happens? */
+#define errno ((int)GetLastError ())
+
+#define ENOENT ERROR_FILE_NOT_FOUND
+#define EMFILE ERROR_TOO_MANY_OPEN_FILES
+#define EACCES ERROR_ACCESS_DENIED
+#define EBADF ERROR_INVALID_HANDLE
+#define ENOMEM ERROR_NOT_ENOUGH_MEMORY
+#define EXDEV ERROR_NOT_SAME_DEVICE
+#define ENFILE ERROR_NO_MORE_FILES
+#define EROFS ERROR_WRITE_PROTECT
+#define ENOLCK ERROR_SHARING_BUFFER_EXCEEDED
+#define ENOSYS ERROR_NOT_SUPPORTED
+#define EEXIST ERROR_FILE_EXISTS
+#define EPERM ERROR_CANNOT_MAKE
+#define EINVAL ERROR_INVALID_PARAMETER
+#define EINTR ERROR_INVALID_AT_INTERRUPT_TIME
+#define EPIPE ERROR_BROKEN_PIPE
+#define ENOSPC ERROR_DISK_FULL
+#define ENOTEMPTY ERROR_DIR_NOT_EMPTY
+#define EBUSY ERROR_BUSY
+#define ENAMETOOLONG ERROR_FILENAME_EXCED_RANGE
+#define EAGAIN ERROR_MORE_DATA
+#define ENOTDIR ERROR_DIRECTORY
+#define ERANGE ERROR_ARITHMETIC_OVERFLOW
+#define ENXIO ERROR_FILE_INVALID
+#define EFAULT ERROR_PROCESS_ABORTED
+#define EIO ERROR_IO_DEVICE
+#define EDEADLOCK ERROR_POSSIBLE_DEADLOCK
+#define ENODEV ERROR_BAD_DEVICE
+
+/* Windows CE is missing more stuff that is pretty standard. */
+
+#define strdup _strdup
+#define stricmp _stricmp
+#define strnicmp _strnicmp
+
+#define environ _dbus_wince_environ
+extern char *environ[];
+
+#define getenv _dbus_wince_getenv
+char *getenv (const char *name);
+
+#define putenv _dbus_wince_putenv
+int putenv (char *str);
+
+#define clock _dbus_wince_clock
+clock_t clock (void);
+
+#define abort _dbus_wince_abort
+void abort (void);
+
+#define _S_IFMT 0170000 /* file type mask */
+#define _S_IFDIR 0040000 /* directory */
+#define _S_IFCHR 0020000 /* character special */
+#define _S_IFIFO 0010000 /* pipe */
+#define _S_IFREG 0100000 /* regular */
+#define _S_IREAD 0000400 /* read permission, owner */
+#define _S_IWRITE 0000200 /* write permission, owner */
+#define _S_IEXEC 0000100 /* execute/search permission, owner */
+
+#ifndef __OFF_T_DEFINED
+typedef long off_t;
+#define __OFF_T_DEFINED
+#endif
+#ifndef _INTPTR_T_DEFINED
+typedef int intptr_t;
+#define _INTPTR_T_DEFINED
+#endif
+#ifndef _UINTPTR_T_DEFINED
+typedef unsigned int uintptr_t;
+#define _UINTPTR_T_DEFINED
+#endif
+
+#ifndef _MAX_FNAME
+#define _MAX_FNAME 256
+#endif
+
+#ifndef _IOFBF
+#define _IOFBF 0
+#endif
+#ifndef _IOLBF
+#define _IOLBF 1
+#endif
+#ifndef _IONBF
+#define _IONBF 2
+#endif
+
+
+/* Windows CE is missing some Windows functions that we want. */
+
+#define GetSystemTimeAsFileTime _dbus_wince_GetSystemTimeAsFileTime
+void GetSystemTimeAsFileTime (LPFILETIME ftp);
+
+#define _mbsrchr _dbus_wince_mbsrchr
+unsigned char* _mbsrchr (const unsigned char*, unsigned int);
+
+#define OpenFileMappingA _dbus_wince_OpenFileMappingA
+HANDLE OpenFileMappingA(DWORD,BOOL,LPCSTR);
+
+#define MoveFileExA _dbus_wince_MoveFileExA
+BOOL MoveFileExA(LPCSTR,LPCSTR,DWORD);
+#ifndef MOVEFILE_REPLACE_EXISTING
+#define MOVEFILE_REPLACE_EXISTING 0x00000001
+#endif
+
+#define SetHandleInformation _dbus_wince_SetHandleInformation
+BOOL SetHandleInformation(HANDLE,DWORD,DWORD);
+#ifndef HANDLE_FLAG_INHERIT
+#define HANDLE_FLAG_INHERIT 0x01
+#endif
+#ifndef HANDLE_FLAG_PROTECT
+#define HANDLE_FLAG_PROTECT_FROM_CLOSE 0x02
+#endif
+
+#define SearchPathA _dbus_wince_SearchPathA
+DWORD SearchPathA(LPCSTR,LPCSTR,LPCSTR,DWORD,LPSTR,LPSTR*);
+
+/* Instead of emulating all functions needed for this, we replace the
+ whole thing. */
+dbus_bool_t _dbus_getsid(char **sid);
+
+
+#define LookupAccountNameW _dbus_wince_LookupAccountNameW
+BOOL LookupAccountNameW(LPCWSTR,LPCWSTR,PSID,PDWORD,LPWSTR,PDWORD,PSID_NAME_USE);
+
+#define IsValidSid _dbus_wince_IsValidSid
+BOOL IsValidSid(PSID);
+
+
+/* Windows CE does only have the UNICODE interfaces (FooW), but we
+ want to use the ASCII interfaces (FooA). We implement them
+ here. */
+
+#define CreateFileA _dbus_wince_CreateFileA
+HANDLE CreateFileA(LPCSTR,DWORD,DWORD,LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE);
+
+#define DeleteFileA _dbus_wince_DeleteFileA
+BOOL DeleteFileA(LPCSTR);
+
+#define GetFileAttributesA _dbus_wince_GetFileAttributesA
+DWORD GetFileAttributesA(LPCSTR);
+
+#define GetFileAttributesExA _dbus_wince_GetFileAttributesExA
+BOOL GetFileAttributesExA(LPCSTR,GET_FILEEX_INFO_LEVELS,PVOID);
+
+#define CreateFileMappingA _dbus_wince_CreateFileMappingA
+HANDLE CreateFileMappingA(HANDLE,LPSECURITY_ATTRIBUTES,DWORD,DWORD,DWORD,LPCSTR);
+
+#define CreateDirectoryA _dbus_wince_CreateDirectoryA
+BOOL CreateDirectoryA(LPCSTR,LPSECURITY_ATTRIBUTES);
+
+#define RemoveDirectoryA _dbus_wince_RemoveDirectoryA
+BOOL RemoveDirectoryA(LPCSTR);
+
+#define FindFirstFileA _dbus_wince_FindFirstFileA
+HANDLE FindFirstFileA(LPCSTR,LPWIN32_FIND_DATAA);
+
+#define FindNextFileA _dbus_wince_FindNextFileA
+BOOL FindNextFileA(HANDLE,LPWIN32_FIND_DATAA);
+
+#define CreateMutexA _dbus_wince_CreateMutexA
+HANDLE CreateMutexA(LPSECURITY_ATTRIBUTES,BOOL,LPCSTR);
+
+#define CreateProcessA _dbus_wince_CreateProcessA
+BOOL CreateProcessA(LPCSTR,LPSTR,LPSECURITY_ATTRIBUTES,LPSECURITY_ATTRIBUTES,BOOL,DWORD,PVOID,LPCSTR,LPSTARTUPINFOA,LPPROCESS_INFORMATION);
+#ifndef CREATE_NO_WINDOW
+#define CREATE_NO_WINDOW 0x08000000
+#endif
+
+
+#define RegOpenKeyExA _dbus_wince_RegOpenKeyExA
+LONG RegOpenKeyExA(HKEY,LPCSTR,DWORD,REGSAM,PHKEY);
+
+#define RegQueryValueExA _dbus_wince_RegQueryValueExA
+LONG WINAPI RegQueryValueExA(HKEY,LPCSTR,LPDWORD,LPDWORD,LPBYTE,LPDWORD);
+
+
+#define FormatMessageA _dbus_wince_FormatMessageA
+DWORD FormatMessageA(DWORD,PCVOID,DWORD,DWORD,LPSTR,DWORD,va_list*);
+
+#define GetModuleFileNameA _dbus_wince_GetModuleFileNameA
+DWORD GetModuleFileNameA(HINSTANCE,LPSTR,DWORD);
+
+#define GetTempPathA _dbus_wince_GetTempPathA
+DWORD GetTempPathA(DWORD,LPSTR);
+
+#define SHGetSpecialFolderPathA _dbus_wince_SHGetSpecialFolderPathA
+BOOL SHGetSpecialFolderPathA(HWND,LPSTR,int,BOOL);
+
+
+#define OutputDebugStringA _dbus_wince_OutputDebugStringA
+void OutputDebugStringA(LPCSTR);
+
+
+DBUS_END_DECLS
+
+#endif /* DBUS_SYSDEPS_WINCE_GLUE_H */
diff --git a/lib-x86-32/include/dbus-1/dbus/dbus-sysdeps.h b/lib-x86-32/include/dbus-1/dbus/dbus-sysdeps.h
new file mode 100644
index 00000000..c98db36d
--- /dev/null
+++ b/lib-x86-32/include/dbus-1/dbus/dbus-sysdeps.h
@@ -0,0 +1,531 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-sysdeps.h Wrappers around system/libc features (internal to D-Bus implementation)
+ *
+ * Copyright (C) 2002, 2003 Red Hat, Inc.
+ * Copyright (C) 2003 CodeFactory AB
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef DBUS_SYSDEPS_H
+#define DBUS_SYSDEPS_H
+
+#include "config.h"
+
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
+
+#include <dbus/dbus-errors.h>
+#include <dbus/dbus-file.h>
+#include <dbus/dbus-string.h>
+
+/* this is perhaps bogus, but strcmp() etc. are faster if we use the
+ * stuff straight out of string.h, so have this here for now.
+ */
+#include <string.h>
+#include <stdarg.h>
+
+/* AIX sys/poll.h does #define events reqevents, and other
+ * wonderousness, so must include sys/poll before declaring
+ * DBusPollFD
+ */
+#ifdef HAVE_POLL
+#include <sys/poll.h>
+#endif
+
+#ifdef DBUS_WINCE
+/* Windows CE lacks some system functions (such as errno and clock).
+ We bring them in here. */
+#include "dbus-sysdeps-wince-glue.h"
+#endif
+
+DBUS_BEGIN_DECLS
+
+#ifdef DBUS_WIN
+#define _DBUS_PATH_SEPARATOR ";"
+#else
+#define _DBUS_PATH_SEPARATOR ":"
+#endif
+
+/* Forward declarations */
+
+
+/** An opaque list type */
+typedef struct DBusList DBusList;
+
+/** Object that contains a list of credentials such as UNIX or Windows user ID */
+typedef struct DBusCredentials DBusCredentials;
+
+/** A wrapper around a pipe descriptor or handle */
+typedef struct DBusPipe DBusPipe;
+
+/**
+ * @addtogroup DBusSysdeps
+ *
+ * @{
+ */
+
+void _dbus_abort (void) _DBUS_GNUC_NORETURN;
+
+const char* _dbus_getenv (const char *varname);
+dbus_bool_t _dbus_setenv (const char *varname,
+ const char *value);
+dbus_bool_t _dbus_clearenv (void);
+char ** _dbus_get_environment (void);
+
+/** A process ID */
+typedef unsigned long dbus_pid_t;
+/** A user ID */
+typedef unsigned long dbus_uid_t;
+/** A group ID */
+typedef unsigned long dbus_gid_t;
+
+/** an invalid PID used to represent an uninitialized dbus_pid_t field */
+#define DBUS_PID_UNSET ((dbus_pid_t) -1)
+/** an invalid UID used to represent an uninitialized dbus_uid_t field */
+#define DBUS_UID_UNSET ((dbus_uid_t) -1)
+/** an invalid GID used to represent an uninitialized dbus_gid_t field */
+#define DBUS_GID_UNSET ((dbus_gid_t) -1)
+
+/** an appropriate printf format for dbus_pid_t */
+#define DBUS_PID_FORMAT "%lu"
+/** an appropriate printf format for dbus_uid_t */
+#define DBUS_UID_FORMAT "%lu"
+/** an appropriate printf format for dbus_gid_t */
+#define DBUS_GID_FORMAT "%lu"
+
+
+/**
+ * Socket interface
+ *
+ * @todo Use for the file descriptors a struct
+ * - struct DBusSocket{ int d; }; -
+ * instead of int to get type-safety which
+ * will be checked by the compiler.
+ *
+ */
+
+dbus_bool_t _dbus_open_tcp_socket (int *fd,
+ DBusError *error);
+dbus_bool_t _dbus_close_socket (int fd,
+ DBusError *error);
+int _dbus_read_socket (int fd,
+ DBusString *buffer,
+ int count);
+int _dbus_write_socket (int fd,
+ const DBusString *buffer,
+ int start,
+ int len);
+int _dbus_write_socket_two (int fd,
+ const DBusString *buffer1,
+ int start1,
+ int len1,
+ const DBusString *buffer2,
+ int start2,
+ int len2);
+
+int _dbus_read_socket_with_unix_fds (int fd,
+ DBusString *buffer,
+ int count,
+ int *fds,
+ int *n_fds);
+int _dbus_write_socket_with_unix_fds (int fd,
+ const DBusString *buffer,
+ int start,
+ int len,
+ const int *fds,
+ int n_fds);
+int _dbus_write_socket_with_unix_fds_two (int fd,
+ const DBusString *buffer1,
+ int start1,
+ int len1,
+ const DBusString *buffer2,
+ int start2,
+ int len2,
+ const int *fds,
+ int n_fds);
+
+dbus_bool_t _dbus_socket_is_invalid (int fd);
+
+int _dbus_connect_tcp_socket (const char *host,
+ const char *port,
+ const char *family,
+ DBusError *error);
+int _dbus_connect_tcp_socket_with_nonce (const char *host,
+ const char *port,
+ const char *family,
+ const char *noncefile,
+ DBusError *error);
+int _dbus_listen_tcp_socket (const char *host,
+ const char *port,
+ const char *family,
+ DBusString *retport,
+ int **fds_p,
+ DBusError *error);
+int _dbus_accept (int listen_fd);
+
+
+dbus_bool_t _dbus_read_credentials_socket (int client_fd,
+ DBusCredentials *credentials,
+ DBusError *error);
+dbus_bool_t _dbus_send_credentials_socket (int server_fd,
+ DBusError *error);
+
+dbus_bool_t _dbus_credentials_add_from_user (DBusCredentials *credentials,
+ const DBusString *username);
+dbus_bool_t _dbus_credentials_add_from_current_process (DBusCredentials *credentials);
+dbus_bool_t _dbus_append_user_from_current_process (DBusString *str);
+
+dbus_bool_t _dbus_parse_unix_user_from_config (const DBusString *username,
+ dbus_uid_t *uid_p);
+dbus_bool_t _dbus_parse_unix_group_from_config (const DBusString *groupname,
+ dbus_gid_t *gid_p);
+dbus_bool_t _dbus_unix_groups_from_uid (dbus_uid_t uid,
+ dbus_gid_t **group_ids,
+ int *n_group_ids);
+dbus_bool_t _dbus_unix_user_is_at_console (dbus_uid_t uid,
+ DBusError *error);
+dbus_bool_t _dbus_unix_user_is_process_owner (dbus_uid_t uid);
+dbus_bool_t _dbus_windows_user_is_process_owner (const char *windows_sid);
+
+dbus_bool_t _dbus_append_keyring_directory_for_credentials (DBusString *directory,
+ DBusCredentials *credentials);
+
+void _dbus_daemon_publish_session_bus_address (const char* address);
+
+void _dbus_daemon_unpublish_session_bus_address (void);
+
+dbus_bool_t _dbus_socket_can_pass_unix_fd(int fd);
+
+/** Opaque type representing an atomically-modifiable integer
+ * that can be used from multiple threads.
+ */
+typedef struct DBusAtomic DBusAtomic;
+
+/**
+ * An atomic integer safe to increment or decrement from multiple threads.
+ */
+struct DBusAtomic
+{
+#ifdef DBUS_WIN
+ volatile long value; /**< Value of the atomic integer. */
+#else
+ volatile dbus_int32_t value; /**< Value of the atomic integer. */
+#endif
+};
+
+/* The value we get from autofoo is in the form of a cpp expression;
+ * convert that to a conventional defined/undef switch. (We can't get
+ * the conventional defined/undef because of multiarch builds only running
+ * ./configure once, on Darwin.) */
+#if DBUS_HAVE_ATOMIC_INT_COND
+# define DBUS_HAVE_ATOMIC_INT 1
+#else
+# undef DBUS_HAVE_ATOMIC_INT
+#endif
+
+dbus_int32_t _dbus_atomic_inc (DBusAtomic *atomic);
+dbus_int32_t _dbus_atomic_dec (DBusAtomic *atomic);
+
+
+/* AIX uses different values for poll */
+
+#ifdef _AIX
+/** There is data to read */
+#define _DBUS_POLLIN 0x0001
+/** There is urgent data to read */
+#define _DBUS_POLLPRI 0x0004
+/** Writing now will not block */
+#define _DBUS_POLLOUT 0x0002
+/** Error condition */
+#define _DBUS_POLLERR 0x4000
+/** Hung up */
+#define _DBUS_POLLHUP 0x2000
+/** Invalid request: fd not open */
+#define _DBUS_POLLNVAL 0x8000
+#elif defined(__HAIKU__)
+/** There is data to read */
+#define _DBUS_POLLIN 0x0001
+/** Writing now will not block */
+#define _DBUS_POLLOUT 0x0002
+/** Error condition */
+#define _DBUS_POLLERR 0x0004
+/** There is urgent data to read */
+#define _DBUS_POLLPRI 0x0020
+/** Hung up */
+#define _DBUS_POLLHUP 0x0080
+/** Invalid request: fd not open */
+#define _DBUS_POLLNVAL 0x1000
+#else
+/** There is data to read */
+#define _DBUS_POLLIN 0x0001
+/** There is urgent data to read */
+#define _DBUS_POLLPRI 0x0002
+/** Writing now will not block */
+#define _DBUS_POLLOUT 0x0004
+/** Error condition */
+#define _DBUS_POLLERR 0x0008
+/** Hung up */
+#define _DBUS_POLLHUP 0x0010
+/** Invalid request: fd not open */
+#define _DBUS_POLLNVAL 0x0020
+#endif
+
+/**
+ * A portable struct pollfd wrapper.
+ */
+typedef struct
+{
+ int fd; /**< File descriptor */
+ short events; /**< Events to poll for */
+ short revents; /**< Events that occurred */
+} DBusPollFD;
+
+int _dbus_poll (DBusPollFD *fds,
+ int n_fds,
+ int timeout_milliseconds);
+
+void _dbus_sleep_milliseconds (int milliseconds);
+
+void _dbus_get_current_time (long *tv_sec,
+ long *tv_usec);
+
+/**
+ * directory interface
+ */
+dbus_bool_t _dbus_create_directory (const DBusString *filename,
+ DBusError *error);
+dbus_bool_t _dbus_delete_directory (const DBusString *filename,
+ DBusError *error);
+
+dbus_bool_t _dbus_concat_dir_and_file (DBusString *dir,
+ const DBusString *next_component);
+dbus_bool_t _dbus_string_get_dirname (const DBusString *filename,
+ DBusString *dirname);
+dbus_bool_t _dbus_path_is_absolute (const DBusString *filename);
+
+dbus_bool_t _dbus_get_standard_session_servicedirs (DBusList **dirs);
+dbus_bool_t _dbus_get_standard_system_servicedirs (DBusList **dirs);
+
+dbus_bool_t _dbus_append_system_config_file (DBusString *str);
+dbus_bool_t _dbus_append_session_config_file (DBusString *str);
+
+/** Opaque type for reading a directory listing */
+typedef struct DBusDirIter DBusDirIter;
+
+DBusDirIter* _dbus_directory_open (const DBusString *filename,
+ DBusError *error);
+dbus_bool_t _dbus_directory_get_next_file (DBusDirIter *iter,
+ DBusString *filename,
+ DBusError *error);
+void _dbus_directory_close (DBusDirIter *iter);
+
+dbus_bool_t _dbus_check_dir_is_private_to_user (DBusString *dir,
+ DBusError *error);
+
+void _dbus_fd_set_close_on_exec (intptr_t fd);
+
+const char* _dbus_get_tmpdir (void);
+
+/**
+ * Random numbers
+ */
+void _dbus_generate_pseudorandom_bytes_buffer (char *buffer,
+ int n_bytes);
+void _dbus_generate_random_bytes_buffer (char *buffer,
+ int n_bytes);
+dbus_bool_t _dbus_generate_random_bytes (DBusString *str,
+ int n_bytes);
+dbus_bool_t _dbus_generate_random_ascii (DBusString *str,
+ int n_bytes);
+
+const char* _dbus_error_from_errno (int error_number);
+const char* _dbus_error_from_system_errno (void);
+
+void _dbus_set_errno_to_zero (void);
+dbus_bool_t _dbus_get_is_errno_nonzero (void);
+dbus_bool_t _dbus_get_is_errno_eagain_or_ewouldblock (void);
+dbus_bool_t _dbus_get_is_errno_enomem (void);
+dbus_bool_t _dbus_get_is_errno_eintr (void);
+dbus_bool_t _dbus_get_is_errno_epipe (void);
+const char* _dbus_strerror_from_errno (void);
+
+void _dbus_disable_sigpipe (void);
+
+
+void _dbus_exit (int code) _DBUS_GNUC_NORETURN;
+
+int _dbus_printf_string_upper_bound (const char *format,
+ va_list args);
+
+
+/**
+ * Portable struct with stat() results
+ */
+typedef struct
+{
+ unsigned long mode; /**< File mode */
+ unsigned long nlink; /**< Number of hard links */
+ dbus_uid_t uid; /**< User owning file */
+ dbus_gid_t gid; /**< Group owning file */
+ unsigned long size; /**< Size of file */
+ unsigned long atime; /**< Access time */
+ unsigned long mtime; /**< Modify time */
+ unsigned long ctime; /**< Creation time */
+} DBusStat;
+
+dbus_bool_t _dbus_stat (const DBusString *filename,
+ DBusStat *statbuf,
+ DBusError *error);
+dbus_bool_t _dbus_full_duplex_pipe (int *fd1,
+ int *fd2,
+ dbus_bool_t blocking,
+ DBusError *error);
+
+void _dbus_print_backtrace (void);
+
+dbus_bool_t _dbus_become_daemon (const DBusString *pidfile,
+ DBusPipe *print_pid_pipe,
+ DBusError *error,
+ dbus_bool_t keep_umask);
+
+dbus_bool_t _dbus_verify_daemon_user (const char *user);
+dbus_bool_t _dbus_change_to_daemon_user (const char *user,
+ DBusError *error);
+
+dbus_bool_t _dbus_write_pid_to_file_and_pipe (const DBusString *pidfile,
+ DBusPipe *print_pid_pipe,
+ dbus_pid_t pid_to_write,
+ DBusError *error);
+
+dbus_bool_t _dbus_command_for_pid (unsigned long pid,
+ DBusString *str,
+ int max_len,
+ DBusError *error);
+
+/** A UNIX signal handler */
+typedef void (* DBusSignalHandler) (int sig);
+
+void _dbus_set_signal_handler (int sig,
+ DBusSignalHandler handler);
+
+dbus_bool_t _dbus_user_at_console (const char *username,
+ DBusError *error);
+
+void _dbus_init_system_log (void);
+
+typedef enum {
+ DBUS_SYSTEM_LOG_INFO,
+ DBUS_SYSTEM_LOG_SECURITY,
+ DBUS_SYSTEM_LOG_FATAL
+} DBusSystemLogSeverity;
+
+void _dbus_system_log (DBusSystemLogSeverity severity, const char *msg, ...) _DBUS_GNUC_PRINTF (2, 3);
+void _dbus_system_logv (DBusSystemLogSeverity severity, const char *msg, va_list args);
+
+/* Define DBUS_VA_COPY() to do the right thing for copying va_list variables.
+ * config.h may have already defined DBUS_VA_COPY as va_copy or __va_copy.
+ */
+#if !defined (DBUS_VA_COPY)
+# if defined (__GNUC__) && defined (__PPC__) && (defined (_CALL_SYSV) || defined (_WIN32))
+# define DBUS_VA_COPY(ap1, ap2) (*(ap1) = *(ap2))
+# elif defined (DBUS_VA_COPY_AS_ARRAY)
+# define DBUS_VA_COPY(ap1, ap2) memcpy ((ap1), (ap2), sizeof (va_list))
+# else /* va_list is a pointer */
+# define DBUS_VA_COPY(ap1, ap2) ((ap1) = (ap2))
+# endif /* va_list is a pointer */
+#endif /* !DBUS_VA_COPY */
+
+
+/**
+ * Casts a primitive C type to a byte array and then indexes
+ * a particular byte of the array.
+ */
+#define _DBUS_BYTE_OF_PRIMITIVE(p, i) \
+ (((const char*)&(p))[(i)])
+/** On x86 there is an 80-bit FPU, and if you do "a == b" it may have a
+ * or b in an 80-bit register, thus failing to compare the two 64-bit
+ * doubles for bitwise equality. So this macro compares the two doubles
+ * bitwise.
+ */
+#define _DBUS_DOUBLES_BITWISE_EQUAL(a, b) \
+ (_DBUS_BYTE_OF_PRIMITIVE (a, 0) == _DBUS_BYTE_OF_PRIMITIVE (b, 0) && \
+ _DBUS_BYTE_OF_PRIMITIVE (a, 1) == _DBUS_BYTE_OF_PRIMITIVE (b, 1) && \
+ _DBUS_BYTE_OF_PRIMITIVE (a, 2) == _DBUS_BYTE_OF_PRIMITIVE (b, 2) && \
+ _DBUS_BYTE_OF_PRIMITIVE (a, 3) == _DBUS_BYTE_OF_PRIMITIVE (b, 3) && \
+ _DBUS_BYTE_OF_PRIMITIVE (a, 4) == _DBUS_BYTE_OF_PRIMITIVE (b, 4) && \
+ _DBUS_BYTE_OF_PRIMITIVE (a, 5) == _DBUS_BYTE_OF_PRIMITIVE (b, 5) && \
+ _DBUS_BYTE_OF_PRIMITIVE (a, 6) == _DBUS_BYTE_OF_PRIMITIVE (b, 6) && \
+ _DBUS_BYTE_OF_PRIMITIVE (a, 7) == _DBUS_BYTE_OF_PRIMITIVE (b, 7))
+
+dbus_bool_t _dbus_get_autolaunch_address (DBusString *address,
+ DBusError *error);
+
+dbus_bool_t _dbus_lookup_session_address (dbus_bool_t *supported,
+ DBusString *address,
+ DBusError *error);
+
+/** Type representing a universally unique ID
+ * @todo rename to UUID instead of GUID
+ */
+typedef union DBusGUID DBusGUID;
+
+dbus_bool_t _dbus_read_local_machine_uuid (DBusGUID *machine_id,
+ dbus_bool_t create_if_not_found,
+ DBusError *error);
+
+/**
+ * Initialize threads as in dbus_threads_init_default(), appropriately
+ * for the platform.
+ * @returns #FALSE if no memory
+ */
+dbus_bool_t _dbus_threads_init_platform_specific (void);
+
+dbus_bool_t _dbus_split_paths_and_append (DBusString *dirs,
+ const char *suffix,
+ DBusList **dir_list);
+
+unsigned long _dbus_pid_for_log (void);
+
+/* FIXME move back to dbus-sysdeps-unix.h probably -
+ * the PID file handling just needs a little more abstraction
+ * in the bus daemon first.
+ */
+dbus_pid_t _dbus_getpid (void);
+
+dbus_bool_t _dbus_change_to_daemon_user (const char *user,
+ DBusError *error);
+
+void _dbus_flush_caches (void);
+
+/*
+ * replaces the term DBUS_PREFIX in configure_time_path by the
+ * current dbus installation directory. On unix this function is a noop
+ *
+ * @param configure_time_path
+ * @return real path
+ */
+const char *
+_dbus_replace_install_prefix (const char *configure_time_path);
+
+/** @} */
+
+DBUS_END_DECLS
+
+#endif /* DBUS_SYSDEPS_H */
diff --git a/lib-x86-32/include/dbus-1/dbus/dbus-test.h b/lib-x86-32/include/dbus-1/dbus/dbus-test.h
new file mode 100644
index 00000000..0238b0ce
--- /dev/null
+++ b/lib-x86-32/include/dbus-1/dbus/dbus-test.h
@@ -0,0 +1,83 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-test.h Declarations of test functions.
+ *
+ * Copyright (C) 2002 Red Hat Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef DBUS_TEST_H
+#define DBUS_TEST_H
+
+#include <dbus/dbus-types.h>
+#include <dbus/dbus-string.h>
+#include <dbus/dbus-marshal-validate.h>
+
+dbus_bool_t _dbus_hash_test (void);
+dbus_bool_t _dbus_dict_test (void);
+dbus_bool_t _dbus_list_test (void);
+dbus_bool_t _dbus_marshal_test (void);
+dbus_bool_t _dbus_marshal_recursive_test (void);
+dbus_bool_t _dbus_marshal_byteswap_test (void);
+dbus_bool_t _dbus_marshal_header_test (void);
+dbus_bool_t _dbus_marshal_validate_test (void);
+dbus_bool_t _dbus_misc_test (void);
+dbus_bool_t _dbus_signature_test (void);
+dbus_bool_t _dbus_mem_pool_test (void);
+dbus_bool_t _dbus_string_test (void);
+dbus_bool_t _dbus_address_test (void);
+dbus_bool_t _dbus_server_test (void);
+dbus_bool_t _dbus_message_test (const char *test_data_dir);
+dbus_bool_t _dbus_auth_test (const char *test_data_dir);
+dbus_bool_t _dbus_md5_test (void);
+dbus_bool_t _dbus_sha_test (const char *test_data_dir);
+dbus_bool_t _dbus_keyring_test (void);
+dbus_bool_t _dbus_data_slot_test (void);
+dbus_bool_t _dbus_sysdeps_test (void);
+dbus_bool_t _dbus_spawn_test (const char *test_data_dir);
+dbus_bool_t _dbus_userdb_test (const char *test_data_dir);
+dbus_bool_t _dbus_memory_test (void);
+dbus_bool_t _dbus_object_tree_test (void);
+dbus_bool_t _dbus_pending_call_test (const char *test_data_dir);
+dbus_bool_t _dbus_credentials_test (const char *test_data_dir);
+
+void dbus_internal_do_not_use_run_tests (const char *test_data_dir,
+ const char *specific_test);
+dbus_bool_t dbus_internal_do_not_use_try_message_file (const DBusString *filename,
+ DBusValidity expected_validity);
+dbus_bool_t dbus_internal_do_not_use_try_message_data (const DBusString *data,
+ DBusValidity expected_validity);
+dbus_bool_t dbus_internal_do_not_use_load_message_file (const DBusString *filename,
+ DBusString *data);
+
+
+/* returns FALSE on fatal failure */
+typedef dbus_bool_t (* DBusForeachMessageFileFunc) (const DBusString *filename,
+ DBusValidity expected_validity,
+ void *data);
+
+dbus_bool_t dbus_internal_do_not_use_foreach_message_file (const char *test_data_dir,
+ DBusForeachMessageFileFunc func,
+ void *user_data);
+dbus_bool_t dbus_internal_do_not_use_generate_bodies (int sequence,
+ int byte_order,
+ DBusString *signature,
+ DBusString *body);
+
+
+#endif /* DBUS_TEST_H */
diff --git a/lib-x86-32/include/dbus-1/dbus/dbus-threads-internal.h b/lib-x86-32/include/dbus-1/dbus/dbus-threads-internal.h
new file mode 100644
index 00000000..11f9ce20
--- /dev/null
+++ b/lib-x86-32/include/dbus-1/dbus/dbus-threads-internal.h
@@ -0,0 +1,53 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-threads-internal.h D-Bus thread primitives
+ *
+ * Copyright (C) 2002, 2005 Red Hat Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+#ifndef DBUS_THREADS_INTERNAL_H
+#define DBUS_THREADS_INTERNAL_H
+
+#include <dbus/dbus-macros.h>
+#include <dbus/dbus-types.h>
+#include <dbus/dbus-threads.h>
+
+DBUS_BEGIN_DECLS
+
+DBusMutex* _dbus_mutex_new (void);
+void _dbus_mutex_free (DBusMutex *mutex);
+void _dbus_mutex_lock (DBusMutex *mutex);
+void _dbus_mutex_unlock (DBusMutex *mutex);
+void _dbus_mutex_new_at_location (DBusMutex **location_p);
+void _dbus_mutex_free_at_location (DBusMutex **location_p);
+
+DBusCondVar* _dbus_condvar_new (void);
+void _dbus_condvar_free (DBusCondVar *cond);
+void _dbus_condvar_wait (DBusCondVar *cond,
+ DBusMutex *mutex);
+dbus_bool_t _dbus_condvar_wait_timeout (DBusCondVar *cond,
+ DBusMutex *mutex,
+ int timeout_milliseconds);
+void _dbus_condvar_wake_one (DBusCondVar *cond);
+void _dbus_condvar_wake_all (DBusCondVar *cond);
+void _dbus_condvar_new_at_location (DBusCondVar **location_p);
+void _dbus_condvar_free_at_location (DBusCondVar **location_p);
+
+DBUS_END_DECLS
+
+#endif /* DBUS_THREADS_INTERNAL_H */
diff --git a/lib-x86-32/include/dbus-1/dbus/dbus-threads.h b/lib-x86-32/include/dbus-1/dbus/dbus-threads.h
new file mode 100644
index 00000000..ba07ca57
--- /dev/null
+++ b/lib-x86-32/include/dbus-1/dbus/dbus-threads.h
@@ -0,0 +1,198 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-threads.h D-Bus threads handling
+ *
+ * Copyright (C) 2002 Red Hat Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+#if !defined (DBUS_INSIDE_DBUS_H) && !defined (DBUS_COMPILATION)
+#error "Only <dbus/dbus.h> can be included directly, this file may disappear or change contents."
+#endif
+
+#ifndef DBUS_THREADS_H
+#define DBUS_THREADS_H
+
+#include <dbus/dbus-macros.h>
+#include <dbus/dbus-types.h>
+
+DBUS_BEGIN_DECLS
+
+/**
+ * @addtogroup DBusThreads
+ * @{
+ */
+
+/** An opaque mutex type provided by the #DBusThreadFunctions implementation installed by dbus_threads_init(). */
+typedef struct DBusMutex DBusMutex;
+/** An opaque condition variable type provided by the #DBusThreadFunctions implementation installed by dbus_threads_init(). */
+typedef struct DBusCondVar DBusCondVar;
+
+/** Deprecated, provide DBusRecursiveMutexNewFunction instead. */
+typedef DBusMutex* (* DBusMutexNewFunction) (void);
+/** Deprecated, provide DBusRecursiveMutexFreeFunction instead. */
+typedef void (* DBusMutexFreeFunction) (DBusMutex *mutex);
+/** Deprecated, provide DBusRecursiveMutexLockFunction instead. Return value is lock success, but gets ignored in practice. */
+typedef dbus_bool_t (* DBusMutexLockFunction) (DBusMutex *mutex);
+/** Deprecated, provide DBusRecursiveMutexUnlockFunction instead. Return value is unlock success, but gets ignored in practice. */
+typedef dbus_bool_t (* DBusMutexUnlockFunction) (DBusMutex *mutex);
+
+/** Creates a new recursively-lockable mutex, or returns #NULL if not
+ * enough memory. Can only fail due to lack of memory. Found in
+ * #DBusThreadFunctions. Do not just use PTHREAD_MUTEX_RECURSIVE for
+ * this, because it does not save/restore the recursion count when
+ * waiting on a condition. libdbus requires the Java-style behavior
+ * where the mutex is fully unlocked to wait on a condition.
+ */
+typedef DBusMutex* (* DBusRecursiveMutexNewFunction) (void);
+/** Frees a recursively-lockable mutex. Found in #DBusThreadFunctions.
+ */
+typedef void (* DBusRecursiveMutexFreeFunction) (DBusMutex *mutex);
+/** Locks a recursively-lockable mutex. Found in #DBusThreadFunctions.
+ * Can only fail due to lack of memory.
+ */
+typedef void (* DBusRecursiveMutexLockFunction) (DBusMutex *mutex);
+/** Unlocks a recursively-lockable mutex. Found in #DBusThreadFunctions.
+ * Can only fail due to lack of memory.
+ */
+typedef void (* DBusRecursiveMutexUnlockFunction) (DBusMutex *mutex);
+
+/** Creates a new condition variable. Found in #DBusThreadFunctions.
+ * Can only fail (returning #NULL) due to lack of memory.
+ */
+typedef DBusCondVar* (* DBusCondVarNewFunction) (void);
+/** Frees a condition variable. Found in #DBusThreadFunctions.
+ */
+typedef void (* DBusCondVarFreeFunction) (DBusCondVar *cond);
+
+/** Waits on a condition variable. Found in
+ * #DBusThreadFunctions. Must work with either a recursive or
+ * nonrecursive mutex, whichever the thread implementation
+ * provides. Note that PTHREAD_MUTEX_RECURSIVE does not work with
+ * condition variables (does not save/restore the recursion count) so
+ * don't try using simply pthread_cond_wait() and a
+ * PTHREAD_MUTEX_RECURSIVE to implement this, it won't work right.
+ *
+ * Has no error conditions. Must succeed if it returns.
+ */
+typedef void (* DBusCondVarWaitFunction) (DBusCondVar *cond,
+ DBusMutex *mutex);
+
+/** Waits on a condition variable with a timeout. Found in
+ * #DBusThreadFunctions. Returns #TRUE if the wait did not
+ * time out, and #FALSE if it did.
+ *
+ * Has no error conditions. Must succeed if it returns.
+ */
+typedef dbus_bool_t (* DBusCondVarWaitTimeoutFunction) (DBusCondVar *cond,
+ DBusMutex *mutex,
+ int timeout_milliseconds);
+/** Wakes one waiting thread on a condition variable. Found in #DBusThreadFunctions.
+ *
+ * Has no error conditions. Must succeed if it returns.
+ */
+typedef void (* DBusCondVarWakeOneFunction) (DBusCondVar *cond);
+
+/** Wakes all waiting threads on a condition variable. Found in #DBusThreadFunctions.
+ *
+ * Has no error conditions. Must succeed if it returns.
+ */
+typedef void (* DBusCondVarWakeAllFunction) (DBusCondVar *cond);
+
+/**
+ * Flags indicating which functions are present in #DBusThreadFunctions. Used to allow
+ * the library to detect older callers of dbus_threads_init() if new possible functions
+ * are added to #DBusThreadFunctions.
+ */
+typedef enum
+{
+ DBUS_THREAD_FUNCTIONS_MUTEX_NEW_MASK = 1 << 0,
+ DBUS_THREAD_FUNCTIONS_MUTEX_FREE_MASK = 1 << 1,
+ DBUS_THREAD_FUNCTIONS_MUTEX_LOCK_MASK = 1 << 2,
+ DBUS_THREAD_FUNCTIONS_MUTEX_UNLOCK_MASK = 1 << 3,
+ DBUS_THREAD_FUNCTIONS_CONDVAR_NEW_MASK = 1 << 4,
+ DBUS_THREAD_FUNCTIONS_CONDVAR_FREE_MASK = 1 << 5,
+ DBUS_THREAD_FUNCTIONS_CONDVAR_WAIT_MASK = 1 << 6,
+ DBUS_THREAD_FUNCTIONS_CONDVAR_WAIT_TIMEOUT_MASK = 1 << 7,
+ DBUS_THREAD_FUNCTIONS_CONDVAR_WAKE_ONE_MASK = 1 << 8,
+ DBUS_THREAD_FUNCTIONS_CONDVAR_WAKE_ALL_MASK = 1 << 9,
+ DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_NEW_MASK = 1 << 10,
+ DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_FREE_MASK = 1 << 11,
+ DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_LOCK_MASK = 1 << 12,
+ DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_UNLOCK_MASK = 1 << 13,
+ DBUS_THREAD_FUNCTIONS_ALL_MASK = (1 << 14) - 1
+} DBusThreadFunctionsMask;
+
+/**
+ * Functions that must be implemented to make the D-Bus library
+ * thread-aware. The recursive mutex functions should be specified
+ * rather than the old, deprecated nonrecursive ones.
+ *
+ * The condition variable functions have to work with recursive
+ * mutexes if you provide those, or with nonrecursive mutexes if you
+ * provide those.
+ *
+ * If implementing threads using pthreads, be aware that
+ * PTHREAD_MUTEX_RECURSIVE is broken in combination with condition
+ * variables. libdbus relies on the Java-style behavior that when
+ * waiting on a condition, the recursion count is saved and restored,
+ * and the mutex is completely unlocked, not just decremented one
+ * level of recursion.
+ *
+ * Thus with pthreads you probably have to roll your own emulated
+ * recursive mutexes, you can't use PTHREAD_MUTEX_RECURSIVE. This is
+ * what dbus_threads_init_default() does on platforms that use
+ * pthreads.
+ */
+typedef struct
+{
+ unsigned int mask; /**< Mask indicating which functions are present. */
+
+ DBusMutexNewFunction mutex_new; /**< Function to create a mutex; optional and deprecated. */
+ DBusMutexFreeFunction mutex_free; /**< Function to free a mutex; optional and deprecated. */
+ DBusMutexLockFunction mutex_lock; /**< Function to lock a mutex; optional and deprecated. */
+ DBusMutexUnlockFunction mutex_unlock; /**< Function to unlock a mutex; optional and deprecated. */
+
+ DBusCondVarNewFunction condvar_new; /**< Function to create a condition variable */
+ DBusCondVarFreeFunction condvar_free; /**< Function to free a condition variable */
+ DBusCondVarWaitFunction condvar_wait; /**< Function to wait on a condition */
+ DBusCondVarWaitTimeoutFunction condvar_wait_timeout; /**< Function to wait on a condition with a timeout */
+ DBusCondVarWakeOneFunction condvar_wake_one; /**< Function to wake one thread waiting on the condition */
+ DBusCondVarWakeAllFunction condvar_wake_all; /**< Function to wake all threads waiting on the condition */
+
+ DBusRecursiveMutexNewFunction recursive_mutex_new; /**< Function to create a recursive mutex */
+ DBusRecursiveMutexFreeFunction recursive_mutex_free; /**< Function to free a recursive mutex */
+ DBusRecursiveMutexLockFunction recursive_mutex_lock; /**< Function to lock a recursive mutex */
+ DBusRecursiveMutexUnlockFunction recursive_mutex_unlock; /**< Function to unlock a recursive mutex */
+
+ void (* padding1) (void); /**< Reserved for future expansion */
+ void (* padding2) (void); /**< Reserved for future expansion */
+ void (* padding3) (void); /**< Reserved for future expansion */
+ void (* padding4) (void); /**< Reserved for future expansion */
+
+} DBusThreadFunctions;
+
+DBUS_EXPORT
+dbus_bool_t dbus_threads_init (const DBusThreadFunctions *functions);
+DBUS_EXPORT
+dbus_bool_t dbus_threads_init_default (void);
+
+/** @} */
+
+DBUS_END_DECLS
+
+#endif /* DBUS_THREADS_H */
diff --git a/lib-x86-32/include/dbus-1/dbus/dbus-timeout.h b/lib-x86-32/include/dbus-1/dbus/dbus-timeout.h
new file mode 100644
index 00000000..d0a8af4a
--- /dev/null
+++ b/lib-x86-32/include/dbus-1/dbus/dbus-timeout.h
@@ -0,0 +1,75 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-timeout.h DBusTimeout internal interfaces
+ *
+ * Copyright (C) 2003 CodeFactory AB
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+#ifndef DBUS_TIMEOUT_H
+#define DBUS_TIMEOUT_H
+
+#include <dbus/dbus-connection.h>
+#include <dbus/dbus-internals.h>
+
+DBUS_BEGIN_DECLS
+
+/**
+ * @addtogroup DBusTimeoutInternals
+ * @{
+ */
+
+/* Public methods on DBusTimeout are in dbus-connection.h */
+
+typedef struct DBusTimeoutList DBusTimeoutList;
+
+/** function to run when the timeout is handled */
+typedef dbus_bool_t (* DBusTimeoutHandler) (void *data);
+
+DBusTimeout* _dbus_timeout_new (int interval,
+ DBusTimeoutHandler handler,
+ void *data,
+ DBusFreeFunction free_data_function);
+DBusTimeout* _dbus_timeout_ref (DBusTimeout *timeout);
+void _dbus_timeout_unref (DBusTimeout *timeout);
+void _dbus_timeout_set_interval (DBusTimeout *timeout,
+ int interval);
+void _dbus_timeout_set_enabled (DBusTimeout *timeout,
+ dbus_bool_t enabled);
+
+DBusTimeoutList *_dbus_timeout_list_new (void);
+void _dbus_timeout_list_free (DBusTimeoutList *timeout_list);
+dbus_bool_t _dbus_timeout_list_set_functions (DBusTimeoutList *timeout_list,
+ DBusAddTimeoutFunction add_function,
+ DBusRemoveTimeoutFunction remove_function,
+ DBusTimeoutToggledFunction toggled_function,
+ void *data,
+ DBusFreeFunction free_data_function);
+dbus_bool_t _dbus_timeout_list_add_timeout (DBusTimeoutList *timeout_list,
+ DBusTimeout *timeout);
+void _dbus_timeout_list_remove_timeout (DBusTimeoutList *timeout_list,
+ DBusTimeout *timeout);
+void _dbus_timeout_list_toggle_timeout (DBusTimeoutList *timeout_list,
+ DBusTimeout *timeout,
+ dbus_bool_t enabled);
+
+
+/** @} */
+
+DBUS_END_DECLS
+
+#endif /* DBUS_TIMEOUT_H */
diff --git a/lib-x86-32/include/dbus-1/dbus/dbus-transport-protected.h b/lib-x86-32/include/dbus-1/dbus/dbus-transport-protected.h
new file mode 100644
index 00000000..44b9d785
--- /dev/null
+++ b/lib-x86-32/include/dbus-1/dbus/dbus-transport-protected.h
@@ -0,0 +1,146 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-transport-protected.h Used by subclasses of DBusTransport object (internal to D-Bus implementation)
+ *
+ * Copyright (C) 2002, 2004 Red Hat Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+#ifndef DBUS_TRANSPORT_PROTECTED_H
+#define DBUS_TRANSPORT_PROTECTED_H
+
+#include <dbus/dbus-internals.h>
+#include <dbus/dbus-errors.h>
+#include <dbus/dbus-transport.h>
+#include <dbus/dbus-message-internal.h>
+#include <dbus/dbus-auth.h>
+#include <dbus/dbus-resources.h>
+
+DBUS_BEGIN_DECLS
+
+typedef struct DBusTransportVTable DBusTransportVTable;
+
+/**
+ * The virtual table that must be implemented to
+ * create a new kind of transport.
+ */
+struct DBusTransportVTable
+{
+ void (* finalize) (DBusTransport *transport);
+ /**< The finalize method must free the transport. */
+
+ dbus_bool_t (* handle_watch) (DBusTransport *transport,
+ DBusWatch *watch,
+ unsigned int flags);
+ /**< The handle_watch method handles reading/writing
+ * data as indicated by the flags.
+ */
+
+ void (* disconnect) (DBusTransport *transport);
+ /**< Disconnect this transport. */
+
+ dbus_bool_t (* connection_set) (DBusTransport *transport);
+ /**< Called when transport->connection has been filled in */
+
+ void (* do_iteration) (DBusTransport *transport,
+ unsigned int flags,
+ int timeout_milliseconds);
+ /**< Called to do a single "iteration" (block on select/poll
+ * followed by reading or writing data).
+ */
+
+ void (* live_messages_changed) (DBusTransport *transport);
+ /**< Outstanding messages counter changed */
+
+ dbus_bool_t (* get_socket_fd) (DBusTransport *transport,
+ int *fd_p);
+ /**< Get socket file descriptor */
+};
+
+/**
+ * Object representing a transport such as a socket.
+ * A transport can shuttle messages from point A to point B,
+ * and is the backend for a #DBusConnection.
+ *
+ */
+struct DBusTransport
+{
+ int refcount; /**< Reference count. */
+
+ const DBusTransportVTable *vtable; /**< Virtual methods for this instance. */
+
+ DBusConnection *connection; /**< Connection owning this transport. */
+
+ DBusMessageLoader *loader; /**< Message-loading buffer. */
+
+ DBusAuth *auth; /**< Authentication conversation */
+
+ DBusCredentials *credentials; /**< Credentials of other end read from the socket */
+
+ long max_live_messages_size; /**< Max total size of received messages. */
+ long max_live_messages_unix_fds; /**< Max total unix fds of received messages. */
+
+ DBusCounter *live_messages; /**< Counter for size/unix fds of all live messages. */
+
+ char *address; /**< Address of the server we are connecting to (#NULL for the server side of a transport) */
+
+ char *expected_guid; /**< GUID we expect the server to have, #NULL on server side or if we don't have an expectation */
+
+ DBusAllowUnixUserFunction unix_user_function; /**< Function for checking whether a user is authorized. */
+ void *unix_user_data; /**< Data for unix_user_function */
+
+ DBusFreeFunction free_unix_user_data; /**< Function to free unix_user_data */
+
+ DBusAllowWindowsUserFunction windows_user_function; /**< Function for checking whether a user is authorized. */
+ void *windows_user_data; /**< Data for windows_user_function */
+
+ DBusFreeFunction free_windows_user_data; /**< Function to free windows_user_data */
+
+ unsigned int disconnected : 1; /**< #TRUE if we are disconnected. */
+ unsigned int authenticated : 1; /**< Cache of auth state; use _dbus_transport_get_is_authenticated() to query value */
+ unsigned int send_credentials_pending : 1; /**< #TRUE if we need to send credentials */
+ unsigned int receive_credentials_pending : 1; /**< #TRUE if we need to receive credentials */
+ unsigned int is_server : 1; /**< #TRUE if on the server side */
+ unsigned int unused_bytes_recovered : 1; /**< #TRUE if we've recovered unused bytes from auth */
+ unsigned int allow_anonymous : 1; /**< #TRUE if an anonymous client can connect */
+};
+
+dbus_bool_t _dbus_transport_init_base (DBusTransport *transport,
+ const DBusTransportVTable *vtable,
+ const DBusString *server_guid,
+ const DBusString *address);
+void _dbus_transport_finalize_base (DBusTransport *transport);
+
+
+typedef enum
+{
+ DBUS_TRANSPORT_OPEN_NOT_HANDLED, /**< we aren't in charge of this address type */
+ DBUS_TRANSPORT_OPEN_OK, /**< we set up the listen */
+ DBUS_TRANSPORT_OPEN_BAD_ADDRESS, /**< malformed address */
+ DBUS_TRANSPORT_OPEN_DID_NOT_CONNECT /**< well-formed address but failed to set it up */
+} DBusTransportOpenResult;
+
+DBusTransportOpenResult _dbus_transport_open_platform_specific (DBusAddressEntry *entry,
+ DBusTransport **transport_p,
+ DBusError *error);
+
+#define DBUS_TRANSPORT_CAN_SEND_UNIX_FD(x) \
+ _dbus_auth_get_unix_fd_negotiated((x)->auth)
+
+DBUS_END_DECLS
+
+#endif /* DBUS_TRANSPORT_PROTECTED_H */
diff --git a/lib-x86-32/include/dbus-1/dbus/dbus-transport-socket.h b/lib-x86-32/include/dbus-1/dbus/dbus-transport-socket.h
new file mode 100644
index 00000000..8aefae37
--- /dev/null
+++ b/lib-x86-32/include/dbus-1/dbus/dbus-transport-socket.h
@@ -0,0 +1,46 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-transport-socket.h Socket subclasses of DBusTransport
+ *
+ * Copyright (C) 2002, 2006 Red Hat Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+#ifndef DBUS_TRANSPORT_SOCKET_H
+#define DBUS_TRANSPORT_SOCKET_H
+
+#include <dbus/dbus-transport-protected.h>
+
+DBUS_BEGIN_DECLS
+
+DBusTransport* _dbus_transport_new_for_socket (int fd,
+ const DBusString *server_guid,
+ const DBusString *address);
+DBusTransport* _dbus_transport_new_for_tcp_socket (const char *host,
+ const char *port,
+ const char *family,
+ const char *noncefile,
+ DBusError *error);
+DBusTransportOpenResult _dbus_transport_open_socket (DBusAddressEntry *entry,
+ DBusTransport **transport_p,
+ DBusError *error);
+
+
+
+DBUS_END_DECLS
+
+#endif /* DBUS_TRANSPORT_SOCKET_H */
diff --git a/lib-x86-32/include/dbus-1/dbus/dbus-transport-unix.h b/lib-x86-32/include/dbus-1/dbus/dbus-transport-unix.h
new file mode 100644
index 00000000..783a8313
--- /dev/null
+++ b/lib-x86-32/include/dbus-1/dbus/dbus-transport-unix.h
@@ -0,0 +1,37 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-transport-unix.h UNIX socket subclasses of DBusTransport
+ *
+ * Copyright (C) 2002 Red Hat Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+#ifndef DBUS_TRANSPORT_UNIX_H
+#define DBUS_TRANSPORT_UNIX_H
+
+#include <dbus/dbus-transport.h>
+
+DBUS_BEGIN_DECLS
+
+DBusTransport* _dbus_transport_new_for_domain_socket (const char *path,
+ dbus_bool_t abstract,
+ DBusError *error);
+
+
+DBUS_END_DECLS
+
+#endif /* DBUS_TRANSPORT_UNIX_H */
diff --git a/lib-x86-32/include/dbus-1/dbus/dbus-transport-win.h b/lib-x86-32/include/dbus-1/dbus/dbus-transport-win.h
new file mode 100644
index 00000000..af997a27
--- /dev/null
+++ b/lib-x86-32/include/dbus-1/dbus/dbus-transport-win.h
@@ -0,0 +1,33 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-transport-win.h Windows socket subclasses of DBusTransport
+ *
+ * Copyright (C) 2002 Red Hat Inc.
+ * Copyright (C) 2007 Ralf Habacker <ralf.habacker@freenet.de>
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+#ifndef DBUS_TRANSPORT_WIN_H
+#define DBUS_TRANSPORT_WIN_H
+
+#include <dbus/dbus-transport.h>
+
+DBUS_BEGIN_DECLS
+
+DBUS_END_DECLS
+
+#endif /* DBUS_TRANSPORT_WIN_H */
diff --git a/lib-x86-32/include/dbus-1/dbus/dbus-transport.h b/lib-x86-32/include/dbus-1/dbus/dbus-transport.h
new file mode 100644
index 00000000..0db048a2
--- /dev/null
+++ b/lib-x86-32/include/dbus-1/dbus/dbus-transport.h
@@ -0,0 +1,103 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-transport.h DBusTransport object (internal to D-BUS implementation)
+ *
+ * Copyright (C) 2002, 2004 Red Hat Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+#ifndef DBUS_TRANSPORT_H
+#define DBUS_TRANSPORT_H
+
+#include <dbus/dbus-internals.h>
+#include <dbus/dbus-connection.h>
+#include <dbus/dbus-protocol.h>
+#include <dbus/dbus-address.h>
+
+DBUS_BEGIN_DECLS
+
+typedef struct DBusTransport DBusTransport;
+
+DBusTransport* _dbus_transport_open (DBusAddressEntry *entry,
+ DBusError *error);
+DBusTransport* _dbus_transport_ref (DBusTransport *transport);
+void _dbus_transport_unref (DBusTransport *transport);
+void _dbus_transport_disconnect (DBusTransport *transport);
+dbus_bool_t _dbus_transport_get_is_connected (DBusTransport *transport);
+dbus_bool_t _dbus_transport_get_is_authenticated (DBusTransport *transport);
+dbus_bool_t _dbus_transport_get_is_anonymous (DBusTransport *transport);
+dbus_bool_t _dbus_transport_can_pass_unix_fd (DBusTransport *transport);
+
+const char* _dbus_transport_get_address (DBusTransport *transport);
+const char* _dbus_transport_get_server_id (DBusTransport *transport);
+dbus_bool_t _dbus_transport_handle_watch (DBusTransport *transport,
+ DBusWatch *watch,
+ unsigned int condition);
+dbus_bool_t _dbus_transport_set_connection (DBusTransport *transport,
+ DBusConnection *connection);
+void _dbus_transport_do_iteration (DBusTransport *transport,
+ unsigned int flags,
+ int timeout_milliseconds);
+DBusDispatchStatus _dbus_transport_get_dispatch_status (DBusTransport *transport);
+dbus_bool_t _dbus_transport_queue_messages (DBusTransport *transport);
+
+void _dbus_transport_set_max_message_size (DBusTransport *transport,
+ long size);
+long _dbus_transport_get_max_message_size (DBusTransport *transport);
+void _dbus_transport_set_max_received_size (DBusTransport *transport,
+ long size);
+long _dbus_transport_get_max_received_size (DBusTransport *transport);
+
+void _dbus_transport_set_max_message_unix_fds (DBusTransport *transport,
+ long n);
+long _dbus_transport_get_max_message_unix_fds (DBusTransport *transport);
+void _dbus_transport_set_max_received_unix_fds(DBusTransport *transport,
+ long n);
+long _dbus_transport_get_max_received_unix_fds(DBusTransport *transport);
+
+dbus_bool_t _dbus_transport_get_socket_fd (DBusTransport *transport,
+ int *fd_p);
+dbus_bool_t _dbus_transport_get_unix_user (DBusTransport *transport,
+ unsigned long *uid);
+dbus_bool_t _dbus_transport_get_unix_process_id (DBusTransport *transport,
+ unsigned long *pid);
+dbus_bool_t _dbus_transport_get_adt_audit_session_data (DBusTransport *transport,
+ void **data,
+ int *data_size);
+void _dbus_transport_set_unix_user_function (DBusTransport *transport,
+ DBusAllowUnixUserFunction function,
+ void *data,
+ DBusFreeFunction free_data_function,
+ void **old_data,
+ DBusFreeFunction *old_free_data_function);
+dbus_bool_t _dbus_transport_get_windows_user (DBusTransport *transport,
+ char **windows_sid_p);
+void _dbus_transport_set_windows_user_function (DBusTransport *transport,
+ DBusAllowWindowsUserFunction function,
+ void *data,
+ DBusFreeFunction free_data_function,
+ void **old_data,
+ DBusFreeFunction *old_free_data_function);
+dbus_bool_t _dbus_transport_set_auth_mechanisms (DBusTransport *transport,
+ const char **mechanisms);
+void _dbus_transport_set_allow_anonymous (DBusTransport *transport,
+ dbus_bool_t value);
+
+
+DBUS_END_DECLS
+
+#endif /* DBUS_TRANSPORT_H */
diff --git a/lib-x86-32/include/dbus-1/dbus/dbus-types.h b/lib-x86-32/include/dbus-1/dbus/dbus-types.h
new file mode 100644
index 00000000..54f348f3
--- /dev/null
+++ b/lib-x86-32/include/dbus-1/dbus/dbus-types.h
@@ -0,0 +1,139 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-types.h types such as dbus_bool_t
+ *
+ * Copyright (C) 2002 Red Hat Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+#if !defined (DBUS_INSIDE_DBUS_H) && !defined (DBUS_COMPILATION)
+#error "Only <dbus/dbus.h> can be included directly, this file may disappear or change contents."
+#endif
+
+#ifndef DBUS_TYPES_H
+#define DBUS_TYPES_H
+
+#include <stddef.h>
+#include <dbus/dbus-arch-deps.h>
+
+typedef dbus_uint32_t dbus_unichar_t;
+/* boolean size must be fixed at 4 bytes due to wire protocol! */
+typedef dbus_uint32_t dbus_bool_t;
+
+/* Normally docs are in .c files, but there isn't a .c file for this. */
+/**
+ * @defgroup DBusTypes Basic types
+ * @ingroup DBus
+ * @brief dbus_bool_t, dbus_int32_t, etc.
+ *
+ * Typedefs for common primitive types.
+ *
+ * @{
+ */
+
+/**
+ * @typedef dbus_bool_t
+ *
+ * A boolean, valid values are #TRUE and #FALSE.
+ */
+
+/**
+ * @typedef dbus_uint32_t
+ *
+ * A 32-bit unsigned integer on all platforms.
+ */
+
+/**
+ * @typedef dbus_int32_t
+ *
+ * A 32-bit signed integer on all platforms.
+ */
+
+/**
+ * @typedef dbus_uint16_t
+ *
+ * A 16-bit unsigned integer on all platforms.
+ */
+
+/**
+ * @typedef dbus_int16_t
+ *
+ * A 16-bit signed integer on all platforms.
+ */
+
+
+/**
+ * @typedef dbus_uint64_t
+ *
+ * A 64-bit unsigned integer on all platforms that support it.
+ * If supported, #DBUS_HAVE_INT64 will be defined.
+ *
+ * C99 requires a 64-bit type and most likely all interesting
+ * compilers support one. GLib for example flat-out requires
+ * a 64-bit type.
+ *
+ * You probably want to just assume #DBUS_HAVE_INT64 is always defined.
+ */
+
+/**
+ * @typedef dbus_int64_t
+ *
+ * A 64-bit signed integer on all platforms that support it.
+ * If supported, #DBUS_HAVE_INT64 will be defined.
+ *
+ * C99 requires a 64-bit type and most likely all interesting
+ * compilers support one. GLib for example flat-out requires
+ * a 64-bit type.
+ *
+ * You probably want to just assume #DBUS_HAVE_INT64 is always defined.
+ */
+
+/**
+ * @def DBUS_HAVE_INT64
+ *
+ * Defined if 64-bit integers are available. Will be defined
+ * on any platform you care about, unless you care about
+ * some truly ancient UNIX, or some bizarre embedded platform.
+ *
+ * C99 requires a 64-bit type and most likely all interesting
+ * compilers support one. GLib for example flat-out requires
+ * a 64-bit type.
+ *
+ * You should feel comfortable ignoring this macro and just using
+ * int64 unconditionally.
+ *
+ */
+
+/**
+ * @def DBUS_INT64_CONSTANT
+ *
+ * Declare a 64-bit signed integer constant. The macro
+ * adds the necessary "LL" or whatever after the integer,
+ * giving a literal such as "325145246765LL"
+ */
+
+/**
+ * @def DBUS_UINT64_CONSTANT
+ *
+ * Declare a 64-bit unsigned integer constant. The macro
+ * adds the necessary "ULL" or whatever after the integer,
+ * giving a literal such as "325145246765ULL"
+ */
+
+/** @} */
+
+#endif /* DBUS_TYPES_H */
diff --git a/lib-x86-32/include/dbus-1/dbus/dbus-userdb.h b/lib-x86-32/include/dbus-1/dbus/dbus-userdb.h
new file mode 100644
index 00000000..cb49d9e7
--- /dev/null
+++ b/lib-x86-32/include/dbus-1/dbus/dbus-userdb.h
@@ -0,0 +1,121 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-userdb.h User database abstraction
+ *
+ * Copyright (C) 2003 Red Hat, Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef DBUS_USERDB_H
+#define DBUS_USERDB_H
+
+#include <dbus/dbus-sysdeps-unix.h>
+
+#ifdef DBUS_WIN
+#error "Don't include this on Windows"
+#endif
+
+DBUS_BEGIN_DECLS
+
+typedef struct DBusUserDatabase DBusUserDatabase;
+
+#ifdef DBUS_USERDB_INCLUDES_PRIVATE
+#include <dbus/dbus-hash.h>
+
+/**
+ * Internals of DBusUserDatabase
+ */
+struct DBusUserDatabase
+{
+ int refcount; /**< Reference count */
+
+ DBusHashTable *users; /**< Users in the database by UID */
+ DBusHashTable *groups; /**< Groups in the database by GID */
+ DBusHashTable *users_by_name; /**< Users in the database by name */
+ DBusHashTable *groups_by_name; /**< Groups in the database by name */
+
+};
+
+
+DBusUserDatabase* _dbus_user_database_new (void);
+DBusUserDatabase* _dbus_user_database_ref (DBusUserDatabase *db);
+void _dbus_user_database_flush (DBusUserDatabase *db);
+void _dbus_user_database_unref (DBusUserDatabase *db);
+dbus_bool_t _dbus_user_database_get_uid (DBusUserDatabase *db,
+ dbus_uid_t uid,
+ const DBusUserInfo **info,
+ DBusError *error);
+dbus_bool_t _dbus_user_database_get_gid (DBusUserDatabase *db,
+ dbus_gid_t gid,
+ const DBusGroupInfo **info,
+ DBusError *error);
+dbus_bool_t _dbus_user_database_get_username (DBusUserDatabase *db,
+ const DBusString *username,
+ const DBusUserInfo **info,
+ DBusError *error);
+dbus_bool_t _dbus_user_database_get_groupname (DBusUserDatabase *db,
+ const DBusString *groupname,
+ const DBusGroupInfo **info,
+ DBusError *error);
+
+DBusUserInfo* _dbus_user_database_lookup (DBusUserDatabase *db,
+ dbus_uid_t uid,
+ const DBusString *username,
+ DBusError *error);
+DBusGroupInfo* _dbus_user_database_lookup_group (DBusUserDatabase *db,
+ dbus_gid_t gid,
+ const DBusString *groupname,
+ DBusError *error);
+void _dbus_user_info_free_allocated (DBusUserInfo *info);
+void _dbus_group_info_free_allocated (DBusGroupInfo *info);
+#endif /* DBUS_USERDB_INCLUDES_PRIVATE */
+
+DBusUserDatabase* _dbus_user_database_get_system (void);
+void _dbus_user_database_lock_system (void);
+void _dbus_user_database_unlock_system (void);
+void _dbus_user_database_flush_system (void);
+
+dbus_bool_t _dbus_get_user_id (const DBusString *username,
+ dbus_uid_t *uid);
+dbus_bool_t _dbus_get_group_id (const DBusString *group_name,
+ dbus_gid_t *gid);
+dbus_bool_t _dbus_get_user_id_and_primary_group (const DBusString *username,
+ dbus_uid_t *uid_p,
+ dbus_gid_t *gid_p);
+dbus_bool_t _dbus_credentials_from_uid (dbus_uid_t user_id,
+ DBusCredentials *credentials);
+dbus_bool_t _dbus_groups_from_uid (dbus_uid_t uid,
+ dbus_gid_t **group_ids,
+ int *n_group_ids);
+dbus_bool_t _dbus_is_console_user (dbus_uid_t uid,
+ DBusError *error);
+
+dbus_bool_t _dbus_is_a_number (const DBusString *str,
+ unsigned long *num);
+
+dbus_bool_t _dbus_username_from_current_process (const DBusString **username);
+dbus_bool_t _dbus_homedir_from_current_process (const DBusString **homedir);
+dbus_bool_t _dbus_homedir_from_username (const DBusString *username,
+ DBusString *homedir);
+
+dbus_bool_t _dbus_homedir_from_uid (dbus_uid_t uid,
+ DBusString *homedir);
+
+DBUS_END_DECLS
+
+#endif /* DBUS_USERDB_H */
diff --git a/lib-x86-32/include/dbus-1/dbus/dbus-uuidgen.h b/lib-x86-32/include/dbus-1/dbus/dbus-uuidgen.h
new file mode 100644
index 00000000..9c1b8595
--- /dev/null
+++ b/lib-x86-32/include/dbus-1/dbus/dbus-uuidgen.h
@@ -0,0 +1,47 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-uuidgen.h The guts of the dbus-uuidgen binary live in libdbus, in this file.
+ *
+ * Copyright (C) 2006 Red Hat, Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+#ifdef DBUS_INSIDE_DBUS_H
+#error "You can't include dbus-uuidgen.h in the public header dbus.h"
+#endif
+
+#ifndef DBUS_UUIDGEN_H
+#define DBUS_UUIDGEN_H
+
+#include <dbus/dbus-types.h>
+#include <dbus/dbus-errors.h>
+
+DBUS_BEGIN_DECLS
+
+dbus_bool_t dbus_internal_do_not_use_get_uuid (const char *filename,
+ char **uuid_p,
+ dbus_bool_t create_if_not_found,
+ DBusError *error);
+dbus_bool_t dbus_internal_do_not_use_ensure_uuid (const char *filename,
+ char **uuid_p,
+ DBusError *error);
+dbus_bool_t dbus_internal_do_not_use_create_uuid (char **uuid_p);
+
+
+DBUS_END_DECLS
+
+#endif /* DBUS_UUIDGEN_H */
diff --git a/lib-x86-32/include/dbus-1/dbus/dbus-watch.h b/lib-x86-32/include/dbus-1/dbus/dbus-watch.h
new file mode 100644
index 00000000..fa953ec1
--- /dev/null
+++ b/lib-x86-32/include/dbus-1/dbus/dbus-watch.h
@@ -0,0 +1,83 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-watch.h DBusWatch internal interfaces
+ *
+ * Copyright (C) 2002 Red Hat Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+#ifndef DBUS_WATCH_H
+#define DBUS_WATCH_H
+
+#include <dbus/dbus-internals.h>
+#include <dbus/dbus-connection.h>
+
+DBUS_BEGIN_DECLS
+
+/**
+ * @addtogroup DBusWatchInternals
+ * @{
+ */
+
+/* Public methods on DBusWatch are in dbus-connection.h */
+
+typedef struct DBusWatchList DBusWatchList;
+
+/** function to run when the watch is handled */
+typedef dbus_bool_t (* DBusWatchHandler) (DBusWatch *watch,
+ unsigned int flags,
+ void *data);
+
+DBusWatch* _dbus_watch_new (int fd,
+ unsigned int flags,
+ dbus_bool_t enabled,
+ DBusWatchHandler handler,
+ void *data,
+ DBusFreeFunction free_data_function);
+DBusWatch* _dbus_watch_ref (DBusWatch *watch);
+void _dbus_watch_unref (DBusWatch *watch);
+void _dbus_watch_invalidate (DBusWatch *watch);
+void _dbus_watch_sanitize_condition (DBusWatch *watch,
+ unsigned int *condition);
+void _dbus_watch_set_handler (DBusWatch *watch,
+ DBusWatchHandler handler,
+ void *data,
+ DBusFreeFunction free_data_function);
+
+
+DBusWatchList* _dbus_watch_list_new (void);
+void _dbus_watch_list_free (DBusWatchList *watch_list);
+dbus_bool_t _dbus_watch_list_set_functions (DBusWatchList *watch_list,
+ DBusAddWatchFunction add_function,
+ DBusRemoveWatchFunction remove_function,
+ DBusWatchToggledFunction toggled_function,
+ void *data,
+ DBusFreeFunction free_data_function);
+dbus_bool_t _dbus_watch_list_add_watch (DBusWatchList *watch_list,
+ DBusWatch *watch);
+void _dbus_watch_list_remove_watch (DBusWatchList *watch_list,
+ DBusWatch *watch);
+void _dbus_watch_list_toggle_watch (DBusWatchList *watch_list,
+ DBusWatch *watch,
+ dbus_bool_t enabled);
+dbus_bool_t _dbus_watch_get_enabled (DBusWatch *watch);
+
+/** @} */
+
+DBUS_END_DECLS
+
+#endif /* DBUS_WATCH_H */
diff --git a/lib-x86-32/include/dbus-1/dbus/dbus.h b/lib-x86-32/include/dbus-1/dbus/dbus.h
new file mode 100644
index 00000000..1f099508
--- /dev/null
+++ b/lib-x86-32/include/dbus-1/dbus/dbus.h
@@ -0,0 +1,103 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus.h Convenience header including all other headers
+ *
+ * Copyright (C) 2002, 2003 Red Hat Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef DBUS_H
+#define DBUS_H
+
+#define DBUS_INSIDE_DBUS_H 1
+
+#include <dbus/dbus-arch-deps.h>
+#include <dbus/dbus-address.h>
+#include <dbus/dbus-bus.h>
+#include <dbus/dbus-connection.h>
+#include <dbus/dbus-errors.h>
+#include <dbus/dbus-macros.h>
+#include <dbus/dbus-message.h>
+#include <dbus/dbus-misc.h>
+#include <dbus/dbus-pending-call.h>
+#include <dbus/dbus-protocol.h>
+#include <dbus/dbus-server.h>
+#include <dbus/dbus-shared.h>
+#include <dbus/dbus-signature.h>
+#include <dbus/dbus-threads.h>
+#include <dbus/dbus-types.h>
+
+#undef DBUS_INSIDE_DBUS_H
+
+/**
+ * @defgroup DBus D-Bus low-level public API
+ * @brief The low-level public API of the D-Bus library
+ *
+ * libdbus provides a low-level C API intended primarily for use by
+ * bindings to specific object systems and languages. D-Bus is most
+ * convenient when used with the GLib bindings, Python bindings, Qt
+ * bindings, Mono bindings, and so forth. This low-level API has a
+ * lot of complexity useful only for bindings.
+ *
+ * @{
+ */
+
+/** @} */
+
+/**
+ * @mainpage
+ *
+ * This manual documents the <em>low-level</em> D-Bus C API. <b>If you use
+ * this low-level API directly, you're signing up for some pain.</b>
+ *
+ * Caveats aside, you might get started learning the low-level API by reading
+ * about @ref DBusConnection and @ref DBusMessage.
+ *
+ * There are several other places to look for D-Bus information, such
+ * as the tutorial and the specification; those can be found at <a
+ * href="http://www.freedesktop.org/wiki/Software/dbus">the D-Bus
+ * website</a>. If you're interested in a sysadmin or package
+ * maintainer's perspective on the dbus-daemon itself and its
+ * configuration, be sure to check out the man pages as well.
+ *
+ * The low-level API documented in this manual deliberately lacks
+ * most convenience functions - those are left up to higher-level libraries
+ * based on frameworks such as GLib, Qt, Python, Mono, Java,
+ * etc. These higher-level libraries (often called "D-Bus bindings")
+ * have features such as object systems and main loops that allow a
+ * <em>much</em> more convenient API.
+ *
+ * The low-level API also contains plenty of clutter to support
+ * integration with arbitrary object systems, languages, main loops,
+ * and so forth. These features add a lot of noise to the API that you
+ * probably don't care about unless you're coding a binding.
+ *
+ * This manual also contains docs for @ref DBusInternals "D-Bus internals",
+ * so you can use it to get oriented to the D-Bus source code if you're
+ * interested in patching the code. You should also read the
+ * file HACKING which comes with the source code if you plan to contribute to
+ * D-Bus.
+ *
+ * As you read the code, you can identify internal D-Bus functions
+ * because they start with an underscore ('_') character. Also, any
+ * identifier or macro that lacks a DBus, dbus_, or DBUS_ namepace
+ * prefix is internal, with a couple of exceptions such as #NULL,
+ * #TRUE, and #FALSE.
+ */
+
+#endif /* DBUS_H */
diff --git a/lib-x86-32/include/dbus-1/dbus/sd-daemon.h b/lib-x86-32/include/dbus-1/dbus/sd-daemon.h
new file mode 100644
index 00000000..c68c96d2
--- /dev/null
+++ b/lib-x86-32/include/dbus-1/dbus/sd-daemon.h
@@ -0,0 +1,257 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#ifndef foosddaemonhfoo
+#define foosddaemonhfoo
+
+/***
+ Copyright 2010 Lennart Poettering
+
+ Permission is hereby granted, free of charge, to any person
+ obtaining a copy of this software and associated documentation files
+ (the "Software"), to deal in the Software without restriction,
+ including without limitation the rights to use, copy, modify, merge,
+ publish, distribute, sublicense, and/or sell copies of the Software,
+ and to permit persons to whom the Software is furnished to do so,
+ subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
+***/
+
+#include <sys/types.h>
+#include <inttypes.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ Reference implementation of a few systemd related interfaces for
+ writing daemons. These interfaces are trivial to implement. To
+ simplify porting we provide this reference implementation.
+ Applications are welcome to reimplement the algorithms described
+ here if they do not want to include these two source files.
+
+ The following functionality is provided:
+
+ - Support for logging with log levels on stderr
+ - File descriptor passing for socket-based activation
+ - Daemon startup and status notification
+ - Detection of systemd boots
+
+ You may compile this with -DDISABLE_SYSTEMD to disable systemd
+ support. This makes all those calls NOPs that are directly related to
+ systemd (i.e. only sd_is_xxx() will stay useful).
+
+ Since this is drop-in code we don't want any of our symbols to be
+ exported in any case. Hence we declare hidden visibility for all of
+ them.
+
+ You may find an up-to-date version of these source files online:
+
+ http://cgit.freedesktop.org/systemd/plain/src/sd-daemon.h
+ http://cgit.freedesktop.org/systemd/plain/src/sd-daemon.c
+
+ This should compile on non-Linux systems, too, but with the
+ exception of the sd_is_xxx() calls all functions will become NOPs.
+
+ See sd-daemon(7) for more information.
+*/
+
+#if __GNUC__ >= 4
+#define _sd_printf_attr_(a,b) __attribute__ ((format (printf, a, b)))
+#define _sd_hidden_ __attribute__ ((visibility("hidden")))
+#else
+#define _sd_printf_attr_(a,b)
+#define _sd_hidden_
+#endif
+
+/*
+ Log levels for usage on stderr:
+
+ fprintf(stderr, SD_NOTICE "Hello World!\n");
+
+ This is similar to printk() usage in the kernel.
+*/
+#define SD_EMERG "<0>" /* system is unusable */
+#define SD_ALERT "<1>" /* action must be taken immediately */
+#define SD_CRIT "<2>" /* critical conditions */
+#define SD_ERR "<3>" /* error conditions */
+#define SD_WARNING "<4>" /* warning conditions */
+#define SD_NOTICE "<5>" /* normal but significant condition */
+#define SD_INFO "<6>" /* informational */
+#define SD_DEBUG "<7>" /* debug-level messages */
+
+/* The first passed file descriptor is fd 3 */
+#define SD_LISTEN_FDS_START 3
+
+/*
+ Returns how many file descriptors have been passed, or a negative
+ errno code on failure. Optionally, removes the $LISTEN_FDS and
+ $LISTEN_PID file descriptors from the environment (recommended, but
+ problematic in threaded environments). If r is the return value of
+ this function you'll find the file descriptors passed as fds
+ SD_LISTEN_FDS_START to SD_LISTEN_FDS_START+r-1. Returns a negative
+ errno style error code on failure. This function call ensures that
+ the FD_CLOEXEC flag is set for the passed file descriptors, to make
+ sure they are not passed on to child processes. If FD_CLOEXEC shall
+ not be set, the caller needs to unset it after this call for all file
+ descriptors that are used.
+
+ See sd_listen_fds(3) for more information.
+*/
+int sd_listen_fds(int unset_environment) _sd_hidden_;
+
+/*
+ Helper call for identifying a passed file descriptor. Returns 1 if
+ the file descriptor is a FIFO in the file system stored under the
+ specified path, 0 otherwise. If path is NULL a path name check will
+ not be done and the call only verifies if the file descriptor
+ refers to a FIFO. Returns a negative errno style error code on
+ failure.
+
+ See sd_is_fifo(3) for more information.
+*/
+int sd_is_fifo(int fd, const char *path) _sd_hidden_;
+
+/*
+ Helper call for identifying a passed file descriptor. Returns 1 if
+ the file descriptor is a socket of the specified family (AF_INET,
+ ...) and type (SOCK_DGRAM, SOCK_STREAM, ...), 0 otherwise. If
+ family is 0 a socket family check will not be done. If type is 0 a
+ socket type check will not be done and the call only verifies if
+ the file descriptor refers to a socket. If listening is > 0 it is
+ verified that the socket is in listening mode. (i.e. listen() has
+ been called) If listening is == 0 it is verified that the socket is
+ not in listening mode. If listening is < 0 no listening mode check
+ is done. Returns a negative errno style error code on failure.
+
+ See sd_is_socket(3) for more information.
+*/
+int sd_is_socket(int fd, int family, int type, int listening) _sd_hidden_;
+
+/*
+ Helper call for identifying a passed file descriptor. Returns 1 if
+ the file descriptor is an Internet socket, of the specified family
+ (either AF_INET or AF_INET6) and the specified type (SOCK_DGRAM,
+ SOCK_STREAM, ...), 0 otherwise. If version is 0 a protocol version
+ check is not done. If type is 0 a socket type check will not be
+ done. If port is 0 a socket port check will not be done. The
+ listening flag is used the same way as in sd_is_socket(). Returns a
+ negative errno style error code on failure.
+
+ See sd_is_socket_inet(3) for more information.
+*/
+int sd_is_socket_inet(int fd, int family, int type, int listening, uint16_t port) _sd_hidden_;
+
+/*
+ Helper call for identifying a passed file descriptor. Returns 1 if
+ the file descriptor is an AF_UNIX socket of the specified type
+ (SOCK_DGRAM, SOCK_STREAM, ...) and path, 0 otherwise. If type is 0
+ a socket type check will not be done. If path is NULL a socket path
+ check will not be done. For normal AF_UNIX sockets set length to
+ 0. For abstract namespace sockets set length to the length of the
+ socket name (including the initial 0 byte), and pass the full
+ socket path in path (including the initial 0 byte). The listening
+ flag is used the same way as in sd_is_socket(). Returns a negative
+ errno style error code on failure.
+
+ See sd_is_socket_unix(3) for more information.
+*/
+int sd_is_socket_unix(int fd, int type, int listening, const char *path, size_t length) _sd_hidden_;
+
+/*
+ Informs systemd about changed daemon state. This takes a number of
+ newline seperated environment-style variable assignments in a
+ string. The following variables are known:
+
+ READY=1 Tells systemd that daemon startup is finished (only
+ relevant for services of Type=notify). The passed
+ argument is a boolean "1" or "0". Since there is
+ little value in signalling non-readiness the only
+ value daemons should send is "READY=1".
+
+ STATUS=... Passes a single-line status string back to systemd
+ that describes the daemon state. This is free-from
+ and can be used for various purposes: general state
+ feedback, fsck-like programs could pass completion
+ percentages and failing programs could pass a human
+ readable error message. Example: "STATUS=Completed
+ 66% of file system check..."
+
+ ERRNO=... If a daemon fails, the errno-style error code,
+ formatted as string. Example: "ERRNO=2" for ENOENT.
+
+ BUSERROR=... If a daemon fails, the D-Bus error-style error
+ code. Example: "BUSERROR=org.freedesktop.DBus.Error.TimedOut"
+
+ MAINPID=... The main pid of a daemon, in case systemd did not
+ fork off the process itself. Example: "MAINPID=4711"
+
+ Daemons can choose to send additional variables. However, it is
+ recommened to prefix variable names not listed above with X_.
+
+ Returns a negative errno-style error code on failure. Returns > 0
+ if systemd could be notified, 0 if it couldn't possibly because
+ systemd is not running.
+
+ Example: When a daemon finished starting up, it could issue this
+ call to notify systemd about it:
+
+ sd_notify(0, "READY=1");
+
+ See sd_notifyf() for more complete examples.
+
+ See sd_notify(3) for more information.
+*/
+int sd_notify(int unset_environment, const char *state) _sd_hidden_;
+
+/*
+ Similar to sd_notify() but takes a format string.
+
+ Example 1: A daemon could send the following after initialization:
+
+ sd_notifyf(0, "READY=1\n"
+ "STATUS=Processing requests...\n"
+ "MAINPID=%lu",
+ (unsigned long) getpid());
+
+ Example 2: A daemon could send the following shortly before
+ exiting, on failure:
+
+ sd_notifyf(0, "STATUS=Failed to start up: %s\n"
+ "ERRNO=%i",
+ strerror(errno),
+ errno);
+
+ See sd_notifyf(3) for more information.
+*/
+int sd_notifyf(int unset_environment, const char *format, ...) _sd_printf_attr_(2,3) _sd_hidden_;
+
+/*
+ Returns > 0 if the system was booted with systemd. Returns < 0 on
+ error. Returns 0 if the system was not booted with systemd. Note
+ that all of the functions above handle non-systemd boots just
+ fine. You should NOT protect them with a call to this function. Also
+ note that this function checks whether the system, not the user
+ session is controlled by systemd. However the functions above work
+ for both session and system services.
+
+ See sd_booted(3) for more information.
+*/
+int sd_booted(void) _sd_hidden_;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib-x86-32/include/faad.h b/lib-x86-32/include/faad.h
new file mode 100644
index 00000000..72f40728
--- /dev/null
+++ b/lib-x86-32/include/faad.h
@@ -0,0 +1,35 @@
+/*
+** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+**
+** Any non-GPL usage of this software or parts of this software is strictly
+** forbidden.
+**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
+** Commercial non-GPL licensing of this software is possible.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
+**
+** $Id: faad.h,v 1.51 2007/11/01 12:33:29 menno Exp $
+**/
+
+/* warn people for update */
+#pragma message("please update faad2 include filename and function names!")
+
+/* Backwards compatible link */
+#include "neaacdec.h"
diff --git a/lib-x86-32/include/libavcodec/avcodec.h b/lib-x86-32/include/libavcodec/avcodec.h
new file mode 100644
index 00000000..974e87cc
--- /dev/null
+++ b/lib-x86-32/include/libavcodec/avcodec.h
@@ -0,0 +1,3968 @@
+/*
+ * copyright (c) 2001 Fabrice Bellard
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVCODEC_AVCODEC_H
+#define AVCODEC_AVCODEC_H
+
+/**
+ * @file
+ * external API header
+ */
+
+#include <errno.h>
+#include "libavutil/avutil.h"
+
+#define LIBAVCODEC_VERSION_MAJOR 52
+#define LIBAVCODEC_VERSION_MINOR 72
+#define LIBAVCODEC_VERSION_MICRO 2
+
+#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
+ LIBAVCODEC_VERSION_MINOR, \
+ LIBAVCODEC_VERSION_MICRO)
+#define LIBAVCODEC_VERSION AV_VERSION(LIBAVCODEC_VERSION_MAJOR, \
+ LIBAVCODEC_VERSION_MINOR, \
+ LIBAVCODEC_VERSION_MICRO)
+#define LIBAVCODEC_BUILD LIBAVCODEC_VERSION_INT
+
+#define LIBAVCODEC_IDENT "Lavc" AV_STRINGIFY(LIBAVCODEC_VERSION)
+
+#define AV_NOPTS_VALUE INT64_C(0x8000000000000000)
+#define AV_TIME_BASE 1000000
+#define AV_TIME_BASE_Q (AVRational){1, AV_TIME_BASE}
+
+/**
+ * Identifies the syntax and semantics of the bitstream.
+ * The principle is roughly:
+ * Two decoders with the same ID can decode the same streams.
+ * Two encoders with the same ID can encode compatible streams.
+ * There may be slight deviations from the principle due to implementation
+ * details.
+ *
+ * If you add a codec ID to this list, add it so that
+ * 1. no value of a existing codec ID changes (that would break ABI),
+ * 2. it is as close as possible to similar codecs.
+ */
+enum CodecID {
+ CODEC_ID_NONE,
+
+ /* video codecs */
+ CODEC_ID_MPEG1VIDEO,
+ CODEC_ID_MPEG2VIDEO, ///< preferred ID for MPEG-1/2 video decoding
+ CODEC_ID_MPEG2VIDEO_XVMC,
+ CODEC_ID_H261,
+ CODEC_ID_H263,
+ CODEC_ID_RV10,
+ CODEC_ID_RV20,
+ CODEC_ID_MJPEG,
+ CODEC_ID_MJPEGB,
+ CODEC_ID_LJPEG,
+ CODEC_ID_SP5X,
+ CODEC_ID_JPEGLS,
+ CODEC_ID_MPEG4,
+ CODEC_ID_RAWVIDEO,
+ CODEC_ID_MSMPEG4V1,
+ CODEC_ID_MSMPEG4V2,
+ CODEC_ID_MSMPEG4V3,
+ CODEC_ID_WMV1,
+ CODEC_ID_WMV2,
+ CODEC_ID_H263P,
+ CODEC_ID_H263I,
+ CODEC_ID_FLV1,
+ CODEC_ID_SVQ1,
+ CODEC_ID_SVQ3,
+ CODEC_ID_DVVIDEO,
+ CODEC_ID_HUFFYUV,
+ CODEC_ID_CYUV,
+ CODEC_ID_H264,
+ CODEC_ID_INDEO3,
+ CODEC_ID_VP3,
+ CODEC_ID_THEORA,
+ CODEC_ID_ASV1,
+ CODEC_ID_ASV2,
+ CODEC_ID_FFV1,
+ CODEC_ID_4XM,
+ CODEC_ID_VCR1,
+ CODEC_ID_CLJR,
+ CODEC_ID_MDEC,
+ CODEC_ID_ROQ,
+ CODEC_ID_INTERPLAY_VIDEO,
+ CODEC_ID_XAN_WC3,
+ CODEC_ID_XAN_WC4,
+ CODEC_ID_RPZA,
+ CODEC_ID_CINEPAK,
+ CODEC_ID_WS_VQA,
+ CODEC_ID_MSRLE,
+ CODEC_ID_MSVIDEO1,
+ CODEC_ID_IDCIN,
+ CODEC_ID_8BPS,
+ CODEC_ID_SMC,
+ CODEC_ID_FLIC,
+ CODEC_ID_TRUEMOTION1,
+ CODEC_ID_VMDVIDEO,
+ CODEC_ID_MSZH,
+ CODEC_ID_ZLIB,
+ CODEC_ID_QTRLE,
+ CODEC_ID_SNOW,
+ CODEC_ID_TSCC,
+ CODEC_ID_ULTI,
+ CODEC_ID_QDRAW,
+ CODEC_ID_VIXL,
+ CODEC_ID_QPEG,
+#if LIBAVCODEC_VERSION_MAJOR < 53
+ CODEC_ID_XVID,
+#endif
+ CODEC_ID_PNG,
+ CODEC_ID_PPM,
+ CODEC_ID_PBM,
+ CODEC_ID_PGM,
+ CODEC_ID_PGMYUV,
+ CODEC_ID_PAM,
+ CODEC_ID_FFVHUFF,
+ CODEC_ID_RV30,
+ CODEC_ID_RV40,
+ CODEC_ID_VC1,
+ CODEC_ID_WMV3,
+ CODEC_ID_LOCO,
+ CODEC_ID_WNV1,
+ CODEC_ID_AASC,
+ CODEC_ID_INDEO2,
+ CODEC_ID_FRAPS,
+ CODEC_ID_TRUEMOTION2,
+ CODEC_ID_BMP,
+ CODEC_ID_CSCD,
+ CODEC_ID_MMVIDEO,
+ CODEC_ID_ZMBV,
+ CODEC_ID_AVS,
+ CODEC_ID_SMACKVIDEO,
+ CODEC_ID_NUV,
+ CODEC_ID_KMVC,
+ CODEC_ID_FLASHSV,
+ CODEC_ID_CAVS,
+ CODEC_ID_JPEG2000,
+ CODEC_ID_VMNC,
+ CODEC_ID_VP5,
+ CODEC_ID_VP6,
+ CODEC_ID_VP6F,
+ CODEC_ID_TARGA,
+ CODEC_ID_DSICINVIDEO,
+ CODEC_ID_TIERTEXSEQVIDEO,
+ CODEC_ID_TIFF,
+ CODEC_ID_GIF,
+ CODEC_ID_FFH264,
+ CODEC_ID_DXA,
+ CODEC_ID_DNXHD,
+ CODEC_ID_THP,
+ CODEC_ID_SGI,
+ CODEC_ID_C93,
+ CODEC_ID_BETHSOFTVID,
+ CODEC_ID_PTX,
+ CODEC_ID_TXD,
+ CODEC_ID_VP6A,
+ CODEC_ID_AMV,
+ CODEC_ID_VB,
+ CODEC_ID_PCX,
+ CODEC_ID_SUNRAST,
+ CODEC_ID_INDEO4,
+ CODEC_ID_INDEO5,
+ CODEC_ID_MIMIC,
+ CODEC_ID_RL2,
+ CODEC_ID_8SVX_EXP,
+ CODEC_ID_8SVX_FIB,
+ CODEC_ID_ESCAPE124,
+ CODEC_ID_DIRAC,
+ CODEC_ID_BFI,
+ CODEC_ID_CMV,
+ CODEC_ID_MOTIONPIXELS,
+ CODEC_ID_TGV,
+ CODEC_ID_TGQ,
+ CODEC_ID_TQI,
+ CODEC_ID_AURA,
+ CODEC_ID_AURA2,
+ CODEC_ID_V210X,
+ CODEC_ID_TMV,
+ CODEC_ID_V210,
+ CODEC_ID_DPX,
+ CODEC_ID_MAD,
+ CODEC_ID_FRWU,
+ CODEC_ID_FLASHSV2,
+ CODEC_ID_CDGRAPHICS,
+ CODEC_ID_R210,
+ CODEC_ID_ANM,
+ CODEC_ID_BINKVIDEO,
+ CODEC_ID_IFF_ILBM,
+ CODEC_ID_IFF_BYTERUN1,
+ CODEC_ID_KGV1,
+ CODEC_ID_YOP,
+ CODEC_ID_VP8,
+
+ /* various PCM "codecs" */
+ CODEC_ID_PCM_S16LE= 0x10000,
+ CODEC_ID_PCM_S16BE,
+ CODEC_ID_PCM_U16LE,
+ CODEC_ID_PCM_U16BE,
+ CODEC_ID_PCM_S8,
+ CODEC_ID_PCM_U8,
+ CODEC_ID_PCM_MULAW,
+ CODEC_ID_PCM_ALAW,
+ CODEC_ID_PCM_S32LE,
+ CODEC_ID_PCM_S32BE,
+ CODEC_ID_PCM_U32LE,
+ CODEC_ID_PCM_U32BE,
+ CODEC_ID_PCM_S24LE,
+ CODEC_ID_PCM_S24BE,
+ CODEC_ID_PCM_U24LE,
+ CODEC_ID_PCM_U24BE,
+ CODEC_ID_PCM_S24DAUD,
+ CODEC_ID_PCM_ZORK,
+ CODEC_ID_PCM_S16LE_PLANAR,
+ CODEC_ID_PCM_DVD,
+ CODEC_ID_PCM_F32BE,
+ CODEC_ID_PCM_F32LE,
+ CODEC_ID_PCM_F64BE,
+ CODEC_ID_PCM_F64LE,
+ CODEC_ID_PCM_BLURAY,
+
+ /* various ADPCM codecs */
+ CODEC_ID_ADPCM_IMA_QT= 0x11000,
+ CODEC_ID_ADPCM_IMA_WAV,
+ CODEC_ID_ADPCM_IMA_DK3,
+ CODEC_ID_ADPCM_IMA_DK4,
+ CODEC_ID_ADPCM_IMA_WS,
+ CODEC_ID_ADPCM_IMA_SMJPEG,
+ CODEC_ID_ADPCM_MS,
+ CODEC_ID_ADPCM_4XM,
+ CODEC_ID_ADPCM_XA,
+ CODEC_ID_ADPCM_ADX,
+ CODEC_ID_ADPCM_EA,
+ CODEC_ID_ADPCM_G726,
+ CODEC_ID_ADPCM_CT,
+ CODEC_ID_ADPCM_SWF,
+ CODEC_ID_ADPCM_YAMAHA,
+ CODEC_ID_ADPCM_SBPRO_4,
+ CODEC_ID_ADPCM_SBPRO_3,
+ CODEC_ID_ADPCM_SBPRO_2,
+ CODEC_ID_ADPCM_THP,
+ CODEC_ID_ADPCM_IMA_AMV,
+ CODEC_ID_ADPCM_EA_R1,
+ CODEC_ID_ADPCM_EA_R3,
+ CODEC_ID_ADPCM_EA_R2,
+ CODEC_ID_ADPCM_IMA_EA_SEAD,
+ CODEC_ID_ADPCM_IMA_EA_EACS,
+ CODEC_ID_ADPCM_EA_XAS,
+ CODEC_ID_ADPCM_EA_MAXIS_XA,
+ CODEC_ID_ADPCM_IMA_ISS,
+
+ /* AMR */
+ CODEC_ID_AMR_NB= 0x12000,
+ CODEC_ID_AMR_WB,
+
+ /* RealAudio codecs*/
+ CODEC_ID_RA_144= 0x13000,
+ CODEC_ID_RA_288,
+
+ /* various DPCM codecs */
+ CODEC_ID_ROQ_DPCM= 0x14000,
+ CODEC_ID_INTERPLAY_DPCM,
+ CODEC_ID_XAN_DPCM,
+ CODEC_ID_SOL_DPCM,
+
+ /* audio codecs */
+ CODEC_ID_MP2= 0x15000,
+ CODEC_ID_MP3, ///< preferred ID for decoding MPEG audio layer 1, 2 or 3
+ CODEC_ID_AAC,
+ CODEC_ID_AC3,
+ CODEC_ID_DTS,
+ CODEC_ID_VORBIS,
+ CODEC_ID_DVAUDIO,
+ CODEC_ID_WMAV1,
+ CODEC_ID_WMAV2,
+ CODEC_ID_MACE3,
+ CODEC_ID_MACE6,
+ CODEC_ID_VMDAUDIO,
+ CODEC_ID_SONIC,
+ CODEC_ID_SONIC_LS,
+ CODEC_ID_FLAC,
+ CODEC_ID_MP3ADU,
+ CODEC_ID_MP3ON4,
+ CODEC_ID_SHORTEN,
+ CODEC_ID_ALAC,
+ CODEC_ID_WESTWOOD_SND1,
+ CODEC_ID_GSM, ///< as in Berlin toast format
+ CODEC_ID_QDM2,
+ CODEC_ID_COOK,
+ CODEC_ID_TRUESPEECH,
+ CODEC_ID_TTA,
+ CODEC_ID_SMACKAUDIO,
+ CODEC_ID_QCELP,
+ CODEC_ID_WAVPACK,
+ CODEC_ID_DSICINAUDIO,
+ CODEC_ID_IMC,
+ CODEC_ID_MUSEPACK7,
+ CODEC_ID_MLP,
+ CODEC_ID_GSM_MS, /* as found in WAV */
+ CODEC_ID_ATRAC3,
+ CODEC_ID_VOXWARE,
+ CODEC_ID_APE,
+ CODEC_ID_NELLYMOSER,
+ CODEC_ID_MUSEPACK8,
+ CODEC_ID_SPEEX,
+ CODEC_ID_WMAVOICE,
+ CODEC_ID_WMAPRO,
+ CODEC_ID_WMALOSSLESS,
+ CODEC_ID_ATRAC3P,
+ CODEC_ID_EAC3,
+ CODEC_ID_SIPR,
+ CODEC_ID_MP1,
+ CODEC_ID_TWINVQ,
+ CODEC_ID_TRUEHD,
+ CODEC_ID_MP4ALS,
+ CODEC_ID_ATRAC1,
+ CODEC_ID_BINKAUDIO_RDFT,
+ CODEC_ID_BINKAUDIO_DCT,
+
+ /* subtitle codecs */
+ CODEC_ID_DVD_SUBTITLE= 0x17000,
+ CODEC_ID_DVB_SUBTITLE,
+ CODEC_ID_TEXT, ///< raw UTF-8 text
+ CODEC_ID_XSUB,
+ CODEC_ID_SSA,
+ CODEC_ID_MOV_TEXT,
+ CODEC_ID_HDMV_PGS_SUBTITLE,
+ CODEC_ID_DVB_TELETEXT,
+
+ /* other specific kind of codecs (generally used for attachments) */
+ CODEC_ID_TTF= 0x18000,
+
+ CODEC_ID_PROBE= 0x19000, ///< codec_id is not known (like CODEC_ID_NONE) but lavf should attempt to identify it
+
+ CODEC_ID_MPEG2TS= 0x20000, /**< _FAKE_ codec to indicate a raw MPEG-2 TS
+ * stream (only used by libavformat) */
+};
+
+#if LIBAVCODEC_VERSION_MAJOR < 53
+#define CodecType AVMediaType
+
+#define CODEC_TYPE_UNKNOWN AVMEDIA_TYPE_UNKNOWN
+#define CODEC_TYPE_VIDEO AVMEDIA_TYPE_VIDEO
+#define CODEC_TYPE_AUDIO AVMEDIA_TYPE_AUDIO
+#define CODEC_TYPE_DATA AVMEDIA_TYPE_DATA
+#define CODEC_TYPE_SUBTITLE AVMEDIA_TYPE_SUBTITLE
+#define CODEC_TYPE_ATTACHMENT AVMEDIA_TYPE_ATTACHMENT
+#define CODEC_TYPE_NB AVMEDIA_TYPE_NB
+#endif
+
+/**
+ * all in native-endian format
+ */
+enum SampleFormat {
+ SAMPLE_FMT_NONE = -1,
+ SAMPLE_FMT_U8, ///< unsigned 8 bits
+ SAMPLE_FMT_S16, ///< signed 16 bits
+ SAMPLE_FMT_S32, ///< signed 32 bits
+ SAMPLE_FMT_FLT, ///< float
+ SAMPLE_FMT_DBL, ///< double
+ SAMPLE_FMT_NB ///< Number of sample formats. DO NOT USE if dynamically linking to libavcodec
+};
+
+/* Audio channel masks */
+#define CH_FRONT_LEFT 0x00000001
+#define CH_FRONT_RIGHT 0x00000002
+#define CH_FRONT_CENTER 0x00000004
+#define CH_LOW_FREQUENCY 0x00000008
+#define CH_BACK_LEFT 0x00000010
+#define CH_BACK_RIGHT 0x00000020
+#define CH_FRONT_LEFT_OF_CENTER 0x00000040
+#define CH_FRONT_RIGHT_OF_CENTER 0x00000080
+#define CH_BACK_CENTER 0x00000100
+#define CH_SIDE_LEFT 0x00000200
+#define CH_SIDE_RIGHT 0x00000400
+#define CH_TOP_CENTER 0x00000800
+#define CH_TOP_FRONT_LEFT 0x00001000
+#define CH_TOP_FRONT_CENTER 0x00002000
+#define CH_TOP_FRONT_RIGHT 0x00004000
+#define CH_TOP_BACK_LEFT 0x00008000
+#define CH_TOP_BACK_CENTER 0x00010000
+#define CH_TOP_BACK_RIGHT 0x00020000
+#define CH_STEREO_LEFT 0x20000000 ///< Stereo downmix.
+#define CH_STEREO_RIGHT 0x40000000 ///< See CH_STEREO_LEFT.
+
+/** Channel mask value used for AVCodecContext.request_channel_layout
+ to indicate that the user requests the channel order of the decoder output
+ to be the native codec channel order. */
+#define CH_LAYOUT_NATIVE 0x8000000000000000LL
+
+/* Audio channel convenience macros */
+#define CH_LAYOUT_MONO (CH_FRONT_CENTER)
+#define CH_LAYOUT_STEREO (CH_FRONT_LEFT|CH_FRONT_RIGHT)
+#define CH_LAYOUT_2_1 (CH_LAYOUT_STEREO|CH_BACK_CENTER)
+#define CH_LAYOUT_SURROUND (CH_LAYOUT_STEREO|CH_FRONT_CENTER)
+#define CH_LAYOUT_4POINT0 (CH_LAYOUT_SURROUND|CH_BACK_CENTER)
+#define CH_LAYOUT_2_2 (CH_LAYOUT_STEREO|CH_SIDE_LEFT|CH_SIDE_RIGHT)
+#define CH_LAYOUT_QUAD (CH_LAYOUT_STEREO|CH_BACK_LEFT|CH_BACK_RIGHT)
+#define CH_LAYOUT_5POINT0 (CH_LAYOUT_SURROUND|CH_SIDE_LEFT|CH_SIDE_RIGHT)
+#define CH_LAYOUT_5POINT1 (CH_LAYOUT_5POINT0|CH_LOW_FREQUENCY)
+#define CH_LAYOUT_5POINT0_BACK (CH_LAYOUT_SURROUND|CH_BACK_LEFT|CH_BACK_RIGHT)
+#define CH_LAYOUT_5POINT1_BACK (CH_LAYOUT_5POINT0_BACK|CH_LOW_FREQUENCY)
+#define CH_LAYOUT_7POINT0 (CH_LAYOUT_5POINT0|CH_BACK_LEFT|CH_BACK_RIGHT)
+#define CH_LAYOUT_7POINT1 (CH_LAYOUT_5POINT1|CH_BACK_LEFT|CH_BACK_RIGHT)
+#define CH_LAYOUT_7POINT1_WIDE (CH_LAYOUT_5POINT1_BACK|\
+ CH_FRONT_LEFT_OF_CENTER|CH_FRONT_RIGHT_OF_CENTER)
+#define CH_LAYOUT_STEREO_DOWNMIX (CH_STEREO_LEFT|CH_STEREO_RIGHT)
+
+/* in bytes */
+#define AVCODEC_MAX_AUDIO_FRAME_SIZE 192000 // 1 second of 48khz 32bit audio
+
+/**
+ * Required number of additionally allocated bytes at the end of the input bitstream for decoding.
+ * This is mainly needed because some optimized bitstream readers read
+ * 32 or 64 bit at once and could read over the end.<br>
+ * Note: If the first 23 bits of the additional bytes are not 0, then damaged
+ * MPEG bitstreams could cause overread and segfault.
+ */
+#define FF_INPUT_BUFFER_PADDING_SIZE 8
+
+/**
+ * minimum encoding buffer size
+ * Used to avoid some checks during header writing.
+ */
+#define FF_MIN_BUFFER_SIZE 16384
+
+
+/**
+ * motion estimation type.
+ */
+enum Motion_Est_ID {
+ ME_ZERO = 1, ///< no search, that is use 0,0 vector whenever one is needed
+ ME_FULL,
+ ME_LOG,
+ ME_PHODS,
+ ME_EPZS, ///< enhanced predictive zonal search
+ ME_X1, ///< reserved for experiments
+ ME_HEX, ///< hexagon based search
+ ME_UMH, ///< uneven multi-hexagon search
+ ME_ITER, ///< iterative search
+ ME_TESA, ///< transformed exhaustive search algorithm
+};
+
+enum AVDiscard{
+ /* We leave some space between them for extensions (drop some
+ * keyframes for intra-only or drop just some bidir frames). */
+ AVDISCARD_NONE =-16, ///< discard nothing
+ AVDISCARD_DEFAULT= 0, ///< discard useless packets like 0 size packets in avi
+ AVDISCARD_NONREF = 8, ///< discard all non reference
+ AVDISCARD_BIDIR = 16, ///< discard all bidirectional frames
+ AVDISCARD_NONKEY = 32, ///< discard all frames except keyframes
+ AVDISCARD_ALL = 48, ///< discard all
+};
+
+enum AVColorPrimaries{
+ AVCOL_PRI_BT709 =1, ///< also ITU-R BT1361 / IEC 61966-2-4 / SMPTE RP177 Annex B
+ AVCOL_PRI_UNSPECIFIED=2,
+ AVCOL_PRI_BT470M =4,
+ AVCOL_PRI_BT470BG =5, ///< also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM
+ AVCOL_PRI_SMPTE170M =6, ///< also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC
+ AVCOL_PRI_SMPTE240M =7, ///< functionally identical to above
+ AVCOL_PRI_FILM =8,
+ AVCOL_PRI_NB , ///< Not part of ABI
+};
+
+enum AVColorTransferCharacteristic{
+ AVCOL_TRC_BT709 =1, ///< also ITU-R BT1361
+ AVCOL_TRC_UNSPECIFIED=2,
+ AVCOL_TRC_GAMMA22 =4, ///< also ITU-R BT470M / ITU-R BT1700 625 PAL & SECAM
+ AVCOL_TRC_GAMMA28 =5, ///< also ITU-R BT470BG
+ AVCOL_TRC_NB , ///< Not part of ABI
+};
+
+enum AVColorSpace{
+ AVCOL_SPC_RGB =0,
+ AVCOL_SPC_BT709 =1, ///< also ITU-R BT1361 / IEC 61966-2-4 xvYCC709 / SMPTE RP177 Annex B
+ AVCOL_SPC_UNSPECIFIED=2,
+ AVCOL_SPC_FCC =4,
+ AVCOL_SPC_BT470BG =5, ///< also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM / IEC 61966-2-4 xvYCC601
+ AVCOL_SPC_SMPTE170M =6, ///< also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC / functionally identical to above
+ AVCOL_SPC_SMPTE240M =7,
+ AVCOL_SPC_NB , ///< Not part of ABI
+};
+
+enum AVColorRange{
+ AVCOL_RANGE_UNSPECIFIED=0,
+ AVCOL_RANGE_MPEG =1, ///< the normal 219*2^(n-8) "MPEG" YUV ranges
+ AVCOL_RANGE_JPEG =2, ///< the normal 2^n-1 "JPEG" YUV ranges
+ AVCOL_RANGE_NB , ///< Not part of ABI
+};
+
+/**
+ * X X 3 4 X X are luma samples,
+ * 1 2 1-6 are possible chroma positions
+ * X X 5 6 X 0 is undefined/unknown position
+ */
+enum AVChromaLocation{
+ AVCHROMA_LOC_UNSPECIFIED=0,
+ AVCHROMA_LOC_LEFT =1, ///< mpeg2/4, h264 default
+ AVCHROMA_LOC_CENTER =2, ///< mpeg1, jpeg, h263
+ AVCHROMA_LOC_TOPLEFT =3, ///< DV
+ AVCHROMA_LOC_TOP =4,
+ AVCHROMA_LOC_BOTTOMLEFT =5,
+ AVCHROMA_LOC_BOTTOM =6,
+ AVCHROMA_LOC_NB , ///< Not part of ABI
+};
+
+typedef struct RcOverride{
+ int start_frame;
+ int end_frame;
+ int qscale; // If this is 0 then quality_factor will be used instead.
+ float quality_factor;
+} RcOverride;
+
+#define FF_MAX_B_FRAMES 16
+
+/* encoding support
+ These flags can be passed in AVCodecContext.flags before initialization.
+ Note: Not everything is supported yet.
+*/
+
+#define CODEC_FLAG_QSCALE 0x0002 ///< Use fixed qscale.
+#define CODEC_FLAG_4MV 0x0004 ///< 4 MV per MB allowed / advanced prediction for H.263.
+#define CODEC_FLAG_QPEL 0x0010 ///< Use qpel MC.
+#define CODEC_FLAG_GMC 0x0020 ///< Use GMC.
+#define CODEC_FLAG_MV0 0x0040 ///< Always try a MB with MV=<0,0>.
+#define CODEC_FLAG_PART 0x0080 ///< Use data partitioning.
+/**
+ * The parent program guarantees that the input for B-frames containing
+ * streams is not written to for at least s->max_b_frames+1 frames, if
+ * this is not set the input will be copied.
+ */
+#define CODEC_FLAG_INPUT_PRESERVED 0x0100
+#define CODEC_FLAG_PASS1 0x0200 ///< Use internal 2pass ratecontrol in first pass mode.
+#define CODEC_FLAG_PASS2 0x0400 ///< Use internal 2pass ratecontrol in second pass mode.
+#define CODEC_FLAG_EXTERN_HUFF 0x1000 ///< Use external Huffman table (for MJPEG).
+#define CODEC_FLAG_GRAY 0x2000 ///< Only decode/encode grayscale.
+#define CODEC_FLAG_EMU_EDGE 0x4000 ///< Don't draw edges.
+#define CODEC_FLAG_PSNR 0x8000 ///< error[?] variables will be set during encoding.
+#define CODEC_FLAG_TRUNCATED 0x00010000 /** Input bitstream might be truncated at a random
+ location instead of only at frame boundaries. */
+#define CODEC_FLAG_NORMALIZE_AQP 0x00020000 ///< Normalize adaptive quantization.
+#define CODEC_FLAG_INTERLACED_DCT 0x00040000 ///< Use interlaced DCT.
+#define CODEC_FLAG_LOW_DELAY 0x00080000 ///< Force low delay.
+#define CODEC_FLAG_ALT_SCAN 0x00100000 ///< Use alternate scan.
+#define CODEC_FLAG_GLOBAL_HEADER 0x00400000 ///< Place global headers in extradata instead of every keyframe.
+#define CODEC_FLAG_BITEXACT 0x00800000 ///< Use only bitexact stuff (except (I)DCT).
+/* Fx : Flag for h263+ extra options */
+#define CODEC_FLAG_AC_PRED 0x01000000 ///< H.263 advanced intra coding / MPEG-4 AC prediction
+#define CODEC_FLAG_H263P_UMV 0x02000000 ///< unlimited motion vector
+#define CODEC_FLAG_CBP_RD 0x04000000 ///< Use rate distortion optimization for cbp.
+#define CODEC_FLAG_QP_RD 0x08000000 ///< Use rate distortion optimization for qp selectioon.
+#define CODEC_FLAG_H263P_AIV 0x00000008 ///< H.263 alternative inter VLC
+#define CODEC_FLAG_OBMC 0x00000001 ///< OBMC
+#define CODEC_FLAG_LOOP_FILTER 0x00000800 ///< loop filter
+#define CODEC_FLAG_H263P_SLICE_STRUCT 0x10000000
+#define CODEC_FLAG_INTERLACED_ME 0x20000000 ///< interlaced motion estimation
+#define CODEC_FLAG_SVCD_SCAN_OFFSET 0x40000000 ///< Will reserve space for SVCD scan offset user data.
+#define CODEC_FLAG_CLOSED_GOP 0x80000000
+#define CODEC_FLAG2_FAST 0x00000001 ///< Allow non spec compliant speedup tricks.
+#define CODEC_FLAG2_STRICT_GOP 0x00000002 ///< Strictly enforce GOP size.
+#define CODEC_FLAG2_NO_OUTPUT 0x00000004 ///< Skip bitstream encoding.
+#define CODEC_FLAG2_LOCAL_HEADER 0x00000008 ///< Place global headers at every keyframe instead of in extradata.
+#define CODEC_FLAG2_BPYRAMID 0x00000010 ///< H.264 allow B-frames to be used as references.
+#define CODEC_FLAG2_WPRED 0x00000020 ///< H.264 weighted biprediction for B-frames
+#define CODEC_FLAG2_MIXED_REFS 0x00000040 ///< H.264 one reference per partition, as opposed to one reference per macroblock
+#define CODEC_FLAG2_8X8DCT 0x00000080 ///< H.264 high profile 8x8 transform
+#define CODEC_FLAG2_FASTPSKIP 0x00000100 ///< H.264 fast pskip
+#define CODEC_FLAG2_AUD 0x00000200 ///< H.264 access unit delimiters
+#define CODEC_FLAG2_BRDO 0x00000400 ///< B-frame rate-distortion optimization
+#define CODEC_FLAG2_INTRA_VLC 0x00000800 ///< Use MPEG-2 intra VLC table.
+#define CODEC_FLAG2_MEMC_ONLY 0x00001000 ///< Only do ME/MC (I frames -> ref, P frame -> ME+MC).
+#define CODEC_FLAG2_DROP_FRAME_TIMECODE 0x00002000 ///< timecode is in drop frame format.
+#define CODEC_FLAG2_SKIP_RD 0x00004000 ///< RD optimal MB level residual skipping
+#define CODEC_FLAG2_CHUNKS 0x00008000 ///< Input bitstream might be truncated at a packet boundaries instead of only at frame boundaries.
+#define CODEC_FLAG2_NON_LINEAR_QUANT 0x00010000 ///< Use MPEG-2 nonlinear quantizer.
+#define CODEC_FLAG2_BIT_RESERVOIR 0x00020000 ///< Use a bit reservoir when encoding if possible
+#define CODEC_FLAG2_MBTREE 0x00040000 ///< Use macroblock tree ratecontrol (x264 only)
+#define CODEC_FLAG2_PSY 0x00080000 ///< Use psycho visual optimizations.
+#define CODEC_FLAG2_SSIM 0x00100000 ///< Compute SSIM during encoding, error[] values are undefined.
+
+/* Unsupported options :
+ * Syntax Arithmetic coding (SAC)
+ * Reference Picture Selection
+ * Independent Segment Decoding */
+/* /Fx */
+/* codec capabilities */
+
+#define CODEC_CAP_DRAW_HORIZ_BAND 0x0001 ///< Decoder can use draw_horiz_band callback.
+/**
+ * Codec uses get_buffer() for allocating buffers and supports custom allocators.
+ * If not set, it might not use get_buffer() at all or use operations that
+ * assume the buffer was allocated by avcodec_default_get_buffer.
+ */
+#define CODEC_CAP_DR1 0x0002
+/* If 'parse_only' field is true, then avcodec_parse_frame() can be used. */
+#define CODEC_CAP_PARSE_ONLY 0x0004
+#define CODEC_CAP_TRUNCATED 0x0008
+/* Codec can export data for HW decoding (XvMC). */
+#define CODEC_CAP_HWACCEL 0x0010
+/**
+ * Codec has a nonzero delay and needs to be fed with NULL at the end to get the delayed data.
+ * If this is not set, the codec is guaranteed to never be fed with NULL data.
+ */
+#define CODEC_CAP_DELAY 0x0020
+/**
+ * Codec can be fed a final frame with a smaller size.
+ * This can be used to prevent truncation of the last audio samples.
+ */
+#define CODEC_CAP_SMALL_LAST_FRAME 0x0040
+/**
+ * Codec can export data for HW decoding (VDPAU).
+ */
+#define CODEC_CAP_HWACCEL_VDPAU 0x0080
+/**
+ * Codec can output multiple frames per AVPacket
+ * Normally demuxers return one frame at a time, demuxers which do not do
+ * are connected to a parser to split what they return into proper frames.
+ * This flag is reserved to the very rare category of codecs which have a
+ * bitstream that cannot be split into frames without timeconsuming
+ * operations like full decoding. Demuxers carring such bitstreams thus
+ * may return multiple frames in a packet. This has many disadvantages like
+ * prohibiting stream copy in many cases thus it should only be considered
+ * as a last resort.
+ */
+#define CODEC_CAP_SUBFRAMES 0x0100
+/**
+ * Codec is experimental and is thus avoided in favor of non experimental
+ * encoders
+ */
+#define CODEC_CAP_EXPERIMENTAL 0x0200
+
+//The following defines may change, don't expect compatibility if you use them.
+#define MB_TYPE_INTRA4x4 0x0001
+#define MB_TYPE_INTRA16x16 0x0002 //FIXME H.264-specific
+#define MB_TYPE_INTRA_PCM 0x0004 //FIXME H.264-specific
+#define MB_TYPE_16x16 0x0008
+#define MB_TYPE_16x8 0x0010
+#define MB_TYPE_8x16 0x0020
+#define MB_TYPE_8x8 0x0040
+#define MB_TYPE_INTERLACED 0x0080
+#define MB_TYPE_DIRECT2 0x0100 //FIXME
+#define MB_TYPE_ACPRED 0x0200
+#define MB_TYPE_GMC 0x0400
+#define MB_TYPE_SKIP 0x0800
+#define MB_TYPE_P0L0 0x1000
+#define MB_TYPE_P1L0 0x2000
+#define MB_TYPE_P0L1 0x4000
+#define MB_TYPE_P1L1 0x8000
+#define MB_TYPE_L0 (MB_TYPE_P0L0 | MB_TYPE_P1L0)
+#define MB_TYPE_L1 (MB_TYPE_P0L1 | MB_TYPE_P1L1)
+#define MB_TYPE_L0L1 (MB_TYPE_L0 | MB_TYPE_L1)
+#define MB_TYPE_QUANT 0x00010000
+#define MB_TYPE_CBP 0x00020000
+//Note bits 24-31 are reserved for codec specific use (h264 ref0, mpeg1 0mv, ...)
+
+/**
+ * Pan Scan area.
+ * This specifies the area which should be displayed.
+ * Note there may be multiple such areas for one frame.
+ */
+typedef struct AVPanScan{
+ /**
+ * id
+ * - encoding: Set by user.
+ * - decoding: Set by libavcodec.
+ */
+ int id;
+
+ /**
+ * width and height in 1/16 pel
+ * - encoding: Set by user.
+ * - decoding: Set by libavcodec.
+ */
+ int width;
+ int height;
+
+ /**
+ * position of the top left corner in 1/16 pel for up to 3 fields/frames
+ * - encoding: Set by user.
+ * - decoding: Set by libavcodec.
+ */
+ int16_t position[3][2];
+}AVPanScan;
+
+#define FF_COMMON_FRAME \
+ /**\
+ * pointer to the picture planes.\
+ * This might be different from the first allocated byte\
+ * - encoding: \
+ * - decoding: \
+ */\
+ uint8_t *data[4];\
+ int linesize[4];\
+ /**\
+ * pointer to the first allocated byte of the picture. Can be used in get_buffer/release_buffer.\
+ * This isn't used by libavcodec unless the default get/release_buffer() is used.\
+ * - encoding: \
+ * - decoding: \
+ */\
+ uint8_t *base[4];\
+ /**\
+ * 1 -> keyframe, 0-> not\
+ * - encoding: Set by libavcodec.\
+ * - decoding: Set by libavcodec.\
+ */\
+ int key_frame;\
+\
+ /**\
+ * Picture type of the frame, see ?_TYPE below.\
+ * - encoding: Set by libavcodec. for coded_picture (and set by user for input).\
+ * - decoding: Set by libavcodec.\
+ */\
+ int pict_type;\
+\
+ /**\
+ * presentation timestamp in time_base units (time when frame should be shown to user)\
+ * If AV_NOPTS_VALUE then frame_rate = 1/time_base will be assumed.\
+ * - encoding: MUST be set by user.\
+ * - decoding: Set by libavcodec.\
+ */\
+ int64_t pts;\
+\
+ /**\
+ * picture number in bitstream order\
+ * - encoding: set by\
+ * - decoding: Set by libavcodec.\
+ */\
+ int coded_picture_number;\
+ /**\
+ * picture number in display order\
+ * - encoding: set by\
+ * - decoding: Set by libavcodec.\
+ */\
+ int display_picture_number;\
+\
+ /**\
+ * quality (between 1 (good) and FF_LAMBDA_MAX (bad)) \
+ * - encoding: Set by libavcodec. for coded_picture (and set by user for input).\
+ * - decoding: Set by libavcodec.\
+ */\
+ int quality; \
+\
+ /**\
+ * buffer age (1->was last buffer and dint change, 2->..., ...).\
+ * Set to INT_MAX if the buffer has not been used yet.\
+ * - encoding: unused\
+ * - decoding: MUST be set by get_buffer().\
+ */\
+ int age;\
+\
+ /**\
+ * is this picture used as reference\
+ * The values for this are the same as the MpegEncContext.picture_structure\
+ * variable, that is 1->top field, 2->bottom field, 3->frame/both fields.\
+ * Set to 4 for delayed, non-reference frames.\
+ * - encoding: unused\
+ * - decoding: Set by libavcodec. (before get_buffer() call)).\
+ */\
+ int reference;\
+\
+ /**\
+ * QP table\
+ * - encoding: unused\
+ * - decoding: Set by libavcodec.\
+ */\
+ int8_t *qscale_table;\
+ /**\
+ * QP store stride\
+ * - encoding: unused\
+ * - decoding: Set by libavcodec.\
+ */\
+ int qstride;\
+\
+ /**\
+ * mbskip_table[mb]>=1 if MB didn't change\
+ * stride= mb_width = (width+15)>>4\
+ * - encoding: unused\
+ * - decoding: Set by libavcodec.\
+ */\
+ uint8_t *mbskip_table;\
+\
+ /**\
+ * motion vector table\
+ * @code\
+ * example:\
+ * int mv_sample_log2= 4 - motion_subsample_log2;\
+ * int mb_width= (width+15)>>4;\
+ * int mv_stride= (mb_width << mv_sample_log2) + 1;\
+ * motion_val[direction][x + y*mv_stride][0->mv_x, 1->mv_y];\
+ * @endcode\
+ * - encoding: Set by user.\
+ * - decoding: Set by libavcodec.\
+ */\
+ int16_t (*motion_val[2])[2];\
+\
+ /**\
+ * macroblock type table\
+ * mb_type_base + mb_width + 2\
+ * - encoding: Set by user.\
+ * - decoding: Set by libavcodec.\
+ */\
+ uint32_t *mb_type;\
+\
+ /**\
+ * log2 of the size of the block which a single vector in motion_val represents: \
+ * (4->16x16, 3->8x8, 2-> 4x4, 1-> 2x2)\
+ * - encoding: unused\
+ * - decoding: Set by libavcodec.\
+ */\
+ uint8_t motion_subsample_log2;\
+\
+ /**\
+ * for some private data of the user\
+ * - encoding: unused\
+ * - decoding: Set by user.\
+ */\
+ void *opaque;\
+\
+ /**\
+ * error\
+ * - encoding: Set by libavcodec. if flags&CODEC_FLAG_PSNR.\
+ * - decoding: unused\
+ */\
+ uint64_t error[4];\
+\
+ /**\
+ * type of the buffer (to keep track of who has to deallocate data[*])\
+ * - encoding: Set by the one who allocates it.\
+ * - decoding: Set by the one who allocates it.\
+ * Note: User allocated (direct rendering) & internal buffers cannot coexist currently.\
+ */\
+ int type;\
+ \
+ /**\
+ * When decoding, this signals how much the picture must be delayed.\
+ * extra_delay = repeat_pict / (2*fps)\
+ * - encoding: unused\
+ * - decoding: Set by libavcodec.\
+ */\
+ int repeat_pict;\
+ \
+ /**\
+ * \
+ */\
+ int qscale_type;\
+ \
+ /**\
+ * The content of the picture is interlaced.\
+ * - encoding: Set by user.\
+ * - decoding: Set by libavcodec. (default 0)\
+ */\
+ int interlaced_frame;\
+ \
+ /**\
+ * If the content is interlaced, is top field displayed first.\
+ * - encoding: Set by user.\
+ * - decoding: Set by libavcodec.\
+ */\
+ int top_field_first;\
+ \
+ /**\
+ * Pan scan.\
+ * - encoding: Set by user.\
+ * - decoding: Set by libavcodec.\
+ */\
+ AVPanScan *pan_scan;\
+ \
+ /**\
+ * Tell user application that palette has changed from previous frame.\
+ * - encoding: ??? (no palette-enabled encoder yet)\
+ * - decoding: Set by libavcodec. (default 0).\
+ */\
+ int palette_has_changed;\
+ \
+ /**\
+ * codec suggestion on buffer type if != 0\
+ * - encoding: unused\
+ * - decoding: Set by libavcodec. (before get_buffer() call)).\
+ */\
+ int buffer_hints;\
+\
+ /**\
+ * DCT coefficients\
+ * - encoding: unused\
+ * - decoding: Set by libavcodec.\
+ */\
+ short *dct_coeff;\
+\
+ /**\
+ * motion reference frame index\
+ * the order in which these are stored can depend on the codec.\
+ * - encoding: Set by user.\
+ * - decoding: Set by libavcodec.\
+ */\
+ int8_t *ref_index[2];\
+\
+ /**\
+ * reordered opaque 64bit number (generally a PTS) from AVCodecContext.reordered_opaque\
+ * output in AVFrame.reordered_opaque\
+ * - encoding: unused\
+ * - decoding: Read by user.\
+ */\
+ int64_t reordered_opaque;\
+\
+ /**\
+ * hardware accelerator private data (FFmpeg allocated)\
+ * - encoding: unused\
+ * - decoding: Set by libavcodec\
+ */\
+ void *hwaccel_picture_private;\
+
+
+#define FF_QSCALE_TYPE_MPEG1 0
+#define FF_QSCALE_TYPE_MPEG2 1
+#define FF_QSCALE_TYPE_H264 2
+#define FF_QSCALE_TYPE_VP56 3
+
+#define FF_BUFFER_TYPE_INTERNAL 1
+#define FF_BUFFER_TYPE_USER 2 ///< direct rendering buffers (image is (de)allocated by user)
+#define FF_BUFFER_TYPE_SHARED 4 ///< Buffer from somewhere else; don't deallocate image (data/base), all other tables are not shared.
+#define FF_BUFFER_TYPE_COPY 8 ///< Just a (modified) copy of some other buffer, don't deallocate anything.
+
+
+#define FF_I_TYPE 1 ///< Intra
+#define FF_P_TYPE 2 ///< Predicted
+#define FF_B_TYPE 3 ///< Bi-dir predicted
+#define FF_S_TYPE 4 ///< S(GMC)-VOP MPEG4
+#define FF_SI_TYPE 5 ///< Switching Intra
+#define FF_SP_TYPE 6 ///< Switching Predicted
+#define FF_BI_TYPE 7
+
+#define FF_BUFFER_HINTS_VALID 0x01 // Buffer hints value is meaningful (if 0 ignore).
+#define FF_BUFFER_HINTS_READABLE 0x02 // Codec will read from buffer.
+#define FF_BUFFER_HINTS_PRESERVE 0x04 // User must not alter buffer content.
+#define FF_BUFFER_HINTS_REUSABLE 0x08 // Codec will reuse the buffer (update).
+
+typedef struct AVPacket {
+ /**
+ * Presentation timestamp in AVStream->time_base units; the time at which
+ * the decompressed packet will be presented to the user.
+ * Can be AV_NOPTS_VALUE if it is not stored in the file.
+ * pts MUST be larger or equal to dts as presentation cannot happen before
+ * decompression, unless one wants to view hex dumps. Some formats misuse
+ * the terms dts and pts/cts to mean something different. Such timestamps
+ * must be converted to true pts/dts before they are stored in AVPacket.
+ */
+ int64_t pts;
+ /**
+ * Decompression timestamp in AVStream->time_base units; the time at which
+ * the packet is decompressed.
+ * Can be AV_NOPTS_VALUE if it is not stored in the file.
+ */
+ int64_t dts;
+ uint8_t *data;
+ int size;
+ int stream_index;
+ int flags;
+ /**
+ * Duration of this packet in AVStream->time_base units, 0 if unknown.
+ * Equals next_pts - this_pts in presentation order.
+ */
+ int duration;
+ void (*destruct)(struct AVPacket *);
+ void *priv;
+ int64_t pos; ///< byte position in stream, -1 if unknown
+
+ /**
+ * Time difference in AVStream->time_base units from the pts of this
+ * packet to the point at which the output from the decoder has converged
+ * independent from the availability of previous frames. That is, the
+ * frames are virtually identical no matter if decoding started from
+ * the very first frame or from this keyframe.
+ * Is AV_NOPTS_VALUE if unknown.
+ * This field is not the display duration of the current packet.
+ *
+ * The purpose of this field is to allow seeking in streams that have no
+ * keyframes in the conventional sense. It corresponds to the
+ * recovery point SEI in H.264 and match_time_delta in NUT. It is also
+ * essential for some types of subtitle streams to ensure that all
+ * subtitles are correctly displayed after seeking.
+ */
+ int64_t convergence_duration;
+} AVPacket;
+#define AV_PKT_FLAG_KEY 0x0001
+#if LIBAVCODEC_VERSION_MAJOR < 53
+#define PKT_FLAG_KEY AV_PKT_FLAG_KEY
+#endif
+
+/**
+ * Audio Video Frame.
+ * New fields can be added to the end of FF_COMMON_FRAME with minor version
+ * bumps.
+ * Removal, reordering and changes to existing fields require a major
+ * version bump. No fields should be added into AVFrame before or after
+ * FF_COMMON_FRAME!
+ * sizeof(AVFrame) must not be used outside libav*.
+ */
+typedef struct AVFrame {
+ FF_COMMON_FRAME
+} AVFrame;
+
+/**
+ * main external API structure.
+ * New fields can be added to the end with minor version bumps.
+ * Removal, reordering and changes to existing fields require a major
+ * version bump.
+ * sizeof(AVCodecContext) must not be used outside libav*.
+ */
+typedef struct AVCodecContext {
+ /**
+ * information on struct for av_log
+ * - set by avcodec_alloc_context
+ */
+ const AVClass *av_class;
+ /**
+ * the average bitrate
+ * - encoding: Set by user; unused for constant quantizer encoding.
+ * - decoding: Set by libavcodec. 0 or some bitrate if this info is available in the stream.
+ */
+ int bit_rate;
+
+ /**
+ * number of bits the bitstream is allowed to diverge from the reference.
+ * the reference can be CBR (for CBR pass1) or VBR (for pass2)
+ * - encoding: Set by user; unused for constant quantizer encoding.
+ * - decoding: unused
+ */
+ int bit_rate_tolerance;
+
+ /**
+ * CODEC_FLAG_*.
+ * - encoding: Set by user.
+ * - decoding: Set by user.
+ */
+ int flags;
+
+ /**
+ * Some codecs need additional format info. It is stored here.
+ * If any muxer uses this then ALL demuxers/parsers AND encoders for the
+ * specific codec MUST set it correctly otherwise stream copy breaks.
+ * In general use of this field by muxers is not recommanded.
+ * - encoding: Set by libavcodec.
+ * - decoding: Set by libavcodec. (FIXME: Is this OK?)
+ */
+ int sub_id;
+
+ /**
+ * Motion estimation algorithm used for video coding.
+ * 1 (zero), 2 (full), 3 (log), 4 (phods), 5 (epzs), 6 (x1), 7 (hex),
+ * 8 (umh), 9 (iter), 10 (tesa) [7, 8, 10 are x264 specific, 9 is snow specific]
+ * - encoding: MUST be set by user.
+ * - decoding: unused
+ */
+ int me_method;
+
+ /**
+ * some codecs need / can use extradata like Huffman tables.
+ * mjpeg: Huffman tables
+ * rv10: additional flags
+ * mpeg4: global headers (they can be in the bitstream or here)
+ * The allocated memory should be FF_INPUT_BUFFER_PADDING_SIZE bytes larger
+ * than extradata_size to avoid prolems if it is read with the bitstream reader.
+ * The bytewise contents of extradata must not depend on the architecture or CPU endianness.
+ * - encoding: Set/allocated/freed by libavcodec.
+ * - decoding: Set/allocated/freed by user.
+ */
+ uint8_t *extradata;
+ int extradata_size;
+
+ /**
+ * This is the fundamental unit of time (in seconds) in terms
+ * of which frame timestamps are represented. For fixed-fps content,
+ * timebase should be 1/framerate and timestamp increments should be
+ * identically 1.
+ * - encoding: MUST be set by user.
+ * - decoding: Set by libavcodec.
+ */
+ AVRational time_base;
+
+ /* video only */
+ /**
+ * picture width / height.
+ * - encoding: MUST be set by user.
+ * - decoding: Set by libavcodec.
+ * Note: For compatibility it is possible to set this instead of
+ * coded_width/height before decoding.
+ */
+ int width, height;
+
+#define FF_ASPECT_EXTENDED 15
+
+ /**
+ * the number of pictures in a group of pictures, or 0 for intra_only
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int gop_size;
+
+ /**
+ * Pixel format, see PIX_FMT_xxx.
+ * - encoding: Set by user.
+ * - decoding: Set by libavcodec.
+ */
+ enum PixelFormat pix_fmt;
+
+ /**
+ * Frame rate emulation. If not zero, the lower layer (i.e. format handler)
+ * has to read frames at native frame rate.
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int rate_emu;
+
+ /**
+ * If non NULL, 'draw_horiz_band' is called by the libavcodec
+ * decoder to draw a horizontal band. It improves cache usage. Not
+ * all codecs can do that. You must check the codec capabilities
+ * beforehand.
+ * The function is also used by hardware acceleration APIs.
+ * It is called at least once during frame decoding to pass
+ * the data needed for hardware render.
+ * In that mode instead of pixel data, AVFrame points to
+ * a structure specific to the acceleration API. The application
+ * reads the structure and can change some fields to indicate progress
+ * or mark state.
+ * - encoding: unused
+ * - decoding: Set by user.
+ * @param height the height of the slice
+ * @param y the y position of the slice
+ * @param type 1->top field, 2->bottom field, 3->frame
+ * @param offset offset into the AVFrame.data from which the slice should be read
+ */
+ void (*draw_horiz_band)(struct AVCodecContext *s,
+ const AVFrame *src, int offset[4],
+ int y, int type, int height);
+
+ /* audio only */
+ int sample_rate; ///< samples per second
+ int channels; ///< number of audio channels
+
+ /**
+ * audio sample format
+ * - encoding: Set by user.
+ * - decoding: Set by libavcodec.
+ */
+ enum SampleFormat sample_fmt; ///< sample format
+
+ /* The following data should not be initialized. */
+ /**
+ * Samples per packet, initialized when calling 'init'.
+ */
+ int frame_size;
+ int frame_number; ///< audio or video frame number
+#if LIBAVCODEC_VERSION_MAJOR < 53
+ int real_pict_num; ///< Returns the real picture number of previous encoded frame.
+#endif
+
+ /**
+ * Number of frames the decoded output will be delayed relative to
+ * the encoded input.
+ * - encoding: Set by libavcodec.
+ * - decoding: unused
+ */
+ int delay;
+
+ /* - encoding parameters */
+ float qcompress; ///< amount of qscale change between easy & hard scenes (0.0-1.0)
+ float qblur; ///< amount of qscale smoothing over time (0.0-1.0)
+
+ /**
+ * minimum quantizer
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int qmin;
+
+ /**
+ * maximum quantizer
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int qmax;
+
+ /**
+ * maximum quantizer difference between frames
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int max_qdiff;
+
+ /**
+ * maximum number of B-frames between non-B-frames
+ * Note: The output will be delayed by max_b_frames+1 relative to the input.
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int max_b_frames;
+
+ /**
+ * qscale factor between IP and B-frames
+ * If > 0 then the last P-frame quantizer will be used (q= lastp_q*factor+offset).
+ * If < 0 then normal ratecontrol will be done (q= -normal_q*factor+offset).
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ float b_quant_factor;
+
+ /** obsolete FIXME remove */
+ int rc_strategy;
+#define FF_RC_STRATEGY_XVID 1
+
+ int b_frame_strategy;
+
+ /**
+ * hurry up amount
+ * - encoding: unused
+ * - decoding: Set by user. 1-> Skip B-frames, 2-> Skip IDCT/dequant too, 5-> Skip everything except header
+ * @deprecated Deprecated in favor of skip_idct and skip_frame.
+ */
+ int hurry_up;
+
+ struct AVCodec *codec;
+
+ void *priv_data;
+
+ int rtp_payload_size; /* The size of the RTP payload: the coder will */
+ /* do its best to deliver a chunk with size */
+ /* below rtp_payload_size, the chunk will start */
+ /* with a start code on some codecs like H.263. */
+ /* This doesn't take account of any particular */
+ /* headers inside the transmitted RTP payload. */
+
+
+ /* The RTP callback: This function is called */
+ /* every time the encoder has a packet to send. */
+ /* It depends on the encoder if the data starts */
+ /* with a Start Code (it should). H.263 does. */
+ /* mb_nb contains the number of macroblocks */
+ /* encoded in the RTP payload. */
+ void (*rtp_callback)(struct AVCodecContext *avctx, void *data, int size, int mb_nb);
+
+ /* statistics, used for 2-pass encoding */
+ int mv_bits;
+ int header_bits;
+ int i_tex_bits;
+ int p_tex_bits;
+ int i_count;
+ int p_count;
+ int skip_count;
+ int misc_bits;
+
+ /**
+ * number of bits used for the previously encoded frame
+ * - encoding: Set by libavcodec.
+ * - decoding: unused
+ */
+ int frame_bits;
+
+ /**
+ * Private data of the user, can be used to carry app specific stuff.
+ * - encoding: Set by user.
+ * - decoding: Set by user.
+ */
+ void *opaque;
+
+ char codec_name[32];
+ enum AVMediaType codec_type; /* see AVMEDIA_TYPE_xxx */
+ enum CodecID codec_id; /* see CODEC_ID_xxx */
+
+ /**
+ * fourcc (LSB first, so "ABCD" -> ('D'<<24) + ('C'<<16) + ('B'<<8) + 'A').
+ * This is used to work around some encoder bugs.
+ * A demuxer should set this to what is stored in the field used to identify the codec.
+ * If there are multiple such fields in a container then the demuxer should choose the one
+ * which maximizes the information about the used codec.
+ * If the codec tag field in a container is larger then 32 bits then the demuxer should
+ * remap the longer ID to 32 bits with a table or other structure. Alternatively a new
+ * extra_codec_tag + size could be added but for this a clear advantage must be demonstrated
+ * first.
+ * - encoding: Set by user, if not then the default based on codec_id will be used.
+ * - decoding: Set by user, will be converted to uppercase by libavcodec during init.
+ */
+ unsigned int codec_tag;
+
+ /**
+ * Work around bugs in encoders which sometimes cannot be detected automatically.
+ * - encoding: Set by user
+ * - decoding: Set by user
+ */
+ int workaround_bugs;
+#define FF_BUG_AUTODETECT 1 ///< autodetection
+#define FF_BUG_OLD_MSMPEG4 2
+#define FF_BUG_XVID_ILACE 4
+#define FF_BUG_UMP4 8
+#define FF_BUG_NO_PADDING 16
+#define FF_BUG_AMV 32
+#define FF_BUG_AC_VLC 0 ///< Will be removed, libavcodec can now handle these non-compliant files by default.
+#define FF_BUG_QPEL_CHROMA 64
+#define FF_BUG_STD_QPEL 128
+#define FF_BUG_QPEL_CHROMA2 256
+#define FF_BUG_DIRECT_BLOCKSIZE 512
+#define FF_BUG_EDGE 1024
+#define FF_BUG_HPEL_CHROMA 2048
+#define FF_BUG_DC_CLIP 4096
+#define FF_BUG_MS 8192 ///< Work around various bugs in Microsoft's broken decoders.
+#define FF_BUG_TRUNCATED 16384
+//#define FF_BUG_FAKE_SCALABILITY 16 //Autodetection should work 100%.
+
+ /**
+ * luma single coefficient elimination threshold
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int luma_elim_threshold;
+
+ /**
+ * chroma single coeff elimination threshold
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int chroma_elim_threshold;
+
+ /**
+ * strictly follow the standard (MPEG4, ...).
+ * - encoding: Set by user.
+ * - decoding: Set by user.
+ * Setting this to STRICT or higher means the encoder and decoder will
+ * generally do stupid things. While setting it to inofficial or lower
+ * will mean the encoder might use things that are not supported by all
+ * spec compliant decoders. Decoders make no difference between normal,
+ * inofficial and experimental, that is they always try to decode things
+ * when they can unless they are explicitly asked to behave stupid
+ * (=strictly conform to the specs)
+ */
+ int strict_std_compliance;
+#define FF_COMPLIANCE_VERY_STRICT 2 ///< Strictly conform to a older more strict version of the spec or reference software.
+#define FF_COMPLIANCE_STRICT 1 ///< Strictly conform to all the things in the spec no matter what consequences.
+#define FF_COMPLIANCE_NORMAL 0
+#define FF_COMPLIANCE_INOFFICIAL -1 ///< Allow inofficial extensions.
+#define FF_COMPLIANCE_EXPERIMENTAL -2 ///< Allow nonstandardized experimental things.
+
+ /**
+ * qscale offset between IP and B-frames
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ float b_quant_offset;
+
+ /**
+ * Error recognization; higher values will detect more errors but may
+ * misdetect some more or less valid parts as errors.
+ * - encoding: unused
+ * - decoding: Set by user.
+ */
+ int error_recognition;
+#define FF_ER_CAREFUL 1
+#define FF_ER_COMPLIANT 2
+#define FF_ER_AGGRESSIVE 3
+#define FF_ER_VERY_AGGRESSIVE 4
+
+ /**
+ * Called at the beginning of each frame to get a buffer for it.
+ * If pic.reference is set then the frame will be read later by libavcodec.
+ * avcodec_align_dimensions2() should be used to find the required width and
+ * height, as they normally need to be rounded up to the next multiple of 16.
+ * if CODEC_CAP_DR1 is not set then get_buffer() must call
+ * avcodec_default_get_buffer() instead of providing buffers allocated by
+ * some other means.
+ * - encoding: unused
+ * - decoding: Set by libavcodec., user can override.
+ */
+ int (*get_buffer)(struct AVCodecContext *c, AVFrame *pic);
+
+ /**
+ * Called to release buffers which were allocated with get_buffer.
+ * A released buffer can be reused in get_buffer().
+ * pic.data[*] must be set to NULL.
+ * - encoding: unused
+ * - decoding: Set by libavcodec., user can override.
+ */
+ void (*release_buffer)(struct AVCodecContext *c, AVFrame *pic);
+
+ /**
+ * Size of the frame reordering buffer in the decoder.
+ * For MPEG-2 it is 1 IPB or 0 low delay IP.
+ * - encoding: Set by libavcodec.
+ * - decoding: Set by libavcodec.
+ */
+ int has_b_frames;
+
+ /**
+ * number of bytes per packet if constant and known or 0
+ * Used by some WAV based audio codecs.
+ */
+ int block_align;
+
+ int parse_only; /* - decoding only: If true, only parsing is done
+ (function avcodec_parse_frame()). The frame
+ data is returned. Only MPEG codecs support this now. */
+
+ /**
+ * 0-> h263 quant 1-> mpeg quant
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int mpeg_quant;
+
+ /**
+ * pass1 encoding statistics output buffer
+ * - encoding: Set by libavcodec.
+ * - decoding: unused
+ */
+ char *stats_out;
+
+ /**
+ * pass2 encoding statistics input buffer
+ * Concatenated stuff from stats_out of pass1 should be placed here.
+ * - encoding: Allocated/set/freed by user.
+ * - decoding: unused
+ */
+ char *stats_in;
+
+ /**
+ * ratecontrol qmin qmax limiting method
+ * 0-> clipping, 1-> use a nice continous function to limit qscale wthin qmin/qmax.
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ float rc_qsquish;
+
+ float rc_qmod_amp;
+ int rc_qmod_freq;
+
+ /**
+ * ratecontrol override, see RcOverride
+ * - encoding: Allocated/set/freed by user.
+ * - decoding: unused
+ */
+ RcOverride *rc_override;
+ int rc_override_count;
+
+ /**
+ * rate control equation
+ * - encoding: Set by user
+ * - decoding: unused
+ */
+ const char *rc_eq;
+
+ /**
+ * maximum bitrate
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int rc_max_rate;
+
+ /**
+ * minimum bitrate
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int rc_min_rate;
+
+ /**
+ * decoder bitstream buffer size
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int rc_buffer_size;
+ float rc_buffer_aggressivity;
+
+ /**
+ * qscale factor between P and I-frames
+ * If > 0 then the last p frame quantizer will be used (q= lastp_q*factor+offset).
+ * If < 0 then normal ratecontrol will be done (q= -normal_q*factor+offset).
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ float i_quant_factor;
+
+ /**
+ * qscale offset between P and I-frames
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ float i_quant_offset;
+
+ /**
+ * initial complexity for pass1 ratecontrol
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ float rc_initial_cplx;
+
+ /**
+ * DCT algorithm, see FF_DCT_* below
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int dct_algo;
+#define FF_DCT_AUTO 0
+#define FF_DCT_FASTINT 1
+#define FF_DCT_INT 2
+#define FF_DCT_MMX 3
+#define FF_DCT_MLIB 4
+#define FF_DCT_ALTIVEC 5
+#define FF_DCT_FAAN 6
+
+ /**
+ * luminance masking (0-> disabled)
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ float lumi_masking;
+
+ /**
+ * temporary complexity masking (0-> disabled)
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ float temporal_cplx_masking;
+
+ /**
+ * spatial complexity masking (0-> disabled)
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ float spatial_cplx_masking;
+
+ /**
+ * p block masking (0-> disabled)
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ float p_masking;
+
+ /**
+ * darkness masking (0-> disabled)
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ float dark_masking;
+
+ /**
+ * IDCT algorithm, see FF_IDCT_* below.
+ * - encoding: Set by user.
+ * - decoding: Set by user.
+ */
+ int idct_algo;
+#define FF_IDCT_AUTO 0
+#define FF_IDCT_INT 1
+#define FF_IDCT_SIMPLE 2
+#define FF_IDCT_SIMPLEMMX 3
+#define FF_IDCT_LIBMPEG2MMX 4
+#define FF_IDCT_PS2 5
+#define FF_IDCT_MLIB 6
+#define FF_IDCT_ARM 7
+#define FF_IDCT_ALTIVEC 8
+#define FF_IDCT_SH4 9
+#define FF_IDCT_SIMPLEARM 10
+#define FF_IDCT_H264 11
+#define FF_IDCT_VP3 12
+#define FF_IDCT_IPP 13
+#define FF_IDCT_XVIDMMX 14
+#define FF_IDCT_CAVS 15
+#define FF_IDCT_SIMPLEARMV5TE 16
+#define FF_IDCT_SIMPLEARMV6 17
+#define FF_IDCT_SIMPLEVIS 18
+#define FF_IDCT_WMV2 19
+#define FF_IDCT_FAAN 20
+#define FF_IDCT_EA 21
+#define FF_IDCT_SIMPLENEON 22
+#define FF_IDCT_SIMPLEALPHA 23
+#define FF_IDCT_BINK 24
+
+ /**
+ * slice count
+ * - encoding: Set by libavcodec.
+ * - decoding: Set by user (or 0).
+ */
+ int slice_count;
+ /**
+ * slice offsets in the frame in bytes
+ * - encoding: Set/allocated by libavcodec.
+ * - decoding: Set/allocated by user (or NULL).
+ */
+ int *slice_offset;
+
+ /**
+ * error concealment flags
+ * - encoding: unused
+ * - decoding: Set by user.
+ */
+ int error_concealment;
+#define FF_EC_GUESS_MVS 1
+#define FF_EC_DEBLOCK 2
+
+ /**
+ * dsp_mask could be add used to disable unwanted CPU features
+ * CPU features (i.e. MMX, SSE. ...)
+ *
+ * With the FORCE flag you may instead enable given CPU features.
+ * (Dangerous: Usable in case of misdetection, improper usage however will
+ * result into program crash.)
+ */
+ unsigned dsp_mask;
+#define FF_MM_FORCE 0x80000000 /* Force usage of selected flags (OR) */
+ /* lower 16 bits - CPU features */
+#define FF_MM_MMX 0x0001 ///< standard MMX
+#define FF_MM_3DNOW 0x0004 ///< AMD 3DNOW
+#if LIBAVCODEC_VERSION_MAJOR < 53
+#define FF_MM_MMXEXT 0x0002 ///< SSE integer functions or AMD MMX ext
+#endif
+#define FF_MM_MMX2 0x0002 ///< SSE integer functions or AMD MMX ext
+#define FF_MM_SSE 0x0008 ///< SSE functions
+#define FF_MM_SSE2 0x0010 ///< PIV SSE2 functions
+#define FF_MM_3DNOWEXT 0x0020 ///< AMD 3DNowExt
+#define FF_MM_SSE3 0x0040 ///< Prescott SSE3 functions
+#define FF_MM_SSSE3 0x0080 ///< Conroe SSSE3 functions
+#define FF_MM_SSE4 0x0100 ///< Penryn SSE4.1 functions
+#define FF_MM_SSE42 0x0200 ///< Nehalem SSE4.2 functions
+#define FF_MM_IWMMXT 0x0100 ///< XScale IWMMXT
+#define FF_MM_ALTIVEC 0x0001 ///< standard AltiVec
+
+ /**
+ * bits per sample/pixel from the demuxer (needed for huffyuv).
+ * - encoding: Set by libavcodec.
+ * - decoding: Set by user.
+ */
+ int bits_per_coded_sample;
+
+ /**
+ * prediction method (needed for huffyuv)
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int prediction_method;
+#define FF_PRED_LEFT 0
+#define FF_PRED_PLANE 1
+#define FF_PRED_MEDIAN 2
+
+ /**
+ * sample aspect ratio (0 if unknown)
+ * That is the width of a pixel divided by the height of the pixel.
+ * Numerator and denominator must be relatively prime and smaller than 256 for some video standards.
+ * - encoding: Set by user.
+ * - decoding: Set by libavcodec.
+ */
+ AVRational sample_aspect_ratio;
+
+ /**
+ * the picture in the bitstream
+ * - encoding: Set by libavcodec.
+ * - decoding: Set by libavcodec.
+ */
+ AVFrame *coded_frame;
+
+ /**
+ * debug
+ * - encoding: Set by user.
+ * - decoding: Set by user.
+ */
+ int debug;
+#define FF_DEBUG_PICT_INFO 1
+#define FF_DEBUG_RC 2
+#define FF_DEBUG_BITSTREAM 4
+#define FF_DEBUG_MB_TYPE 8
+#define FF_DEBUG_QP 16
+#define FF_DEBUG_MV 32
+#define FF_DEBUG_DCT_COEFF 0x00000040
+#define FF_DEBUG_SKIP 0x00000080
+#define FF_DEBUG_STARTCODE 0x00000100
+#define FF_DEBUG_PTS 0x00000200
+#define FF_DEBUG_ER 0x00000400
+#define FF_DEBUG_MMCO 0x00000800
+#define FF_DEBUG_BUGS 0x00001000
+#define FF_DEBUG_VIS_QP 0x00002000
+#define FF_DEBUG_VIS_MB_TYPE 0x00004000
+#define FF_DEBUG_BUFFERS 0x00008000
+
+ /**
+ * debug
+ * - encoding: Set by user.
+ * - decoding: Set by user.
+ */
+ int debug_mv;
+#define FF_DEBUG_VIS_MV_P_FOR 0x00000001 //visualize forward predicted MVs of P frames
+#define FF_DEBUG_VIS_MV_B_FOR 0x00000002 //visualize forward predicted MVs of B frames
+#define FF_DEBUG_VIS_MV_B_BACK 0x00000004 //visualize backward predicted MVs of B frames
+
+ /**
+ * error
+ * - encoding: Set by libavcodec if flags&CODEC_FLAG_PSNR.
+ * - decoding: unused
+ */
+ uint64_t error[4];
+
+ /**
+ * minimum MB quantizer
+ * - encoding: unused
+ * - decoding: unused
+ */
+ int mb_qmin;
+
+ /**
+ * maximum MB quantizer
+ * - encoding: unused
+ * - decoding: unused
+ */
+ int mb_qmax;
+
+ /**
+ * motion estimation comparison function
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int me_cmp;
+ /**
+ * subpixel motion estimation comparison function
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int me_sub_cmp;
+ /**
+ * macroblock comparison function (not supported yet)
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int mb_cmp;
+ /**
+ * interlaced DCT comparison function
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int ildct_cmp;
+#define FF_CMP_SAD 0
+#define FF_CMP_SSE 1
+#define FF_CMP_SATD 2
+#define FF_CMP_DCT 3
+#define FF_CMP_PSNR 4
+#define FF_CMP_BIT 5
+#define FF_CMP_RD 6
+#define FF_CMP_ZERO 7
+#define FF_CMP_VSAD 8
+#define FF_CMP_VSSE 9
+#define FF_CMP_NSSE 10
+#define FF_CMP_W53 11
+#define FF_CMP_W97 12
+#define FF_CMP_DCTMAX 13
+#define FF_CMP_DCT264 14
+#define FF_CMP_CHROMA 256
+
+ /**
+ * ME diamond size & shape
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int dia_size;
+
+ /**
+ * amount of previous MV predictors (2a+1 x 2a+1 square)
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int last_predictor_count;
+
+ /**
+ * prepass for motion estimation
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int pre_me;
+
+ /**
+ * motion estimation prepass comparison function
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int me_pre_cmp;
+
+ /**
+ * ME prepass diamond size & shape
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int pre_dia_size;
+
+ /**
+ * subpel ME quality
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int me_subpel_quality;
+
+ /**
+ * callback to negotiate the pixelFormat
+ * @param fmt is the list of formats which are supported by the codec,
+ * it is terminated by -1 as 0 is a valid format, the formats are ordered by quality.
+ * The first is always the native one.
+ * @return the chosen format
+ * - encoding: unused
+ * - decoding: Set by user, if not set the native format will be chosen.
+ */
+ enum PixelFormat (*get_format)(struct AVCodecContext *s, const enum PixelFormat * fmt);
+
+ /**
+ * DTG active format information (additional aspect ratio
+ * information only used in DVB MPEG-2 transport streams)
+ * 0 if not set.
+ *
+ * - encoding: unused
+ * - decoding: Set by decoder.
+ */
+ int dtg_active_format;
+#define FF_DTG_AFD_SAME 8
+#define FF_DTG_AFD_4_3 9
+#define FF_DTG_AFD_16_9 10
+#define FF_DTG_AFD_14_9 11
+#define FF_DTG_AFD_4_3_SP_14_9 13
+#define FF_DTG_AFD_16_9_SP_14_9 14
+#define FF_DTG_AFD_SP_4_3 15
+
+ /**
+ * maximum motion estimation search range in subpel units
+ * If 0 then no limit.
+ *
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int me_range;
+
+ /**
+ * intra quantizer bias
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int intra_quant_bias;
+#define FF_DEFAULT_QUANT_BIAS 999999
+
+ /**
+ * inter quantizer bias
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int inter_quant_bias;
+
+ /**
+ * color table ID
+ * - encoding: unused
+ * - decoding: Which clrtable should be used for 8bit RGB images.
+ * Tables have to be stored somewhere. FIXME
+ */
+ int color_table_id;
+
+ /**
+ * internal_buffer count
+ * Don't touch, used by libavcodec default_get_buffer().
+ */
+ int internal_buffer_count;
+
+ /**
+ * internal_buffers
+ * Don't touch, used by libavcodec default_get_buffer().
+ */
+ void *internal_buffer;
+
+#define FF_LAMBDA_SHIFT 7
+#define FF_LAMBDA_SCALE (1<<FF_LAMBDA_SHIFT)
+#define FF_QP2LAMBDA 118 ///< factor to convert from H.263 QP to lambda
+#define FF_LAMBDA_MAX (256*128-1)
+
+#define FF_QUALITY_SCALE FF_LAMBDA_SCALE //FIXME maybe remove
+ /**
+ * Global quality for codecs which cannot change it per frame.
+ * This should be proportional to MPEG-1/2/4 qscale.
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int global_quality;
+
+#define FF_CODER_TYPE_VLC 0
+#define FF_CODER_TYPE_AC 1
+#define FF_CODER_TYPE_RAW 2
+#define FF_CODER_TYPE_RLE 3
+#define FF_CODER_TYPE_DEFLATE 4
+ /**
+ * coder type
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int coder_type;
+
+ /**
+ * context model
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int context_model;
+#if 0
+ /**
+ *
+ * - encoding: unused
+ * - decoding: Set by user.
+ */
+ uint8_t * (*realloc)(struct AVCodecContext *s, uint8_t *buf, int buf_size);
+#endif
+
+ /**
+ * slice flags
+ * - encoding: unused
+ * - decoding: Set by user.
+ */
+ int slice_flags;
+#define SLICE_FLAG_CODED_ORDER 0x0001 ///< draw_horiz_band() is called in coded order instead of display
+#define SLICE_FLAG_ALLOW_FIELD 0x0002 ///< allow draw_horiz_band() with field slices (MPEG2 field pics)
+#define SLICE_FLAG_ALLOW_PLANE 0x0004 ///< allow draw_horiz_band() with 1 component at a time (SVQ1)
+
+ /**
+ * XVideo Motion Acceleration
+ * - encoding: forbidden
+ * - decoding: set by decoder
+ */
+ int xvmc_acceleration;
+
+ /**
+ * macroblock decision mode
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int mb_decision;
+#define FF_MB_DECISION_SIMPLE 0 ///< uses mb_cmp
+#define FF_MB_DECISION_BITS 1 ///< chooses the one which needs the fewest bits
+#define FF_MB_DECISION_RD 2 ///< rate distortion
+
+ /**
+ * custom intra quantization matrix
+ * - encoding: Set by user, can be NULL.
+ * - decoding: Set by libavcodec.
+ */
+ uint16_t *intra_matrix;
+
+ /**
+ * custom inter quantization matrix
+ * - encoding: Set by user, can be NULL.
+ * - decoding: Set by libavcodec.
+ */
+ uint16_t *inter_matrix;
+
+ /**
+ * fourcc from the AVI stream header (LSB first, so "ABCD" -> ('D'<<24) + ('C'<<16) + ('B'<<8) + 'A').
+ * This is used to work around some encoder bugs.
+ * - encoding: unused
+ * - decoding: Set by user, will be converted to uppercase by libavcodec during init.
+ */
+ unsigned int stream_codec_tag;
+
+ /**
+ * scene change detection threshold
+ * 0 is default, larger means fewer detected scene changes.
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int scenechange_threshold;
+
+ /**
+ * minimum Lagrange multipler
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int lmin;
+
+ /**
+ * maximum Lagrange multipler
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int lmax;
+
+ /**
+ * palette control structure
+ * - encoding: ??? (no palette-enabled encoder yet)
+ * - decoding: Set by user.
+ */
+ struct AVPaletteControl *palctrl;
+
+ /**
+ * noise reduction strength
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int noise_reduction;
+
+ /**
+ * Called at the beginning of a frame to get cr buffer for it.
+ * Buffer type (size, hints) must be the same. libavcodec won't check it.
+ * libavcodec will pass previous buffer in pic, function should return
+ * same buffer or new buffer with old frame "painted" into it.
+ * If pic.data[0] == NULL must behave like get_buffer().
+ * if CODEC_CAP_DR1 is not set then reget_buffer() must call
+ * avcodec_default_reget_buffer() instead of providing buffers allocated by
+ * some other means.
+ * - encoding: unused
+ * - decoding: Set by libavcodec., user can override
+ */
+ int (*reget_buffer)(struct AVCodecContext *c, AVFrame *pic);
+
+ /**
+ * Number of bits which should be loaded into the rc buffer before decoding starts.
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int rc_initial_buffer_occupancy;
+
+ /**
+ *
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int inter_threshold;
+
+ /**
+ * CODEC_FLAG2_*
+ * - encoding: Set by user.
+ * - decoding: Set by user.
+ */
+ int flags2;
+
+ /**
+ * Simulates errors in the bitstream to test error concealment.
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int error_rate;
+
+ /**
+ * MP3 antialias algorithm, see FF_AA_* below.
+ * - encoding: unused
+ * - decoding: Set by user.
+ */
+ int antialias_algo;
+#define FF_AA_AUTO 0
+#define FF_AA_FASTINT 1 //not implemented yet
+#define FF_AA_INT 2
+#define FF_AA_FLOAT 3
+ /**
+ * quantizer noise shaping
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int quantizer_noise_shaping;
+
+ /**
+ * thread count
+ * is used to decide how many independent tasks should be passed to execute()
+ * - encoding: Set by user.
+ * - decoding: Set by user.
+ */
+ int thread_count;
+
+ /**
+ * The codec may call this to execute several independent things.
+ * It will return only after finishing all tasks.
+ * The user may replace this with some multithreaded implementation,
+ * the default implementation will execute the parts serially.
+ * @param count the number of things to execute
+ * - encoding: Set by libavcodec, user can override.
+ * - decoding: Set by libavcodec, user can override.
+ */
+ int (*execute)(struct AVCodecContext *c, int (*func)(struct AVCodecContext *c2, void *arg), void *arg2, int *ret, int count, int size);
+
+ /**
+ * thread opaque
+ * Can be used by execute() to store some per AVCodecContext stuff.
+ * - encoding: set by execute()
+ * - decoding: set by execute()
+ */
+ void *thread_opaque;
+
+ /**
+ * Motion estimation threshold below which no motion estimation is
+ * performed, but instead the user specified motion vectors are used.
+ *
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int me_threshold;
+
+ /**
+ * Macroblock threshold below which the user specified macroblock types will be used.
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int mb_threshold;
+
+ /**
+ * precision of the intra DC coefficient - 8
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int intra_dc_precision;
+
+ /**
+ * noise vs. sse weight for the nsse comparsion function
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int nsse_weight;
+
+ /**
+ * Number of macroblock rows at the top which are skipped.
+ * - encoding: unused
+ * - decoding: Set by user.
+ */
+ int skip_top;
+
+ /**
+ * Number of macroblock rows at the bottom which are skipped.
+ * - encoding: unused
+ * - decoding: Set by user.
+ */
+ int skip_bottom;
+
+ /**
+ * profile
+ * - encoding: Set by user.
+ * - decoding: Set by libavcodec.
+ */
+ int profile;
+#define FF_PROFILE_UNKNOWN -99
+
+#define FF_PROFILE_AAC_MAIN 0
+#define FF_PROFILE_AAC_LOW 1
+#define FF_PROFILE_AAC_SSR 2
+#define FF_PROFILE_AAC_LTP 3
+
+#define FF_PROFILE_H264_BASELINE 66
+#define FF_PROFILE_H264_MAIN 77
+#define FF_PROFILE_H264_EXTENDED 88
+#define FF_PROFILE_H264_HIGH 100
+#define FF_PROFILE_H264_HIGH_10 110
+#define FF_PROFILE_H264_HIGH_422 122
+#define FF_PROFILE_H264_HIGH_444 244
+#define FF_PROFILE_H264_CAVLC_444 44
+
+ /**
+ * level
+ * - encoding: Set by user.
+ * - decoding: Set by libavcodec.
+ */
+ int level;
+#define FF_LEVEL_UNKNOWN -99
+
+ /**
+ * low resolution decoding, 1-> 1/2 size, 2->1/4 size
+ * - encoding: unused
+ * - decoding: Set by user.
+ */
+ int lowres;
+
+ /**
+ * Bitstream width / height, may be different from width/height if lowres
+ * or other things are used.
+ * - encoding: unused
+ * - decoding: Set by user before init if known. Codec should override / dynamically change if needed.
+ */
+ int coded_width, coded_height;
+
+ /**
+ * frame skip threshold
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int frame_skip_threshold;
+
+ /**
+ * frame skip factor
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int frame_skip_factor;
+
+ /**
+ * frame skip exponent
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int frame_skip_exp;
+
+ /**
+ * frame skip comparison function
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int frame_skip_cmp;
+
+ /**
+ * Border processing masking, raises the quantizer for mbs on the borders
+ * of the picture.
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ float border_masking;
+
+ /**
+ * minimum MB lagrange multipler
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int mb_lmin;
+
+ /**
+ * maximum MB lagrange multipler
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int mb_lmax;
+
+ /**
+ *
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int me_penalty_compensation;
+
+ /**
+ *
+ * - encoding: unused
+ * - decoding: Set by user.
+ */
+ enum AVDiscard skip_loop_filter;
+
+ /**
+ *
+ * - encoding: unused
+ * - decoding: Set by user.
+ */
+ enum AVDiscard skip_idct;
+
+ /**
+ *
+ * - encoding: unused
+ * - decoding: Set by user.
+ */
+ enum AVDiscard skip_frame;
+
+ /**
+ *
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int bidir_refine;
+
+ /**
+ *
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int brd_scale;
+
+ /**
+ * constant rate factor - quality-based VBR - values ~correspond to qps
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ float crf;
+
+ /**
+ * constant quantization parameter rate control method
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int cqp;
+
+ /**
+ * minimum GOP size
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int keyint_min;
+
+ /**
+ * number of reference frames
+ * - encoding: Set by user.
+ * - decoding: Set by lavc.
+ */
+ int refs;
+
+ /**
+ * chroma qp offset from luma
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int chromaoffset;
+
+ /**
+ * Influences how often B-frames are used.
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int bframebias;
+
+ /**
+ * trellis RD quantization
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int trellis;
+
+ /**
+ * Reduce fluctuations in qp (before curve compression).
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ float complexityblur;
+
+ /**
+ * in-loop deblocking filter alphac0 parameter
+ * alpha is in the range -6...6
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int deblockalpha;
+
+ /**
+ * in-loop deblocking filter beta parameter
+ * beta is in the range -6...6
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int deblockbeta;
+
+ /**
+ * macroblock subpartition sizes to consider - p8x8, p4x4, b8x8, i8x8, i4x4
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int partitions;
+#define X264_PART_I4X4 0x001 /* Analyze i4x4 */
+#define X264_PART_I8X8 0x002 /* Analyze i8x8 (requires 8x8 transform) */
+#define X264_PART_P8X8 0x010 /* Analyze p16x8, p8x16 and p8x8 */
+#define X264_PART_P4X4 0x020 /* Analyze p8x4, p4x8, p4x4 */
+#define X264_PART_B8X8 0x100 /* Analyze b16x8, b8x16 and b8x8 */
+
+ /**
+ * direct MV prediction mode - 0 (none), 1 (spatial), 2 (temporal), 3 (auto)
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int directpred;
+
+ /**
+ * Audio cutoff bandwidth (0 means "automatic")
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int cutoff;
+
+ /**
+ * Multiplied by qscale for each frame and added to scene_change_score.
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int scenechange_factor;
+
+ /**
+ *
+ * Note: Value depends upon the compare function used for fullpel ME.
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int mv0_threshold;
+
+ /**
+ * Adjusts sensitivity of b_frame_strategy 1.
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int b_sensitivity;
+
+ /**
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int compression_level;
+#define FF_COMPRESSION_DEFAULT -1
+
+ /**
+ * Sets whether to use LPC mode - used by FLAC encoder.
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int use_lpc;
+
+ /**
+ * LPC coefficient precision - used by FLAC encoder
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int lpc_coeff_precision;
+
+ /**
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int min_prediction_order;
+
+ /**
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int max_prediction_order;
+
+ /**
+ * search method for selecting prediction order
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int prediction_order_method;
+
+ /**
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int min_partition_order;
+
+ /**
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int max_partition_order;
+
+ /**
+ * GOP timecode frame start number, in non drop frame format
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int64_t timecode_frame_start;
+
+#if LIBAVCODEC_VERSION_MAJOR < 53
+ /**
+ * Decoder should decode to this many channels if it can (0 for default)
+ * - encoding: unused
+ * - decoding: Set by user.
+ * @deprecated Deprecated in favor of request_channel_layout.
+ */
+ int request_channels;
+#endif
+
+ /**
+ * Percentage of dynamic range compression to be applied by the decoder.
+ * The default value is 1.0, corresponding to full compression.
+ * - encoding: unused
+ * - decoding: Set by user.
+ */
+ float drc_scale;
+
+ /**
+ * opaque 64bit number (generally a PTS) that will be reordered and
+ * output in AVFrame.reordered_opaque
+ * - encoding: unused
+ * - decoding: Set by user.
+ */
+ int64_t reordered_opaque;
+
+ /**
+ * Bits per sample/pixel of internal libavcodec pixel/sample format.
+ * This field is applicable only when sample_fmt is SAMPLE_FMT_S32.
+ * - encoding: set by user.
+ * - decoding: set by libavcodec.
+ */
+ int bits_per_raw_sample;
+
+ /**
+ * Audio channel layout.
+ * - encoding: set by user.
+ * - decoding: set by libavcodec.
+ */
+ int64_t channel_layout;
+
+ /**
+ * Request decoder to use this channel layout if it can (0 for default)
+ * - encoding: unused
+ * - decoding: Set by user.
+ */
+ int64_t request_channel_layout;
+
+ /**
+ * Ratecontrol attempt to use, at maximum, <value> of what can be used without an underflow.
+ * - encoding: Set by user.
+ * - decoding: unused.
+ */
+ float rc_max_available_vbv_use;
+
+ /**
+ * Ratecontrol attempt to use, at least, <value> times the amount needed to prevent a vbv overflow.
+ * - encoding: Set by user.
+ * - decoding: unused.
+ */
+ float rc_min_vbv_overflow_use;
+
+ /**
+ * Hardware accelerator in use
+ * - encoding: unused.
+ * - decoding: Set by libavcodec
+ */
+ struct AVHWAccel *hwaccel;
+
+ /**
+ * For some codecs, the time base is closer to the field rate than the frame rate.
+ * Most notably, H.264 and MPEG-2 specify time_base as half of frame duration
+ * if no telecine is used ...
+ *
+ * Set to time_base ticks per frame. Default 1, e.g., H.264/MPEG-2 set it to 2.
+ */
+ int ticks_per_frame;
+
+ /**
+ * Hardware accelerator context.
+ * For some hardware accelerators, a global context needs to be
+ * provided by the user. In that case, this holds display-dependent
+ * data FFmpeg cannot instantiate itself. Please refer to the
+ * FFmpeg HW accelerator documentation to know how to fill this
+ * is. e.g. for VA API, this is a struct vaapi_context.
+ * - encoding: unused
+ * - decoding: Set by user
+ */
+ void *hwaccel_context;
+
+ /**
+ * Chromaticity coordinates of the source primaries.
+ * - encoding: Set by user
+ * - decoding: Set by libavcodec
+ */
+ enum AVColorPrimaries color_primaries;
+
+ /**
+ * Color Transfer Characteristic.
+ * - encoding: Set by user
+ * - decoding: Set by libavcodec
+ */
+ enum AVColorTransferCharacteristic color_trc;
+
+ /**
+ * YUV colorspace type.
+ * - encoding: Set by user
+ * - decoding: Set by libavcodec
+ */
+ enum AVColorSpace colorspace;
+
+ /**
+ * MPEG vs JPEG YUV range.
+ * - encoding: Set by user
+ * - decoding: Set by libavcodec
+ */
+ enum AVColorRange color_range;
+
+ /**
+ * This defines the location of chroma samples.
+ * - encoding: Set by user
+ * - decoding: Set by libavcodec
+ */
+ enum AVChromaLocation chroma_sample_location;
+
+ /**
+ * The codec may call this to execute several independent things.
+ * It will return only after finishing all tasks.
+ * The user may replace this with some multithreaded implementation,
+ * the default implementation will execute the parts serially.
+ * Also see avcodec_thread_init and e.g. the --enable-pthread configure option.
+ * @param c context passed also to func
+ * @param count the number of things to execute
+ * @param arg2 argument passed unchanged to func
+ * @param ret return values of executed functions, must have space for "count" values. May be NULL.
+ * @param func function that will be called count times, with jobnr from 0 to count-1.
+ * threadnr will be in the range 0 to c->thread_count-1 < MAX_THREADS and so that no
+ * two instances of func executing at the same time will have the same threadnr.
+ * @return always 0 currently, but code should handle a future improvement where when any call to func
+ * returns < 0 no further calls to func may be done and < 0 is returned.
+ * - encoding: Set by libavcodec, user can override.
+ * - decoding: Set by libavcodec, user can override.
+ */
+ int (*execute2)(struct AVCodecContext *c, int (*func)(struct AVCodecContext *c2, void *arg, int jobnr, int threadnr), void *arg2, int *ret, int count);
+
+ /**
+ * explicit P-frame weighted prediction analysis method
+ * 0: off
+ * 1: fast blind weighting (one reference duplicate with -1 offset)
+ * 2: smart weighting (full fade detection analysis)
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int weighted_p_pred;
+
+ /**
+ * AQ mode
+ * 0: Disabled
+ * 1: Variance AQ (complexity mask)
+ * 2: Auto-variance AQ (experimental)
+ * - encoding: Set by user
+ * - decoding: unused
+ */
+ int aq_mode;
+
+ /**
+ * AQ strength
+ * Reduces blocking and blurring in flat and textured areas.
+ * - encoding: Set by user
+ * - decoding: unused
+ */
+ float aq_strength;
+
+ /**
+ * PSY RD
+ * Strength of psychovisual optimization
+ * - encoding: Set by user
+ * - decoding: unused
+ */
+ float psy_rd;
+
+ /**
+ * PSY trellis
+ * Strength of psychovisual optimization
+ * - encoding: Set by user
+ * - decoding: unused
+ */
+ float psy_trellis;
+
+ /**
+ * RC lookahead
+ * Number of frames for frametype and ratecontrol lookahead
+ * - encoding: Set by user
+ * - decoding: unused
+ */
+ int rc_lookahead;
+} AVCodecContext;
+
+/**
+ * AVCodec.
+ */
+typedef struct AVCodec {
+ /**
+ * Name of the codec implementation.
+ * The name is globally unique among encoders and among decoders (but an
+ * encoder and a decoder can share the same name).
+ * This is the primary way to find a codec from the user perspective.
+ */
+ const char *name;
+ enum AVMediaType type;
+ enum CodecID id;
+ int priv_data_size;
+ int (*init)(AVCodecContext *);
+ int (*encode)(AVCodecContext *, uint8_t *buf, int buf_size, void *data);
+ int (*close)(AVCodecContext *);
+ int (*decode)(AVCodecContext *, void *outdata, int *outdata_size, AVPacket *avpkt);
+ /**
+ * Codec capabilities.
+ * see CODEC_CAP_*
+ */
+ int capabilities;
+ struct AVCodec *next;
+ /**
+ * Flush buffers.
+ * Will be called when seeking
+ */
+ void (*flush)(AVCodecContext *);
+ const AVRational *supported_framerates; ///< array of supported framerates, or NULL if any, array is terminated by {0,0}
+ const enum PixelFormat *pix_fmts; ///< array of supported pixel formats, or NULL if unknown, array is terminated by -1
+ /**
+ * Descriptive name for the codec, meant to be more human readable than name.
+ * You should use the NULL_IF_CONFIG_SMALL() macro to define it.
+ */
+ const char *long_name;
+ const int *supported_samplerates; ///< array of supported audio samplerates, or NULL if unknown, array is terminated by 0
+ const enum SampleFormat *sample_fmts; ///< array of supported sample formats, or NULL if unknown, array is terminated by -1
+ const int64_t *channel_layouts; ///< array of support channel layouts, or NULL if unknown. array is terminated by 0
+} AVCodec;
+
+/**
+ * AVHWAccel.
+ */
+typedef struct AVHWAccel {
+ /**
+ * Name of the hardware accelerated codec.
+ * The name is globally unique among encoders and among decoders (but an
+ * encoder and a decoder can share the same name).
+ */
+ const char *name;
+
+ /**
+ * Type of codec implemented by the hardware accelerator.
+ *
+ * See AVMEDIA_TYPE_xxx
+ */
+ enum AVMediaType type;
+
+ /**
+ * Codec implemented by the hardware accelerator.
+ *
+ * See CODEC_ID_xxx
+ */
+ enum CodecID id;
+
+ /**
+ * Supported pixel format.
+ *
+ * Only hardware accelerated formats are supported here.
+ */
+ enum PixelFormat pix_fmt;
+
+ /**
+ * Hardware accelerated codec capabilities.
+ * see FF_HWACCEL_CODEC_CAP_*
+ */
+ int capabilities;
+
+ struct AVHWAccel *next;
+
+ /**
+ * Called at the beginning of each frame or field picture.
+ *
+ * Meaningful frame information (codec specific) is guaranteed to
+ * be parsed at this point. This function is mandatory.
+ *
+ * Note that buf can be NULL along with buf_size set to 0.
+ * Otherwise, this means the whole frame is available at this point.
+ *
+ * @param avctx the codec context
+ * @param buf the frame data buffer base
+ * @param buf_size the size of the frame in bytes
+ * @return zero if successful, a negative value otherwise
+ */
+ int (*start_frame)(AVCodecContext *avctx, const uint8_t *buf, uint32_t buf_size);
+
+ /**
+ * Callback for each slice.
+ *
+ * Meaningful slice information (codec specific) is guaranteed to
+ * be parsed at this point. This function is mandatory.
+ *
+ * @param avctx the codec context
+ * @param buf the slice data buffer base
+ * @param buf_size the size of the slice in bytes
+ * @return zero if successful, a negative value otherwise
+ */
+ int (*decode_slice)(AVCodecContext *avctx, const uint8_t *buf, uint32_t buf_size);
+
+ /**
+ * Called at the end of each frame or field picture.
+ *
+ * The whole picture is parsed at this point and can now be sent
+ * to the hardware accelerator. This function is mandatory.
+ *
+ * @param avctx the codec context
+ * @return zero if successful, a negative value otherwise
+ */
+ int (*end_frame)(AVCodecContext *avctx);
+
+ /**
+ * Size of HW accelerator private data.
+ *
+ * Private data is allocated with av_mallocz() before
+ * AVCodecContext.get_buffer() and deallocated after
+ * AVCodecContext.release_buffer().
+ */
+ int priv_data_size;
+} AVHWAccel;
+
+/**
+ * four components are given, that's all.
+ * the last component is alpha
+ */
+typedef struct AVPicture {
+ uint8_t *data[4];
+ int linesize[4]; ///< number of bytes per line
+} AVPicture;
+
+#if LIBAVCODEC_VERSION_MAJOR < 53
+/**
+ * AVPaletteControl
+ * This structure defines a method for communicating palette changes
+ * between and demuxer and a decoder.
+ *
+ * @deprecated Use AVPacket to send palette changes instead.
+ * This is totally broken.
+ */
+#define AVPALETTE_SIZE 1024
+#define AVPALETTE_COUNT 256
+typedef struct AVPaletteControl {
+
+ /* Demuxer sets this to 1 to indicate the palette has changed;
+ * decoder resets to 0. */
+ int palette_changed;
+
+ /* 4-byte ARGB palette entries, stored in native byte order; note that
+ * the individual palette components should be on a 8-bit scale; if
+ * the palette data comes from an IBM VGA native format, the component
+ * data is probably 6 bits in size and needs to be scaled. */
+ unsigned int palette[AVPALETTE_COUNT];
+
+} AVPaletteControl attribute_deprecated;
+#endif
+
+enum AVSubtitleType {
+ SUBTITLE_NONE,
+
+ SUBTITLE_BITMAP, ///< A bitmap, pict will be set
+
+ /**
+ * Plain text, the text field must be set by the decoder and is
+ * authoritative. ass and pict fields may contain approximations.
+ */
+ SUBTITLE_TEXT,
+
+ /**
+ * Formatted text, the ass field must be set by the decoder and is
+ * authoritative. pict and text fields may contain approximations.
+ */
+ SUBTITLE_ASS,
+};
+
+typedef struct AVSubtitleRect {
+ int x; ///< top left corner of pict, undefined when pict is not set
+ int y; ///< top left corner of pict, undefined when pict is not set
+ int w; ///< width of pict, undefined when pict is not set
+ int h; ///< height of pict, undefined when pict is not set
+ int nb_colors; ///< number of colors in pict, undefined when pict is not set
+
+ /**
+ * data+linesize for the bitmap of this subtitle.
+ * can be set for text/ass as well once they where rendered
+ */
+ AVPicture pict;
+ enum AVSubtitleType type;
+
+ char *text; ///< 0 terminated plain UTF-8 text
+
+ /**
+ * 0 terminated ASS/SSA compatible event line.
+ * The pressentation of this is unaffected by the other values in this
+ * struct.
+ */
+ char *ass;
+} AVSubtitleRect;
+
+typedef struct AVSubtitle {
+ uint16_t format; /* 0 = graphics */
+ uint32_t start_display_time; /* relative to packet pts, in ms */
+ uint32_t end_display_time; /* relative to packet pts, in ms */
+ unsigned num_rects;
+ AVSubtitleRect **rects;
+ int64_t pts; ///< Same as packet pts, in AV_TIME_BASE
+} AVSubtitle;
+
+/* packet functions */
+
+/**
+ * @deprecated use NULL instead
+ */
+attribute_deprecated void av_destruct_packet_nofree(AVPacket *pkt);
+
+/**
+ * Default packet destructor.
+ */
+void av_destruct_packet(AVPacket *pkt);
+
+/**
+ * Initialize optional fields of a packet with default values.
+ *
+ * @param pkt packet
+ */
+void av_init_packet(AVPacket *pkt);
+
+/**
+ * Allocate the payload of a packet and initialize its fields with
+ * default values.
+ *
+ * @param pkt packet
+ * @param size wanted payload size
+ * @return 0 if OK, AVERROR_xxx otherwise
+ */
+int av_new_packet(AVPacket *pkt, int size);
+
+/**
+ * Reduce packet size, correctly zeroing padding
+ *
+ * @param pkt packet
+ * @param size new size
+ */
+void av_shrink_packet(AVPacket *pkt, int size);
+
+/**
+ * @warning This is a hack - the packet memory allocation stuff is broken. The
+ * packet is allocated if it was not really allocated.
+ */
+int av_dup_packet(AVPacket *pkt);
+
+/**
+ * Free a packet.
+ *
+ * @param pkt packet to free
+ */
+void av_free_packet(AVPacket *pkt);
+
+/* resample.c */
+
+struct ReSampleContext;
+struct AVResampleContext;
+
+typedef struct ReSampleContext ReSampleContext;
+
+#if LIBAVCODEC_VERSION_MAJOR < 53
+/**
+ * @deprecated Use av_audio_resample_init() instead.
+ */
+attribute_deprecated ReSampleContext *audio_resample_init(int output_channels, int input_channels,
+ int output_rate, int input_rate);
+#endif
+/**
+ * Initializes audio resampling context
+ *
+ * @param output_channels number of output channels
+ * @param input_channels number of input channels
+ * @param output_rate output sample rate
+ * @param input_rate input sample rate
+ * @param sample_fmt_out requested output sample format
+ * @param sample_fmt_in input sample format
+ * @param filter_length length of each FIR filter in the filterbank relative to the cutoff freq
+ * @param log2_phase_count log2 of the number of entries in the polyphase filterbank
+ * @param linear If 1 then the used FIR filter will be linearly interpolated
+ between the 2 closest, if 0 the closest will be used
+ * @param cutoff cutoff frequency, 1.0 corresponds to half the output sampling rate
+ * @return allocated ReSampleContext, NULL if error occured
+ */
+ReSampleContext *av_audio_resample_init(int output_channels, int input_channels,
+ int output_rate, int input_rate,
+ enum SampleFormat sample_fmt_out,
+ enum SampleFormat sample_fmt_in,
+ int filter_length, int log2_phase_count,
+ int linear, double cutoff);
+
+int audio_resample(ReSampleContext *s, short *output, short *input, int nb_samples);
+void audio_resample_close(ReSampleContext *s);
+
+
+/**
+ * Initializes an audio resampler.
+ * Note, if either rate is not an integer then simply scale both rates up so they are.
+ * @param filter_length length of each FIR filter in the filterbank relative to the cutoff freq
+ * @param log2_phase_count log2 of the number of entries in the polyphase filterbank
+ * @param linear If 1 then the used FIR filter will be linearly interpolated
+ between the 2 closest, if 0 the closest will be used
+ * @param cutoff cutoff frequency, 1.0 corresponds to half the output sampling rate
+ */
+struct AVResampleContext *av_resample_init(int out_rate, int in_rate, int filter_length, int log2_phase_count, int linear, double cutoff);
+
+/**
+ * resamples.
+ * @param src an array of unconsumed samples
+ * @param consumed the number of samples of src which have been consumed are returned here
+ * @param src_size the number of unconsumed samples available
+ * @param dst_size the amount of space in samples available in dst
+ * @param update_ctx If this is 0 then the context will not be modified, that way several channels can be resampled with the same context.
+ * @return the number of samples written in dst or -1 if an error occurred
+ */
+int av_resample(struct AVResampleContext *c, short *dst, short *src, int *consumed, int src_size, int dst_size, int update_ctx);
+
+
+/**
+ * Compensates samplerate/timestamp drift. The compensation is done by changing
+ * the resampler parameters, so no audible clicks or similar distortions occur
+ * @param compensation_distance distance in output samples over which the compensation should be performed
+ * @param sample_delta number of output samples which should be output less
+ *
+ * example: av_resample_compensate(c, 10, 500)
+ * here instead of 510 samples only 500 samples would be output
+ *
+ * note, due to rounding the actual compensation might be slightly different,
+ * especially if the compensation_distance is large and the in_rate used during init is small
+ */
+void av_resample_compensate(struct AVResampleContext *c, int sample_delta, int compensation_distance);
+void av_resample_close(struct AVResampleContext *c);
+
+/**
+ * Allocate memory for a picture. Call avpicture_free to free it.
+ *
+ * @param picture the picture to be filled in
+ * @param pix_fmt the format of the picture
+ * @param width the width of the picture
+ * @param height the height of the picture
+ * @return zero if successful, a negative value if not
+ */
+int avpicture_alloc(AVPicture *picture, enum PixelFormat pix_fmt, int width, int height);
+
+/**
+ * Free a picture previously allocated by avpicture_alloc().
+ *
+ * @param picture the AVPicture to be freed
+ */
+void avpicture_free(AVPicture *picture);
+
+/**
+ * Fill in the AVPicture fields.
+ * The fields of the given AVPicture are filled in by using the 'ptr' address
+ * which points to the image data buffer. Depending on the specified picture
+ * format, one or multiple image data pointers and line sizes will be set.
+ * If a planar format is specified, several pointers will be set pointing to
+ * the different picture planes and the line sizes of the different planes
+ * will be stored in the lines_sizes array.
+ * Call with ptr == NULL to get the required size for the ptr buffer.
+ *
+ * @param picture AVPicture whose fields are to be filled in
+ * @param ptr Buffer which will contain or contains the actual image data
+ * @param pix_fmt The format in which the picture data is stored.
+ * @param width the width of the image in pixels
+ * @param height the height of the image in pixels
+ * @return size of the image data in bytes
+ */
+int avpicture_fill(AVPicture *picture, uint8_t *ptr,
+ enum PixelFormat pix_fmt, int width, int height);
+int avpicture_layout(const AVPicture* src, enum PixelFormat pix_fmt, int width, int height,
+ unsigned char *dest, int dest_size);
+
+/**
+ * Calculate the size in bytes that a picture of the given width and height
+ * would occupy if stored in the given picture format.
+ * Note that this returns the size of a compact representation as generated
+ * by avpicture_layout, which can be smaller than the size required for e.g.
+ * avpicture_fill.
+ *
+ * @param pix_fmt the given picture format
+ * @param width the width of the image
+ * @param height the height of the image
+ * @return Image data size in bytes or -1 on error (e.g. too large dimensions).
+ */
+int avpicture_get_size(enum PixelFormat pix_fmt, int width, int height);
+void avcodec_get_chroma_sub_sample(enum PixelFormat pix_fmt, int *h_shift, int *v_shift);
+const char *avcodec_get_pix_fmt_name(enum PixelFormat pix_fmt);
+void avcodec_set_dimensions(AVCodecContext *s, int width, int height);
+
+#if LIBAVCODEC_VERSION_MAJOR < 53
+/**
+ * Returns the pixel format corresponding to the name name.
+ *
+ * If there is no pixel format with name name, then looks for a
+ * pixel format with the name corresponding to the native endian
+ * format of name.
+ * For example in a little-endian system, first looks for "gray16",
+ * then for "gray16le".
+ *
+ * Finally if no pixel format has been found, returns PIX_FMT_NONE.
+ *
+ * @deprecated Deprecated in favor of av_get_pix_fmt().
+ */
+attribute_deprecated enum PixelFormat avcodec_get_pix_fmt(const char* name);
+#endif
+
+/**
+ * Returns a value representing the fourCC code associated to the
+ * pixel format pix_fmt, or 0 if no associated fourCC code can be
+ * found.
+ */
+unsigned int avcodec_pix_fmt_to_codec_tag(enum PixelFormat pix_fmt);
+
+#define FF_LOSS_RESOLUTION 0x0001 /**< loss due to resolution change */
+#define FF_LOSS_DEPTH 0x0002 /**< loss due to color depth change */
+#define FF_LOSS_COLORSPACE 0x0004 /**< loss due to color space conversion */
+#define FF_LOSS_ALPHA 0x0008 /**< loss of alpha bits */
+#define FF_LOSS_COLORQUANT 0x0010 /**< loss due to color quantization */
+#define FF_LOSS_CHROMA 0x0020 /**< loss of chroma (e.g. RGB to gray conversion) */
+
+/**
+ * Computes what kind of losses will occur when converting from one specific
+ * pixel format to another.
+ * When converting from one pixel format to another, information loss may occur.
+ * For example, when converting from RGB24 to GRAY, the color information will
+ * be lost. Similarly, other losses occur when converting from some formats to
+ * other formats. These losses can involve loss of chroma, but also loss of
+ * resolution, loss of color depth, loss due to the color space conversion, loss
+ * of the alpha bits or loss due to color quantization.
+ * avcodec_get_fix_fmt_loss() informs you about the various types of losses
+ * which will occur when converting from one pixel format to another.
+ *
+ * @param[in] dst_pix_fmt destination pixel format
+ * @param[in] src_pix_fmt source pixel format
+ * @param[in] has_alpha Whether the source pixel format alpha channel is used.
+ * @return Combination of flags informing you what kind of losses will occur.
+ */
+int avcodec_get_pix_fmt_loss(enum PixelFormat dst_pix_fmt, enum PixelFormat src_pix_fmt,
+ int has_alpha);
+
+/**
+ * Finds the best pixel format to convert to given a certain source pixel
+ * format. When converting from one pixel format to another, information loss
+ * may occur. For example, when converting from RGB24 to GRAY, the color
+ * information will be lost. Similarly, other losses occur when converting from
+ * some formats to other formats. avcodec_find_best_pix_fmt() searches which of
+ * the given pixel formats should be used to suffer the least amount of loss.
+ * The pixel formats from which it chooses one, are determined by the
+ * pix_fmt_mask parameter.
+ *
+ * @code
+ * src_pix_fmt = PIX_FMT_YUV420P;
+ * pix_fmt_mask = (1 << PIX_FMT_YUV422P) || (1 << PIX_FMT_RGB24);
+ * dst_pix_fmt = avcodec_find_best_pix_fmt(pix_fmt_mask, src_pix_fmt, alpha, &loss);
+ * @endcode
+ *
+ * @param[in] pix_fmt_mask bitmask determining which pixel format to choose from
+ * @param[in] src_pix_fmt source pixel format
+ * @param[in] has_alpha Whether the source pixel format alpha channel is used.
+ * @param[out] loss_ptr Combination of flags informing you what kind of losses will occur.
+ * @return The best pixel format to convert to or -1 if none was found.
+ */
+enum PixelFormat avcodec_find_best_pix_fmt(int64_t pix_fmt_mask, enum PixelFormat src_pix_fmt,
+ int has_alpha, int *loss_ptr);
+
+
+/**
+ * Print in buf the string corresponding to the pixel format with
+ * number pix_fmt, or an header if pix_fmt is negative.
+ *
+ * @param[in] buf the buffer where to write the string
+ * @param[in] buf_size the size of buf
+ * @param[in] pix_fmt the number of the pixel format to print the corresponding info string, or
+ * a negative value to print the corresponding header.
+ * Meaningful values for obtaining a pixel format info vary from 0 to PIX_FMT_NB -1.
+ */
+void avcodec_pix_fmt_string (char *buf, int buf_size, enum PixelFormat pix_fmt);
+
+#define FF_ALPHA_TRANSP 0x0001 /* image has some totally transparent pixels */
+#define FF_ALPHA_SEMI_TRANSP 0x0002 /* image has some transparent pixels */
+
+/**
+ * Tell if an image really has transparent alpha values.
+ * @return ored mask of FF_ALPHA_xxx constants
+ */
+int img_get_alpha_info(const AVPicture *src,
+ enum PixelFormat pix_fmt, int width, int height);
+
+/* deinterlace a picture */
+/* deinterlace - if not supported return -1 */
+int avpicture_deinterlace(AVPicture *dst, const AVPicture *src,
+ enum PixelFormat pix_fmt, int width, int height);
+
+/* external high level API */
+
+/**
+ * If c is NULL, returns the first registered codec,
+ * if c is non-NULL, returns the next registered codec after c,
+ * or NULL if c is the last one.
+ */
+AVCodec *av_codec_next(AVCodec *c);
+
+/**
+ * Returns the LIBAVCODEC_VERSION_INT constant.
+ */
+unsigned avcodec_version(void);
+
+/**
+ * Returns the libavcodec build-time configuration.
+ */
+const char *avcodec_configuration(void);
+
+/**
+ * Returns the libavcodec license.
+ */
+const char *avcodec_license(void);
+
+/**
+ * Initializes libavcodec.
+ *
+ * @warning This function must be called before any other libavcodec
+ * function.
+ */
+void avcodec_init(void);
+
+#if LIBAVCODEC_VERSION_MAJOR < 53
+/**
+ * @deprecated Deprecated in favor of avcodec_register().
+ */
+attribute_deprecated void register_avcodec(AVCodec *codec);
+#endif
+
+/**
+ * Register the codec codec and initialize libavcodec.
+ *
+ * @see avcodec_init()
+ */
+void avcodec_register(AVCodec *codec);
+
+/**
+ * Finds a registered encoder with a matching codec ID.
+ *
+ * @param id CodecID of the requested encoder
+ * @return An encoder if one was found, NULL otherwise.
+ */
+AVCodec *avcodec_find_encoder(enum CodecID id);
+
+/**
+ * Finds a registered encoder with the specified name.
+ *
+ * @param name name of the requested encoder
+ * @return An encoder if one was found, NULL otherwise.
+ */
+AVCodec *avcodec_find_encoder_by_name(const char *name);
+
+/**
+ * Finds a registered decoder with a matching codec ID.
+ *
+ * @param id CodecID of the requested decoder
+ * @return A decoder if one was found, NULL otherwise.
+ */
+AVCodec *avcodec_find_decoder(enum CodecID id);
+
+/**
+ * Finds a registered decoder with the specified name.
+ *
+ * @param name name of the requested decoder
+ * @return A decoder if one was found, NULL otherwise.
+ */
+AVCodec *avcodec_find_decoder_by_name(const char *name);
+void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode);
+
+/**
+ * Sets the fields of the given AVCodecContext to default values.
+ *
+ * @param s The AVCodecContext of which the fields should be set to default values.
+ */
+void avcodec_get_context_defaults(AVCodecContext *s);
+
+/** THIS FUNCTION IS NOT YET PART OF THE PUBLIC API!
+ * we WILL change its arguments and name a few times! */
+void avcodec_get_context_defaults2(AVCodecContext *s, enum AVMediaType);
+
+/**
+ * Allocates an AVCodecContext and sets its fields to default values. The
+ * resulting struct can be deallocated by simply calling av_free().
+ *
+ * @return An AVCodecContext filled with default values or NULL on failure.
+ * @see avcodec_get_context_defaults
+ */
+AVCodecContext *avcodec_alloc_context(void);
+
+/** THIS FUNCTION IS NOT YET PART OF THE PUBLIC API!
+ * we WILL change its arguments and name a few times! */
+AVCodecContext *avcodec_alloc_context2(enum AVMediaType);
+
+/**
+ * Copy the settings of the source AVCodecContext into the destination
+ * AVCodecContext. The resulting destination codec context will be
+ * unopened, i.e. you are required to call avcodec_open() before you
+ * can use this AVCodecContext to decode/encode video/audio data.
+ *
+ * @param dest target codec context, should be initialized with
+ * avcodec_alloc_context(), but otherwise uninitialized
+ * @param src source codec context
+ * @return AVERROR() on error (e.g. memory allocation error), 0 on success
+ */
+int avcodec_copy_context(AVCodecContext *dest, const AVCodecContext *src);
+
+/**
+ * Sets the fields of the given AVFrame to default values.
+ *
+ * @param pic The AVFrame of which the fields should be set to default values.
+ */
+void avcodec_get_frame_defaults(AVFrame *pic);
+
+/**
+ * Allocates an AVFrame and sets its fields to default values. The resulting
+ * struct can be deallocated by simply calling av_free().
+ *
+ * @return An AVFrame filled with default values or NULL on failure.
+ * @see avcodec_get_frame_defaults
+ */
+AVFrame *avcodec_alloc_frame(void);
+
+int avcodec_default_get_buffer(AVCodecContext *s, AVFrame *pic);
+void avcodec_default_release_buffer(AVCodecContext *s, AVFrame *pic);
+int avcodec_default_reget_buffer(AVCodecContext *s, AVFrame *pic);
+
+/**
+ * Returns the amount of padding in pixels which the get_buffer callback must
+ * provide around the edge of the image for codecs which do not have the
+ * CODEC_FLAG_EMU_EDGE flag.
+ *
+ * @return Required padding in pixels.
+ */
+unsigned avcodec_get_edge_width(void);
+/**
+ * Modifies width and height values so that they will result in a memory
+ * buffer that is acceptable for the codec if you do not use any horizontal
+ * padding.
+ *
+ * May only be used if a codec with CODEC_CAP_DR1 has been opened.
+ * If CODEC_FLAG_EMU_EDGE is not set, the dimensions must have been increased
+ * according to avcodec_get_edge_width() before.
+ */
+void avcodec_align_dimensions(AVCodecContext *s, int *width, int *height);
+/**
+ * Modifies width and height values so that they will result in a memory
+ * buffer that is acceptable for the codec if you also ensure that all
+ * line sizes are a multiple of the respective linesize_align[i].
+ *
+ * May only be used if a codec with CODEC_CAP_DR1 has been opened.
+ * If CODEC_FLAG_EMU_EDGE is not set, the dimensions must have been increased
+ * according to avcodec_get_edge_width() before.
+ */
+void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height,
+ int linesize_align[4]);
+
+/**
+ * Checks if the given dimension of a picture is valid, meaning that all
+ * bytes of the picture can be addressed with a signed int.
+ *
+ * @param[in] w Width of the picture.
+ * @param[in] h Height of the picture.
+ * @return Zero if valid, a negative value if invalid.
+ */
+int avcodec_check_dimensions(void *av_log_ctx, unsigned int w, unsigned int h);
+enum PixelFormat avcodec_default_get_format(struct AVCodecContext *s, const enum PixelFormat * fmt);
+
+int avcodec_thread_init(AVCodecContext *s, int thread_count);
+void avcodec_thread_free(AVCodecContext *s);
+int avcodec_default_execute(AVCodecContext *c, int (*func)(AVCodecContext *c2, void *arg2),void *arg, int *ret, int count, int size);
+int avcodec_default_execute2(AVCodecContext *c, int (*func)(AVCodecContext *c2, void *arg2, int, int),void *arg, int *ret, int count);
+//FIXME func typedef
+
+/**
+ * Initializes the AVCodecContext to use the given AVCodec. Prior to using this
+ * function the context has to be allocated.
+ *
+ * The functions avcodec_find_decoder_by_name(), avcodec_find_encoder_by_name(),
+ * avcodec_find_decoder() and avcodec_find_encoder() provide an easy way for
+ * retrieving a codec.
+ *
+ * @warning This function is not thread safe!
+ *
+ * @code
+ * avcodec_register_all();
+ * codec = avcodec_find_decoder(CODEC_ID_H264);
+ * if (!codec)
+ * exit(1);
+ *
+ * context = avcodec_alloc_context();
+ *
+ * if (avcodec_open(context, codec) < 0)
+ * exit(1);
+ * @endcode
+ *
+ * @param avctx The context which will be set up to use the given codec.
+ * @param codec The codec to use within the context.
+ * @return zero on success, a negative value on error
+ * @see avcodec_alloc_context, avcodec_find_decoder, avcodec_find_encoder
+ */
+int avcodec_open(AVCodecContext *avctx, AVCodec *codec);
+
+#if LIBAVCODEC_VERSION_MAJOR < 53
+/**
+ * Decodes an audio frame from buf into samples.
+ * Wrapper function which calls avcodec_decode_audio3.
+ *
+ * @deprecated Use avcodec_decode_audio3 instead.
+ * @param avctx the codec context
+ * @param[out] samples the output buffer
+ * @param[in,out] frame_size_ptr the output buffer size in bytes
+ * @param[in] buf the input buffer
+ * @param[in] buf_size the input buffer size in bytes
+ * @return On error a negative value is returned, otherwise the number of bytes
+ * used or zero if no frame could be decompressed.
+ */
+attribute_deprecated int avcodec_decode_audio2(AVCodecContext *avctx, int16_t *samples,
+ int *frame_size_ptr,
+ const uint8_t *buf, int buf_size);
+#endif
+
+/**
+ * Decodes the audio frame of size avpkt->size from avpkt->data into samples.
+ * Some decoders may support multiple frames in a single AVPacket, such
+ * decoders would then just decode the first frame. In this case,
+ * avcodec_decode_audio3 has to be called again with an AVPacket that contains
+ * the remaining data in order to decode the second frame etc.
+ * If no frame
+ * could be outputted, frame_size_ptr is zero. Otherwise, it is the
+ * decompressed frame size in bytes.
+ *
+ * @warning You must set frame_size_ptr to the allocated size of the
+ * output buffer before calling avcodec_decode_audio3().
+ *
+ * @warning The input buffer must be FF_INPUT_BUFFER_PADDING_SIZE larger than
+ * the actual read bytes because some optimized bitstream readers read 32 or 64
+ * bits at once and could read over the end.
+ *
+ * @warning The end of the input buffer avpkt->data should be set to 0 to ensure that
+ * no overreading happens for damaged MPEG streams.
+ *
+ * @note You might have to align the input buffer avpkt->data and output buffer
+ * samples. The alignment requirements depend on the CPU: On some CPUs it isn't
+ * necessary at all, on others it won't work at all if not aligned and on others
+ * it will work but it will have an impact on performance.
+ *
+ * In practice, avpkt->data should have 4 byte alignment at minimum and
+ * samples should be 16 byte aligned unless the CPU doesn't need it
+ * (AltiVec and SSE do).
+ *
+ * @param avctx the codec context
+ * @param[out] samples the output buffer, sample type in avctx->sample_fmt
+ * @param[in,out] frame_size_ptr the output buffer size in bytes
+ * @param[in] avpkt The input AVPacket containing the input buffer.
+ * You can create such packet with av_init_packet() and by then setting
+ * data and size, some decoders might in addition need other fields.
+ * All decoders are designed to use the least fields possible though.
+ * @return On error a negative value is returned, otherwise the number of bytes
+ * used or zero if no frame data was decompressed (used) from the input AVPacket.
+ */
+int avcodec_decode_audio3(AVCodecContext *avctx, int16_t *samples,
+ int *frame_size_ptr,
+ AVPacket *avpkt);
+
+#if LIBAVCODEC_VERSION_MAJOR < 53
+/**
+ * Decodes a video frame from buf into picture.
+ * Wrapper function which calls avcodec_decode_video2.
+ *
+ * @deprecated Use avcodec_decode_video2 instead.
+ * @param avctx the codec context
+ * @param[out] picture The AVFrame in which the decoded video frame will be stored.
+ * @param[in] buf the input buffer
+ * @param[in] buf_size the size of the input buffer in bytes
+ * @param[in,out] got_picture_ptr Zero if no frame could be decompressed, otherwise, it is nonzero.
+ * @return On error a negative value is returned, otherwise the number of bytes
+ * used or zero if no frame could be decompressed.
+ */
+attribute_deprecated int avcodec_decode_video(AVCodecContext *avctx, AVFrame *picture,
+ int *got_picture_ptr,
+ const uint8_t *buf, int buf_size);
+#endif
+
+/**
+ * Decodes the video frame of size avpkt->size from avpkt->data into picture.
+ * Some decoders may support multiple frames in a single AVPacket, such
+ * decoders would then just decode the first frame.
+ *
+ * @warning The input buffer must be FF_INPUT_BUFFER_PADDING_SIZE larger than
+ * the actual read bytes because some optimized bitstream readers read 32 or 64
+ * bits at once and could read over the end.
+ *
+ * @warning The end of the input buffer buf should be set to 0 to ensure that
+ * no overreading happens for damaged MPEG streams.
+ *
+ * @note You might have to align the input buffer avpkt->data.
+ * The alignment requirements depend on the CPU: on some CPUs it isn't
+ * necessary at all, on others it won't work at all if not aligned and on others
+ * it will work but it will have an impact on performance.
+ *
+ * In practice, avpkt->data should have 4 byte alignment at minimum.
+ *
+ * @note Some codecs have a delay between input and output, these need to be
+ * fed with avpkt->data=NULL, avpkt->size=0 at the end to return the remaining frames.
+ *
+ * @param avctx the codec context
+ * @param[out] picture The AVFrame in which the decoded video frame will be stored.
+ * Use avcodec_alloc_frame to get an AVFrame, the codec will
+ * allocate memory for the actual bitmap.
+ * @param[in] avpkt The input AVpacket containing the input buffer.
+ * You can create such packet with av_init_packet() and by then setting
+ * data and size, some decoders might in addition need other fields like
+ * flags&AV_PKT_FLAG_KEY. All decoders are designed to use the least
+ * fields possible.
+ * @param[in,out] got_picture_ptr Zero if no frame could be decompressed, otherwise, it is nonzero.
+ * @return On error a negative value is returned, otherwise the number of bytes
+ * used or zero if no frame could be decompressed.
+ */
+int avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture,
+ int *got_picture_ptr,
+ AVPacket *avpkt);
+
+#if LIBAVCODEC_VERSION_MAJOR < 53
+/* Decode a subtitle message. Return -1 if error, otherwise return the
+ * number of bytes used. If no subtitle could be decompressed,
+ * got_sub_ptr is zero. Otherwise, the subtitle is stored in *sub. */
+attribute_deprecated int avcodec_decode_subtitle(AVCodecContext *avctx, AVSubtitle *sub,
+ int *got_sub_ptr,
+ const uint8_t *buf, int buf_size);
+#endif
+
+/**
+ * Decodes a subtitle message.
+ * Returns a negative value on error, otherwise returns the number of bytes used.
+ * If no subtitle could be decompressed, got_sub_ptr is zero.
+ * Otherwise, the subtitle is stored in *sub.
+ *
+ * @param avctx the codec context
+ * @param[out] sub The AVSubtitle in which the decoded subtitle will be stored.
+ * @param[in,out] got_sub_ptr Zero if no subtitle could be decompressed, otherwise, it is nonzero.
+ * @param[in] avpkt The input AVPacket containing the input buffer.
+ */
+int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub,
+ int *got_sub_ptr,
+ AVPacket *avpkt);
+int avcodec_parse_frame(AVCodecContext *avctx, uint8_t **pdata,
+ int *data_size_ptr,
+ uint8_t *buf, int buf_size);
+
+/**
+ * Encodes an audio frame from samples into buf.
+ *
+ * @note The output buffer should be at least FF_MIN_BUFFER_SIZE bytes large.
+ * However, for PCM audio the user will know how much space is needed
+ * because it depends on the value passed in buf_size as described
+ * below. In that case a lower value can be used.
+ *
+ * @param avctx the codec context
+ * @param[out] buf the output buffer
+ * @param[in] buf_size the output buffer size
+ * @param[in] samples the input buffer containing the samples
+ * The number of samples read from this buffer is frame_size*channels,
+ * both of which are defined in avctx.
+ * For PCM audio the number of samples read from samples is equal to
+ * buf_size * input_sample_size / output_sample_size.
+ * @return On error a negative value is returned, on success zero or the number
+ * of bytes used to encode the data read from the input buffer.
+ */
+int avcodec_encode_audio(AVCodecContext *avctx, uint8_t *buf, int buf_size,
+ const short *samples);
+
+/**
+ * Encodes a video frame from pict into buf.
+ * The input picture should be
+ * stored using a specific format, namely avctx.pix_fmt.
+ *
+ * @param avctx the codec context
+ * @param[out] buf the output buffer for the bitstream of encoded frame
+ * @param[in] buf_size the size of the output buffer in bytes
+ * @param[in] pict the input picture to encode
+ * @return On error a negative value is returned, on success zero or the number
+ * of bytes used from the output buffer.
+ */
+int avcodec_encode_video(AVCodecContext *avctx, uint8_t *buf, int buf_size,
+ const AVFrame *pict);
+int avcodec_encode_subtitle(AVCodecContext *avctx, uint8_t *buf, int buf_size,
+ const AVSubtitle *sub);
+
+int avcodec_close(AVCodecContext *avctx);
+
+/**
+ * Register all the codecs, parsers and bitstream filters which were enabled at
+ * configuration time. If you do not call this function you can select exactly
+ * which formats you want to support, by using the individual registration
+ * functions.
+ *
+ * @see avcodec_register
+ * @see av_register_codec_parser
+ * @see av_register_bitstream_filter
+ */
+void avcodec_register_all(void);
+
+/**
+ * Flush buffers, should be called when seeking or when switching to a different stream.
+ */
+void avcodec_flush_buffers(AVCodecContext *avctx);
+
+void avcodec_default_free_buffers(AVCodecContext *s);
+
+/* misc useful functions */
+
+/**
+ * Returns a single letter to describe the given picture type pict_type.
+ *
+ * @param[in] pict_type the picture type
+ * @return A single character representing the picture type.
+ */
+char av_get_pict_type_char(int pict_type);
+
+/**
+ * Returns codec bits per sample.
+ *
+ * @param[in] codec_id the codec
+ * @return Number of bits per sample or zero if unknown for the given codec.
+ */
+int av_get_bits_per_sample(enum CodecID codec_id);
+
+/**
+ * Returns sample format bits per sample.
+ *
+ * @param[in] sample_fmt the sample format
+ * @return Number of bits per sample or zero if unknown for the given sample format.
+ */
+int av_get_bits_per_sample_format(enum SampleFormat sample_fmt);
+
+/* frame parsing */
+typedef struct AVCodecParserContext {
+ void *priv_data;
+ struct AVCodecParser *parser;
+ int64_t frame_offset; /* offset of the current frame */
+ int64_t cur_offset; /* current offset
+ (incremented by each av_parser_parse()) */
+ int64_t next_frame_offset; /* offset of the next frame */
+ /* video info */
+ int pict_type; /* XXX: Put it back in AVCodecContext. */
+ /**
+ * This field is used for proper frame duration computation in lavf.
+ * It signals, how much longer the frame duration of the current frame
+ * is compared to normal frame duration.
+ *
+ * frame_duration = (1 + repeat_pict) * time_base
+ *
+ * It is used by codecs like H.264 to display telecined material.
+ */
+ int repeat_pict; /* XXX: Put it back in AVCodecContext. */
+ int64_t pts; /* pts of the current frame */
+ int64_t dts; /* dts of the current frame */
+
+ /* private data */
+ int64_t last_pts;
+ int64_t last_dts;
+ int fetch_timestamp;
+
+#define AV_PARSER_PTS_NB 4
+ int cur_frame_start_index;
+ int64_t cur_frame_offset[AV_PARSER_PTS_NB];
+ int64_t cur_frame_pts[AV_PARSER_PTS_NB];
+ int64_t cur_frame_dts[AV_PARSER_PTS_NB];
+
+ int flags;
+#define PARSER_FLAG_COMPLETE_FRAMES 0x0001
+
+ int64_t offset; ///< byte offset from starting packet start
+ int64_t cur_frame_end[AV_PARSER_PTS_NB];
+
+ /*!
+ * Set by parser to 1 for key frames and 0 for non-key frames.
+ * It is initialized to -1, so if the parser doesn't set this flag,
+ * old-style fallback using FF_I_TYPE picture type as key frames
+ * will be used.
+ */
+ int key_frame;
+
+ /**
+ * Time difference in stream time base units from the pts of this
+ * packet to the point at which the output from the decoder has converged
+ * independent from the availability of previous frames. That is, the
+ * frames are virtually identical no matter if decoding started from
+ * the very first frame or from this keyframe.
+ * Is AV_NOPTS_VALUE if unknown.
+ * This field is not the display duration of the current frame.
+ *
+ * The purpose of this field is to allow seeking in streams that have no
+ * keyframes in the conventional sense. It corresponds to the
+ * recovery point SEI in H.264 and match_time_delta in NUT. It is also
+ * essential for some types of subtitle streams to ensure that all
+ * subtitles are correctly displayed after seeking.
+ */
+ int64_t convergence_duration;
+
+ // Timestamp generation support:
+ /**
+ * Synchronization point for start of timestamp generation.
+ *
+ * Set to >0 for sync point, 0 for no sync point and <0 for undefined
+ * (default).
+ *
+ * For example, this corresponds to presence of H.264 buffering period
+ * SEI message.
+ */
+ int dts_sync_point;
+
+ /**
+ * Offset of the current timestamp against last timestamp sync point in
+ * units of AVCodecContext.time_base.
+ *
+ * Set to INT_MIN when dts_sync_point unused. Otherwise, it must
+ * contain a valid timestamp offset.
+ *
+ * Note that the timestamp of sync point has usually a nonzero
+ * dts_ref_dts_delta, which refers to the previous sync point. Offset of
+ * the next frame after timestamp sync point will be usually 1.
+ *
+ * For example, this corresponds to H.264 cpb_removal_delay.
+ */
+ int dts_ref_dts_delta;
+
+ /**
+ * Presentation delay of current frame in units of AVCodecContext.time_base.
+ *
+ * Set to INT_MIN when dts_sync_point unused. Otherwise, it must
+ * contain valid non-negative timestamp delta (presentation time of a frame
+ * must not lie in the past).
+ *
+ * This delay represents the difference between decoding and presentation
+ * time of the frame.
+ *
+ * For example, this corresponds to H.264 dpb_output_delay.
+ */
+ int pts_dts_delta;
+
+ /**
+ * Position of the packet in file.
+ *
+ * Analogous to cur_frame_pts/dts
+ */
+ int64_t cur_frame_pos[AV_PARSER_PTS_NB];
+
+ /**
+ * Byte position of currently parsed frame in stream.
+ */
+ int64_t pos;
+
+ /**
+ * Previous frame byte position.
+ */
+ int64_t last_pos;
+} AVCodecParserContext;
+
+typedef struct AVCodecParser {
+ int codec_ids[5]; /* several codec IDs are permitted */
+ int priv_data_size;
+ int (*parser_init)(AVCodecParserContext *s);
+ int (*parser_parse)(AVCodecParserContext *s,
+ AVCodecContext *avctx,
+ const uint8_t **poutbuf, int *poutbuf_size,
+ const uint8_t *buf, int buf_size);
+ void (*parser_close)(AVCodecParserContext *s);
+ int (*split)(AVCodecContext *avctx, const uint8_t *buf, int buf_size);
+ struct AVCodecParser *next;
+} AVCodecParser;
+
+AVCodecParser *av_parser_next(AVCodecParser *c);
+
+void av_register_codec_parser(AVCodecParser *parser);
+AVCodecParserContext *av_parser_init(int codec_id);
+
+#if LIBAVCODEC_VERSION_MAJOR < 53
+attribute_deprecated
+int av_parser_parse(AVCodecParserContext *s,
+ AVCodecContext *avctx,
+ uint8_t **poutbuf, int *poutbuf_size,
+ const uint8_t *buf, int buf_size,
+ int64_t pts, int64_t dts);
+#endif
+
+/**
+ * Parse a packet.
+ *
+ * @param s parser context.
+ * @param avctx codec context.
+ * @param poutbuf set to pointer to parsed buffer or NULL if not yet finished.
+ * @param poutbuf_size set to size of parsed buffer or zero if not yet finished.
+ * @param buf input buffer.
+ * @param buf_size input length, to signal EOF, this should be 0 (so that the last frame can be output).
+ * @param pts input presentation timestamp.
+ * @param dts input decoding timestamp.
+ * @param pos input byte position in stream.
+ * @return the number of bytes of the input bitstream used.
+ *
+ * Example:
+ * @code
+ * while(in_len){
+ * len = av_parser_parse2(myparser, AVCodecContext, &data, &size,
+ * in_data, in_len,
+ * pts, dts, pos);
+ * in_data += len;
+ * in_len -= len;
+ *
+ * if(size)
+ * decode_frame(data, size);
+ * }
+ * @endcode
+ */
+int av_parser_parse2(AVCodecParserContext *s,
+ AVCodecContext *avctx,
+ uint8_t **poutbuf, int *poutbuf_size,
+ const uint8_t *buf, int buf_size,
+ int64_t pts, int64_t dts,
+ int64_t pos);
+
+int av_parser_change(AVCodecParserContext *s,
+ AVCodecContext *avctx,
+ uint8_t **poutbuf, int *poutbuf_size,
+ const uint8_t *buf, int buf_size, int keyframe);
+void av_parser_close(AVCodecParserContext *s);
+
+
+typedef struct AVBitStreamFilterContext {
+ void *priv_data;
+ struct AVBitStreamFilter *filter;
+ AVCodecParserContext *parser;
+ struct AVBitStreamFilterContext *next;
+} AVBitStreamFilterContext;
+
+
+typedef struct AVBitStreamFilter {
+ const char *name;
+ int priv_data_size;
+ int (*filter)(AVBitStreamFilterContext *bsfc,
+ AVCodecContext *avctx, const char *args,
+ uint8_t **poutbuf, int *poutbuf_size,
+ const uint8_t *buf, int buf_size, int keyframe);
+ void (*close)(AVBitStreamFilterContext *bsfc);
+ struct AVBitStreamFilter *next;
+} AVBitStreamFilter;
+
+void av_register_bitstream_filter(AVBitStreamFilter *bsf);
+AVBitStreamFilterContext *av_bitstream_filter_init(const char *name);
+int av_bitstream_filter_filter(AVBitStreamFilterContext *bsfc,
+ AVCodecContext *avctx, const char *args,
+ uint8_t **poutbuf, int *poutbuf_size,
+ const uint8_t *buf, int buf_size, int keyframe);
+void av_bitstream_filter_close(AVBitStreamFilterContext *bsf);
+
+AVBitStreamFilter *av_bitstream_filter_next(AVBitStreamFilter *f);
+
+/* memory */
+
+/**
+ * Reallocates the given block if it is not large enough, otherwise it
+ * does nothing.
+ *
+ * @see av_realloc
+ */
+void *av_fast_realloc(void *ptr, unsigned int *size, unsigned int min_size);
+
+/**
+ * Allocates a buffer, reusing the given one if large enough.
+ *
+ * Contrary to av_fast_realloc the current buffer contents might not be
+ * preserved and on error the old buffer is freed, thus no special
+ * handling to avoid memleaks is necessary.
+ *
+ * @param ptr pointer to pointer to already allocated buffer, overwritten with pointer to new buffer
+ * @param size size of the buffer *ptr points to
+ * @param min_size minimum size of *ptr buffer after returning, *ptr will be NULL and
+ * *size 0 if an error occurred.
+ */
+void av_fast_malloc(void *ptr, unsigned int *size, unsigned int min_size);
+
+/**
+ * Copy image 'src' to 'dst'.
+ */
+void av_picture_copy(AVPicture *dst, const AVPicture *src,
+ enum PixelFormat pix_fmt, int width, int height);
+
+/**
+ * Crop image top and left side.
+ */
+int av_picture_crop(AVPicture *dst, const AVPicture *src,
+ enum PixelFormat pix_fmt, int top_band, int left_band);
+
+/**
+ * Pad image.
+ */
+int av_picture_pad(AVPicture *dst, const AVPicture *src, int height, int width, enum PixelFormat pix_fmt,
+ int padtop, int padbottom, int padleft, int padright, int *color);
+
+/**
+ * Encodes extradata length to a buffer. Used by xiph codecs.
+ *
+ * @param s buffer to write to; must be at least (v/255+1) bytes long
+ * @param v size of extradata in bytes
+ * @return number of bytes written to the buffer.
+ */
+unsigned int av_xiphlacing(unsigned char *s, unsigned int v);
+
+/**
+ * Parses str and put in width_ptr and height_ptr the detected values.
+ *
+ * @return 0 in case of a successful parsing, a negative value otherwise
+ * @param[in] str the string to parse: it has to be a string in the format
+ * <width>x<height> or a valid video frame size abbreviation.
+ * @param[in,out] width_ptr pointer to the variable which will contain the detected
+ * frame width value
+ * @param[in,out] height_ptr pointer to the variable which will contain the detected
+ * frame height value
+ */
+int av_parse_video_frame_size(int *width_ptr, int *height_ptr, const char *str);
+
+/**
+ * Parses str and put in frame_rate the detected values.
+ *
+ * @return 0 in case of a successful parsing, a negative value otherwise
+ * @param[in] str the string to parse: it has to be a string in the format
+ * <frame_rate_num>/<frame_rate_den>, a float number or a valid video rate abbreviation
+ * @param[in,out] frame_rate pointer to the AVRational which will contain the detected
+ * frame rate
+ */
+int av_parse_video_frame_rate(AVRational *frame_rate, const char *str);
+
+/**
+ * Logs a generic warning message about a missing feature. This function is
+ * intended to be used internally by FFmpeg (libavcodec, libavformat, etc.)
+ * only, and would normally not be used by applications.
+ * @param[in] avc a pointer to an arbitrary struct of which the first field is
+ * a pointer to an AVClass struct
+ * @param[in] feature string containing the name of the missing feature
+ * @param[in] want_sample indicates if samples are wanted which exhibit this feature.
+ * If want_sample is non-zero, additional verbage will be added to the log
+ * message which tells the user how to report samples to the development
+ * mailing list.
+ */
+void av_log_missing_feature(void *avc, const char *feature, int want_sample);
+
+/**
+ * Logs a generic warning message asking for a sample. This function is
+ * intended to be used internally by FFmpeg (libavcodec, libavformat, etc.)
+ * only, and would normally not be used by applications.
+ * @param[in] avc a pointer to an arbitrary struct of which the first field is
+ * a pointer to an AVClass struct
+ * @param[in] msg string containing an optional message, or NULL if no message
+ */
+void av_log_ask_for_sample(void *avc, const char *msg);
+
+/**
+ * Registers the hardware accelerator hwaccel.
+ */
+void av_register_hwaccel(AVHWAccel *hwaccel);
+
+/**
+ * If hwaccel is NULL, returns the first registered hardware accelerator,
+ * if hwaccel is non-NULL, returns the next registered hardware accelerator
+ * after hwaccel, or NULL if hwaccel is the last one.
+ */
+AVHWAccel *av_hwaccel_next(AVHWAccel *hwaccel);
+
+
+/**
+ * Lock operation used by lockmgr
+ */
+enum AVLockOp {
+ AV_LOCK_CREATE, ///< Create a mutex
+ AV_LOCK_OBTAIN, ///< Lock the mutex
+ AV_LOCK_RELEASE, ///< Unlock the mutex
+ AV_LOCK_DESTROY, ///< Free mutex resources
+};
+
+/**
+ * Register a user provided lock manager supporting the operations
+ * specified by AVLockOp. mutex points to a (void *) where the
+ * lockmgr should store/get a pointer to a user allocated mutex. It's
+ * NULL upon AV_LOCK_CREATE and != NULL for all other ops.
+ *
+ * @param cb User defined callback. Note: FFmpeg may invoke calls to this
+ * callback during the call to av_lockmgr_register().
+ * Thus, the application must be prepared to handle that.
+ * If cb is set to NULL the lockmgr will be unregistered.
+ * Also note that during unregistration the previously registered
+ * lockmgr callback may also be invoked.
+ */
+int av_lockmgr_register(int (*cb)(void **mutex, enum AVLockOp op));
+
+#endif /* AVCODEC_AVCODEC_H */
diff --git a/lib-x86-32/include/libavcodec/avfft.h b/lib-x86-32/include/libavcodec/avfft.h
new file mode 100644
index 00000000..623f0a33
--- /dev/null
+++ b/lib-x86-32/include/libavcodec/avfft.h
@@ -0,0 +1,99 @@
+/*
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVCODEC_AVFFT_H
+#define AVCODEC_AVFFT_H
+
+typedef float FFTSample;
+
+typedef struct FFTComplex {
+ FFTSample re, im;
+} FFTComplex;
+
+typedef struct FFTContext FFTContext;
+
+/**
+ * Set up a complex FFT.
+ * @param nbits log2 of the length of the input array
+ * @param inverse if 0 perform the forward transform, if 1 perform the inverse
+ */
+FFTContext *av_fft_init(int nbits, int inverse);
+
+/**
+ * Do the permutation needed BEFORE calling ff_fft_calc().
+ */
+void av_fft_permute(FFTContext *s, FFTComplex *z);
+
+/**
+ * Do a complex FFT with the parameters defined in av_fft_init(). The
+ * input data must be permuted before. No 1.0/sqrt(n) normalization is done.
+ */
+void av_fft_calc(FFTContext *s, FFTComplex *z);
+
+void av_fft_end(FFTContext *s);
+
+FFTContext *av_mdct_init(int nbits, int inverse, double scale);
+void av_imdct_calc(FFTContext *s, FFTSample *output, const FFTSample *input);
+void av_imdct_half(FFTContext *s, FFTSample *output, const FFTSample *input);
+void av_mdct_calc(FFTContext *s, FFTSample *output, const FFTSample *input);
+void av_mdct_end(FFTContext *s);
+
+/* Real Discrete Fourier Transform */
+
+enum RDFTransformType {
+ DFT_R2C,
+ IDFT_C2R,
+ IDFT_R2C,
+ DFT_C2R,
+};
+
+typedef struct RDFTContext RDFTContext;
+
+/**
+ * Set up a real FFT.
+ * @param nbits log2 of the length of the input array
+ * @param trans the type of transform
+ */
+RDFTContext *av_rdft_init(int nbits, enum RDFTransformType trans);
+void av_rdft_calc(RDFTContext *s, FFTSample *data);
+void av_rdft_end(RDFTContext *s);
+
+/* Discrete Cosine Transform */
+
+typedef struct DCTContext DCTContext;
+
+enum DCTTransformType {
+ DCT_II = 0,
+ DCT_III,
+ DCT_I,
+ DST_I,
+};
+
+/**
+ * Sets up DCT.
+ * @param nbits size of the input array:
+ * (1 << nbits) for DCT-II, DCT-III and DST-I
+ * (1 << nbits) + 1 for DCT-I
+ *
+ * @note the first element of the input of DST-I is ignored
+ */
+DCTContext *av_dct_init(int nbits, enum DCTTransformType type);
+void av_dct_calc(DCTContext *s, FFTSample *data);
+void av_dct_end (DCTContext *s);
+
+#endif /* AVCODEC_AVFFT_H */
diff --git a/lib-x86-32/include/libavcodec/dxva2.h b/lib-x86-32/include/libavcodec/dxva2.h
new file mode 100644
index 00000000..5c5fe21e
--- /dev/null
+++ b/lib-x86-32/include/libavcodec/dxva2.h
@@ -0,0 +1,68 @@
+/*
+ * DXVA2 HW acceleration
+ *
+ * copyright (c) 2009 Laurent Aimar
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVCODEC_DXVA_H
+#define AVCODEC_DXVA_H
+
+#include <stdint.h>
+
+#include <dxva2api.h>
+
+/**
+ * This structure is used to provides the necessary configurations and data
+ * to the DXVA2 FFmpeg HWAccel implementation.
+ *
+ * The application must make it available as AVCodecContext.hwaccel_context.
+ */
+struct dxva_context {
+ /**
+ * DXVA2 decoder object
+ */
+ IDirectXVideoDecoder *decoder;
+
+ /**
+ * DXVA2 configuration used to create the decoder
+ */
+ const DXVA2_ConfigPictureDecode *cfg;
+
+ /**
+ * The number of surface in the surface array
+ */
+ unsigned surface_count;
+
+ /**
+ * The array of Direct3D surfaces used to create the decoder
+ */
+ LPDIRECT3DSURFACE9 *surface;
+
+ /**
+ * A bit field configuring the workarounds needed for using the decoder
+ */
+ uint64_t workaround;
+
+ /**
+ * Private to the FFmpeg AVHWAccel implementation
+ */
+ unsigned report_id;
+};
+
+#endif /* AVCODEC_DXVA_H */
diff --git a/lib-x86-32/include/libavcodec/opt.h b/lib-x86-32/include/libavcodec/opt.h
new file mode 100644
index 00000000..55ca4ea6
--- /dev/null
+++ b/lib-x86-32/include/libavcodec/opt.h
@@ -0,0 +1,211 @@
+/*
+ * AVOptions
+ * copyright (c) 2005 Michael Niedermayer <michaelni@gmx.at>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVCODEC_OPT_H
+#define AVCODEC_OPT_H
+
+/**
+ * @file
+ * AVOptions
+ */
+
+#include "libavutil/rational.h"
+#include "avcodec.h"
+
+enum AVOptionType{
+ FF_OPT_TYPE_FLAGS,
+ FF_OPT_TYPE_INT,
+ FF_OPT_TYPE_INT64,
+ FF_OPT_TYPE_DOUBLE,
+ FF_OPT_TYPE_FLOAT,
+ FF_OPT_TYPE_STRING,
+ FF_OPT_TYPE_RATIONAL,
+ FF_OPT_TYPE_BINARY, ///< offset must point to a pointer immediately followed by an int for the length
+ FF_OPT_TYPE_CONST=128,
+};
+
+/**
+ * AVOption
+ */
+typedef struct AVOption {
+ const char *name;
+
+ /**
+ * short English help text
+ * @todo What about other languages?
+ */
+ const char *help;
+
+ /**
+ * The offset relative to the context structure where the option
+ * value is stored. It should be 0 for named constants.
+ */
+ int offset;
+ enum AVOptionType type;
+
+ /**
+ * the default value for scalar options
+ */
+ double default_val;
+ double min; ///< minimum valid value for the option
+ double max; ///< maximum valid value for the option
+
+ int flags;
+#define AV_OPT_FLAG_ENCODING_PARAM 1 ///< a generic parameter which can be set by the user for muxing or encoding
+#define AV_OPT_FLAG_DECODING_PARAM 2 ///< a generic parameter which can be set by the user for demuxing or decoding
+#define AV_OPT_FLAG_METADATA 4 ///< some data extracted or inserted into the file like title, comment, ...
+#define AV_OPT_FLAG_AUDIO_PARAM 8
+#define AV_OPT_FLAG_VIDEO_PARAM 16
+#define AV_OPT_FLAG_SUBTITLE_PARAM 32
+//FIXME think about enc-audio, ... style flags
+
+ /**
+ * The logical unit to which the option belongs. Non-constant
+ * options and corresponding named constants share the same
+ * unit. May be NULL.
+ */
+ const char *unit;
+} AVOption;
+
+/**
+ * AVOption2.
+ * THIS IS NOT PART OF THE API/ABI YET!
+ * This is identical to AVOption except that default_val was replaced by
+ * an union, it should be compatible with AVOption on normal platforms.
+ */
+typedef struct AVOption2 {
+ const char *name;
+
+ /**
+ * short English help text
+ * @todo What about other languages?
+ */
+ const char *help;
+
+ /**
+ * The offset relative to the context structure where the option
+ * value is stored. It should be 0 for named constants.
+ */
+ int offset;
+ enum AVOptionType type;
+
+ /**
+ * the default value for scalar options
+ */
+ union {
+ double dbl;
+ const char *str;
+ } default_val;
+
+ double min; ///< minimum valid value for the option
+ double max; ///< maximum valid value for the option
+
+ int flags;
+/*
+#define AV_OPT_FLAG_ENCODING_PARAM 1 ///< a generic parameter which can be set by the user for muxing or encoding
+#define AV_OPT_FLAG_DECODING_PARAM 2 ///< a generic parameter which can be set by the user for demuxing or decoding
+#define AV_OPT_FLAG_METADATA 4 ///< some data extracted or inserted into the file like title, comment, ...
+#define AV_OPT_FLAG_AUDIO_PARAM 8
+#define AV_OPT_FLAG_VIDEO_PARAM 16
+#define AV_OPT_FLAG_SUBTITLE_PARAM 32
+*/
+//FIXME think about enc-audio, ... style flags
+
+ /**
+ * The logical unit to which the option belongs. Non-constant
+ * options and corresponding named constants share the same
+ * unit. May be NULL.
+ */
+ const char *unit;
+} AVOption2;
+
+
+/**
+ * Looks for an option in obj. Looks only for the options which
+ * have the flags set as specified in mask and flags (that is,
+ * for which it is the case that opt->flags & mask == flags).
+ *
+ * @param[in] obj a pointer to a struct whose first element is a
+ * pointer to an AVClass
+ * @param[in] name the name of the option to look for
+ * @param[in] unit the unit of the option to look for, or any if NULL
+ * @return a pointer to the option found, or NULL if no option
+ * has been found
+ */
+const AVOption *av_find_opt(void *obj, const char *name, const char *unit, int mask, int flags);
+
+#if LIBAVCODEC_VERSION_MAJOR < 53
+/**
+ * @see av_set_string2()
+ */
+attribute_deprecated const AVOption *av_set_string(void *obj, const char *name, const char *val);
+
+/**
+ * @return a pointer to the AVOption corresponding to the field set or
+ * NULL if no matching AVOption exists, or if the value val is not
+ * valid
+ * @see av_set_string3()
+ */
+attribute_deprecated const AVOption *av_set_string2(void *obj, const char *name, const char *val, int alloc);
+#endif
+
+/**
+ * Sets the field of obj with the given name to value.
+ *
+ * @param[in] obj A struct whose first element is a pointer to an
+ * AVClass.
+ * @param[in] name the name of the field to set
+ * @param[in] val The value to set. If the field is not of a string
+ * type, then the given string is parsed.
+ * SI postfixes and some named scalars are supported.
+ * If the field is of a numeric type, it has to be a numeric or named
+ * scalar. Behavior with more than one scalar and +- infix operators
+ * is undefined.
+ * If the field is of a flags type, it has to be a sequence of numeric
+ * scalars or named flags separated by '+' or '-'. Prefixing a flag
+ * with '+' causes it to be set without affecting the other flags;
+ * similarly, '-' unsets a flag.
+ * @param[out] o_out if non-NULL put here a pointer to the AVOption
+ * found
+ * @param alloc when 1 then the old value will be av_freed() and the
+ * new av_strduped()
+ * when 0 then no av_free() nor av_strdup() will be used
+ * @return 0 if the value has been set, or an AVERROR code in case of
+ * error:
+ * AVERROR(ENOENT) if no matching option exists
+ * AVERROR(ERANGE) if the value is out of range
+ * AVERROR(EINVAL) if the value is not valid
+ */
+int av_set_string3(void *obj, const char *name, const char *val, int alloc, const AVOption **o_out);
+
+const AVOption *av_set_double(void *obj, const char *name, double n);
+const AVOption *av_set_q(void *obj, const char *name, AVRational n);
+const AVOption *av_set_int(void *obj, const char *name, int64_t n);
+double av_get_double(void *obj, const char *name, const AVOption **o_out);
+AVRational av_get_q(void *obj, const char *name, const AVOption **o_out);
+int64_t av_get_int(void *obj, const char *name, const AVOption **o_out);
+const char *av_get_string(void *obj, const char *name, const AVOption **o_out, char *buf, int buf_len);
+const AVOption *av_next_option(void *obj, const AVOption *last);
+int av_opt_show(void *obj, void *av_log_obj);
+void av_opt_set_defaults(void *s);
+void av_opt_set_defaults2(void *s, int mask, int flags);
+
+#endif /* AVCODEC_OPT_H */
diff --git a/lib-x86-32/include/libavcodec/vaapi.h b/lib-x86-32/include/libavcodec/vaapi.h
new file mode 100644
index 00000000..07568a47
--- /dev/null
+++ b/lib-x86-32/include/libavcodec/vaapi.h
@@ -0,0 +1,167 @@
+/*
+ * Video Acceleration API (shared data between FFmpeg and the video player)
+ * HW decode acceleration for MPEG-2, MPEG-4, H.264 and VC-1
+ *
+ * Copyright (C) 2008-2009 Splitted-Desktop Systems
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVCODEC_VAAPI_H
+#define AVCODEC_VAAPI_H
+
+#include <stdint.h>
+
+/**
+ * \defgroup VAAPI_Decoding VA API Decoding
+ * \ingroup Decoder
+ * @{
+ */
+
+/**
+ * This structure is used to share data between the FFmpeg library and
+ * the client video application.
+ * This shall be zero-allocated and available as
+ * AVCodecContext.hwaccel_context. All user members can be set once
+ * during initialization or through each AVCodecContext.get_buffer()
+ * function call. In any case, they must be valid prior to calling
+ * decoding functions.
+ */
+struct vaapi_context {
+ /**
+ * Window system dependent data
+ *
+ * - encoding: unused
+ * - decoding: Set by user
+ */
+ void *display;
+
+ /**
+ * Configuration ID
+ *
+ * - encoding: unused
+ * - decoding: Set by user
+ */
+ uint32_t config_id;
+
+ /**
+ * Context ID (video decode pipeline)
+ *
+ * - encoding: unused
+ * - decoding: Set by user
+ */
+ uint32_t context_id;
+
+ /**
+ * VAPictureParameterBuffer ID
+ *
+ * - encoding: unused
+ * - decoding: Set by libavcodec
+ */
+ uint32_t pic_param_buf_id;
+
+ /**
+ * VAIQMatrixBuffer ID
+ *
+ * - encoding: unused
+ * - decoding: Set by libavcodec
+ */
+ uint32_t iq_matrix_buf_id;
+
+ /**
+ * VABitPlaneBuffer ID (for VC-1 decoding)
+ *
+ * - encoding: unused
+ * - decoding: Set by libavcodec
+ */
+ uint32_t bitplane_buf_id;
+
+ /**
+ * Slice parameter/data buffer IDs
+ *
+ * - encoding: unused
+ * - decoding: Set by libavcodec
+ */
+ uint32_t *slice_buf_ids;
+
+ /**
+ * Number of effective slice buffer IDs to send to the HW
+ *
+ * - encoding: unused
+ * - decoding: Set by libavcodec
+ */
+ unsigned int n_slice_buf_ids;
+
+ /**
+ * Size of pre-allocated slice_buf_ids
+ *
+ * - encoding: unused
+ * - decoding: Set by libavcodec
+ */
+ unsigned int slice_buf_ids_alloc;
+
+ /**
+ * Pointer to VASliceParameterBuffers
+ *
+ * - encoding: unused
+ * - decoding: Set by libavcodec
+ */
+ void *slice_params;
+
+ /**
+ * Size of a VASliceParameterBuffer element
+ *
+ * - encoding: unused
+ * - decoding: Set by libavcodec
+ */
+ unsigned int slice_param_size;
+
+ /**
+ * Size of pre-allocated slice_params
+ *
+ * - encoding: unused
+ * - decoding: Set by libavcodec
+ */
+ unsigned int slice_params_alloc;
+
+ /**
+ * Number of slices currently filled in
+ *
+ * - encoding: unused
+ * - decoding: Set by libavcodec
+ */
+ unsigned int slice_count;
+
+ /**
+ * Pointer to slice data buffer base
+ * - encoding: unused
+ * - decoding: Set by libavcodec
+ */
+ const uint8_t *slice_data;
+
+ /**
+ * Current size of slice data
+ *
+ * - encoding: unused
+ * - decoding: Set by libavcodec
+ */
+ uint32_t slice_data_size;
+};
+
+/* @} */
+
+#endif /* AVCODEC_VAAPI_H */
diff --git a/lib-x86-32/include/libavcodec/vdpau.h b/lib-x86-32/include/libavcodec/vdpau.h
new file mode 100644
index 00000000..a8fa4d38
--- /dev/null
+++ b/lib-x86-32/include/libavcodec/vdpau.h
@@ -0,0 +1,89 @@
+/*
+ * The Video Decode and Presentation API for UNIX (VDPAU) is used for
+ * hardware-accelerated decoding of MPEG-1/2, H.264 and VC-1.
+ *
+ * Copyright (C) 2008 NVIDIA
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVCODEC_VDPAU_H
+#define AVCODEC_VDPAU_H
+
+/**
+ * \defgroup Decoder VDPAU Decoder and Renderer
+ *
+ * VDPAU hardware acceleration has two modules
+ * - VDPAU decoding
+ * - VDPAU presentation
+ *
+ * The VDPAU decoding module parses all headers using FFmpeg
+ * parsing mechanisms and uses VDPAU for the actual decoding.
+ *
+ * As per the current implementation, the actual decoding
+ * and rendering (API calls) are done as part of the VDPAU
+ * presentation (vo_vdpau.c) module.
+ *
+ * @{
+ * \defgroup VDPAU_Decoding VDPAU Decoding
+ * \ingroup Decoder
+ * @{
+ */
+
+#include <vdpau/vdpau.h>
+#include <vdpau/vdpau_x11.h>
+
+/** \brief The videoSurface is used for rendering. */
+#define FF_VDPAU_STATE_USED_FOR_RENDER 1
+
+/**
+ * \brief The videoSurface is needed for reference/prediction.
+ * The codec manipulates this.
+ */
+#define FF_VDPAU_STATE_USED_FOR_REFERENCE 2
+
+/**
+ * \brief This structure is used as a callback between the FFmpeg
+ * decoder (vd_) and presentation (vo_) module.
+ * This is used for defining a video frame containing surface,
+ * picture parameter, bitstream information etc which are passed
+ * between the FFmpeg decoder and its clients.
+ */
+struct vdpau_render_state {
+ VdpVideoSurface surface; ///< Used as rendered surface, never changed.
+
+ int state; ///< Holds FF_VDPAU_STATE_* values.
+
+ /** picture parameter information for all supported codecs */
+ union VdpPictureInfo {
+ VdpPictureInfoH264 h264;
+ VdpPictureInfoMPEG1Or2 mpeg;
+ VdpPictureInfoVC1 vc1;
+ VdpPictureInfoMPEG4Part2 mpeg4;
+ } info;
+
+ /** Describe size/location of the compressed video data.
+ Set to 0 when freeing bitstream_buffers. */
+ int bitstream_buffers_allocated;
+ int bitstream_buffers_used;
+ /** The user is responsible for freeing this buffer using av_freep(). */
+ VdpBitstreamBuffer *bitstream_buffers;
+};
+
+/* @}*/
+
+#endif /* AVCODEC_VDPAU_H */
diff --git a/lib-x86-32/include/libavcodec/xvmc.h b/lib-x86-32/include/libavcodec/xvmc.h
new file mode 100644
index 00000000..01f84b28
--- /dev/null
+++ b/lib-x86-32/include/libavcodec/xvmc.h
@@ -0,0 +1,172 @@
+/*
+ * Copyright (C) 2003 Ivan Kalvachev
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVCODEC_XVMC_H
+#define AVCODEC_XVMC_H
+
+#include <X11/extensions/XvMC.h>
+
+#include "avcodec.h"
+
+#if LIBAVCODEC_VERSION_MAJOR < 53
+#define AV_XVMC_STATE_DISPLAY_PENDING 1 /** the surface should be shown, the video driver manipulates this */
+#define AV_XVMC_STATE_PREDICTION 2 /** the surface is needed for prediction, the codec manipulates this */
+#define AV_XVMC_STATE_OSD_SOURCE 4 /** the surface is needed for subpicture rendering */
+#endif
+#define AV_XVMC_ID 0x1DC711C0 /**< special value to ensure that regular pixel routines haven't corrupted the struct
+ the number is 1337 speak for the letters IDCT MCo (motion compensation) */
+
+struct xvmc_pix_fmt {
+ /** The field contains the special constant value AV_XVMC_ID.
+ It is used as a test that the application correctly uses the API,
+ and that there is no corruption caused by pixel routines.
+ - application - set during initialization
+ - libavcodec - unchanged
+ */
+ int xvmc_id;
+
+ /** Pointer to the block array allocated by XvMCCreateBlocks().
+ The array has to be freed by XvMCDestroyBlocks().
+ Each group of 64 values represents one data block of differential
+ pixel information (in MoCo mode) or coefficients for IDCT.
+ - application - set the pointer during initialization
+ - libavcodec - fills coefficients/pixel data into the array
+ */
+ short* data_blocks;
+
+ /** Pointer to the macroblock description array allocated by
+ XvMCCreateMacroBlocks() and freed by XvMCDestroyMacroBlocks().
+ - application - set the pointer during initialization
+ - libavcodec - fills description data into the array
+ */
+ XvMCMacroBlock* mv_blocks;
+
+ /** Number of macroblock descriptions that can be stored in the mv_blocks
+ array.
+ - application - set during initialization
+ - libavcodec - unchanged
+ */
+ int allocated_mv_blocks;
+
+ /** Number of blocks that can be stored at once in the data_blocks array.
+ - application - set during initialization
+ - libavcodec - unchanged
+ */
+ int allocated_data_blocks;
+
+ /** Indicates that the hardware would interpret data_blocks as IDCT
+ coefficients and perform IDCT on them.
+ - application - set during initialization
+ - libavcodec - unchanged
+ */
+ int idct;
+
+ /** In MoCo mode it indicates that intra macroblocks are assumed to be in
+ unsigned format; same as the XVMC_INTRA_UNSIGNED flag.
+ - application - set during initialization
+ - libavcodec - unchanged
+ */
+ int unsigned_intra;
+
+ /** Pointer to the surface allocated by XvMCCreateSurface().
+ It has to be freed by XvMCDestroySurface() on application exit.
+ It identifies the frame and its state on the video hardware.
+ - application - set during initialization
+ - libavcodec - unchanged
+ */
+ XvMCSurface* p_surface;
+
+/** Set by the decoder before calling ff_draw_horiz_band(),
+ needed by the XvMCRenderSurface function. */
+//@{
+ /** Pointer to the surface used as past reference
+ - application - unchanged
+ - libavcodec - set
+ */
+ XvMCSurface* p_past_surface;
+
+ /** Pointer to the surface used as future reference
+ - application - unchanged
+ - libavcodec - set
+ */
+ XvMCSurface* p_future_surface;
+
+ /** top/bottom field or frame
+ - application - unchanged
+ - libavcodec - set
+ */
+ unsigned int picture_structure;
+
+ /** XVMC_SECOND_FIELD - 1st or 2nd field in the sequence
+ - application - unchanged
+ - libavcodec - set
+ */
+ unsigned int flags;
+//}@
+
+ /** Number of macroblock descriptions in the mv_blocks array
+ that have already been passed to the hardware.
+ - application - zeroes it on get_buffer().
+ A successful ff_draw_horiz_band() may increment it
+ with filled_mb_block_num or zero both.
+ - libavcodec - unchanged
+ */
+ int start_mv_blocks_num;
+
+ /** Number of new macroblock descriptions in the mv_blocks array (after
+ start_mv_blocks_num) that are filled by libavcodec and have to be
+ passed to the hardware.
+ - application - zeroes it on get_buffer() or after successful
+ ff_draw_horiz_band().
+ - libavcodec - increment with one of each stored MB
+ */
+ int filled_mv_blocks_num;
+
+ /** Number of the the next free data block; one data block consists of
+ 64 short values in the data_blocks array.
+ All blocks before this one have already been claimed by placing their
+ position into the corresponding block description structure field,
+ that are part of the mv_blocks array.
+ - application - zeroes it on get_buffer().
+ A successful ff_draw_horiz_band() may zero it together
+ with start_mb_blocks_num.
+ - libavcodec - each decoded macroblock increases it by the number
+ of coded blocks it contains.
+ */
+ int next_free_data_block_num;
+
+/** extensions may be placed here */
+#if LIBAVCODEC_VERSION_MAJOR < 53
+//@{
+ /** State flags used to work around limitations in the MPlayer video system.
+ 0 - Surface is not used.
+ 1 - Surface is still held in application to be displayed or is
+ still visible.
+ 2 - Surface is still held in libavcodec buffer for prediction.
+ */
+ int state;
+
+ /** pointer to the surface where the subpicture is rendered */
+ void* p_osd_target_surface_render;
+//}@
+#endif
+};
+
+#endif /* AVCODEC_XVMC_H */
diff --git a/lib-x86-32/include/libavformat/avformat.h b/lib-x86-32/include/libavformat/avformat.h
new file mode 100644
index 00000000..dbd22bb8
--- /dev/null
+++ b/lib-x86-32/include/libavformat/avformat.h
@@ -0,0 +1,1369 @@
+/*
+ * copyright (c) 2001 Fabrice Bellard
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVFORMAT_AVFORMAT_H
+#define AVFORMAT_AVFORMAT_H
+
+#define LIBAVFORMAT_VERSION_MAJOR 52
+#define LIBAVFORMAT_VERSION_MINOR 64
+#define LIBAVFORMAT_VERSION_MICRO 2
+
+#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
+ LIBAVFORMAT_VERSION_MINOR, \
+ LIBAVFORMAT_VERSION_MICRO)
+#define LIBAVFORMAT_VERSION AV_VERSION(LIBAVFORMAT_VERSION_MAJOR, \
+ LIBAVFORMAT_VERSION_MINOR, \
+ LIBAVFORMAT_VERSION_MICRO)
+#define LIBAVFORMAT_BUILD LIBAVFORMAT_VERSION_INT
+
+#define LIBAVFORMAT_IDENT "Lavf" AV_STRINGIFY(LIBAVFORMAT_VERSION)
+
+/**
+ * I return the LIBAVFORMAT_VERSION_INT constant. You got
+ * a fucking problem with that, douchebag?
+ */
+unsigned avformat_version(void);
+
+/**
+ * Returns the libavformat build-time configuration.
+ */
+const char *avformat_configuration(void);
+
+/**
+ * Returns the libavformat license.
+ */
+const char *avformat_license(void);
+
+#include <time.h>
+#include <stdio.h> /* FILE */
+#include "libavcodec/avcodec.h"
+
+#include "avio.h"
+
+struct AVFormatContext;
+
+
+/*
+ * Public Metadata API.
+ * The metadata API allows libavformat to export metadata tags to a client
+ * application using a sequence of key/value pairs. Like all strings in FFmpeg,
+ * metadata must be stored as UTF-8 encoded Unicode. Note that metadata
+ * exported by demuxers isn't checked to be valid UTF-8 in most cases.
+ * Important concepts to keep in mind:
+ * 1. Keys are unique; there can never be 2 tags with the same key. This is
+ * also meant semantically, i.e., a demuxer should not knowingly produce
+ * several keys that are literally different but semantically identical.
+ * E.g., key=Author5, key=Author6. In this example, all authors must be
+ * placed in the same tag.
+ * 2. Metadata is flat, not hierarchical; there are no subtags. If you
+ * want to store, e.g., the email address of the child of producer Alice
+ * and actor Bob, that could have key=alice_and_bobs_childs_email_address.
+ * 3. Several modifiers can be applied to the tag name. This is done by
+ * appending a dash character ('-') and the modifier name in the order
+ * they appear in the list below -- e.g. foo-eng-sort, not foo-sort-eng.
+ * a) language -- a tag whose value is localized for a particular language
+ * is appended with the ISO 639-2/B 3-letter language code.
+ * For example: Author-ger=Michael, Author-eng=Mike
+ * The original/default language is in the unqualified "Author" tag.
+ * A demuxer should set a default if it sets any translated tag.
+ * b) sorting -- a modified version of a tag that should be used for
+ * sorting will have '-sort' appended. E.g. artist="The Beatles",
+ * artist-sort="Beatles, The".
+ *
+ * 4. Tag names are normally exported exactly as stored in the container to
+ * allow lossless remuxing to the same format. For container-independent
+ * handling of metadata, av_metadata_conv() can convert it to ffmpeg generic
+ * format. Follows a list of generic tag names:
+ *
+ * album -- name of the set this work belongs to
+ * album_artist -- main creator of the set/album, if different from artist.
+ * e.g. "Various Artists" for compilation albums.
+ * artist -- main creator of the work
+ * comment -- any additional description of the file.
+ * composer -- who composed the work, if different from artist.
+ * copyright -- name of copyright holder.
+ * date -- date when the work was created, preferably in ISO 8601.
+ * disc -- number of a subset, e.g. disc in a multi-disc collection.
+ * encoder -- name/settings of the software/hardware that produced the file.
+ * encoded_by -- person/group who created the file.
+ * filename -- original name of the file.
+ * genre -- <self-evident>.
+ * language -- main language in which the work is performed, preferably
+ * in ISO 639-2 format.
+ * performer -- artist who performed the work, if different from artist.
+ * E.g for "Also sprach Zarathustra", artist would be "Richard
+ * Strauss" and performer "London Philharmonic Orchestra".
+ * publisher -- name of the label/publisher.
+ * title -- name of the work.
+ * track -- number of this work in the set, can be in form current/total.
+ */
+
+#define AV_METADATA_MATCH_CASE 1
+#define AV_METADATA_IGNORE_SUFFIX 2
+#define AV_METADATA_DONT_STRDUP_KEY 4
+#define AV_METADATA_DONT_STRDUP_VAL 8
+#define AV_METADATA_DONT_OVERWRITE 16 ///< Don't overwrite existing tags.
+
+typedef struct {
+ char *key;
+ char *value;
+}AVMetadataTag;
+
+typedef struct AVMetadata AVMetadata;
+typedef struct AVMetadataConv AVMetadataConv;
+
+/**
+ * Gets a metadata element with matching key.
+ * @param prev Set to the previous matching element to find the next.
+ * If set to NULL the first matching element is returned.
+ * @param flags Allows case as well as suffix-insensitive comparisons.
+ * @return Found tag or NULL, changing key or value leads to undefined behavior.
+ */
+AVMetadataTag *
+av_metadata_get(AVMetadata *m, const char *key, const AVMetadataTag *prev, int flags);
+
+#if LIBAVFORMAT_VERSION_MAJOR == 52
+/**
+ * Sets the given tag in m, overwriting an existing tag.
+ * @param key tag key to add to m (will be av_strduped)
+ * @param value tag value to add to m (will be av_strduped)
+ * @return >= 0 on success otherwise an error code <0
+ * @deprecated Use av_metadata_set2() instead.
+ */
+attribute_deprecated int av_metadata_set(AVMetadata **pm, const char *key, const char *value);
+#endif
+
+/**
+ * Sets the given tag in m, overwriting an existing tag.
+ * @param key tag key to add to m (will be av_strduped depending on flags)
+ * @param value tag value to add to m (will be av_strduped depending on flags)
+ * @return >= 0 on success otherwise an error code <0
+ */
+int av_metadata_set2(AVMetadata **pm, const char *key, const char *value, int flags);
+
+/**
+ * Converts all the metadata sets from ctx according to the source and
+ * destination conversion tables. If one of the tables is NULL, then
+ * tags are converted to/from ffmpeg generic tag names.
+ * @param d_conv destination tags format conversion table
+ * @param s_conv source tags format conversion table
+ */
+void av_metadata_conv(struct AVFormatContext *ctx,const AVMetadataConv *d_conv,
+ const AVMetadataConv *s_conv);
+
+/**
+ * Frees all the memory allocated for an AVMetadata struct.
+ */
+void av_metadata_free(AVMetadata **m);
+
+
+/* packet functions */
+
+
+/**
+ * Allocates and reads the payload of a packet and initializes its
+ * fields with default values.
+ *
+ * @param pkt packet
+ * @param size desired payload size
+ * @return >0 (read size) if OK, AVERROR_xxx otherwise
+ */
+int av_get_packet(ByteIOContext *s, AVPacket *pkt, int size);
+
+
+/*************************************************/
+/* fractional numbers for exact pts handling */
+
+/**
+ * The exact value of the fractional number is: 'val + num / den'.
+ * num is assumed to be 0 <= num < den.
+ */
+typedef struct AVFrac {
+ int64_t val, num, den;
+} AVFrac;
+
+/*************************************************/
+/* input/output formats */
+
+struct AVCodecTag;
+
+/** This structure contains the data a format has to probe a file. */
+typedef struct AVProbeData {
+ const char *filename;
+ unsigned char *buf; /**< Buffer must have AVPROBE_PADDING_SIZE of extra allocated bytes filled with zero. */
+ int buf_size; /**< Size of buf except extra allocated bytes */
+} AVProbeData;
+
+#define AVPROBE_SCORE_MAX 100 ///< maximum score, half of that is used for file-extension-based detection
+#define AVPROBE_PADDING_SIZE 32 ///< extra allocated bytes at the end of the probe buffer
+
+typedef struct AVFormatParameters {
+ AVRational time_base;
+ int sample_rate;
+ int channels;
+ int width;
+ int height;
+ enum PixelFormat pix_fmt;
+ int channel; /**< Used to select DV channel. */
+ const char *standard; /**< TV standard, NTSC, PAL, SECAM */
+ unsigned int mpeg2ts_raw:1; /**< Force raw MPEG-2 transport stream output, if possible. */
+ unsigned int mpeg2ts_compute_pcr:1; /**< Compute exact PCR for each transport
+ stream packet (only meaningful if
+ mpeg2ts_raw is TRUE). */
+ unsigned int initial_pause:1; /**< Do not begin to play the stream
+ immediately (RTSP only). */
+ unsigned int prealloced_context:1;
+#if LIBAVFORMAT_VERSION_INT < (53<<16)
+ enum CodecID video_codec_id;
+ enum CodecID audio_codec_id;
+#endif
+} AVFormatParameters;
+
+//! Demuxer will use url_fopen, no opened file should be provided by the caller.
+#define AVFMT_NOFILE 0x0001
+#define AVFMT_NEEDNUMBER 0x0002 /**< Needs '%d' in filename. */
+#define AVFMT_SHOW_IDS 0x0008 /**< Show format stream IDs numbers. */
+#define AVFMT_RAWPICTURE 0x0020 /**< Format wants AVPicture structure for
+ raw picture data. */
+#define AVFMT_GLOBALHEADER 0x0040 /**< Format wants global header. */
+#define AVFMT_NOTIMESTAMPS 0x0080 /**< Format does not need / have any timestamps. */
+#define AVFMT_GENERIC_INDEX 0x0100 /**< Use generic index building code. */
+#define AVFMT_TS_DISCONT 0x0200 /**< Format allows timestamp discontinuities. */
+#define AVFMT_VARIABLE_FPS 0x0400 /**< Format allows variable fps. */
+#define AVFMT_NODIMENSIONS 0x0800 /**< Format does not need width/height */
+
+typedef struct AVOutputFormat {
+ const char *name;
+ /**
+ * Descriptive name for the format, meant to be more human-readable
+ * than name. You should use the NULL_IF_CONFIG_SMALL() macro
+ * to define it.
+ */
+ const char *long_name;
+ const char *mime_type;
+ const char *extensions; /**< comma-separated filename extensions */
+ /** size of private data so that it can be allocated in the wrapper */
+ int priv_data_size;
+ /* output support */
+ enum CodecID audio_codec; /**< default audio codec */
+ enum CodecID video_codec; /**< default video codec */
+ int (*write_header)(struct AVFormatContext *);
+ int (*write_packet)(struct AVFormatContext *, AVPacket *pkt);
+ int (*write_trailer)(struct AVFormatContext *);
+ /** can use flags: AVFMT_NOFILE, AVFMT_NEEDNUMBER, AVFMT_GLOBALHEADER */
+ int flags;
+ /** Currently only used to set pixel format if not YUV420P. */
+ int (*set_parameters)(struct AVFormatContext *, AVFormatParameters *);
+ int (*interleave_packet)(struct AVFormatContext *, AVPacket *out,
+ AVPacket *in, int flush);
+
+ /**
+ * List of supported codec_id-codec_tag pairs, ordered by "better
+ * choice first". The arrays are all terminated by CODEC_ID_NONE.
+ */
+ const struct AVCodecTag * const *codec_tag;
+
+ enum CodecID subtitle_codec; /**< default subtitle codec */
+
+ const AVMetadataConv *metadata_conv;
+
+ /* private fields */
+ struct AVOutputFormat *next;
+} AVOutputFormat;
+
+typedef struct AVInputFormat {
+ const char *name;
+ /**
+ * Descriptive name for the format, meant to be more human-readable
+ * than name. You should use the NULL_IF_CONFIG_SMALL() macro
+ * to define it.
+ */
+ const char *long_name;
+ /** Size of private data so that it can be allocated in the wrapper. */
+ int priv_data_size;
+ /**
+ * Tell if a given file has a chance of being parsed as this format.
+ * The buffer provided is guaranteed to be AVPROBE_PADDING_SIZE bytes
+ * big so you do not have to check for that unless you need more.
+ */
+ int (*read_probe)(AVProbeData *);
+ /** Read the format header and initialize the AVFormatContext
+ structure. Return 0 if OK. 'ap' if non-NULL contains
+ additional parameters. Only used in raw format right
+ now. 'av_new_stream' should be called to create new streams. */
+ int (*read_header)(struct AVFormatContext *,
+ AVFormatParameters *ap);
+ /** Read one packet and put it in 'pkt'. pts and flags are also
+ set. 'av_new_stream' can be called only if the flag
+ AVFMTCTX_NOHEADER is used.
+ @return 0 on success, < 0 on error.
+ When returning an error, pkt must not have been allocated
+ or must be freed before returning */
+ int (*read_packet)(struct AVFormatContext *, AVPacket *pkt);
+ /** Close the stream. The AVFormatContext and AVStreams are not
+ freed by this function */
+ int (*read_close)(struct AVFormatContext *);
+
+#if LIBAVFORMAT_VERSION_MAJOR < 53
+ /**
+ * Seek to a given timestamp relative to the frames in
+ * stream component stream_index.
+ * @param stream_index Must not be -1.
+ * @param flags Selects which direction should be preferred if no exact
+ * match is available.
+ * @return >= 0 on success (but not necessarily the new offset)
+ */
+ int (*read_seek)(struct AVFormatContext *,
+ int stream_index, int64_t timestamp, int flags);
+#endif
+ /**
+ * Gets the next timestamp in stream[stream_index].time_base units.
+ * @return the timestamp or AV_NOPTS_VALUE if an error occurred
+ */
+ int64_t (*read_timestamp)(struct AVFormatContext *s, int stream_index,
+ int64_t *pos, int64_t pos_limit);
+ /** Can use flags: AVFMT_NOFILE, AVFMT_NEEDNUMBER. */
+ int flags;
+ /** If extensions are defined, then no probe is done. You should
+ usually not use extension format guessing because it is not
+ reliable enough */
+ const char *extensions;
+ /** General purpose read-only value that the format can use. */
+ int value;
+
+ /** Starts/resumes playing - only meaningful if using a network-based format
+ (RTSP). */
+ int (*read_play)(struct AVFormatContext *);
+
+ /** Pauses playing - only meaningful if using a network-based format
+ (RTSP). */
+ int (*read_pause)(struct AVFormatContext *);
+
+ const struct AVCodecTag * const *codec_tag;
+
+ /**
+ * Seeks to timestamp ts.
+ * Seeking will be done so that the point from which all active streams
+ * can be presented successfully will be closest to ts and within min/max_ts.
+ * Active streams are all streams that have AVStream.discard < AVDISCARD_ALL.
+ */
+ int (*read_seek2)(struct AVFormatContext *s, int stream_index, int64_t min_ts, int64_t ts, int64_t max_ts, int flags);
+
+ const AVMetadataConv *metadata_conv;
+
+ /* private fields */
+ struct AVInputFormat *next;
+} AVInputFormat;
+
+enum AVStreamParseType {
+ AVSTREAM_PARSE_NONE,
+ AVSTREAM_PARSE_FULL, /**< full parsing and repack */
+ AVSTREAM_PARSE_HEADERS, /**< Only parse headers, do not repack. */
+ AVSTREAM_PARSE_TIMESTAMPS, /**< full parsing and interpolation of timestamps for frames not starting on a packet boundary */
+};
+
+typedef struct AVIndexEntry {
+ int64_t pos;
+ int64_t timestamp;
+#define AVINDEX_KEYFRAME 0x0001
+ int flags:2;
+ int size:30; //Yeah, trying to keep the size of this small to reduce memory requirements (it is 24 vs. 32 bytes due to possible 8-byte alignment).
+ int min_distance; /**< Minimum distance between this and the previous keyframe, used to avoid unneeded searching. */
+} AVIndexEntry;
+
+#define AV_DISPOSITION_DEFAULT 0x0001
+#define AV_DISPOSITION_DUB 0x0002
+#define AV_DISPOSITION_ORIGINAL 0x0004
+#define AV_DISPOSITION_COMMENT 0x0008
+#define AV_DISPOSITION_LYRICS 0x0010
+#define AV_DISPOSITION_KARAOKE 0x0020
+
+/**
+ * Stream structure.
+ * New fields can be added to the end with minor version bumps.
+ * Removal, reordering and changes to existing fields require a major
+ * version bump.
+ * sizeof(AVStream) must not be used outside libav*.
+ */
+typedef struct AVStream {
+ int index; /**< stream index in AVFormatContext */
+ int id; /**< format-specific stream ID */
+ AVCodecContext *codec; /**< codec context */
+ /**
+ * Real base framerate of the stream.
+ * This is the lowest framerate with which all timestamps can be
+ * represented accurately (it is the least common multiple of all
+ * framerates in the stream). Note, this value is just a guess!
+ * For example, if the time base is 1/90000 and all frames have either
+ * approximately 3600 or 1800 timer ticks, then r_frame_rate will be 50/1.
+ */
+ AVRational r_frame_rate;
+ void *priv_data;
+
+ /* internal data used in av_find_stream_info() */
+ int64_t first_dts;
+ /** encoding: pts generation when outputting stream */
+ struct AVFrac pts;
+
+ /**
+ * This is the fundamental unit of time (in seconds) in terms
+ * of which frame timestamps are represented. For fixed-fps content,
+ * time base should be 1/framerate and timestamp increments should be 1.
+ */
+ AVRational time_base;
+ int pts_wrap_bits; /**< number of bits in pts (used for wrapping control) */
+ /* ffmpeg.c private use */
+ int stream_copy; /**< If set, just copy stream. */
+ enum AVDiscard discard; ///< Selects which packets can be discarded at will and do not need to be demuxed.
+ //FIXME move stuff to a flags field?
+ /** Quality, as it has been removed from AVCodecContext and put in AVVideoFrame.
+ * MN: dunno if that is the right place for it */
+ float quality;
+ /**
+ * Decoding: pts of the first frame of the stream, in stream time base.
+ * Only set this if you are absolutely 100% sure that the value you set
+ * it to really is the pts of the first frame.
+ * This may be undefined (AV_NOPTS_VALUE).
+ * @note The ASF header does NOT contain a correct start_time the ASF
+ * demuxer must NOT set this.
+ */
+ int64_t start_time;
+ /**
+ * Decoding: duration of the stream, in stream time base.
+ * If a source file does not specify a duration, but does specify
+ * a bitrate, this value will be estimated from bitrate and file size.
+ */
+ int64_t duration;
+
+#if LIBAVFORMAT_VERSION_INT < (53<<16)
+ char language[4]; /** ISO 639-2/B 3-letter language code (empty string if undefined) */
+#endif
+
+ /* av_read_frame() support */
+ enum AVStreamParseType need_parsing;
+ struct AVCodecParserContext *parser;
+
+ int64_t cur_dts;
+ int last_IP_duration;
+ int64_t last_IP_pts;
+ /* av_seek_frame() support */
+ AVIndexEntry *index_entries; /**< Only used if the format does not
+ support seeking natively. */
+ int nb_index_entries;
+ unsigned int index_entries_allocated_size;
+
+ int64_t nb_frames; ///< number of frames in this stream if known or 0
+
+#if LIBAVFORMAT_VERSION_INT < (53<<16)
+ int64_t unused[4+1];
+
+ char *filename; /**< source filename of the stream */
+#endif
+
+ int disposition; /**< AV_DISPOSITION_* bit field */
+
+ AVProbeData probe_data;
+#define MAX_REORDER_DELAY 16
+ int64_t pts_buffer[MAX_REORDER_DELAY+1];
+
+ /**
+ * sample aspect ratio (0 if unknown)
+ * - encoding: Set by user.
+ * - decoding: Set by libavformat.
+ */
+ AVRational sample_aspect_ratio;
+
+ AVMetadata *metadata;
+
+ /* av_read_frame() support */
+ const uint8_t *cur_ptr;
+ int cur_len;
+ AVPacket cur_pkt;
+
+ // Timestamp generation support:
+ /**
+ * Timestamp corresponding to the last dts sync point.
+ *
+ * Initialized when AVCodecParserContext.dts_sync_point >= 0 and
+ * a DTS is received from the underlying container. Otherwise set to
+ * AV_NOPTS_VALUE by default.
+ */
+ int64_t reference_dts;
+
+ /**
+ * Number of packets to buffer for codec probing
+ * NOT PART OF PUBLIC API
+ */
+#define MAX_PROBE_PACKETS 2500
+ int probe_packets;
+
+ /**
+ * last packet in packet_buffer for this stream when muxing.
+ * used internally, NOT PART OF PUBLIC API, dont read or write from outside of libav*
+ */
+ struct AVPacketList *last_in_packet_buffer;
+
+ /**
+ * Average framerate
+ */
+ AVRational avg_frame_rate;
+
+ /**
+ * Number of frames that have been demuxed during av_find_stream_info()
+ */
+ int codec_info_nb_frames;
+} AVStream;
+
+#define AV_PROGRAM_RUNNING 1
+
+/**
+ * New fields can be added to the end with minor version bumps.
+ * Removal, reordering and changes to existing fields require a major
+ * version bump.
+ * sizeof(AVProgram) must not be used outside libav*.
+ */
+typedef struct AVProgram {
+ int id;
+#if LIBAVFORMAT_VERSION_INT < (53<<16)
+ char *provider_name; ///< network name for DVB streams
+ char *name; ///< service name for DVB streams
+#endif
+ int flags;
+ enum AVDiscard discard; ///< selects which program to discard and which to feed to the caller
+ unsigned int *stream_index;
+ unsigned int nb_stream_indexes;
+ AVMetadata *metadata;
+} AVProgram;
+
+#define AVFMTCTX_NOHEADER 0x0001 /**< signal that no header is present
+ (streams are added dynamically) */
+
+typedef struct AVChapter {
+ int id; ///< unique ID to identify the chapter
+ AVRational time_base; ///< time base in which the start/end timestamps are specified
+ int64_t start, end; ///< chapter start/end time in time_base units
+#if LIBAVFORMAT_VERSION_INT < (53<<16)
+ char *title; ///< chapter title
+#endif
+ AVMetadata *metadata;
+} AVChapter;
+
+#if LIBAVFORMAT_VERSION_MAJOR < 53
+#define MAX_STREAMS 20
+#else
+#define MAX_STREAMS 100
+#endif
+
+/**
+ * Format I/O context.
+ * New fields can be added to the end with minor version bumps.
+ * Removal, reordering and changes to existing fields require a major
+ * version bump.
+ * sizeof(AVFormatContext) must not be used outside libav*.
+ */
+typedef struct AVFormatContext {
+ const AVClass *av_class; /**< Set by avformat_alloc_context. */
+ /* Can only be iformat or oformat, not both at the same time. */
+ struct AVInputFormat *iformat;
+ struct AVOutputFormat *oformat;
+ void *priv_data;
+ ByteIOContext *pb;
+ unsigned int nb_streams;
+ AVStream *streams[MAX_STREAMS];
+ char filename[1024]; /**< input or output filename */
+ /* stream info */
+ int64_t timestamp;
+#if LIBAVFORMAT_VERSION_INT < (53<<16)
+ char title[512];
+ char author[512];
+ char copyright[512];
+ char comment[512];
+ char album[512];
+ int year; /**< ID3 year, 0 if none */
+ int track; /**< track number, 0 if none */
+ char genre[32]; /**< ID3 genre */
+#endif
+
+ int ctx_flags; /**< Format-specific flags, see AVFMTCTX_xx */
+ /* private data for pts handling (do not modify directly). */
+ /** This buffer is only needed when packets were already buffered but
+ not decoded, for example to get the codec parameters in MPEG
+ streams. */
+ struct AVPacketList *packet_buffer;
+
+ /** Decoding: position of the first frame of the component, in
+ AV_TIME_BASE fractional seconds. NEVER set this value directly:
+ It is deduced from the AVStream values. */
+ int64_t start_time;
+ /** Decoding: duration of the stream, in AV_TIME_BASE fractional
+ seconds. Only set this value if you know none of the individual stream
+ durations and also dont set any of them. This is deduced from the
+ AVStream values if not set. */
+ int64_t duration;
+ /** decoding: total file size, 0 if unknown */
+ int64_t file_size;
+ /** Decoding: total stream bitrate in bit/s, 0 if not
+ available. Never set it directly if the file_size and the
+ duration are known as FFmpeg can compute it automatically. */
+ int bit_rate;
+
+ /* av_read_frame() support */
+ AVStream *cur_st;
+#if LIBAVFORMAT_VERSION_INT < (53<<16)
+ const uint8_t *cur_ptr_deprecated;
+ int cur_len_deprecated;
+ AVPacket cur_pkt_deprecated;
+#endif
+
+ /* av_seek_frame() support */
+ int64_t data_offset; /** offset of the first packet */
+ int index_built;
+
+ int mux_rate;
+ unsigned int packet_size;
+ int preload;
+ int max_delay;
+
+#define AVFMT_NOOUTPUTLOOP -1
+#define AVFMT_INFINITEOUTPUTLOOP 0
+ /** number of times to loop output in formats that support it */
+ int loop_output;
+
+ int flags;
+#define AVFMT_FLAG_GENPTS 0x0001 ///< Generate missing pts even if it requires parsing future frames.
+#define AVFMT_FLAG_IGNIDX 0x0002 ///< Ignore index.
+#define AVFMT_FLAG_NONBLOCK 0x0004 ///< Do not block when reading packets from input.
+#define AVFMT_FLAG_IGNDTS 0x0008 ///< Ignore DTS on frames that contain both DTS & PTS
+#define AVFMT_FLAG_NOFILLIN 0x0010 ///< Do not infer any values from other values, just return what is stored in the container
+#define AVFMT_FLAG_NOPARSE 0x0020 ///< Do not use AVParsers, you also must set AVFMT_FLAG_NOFILLIN as the fillin code works on frames and no parsing -> no frames. Also seeking to frames can not work if parsing to find frame boundaries has been disabled
+#define AVFMT_FLAG_RTP_HINT 0x0040 ///< Add RTP hinting to the output file
+
+ int loop_input;
+ /** decoding: size of data to probe; encoding: unused. */
+ unsigned int probesize;
+
+ /**
+ * Maximum time (in AV_TIME_BASE units) during which the input should
+ * be analyzed in av_find_stream_info().
+ */
+ int max_analyze_duration;
+
+ const uint8_t *key;
+ int keylen;
+
+ unsigned int nb_programs;
+ AVProgram **programs;
+
+ /**
+ * Forced video codec_id.
+ * Demuxing: Set by user.
+ */
+ enum CodecID video_codec_id;
+ /**
+ * Forced audio codec_id.
+ * Demuxing: Set by user.
+ */
+ enum CodecID audio_codec_id;
+ /**
+ * Forced subtitle codec_id.
+ * Demuxing: Set by user.
+ */
+ enum CodecID subtitle_codec_id;
+
+ /**
+ * Maximum amount of memory in bytes to use for the index of each stream.
+ * If the index exceeds this size, entries will be discarded as
+ * needed to maintain a smaller size. This can lead to slower or less
+ * accurate seeking (depends on demuxer).
+ * Demuxers for which a full in-memory index is mandatory will ignore
+ * this.
+ * muxing : unused
+ * demuxing: set by user
+ */
+ unsigned int max_index_size;
+
+ /**
+ * Maximum amount of memory in bytes to use for buffering frames
+ * obtained from realtime capture devices.
+ */
+ unsigned int max_picture_buffer;
+
+ unsigned int nb_chapters;
+ AVChapter **chapters;
+
+ /**
+ * Flags to enable debugging.
+ */
+ int debug;
+#define FF_FDEBUG_TS 0x0001
+
+ /**
+ * Raw packets from the demuxer, prior to parsing and decoding.
+ * This buffer is used for buffering packets until the codec can
+ * be identified, as parsing cannot be done without knowing the
+ * codec.
+ */
+ struct AVPacketList *raw_packet_buffer;
+ struct AVPacketList *raw_packet_buffer_end;
+
+ struct AVPacketList *packet_buffer_end;
+
+ AVMetadata *metadata;
+
+ /**
+ * Remaining size available for raw_packet_buffer, in bytes.
+ * NOT PART OF PUBLIC API
+ */
+#define RAW_PACKET_BUFFER_SIZE 2500000
+ int raw_packet_buffer_remaining_size;
+
+ /**
+ * Start time of the stream in real world time, in microseconds
+ * since the unix epoch (00:00 1st January 1970). That is, pts=0
+ * in the stream was captured at this real world time.
+ * - encoding: Set by user.
+ * - decoding: Unused.
+ */
+ int64_t start_time_realtime;
+} AVFormatContext;
+
+typedef struct AVPacketList {
+ AVPacket pkt;
+ struct AVPacketList *next;
+} AVPacketList;
+
+#if LIBAVFORMAT_VERSION_INT < (53<<16)
+extern AVInputFormat *first_iformat;
+extern AVOutputFormat *first_oformat;
+#endif
+
+/**
+ * If f is NULL, returns the first registered input format,
+ * if f is non-NULL, returns the next registered input format after f
+ * or NULL if f is the last one.
+ */
+AVInputFormat *av_iformat_next(AVInputFormat *f);
+
+/**
+ * If f is NULL, returns the first registered output format,
+ * if f is non-NULL, returns the next registered output format after f
+ * or NULL if f is the last one.
+ */
+AVOutputFormat *av_oformat_next(AVOutputFormat *f);
+
+enum CodecID av_guess_image2_codec(const char *filename);
+
+/* XXX: Use automatic init with either ELF sections or C file parser */
+/* modules. */
+
+/* utils.c */
+void av_register_input_format(AVInputFormat *format);
+void av_register_output_format(AVOutputFormat *format);
+#if LIBAVFORMAT_VERSION_MAJOR < 53
+attribute_deprecated AVOutputFormat *guess_stream_format(const char *short_name,
+ const char *filename,
+ const char *mime_type);
+
+/**
+ * @deprecated Use av_guess_format() instead.
+ */
+attribute_deprecated AVOutputFormat *guess_format(const char *short_name,
+ const char *filename,
+ const char *mime_type);
+#endif
+
+/**
+ * Returns the output format in the list of registered output formats
+ * which best matches the provided parameters, or returns NULL if
+ * there is no match.
+ *
+ * @param short_name if non-NULL checks if short_name matches with the
+ * names of the registered formats
+ * @param filename if non-NULL checks if filename terminates with the
+ * extensions of the registered formats
+ * @param mime_type if non-NULL checks if mime_type matches with the
+ * MIME type of the registered formats
+ */
+AVOutputFormat *av_guess_format(const char *short_name,
+ const char *filename,
+ const char *mime_type);
+
+/**
+ * Guesses the codec ID based upon muxer and filename.
+ */
+enum CodecID av_guess_codec(AVOutputFormat *fmt, const char *short_name,
+ const char *filename, const char *mime_type,
+ enum AVMediaType type);
+
+/**
+ * Sends a nice hexadecimal dump of a buffer to the specified file stream.
+ *
+ * @param f The file stream pointer where the dump should be sent to.
+ * @param buf buffer
+ * @param size buffer size
+ *
+ * @see av_hex_dump_log, av_pkt_dump, av_pkt_dump_log
+ */
+void av_hex_dump(FILE *f, uint8_t *buf, int size);
+
+/**
+ * Sends a nice hexadecimal dump of a buffer to the log.
+ *
+ * @param avcl A pointer to an arbitrary struct of which the first field is a
+ * pointer to an AVClass struct.
+ * @param level The importance level of the message, lower values signifying
+ * higher importance.
+ * @param buf buffer
+ * @param size buffer size
+ *
+ * @see av_hex_dump, av_pkt_dump, av_pkt_dump_log
+ */
+void av_hex_dump_log(void *avcl, int level, uint8_t *buf, int size);
+
+/**
+ * Sends a nice dump of a packet to the specified file stream.
+ *
+ * @param f The file stream pointer where the dump should be sent to.
+ * @param pkt packet to dump
+ * @param dump_payload True if the payload must be displayed, too.
+ */
+void av_pkt_dump(FILE *f, AVPacket *pkt, int dump_payload);
+
+/**
+ * Sends a nice dump of a packet to the log.
+ *
+ * @param avcl A pointer to an arbitrary struct of which the first field is a
+ * pointer to an AVClass struct.
+ * @param level The importance level of the message, lower values signifying
+ * higher importance.
+ * @param pkt packet to dump
+ * @param dump_payload True if the payload must be displayed, too.
+ */
+void av_pkt_dump_log(void *avcl, int level, AVPacket *pkt, int dump_payload);
+
+/**
+ * Initializes libavformat and registers all the muxers, demuxers and
+ * protocols. If you do not call this function, then you can select
+ * exactly which formats you want to support.
+ *
+ * @see av_register_input_format()
+ * @see av_register_output_format()
+ * @see av_register_protocol()
+ */
+void av_register_all(void);
+
+/**
+ * Gets the CodecID for the given codec tag tag.
+ * If no codec id is found returns CODEC_ID_NONE.
+ *
+ * @param tags list of supported codec_id-codec_tag pairs, as stored
+ * in AVInputFormat.codec_tag and AVOutputFormat.codec_tag
+ */
+enum CodecID av_codec_get_id(const struct AVCodecTag * const *tags, unsigned int tag);
+
+/**
+ * Gets the codec tag for the given codec id id.
+ * If no codec tag is found returns 0.
+ *
+ * @param tags list of supported codec_id-codec_tag pairs, as stored
+ * in AVInputFormat.codec_tag and AVOutputFormat.codec_tag
+ */
+unsigned int av_codec_get_tag(const struct AVCodecTag * const *tags, enum CodecID id);
+
+/* media file input */
+
+/**
+ * Finds AVInputFormat based on the short name of the input format.
+ */
+AVInputFormat *av_find_input_format(const char *short_name);
+
+/**
+ * Guesses the file format.
+ *
+ * @param is_opened Whether the file is already opened; determines whether
+ * demuxers with or without AVFMT_NOFILE are probed.
+ */
+AVInputFormat *av_probe_input_format(AVProbeData *pd, int is_opened);
+
+/**
+ * Guesses the file format.
+ *
+ * @param is_opened Whether the file is already opened; determines whether
+ * demuxers with or without AVFMT_NOFILE are probed.
+ * @param score_max A probe score larger that this is required to accept a
+ * detection, the variable is set to the actual detection
+ * score afterwards.
+ * If the score is <= AVPROBE_SCORE_MAX / 4 it is recommended
+ * to retry with a larger probe buffer.
+ */
+AVInputFormat *av_probe_input_format2(AVProbeData *pd, int is_opened, int *score_max);
+
+/**
+ * Allocates all the structures needed to read an input stream.
+ * This does not open the needed codecs for decoding the stream[s].
+ */
+int av_open_input_stream(AVFormatContext **ic_ptr,
+ ByteIOContext *pb, const char *filename,
+ AVInputFormat *fmt, AVFormatParameters *ap);
+
+/**
+ * Opens a media file as input. The codecs are not opened. Only the file
+ * header (if present) is read.
+ *
+ * @param ic_ptr The opened media file handle is put here.
+ * @param filename filename to open
+ * @param fmt If non-NULL, force the file format to use.
+ * @param buf_size optional buffer size (zero if default is OK)
+ * @param ap Additional parameters needed when opening the file
+ * (NULL if default).
+ * @return 0 if OK, AVERROR_xxx otherwise
+ */
+int av_open_input_file(AVFormatContext **ic_ptr, const char *filename,
+ AVInputFormat *fmt,
+ int buf_size,
+ AVFormatParameters *ap);
+
+#if LIBAVFORMAT_VERSION_MAJOR < 53
+/**
+ * @deprecated Use avformat_alloc_context() instead.
+ */
+attribute_deprecated AVFormatContext *av_alloc_format_context(void);
+#endif
+
+/**
+ * Allocates an AVFormatContext.
+ * Can be freed with av_free() but do not forget to free everything you
+ * explicitly allocated as well!
+ */
+AVFormatContext *avformat_alloc_context(void);
+
+/**
+ * Reads packets of a media file to get stream information. This
+ * is useful for file formats with no headers such as MPEG. This
+ * function also computes the real framerate in case of MPEG-2 repeat
+ * frame mode.
+ * The logical file position is not changed by this function;
+ * examined packets may be buffered for later processing.
+ *
+ * @param ic media file handle
+ * @return >=0 if OK, AVERROR_xxx on error
+ * @todo Let the user decide somehow what information is needed so that
+ * we do not waste time getting stuff the user does not need.
+ */
+int av_find_stream_info(AVFormatContext *ic);
+
+/**
+ * Reads a transport packet from a media file.
+ *
+ * This function is obsolete and should never be used.
+ * Use av_read_frame() instead.
+ *
+ * @param s media file handle
+ * @param pkt is filled
+ * @return 0 if OK, AVERROR_xxx on error
+ */
+int av_read_packet(AVFormatContext *s, AVPacket *pkt);
+
+/**
+ * Returns the next frame of a stream.
+ *
+ * The returned packet is valid
+ * until the next av_read_frame() or until av_close_input_file() and
+ * must be freed with av_free_packet. For video, the packet contains
+ * exactly one frame. For audio, it contains an integer number of
+ * frames if each frame has a known fixed size (e.g. PCM or ADPCM
+ * data). If the audio frames have a variable size (e.g. MPEG audio),
+ * then it contains one frame.
+ *
+ * pkt->pts, pkt->dts and pkt->duration are always set to correct
+ * values in AVStream.time_base units (and guessed if the format cannot
+ * provide them). pkt->pts can be AV_NOPTS_VALUE if the video format
+ * has B-frames, so it is better to rely on pkt->dts if you do not
+ * decompress the payload.
+ *
+ * @return 0 if OK, < 0 on error or end of file
+ */
+int av_read_frame(AVFormatContext *s, AVPacket *pkt);
+
+/**
+ * Seeks to the keyframe at timestamp.
+ * 'timestamp' in 'stream_index'.
+ * @param stream_index If stream_index is (-1), a default
+ * stream is selected, and timestamp is automatically converted
+ * from AV_TIME_BASE units to the stream specific time_base.
+ * @param timestamp Timestamp in AVStream.time_base units
+ * or, if no stream is specified, in AV_TIME_BASE units.
+ * @param flags flags which select direction and seeking mode
+ * @return >= 0 on success
+ */
+int av_seek_frame(AVFormatContext *s, int stream_index, int64_t timestamp,
+ int flags);
+
+/**
+ * Seeks to timestamp ts.
+ * Seeking will be done so that the point from which all active streams
+ * can be presented successfully will be closest to ts and within min/max_ts.
+ * Active streams are all streams that have AVStream.discard < AVDISCARD_ALL.
+ *
+ * If flags contain AVSEEK_FLAG_BYTE, then all timestamps are in bytes and
+ * are the file position (this may not be supported by all demuxers).
+ * If flags contain AVSEEK_FLAG_FRAME, then all timestamps are in frames
+ * in the stream with stream_index (this may not be supported by all demuxers).
+ * Otherwise all timestamps are in units of the stream selected by stream_index
+ * or if stream_index is -1, in AV_TIME_BASE units.
+ * If flags contain AVSEEK_FLAG_ANY, then non-keyframes are treated as
+ * keyframes (this may not be supported by all demuxers).
+ *
+ * @param stream_index index of the stream which is used as time base reference
+ * @param min_ts smallest acceptable timestamp
+ * @param ts target timestamp
+ * @param max_ts largest acceptable timestamp
+ * @param flags flags
+ * @return >=0 on success, error code otherwise
+ *
+ * @NOTE This is part of the new seek API which is still under construction.
+ * Thus do not use this yet. It may change at any time, do not expect
+ * ABI compatibility yet!
+ */
+int avformat_seek_file(AVFormatContext *s, int stream_index, int64_t min_ts, int64_t ts, int64_t max_ts, int flags);
+
+/**
+ * Starts playing a network-based stream (e.g. RTSP stream) at the
+ * current position.
+ */
+int av_read_play(AVFormatContext *s);
+
+/**
+ * Pauses a network-based stream (e.g. RTSP stream).
+ *
+ * Use av_read_play() to resume it.
+ */
+int av_read_pause(AVFormatContext *s);
+
+/**
+ * Frees a AVFormatContext allocated by av_open_input_stream.
+ * @param s context to free
+ */
+void av_close_input_stream(AVFormatContext *s);
+
+/**
+ * Closes a media file (but not its codecs).
+ *
+ * @param s media file handle
+ */
+void av_close_input_file(AVFormatContext *s);
+
+/**
+ * Adds a new stream to a media file.
+ *
+ * Can only be called in the read_header() function. If the flag
+ * AVFMTCTX_NOHEADER is in the format context, then new streams
+ * can be added in read_packet too.
+ *
+ * @param s media file handle
+ * @param id file-format-dependent stream ID
+ */
+AVStream *av_new_stream(AVFormatContext *s, int id);
+AVProgram *av_new_program(AVFormatContext *s, int id);
+
+/**
+ * Adds a new chapter.
+ * This function is NOT part of the public API
+ * and should ONLY be used by demuxers.
+ *
+ * @param s media file handle
+ * @param id unique ID for this chapter
+ * @param start chapter start time in time_base units
+ * @param end chapter end time in time_base units
+ * @param title chapter title
+ *
+ * @return AVChapter or NULL on error
+ */
+AVChapter *ff_new_chapter(AVFormatContext *s, int id, AVRational time_base,
+ int64_t start, int64_t end, const char *title);
+
+/**
+ * Sets the pts for a given stream.
+ *
+ * @param s stream
+ * @param pts_wrap_bits number of bits effectively used by the pts
+ * (used for wrap control, 33 is the value for MPEG)
+ * @param pts_num numerator to convert to seconds (MPEG: 1)
+ * @param pts_den denominator to convert to seconds (MPEG: 90000)
+ */
+void av_set_pts_info(AVStream *s, int pts_wrap_bits,
+ unsigned int pts_num, unsigned int pts_den);
+
+#define AVSEEK_FLAG_BACKWARD 1 ///< seek backward
+#define AVSEEK_FLAG_BYTE 2 ///< seeking based on position in bytes
+#define AVSEEK_FLAG_ANY 4 ///< seek to any frame, even non-keyframes
+#define AVSEEK_FLAG_FRAME 8 ///< seeking based on frame number
+
+int av_find_default_stream_index(AVFormatContext *s);
+
+/**
+ * Gets the index for a specific timestamp.
+ * @param flags if AVSEEK_FLAG_BACKWARD then the returned index will correspond
+ * to the timestamp which is <= the requested one, if backward
+ * is 0, then it will be >=
+ * if AVSEEK_FLAG_ANY seek to any frame, only keyframes otherwise
+ * @return < 0 if no such timestamp could be found
+ */
+int av_index_search_timestamp(AVStream *st, int64_t timestamp, int flags);
+
+/**
+ * Ensures the index uses less memory than the maximum specified in
+ * AVFormatContext.max_index_size by discarding entries if it grows
+ * too large.
+ * This function is not part of the public API and should only be called
+ * by demuxers.
+ */
+void ff_reduce_index(AVFormatContext *s, int stream_index);
+
+/**
+ * Adds an index entry into a sorted list. Updates the entry if the list
+ * already contains it.
+ *
+ * @param timestamp timestamp in the time base of the given stream
+ */
+int av_add_index_entry(AVStream *st, int64_t pos, int64_t timestamp,
+ int size, int distance, int flags);
+
+/**
+ * Does a binary search using av_index_search_timestamp() and
+ * AVCodec.read_timestamp().
+ * This is not supposed to be called directly by a user application,
+ * but by demuxers.
+ * @param target_ts target timestamp in the time base of the given stream
+ * @param stream_index stream number
+ */
+int av_seek_frame_binary(AVFormatContext *s, int stream_index,
+ int64_t target_ts, int flags);
+
+/**
+ * Updates cur_dts of all streams based on the given timestamp and AVStream.
+ *
+ * Stream ref_st unchanged, others set cur_dts in their native time base.
+ * Only needed for timestamp wrapping or if (dts not set and pts!=dts).
+ * @param timestamp new dts expressed in time_base of param ref_st
+ * @param ref_st reference stream giving time_base of param timestamp
+ */
+void av_update_cur_dts(AVFormatContext *s, AVStream *ref_st, int64_t timestamp);
+
+/**
+ * Does a binary search using read_timestamp().
+ * This is not supposed to be called directly by a user application,
+ * but by demuxers.
+ * @param target_ts target timestamp in the time base of the given stream
+ * @param stream_index stream number
+ */
+int64_t av_gen_search(AVFormatContext *s, int stream_index,
+ int64_t target_ts, int64_t pos_min,
+ int64_t pos_max, int64_t pos_limit,
+ int64_t ts_min, int64_t ts_max,
+ int flags, int64_t *ts_ret,
+ int64_t (*read_timestamp)(struct AVFormatContext *, int , int64_t *, int64_t ));
+
+/** media file output */
+int av_set_parameters(AVFormatContext *s, AVFormatParameters *ap);
+
+/**
+ * Allocates the stream private data and writes the stream header to an
+ * output media file.
+ *
+ * @param s media file handle
+ * @return 0 if OK, AVERROR_xxx on error
+ */
+int av_write_header(AVFormatContext *s);
+
+/**
+ * Writes a packet to an output media file.
+ *
+ * The packet shall contain one audio or video frame.
+ * The packet must be correctly interleaved according to the container
+ * specification, if not then av_interleaved_write_frame must be used.
+ *
+ * @param s media file handle
+ * @param pkt The packet, which contains the stream_index, buf/buf_size,
+ dts/pts, ...
+ * @return < 0 on error, = 0 if OK, 1 if end of stream wanted
+ */
+int av_write_frame(AVFormatContext *s, AVPacket *pkt);
+
+/**
+ * Writes a packet to an output media file ensuring correct interleaving.
+ *
+ * The packet must contain one audio or video frame.
+ * If the packets are already correctly interleaved, the application should
+ * call av_write_frame() instead as it is slightly faster. It is also important
+ * to keep in mind that completely non-interleaved input will need huge amounts
+ * of memory to interleave with this, so it is preferable to interleave at the
+ * demuxer level.
+ *
+ * @param s media file handle
+ * @param pkt The packet, which contains the stream_index, buf/buf_size,
+ dts/pts, ...
+ * @return < 0 on error, = 0 if OK, 1 if end of stream wanted
+ */
+int av_interleaved_write_frame(AVFormatContext *s, AVPacket *pkt);
+
+/**
+ * Interleaves a packet per dts in an output media file.
+ *
+ * Packets with pkt->destruct == av_destruct_packet will be freed inside this
+ * function, so they cannot be used after it. Note that calling av_free_packet()
+ * on them is still safe.
+ *
+ * @param s media file handle
+ * @param out the interleaved packet will be output here
+ * @param in the input packet
+ * @param flush 1 if no further packets are available as input and all
+ * remaining packets should be output
+ * @return 1 if a packet was output, 0 if no packet could be output,
+ * < 0 if an error occurred
+ */
+int av_interleave_packet_per_dts(AVFormatContext *s, AVPacket *out,
+ AVPacket *pkt, int flush);
+
+/**
+ * Writes the stream trailer to an output media file and frees the
+ * file private data.
+ *
+ * May only be called after a successful call to av_write_header.
+ *
+ * @param s media file handle
+ * @return 0 if OK, AVERROR_xxx on error
+ */
+int av_write_trailer(AVFormatContext *s);
+
+void dump_format(AVFormatContext *ic,
+ int index,
+ const char *url,
+ int is_output);
+
+#if LIBAVFORMAT_VERSION_MAJOR < 53
+/**
+ * Parses width and height out of string str.
+ * @deprecated Use av_parse_video_frame_size instead.
+ */
+attribute_deprecated int parse_image_size(int *width_ptr, int *height_ptr,
+ const char *str);
+
+/**
+ * Converts framerate from a string to a fraction.
+ * @deprecated Use av_parse_video_frame_rate instead.
+ */
+attribute_deprecated int parse_frame_rate(int *frame_rate, int *frame_rate_base,
+ const char *arg);
+#endif
+
+/**
+ * Parses datestr and returns a corresponding number of microseconds.
+ * @param datestr String representing a date or a duration.
+ * - If a date the syntax is:
+ * @code
+ * [{YYYY-MM-DD|YYYYMMDD}]{T| }{HH[:MM[:SS[.m...]]][Z]|HH[MM[SS[.m...]]][Z]}
+ * @endcode
+ * Time is local time unless Z is appended, in which case it is
+ * interpreted as UTC.
+ * If the year-month-day part is not specified it takes the current
+ * year-month-day.
+ * Returns the number of microseconds since 1st of January, 1970 up to
+ * the time of the parsed date or INT64_MIN if datestr cannot be
+ * successfully parsed.
+ * - If a duration the syntax is:
+ * @code
+ * [-]HH[:MM[:SS[.m...]]]
+ * [-]S+[.m...]
+ * @endcode
+ * Returns the number of microseconds contained in a time interval
+ * with the specified duration or INT64_MIN if datestr cannot be
+ * successfully parsed.
+ * @param duration Flag which tells how to interpret datestr, if
+ * not zero datestr is interpreted as a duration, otherwise as a
+ * date.
+ */
+int64_t parse_date(const char *datestr, int duration);
+
+/** Gets the current time in microseconds. */
+int64_t av_gettime(void);
+
+/* ffm-specific for ffserver */
+#define FFM_PACKET_SIZE 4096
+int64_t ffm_read_write_index(int fd);
+int ffm_write_write_index(int fd, int64_t pos);
+void ffm_set_write_index(AVFormatContext *s, int64_t pos, int64_t file_size);
+
+/**
+ * Attempts to find a specific tag in a URL.
+ *
+ * syntax: '?tag1=val1&tag2=val2...'. Little URL decoding is done.
+ * Return 1 if found.
+ */
+int find_info_tag(char *arg, int arg_size, const char *tag1, const char *info);
+
+/**
+ * Returns in 'buf' the path with '%d' replaced by a number.
+ *
+ * Also handles the '%0nd' format where 'n' is the total number
+ * of digits and '%%'.
+ *
+ * @param buf destination buffer
+ * @param buf_size destination buffer size
+ * @param path numbered sequence string
+ * @param number frame number
+ * @return 0 if OK, -1 on format error
+ */
+int av_get_frame_filename(char *buf, int buf_size,
+ const char *path, int number);
+
+/**
+ * Checks whether filename actually is a numbered sequence generator.
+ *
+ * @param filename possible numbered sequence string
+ * @return 1 if a valid numbered sequence string, 0 otherwise
+ */
+int av_filename_number_test(const char *filename);
+
+/**
+ * Generates an SDP for an RTP session.
+ *
+ * @param ac array of AVFormatContexts describing the RTP streams. If the
+ * array is composed by only one context, such context can contain
+ * multiple AVStreams (one AVStream per RTP stream). Otherwise,
+ * all the contexts in the array (an AVCodecContext per RTP stream)
+ * must contain only one AVStream.
+ * @param n_files number of AVCodecContexts contained in ac
+ * @param buff buffer where the SDP will be stored (must be allocated by
+ * the caller)
+ * @param size the size of the buffer
+ * @return 0 if OK, AVERROR_xxx on error
+ */
+int avf_sdp_create(AVFormatContext *ac[], int n_files, char *buff, int size);
+
+/**
+ * Returns a positive value if the given filename has one of the given
+ * extensions, 0 otherwise.
+ *
+ * @param extensions a comma-separated list of filename extensions
+ */
+int av_match_ext(const char *filename, const char *extensions);
+
+#endif /* AVFORMAT_AVFORMAT_H */
diff --git a/lib-x86-32/include/libavformat/avio.h b/lib-x86-32/include/libavformat/avio.h
new file mode 100644
index 00000000..9ffe9356
--- /dev/null
+++ b/lib-x86-32/include/libavformat/avio.h
@@ -0,0 +1,525 @@
+/*
+ * copyright (c) 2001 Fabrice Bellard
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#ifndef AVFORMAT_AVIO_H
+#define AVFORMAT_AVIO_H
+
+/**
+ * @file
+ * unbuffered I/O operations
+ *
+ * @warning This file has to be considered an internal but installed
+ * header, so it should not be directly included in your projects.
+ */
+
+#include <stdint.h>
+
+#include "libavutil/common.h"
+
+/* unbuffered I/O */
+
+/**
+ * URL Context.
+ * New fields can be added to the end with minor version bumps.
+ * Removal, reordering and changes to existing fields require a major
+ * version bump.
+ * sizeof(URLContext) must not be used outside libav*.
+ */
+typedef struct URLContext {
+#if LIBAVFORMAT_VERSION_MAJOR >= 53
+ const AVClass *av_class; ///< information for av_log(). Set by url_open().
+#endif
+ struct URLProtocol *prot;
+ int flags;
+ int is_streamed; /**< true if streamed (no seek possible), default = false */
+ int max_packet_size; /**< if non zero, the stream is packetized with this max packet size */
+ void *priv_data;
+ char *filename; /**< specified URL */
+} URLContext;
+
+typedef struct URLPollEntry {
+ URLContext *handle;
+ int events;
+ int revents;
+} URLPollEntry;
+
+#define URL_RDONLY 0
+#define URL_WRONLY 1
+#define URL_RDWR 2
+
+typedef int URLInterruptCB(void);
+
+/**
+ * Creates an URLContext for accessing to the resource indicated by
+ * url, and opens it using the URLProtocol up.
+ *
+ * @param puc pointer to the location where, in case of success, the
+ * function puts the pointer to the created URLContext
+ * @param flags flags which control how the resource indicated by url
+ * is to be opened
+ * @return 0 in case of success, a negative value corresponding to an
+ * AVERROR code in case of failure
+ */
+int url_open_protocol (URLContext **puc, struct URLProtocol *up,
+ const char *url, int flags);
+
+/**
+ * Creates an URLContext for accessing to the resource indicated by
+ * url, and opens it.
+ *
+ * @param puc pointer to the location where, in case of success, the
+ * function puts the pointer to the created URLContext
+ * @param flags flags which control how the resource indicated by url
+ * is to be opened
+ * @return 0 in case of success, a negative value corresponding to an
+ * AVERROR code in case of failure
+ */
+int url_open(URLContext **h, const char *url, int flags);
+
+/**
+ * Reads up to size bytes from the resource accessed by h, and stores
+ * the read bytes in buf.
+ *
+ * @return The number of bytes actually read, or a negative value
+ * corresponding to an AVERROR code in case of error. A value of zero
+ * indicates that it is not possible to read more from the accessed
+ * resource (except if the value of the size argument is also zero).
+ */
+int url_read(URLContext *h, unsigned char *buf, int size);
+
+/**
+ * Read as many bytes as possible (up to size), calling the
+ * read function multiple times if necessary.
+ * Will also retry if the read function returns AVERROR(EAGAIN).
+ * This makes special short-read handling in applications
+ * unnecessary, if the return value is < size then it is
+ * certain there was either an error or the end of file was reached.
+ */
+int url_read_complete(URLContext *h, unsigned char *buf, int size);
+int url_write(URLContext *h, unsigned char *buf, int size);
+
+/**
+ * Changes the position that will be used by the next read/write
+ * operation on the resource accessed by h.
+ *
+ * @param pos specifies the new position to set
+ * @param whence specifies how pos should be interpreted, it must be
+ * one of SEEK_SET (seek from the beginning), SEEK_CUR (seek from the
+ * current position), SEEK_END (seek from the end), or AVSEEK_SIZE
+ * (return the filesize of the requested resource, pos is ignored).
+ * @return a negative value corresponding to an AVERROR code in case
+ * of failure, or the resulting file position, measured in bytes from
+ * the beginning of the file. You can use this feature together with
+ * SEEK_CUR to read the current file position.
+ */
+int64_t url_seek(URLContext *h, int64_t pos, int whence);
+
+/**
+ * Closes the resource accessed by the URLContext h, and frees the
+ * memory used by it.
+ *
+ * @return a negative value if an error condition occurred, 0
+ * otherwise
+ */
+int url_close(URLContext *h);
+
+/**
+ * Returns a non-zero value if the resource indicated by url
+ * exists, 0 otherwise.
+ */
+int url_exist(const char *url);
+
+int64_t url_filesize(URLContext *h);
+
+/**
+ * Return the file descriptor associated with this URL. For RTP, this
+ * will return only the RTP file descriptor, not the RTCP file descriptor.
+ * To get both, use rtp_get_file_handles().
+ *
+ * @return the file descriptor associated with this URL, or <0 on error.
+ */
+int url_get_file_handle(URLContext *h);
+
+/**
+ * Return the maximum packet size associated to packetized file
+ * handle. If the file is not packetized (stream like HTTP or file on
+ * disk), then 0 is returned.
+ *
+ * @param h file handle
+ * @return maximum packet size in bytes
+ */
+int url_get_max_packet_size(URLContext *h);
+void url_get_filename(URLContext *h, char *buf, int buf_size);
+
+/**
+ * The callback is called in blocking functions to test regulary if
+ * asynchronous interruption is needed. AVERROR(EINTR) is returned
+ * in this case by the interrupted function. 'NULL' means no interrupt
+ * callback is given.
+ */
+void url_set_interrupt_cb(URLInterruptCB *interrupt_cb);
+
+/* not implemented */
+int url_poll(URLPollEntry *poll_table, int n, int timeout);
+
+/**
+ * Pause and resume playing - only meaningful if using a network streaming
+ * protocol (e.g. MMS).
+ * @param pause 1 for pause, 0 for resume
+ */
+int av_url_read_pause(URLContext *h, int pause);
+
+/**
+ * Seek to a given timestamp relative to some component stream.
+ * Only meaningful if using a network streaming protocol (e.g. MMS.).
+ * @param stream_index The stream index that the timestamp is relative to.
+ * If stream_index is (-1) the timestamp should be in AV_TIME_BASE
+ * units from the beginning of the presentation.
+ * If a stream_index >= 0 is used and the protocol does not support
+ * seeking based on component streams, the call will fail with ENOTSUP.
+ * @param timestamp timestamp in AVStream.time_base units
+ * or if there is no stream specified then in AV_TIME_BASE units.
+ * @param flags Optional combination of AVSEEK_FLAG_BACKWARD, AVSEEK_FLAG_BYTE
+ * and AVSEEK_FLAG_ANY. The protocol may silently ignore
+ * AVSEEK_FLAG_BACKWARD and AVSEEK_FLAG_ANY, but AVSEEK_FLAG_BYTE will
+ * fail with ENOTSUP if used and not supported.
+ * @return >= 0 on success
+ * @see AVInputFormat::read_seek
+ */
+int64_t av_url_read_seek(URLContext *h, int stream_index,
+ int64_t timestamp, int flags);
+
+/**
+ * Passing this as the "whence" parameter to a seek function causes it to
+ * return the filesize without seeking anywhere. Supporting this is optional.
+ * If it is not supported then the seek function will return <0.
+ */
+#define AVSEEK_SIZE 0x10000
+
+/**
+ * Oring this flag as into the "whence" parameter to a seek function causes it to
+ * seek by any means (like reopening and linear reading) or other normally unreasonble
+ * means that can be extreemly slow.
+ * This may be ignored by the seek code.
+ */
+#define AVSEEK_FORCE 0x20000
+
+typedef struct URLProtocol {
+ const char *name;
+ int (*url_open)(URLContext *h, const char *url, int flags);
+ int (*url_read)(URLContext *h, unsigned char *buf, int size);
+ int (*url_write)(URLContext *h, unsigned char *buf, int size);
+ int64_t (*url_seek)(URLContext *h, int64_t pos, int whence);
+ int (*url_close)(URLContext *h);
+ struct URLProtocol *next;
+ int (*url_read_pause)(URLContext *h, int pause);
+ int64_t (*url_read_seek)(URLContext *h, int stream_index,
+ int64_t timestamp, int flags);
+ int (*url_get_file_handle)(URLContext *h);
+} URLProtocol;
+
+#if LIBAVFORMAT_VERSION_MAJOR < 53
+extern URLProtocol *first_protocol;
+#endif
+
+extern URLInterruptCB *url_interrupt_cb;
+
+/**
+ * If protocol is NULL, returns the first registered protocol,
+ * if protocol is non-NULL, returns the next registered protocol after protocol,
+ * or NULL if protocol is the last one.
+ */
+URLProtocol *av_protocol_next(URLProtocol *p);
+
+#if LIBAVFORMAT_VERSION_MAJOR < 53
+/**
+ * @deprecated Use av_register_protocol() instead.
+ */
+attribute_deprecated int register_protocol(URLProtocol *protocol);
+#endif
+
+/**
+ * Registers the URLProtocol protocol.
+ */
+int av_register_protocol(URLProtocol *protocol);
+
+/**
+ * Bytestream IO Context.
+ * New fields can be added to the end with minor version bumps.
+ * Removal, reordering and changes to existing fields require a major
+ * version bump.
+ * sizeof(ByteIOContext) must not be used outside libav*.
+ */
+typedef struct {
+ unsigned char *buffer;
+ int buffer_size;
+ unsigned char *buf_ptr, *buf_end;
+ void *opaque;
+ int (*read_packet)(void *opaque, uint8_t *buf, int buf_size);
+ int (*write_packet)(void *opaque, uint8_t *buf, int buf_size);
+ int64_t (*seek)(void *opaque, int64_t offset, int whence);
+ int64_t pos; /**< position in the file of the current buffer */
+ int must_flush; /**< true if the next seek should flush */
+ int eof_reached; /**< true if eof reached */
+ int write_flag; /**< true if open for writing */
+ int is_streamed;
+ int max_packet_size;
+ unsigned long checksum;
+ unsigned char *checksum_ptr;
+ unsigned long (*update_checksum)(unsigned long checksum, const uint8_t *buf, unsigned int size);
+ int error; ///< contains the error code or 0 if no error happened
+ int (*read_pause)(void *opaque, int pause);
+ int64_t (*read_seek)(void *opaque, int stream_index,
+ int64_t timestamp, int flags);
+} ByteIOContext;
+
+int init_put_byte(ByteIOContext *s,
+ unsigned char *buffer,
+ int buffer_size,
+ int write_flag,
+ void *opaque,
+ int (*read_packet)(void *opaque, uint8_t *buf, int buf_size),
+ int (*write_packet)(void *opaque, uint8_t *buf, int buf_size),
+ int64_t (*seek)(void *opaque, int64_t offset, int whence));
+ByteIOContext *av_alloc_put_byte(
+ unsigned char *buffer,
+ int buffer_size,
+ int write_flag,
+ void *opaque,
+ int (*read_packet)(void *opaque, uint8_t *buf, int buf_size),
+ int (*write_packet)(void *opaque, uint8_t *buf, int buf_size),
+ int64_t (*seek)(void *opaque, int64_t offset, int whence));
+
+void put_byte(ByteIOContext *s, int b);
+void put_buffer(ByteIOContext *s, const unsigned char *buf, int size);
+void put_le64(ByteIOContext *s, uint64_t val);
+void put_be64(ByteIOContext *s, uint64_t val);
+void put_le32(ByteIOContext *s, unsigned int val);
+void put_be32(ByteIOContext *s, unsigned int val);
+void put_le24(ByteIOContext *s, unsigned int val);
+void put_be24(ByteIOContext *s, unsigned int val);
+void put_le16(ByteIOContext *s, unsigned int val);
+void put_be16(ByteIOContext *s, unsigned int val);
+void put_tag(ByteIOContext *s, const char *tag);
+
+void put_strz(ByteIOContext *s, const char *buf);
+
+/**
+ * fseek() equivalent for ByteIOContext.
+ * @return new position or AVERROR.
+ */
+int64_t url_fseek(ByteIOContext *s, int64_t offset, int whence);
+
+/**
+ * Skip given number of bytes forward.
+ * @param offset number of bytes
+ */
+void url_fskip(ByteIOContext *s, int64_t offset);
+
+/**
+ * ftell() equivalent for ByteIOContext.
+ * @return position or AVERROR.
+ */
+int64_t url_ftell(ByteIOContext *s);
+
+/**
+ * Gets the filesize.
+ * @return filesize or AVERROR
+ */
+int64_t url_fsize(ByteIOContext *s);
+
+/**
+ * feof() equivalent for ByteIOContext.
+ * @return non zero if and only if end of file
+ */
+int url_feof(ByteIOContext *s);
+
+int url_ferror(ByteIOContext *s);
+
+int av_url_read_fpause(ByteIOContext *h, int pause);
+int64_t av_url_read_fseek(ByteIOContext *h, int stream_index,
+ int64_t timestamp, int flags);
+
+#define URL_EOF (-1)
+/** @note return URL_EOF (-1) if EOF */
+int url_fgetc(ByteIOContext *s);
+
+/** @warning currently size is limited */
+#ifdef __GNUC__
+int url_fprintf(ByteIOContext *s, const char *fmt, ...) __attribute__ ((__format__ (__printf__, 2, 3)));
+#else
+int url_fprintf(ByteIOContext *s, const char *fmt, ...);
+#endif
+
+/** @note unlike fgets, the EOL character is not returned and a whole
+ line is parsed. return NULL if first char read was EOF */
+char *url_fgets(ByteIOContext *s, char *buf, int buf_size);
+
+void put_flush_packet(ByteIOContext *s);
+
+
+/**
+ * Reads size bytes from ByteIOContext into buf.
+ * @return number of bytes read or AVERROR
+ */
+int get_buffer(ByteIOContext *s, unsigned char *buf, int size);
+
+/**
+ * Reads size bytes from ByteIOContext into buf.
+ * This reads at most 1 packet. If that is not enough fewer bytes will be
+ * returned.
+ * @return number of bytes read or AVERROR
+ */
+int get_partial_buffer(ByteIOContext *s, unsigned char *buf, int size);
+
+/** @note return 0 if EOF, so you cannot use it if EOF handling is
+ necessary */
+int get_byte(ByteIOContext *s);
+unsigned int get_le24(ByteIOContext *s);
+unsigned int get_le32(ByteIOContext *s);
+uint64_t get_le64(ByteIOContext *s);
+unsigned int get_le16(ByteIOContext *s);
+
+char *get_strz(ByteIOContext *s, char *buf, int maxlen);
+unsigned int get_be16(ByteIOContext *s);
+unsigned int get_be24(ByteIOContext *s);
+unsigned int get_be32(ByteIOContext *s);
+uint64_t get_be64(ByteIOContext *s);
+
+uint64_t ff_get_v(ByteIOContext *bc);
+
+static inline int url_is_streamed(ByteIOContext *s)
+{
+ return s->is_streamed;
+}
+
+/**
+ * Creates and initializes a ByteIOContext for accessing the
+ * resource referenced by the URLContext h.
+ * @note When the URLContext h has been opened in read+write mode, the
+ * ByteIOContext can be used only for writing.
+ *
+ * @param s Used to return the pointer to the created ByteIOContext.
+ * In case of failure the pointed to value is set to NULL.
+ * @return 0 in case of success, a negative value corresponding to an
+ * AVERROR code in case of failure
+ */
+int url_fdopen(ByteIOContext **s, URLContext *h);
+
+/** @warning must be called before any I/O */
+int url_setbufsize(ByteIOContext *s, int buf_size);
+#if LIBAVFORMAT_VERSION_MAJOR < 53
+/** Reset the buffer for reading or writing.
+ * @note Will drop any data currently in the buffer without transmitting it.
+ * @param flags URL_RDONLY to set up the buffer for reading, or URL_WRONLY
+ * to set up the buffer for writing. */
+int url_resetbuf(ByteIOContext *s, int flags);
+#endif
+
+/**
+ * Rewinds the ByteIOContext using the specified buffer containing the first buf_size bytes of the file.
+ * Used after probing to avoid seeking.
+ * Joins buf and s->buffer, taking any overlap into consideration.
+ * @note s->buffer must overlap with buf or they can't be joined and the function fails
+ * @note This function is NOT part of the public API
+ *
+ * @param s The read-only ByteIOContext to rewind
+ * @param buf The probe buffer containing the first buf_size bytes of the file
+ * @param buf_size The size of buf
+ * @return 0 in case of success, a negative value corresponding to an
+ * AVERROR code in case of failure
+ */
+int ff_rewind_with_probe_data(ByteIOContext *s, unsigned char *buf, int buf_size);
+
+/**
+ * Creates and initializes a ByteIOContext for accessing the
+ * resource indicated by url.
+ * @note When the resource indicated by url has been opened in
+ * read+write mode, the ByteIOContext can be used only for writing.
+ *
+ * @param s Used to return the pointer to the created ByteIOContext.
+ * In case of failure the pointed to value is set to NULL.
+ * @param flags flags which control how the resource indicated by url
+ * is to be opened
+ * @return 0 in case of success, a negative value corresponding to an
+ * AVERROR code in case of failure
+ */
+int url_fopen(ByteIOContext **s, const char *url, int flags);
+
+int url_fclose(ByteIOContext *s);
+URLContext *url_fileno(ByteIOContext *s);
+
+/**
+ * Return the maximum packet size associated to packetized buffered file
+ * handle. If the file is not packetized (stream like http or file on
+ * disk), then 0 is returned.
+ *
+ * @param s buffered file handle
+ * @return maximum packet size in bytes
+ */
+int url_fget_max_packet_size(ByteIOContext *s);
+
+int url_open_buf(ByteIOContext **s, uint8_t *buf, int buf_size, int flags);
+
+/** return the written or read size */
+int url_close_buf(ByteIOContext *s);
+
+/**
+ * Open a write only memory stream.
+ *
+ * @param s new IO context
+ * @return zero if no error.
+ */
+int url_open_dyn_buf(ByteIOContext **s);
+
+/**
+ * Open a write only packetized memory stream with a maximum packet
+ * size of 'max_packet_size'. The stream is stored in a memory buffer
+ * with a big endian 4 byte header giving the packet size in bytes.
+ *
+ * @param s new IO context
+ * @param max_packet_size maximum packet size (must be > 0)
+ * @return zero if no error.
+ */
+int url_open_dyn_packet_buf(ByteIOContext **s, int max_packet_size);
+
+/**
+ * Return the written size and a pointer to the buffer. The buffer
+ * must be freed with av_free().
+ * @param s IO context
+ * @param pbuffer pointer to a byte buffer
+ * @return the length of the byte buffer
+ */
+int url_close_dyn_buf(ByteIOContext *s, uint8_t **pbuffer);
+
+unsigned long ff_crc04C11DB7_update(unsigned long checksum, const uint8_t *buf,
+ unsigned int len);
+unsigned long get_checksum(ByteIOContext *s);
+void init_checksum(ByteIOContext *s,
+ unsigned long (*update_checksum)(unsigned long c, const uint8_t *p, unsigned int len),
+ unsigned long checksum);
+
+/* udp.c */
+int udp_set_remote_url(URLContext *h, const char *uri);
+int udp_get_local_port(URLContext *h);
+#if (LIBAVFORMAT_VERSION_MAJOR <= 52)
+int udp_get_file_handle(URLContext *h);
+#endif
+
+#endif /* AVFORMAT_AVIO_H */
diff --git a/lib-x86-32/include/libavutil/adler32.h b/lib-x86-32/include/libavutil/adler32.h
new file mode 100644
index 00000000..9626c805
--- /dev/null
+++ b/lib-x86-32/include/libavutil/adler32.h
@@ -0,0 +1,30 @@
+/*
+ * copyright (c) 2006 Mans Rullgard
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVUTIL_ADLER32_H
+#define AVUTIL_ADLER32_H
+
+#include <stdint.h>
+#include "attributes.h"
+
+unsigned long av_adler32_update(unsigned long adler, const uint8_t *buf,
+ unsigned int len) av_pure;
+
+#endif /* AVUTIL_ADLER32_H */
diff --git a/lib-x86-32/include/libavutil/attributes.h b/lib-x86-32/include/libavutil/attributes.h
new file mode 100644
index 00000000..da45234c
--- /dev/null
+++ b/lib-x86-32/include/libavutil/attributes.h
@@ -0,0 +1,113 @@
+/*
+ * copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * Macro definitions for various function/variable attributes
+ */
+
+#ifndef AVUTIL_ATTRIBUTES_H
+#define AVUTIL_ATTRIBUTES_H
+
+#ifdef __GNUC__
+# define AV_GCC_VERSION_AT_LEAST(x,y) (__GNUC__ > x || __GNUC__ == x && __GNUC_MINOR__ >= y)
+#else
+# define AV_GCC_VERSION_AT_LEAST(x,y) 0
+#endif
+
+#ifndef av_always_inline
+#if AV_GCC_VERSION_AT_LEAST(3,1)
+# define av_always_inline __attribute__((always_inline)) inline
+#else
+# define av_always_inline inline
+#endif
+#endif
+
+#ifndef av_noinline
+#if AV_GCC_VERSION_AT_LEAST(3,1)
+# define av_noinline __attribute__((noinline))
+#else
+# define av_noinline
+#endif
+#endif
+
+#ifndef av_pure
+#if AV_GCC_VERSION_AT_LEAST(3,1)
+# define av_pure __attribute__((pure))
+#else
+# define av_pure
+#endif
+#endif
+
+#ifndef av_const
+#if AV_GCC_VERSION_AT_LEAST(2,6)
+# define av_const __attribute__((const))
+#else
+# define av_const
+#endif
+#endif
+
+#ifndef av_cold
+#if (!defined(__ICC) || __ICC > 1110) && AV_GCC_VERSION_AT_LEAST(4,3)
+# define av_cold __attribute__((cold))
+#else
+# define av_cold
+#endif
+#endif
+
+#ifndef av_flatten
+#if (!defined(__ICC) || __ICC > 1110) && AV_GCC_VERSION_AT_LEAST(4,1)
+# define av_flatten __attribute__((flatten))
+#else
+# define av_flatten
+#endif
+#endif
+
+#ifndef attribute_deprecated
+#if AV_GCC_VERSION_AT_LEAST(3,1)
+# define attribute_deprecated __attribute__((deprecated))
+#else
+# define attribute_deprecated
+#endif
+#endif
+
+#ifndef av_unused
+#if defined(__GNUC__)
+# define av_unused __attribute__((unused))
+#else
+# define av_unused
+#endif
+#endif
+
+#ifndef av_uninit
+#if defined(__GNUC__) && !defined(__ICC)
+# define av_uninit(x) x=x
+#else
+# define av_uninit(x) x
+#endif
+#endif
+
+#ifdef __GNUC__
+# define av_builtin_constant_p __builtin_constant_p
+#else
+# define av_builtin_constant_p(x) 0
+#endif
+
+#endif /* AVUTIL_ATTRIBUTES_H */
diff --git a/lib-x86-32/include/libavutil/avconfig.h b/lib-x86-32/include/libavutil/avconfig.h
new file mode 100644
index 00000000..b028bb4f
--- /dev/null
+++ b/lib-x86-32/include/libavutil/avconfig.h
@@ -0,0 +1,5 @@
+/* Generated by ffconf */
+#ifndef AVUTIL_AVCONFIG_H
+#define AVUTIL_AVCONFIG_H
+#define AV_HAVE_BIGENDIAN 0
+#endif /* AVUTIL_AVCONFIG_H */
diff --git a/lib-x86-32/include/libavutil/avstring.h b/lib-x86-32/include/libavutil/avstring.h
new file mode 100644
index 00000000..01c2391b
--- /dev/null
+++ b/lib-x86-32/include/libavutil/avstring.h
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2007 Mans Rullgard
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVUTIL_AVSTRING_H
+#define AVUTIL_AVSTRING_H
+
+#include <stddef.h>
+
+/**
+ * Return non-zero if pfx is a prefix of str. If it is, *ptr is set to
+ * the address of the first character in str after the prefix.
+ *
+ * @param str input string
+ * @param pfx prefix to test
+ * @param ptr updated if the prefix is matched inside str
+ * @return non-zero if the prefix matches, zero otherwise
+ */
+int av_strstart(const char *str, const char *pfx, const char **ptr);
+
+/**
+ * Return non-zero if pfx is a prefix of str independent of case. If
+ * it is, *ptr is set to the address of the first character in str
+ * after the prefix.
+ *
+ * @param str input string
+ * @param pfx prefix to test
+ * @param ptr updated if the prefix is matched inside str
+ * @return non-zero if the prefix matches, zero otherwise
+ */
+int av_stristart(const char *str, const char *pfx, const char **ptr);
+
+/**
+ * Locate the first case-independent occurrence in the string haystack
+ * of the string needle. A zero-length string needle is considered to
+ * match at the start of haystack.
+ *
+ * This function is a case-insensitive version of the standard strstr().
+ *
+ * @param haystack string to search in
+ * @param needle string to search for
+ * @return pointer to the located match within haystack
+ * or a null pointer if no match
+ */
+char *av_stristr(const char *haystack, const char *needle);
+
+/**
+ * Copy the string src to dst, but no more than size - 1 bytes, and
+ * null-terminate dst.
+ *
+ * This function is the same as BSD strlcpy().
+ *
+ * @param dst destination buffer
+ * @param src source string
+ * @param size size of destination buffer
+ * @return the length of src
+ *
+ * WARNING: since the return value is the length of src, src absolutely
+ * _must_ be a properly 0-terminated string, otherwise this will read beyond
+ * the end of the buffer and possibly crash.
+ */
+size_t av_strlcpy(char *dst, const char *src, size_t size);
+
+/**
+ * Append the string src to the string dst, but to a total length of
+ * no more than size - 1 bytes, and null-terminate dst.
+ *
+ * This function is similar to BSD strlcat(), but differs when
+ * size <= strlen(dst).
+ *
+ * @param dst destination buffer
+ * @param src source string
+ * @param size size of destination buffer
+ * @return the total length of src and dst
+ *
+ * WARNING: since the return value use the length of src and dst, these absolutely
+ * _must_ be a properly 0-terminated strings, otherwise this will read beyond
+ * the end of the buffer and possibly crash.
+ */
+size_t av_strlcat(char *dst, const char *src, size_t size);
+
+/**
+ * Append output to a string, according to a format. Never write out of
+ * the destination buffer, and always put a terminating 0 within
+ * the buffer.
+ * @param dst destination buffer (string to which the output is
+ * appended)
+ * @param size total size of the destination buffer
+ * @param fmt printf-compatible format string, specifying how the
+ * following parameters are used
+ * @return the length of the string that would have been generated
+ * if enough space had been available
+ */
+size_t av_strlcatf(char *dst, size_t size, const char *fmt, ...);
+
+/**
+ * Convert a number to a av_malloced string.
+ */
+char *av_d2str(double d);
+
+#endif /* AVUTIL_AVSTRING_H */
diff --git a/lib-x86-32/include/libavutil/avutil.h b/lib-x86-32/include/libavutil/avutil.h
new file mode 100644
index 00000000..e9e07b92
--- /dev/null
+++ b/lib-x86-32/include/libavutil/avutil.h
@@ -0,0 +1,89 @@
+/*
+ * copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVUTIL_AVUTIL_H
+#define AVUTIL_AVUTIL_H
+
+/**
+ * @file
+ * external API header
+ */
+
+
+#define AV_STRINGIFY(s) AV_TOSTRING(s)
+#define AV_TOSTRING(s) #s
+
+#define AV_GLUE(a, b) a ## b
+#define AV_JOIN(a, b) AV_GLUE(a, b)
+
+#define AV_PRAGMA(s) _Pragma(#s)
+
+#define AV_VERSION_INT(a, b, c) (a<<16 | b<<8 | c)
+#define AV_VERSION_DOT(a, b, c) a ##.## b ##.## c
+#define AV_VERSION(a, b, c) AV_VERSION_DOT(a, b, c)
+
+#define LIBAVUTIL_VERSION_MAJOR 50
+#define LIBAVUTIL_VERSION_MINOR 15
+#define LIBAVUTIL_VERSION_MICRO 1
+
+#define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
+ LIBAVUTIL_VERSION_MINOR, \
+ LIBAVUTIL_VERSION_MICRO)
+#define LIBAVUTIL_VERSION AV_VERSION(LIBAVUTIL_VERSION_MAJOR, \
+ LIBAVUTIL_VERSION_MINOR, \
+ LIBAVUTIL_VERSION_MICRO)
+#define LIBAVUTIL_BUILD LIBAVUTIL_VERSION_INT
+
+#define LIBAVUTIL_IDENT "Lavu" AV_STRINGIFY(LIBAVUTIL_VERSION)
+
+/**
+ * Returns the LIBAVUTIL_VERSION_INT constant.
+ */
+unsigned avutil_version(void);
+
+/**
+ * Returns the libavutil build-time configuration.
+ */
+const char *avutil_configuration(void);
+
+/**
+ * Returns the libavutil license.
+ */
+const char *avutil_license(void);
+
+enum AVMediaType {
+ AVMEDIA_TYPE_UNKNOWN = -1,
+ AVMEDIA_TYPE_VIDEO,
+ AVMEDIA_TYPE_AUDIO,
+ AVMEDIA_TYPE_DATA,
+ AVMEDIA_TYPE_SUBTITLE,
+ AVMEDIA_TYPE_ATTACHMENT,
+ AVMEDIA_TYPE_NB
+};
+
+#include "common.h"
+#include "error.h"
+#include "mathematics.h"
+#include "rational.h"
+#include "intfloat_readwrite.h"
+#include "log.h"
+#include "pixfmt.h"
+
+#endif /* AVUTIL_AVUTIL_H */
diff --git a/lib-x86-32/include/libavutil/base64.h b/lib-x86-32/include/libavutil/base64.h
new file mode 100644
index 00000000..103860ef
--- /dev/null
+++ b/lib-x86-32/include/libavutil/base64.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2006 Ryan Martell. (rdm4@martellventures.com)
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVUTIL_BASE64_H
+#define AVUTIL_BASE64_H
+
+#include <stdint.h>
+
+/**
+ * Decodes the base64-encoded string in in and puts the decoded
+ * data in out.
+ *
+ * @param out_size size in bytes of the out buffer, it should be at
+ * least 3/4 of the length of in
+ * @return the number of bytes written, or a negative value in case of
+ * error
+ */
+int av_base64_decode(uint8_t *out, const char *in, int out_size);
+
+/**
+ * Encodes in base64 the data in in and puts the resulting string
+ * in out.
+ *
+ * @param out_size size in bytes of the out string, it should be at
+ * least ((in_size + 2) / 3) * 4 + 1
+ * @param in_size size in bytes of the in buffer
+ * @return the string containing the encoded data, or NULL in case of
+ * error
+ */
+char *av_base64_encode(char *out, int out_size, const uint8_t *in, int in_size);
+
+#endif /* AVUTIL_BASE64_H */
diff --git a/lib-x86-32/include/libavutil/common.h b/lib-x86-32/include/libavutil/common.h
new file mode 100644
index 00000000..4aa00a99
--- /dev/null
+++ b/lib-x86-32/include/libavutil/common.h
@@ -0,0 +1,308 @@
+/*
+ * copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * common internal and external API header
+ */
+
+#ifndef AVUTIL_COMMON_H
+#define AVUTIL_COMMON_H
+
+#include <ctype.h>
+#include <errno.h>
+#include <inttypes.h>
+#include <limits.h>
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "attributes.h"
+
+//rounded division & shift
+#define RSHIFT(a,b) ((a) > 0 ? ((a) + ((1<<(b))>>1))>>(b) : ((a) + ((1<<(b))>>1)-1)>>(b))
+/* assume b>0 */
+#define ROUNDED_DIV(a,b) (((a)>0 ? (a) + ((b)>>1) : (a) - ((b)>>1))/(b))
+#define FFABS(a) ((a) >= 0 ? (a) : (-(a)))
+#define FFSIGN(a) ((a) > 0 ? 1 : -1)
+
+#define FFMAX(a,b) ((a) > (b) ? (a) : (b))
+#define FFMAX3(a,b,c) FFMAX(FFMAX(a,b),c)
+#define FFMIN(a,b) ((a) > (b) ? (b) : (a))
+#define FFMIN3(a,b,c) FFMIN(FFMIN(a,b),c)
+
+#define FFSWAP(type,a,b) do{type SWAP_tmp= b; b= a; a= SWAP_tmp;}while(0)
+#define FF_ARRAY_ELEMS(a) (sizeof(a) / sizeof((a)[0]))
+#define FFALIGN(x, a) (((x)+(a)-1)&~((a)-1))
+
+/* misc math functions */
+extern const uint8_t ff_log2_tab[256];
+
+extern const uint8_t av_reverse[256];
+
+static inline av_const int av_log2_c(unsigned int v)
+{
+ int n = 0;
+ if (v & 0xffff0000) {
+ v >>= 16;
+ n += 16;
+ }
+ if (v & 0xff00) {
+ v >>= 8;
+ n += 8;
+ }
+ n += ff_log2_tab[v];
+
+ return n;
+}
+
+static inline av_const int av_log2_16bit_c(unsigned int v)
+{
+ int n = 0;
+ if (v & 0xff00) {
+ v >>= 8;
+ n += 8;
+ }
+ n += ff_log2_tab[v];
+
+ return n;
+}
+
+#ifdef HAVE_AV_CONFIG_H
+# include "config.h"
+# include "intmath.h"
+#endif
+
+#ifndef av_log2
+# define av_log2 av_log2_c
+#endif
+#ifndef av_log2_16bit
+# define av_log2_16bit av_log2_16bit_c
+#endif
+
+/**
+ * Clips a signed integer value into the amin-amax range.
+ * @param a value to clip
+ * @param amin minimum value of the clip range
+ * @param amax maximum value of the clip range
+ * @return clipped value
+ */
+static inline av_const int av_clip(int a, int amin, int amax)
+{
+ if (a < amin) return amin;
+ else if (a > amax) return amax;
+ else return a;
+}
+
+/**
+ * Clips a signed integer value into the 0-255 range.
+ * @param a value to clip
+ * @return clipped value
+ */
+static inline av_const uint8_t av_clip_uint8(int a)
+{
+ if (a&(~0xFF)) return (-a)>>31;
+ else return a;
+}
+
+/**
+ * Clips a signed integer value into the 0-65535 range.
+ * @param a value to clip
+ * @return clipped value
+ */
+static inline av_const uint16_t av_clip_uint16(int a)
+{
+ if (a&(~0xFFFF)) return (-a)>>31;
+ else return a;
+}
+
+/**
+ * Clips a signed integer value into the -32768,32767 range.
+ * @param a value to clip
+ * @return clipped value
+ */
+static inline av_const int16_t av_clip_int16(int a)
+{
+ if ((a+0x8000) & ~0xFFFF) return (a>>31) ^ 0x7FFF;
+ else return a;
+}
+
+/**
+ * Clips a signed 64-bit integer value into the -2147483648,2147483647 range.
+ * @param a value to clip
+ * @return clipped value
+ */
+static inline av_const int32_t av_clipl_int32(int64_t a)
+{
+ if ((a+0x80000000u) & ~UINT64_C(0xFFFFFFFF)) return (a>>63) ^ 0x7FFFFFFF;
+ else return a;
+}
+
+/**
+ * Clips a float value into the amin-amax range.
+ * @param a value to clip
+ * @param amin minimum value of the clip range
+ * @param amax maximum value of the clip range
+ * @return clipped value
+ */
+static inline av_const float av_clipf(float a, float amin, float amax)
+{
+ if (a < amin) return amin;
+ else if (a > amax) return amax;
+ else return a;
+}
+
+/** Computes ceil(log2(x)).
+ * @param x value used to compute ceil(log2(x))
+ * @return computed ceiling of log2(x)
+ */
+static inline av_const int av_ceil_log2(int x)
+{
+ return av_log2((x - 1) << 1);
+}
+
+#define MKTAG(a,b,c,d) (a | (b << 8) | (c << 16) | (d << 24))
+#define MKBETAG(a,b,c,d) (d | (c << 8) | (b << 16) | (a << 24))
+
+/*!
+ * \def GET_UTF8(val, GET_BYTE, ERROR)
+ * Converts a UTF-8 character (up to 4 bytes long) to its 32-bit UCS-4 encoded form
+ * \param val is the output and should be of type uint32_t. It holds the converted
+ * UCS-4 character and should be a left value.
+ * \param GET_BYTE gets UTF-8 encoded bytes from any proper source. It can be
+ * a function or a statement whose return value or evaluated value is of type
+ * uint8_t. It will be executed up to 4 times for values in the valid UTF-8 range,
+ * and up to 7 times in the general case.
+ * \param ERROR action that should be taken when an invalid UTF-8 byte is returned
+ * from GET_BYTE. It should be a statement that jumps out of the macro,
+ * like exit(), goto, return, break, or continue.
+ */
+#define GET_UTF8(val, GET_BYTE, ERROR)\
+ val= GET_BYTE;\
+ {\
+ int ones= 7 - av_log2(val ^ 255);\
+ if(ones==1)\
+ ERROR\
+ val&= 127>>ones;\
+ while(--ones > 0){\
+ int tmp= GET_BYTE - 128;\
+ if(tmp>>6)\
+ ERROR\
+ val= (val<<6) + tmp;\
+ }\
+ }
+
+/*!
+ * \def GET_UTF16(val, GET_16BIT, ERROR)
+ * Converts a UTF-16 character (2 or 4 bytes) to its 32-bit UCS-4 encoded form
+ * \param val is the output and should be of type uint32_t. It holds the converted
+ * UCS-4 character and should be a left value.
+ * \param GET_16BIT gets two bytes of UTF-16 encoded data converted to native endianness.
+ * It can be a function or a statement whose return value or evaluated value is of type
+ * uint16_t. It will be executed up to 2 times.
+ * \param ERROR action that should be taken when an invalid UTF-16 surrogate is
+ * returned from GET_BYTE. It should be a statement that jumps out of the macro,
+ * like exit(), goto, return, break, or continue.
+ */
+#define GET_UTF16(val, GET_16BIT, ERROR)\
+ val = GET_16BIT;\
+ {\
+ unsigned int hi = val - 0xD800;\
+ if (hi < 0x800) {\
+ val = GET_16BIT - 0xDC00;\
+ if (val > 0x3FFU || hi > 0x3FFU)\
+ ERROR\
+ val += (hi<<10) + 0x10000;\
+ }\
+ }\
+
+/*!
+ * \def PUT_UTF8(val, tmp, PUT_BYTE)
+ * Converts a 32-bit Unicode character to its UTF-8 encoded form (up to 4 bytes long).
+ * \param val is an input-only argument and should be of type uint32_t. It holds
+ * a UCS-4 encoded Unicode character that is to be converted to UTF-8. If
+ * val is given as a function it is executed only once.
+ * \param tmp is a temporary variable and should be of type uint8_t. It
+ * represents an intermediate value during conversion that is to be
+ * output by PUT_BYTE.
+ * \param PUT_BYTE writes the converted UTF-8 bytes to any proper destination.
+ * It could be a function or a statement, and uses tmp as the input byte.
+ * For example, PUT_BYTE could be "*output++ = tmp;" PUT_BYTE will be
+ * executed up to 4 times for values in the valid UTF-8 range and up to
+ * 7 times in the general case, depending on the length of the converted
+ * Unicode character.
+ */
+#define PUT_UTF8(val, tmp, PUT_BYTE)\
+ {\
+ int bytes, shift;\
+ uint32_t in = val;\
+ if (in < 0x80) {\
+ tmp = in;\
+ PUT_BYTE\
+ } else {\
+ bytes = (av_log2(in) + 4) / 5;\
+ shift = (bytes - 1) * 6;\
+ tmp = (256 - (256 >> bytes)) | (in >> shift);\
+ PUT_BYTE\
+ while (shift >= 6) {\
+ shift -= 6;\
+ tmp = 0x80 | ((in >> shift) & 0x3f);\
+ PUT_BYTE\
+ }\
+ }\
+ }
+
+/*!
+ * \def PUT_UTF16(val, tmp, PUT_16BIT)
+ * Converts a 32-bit Unicode character to its UTF-16 encoded form (2 or 4 bytes).
+ * \param val is an input-only argument and should be of type uint32_t. It holds
+ * a UCS-4 encoded Unicode character that is to be converted to UTF-16. If
+ * val is given as a function it is executed only once.
+ * \param tmp is a temporary variable and should be of type uint16_t. It
+ * represents an intermediate value during conversion that is to be
+ * output by PUT_16BIT.
+ * \param PUT_16BIT writes the converted UTF-16 data to any proper destination
+ * in desired endianness. It could be a function or a statement, and uses tmp
+ * as the input byte. For example, PUT_BYTE could be "*output++ = tmp;"
+ * PUT_BYTE will be executed 1 or 2 times depending on input character.
+ */
+#define PUT_UTF16(val, tmp, PUT_16BIT)\
+ {\
+ uint32_t in = val;\
+ if (in < 0x10000) {\
+ tmp = in;\
+ PUT_16BIT\
+ } else {\
+ tmp = 0xD800 | ((in - 0x10000) >> 10);\
+ PUT_16BIT\
+ tmp = 0xDC00 | ((in - 0x10000) & 0x3FF);\
+ PUT_16BIT\
+ }\
+ }\
+
+
+
+#include "mem.h"
+
+#ifdef HAVE_AV_CONFIG_H
+# include "internal.h"
+#endif /* HAVE_AV_CONFIG_H */
+
+#endif /* AVUTIL_COMMON_H */
diff --git a/lib-x86-32/include/libavutil/crc.h b/lib-x86-32/include/libavutil/crc.h
new file mode 100644
index 00000000..6c0baab5
--- /dev/null
+++ b/lib-x86-32/include/libavutil/crc.h
@@ -0,0 +1,44 @@
+/*
+ * copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVUTIL_CRC_H
+#define AVUTIL_CRC_H
+
+#include <stdint.h>
+#include <stddef.h>
+#include "attributes.h"
+
+typedef uint32_t AVCRC;
+
+typedef enum {
+ AV_CRC_8_ATM,
+ AV_CRC_16_ANSI,
+ AV_CRC_16_CCITT,
+ AV_CRC_32_IEEE,
+ AV_CRC_32_IEEE_LE, /*< reversed bitorder version of AV_CRC_32_IEEE */
+ AV_CRC_MAX, /*< Not part of public API! Do not use outside libavutil. */
+}AVCRCId;
+
+int av_crc_init(AVCRC *ctx, int le, int bits, uint32_t poly, int ctx_size);
+const AVCRC *av_crc_get_table(AVCRCId crc_id);
+uint32_t av_crc(const AVCRC *ctx, uint32_t start_crc, const uint8_t *buffer, size_t length) av_pure;
+
+#endif /* AVUTIL_CRC_H */
+
diff --git a/lib-x86-32/include/libavutil/error.h b/lib-x86-32/include/libavutil/error.h
new file mode 100644
index 00000000..13a9a359
--- /dev/null
+++ b/lib-x86-32/include/libavutil/error.h
@@ -0,0 +1,72 @@
+/*
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * error code definitions
+ */
+
+#ifndef AVUTIL_ERROR_H
+#define AVUTIL_ERROR_H
+
+#include <errno.h>
+#include "avutil.h"
+
+/* error handling */
+#if EDOM > 0
+#define AVERROR(e) (-(e)) ///< Returns a negative error code from a POSIX error code, to return from library functions.
+#define AVUNERROR(e) (-(e)) ///< Returns a POSIX error code from a library function error return value.
+#else
+/* Some platforms have E* and errno already negated. */
+#define AVERROR(e) (e)
+#define AVUNERROR(e) (e)
+#endif
+
+#if LIBAVUTIL_VERSION_MAJOR < 51
+#define AVERROR_INVALIDDATA AVERROR(EINVAL) ///< Invalid data found when processing input
+#define AVERROR_IO AVERROR(EIO) ///< I/O error
+#define AVERROR_NOENT AVERROR(ENOENT) ///< No such file or directory
+#define AVERROR_NOFMT AVERROR(EILSEQ) ///< Unknown format
+#define AVERROR_NOMEM AVERROR(ENOMEM) ///< Not enough memory
+#define AVERROR_NOTSUPP AVERROR(ENOSYS) ///< Operation not supported
+#define AVERROR_NUMEXPECTED AVERROR(EDOM) ///< Number syntax expected in filename
+#define AVERROR_UNKNOWN AVERROR(EINVAL) ///< Unknown error
+#endif
+
+#define AVERROR_EOF AVERROR(EPIPE) ///< End of file
+
+#define AVERROR_PATCHWELCOME (-MKTAG('P','A','W','E')) ///< Not yet implemented in FFmpeg, patches welcome
+
+#if LIBAVUTIL_VERSION_MAJOR > 50
+#define AVERROR_INVALIDDATA (-MKTAG('I','N','D','A')) ///< Invalid data found when processing input
+#define AVERROR_NUMEXPECTED (-MKTAG('N','U','E','X')) ///< Number syntax expected in filename
+#endif
+
+/**
+ * Puts a description of the AVERROR code errnum in errbuf.
+ * In case of failure the global variable errno is set to indicate the
+ * error. Even in case of failure av_strerror() will print a generic
+ * error message indicating the errnum provided to errbuf.
+ *
+ * @param errbuf_size the size in bytes of errbuf
+ * @return 0 on success, a negative value if a description for errnum
+ * cannot be found
+ */
+int av_strerror(int errnum, char *errbuf, size_t errbuf_size);
+
+#endif /* AVUTIL_ERROR_H */
diff --git a/lib-x86-32/include/libavutil/fifo.h b/lib-x86-32/include/libavutil/fifo.h
new file mode 100644
index 00000000..fb1ed47f
--- /dev/null
+++ b/lib-x86-32/include/libavutil/fifo.h
@@ -0,0 +1,116 @@
+/*
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * a very simple circular buffer FIFO implementation
+ */
+
+#ifndef AVUTIL_FIFO_H
+#define AVUTIL_FIFO_H
+
+#include <stdint.h>
+
+typedef struct AVFifoBuffer {
+ uint8_t *buffer;
+ uint8_t *rptr, *wptr, *end;
+ uint32_t rndx, wndx;
+} AVFifoBuffer;
+
+/**
+ * Initializes an AVFifoBuffer.
+ * @param size of FIFO
+ * @return AVFifoBuffer or NULL in case of memory allocation failure
+ */
+AVFifoBuffer *av_fifo_alloc(unsigned int size);
+
+/**
+ * Frees an AVFifoBuffer.
+ * @param *f AVFifoBuffer to free
+ */
+void av_fifo_free(AVFifoBuffer *f);
+
+/**
+ * Resets the AVFifoBuffer to the state right after av_fifo_alloc, in particular it is emptied.
+ * @param *f AVFifoBuffer to reset
+ */
+void av_fifo_reset(AVFifoBuffer *f);
+
+/**
+ * Returns the amount of data in bytes in the AVFifoBuffer, that is the
+ * amount of data you can read from it.
+ * @param *f AVFifoBuffer to read from
+ * @return size
+ */
+int av_fifo_size(AVFifoBuffer *f);
+
+/**
+ * Returns the amount of space in bytes in the AVFifoBuffer, that is the
+ * amount of data you can write into it.
+ * @param *f AVFifoBuffer to write into
+ * @return size
+ */
+int av_fifo_space(AVFifoBuffer *f);
+
+/**
+ * Feeds data from an AVFifoBuffer to a user-supplied callback.
+ * @param *f AVFifoBuffer to read from
+ * @param buf_size number of bytes to read
+ * @param *func generic read function
+ * @param *dest data destination
+ */
+int av_fifo_generic_read(AVFifoBuffer *f, void *dest, int buf_size, void (*func)(void*, void*, int));
+
+/**
+ * Feeds data from a user-supplied callback to an AVFifoBuffer.
+ * @param *f AVFifoBuffer to write to
+ * @param *src data source; non-const since it may be used as a
+ * modifiable context by the function defined in func
+ * @param size number of bytes to write
+ * @param *func generic write function; the first parameter is src,
+ * the second is dest_buf, the third is dest_buf_size.
+ * func must return the number of bytes written to dest_buf, or <= 0 to
+ * indicate no more data available to write.
+ * If func is NULL, src is interpreted as a simple byte array for source data.
+ * @return the number of bytes written to the FIFO
+ */
+int av_fifo_generic_write(AVFifoBuffer *f, void *src, int size, int (*func)(void*, void*, int));
+
+/**
+ * Resizes an AVFifoBuffer.
+ * @param *f AVFifoBuffer to resize
+ * @param size new AVFifoBuffer size in bytes
+ * @return <0 for failure, >=0 otherwise
+ */
+int av_fifo_realloc2(AVFifoBuffer *f, unsigned int size);
+
+/**
+ * Reads and discards the specified amount of data from an AVFifoBuffer.
+ * @param *f AVFifoBuffer to read from
+ * @param size amount of data to read in bytes
+ */
+void av_fifo_drain(AVFifoBuffer *f, int size);
+
+static inline uint8_t av_fifo_peek(AVFifoBuffer *f, int offs)
+{
+ uint8_t *ptr = f->rptr + offs;
+ if (ptr >= f->end)
+ ptr -= f->end - f->buffer;
+ return *ptr;
+}
+#endif /* AVUTIL_FIFO_H */
diff --git a/lib-x86-32/include/libavutil/intfloat_readwrite.h b/lib-x86-32/include/libavutil/intfloat_readwrite.h
new file mode 100644
index 00000000..1b80fc6e
--- /dev/null
+++ b/lib-x86-32/include/libavutil/intfloat_readwrite.h
@@ -0,0 +1,40 @@
+/*
+ * copyright (c) 2005 Michael Niedermayer <michaelni@gmx.at>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVUTIL_INTFLOAT_READWRITE_H
+#define AVUTIL_INTFLOAT_READWRITE_H
+
+#include <stdint.h>
+#include "attributes.h"
+
+/* IEEE 80 bits extended float */
+typedef struct AVExtFloat {
+ uint8_t exponent[2];
+ uint8_t mantissa[8];
+} AVExtFloat;
+
+double av_int2dbl(int64_t v) av_const;
+float av_int2flt(int32_t v) av_const;
+double av_ext2dbl(const AVExtFloat ext) av_const;
+int64_t av_dbl2int(double d) av_const;
+int32_t av_flt2int(float d) av_const;
+AVExtFloat av_dbl2ext(double d) av_const;
+
+#endif /* AVUTIL_INTFLOAT_READWRITE_H */
diff --git a/lib-x86-32/include/libavutil/log.h b/lib-x86-32/include/libavutil/log.h
new file mode 100644
index 00000000..1c3e4901
--- /dev/null
+++ b/lib-x86-32/include/libavutil/log.h
@@ -0,0 +1,123 @@
+/*
+ * copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVUTIL_LOG_H
+#define AVUTIL_LOG_H
+
+#include <stdarg.h>
+#include "avutil.h"
+
+/**
+ * Describes the class of an AVClass context structure. That is an
+ * arbitrary struct of which the first field is a pointer to an
+ * AVClass struct (e.g. AVCodecContext, AVFormatContext etc.).
+ */
+typedef struct {
+ /**
+ * The name of the class; usually it is the same name as the
+ * context structure type to which the AVClass is associated.
+ */
+ const char* class_name;
+
+ /**
+ * A pointer to a function which returns the name of a context
+ * instance ctx associated with the class.
+ */
+ const char* (*item_name)(void* ctx);
+
+ /**
+ * a pointer to the first option specified in the class if any or NULL
+ *
+ * @see av_set_default_options()
+ */
+ const struct AVOption *option;
+
+ /**
+ * LIBAVUTIL_VERSION with which this structure was created.
+ * This is used to allow fields to be added without requiring major
+ * version bumps everywhere.
+ */
+
+ int version;
+} AVClass;
+
+/* av_log API */
+
+#define AV_LOG_QUIET -8
+
+/**
+ * Something went really wrong and we will crash now.
+ */
+#define AV_LOG_PANIC 0
+
+/**
+ * Something went wrong and recovery is not possible.
+ * For example, no header was found for a format which depends
+ * on headers or an illegal combination of parameters is used.
+ */
+#define AV_LOG_FATAL 8
+
+/**
+ * Something went wrong and cannot losslessly be recovered.
+ * However, not all future data is affected.
+ */
+#define AV_LOG_ERROR 16
+
+/**
+ * Something somehow does not look correct. This may or may not
+ * lead to problems. An example would be the use of '-vstrict -2'.
+ */
+#define AV_LOG_WARNING 24
+
+#define AV_LOG_INFO 32
+#define AV_LOG_VERBOSE 40
+
+/**
+ * Stuff which is only useful for libav* developers.
+ */
+#define AV_LOG_DEBUG 48
+
+/**
+ * Sends the specified message to the log if the level is less than or equal
+ * to the current av_log_level. By default, all logging messages are sent to
+ * stderr. This behavior can be altered by setting a different av_vlog callback
+ * function.
+ *
+ * @param avcl A pointer to an arbitrary struct of which the first field is a
+ * pointer to an AVClass struct.
+ * @param level The importance level of the message, lower values signifying
+ * higher importance.
+ * @param fmt The format string (printf-compatible) that specifies how
+ * subsequent arguments are converted to output.
+ * @see av_vlog
+ */
+#ifdef __GNUC__
+void av_log(void*, int level, const char *fmt, ...) __attribute__ ((__format__ (__printf__, 3, 4)));
+#else
+void av_log(void*, int level, const char *fmt, ...);
+#endif
+
+void av_vlog(void*, int level, const char *fmt, va_list);
+int av_log_get_level(void);
+void av_log_set_level(int);
+void av_log_set_callback(void (*)(void*, int, const char*, va_list));
+void av_log_default_callback(void* ptr, int level, const char* fmt, va_list vl);
+
+#endif /* AVUTIL_LOG_H */
diff --git a/lib-x86-32/include/libavutil/lzo.h b/lib-x86-32/include/libavutil/lzo.h
new file mode 100644
index 00000000..6788054b
--- /dev/null
+++ b/lib-x86-32/include/libavutil/lzo.h
@@ -0,0 +1,66 @@
+/*
+ * LZO 1x decompression
+ * copyright (c) 2006 Reimar Doeffinger
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVUTIL_LZO_H
+#define AVUTIL_LZO_H
+
+#include <stdint.h>
+
+/** \defgroup errflags Error flags returned by av_lzo1x_decode
+ * \{ */
+//! end of the input buffer reached before decoding finished
+#define AV_LZO_INPUT_DEPLETED 1
+//! decoded data did not fit into output buffer
+#define AV_LZO_OUTPUT_FULL 2
+//! a reference to previously decoded data was wrong
+#define AV_LZO_INVALID_BACKPTR 4
+//! a non-specific error in the compressed bitstream
+#define AV_LZO_ERROR 8
+/** \} */
+
+#define AV_LZO_INPUT_PADDING 8
+#define AV_LZO_OUTPUT_PADDING 12
+
+/**
+ * \brief Decodes LZO 1x compressed data.
+ * \param out output buffer
+ * \param outlen size of output buffer, number of bytes left are returned here
+ * \param in input buffer
+ * \param inlen size of input buffer, number of bytes left are returned here
+ * \return 0 on success, otherwise a combination of the error flags above
+ *
+ * Make sure all buffers are appropriately padded, in must provide
+ * AV_LZO_INPUT_PADDING, out must provide AV_LZO_OUTPUT_PADDING additional bytes.
+ */
+int av_lzo1x_decode(void *out, int *outlen, const void *in, int *inlen);
+
+/**
+ * \brief deliberately overlapping memcpy implementation
+ * \param dst destination buffer; must be padded with 12 additional bytes
+ * \param back how many bytes back we start (the initial size of the overlapping window)
+ * \param cnt number of bytes to copy, must be >= 0
+ *
+ * cnt > back is valid, this will copy the bytes we just copied,
+ * thus creating a repeating pattern with a period length of back.
+ */
+void av_memcpy_backptr(uint8_t *dst, int back, int cnt);
+
+#endif /* AVUTIL_LZO_H */
diff --git a/lib-x86-32/include/libavutil/mathematics.h b/lib-x86-32/include/libavutil/mathematics.h
new file mode 100644
index 00000000..e198aef8
--- /dev/null
+++ b/lib-x86-32/include/libavutil/mathematics.h
@@ -0,0 +1,98 @@
+/*
+ * copyright (c) 2005 Michael Niedermayer <michaelni@gmx.at>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVUTIL_MATHEMATICS_H
+#define AVUTIL_MATHEMATICS_H
+
+#include <stdint.h>
+#include <math.h>
+#include "attributes.h"
+#include "rational.h"
+
+#ifndef M_E
+#define M_E 2.7182818284590452354 /* e */
+#endif
+#ifndef M_LN2
+#define M_LN2 0.69314718055994530942 /* log_e 2 */
+#endif
+#ifndef M_LN10
+#define M_LN10 2.30258509299404568402 /* log_e 10 */
+#endif
+#ifndef M_LOG2_10
+#define M_LOG2_10 3.32192809488736234787 /* log_2 10 */
+#endif
+#ifndef M_PI
+#define M_PI 3.14159265358979323846 /* pi */
+#endif
+#ifndef M_SQRT1_2
+#define M_SQRT1_2 0.70710678118654752440 /* 1/sqrt(2) */
+#endif
+#ifndef M_SQRT2
+#define M_SQRT2 1.41421356237309504880 /* sqrt(2) */
+#endif
+#ifndef NAN
+#define NAN (0.0/0.0)
+#endif
+#ifndef INFINITY
+#define INFINITY (1.0/0.0)
+#endif
+
+enum AVRounding {
+ AV_ROUND_ZERO = 0, ///< Round toward zero.
+ AV_ROUND_INF = 1, ///< Round away from zero.
+ AV_ROUND_DOWN = 2, ///< Round toward -infinity.
+ AV_ROUND_UP = 3, ///< Round toward +infinity.
+ AV_ROUND_NEAR_INF = 5, ///< Round to nearest and halfway cases away from zero.
+};
+
+/**
+ * Returns the greatest common divisor of a and b.
+ * If both a and b are 0 or either or both are <0 then behavior is
+ * undefined.
+ */
+int64_t av_const av_gcd(int64_t a, int64_t b);
+
+/**
+ * Rescales a 64-bit integer with rounding to nearest.
+ * A simple a*b/c isn't possible as it can overflow.
+ */
+int64_t av_rescale(int64_t a, int64_t b, int64_t c) av_const;
+
+/**
+ * Rescales a 64-bit integer with specified rounding.
+ * A simple a*b/c isn't possible as it can overflow.
+ */
+int64_t av_rescale_rnd(int64_t a, int64_t b, int64_t c, enum AVRounding) av_const;
+
+/**
+ * Rescales a 64-bit integer by 2 rational numbers.
+ */
+int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq) av_const;
+
+/**
+ * Compares 2 timestamps each in its own timebases.
+ * The result of the function is undefined if one of the timestamps
+ * is outside the int64_t range when represented in the others timebase.
+ * @return -1 if ts_a is before ts_b, 1 if ts_a is after ts_b or 0 if they represent the same position
+ */
+int av_compare_ts(int64_t ts_a, AVRational tb_a, int64_t ts_b, AVRational tb_b);
+
+
+#endif /* AVUTIL_MATHEMATICS_H */
diff --git a/lib-x86-32/include/libavutil/md5.h b/lib-x86-32/include/libavutil/md5.h
new file mode 100644
index 00000000..969202a8
--- /dev/null
+++ b/lib-x86-32/include/libavutil/md5.h
@@ -0,0 +1,36 @@
+/*
+ * copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVUTIL_MD5_H
+#define AVUTIL_MD5_H
+
+#include <stdint.h>
+
+extern const int av_md5_size;
+
+struct AVMD5;
+
+void av_md5_init(struct AVMD5 *ctx);
+void av_md5_update(struct AVMD5 *ctx, const uint8_t *src, const int len);
+void av_md5_final(struct AVMD5 *ctx, uint8_t *dst);
+void av_md5_sum(uint8_t *dst, const uint8_t *src, const int len);
+
+#endif /* AVUTIL_MD5_H */
+
diff --git a/lib-x86-32/include/libavutil/mem.h b/lib-x86-32/include/libavutil/mem.h
new file mode 100644
index 00000000..14887927
--- /dev/null
+++ b/lib-x86-32/include/libavutil/mem.h
@@ -0,0 +1,125 @@
+/*
+ * copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * memory handling functions
+ */
+
+#ifndef AVUTIL_MEM_H
+#define AVUTIL_MEM_H
+
+#include "attributes.h"
+
+#if defined(__ICC) || defined(__SUNPRO_C)
+ #define DECLARE_ALIGNED(n,t,v) t __attribute__ ((aligned (n))) v
+ #define DECLARE_ASM_CONST(n,t,v) const t __attribute__ ((aligned (n))) v
+#elif defined(__TI_COMPILER_VERSION__)
+ #define DECLARE_ALIGNED(n,t,v) \
+ AV_PRAGMA(DATA_ALIGN(v,n)) \
+ t __attribute__((aligned(n))) v
+ #define DECLARE_ASM_CONST(n,t,v) \
+ AV_PRAGMA(DATA_ALIGN(v,n)) \
+ static const t __attribute__((aligned(n))) v
+#elif defined(__GNUC__)
+ #define DECLARE_ALIGNED(n,t,v) t __attribute__ ((aligned (n))) v
+ #define DECLARE_ASM_CONST(n,t,v) static const t attribute_used __attribute__ ((aligned (n))) v
+#elif defined(_MSC_VER)
+ #define DECLARE_ALIGNED(n,t,v) __declspec(align(n)) t v
+ #define DECLARE_ASM_CONST(n,t,v) __declspec(align(n)) static const t v
+#else
+ #define DECLARE_ALIGNED(n,t,v) t v
+ #define DECLARE_ASM_CONST(n,t,v) static const t v
+#endif
+
+#if AV_GCC_VERSION_AT_LEAST(3,1)
+ #define av_malloc_attrib __attribute__((__malloc__))
+#else
+ #define av_malloc_attrib
+#endif
+
+#if (!defined(__ICC) || __ICC > 1110) && AV_GCC_VERSION_AT_LEAST(4,3)
+ #define av_alloc_size(n) __attribute__((alloc_size(n)))
+#else
+ #define av_alloc_size(n)
+#endif
+
+/**
+ * Allocates a block of size bytes with alignment suitable for all
+ * memory accesses (including vectors if available on the CPU).
+ * @param size Size in bytes for the memory block to be allocated.
+ * @return Pointer to the allocated block, NULL if the block cannot
+ * be allocated.
+ * @see av_mallocz()
+ */
+void *av_malloc(unsigned int size) av_malloc_attrib av_alloc_size(1);
+
+/**
+ * Allocates or reallocates a block of memory.
+ * If ptr is NULL and size > 0, allocates a new block. If
+ * size is zero, frees the memory block pointed to by ptr.
+ * @param size Size in bytes for the memory block to be allocated or
+ * reallocated.
+ * @param ptr Pointer to a memory block already allocated with
+ * av_malloc(z)() or av_realloc() or NULL.
+ * @return Pointer to a newly reallocated block or NULL if the block
+ * cannot be reallocated or the function is used to free the memory block.
+ * @see av_fast_realloc()
+ */
+void *av_realloc(void *ptr, unsigned int size) av_alloc_size(2);
+
+/**
+ * Frees a memory block which has been allocated with av_malloc(z)() or
+ * av_realloc().
+ * @param ptr Pointer to the memory block which should be freed.
+ * @note ptr = NULL is explicitly allowed.
+ * @note It is recommended that you use av_freep() instead.
+ * @see av_freep()
+ */
+void av_free(void *ptr);
+
+/**
+ * Allocates a block of size bytes with alignment suitable for all
+ * memory accesses (including vectors if available on the CPU) and
+ * zeroes all the bytes of the block.
+ * @param size Size in bytes for the memory block to be allocated.
+ * @return Pointer to the allocated block, NULL if it cannot be allocated.
+ * @see av_malloc()
+ */
+void *av_mallocz(unsigned int size) av_malloc_attrib av_alloc_size(1);
+
+/**
+ * Duplicates the string s.
+ * @param s string to be duplicated
+ * @return Pointer to a newly allocated string containing a
+ * copy of s or NULL if the string cannot be allocated.
+ */
+char *av_strdup(const char *s) av_malloc_attrib;
+
+/**
+ * Frees a memory block which has been allocated with av_malloc(z)() or
+ * av_realloc() and set the pointer pointing to it to NULL.
+ * @param ptr Pointer to the pointer to the memory block which should
+ * be freed.
+ * @see av_free()
+ */
+void av_freep(void *ptr);
+
+#endif /* AVUTIL_MEM_H */
diff --git a/lib-x86-32/include/libavutil/pixdesc.h b/lib-x86-32/include/libavutil/pixdesc.h
new file mode 100644
index 00000000..8e4c85d7
--- /dev/null
+++ b/lib-x86-32/include/libavutil/pixdesc.h
@@ -0,0 +1,154 @@
+/*
+ * pixel format descriptor
+ * Copyright (c) 2009 Michael Niedermayer <michaelni@gmx.at>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVUTIL_PIXDESC_H
+#define AVUTIL_PIXDESC_H
+
+#include <inttypes.h>
+
+typedef struct AVComponentDescriptor{
+ uint16_t plane :2; ///< which of the 4 planes contains the component
+
+ /**
+ * Number of elements between 2 horizontally consecutive pixels minus 1.
+ * Elements are bits for bitstream formats, bytes otherwise.
+ */
+ uint16_t step_minus1 :3;
+
+ /**
+ * Number of elements before the component of the first pixel plus 1.
+ * Elements are bits for bitstream formats, bytes otherwise.
+ */
+ uint16_t offset_plus1 :3;
+ uint16_t shift :3; ///< number of least significant bits that must be shifted away to get the value
+ uint16_t depth_minus1 :4; ///< number of bits in the component minus 1
+}AVComponentDescriptor;
+
+/**
+ * Descriptor that unambiguously describes how the bits of a pixel are
+ * stored in the up to 4 data planes of an image. It also stores the
+ * subsampling factors and number of components.
+ *
+ * @note This is separate of the colorspace (RGB, YCbCr, YPbPr, JPEG-style YUV
+ * and all the YUV variants) AVPixFmtDescriptor just stores how values
+ * are stored not what these values represent.
+ */
+typedef struct AVPixFmtDescriptor{
+ const char *name;
+ uint8_t nb_components; ///< The number of components each pixel has, (1-4)
+
+ /**
+ * Amount to shift the luma width right to find the chroma width.
+ * For YV12 this is 1 for example.
+ * chroma_width = -((-luma_width) >> log2_chroma_w)
+ * The note above is needed to ensure rounding up.
+ * This value only refers to the chroma components.
+ */
+ uint8_t log2_chroma_w; ///< chroma_width = -((-luma_width )>>log2_chroma_w)
+
+ /**
+ * Amount to shift the luma height right to find the chroma height.
+ * For YV12 this is 1 for example.
+ * chroma_height= -((-luma_height) >> log2_chroma_h)
+ * The note above is needed to ensure rounding up.
+ * This value only refers to the chroma components.
+ */
+ uint8_t log2_chroma_h;
+ uint8_t flags;
+
+ /**
+ * Parameters that describe how pixels are packed. If the format
+ * has chroma components, they must be stored in comp[1] and
+ * comp[2].
+ */
+ AVComponentDescriptor comp[4];
+}AVPixFmtDescriptor;
+
+#define PIX_FMT_BE 1 ///< Pixel format is big-endian.
+#define PIX_FMT_PAL 2 ///< Pixel format has a palette in data[1], values are indexes in this palette.
+#define PIX_FMT_BITSTREAM 4 ///< All values of a component are bit-wise packed end to end.
+#define PIX_FMT_HWACCEL 8 ///< Pixel format is an HW accelerated format.
+
+/**
+ * The array of all the pixel format descriptors.
+ */
+extern const AVPixFmtDescriptor av_pix_fmt_descriptors[];
+
+/**
+ * Reads a line from an image, and writes the values of the
+ * pixel format component c to dst.
+ *
+ * @param data the array containing the pointers to the planes of the image
+ * @param linesizes the array containing the linesizes of the image
+ * @param desc the pixel format descriptor for the image
+ * @param x the horizontal coordinate of the first pixel to read
+ * @param y the vertical coordinate of the first pixel to read
+ * @param w the width of the line to read, that is the number of
+ * values to write to dst
+ * @param read_pal_component if not zero and the format is a paletted
+ * format writes the values corresponding to the palette
+ * component c in data[1] to dst, rather than the palette indexes in
+ * data[0]. The behavior is undefined if the format is not paletted.
+ */
+void read_line(uint16_t *dst, const uint8_t *data[4], const int linesize[4],
+ const AVPixFmtDescriptor *desc, int x, int y, int c, int w, int read_pal_component);
+
+/**
+ * Writes the values from src to the pixel format component c of an
+ * image line.
+ *
+ * @param src array containing the values to write
+ * @param data the array containing the pointers to the planes of the
+ * image to write into. It is supposed to be zeroed.
+ * @param linesizes the array containing the linesizes of the image
+ * @param desc the pixel format descriptor for the image
+ * @param x the horizontal coordinate of the first pixel to write
+ * @param y the vertical coordinate of the first pixel to write
+ * @param w the width of the line to write, that is the number of
+ * values to write to the image line
+ */
+void write_line(const uint16_t *src, uint8_t *data[4], const int linesize[4],
+ const AVPixFmtDescriptor *desc, int x, int y, int c, int w);
+
+/**
+ * Returns the pixel format corresponding to name.
+ *
+ * If there is no pixel format with name name, then looks for a
+ * pixel format with the name corresponding to the native endian
+ * format of name.
+ * For example in a little-endian system, first looks for "gray16",
+ * then for "gray16le".
+ *
+ * Finally if no pixel format has been found, returns PIX_FMT_NONE.
+ */
+enum PixelFormat av_get_pix_fmt(const char *name);
+
+/**
+ * Returns the number of bits per pixel used by the pixel format
+ * described by pixdesc.
+ *
+ * The returned number of bits refers to the number of bits actually
+ * used for storing the pixel information, that is padding bits are
+ * not counted.
+ */
+int av_get_bits_per_pixel(const AVPixFmtDescriptor *pixdesc);
+
+#endif /* AVUTIL_PIXDESC_H */
diff --git a/lib-x86-32/include/libavutil/pixfmt.h b/lib-x86-32/include/libavutil/pixfmt.h
new file mode 100644
index 00000000..d976f343
--- /dev/null
+++ b/lib-x86-32/include/libavutil/pixfmt.h
@@ -0,0 +1,163 @@
+/*
+ * copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVUTIL_PIXFMT_H
+#define AVUTIL_PIXFMT_H
+
+/**
+ * @file
+ * pixel format definitions
+ *
+ * @warning This file has to be considered an internal but installed
+ * header, so it should not be directly included in your projects.
+ */
+
+#include "libavutil/avconfig.h"
+
+/**
+ * Pixel format. Notes:
+ *
+ * PIX_FMT_RGB32 is handled in an endian-specific manner. An RGBA
+ * color is put together as:
+ * (A << 24) | (R << 16) | (G << 8) | B
+ * This is stored as BGRA on little-endian CPU architectures and ARGB on
+ * big-endian CPUs.
+ *
+ * When the pixel format is palettized RGB (PIX_FMT_PAL8), the palettized
+ * image data is stored in AVFrame.data[0]. The palette is transported in
+ * AVFrame.data[1], is 1024 bytes long (256 4-byte entries) and is
+ * formatted the same as in PIX_FMT_RGB32 described above (i.e., it is
+ * also endian-specific). Note also that the individual RGB palette
+ * components stored in AVFrame.data[1] should be in the range 0..255.
+ * This is important as many custom PAL8 video codecs that were designed
+ * to run on the IBM VGA graphics adapter use 6-bit palette components.
+ *
+ * For all the 8bit per pixel formats, an RGB32 palette is in data[1] like
+ * for pal8. This palette is filled in automatically by the function
+ * allocating the picture.
+ *
+ * Note, make sure that all newly added big endian formats have pix_fmt&1==1
+ * and that all newly added little endian formats have pix_fmt&1==0
+ * this allows simpler detection of big vs little endian.
+ */
+enum PixelFormat {
+ PIX_FMT_NONE= -1,
+ PIX_FMT_YUV420P, ///< planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
+ PIX_FMT_YUYV422, ///< packed YUV 4:2:2, 16bpp, Y0 Cb Y1 Cr
+ PIX_FMT_RGB24, ///< packed RGB 8:8:8, 24bpp, RGBRGB...
+ PIX_FMT_BGR24, ///< packed RGB 8:8:8, 24bpp, BGRBGR...
+ PIX_FMT_YUV422P, ///< planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
+ PIX_FMT_YUV444P, ///< planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
+ PIX_FMT_YUV410P, ///< planar YUV 4:1:0, 9bpp, (1 Cr & Cb sample per 4x4 Y samples)
+ PIX_FMT_YUV411P, ///< planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples)
+ PIX_FMT_GRAY8, ///< Y , 8bpp
+ PIX_FMT_MONOWHITE, ///< Y , 1bpp, 0 is white, 1 is black, in each byte pixels are ordered from the msb to the lsb
+ PIX_FMT_MONOBLACK, ///< Y , 1bpp, 0 is black, 1 is white, in each byte pixels are ordered from the msb to the lsb
+ PIX_FMT_PAL8, ///< 8 bit with PIX_FMT_RGB32 palette
+ PIX_FMT_YUVJ420P, ///< planar YUV 4:2:0, 12bpp, full scale (JPEG)
+ PIX_FMT_YUVJ422P, ///< planar YUV 4:2:2, 16bpp, full scale (JPEG)
+ PIX_FMT_YUVJ444P, ///< planar YUV 4:4:4, 24bpp, full scale (JPEG)
+ PIX_FMT_XVMC_MPEG2_MC,///< XVideo Motion Acceleration via common packet passing
+ PIX_FMT_XVMC_MPEG2_IDCT,
+ PIX_FMT_UYVY422, ///< packed YUV 4:2:2, 16bpp, Cb Y0 Cr Y1
+ PIX_FMT_UYYVYY411, ///< packed YUV 4:1:1, 12bpp, Cb Y0 Y1 Cr Y2 Y3
+ PIX_FMT_BGR8, ///< packed RGB 3:3:2, 8bpp, (msb)2B 3G 3R(lsb)
+ PIX_FMT_BGR4, ///< packed RGB 1:2:1 bitstream, 4bpp, (msb)1B 2G 1R(lsb), a byte contains two pixels, the first pixel in the byte is the one composed by the 4 msb bits
+ PIX_FMT_BGR4_BYTE, ///< packed RGB 1:2:1, 8bpp, (msb)1B 2G 1R(lsb)
+ PIX_FMT_RGB8, ///< packed RGB 3:3:2, 8bpp, (msb)2R 3G 3B(lsb)
+ PIX_FMT_RGB4, ///< packed RGB 1:2:1 bitstream, 4bpp, (msb)1R 2G 1B(lsb), a byte contains two pixels, the first pixel in the byte is the one composed by the 4 msb bits
+ PIX_FMT_RGB4_BYTE, ///< packed RGB 1:2:1, 8bpp, (msb)1R 2G 1B(lsb)
+ PIX_FMT_NV12, ///< planar YUV 4:2:0, 12bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (first byte U and the following byte V)
+ PIX_FMT_NV21, ///< as above, but U and V bytes are swapped
+
+ PIX_FMT_ARGB, ///< packed ARGB 8:8:8:8, 32bpp, ARGBARGB...
+ PIX_FMT_RGBA, ///< packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
+ PIX_FMT_ABGR, ///< packed ABGR 8:8:8:8, 32bpp, ABGRABGR...
+ PIX_FMT_BGRA, ///< packed BGRA 8:8:8:8, 32bpp, BGRABGRA...
+
+ PIX_FMT_GRAY16BE, ///< Y , 16bpp, big-endian
+ PIX_FMT_GRAY16LE, ///< Y , 16bpp, little-endian
+ PIX_FMT_YUV440P, ///< planar YUV 4:4:0 (1 Cr & Cb sample per 1x2 Y samples)
+ PIX_FMT_YUVJ440P, ///< planar YUV 4:4:0 full scale (JPEG)
+ PIX_FMT_YUVA420P, ///< planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A samples)
+ PIX_FMT_VDPAU_H264,///< H.264 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers
+ PIX_FMT_VDPAU_MPEG1,///< MPEG-1 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers
+ PIX_FMT_VDPAU_MPEG2,///< MPEG-2 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers
+ PIX_FMT_VDPAU_WMV3,///< WMV3 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers
+ PIX_FMT_VDPAU_VC1, ///< VC-1 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers
+ PIX_FMT_RGB48BE, ///< packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, the 2-byte value for each R/G/B component is stored as big-endian
+ PIX_FMT_RGB48LE, ///< packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, the 2-byte value for each R/G/B component is stored as little-endian
+
+ PIX_FMT_RGB565BE, ///< packed RGB 5:6:5, 16bpp, (msb) 5R 6G 5B(lsb), big-endian
+ PIX_FMT_RGB565LE, ///< packed RGB 5:6:5, 16bpp, (msb) 5R 6G 5B(lsb), little-endian
+ PIX_FMT_RGB555BE, ///< packed RGB 5:5:5, 16bpp, (msb)1A 5R 5G 5B(lsb), big-endian, most significant bit to 0
+ PIX_FMT_RGB555LE, ///< packed RGB 5:5:5, 16bpp, (msb)1A 5R 5G 5B(lsb), little-endian, most significant bit to 0
+
+ PIX_FMT_BGR565BE, ///< packed BGR 5:6:5, 16bpp, (msb) 5B 6G 5R(lsb), big-endian
+ PIX_FMT_BGR565LE, ///< packed BGR 5:6:5, 16bpp, (msb) 5B 6G 5R(lsb), little-endian
+ PIX_FMT_BGR555BE, ///< packed BGR 5:5:5, 16bpp, (msb)1A 5B 5G 5R(lsb), big-endian, most significant bit to 1
+ PIX_FMT_BGR555LE, ///< packed BGR 5:5:5, 16bpp, (msb)1A 5B 5G 5R(lsb), little-endian, most significant bit to 1
+
+ PIX_FMT_VAAPI_MOCO, ///< HW acceleration through VA API at motion compensation entry-point, Picture.data[3] contains a vaapi_render_state struct which contains macroblocks as well as various fields extracted from headers
+ PIX_FMT_VAAPI_IDCT, ///< HW acceleration through VA API at IDCT entry-point, Picture.data[3] contains a vaapi_render_state struct which contains fields extracted from headers
+ PIX_FMT_VAAPI_VLD, ///< HW decoding through VA API, Picture.data[3] contains a vaapi_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers
+
+ PIX_FMT_YUV420P16LE, ///< planar YUV 4:2:0, 24bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian
+ PIX_FMT_YUV420P16BE, ///< planar YUV 4:2:0, 24bpp, (1 Cr & Cb sample per 2x2 Y samples), big-endian
+ PIX_FMT_YUV422P16LE, ///< planar YUV 4:2:2, 32bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian
+ PIX_FMT_YUV422P16BE, ///< planar YUV 4:2:2, 32bpp, (1 Cr & Cb sample per 2x1 Y samples), big-endian
+ PIX_FMT_YUV444P16LE, ///< planar YUV 4:4:4, 48bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian
+ PIX_FMT_YUV444P16BE, ///< planar YUV 4:4:4, 48bpp, (1 Cr & Cb sample per 1x1 Y samples), big-endian
+ PIX_FMT_VDPAU_MPEG4, ///< MPEG4 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers
+ PIX_FMT_DXVA2_VLD, ///< HW decoding through DXVA2, Picture.data[3] contains a LPDIRECT3DSURFACE9 pointer
+
+ PIX_FMT_RGB444BE, ///< packed RGB 4:4:4, 16bpp, (msb)4A 4R 4G 4B(lsb), big-endian, most significant bits to 0
+ PIX_FMT_RGB444LE, ///< packed RGB 4:4:4, 16bpp, (msb)4A 4R 4G 4B(lsb), little-endian, most significant bits to 0
+ PIX_FMT_BGR444BE, ///< packed BGR 4:4:4, 16bpp, (msb)4A 4B 4G 4R(lsb), big-endian, most significant bits to 1
+ PIX_FMT_BGR444LE, ///< packed BGR 4:4:4, 16bpp, (msb)4A 4B 4G 4R(lsb), little-endian, most significant bits to 1
+ PIX_FMT_Y400A, ///< 8bit gray, 8bit alpha
+ PIX_FMT_NB, ///< number of pixel formats, DO NOT USE THIS if you want to link with shared libav* because the number of formats might differ between versions
+};
+
+#if AV_HAVE_BIGENDIAN
+# define PIX_FMT_NE(be, le) PIX_FMT_##be
+#else
+# define PIX_FMT_NE(be, le) PIX_FMT_##le
+#endif
+
+#define PIX_FMT_RGB32 PIX_FMT_NE(ARGB, BGRA)
+#define PIX_FMT_RGB32_1 PIX_FMT_NE(RGBA, ABGR)
+#define PIX_FMT_BGR32 PIX_FMT_NE(ABGR, RGBA)
+#define PIX_FMT_BGR32_1 PIX_FMT_NE(BGRA, ARGB)
+
+#define PIX_FMT_GRAY16 PIX_FMT_NE(GRAY16BE, GRAY16LE)
+#define PIX_FMT_RGB48 PIX_FMT_NE(RGB48BE, RGB48LE)
+#define PIX_FMT_RGB565 PIX_FMT_NE(RGB565BE, RGB565LE)
+#define PIX_FMT_RGB555 PIX_FMT_NE(RGB555BE, RGB555LE)
+#define PIX_FMT_RGB444 PIX_FMT_NE(RGB444BE, RGB444LE)
+#define PIX_FMT_BGR565 PIX_FMT_NE(BGR565BE, BGR565LE)
+#define PIX_FMT_BGR555 PIX_FMT_NE(BGR555BE, BGR555LE)
+#define PIX_FMT_BGR444 PIX_FMT_NE(BGR444BE, BGR444LE)
+
+#define PIX_FMT_YUV420P16 PIX_FMT_NE(YUV420P16BE, YUV420P16LE)
+#define PIX_FMT_YUV422P16 PIX_FMT_NE(YUV422P16BE, YUV422P16LE)
+#define PIX_FMT_YUV444P16 PIX_FMT_NE(YUV444P16BE, YUV444P16LE)
+
+#endif /* AVUTIL_PIXFMT_H */
diff --git a/lib-x86-32/include/libavutil/rational.h b/lib-x86-32/include/libavutil/rational.h
new file mode 100644
index 00000000..4d91f7ba
--- /dev/null
+++ b/lib-x86-32/include/libavutil/rational.h
@@ -0,0 +1,129 @@
+/*
+ * rational numbers
+ * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * rational numbers
+ * @author Michael Niedermayer <michaelni@gmx.at>
+ */
+
+#ifndef AVUTIL_RATIONAL_H
+#define AVUTIL_RATIONAL_H
+
+#include <stdint.h>
+#include "attributes.h"
+
+/**
+ * rational number numerator/denominator
+ */
+typedef struct AVRational{
+ int num; ///< numerator
+ int den; ///< denominator
+} AVRational;
+
+/**
+ * Compares two rationals.
+ * @param a first rational
+ * @param b second rational
+ * @return 0 if a==b, 1 if a>b and -1 if a<b
+ */
+static inline int av_cmp_q(AVRational a, AVRational b){
+ const int64_t tmp= a.num * (int64_t)b.den - b.num * (int64_t)a.den;
+
+ if(tmp) return (tmp>>63)|1;
+ else return 0;
+}
+
+/**
+ * Converts rational to double.
+ * @param a rational to convert
+ * @return (double) a
+ */
+static inline double av_q2d(AVRational a){
+ return a.num / (double) a.den;
+}
+
+/**
+ * Reduces a fraction.
+ * This is useful for framerate calculations.
+ * @param dst_num destination numerator
+ * @param dst_den destination denominator
+ * @param num source numerator
+ * @param den source denominator
+ * @param max the maximum allowed for dst_num & dst_den
+ * @return 1 if exact, 0 otherwise
+ */
+int av_reduce(int *dst_num, int *dst_den, int64_t num, int64_t den, int64_t max);
+
+/**
+ * Multiplies two rationals.
+ * @param b first rational
+ * @param c second rational
+ * @return b*c
+ */
+AVRational av_mul_q(AVRational b, AVRational c) av_const;
+
+/**
+ * Divides one rational by another.
+ * @param b first rational
+ * @param c second rational
+ * @return b/c
+ */
+AVRational av_div_q(AVRational b, AVRational c) av_const;
+
+/**
+ * Adds two rationals.
+ * @param b first rational
+ * @param c second rational
+ * @return b+c
+ */
+AVRational av_add_q(AVRational b, AVRational c) av_const;
+
+/**
+ * Subtracts one rational from another.
+ * @param b first rational
+ * @param c second rational
+ * @return b-c
+ */
+AVRational av_sub_q(AVRational b, AVRational c) av_const;
+
+/**
+ * Converts a double precision floating point number to a rational.
+ * @param d double to convert
+ * @param max the maximum allowed numerator and denominator
+ * @return (AVRational) d
+ */
+AVRational av_d2q(double d, int max) av_const;
+
+/**
+ * @return 1 if q1 is nearer to q than q2, -1 if q2 is nearer
+ * than q1, 0 if they have the same distance.
+ */
+int av_nearer_q(AVRational q, AVRational q1, AVRational q2);
+
+/**
+ * Finds the nearest value in q_list to q.
+ * @param q_list an array of rationals terminated by {0, 0}
+ * @return the index of the nearest value found in the array
+ */
+int av_find_nearest_q_idx(AVRational q, const AVRational* q_list);
+
+#endif /* AVUTIL_RATIONAL_H */
diff --git a/lib-x86-32/include/libavutil/sha1.h b/lib-x86-32/include/libavutil/sha1.h
new file mode 100644
index 00000000..cf7c4a65
--- /dev/null
+++ b/lib-x86-32/include/libavutil/sha1.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2007 Michael Niedermayer <michaelni@gmx.at>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVUTIL_SHA1_H
+#define AVUTIL_SHA1_H
+
+#include <stdint.h>
+
+extern const int av_sha1_size;
+
+struct AVSHA1;
+
+/**
+ * Initializes SHA-1 hashing.
+ *
+ * @param context pointer to the function context (of size av_sha_size)
+ * @deprecated use av_sha_init() instead
+ */
+void av_sha1_init(struct AVSHA1* context);
+
+/**
+ * Updates hash value.
+ *
+ * @param context hash function context
+ * @param data input data to update hash with
+ * @param len input data length
+ * @deprecated use av_sha_update() instead
+ */
+void av_sha1_update(struct AVSHA1* context, const uint8_t* data, unsigned int len);
+
+/**
+ * Finishes hashing and output digest value.
+ *
+ * @param context hash function context
+ * @param digest buffer where output digest value is stored
+ * @deprecated use av_sha_final() instead
+ */
+void av_sha1_final(struct AVSHA1* context, uint8_t digest[20]);
+
+#endif /* AVUTIL_SHA1_H */
diff --git a/lib-x86-32/include/mad.h b/lib-x86-32/include/mad.h
new file mode 100644
index 00000000..9ef6cc8f
--- /dev/null
+++ b/lib-x86-32/include/mad.h
@@ -0,0 +1,964 @@
+/*
+ * libmad - MPEG audio decoder library
+ * Copyright (C) 2000-2004 Underbit Technologies, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * If you would like to negotiate alternate licensing terms, you may do
+ * so by contacting: Underbit Technologies, Inc. <info@underbit.com>
+ */
+
+# ifdef __cplusplus
+extern "C" {
+# endif
+
+# define FPM_INTEL
+
+
+
+# define SIZEOF_INT 4
+# define SIZEOF_LONG 4
+# define SIZEOF_LONG_LONG 8
+
+
+/* Id: version.h,v 1.26 2004/01/23 09:41:33 rob Exp */
+
+# ifndef LIBMAD_VERSION_H
+# define LIBMAD_VERSION_H
+
+# define MAD_VERSION_MAJOR 0
+# define MAD_VERSION_MINOR 15
+# define MAD_VERSION_PATCH 1
+# define MAD_VERSION_EXTRA " (beta)"
+
+# define MAD_VERSION_STRINGIZE(str) #str
+# define MAD_VERSION_STRING(num) MAD_VERSION_STRINGIZE(num)
+
+# define MAD_VERSION MAD_VERSION_STRING(MAD_VERSION_MAJOR) "." \
+ MAD_VERSION_STRING(MAD_VERSION_MINOR) "." \
+ MAD_VERSION_STRING(MAD_VERSION_PATCH) \
+ MAD_VERSION_EXTRA
+
+# define MAD_PUBLISHYEAR "2000-2004"
+# define MAD_AUTHOR "Underbit Technologies, Inc."
+# define MAD_EMAIL "info@underbit.com"
+
+extern char const mad_version[];
+extern char const mad_copyright[];
+extern char const mad_author[];
+extern char const mad_build[];
+
+# endif
+
+/* Id: fixed.h,v 1.38 2004/02/17 02:02:03 rob Exp */
+
+# ifndef LIBMAD_FIXED_H
+# define LIBMAD_FIXED_H
+
+# if SIZEOF_INT >= 4
+typedef signed int mad_fixed_t;
+
+typedef signed int mad_fixed64hi_t;
+typedef unsigned int mad_fixed64lo_t;
+# else
+typedef signed long mad_fixed_t;
+
+typedef signed long mad_fixed64hi_t;
+typedef unsigned long mad_fixed64lo_t;
+# endif
+
+# if defined(_MSC_VER)
+# define mad_fixed64_t signed __int64
+# elif 1 || defined(__GNUC__)
+# define mad_fixed64_t signed long long
+# endif
+
+# if defined(FPM_FLOAT)
+typedef double mad_sample_t;
+# else
+typedef mad_fixed_t mad_sample_t;
+# endif
+
+/*
+ * Fixed-point format: 0xABBBBBBB
+ * A == whole part (sign + 3 bits)
+ * B == fractional part (28 bits)
+ *
+ * Values are signed two's complement, so the effective range is:
+ * 0x80000000 to 0x7fffffff
+ * -8.0 to +7.9999999962747097015380859375
+ *
+ * The smallest representable value is:
+ * 0x00000001 == 0.0000000037252902984619140625 (i.e. about 3.725e-9)
+ *
+ * 28 bits of fractional accuracy represent about
+ * 8.6 digits of decimal accuracy.
+ *
+ * Fixed-point numbers can be added or subtracted as normal
+ * integers, but multiplication requires shifting the 64-bit result
+ * from 56 fractional bits back to 28 (and rounding.)
+ *
+ * Changing the definition of MAD_F_FRACBITS is only partially
+ * supported, and must be done with care.
+ */
+
+# define MAD_F_FRACBITS 28
+
+# if MAD_F_FRACBITS == 28
+# define MAD_F(x) ((mad_fixed_t) (x##L))
+# else
+# if MAD_F_FRACBITS < 28
+# warning "MAD_F_FRACBITS < 28"
+# define MAD_F(x) ((mad_fixed_t) \
+ (((x##L) + \
+ (1L << (28 - MAD_F_FRACBITS - 1))) >> \
+ (28 - MAD_F_FRACBITS)))
+# elif MAD_F_FRACBITS > 28
+# error "MAD_F_FRACBITS > 28 not currently supported"
+# define MAD_F(x) ((mad_fixed_t) \
+ ((x##L) << (MAD_F_FRACBITS - 28)))
+# endif
+# endif
+
+# define MAD_F_MIN ((mad_fixed_t) -0x80000000L)
+# define MAD_F_MAX ((mad_fixed_t) +0x7fffffffL)
+
+# define MAD_F_ONE MAD_F(0x10000000)
+
+# define mad_f_tofixed(x) ((mad_fixed_t) \
+ ((x) * (double) (1L << MAD_F_FRACBITS) + 0.5))
+# define mad_f_todouble(x) ((double) \
+ ((x) / (double) (1L << MAD_F_FRACBITS)))
+
+# define mad_f_intpart(x) ((x) >> MAD_F_FRACBITS)
+# define mad_f_fracpart(x) ((x) & ((1L << MAD_F_FRACBITS) - 1))
+ /* (x should be positive) */
+
+# define mad_f_fromint(x) ((x) << MAD_F_FRACBITS)
+
+# define mad_f_add(x, y) ((x) + (y))
+# define mad_f_sub(x, y) ((x) - (y))
+
+# if defined(FPM_FLOAT)
+# error "FPM_FLOAT not yet supported"
+
+# undef MAD_F
+# define MAD_F(x) mad_f_todouble(x)
+
+# define mad_f_mul(x, y) ((x) * (y))
+# define mad_f_scale64
+
+# undef ASO_ZEROCHECK
+
+# elif defined(FPM_64BIT)
+
+/*
+ * This version should be the most accurate if 64-bit types are supported by
+ * the compiler, although it may not be the most efficient.
+ */
+# if defined(OPT_ACCURACY)
+# define mad_f_mul(x, y) \
+ ((mad_fixed_t) \
+ ((((mad_fixed64_t) (x) * (y)) + \
+ (1L << (MAD_F_SCALEBITS - 1))) >> MAD_F_SCALEBITS))
+# else
+# define mad_f_mul(x, y) \
+ ((mad_fixed_t) (((mad_fixed64_t) (x) * (y)) >> MAD_F_SCALEBITS))
+# endif
+
+# define MAD_F_SCALEBITS MAD_F_FRACBITS
+
+/* --- Intel --------------------------------------------------------------- */
+
+# elif defined(FPM_INTEL)
+
+# if defined(_MSC_VER)
+# pragma warning(push)
+# pragma warning(disable: 4035) /* no return value */
+static __forceinline
+mad_fixed_t mad_f_mul_inline(mad_fixed_t x, mad_fixed_t y)
+{
+ enum {
+ fracbits = MAD_F_FRACBITS
+ };
+
+ __asm {
+ mov eax, x
+ imul y
+ shrd eax, edx, fracbits
+ }
+
+ /* implicit return of eax */
+}
+# pragma warning(pop)
+
+# define mad_f_mul mad_f_mul_inline
+# define mad_f_scale64
+# else
+/*
+ * This Intel version is fast and accurate; the disposition of the least
+ * significant bit depends on OPT_ACCURACY via mad_f_scale64().
+ */
+# define MAD_F_MLX(hi, lo, x, y) \
+ asm ("imull %3" \
+ : "=a" (lo), "=d" (hi) \
+ : "%a" (x), "rm" (y) \
+ : "cc")
+
+# if defined(OPT_ACCURACY)
+/*
+ * This gives best accuracy but is not very fast.
+ */
+# define MAD_F_MLA(hi, lo, x, y) \
+ ({ mad_fixed64hi_t __hi; \
+ mad_fixed64lo_t __lo; \
+ MAD_F_MLX(__hi, __lo, (x), (y)); \
+ asm ("addl %2,%0\n\t" \
+ "adcl %3,%1" \
+ : "=rm" (lo), "=rm" (hi) \
+ : "r" (__lo), "r" (__hi), "0" (lo), "1" (hi) \
+ : "cc"); \
+ })
+# endif /* OPT_ACCURACY */
+
+# if defined(OPT_ACCURACY)
+/*
+ * Surprisingly, this is faster than SHRD followed by ADC.
+ */
+# define mad_f_scale64(hi, lo) \
+ ({ mad_fixed64hi_t __hi_; \
+ mad_fixed64lo_t __lo_; \
+ mad_fixed_t __result; \
+ asm ("addl %4,%2\n\t" \
+ "adcl %5,%3" \
+ : "=rm" (__lo_), "=rm" (__hi_) \
+ : "0" (lo), "1" (hi), \
+ "ir" (1L << (MAD_F_SCALEBITS - 1)), "ir" (0) \
+ : "cc"); \
+ asm ("shrdl %3,%2,%1" \
+ : "=rm" (__result) \
+ : "0" (__lo_), "r" (__hi_), "I" (MAD_F_SCALEBITS) \
+ : "cc"); \
+ __result; \
+ })
+# elif defined(OPT_INTEL)
+/*
+ * Alternate Intel scaling that may or may not perform better.
+ */
+# define mad_f_scale64(hi, lo) \
+ ({ mad_fixed_t __result; \
+ asm ("shrl %3,%1\n\t" \
+ "shll %4,%2\n\t" \
+ "orl %2,%1" \
+ : "=rm" (__result) \
+ : "0" (lo), "r" (hi), \
+ "I" (MAD_F_SCALEBITS), "I" (32 - MAD_F_SCALEBITS) \
+ : "cc"); \
+ __result; \
+ })
+# else
+# define mad_f_scale64(hi, lo) \
+ ({ mad_fixed_t __result; \
+ asm ("shrdl %3,%2,%1" \
+ : "=rm" (__result) \
+ : "0" (lo), "r" (hi), "I" (MAD_F_SCALEBITS) \
+ : "cc"); \
+ __result; \
+ })
+# endif /* OPT_ACCURACY */
+
+# define MAD_F_SCALEBITS MAD_F_FRACBITS
+# endif
+
+/* --- ARM ----------------------------------------------------------------- */
+
+# elif defined(FPM_ARM)
+
+/*
+ * This ARM V4 version is as accurate as FPM_64BIT but much faster. The
+ * least significant bit is properly rounded at no CPU cycle cost!
+ */
+# if 1
+/*
+ * This is faster than the default implementation via MAD_F_MLX() and
+ * mad_f_scale64().
+ */
+# define mad_f_mul(x, y) \
+ ({ mad_fixed64hi_t __hi; \
+ mad_fixed64lo_t __lo; \
+ mad_fixed_t __result; \
+ asm ("smull %0, %1, %3, %4\n\t" \
+ "movs %0, %0, lsr %5\n\t" \
+ "adc %2, %0, %1, lsl %6" \
+ : "=&r" (__lo), "=&r" (__hi), "=r" (__result) \
+ : "%r" (x), "r" (y), \
+ "M" (MAD_F_SCALEBITS), "M" (32 - MAD_F_SCALEBITS) \
+ : "cc"); \
+ __result; \
+ })
+# endif
+
+# define MAD_F_MLX(hi, lo, x, y) \
+ asm ("smull %0, %1, %2, %3" \
+ : "=&r" (lo), "=&r" (hi) \
+ : "%r" (x), "r" (y))
+
+# define MAD_F_MLA(hi, lo, x, y) \
+ asm ("smlal %0, %1, %2, %3" \
+ : "+r" (lo), "+r" (hi) \
+ : "%r" (x), "r" (y))
+
+# define MAD_F_MLN(hi, lo) \
+ asm ("rsbs %0, %2, #0\n\t" \
+ "rsc %1, %3, #0" \
+ : "=r" (lo), "=r" (hi) \
+ : "0" (lo), "1" (hi) \
+ : "cc")
+
+# define mad_f_scale64(hi, lo) \
+ ({ mad_fixed_t __result; \
+ asm ("movs %0, %1, lsr %3\n\t" \
+ "adc %0, %0, %2, lsl %4" \
+ : "=&r" (__result) \
+ : "r" (lo), "r" (hi), \
+ "M" (MAD_F_SCALEBITS), "M" (32 - MAD_F_SCALEBITS) \
+ : "cc"); \
+ __result; \
+ })
+
+# define MAD_F_SCALEBITS MAD_F_FRACBITS
+
+/* --- MIPS ---------------------------------------------------------------- */
+
+# elif defined(FPM_MIPS)
+
+/*
+ * This MIPS version is fast and accurate; the disposition of the least
+ * significant bit depends on OPT_ACCURACY via mad_f_scale64().
+ */
+# define MAD_F_MLX(hi, lo, x, y) \
+ asm ("mult %2,%3" \
+ : "=l" (lo), "=h" (hi) \
+ : "%r" (x), "r" (y))
+
+# if defined(HAVE_MADD_ASM)
+# define MAD_F_MLA(hi, lo, x, y) \
+ asm ("madd %2,%3" \
+ : "+l" (lo), "+h" (hi) \
+ : "%r" (x), "r" (y))
+# elif defined(HAVE_MADD16_ASM)
+/*
+ * This loses significant accuracy due to the 16-bit integer limit in the
+ * multiply/accumulate instruction.
+ */
+# define MAD_F_ML0(hi, lo, x, y) \
+ asm ("mult %2,%3" \
+ : "=l" (lo), "=h" (hi) \
+ : "%r" ((x) >> 12), "r" ((y) >> 16))
+# define MAD_F_MLA(hi, lo, x, y) \
+ asm ("madd16 %2,%3" \
+ : "+l" (lo), "+h" (hi) \
+ : "%r" ((x) >> 12), "r" ((y) >> 16))
+# define MAD_F_MLZ(hi, lo) ((mad_fixed_t) (lo))
+# endif
+
+# if defined(OPT_SPEED)
+# define mad_f_scale64(hi, lo) \
+ ((mad_fixed_t) ((hi) << (32 - MAD_F_SCALEBITS)))
+# define MAD_F_SCALEBITS MAD_F_FRACBITS
+# endif
+
+/* --- SPARC --------------------------------------------------------------- */
+
+# elif defined(FPM_SPARC)
+
+/*
+ * This SPARC V8 version is fast and accurate; the disposition of the least
+ * significant bit depends on OPT_ACCURACY via mad_f_scale64().
+ */
+# define MAD_F_MLX(hi, lo, x, y) \
+ asm ("smul %2, %3, %0\n\t" \
+ "rd %%y, %1" \
+ : "=r" (lo), "=r" (hi) \
+ : "%r" (x), "rI" (y))
+
+/* --- PowerPC ------------------------------------------------------------- */
+
+# elif defined(FPM_PPC)
+
+/*
+ * This PowerPC version is fast and accurate; the disposition of the least
+ * significant bit depends on OPT_ACCURACY via mad_f_scale64().
+ */
+# define MAD_F_MLX(hi, lo, x, y) \
+ do { \
+ asm ("mullw %0,%1,%2" \
+ : "=r" (lo) \
+ : "%r" (x), "r" (y)); \
+ asm ("mulhw %0,%1,%2" \
+ : "=r" (hi) \
+ : "%r" (x), "r" (y)); \
+ } \
+ while (0)
+
+# if defined(OPT_ACCURACY)
+/*
+ * This gives best accuracy but is not very fast.
+ */
+# define MAD_F_MLA(hi, lo, x, y) \
+ ({ mad_fixed64hi_t __hi; \
+ mad_fixed64lo_t __lo; \
+ MAD_F_MLX(__hi, __lo, (x), (y)); \
+ asm ("addc %0,%2,%3\n\t" \
+ "adde %1,%4,%5" \
+ : "=r" (lo), "=r" (hi) \
+ : "%r" (lo), "r" (__lo), \
+ "%r" (hi), "r" (__hi) \
+ : "xer"); \
+ })
+# endif
+
+# if defined(OPT_ACCURACY)
+/*
+ * This is slower than the truncating version below it.
+ */
+# define mad_f_scale64(hi, lo) \
+ ({ mad_fixed_t __result, __round; \
+ asm ("rotrwi %0,%1,%2" \
+ : "=r" (__result) \
+ : "r" (lo), "i" (MAD_F_SCALEBITS)); \
+ asm ("extrwi %0,%1,1,0" \
+ : "=r" (__round) \
+ : "r" (__result)); \
+ asm ("insrwi %0,%1,%2,0" \
+ : "+r" (__result) \
+ : "r" (hi), "i" (MAD_F_SCALEBITS)); \
+ asm ("add %0,%1,%2" \
+ : "=r" (__result) \
+ : "%r" (__result), "r" (__round)); \
+ __result; \
+ })
+# else
+# define mad_f_scale64(hi, lo) \
+ ({ mad_fixed_t __result; \
+ asm ("rotrwi %0,%1,%2" \
+ : "=r" (__result) \
+ : "r" (lo), "i" (MAD_F_SCALEBITS)); \
+ asm ("insrwi %0,%1,%2,0" \
+ : "+r" (__result) \
+ : "r" (hi), "i" (MAD_F_SCALEBITS)); \
+ __result; \
+ })
+# endif
+
+# define MAD_F_SCALEBITS MAD_F_FRACBITS
+
+/* --- Default ------------------------------------------------------------- */
+
+# elif defined(FPM_DEFAULT)
+
+/*
+ * This version is the most portable but it loses significant accuracy.
+ * Furthermore, accuracy is biased against the second argument, so care
+ * should be taken when ordering operands.
+ *
+ * The scale factors are constant as this is not used with SSO.
+ *
+ * Pre-rounding is required to stay within the limits of compliance.
+ */
+# if defined(OPT_SPEED)
+# define mad_f_mul(x, y) (((x) >> 12) * ((y) >> 16))
+# else
+# define mad_f_mul(x, y) ((((x) + (1L << 11)) >> 12) * \
+ (((y) + (1L << 15)) >> 16))
+# endif
+
+/* ------------------------------------------------------------------------- */
+
+# else
+# error "no FPM selected"
+# endif
+
+/* default implementations */
+
+# if !defined(mad_f_mul)
+# define mad_f_mul(x, y) \
+ ({ register mad_fixed64hi_t __hi; \
+ register mad_fixed64lo_t __lo; \
+ MAD_F_MLX(__hi, __lo, (x), (y)); \
+ mad_f_scale64(__hi, __lo); \
+ })
+# endif
+
+# if !defined(MAD_F_MLA)
+# define MAD_F_ML0(hi, lo, x, y) ((lo) = mad_f_mul((x), (y)))
+# define MAD_F_MLA(hi, lo, x, y) ((lo) += mad_f_mul((x), (y)))
+# define MAD_F_MLN(hi, lo) ((lo) = -(lo))
+# define MAD_F_MLZ(hi, lo) ((void) (hi), (mad_fixed_t) (lo))
+# endif
+
+# if !defined(MAD_F_ML0)
+# define MAD_F_ML0(hi, lo, x, y) MAD_F_MLX((hi), (lo), (x), (y))
+# endif
+
+# if !defined(MAD_F_MLN)
+# define MAD_F_MLN(hi, lo) ((hi) = ((lo) = -(lo)) ? ~(hi) : -(hi))
+# endif
+
+# if !defined(MAD_F_MLZ)
+# define MAD_F_MLZ(hi, lo) mad_f_scale64((hi), (lo))
+# endif
+
+# if !defined(mad_f_scale64)
+# if defined(OPT_ACCURACY)
+# define mad_f_scale64(hi, lo) \
+ ((((mad_fixed_t) \
+ (((hi) << (32 - (MAD_F_SCALEBITS - 1))) | \
+ ((lo) >> (MAD_F_SCALEBITS - 1)))) + 1) >> 1)
+# else
+# define mad_f_scale64(hi, lo) \
+ ((mad_fixed_t) \
+ (((hi) << (32 - MAD_F_SCALEBITS)) | \
+ ((lo) >> MAD_F_SCALEBITS)))
+# endif
+# define MAD_F_SCALEBITS MAD_F_FRACBITS
+# endif
+
+/* C routines */
+
+mad_fixed_t mad_f_abs(mad_fixed_t);
+mad_fixed_t mad_f_div(mad_fixed_t, mad_fixed_t);
+
+# endif
+
+/* Id: bit.h,v 1.12 2004/01/23 09:41:32 rob Exp */
+
+# ifndef LIBMAD_BIT_H
+# define LIBMAD_BIT_H
+
+struct mad_bitptr {
+ unsigned char const *byte;
+ unsigned short cache;
+ unsigned short left;
+};
+
+void mad_bit_init(struct mad_bitptr *, unsigned char const *);
+
+# define mad_bit_finish(bitptr) /* nothing */
+
+unsigned int mad_bit_length(struct mad_bitptr const *,
+ struct mad_bitptr const *);
+
+# define mad_bit_bitsleft(bitptr) ((bitptr)->left)
+unsigned char const *mad_bit_nextbyte(struct mad_bitptr const *);
+
+void mad_bit_skip(struct mad_bitptr *, unsigned int);
+unsigned long mad_bit_read(struct mad_bitptr *, unsigned int);
+void mad_bit_write(struct mad_bitptr *, unsigned int, unsigned long);
+
+unsigned short mad_bit_crc(struct mad_bitptr, unsigned int, unsigned short);
+
+# endif
+
+/* Id: timer.h,v 1.16 2004/01/23 09:41:33 rob Exp */
+
+# ifndef LIBMAD_TIMER_H
+# define LIBMAD_TIMER_H
+
+typedef struct {
+ signed long seconds; /* whole seconds */
+ unsigned long fraction; /* 1/MAD_TIMER_RESOLUTION seconds */
+} mad_timer_t;
+
+extern mad_timer_t const mad_timer_zero;
+
+# define MAD_TIMER_RESOLUTION 352800000UL
+
+enum mad_units {
+ MAD_UNITS_HOURS = -2,
+ MAD_UNITS_MINUTES = -1,
+ MAD_UNITS_SECONDS = 0,
+
+ /* metric units */
+
+ MAD_UNITS_DECISECONDS = 10,
+ MAD_UNITS_CENTISECONDS = 100,
+ MAD_UNITS_MILLISECONDS = 1000,
+
+ /* audio sample units */
+
+ MAD_UNITS_8000_HZ = 8000,
+ MAD_UNITS_11025_HZ = 11025,
+ MAD_UNITS_12000_HZ = 12000,
+
+ MAD_UNITS_16000_HZ = 16000,
+ MAD_UNITS_22050_HZ = 22050,
+ MAD_UNITS_24000_HZ = 24000,
+
+ MAD_UNITS_32000_HZ = 32000,
+ MAD_UNITS_44100_HZ = 44100,
+ MAD_UNITS_48000_HZ = 48000,
+
+ /* video frame/field units */
+
+ MAD_UNITS_24_FPS = 24,
+ MAD_UNITS_25_FPS = 25,
+ MAD_UNITS_30_FPS = 30,
+ MAD_UNITS_48_FPS = 48,
+ MAD_UNITS_50_FPS = 50,
+ MAD_UNITS_60_FPS = 60,
+
+ /* CD audio frames */
+
+ MAD_UNITS_75_FPS = 75,
+
+ /* video drop-frame units */
+
+ MAD_UNITS_23_976_FPS = -24,
+ MAD_UNITS_24_975_FPS = -25,
+ MAD_UNITS_29_97_FPS = -30,
+ MAD_UNITS_47_952_FPS = -48,
+ MAD_UNITS_49_95_FPS = -50,
+ MAD_UNITS_59_94_FPS = -60
+};
+
+# define mad_timer_reset(timer) ((void) (*(timer) = mad_timer_zero))
+
+int mad_timer_compare(mad_timer_t, mad_timer_t);
+
+# define mad_timer_sign(timer) mad_timer_compare((timer), mad_timer_zero)
+
+void mad_timer_negate(mad_timer_t *);
+mad_timer_t mad_timer_abs(mad_timer_t);
+
+void mad_timer_set(mad_timer_t *, unsigned long, unsigned long, unsigned long);
+void mad_timer_add(mad_timer_t *, mad_timer_t);
+void mad_timer_multiply(mad_timer_t *, signed long);
+
+signed long mad_timer_count(mad_timer_t, enum mad_units);
+unsigned long mad_timer_fraction(mad_timer_t, unsigned long);
+void mad_timer_string(mad_timer_t, char *, char const *,
+ enum mad_units, enum mad_units, unsigned long);
+
+# endif
+
+/* Id: stream.h,v 1.20 2004/02/05 09:02:39 rob Exp */
+
+# ifndef LIBMAD_STREAM_H
+# define LIBMAD_STREAM_H
+
+
+# define MAD_BUFFER_GUARD 8
+# define MAD_BUFFER_MDLEN (511 + 2048 + MAD_BUFFER_GUARD)
+
+enum mad_error {
+ MAD_ERROR_NONE = 0x0000, /* no error */
+
+ MAD_ERROR_BUFLEN = 0x0001, /* input buffer too small (or EOF) */
+ MAD_ERROR_BUFPTR = 0x0002, /* invalid (null) buffer pointer */
+
+ MAD_ERROR_NOMEM = 0x0031, /* not enough memory */
+
+ MAD_ERROR_LOSTSYNC = 0x0101, /* lost synchronization */
+ MAD_ERROR_BADLAYER = 0x0102, /* reserved header layer value */
+ MAD_ERROR_BADBITRATE = 0x0103, /* forbidden bitrate value */
+ MAD_ERROR_BADSAMPLERATE = 0x0104, /* reserved sample frequency value */
+ MAD_ERROR_BADEMPHASIS = 0x0105, /* reserved emphasis value */
+
+ MAD_ERROR_BADCRC = 0x0201, /* CRC check failed */
+ MAD_ERROR_BADBITALLOC = 0x0211, /* forbidden bit allocation value */
+ MAD_ERROR_BADSCALEFACTOR = 0x0221, /* bad scalefactor index */
+ MAD_ERROR_BADMODE = 0x0222, /* bad bitrate/mode combination */
+ MAD_ERROR_BADFRAMELEN = 0x0231, /* bad frame length */
+ MAD_ERROR_BADBIGVALUES = 0x0232, /* bad big_values count */
+ MAD_ERROR_BADBLOCKTYPE = 0x0233, /* reserved block_type */
+ MAD_ERROR_BADSCFSI = 0x0234, /* bad scalefactor selection info */
+ MAD_ERROR_BADDATAPTR = 0x0235, /* bad main_data_begin pointer */
+ MAD_ERROR_BADPART3LEN = 0x0236, /* bad audio data length */
+ MAD_ERROR_BADHUFFTABLE = 0x0237, /* bad Huffman table select */
+ MAD_ERROR_BADHUFFDATA = 0x0238, /* Huffman data overrun */
+ MAD_ERROR_BADSTEREO = 0x0239 /* incompatible block_type for JS */
+};
+
+# define MAD_RECOVERABLE(error) ((error) & 0xff00)
+
+struct mad_stream {
+ unsigned char const *buffer; /* input bitstream buffer */
+ unsigned char const *bufend; /* end of buffer */
+ unsigned long skiplen; /* bytes to skip before next frame */
+
+ int sync; /* stream sync found */
+ unsigned long freerate; /* free bitrate (fixed) */
+
+ unsigned char const *this_frame; /* start of current frame */
+ unsigned char const *next_frame; /* start of next frame */
+ struct mad_bitptr ptr; /* current processing bit pointer */
+
+ struct mad_bitptr anc_ptr; /* ancillary bits pointer */
+ unsigned int anc_bitlen; /* number of ancillary bits */
+
+ unsigned char (*main_data)[MAD_BUFFER_MDLEN];
+ /* Layer III main_data() */
+ unsigned int md_len; /* bytes in main_data */
+
+ int options; /* decoding options (see below) */
+ enum mad_error error; /* error code (see above) */
+};
+
+enum {
+ MAD_OPTION_IGNORECRC = 0x0001, /* ignore CRC errors */
+ MAD_OPTION_HALFSAMPLERATE = 0x0002 /* generate PCM at 1/2 sample rate */
+# if 0 /* not yet implemented */
+ MAD_OPTION_LEFTCHANNEL = 0x0010, /* decode left channel only */
+ MAD_OPTION_RIGHTCHANNEL = 0x0020, /* decode right channel only */
+ MAD_OPTION_SINGLECHANNEL = 0x0030 /* combine channels */
+# endif
+};
+
+void mad_stream_init(struct mad_stream *);
+void mad_stream_finish(struct mad_stream *);
+
+# define mad_stream_options(stream, opts) \
+ ((void) ((stream)->options = (opts)))
+
+void mad_stream_buffer(struct mad_stream *,
+ unsigned char const *, unsigned long);
+void mad_stream_skip(struct mad_stream *, unsigned long);
+
+int mad_stream_sync(struct mad_stream *);
+
+char const *mad_stream_errorstr(struct mad_stream const *);
+
+# endif
+
+/* Id: frame.h,v 1.20 2004/01/23 09:41:32 rob Exp */
+
+# ifndef LIBMAD_FRAME_H
+# define LIBMAD_FRAME_H
+
+
+enum mad_layer {
+ MAD_LAYER_I = 1, /* Layer I */
+ MAD_LAYER_II = 2, /* Layer II */
+ MAD_LAYER_III = 3 /* Layer III */
+};
+
+enum mad_mode {
+ MAD_MODE_SINGLE_CHANNEL = 0, /* single channel */
+ MAD_MODE_DUAL_CHANNEL = 1, /* dual channel */
+ MAD_MODE_JOINT_STEREO = 2, /* joint (MS/intensity) stereo */
+ MAD_MODE_STEREO = 3 /* normal LR stereo */
+};
+
+enum mad_emphasis {
+ MAD_EMPHASIS_NONE = 0, /* no emphasis */
+ MAD_EMPHASIS_50_15_US = 1, /* 50/15 microseconds emphasis */
+ MAD_EMPHASIS_CCITT_J_17 = 3, /* CCITT J.17 emphasis */
+ MAD_EMPHASIS_RESERVED = 2 /* unknown emphasis */
+};
+
+struct mad_header {
+ enum mad_layer layer; /* audio layer (1, 2, or 3) */
+ enum mad_mode mode; /* channel mode (see above) */
+ int mode_extension; /* additional mode info */
+ enum mad_emphasis emphasis; /* de-emphasis to use (see above) */
+
+ unsigned long bitrate; /* stream bitrate (bps) */
+ unsigned int samplerate; /* sampling frequency (Hz) */
+
+ unsigned short crc_check; /* frame CRC accumulator */
+ unsigned short crc_target; /* final target CRC checksum */
+
+ int flags; /* flags (see below) */
+ int private_bits; /* private bits (see below) */
+
+ mad_timer_t duration; /* audio playing time of frame */
+};
+
+struct mad_frame {
+ struct mad_header header; /* MPEG audio header */
+
+ int options; /* decoding options (from stream) */
+
+ mad_fixed_t sbsample[2][36][32]; /* synthesis subband filter samples */
+ mad_fixed_t (*overlap)[2][32][18]; /* Layer III block overlap data */
+};
+
+# define MAD_NCHANNELS(header) ((header)->mode ? 2 : 1)
+# define MAD_NSBSAMPLES(header) \
+ ((header)->layer == MAD_LAYER_I ? 12 : \
+ (((header)->layer == MAD_LAYER_III && \
+ ((header)->flags & MAD_FLAG_LSF_EXT)) ? 18 : 36))
+
+enum {
+ MAD_FLAG_NPRIVATE_III = 0x0007, /* number of Layer III private bits */
+ MAD_FLAG_INCOMPLETE = 0x0008, /* header but not data is decoded */
+
+ MAD_FLAG_PROTECTION = 0x0010, /* frame has CRC protection */
+ MAD_FLAG_COPYRIGHT = 0x0020, /* frame is copyright */
+ MAD_FLAG_ORIGINAL = 0x0040, /* frame is original (else copy) */
+ MAD_FLAG_PADDING = 0x0080, /* frame has additional slot */
+
+ MAD_FLAG_I_STEREO = 0x0100, /* uses intensity joint stereo */
+ MAD_FLAG_MS_STEREO = 0x0200, /* uses middle/side joint stereo */
+ MAD_FLAG_FREEFORMAT = 0x0400, /* uses free format bitrate */
+
+ MAD_FLAG_LSF_EXT = 0x1000, /* lower sampling freq. extension */
+ MAD_FLAG_MC_EXT = 0x2000, /* multichannel audio extension */
+ MAD_FLAG_MPEG_2_5_EXT = 0x4000 /* MPEG 2.5 (unofficial) extension */
+};
+
+enum {
+ MAD_PRIVATE_HEADER = 0x0100, /* header private bit */
+ MAD_PRIVATE_III = 0x001f /* Layer III private bits (up to 5) */
+};
+
+void mad_header_init(struct mad_header *);
+
+# define mad_header_finish(header) /* nothing */
+
+int mad_header_decode(struct mad_header *, struct mad_stream *);
+
+void mad_frame_init(struct mad_frame *);
+void mad_frame_finish(struct mad_frame *);
+
+int mad_frame_decode(struct mad_frame *, struct mad_stream *);
+
+void mad_frame_mute(struct mad_frame *);
+
+# endif
+
+/* Id: synth.h,v 1.15 2004/01/23 09:41:33 rob Exp */
+
+# ifndef LIBMAD_SYNTH_H
+# define LIBMAD_SYNTH_H
+
+
+struct mad_pcm {
+ unsigned int samplerate; /* sampling frequency (Hz) */
+ unsigned short channels; /* number of channels */
+ unsigned short length; /* number of samples per channel */
+ mad_fixed_t samples[2][1152]; /* PCM output samples [ch][sample] */
+};
+
+struct mad_synth {
+ mad_fixed_t filter[2][2][2][16][8]; /* polyphase filterbank outputs */
+ /* [ch][eo][peo][s][v] */
+
+ unsigned int phase; /* current processing phase */
+
+ struct mad_pcm pcm; /* PCM output */
+};
+
+/* single channel PCM selector */
+enum {
+ MAD_PCM_CHANNEL_SINGLE = 0
+};
+
+/* dual channel PCM selector */
+enum {
+ MAD_PCM_CHANNEL_DUAL_1 = 0,
+ MAD_PCM_CHANNEL_DUAL_2 = 1
+};
+
+/* stereo PCM selector */
+enum {
+ MAD_PCM_CHANNEL_STEREO_LEFT = 0,
+ MAD_PCM_CHANNEL_STEREO_RIGHT = 1
+};
+
+void mad_synth_init(struct mad_synth *);
+
+# define mad_synth_finish(synth) /* nothing */
+
+void mad_synth_mute(struct mad_synth *);
+
+void mad_synth_frame(struct mad_synth *, struct mad_frame const *);
+
+# endif
+
+/* Id: decoder.h,v 1.17 2004/01/23 09:41:32 rob Exp */
+
+# ifndef LIBMAD_DECODER_H
+# define LIBMAD_DECODER_H
+
+
+enum mad_decoder_mode {
+ MAD_DECODER_MODE_SYNC = 0,
+ MAD_DECODER_MODE_ASYNC
+};
+
+enum mad_flow {
+ MAD_FLOW_CONTINUE = 0x0000, /* continue normally */
+ MAD_FLOW_STOP = 0x0010, /* stop decoding normally */
+ MAD_FLOW_BREAK = 0x0011, /* stop decoding and signal an error */
+ MAD_FLOW_IGNORE = 0x0020 /* ignore the current frame */
+};
+
+struct mad_decoder {
+ enum mad_decoder_mode mode;
+
+ int options;
+
+ struct {
+ long pid;
+ int in;
+ int out;
+ } async;
+
+ struct {
+ struct mad_stream stream;
+ struct mad_frame frame;
+ struct mad_synth synth;
+ } *sync;
+
+ void *cb_data;
+
+ enum mad_flow (*input_func)(void *, struct mad_stream *);
+ enum mad_flow (*header_func)(void *, struct mad_header const *);
+ enum mad_flow (*filter_func)(void *,
+ struct mad_stream const *, struct mad_frame *);
+ enum mad_flow (*output_func)(void *,
+ struct mad_header const *, struct mad_pcm *);
+ enum mad_flow (*error_func)(void *, struct mad_stream *, struct mad_frame *);
+ enum mad_flow (*message_func)(void *, void *, unsigned int *);
+};
+
+void mad_decoder_init(struct mad_decoder *, void *,
+ enum mad_flow (*)(void *, struct mad_stream *),
+ enum mad_flow (*)(void *, struct mad_header const *),
+ enum mad_flow (*)(void *,
+ struct mad_stream const *,
+ struct mad_frame *),
+ enum mad_flow (*)(void *,
+ struct mad_header const *,
+ struct mad_pcm *),
+ enum mad_flow (*)(void *,
+ struct mad_stream *,
+ struct mad_frame *),
+ enum mad_flow (*)(void *, void *, unsigned int *));
+int mad_decoder_finish(struct mad_decoder *);
+
+# define mad_decoder_options(decoder, opts) \
+ ((void) ((decoder)->options = (opts)))
+
+int mad_decoder_run(struct mad_decoder *, enum mad_decoder_mode);
+int mad_decoder_message(struct mad_decoder *, void *, unsigned int *);
+
+# endif
+
+# ifdef __cplusplus
+}
+# endif
diff --git a/lib-x86-32/include/neaacdec.h b/lib-x86-32/include/neaacdec.h
new file mode 100644
index 00000000..a45f1d09
--- /dev/null
+++ b/lib-x86-32/include/neaacdec.h
@@ -0,0 +1,258 @@
+/*
+** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+**
+** Any non-GPL usage of this software or parts of this software is strictly
+** forbidden.
+**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
+** Commercial non-GPL licensing of this software is possible.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
+**
+** $Id: neaacdec.h,v 1.13 2009/01/26 23:51:15 menno Exp $
+**/
+
+#ifndef __NEAACDEC_H__
+#define __NEAACDEC_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#if 1
+/* MACROS FOR BACKWARDS COMPATIBILITY */
+/* structs */
+#define faacDecHandle NeAACDecHandle
+#define faacDecConfiguration NeAACDecConfiguration
+#define faacDecConfigurationPtr NeAACDecConfigurationPtr
+#define faacDecFrameInfo NeAACDecFrameInfo
+/* functions */
+#define faacDecGetErrorMessage NeAACDecGetErrorMessage
+#define faacDecSetConfiguration NeAACDecSetConfiguration
+#define faacDecGetCurrentConfiguration NeAACDecGetCurrentConfiguration
+#define faacDecInit NeAACDecInit
+#define faacDecInit2 NeAACDecInit2
+#define faacDecInitDRM NeAACDecInitDRM
+#define faacDecPostSeekReset NeAACDecPostSeekReset
+#define faacDecOpen NeAACDecOpen
+#define faacDecClose NeAACDecClose
+#define faacDecDecode NeAACDecDecode
+#define AudioSpecificConfig NeAACDecAudioSpecificConfig
+#endif
+
+
+#ifdef _WIN32
+ #pragma pack(push, 8)
+ #ifndef NEAACDECAPI
+ #define NEAACDECAPI __cdecl
+ #endif
+#else
+ #ifndef NEAACDECAPI
+ #define NEAACDECAPI
+ #endif
+#endif
+
+#define FAAD2_VERSION "2.7"
+
+/* object types for AAC */
+#define MAIN 1
+#define LC 2
+#define SSR 3
+#define LTP 4
+#define HE_AAC 5
+#define ER_LC 17
+#define ER_LTP 19
+#define LD 23
+#define DRM_ER_LC 27 /* special object type for DRM */
+
+/* header types */
+#define RAW 0
+#define ADIF 1
+#define ADTS 2
+#define LATM 3
+
+/* SBR signalling */
+#define NO_SBR 0
+#define SBR_UPSAMPLED 1
+#define SBR_DOWNSAMPLED 2
+#define NO_SBR_UPSAMPLED 3
+
+/* library output formats */
+#define FAAD_FMT_16BIT 1
+#define FAAD_FMT_24BIT 2
+#define FAAD_FMT_32BIT 3
+#define FAAD_FMT_FLOAT 4
+#define FAAD_FMT_FIXED FAAD_FMT_FLOAT
+#define FAAD_FMT_DOUBLE 5
+
+/* Capabilities */
+#define LC_DEC_CAP (1<<0) /* Can decode LC */
+#define MAIN_DEC_CAP (1<<1) /* Can decode MAIN */
+#define LTP_DEC_CAP (1<<2) /* Can decode LTP */
+#define LD_DEC_CAP (1<<3) /* Can decode LD */
+#define ERROR_RESILIENCE_CAP (1<<4) /* Can decode ER */
+#define FIXED_POINT_CAP (1<<5) /* Fixed point */
+
+/* Channel definitions */
+#define FRONT_CHANNEL_CENTER (1)
+#define FRONT_CHANNEL_LEFT (2)
+#define FRONT_CHANNEL_RIGHT (3)
+#define SIDE_CHANNEL_LEFT (4)
+#define SIDE_CHANNEL_RIGHT (5)
+#define BACK_CHANNEL_LEFT (6)
+#define BACK_CHANNEL_RIGHT (7)
+#define BACK_CHANNEL_CENTER (8)
+#define LFE_CHANNEL (9)
+#define UNKNOWN_CHANNEL (0)
+
+/* DRM channel definitions */
+#define DRMCH_MONO 1
+#define DRMCH_STEREO 2
+#define DRMCH_SBR_MONO 3
+#define DRMCH_SBR_STEREO 4
+#define DRMCH_SBR_PS_STEREO 5
+
+
+/* A decode call can eat up to FAAD_MIN_STREAMSIZE bytes per decoded channel,
+ so at least so much bytes per channel should be available in this stream */
+#define FAAD_MIN_STREAMSIZE 768 /* 6144 bits/channel */
+
+
+typedef void *NeAACDecHandle;
+
+typedef struct mp4AudioSpecificConfig
+{
+ /* Audio Specific Info */
+ unsigned char objectTypeIndex;
+ unsigned char samplingFrequencyIndex;
+ unsigned long samplingFrequency;
+ unsigned char channelsConfiguration;
+
+ /* GA Specific Info */
+ unsigned char frameLengthFlag;
+ unsigned char dependsOnCoreCoder;
+ unsigned short coreCoderDelay;
+ unsigned char extensionFlag;
+ unsigned char aacSectionDataResilienceFlag;
+ unsigned char aacScalefactorDataResilienceFlag;
+ unsigned char aacSpectralDataResilienceFlag;
+ unsigned char epConfig;
+
+ char sbr_present_flag;
+ char forceUpSampling;
+ char downSampledSBR;
+} mp4AudioSpecificConfig;
+
+typedef struct NeAACDecConfiguration
+{
+ unsigned char defObjectType;
+ unsigned long defSampleRate;
+ unsigned char outputFormat;
+ unsigned char downMatrix;
+ unsigned char useOldADTSFormat;
+ unsigned char dontUpSampleImplicitSBR;
+} NeAACDecConfiguration, *NeAACDecConfigurationPtr;
+
+typedef struct NeAACDecFrameInfo
+{
+ unsigned long bytesconsumed;
+ unsigned long samples;
+ unsigned char channels;
+ unsigned char error;
+ unsigned long samplerate;
+
+ /* SBR: 0: off, 1: on; upsample, 2: on; downsampled, 3: off; upsampled */
+ unsigned char sbr;
+
+ /* MPEG-4 ObjectType */
+ unsigned char object_type;
+
+ /* AAC header type; MP4 will be signalled as RAW also */
+ unsigned char header_type;
+
+ /* multichannel configuration */
+ unsigned char num_front_channels;
+ unsigned char num_side_channels;
+ unsigned char num_back_channels;
+ unsigned char num_lfe_channels;
+ unsigned char channel_position[64];
+
+ /* PS: 0: off, 1: on */
+ unsigned char ps;
+} NeAACDecFrameInfo;
+
+char* NEAACDECAPI NeAACDecGetErrorMessage(unsigned char errcode);
+
+unsigned long NEAACDECAPI NeAACDecGetCapabilities(void);
+
+NeAACDecHandle NEAACDECAPI NeAACDecOpen(void);
+
+NeAACDecConfigurationPtr NEAACDECAPI NeAACDecGetCurrentConfiguration(NeAACDecHandle hDecoder);
+
+unsigned char NEAACDECAPI NeAACDecSetConfiguration(NeAACDecHandle hDecoder,
+ NeAACDecConfigurationPtr config);
+
+/* Init the library based on info from the AAC file (ADTS/ADIF) */
+long NEAACDECAPI NeAACDecInit(NeAACDecHandle hDecoder,
+ unsigned char *buffer,
+ unsigned long buffer_size,
+ unsigned long *samplerate,
+ unsigned char *channels);
+
+/* Init the library using a DecoderSpecificInfo */
+char NEAACDECAPI NeAACDecInit2(NeAACDecHandle hDecoder,
+ unsigned char *pBuffer,
+ unsigned long SizeOfDecoderSpecificInfo,
+ unsigned long *samplerate,
+ unsigned char *channels);
+
+/* Init the library for DRM */
+char NEAACDECAPI NeAACDecInitDRM(NeAACDecHandle *hDecoder, unsigned long samplerate,
+ unsigned char channels);
+
+void NEAACDECAPI NeAACDecPostSeekReset(NeAACDecHandle hDecoder, long frame);
+
+void NEAACDECAPI NeAACDecClose(NeAACDecHandle hDecoder);
+
+void* NEAACDECAPI NeAACDecDecode(NeAACDecHandle hDecoder,
+ NeAACDecFrameInfo *hInfo,
+ unsigned char *buffer,
+ unsigned long buffer_size);
+
+void* NEAACDECAPI NeAACDecDecode2(NeAACDecHandle hDecoder,
+ NeAACDecFrameInfo *hInfo,
+ unsigned char *buffer,
+ unsigned long buffer_size,
+ void **sample_buffer,
+ unsigned long sample_buffer_size);
+
+char NEAACDECAPI NeAACDecAudioSpecificConfig(unsigned char *pBuffer,
+ unsigned long buffer_size,
+ mp4AudioSpecificConfig *mp4ASC);
+
+#ifdef _WIN32
+ #pragma pack(pop)
+#endif
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/lib-x86-32/include/ogg/Makefile.am b/lib-x86-32/include/ogg/Makefile.am
new file mode 100644
index 00000000..142699d3
--- /dev/null
+++ b/lib-x86-32/include/ogg/Makefile.am
@@ -0,0 +1,6 @@
+## Process this file with automake to produce Makefile.in
+
+oggincludedir = $(includedir)/ogg
+
+ogginclude_HEADERS = ogg.h os_types.h
+nodist_ogginclude_HEADERS = config_types.h
diff --git a/lib-x86-32/include/ogg/config_types.h b/lib-x86-32/include/ogg/config_types.h
new file mode 100644
index 00000000..496e900f
--- /dev/null
+++ b/lib-x86-32/include/ogg/config_types.h
@@ -0,0 +1,11 @@
+#ifndef __CONFIG_TYPES_H__
+#define __CONFIG_TYPES_H__
+
+/* these are filled in by configure */
+typedef int16_t ogg_int16_t;
+typedef u_int16_t ogg_uint16_t;
+typedef int32_t ogg_int32_t;
+typedef u_int32_t ogg_uint32_t;
+typedef int64_t ogg_int64_t;
+
+#endif
diff --git a/lib-x86-32/include/ogg/config_types.h.in b/lib-x86-32/include/ogg/config_types.h.in
new file mode 100644
index 00000000..568a001f
--- /dev/null
+++ b/lib-x86-32/include/ogg/config_types.h.in
@@ -0,0 +1,11 @@
+#ifndef __CONFIG_TYPES_H__
+#define __CONFIG_TYPES_H__
+
+/* these are filled in by configure */
+typedef @SIZE16@ ogg_int16_t;
+typedef @USIZE16@ ogg_uint16_t;
+typedef @SIZE32@ ogg_int32_t;
+typedef @USIZE32@ ogg_uint32_t;
+typedef @SIZE64@ ogg_int64_t;
+
+#endif
diff --git a/lib-x86-32/include/ogg/ogg.h b/lib-x86-32/include/ogg/ogg.h
new file mode 100644
index 00000000..ae0cfd53
--- /dev/null
+++ b/lib-x86-32/include/ogg/ogg.h
@@ -0,0 +1,208 @@
+/********************************************************************
+ * *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
+ * *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007 *
+ * by the Xiph.Org Foundation http://www.xiph.org/ *
+ * *
+ ********************************************************************
+
+ function: toplevel libogg include
+ last mod: $Id: ogg.h 16051 2009-05-27 05:00:06Z xiphmont $
+
+ ********************************************************************/
+#ifndef _OGG_H
+#define _OGG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stddef.h>
+#include <ogg/os_types.h>
+
+typedef struct {
+ void *iov_base;
+ size_t iov_len;
+} ogg_iovec_t;
+
+typedef struct {
+ long endbyte;
+ int endbit;
+
+ unsigned char *buffer;
+ unsigned char *ptr;
+ long storage;
+} oggpack_buffer;
+
+/* ogg_page is used to encapsulate the data in one Ogg bitstream page *****/
+
+typedef struct {
+ unsigned char *header;
+ long header_len;
+ unsigned char *body;
+ long body_len;
+} ogg_page;
+
+/* ogg_stream_state contains the current encode/decode state of a logical
+ Ogg bitstream **********************************************************/
+
+typedef struct {
+ unsigned char *body_data; /* bytes from packet bodies */
+ long body_storage; /* storage elements allocated */
+ long body_fill; /* elements stored; fill mark */
+ long body_returned; /* elements of fill returned */
+
+
+ int *lacing_vals; /* The values that will go to the segment table */
+ ogg_int64_t *granule_vals; /* granulepos values for headers. Not compact
+ this way, but it is simple coupled to the
+ lacing fifo */
+ long lacing_storage;
+ long lacing_fill;
+ long lacing_packet;
+ long lacing_returned;
+
+ unsigned char header[282]; /* working space for header encode */
+ int header_fill;
+
+ int e_o_s; /* set when we have buffered the last packet in the
+ logical bitstream */
+ int b_o_s; /* set after we've written the initial page
+ of a logical bitstream */
+ long serialno;
+ long pageno;
+ ogg_int64_t packetno; /* sequence number for decode; the framing
+ knows where there's a hole in the data,
+ but we need coupling so that the codec
+ (which is in a seperate abstraction
+ layer) also knows about the gap */
+ ogg_int64_t granulepos;
+
+} ogg_stream_state;
+
+/* ogg_packet is used to encapsulate the data and metadata belonging
+ to a single raw Ogg/Vorbis packet *************************************/
+
+typedef struct {
+ unsigned char *packet;
+ long bytes;
+ long b_o_s;
+ long e_o_s;
+
+ ogg_int64_t granulepos;
+
+ ogg_int64_t packetno; /* sequence number for decode; the framing
+ knows where there's a hole in the data,
+ but we need coupling so that the codec
+ (which is in a seperate abstraction
+ layer) also knows about the gap */
+} ogg_packet;
+
+typedef struct {
+ unsigned char *data;
+ int storage;
+ int fill;
+ int returned;
+
+ int unsynced;
+ int headerbytes;
+ int bodybytes;
+} ogg_sync_state;
+
+/* Ogg BITSTREAM PRIMITIVES: bitstream ************************/
+
+extern void oggpack_writeinit(oggpack_buffer *b);
+extern int oggpack_writecheck(oggpack_buffer *b);
+extern void oggpack_writetrunc(oggpack_buffer *b,long bits);
+extern void oggpack_writealign(oggpack_buffer *b);
+extern void oggpack_writecopy(oggpack_buffer *b,void *source,long bits);
+extern void oggpack_reset(oggpack_buffer *b);
+extern void oggpack_writeclear(oggpack_buffer *b);
+extern void oggpack_readinit(oggpack_buffer *b,unsigned char *buf,int bytes);
+extern void oggpack_write(oggpack_buffer *b,unsigned long value,int bits);
+extern long oggpack_look(oggpack_buffer *b,int bits);
+extern long oggpack_look1(oggpack_buffer *b);
+extern void oggpack_adv(oggpack_buffer *b,int bits);
+extern void oggpack_adv1(oggpack_buffer *b);
+extern long oggpack_read(oggpack_buffer *b,int bits);
+extern long oggpack_read1(oggpack_buffer *b);
+extern long oggpack_bytes(oggpack_buffer *b);
+extern long oggpack_bits(oggpack_buffer *b);
+extern unsigned char *oggpack_get_buffer(oggpack_buffer *b);
+
+extern void oggpackB_writeinit(oggpack_buffer *b);
+extern int oggpackB_writecheck(oggpack_buffer *b);
+extern void oggpackB_writetrunc(oggpack_buffer *b,long bits);
+extern void oggpackB_writealign(oggpack_buffer *b);
+extern void oggpackB_writecopy(oggpack_buffer *b,void *source,long bits);
+extern void oggpackB_reset(oggpack_buffer *b);
+extern void oggpackB_writeclear(oggpack_buffer *b);
+extern void oggpackB_readinit(oggpack_buffer *b,unsigned char *buf,int bytes);
+extern void oggpackB_write(oggpack_buffer *b,unsigned long value,int bits);
+extern long oggpackB_look(oggpack_buffer *b,int bits);
+extern long oggpackB_look1(oggpack_buffer *b);
+extern void oggpackB_adv(oggpack_buffer *b,int bits);
+extern void oggpackB_adv1(oggpack_buffer *b);
+extern long oggpackB_read(oggpack_buffer *b,int bits);
+extern long oggpackB_read1(oggpack_buffer *b);
+extern long oggpackB_bytes(oggpack_buffer *b);
+extern long oggpackB_bits(oggpack_buffer *b);
+extern unsigned char *oggpackB_get_buffer(oggpack_buffer *b);
+
+/* Ogg BITSTREAM PRIMITIVES: encoding **************************/
+
+extern int ogg_stream_packetin(ogg_stream_state *os, ogg_packet *op);
+extern int ogg_stream_iovecin(ogg_stream_state *os, ogg_iovec_t *iov,
+ int count, long e_o_s, ogg_int64_t granulepos);
+extern int ogg_stream_pageout(ogg_stream_state *os, ogg_page *og);
+extern int ogg_stream_flush(ogg_stream_state *os, ogg_page *og);
+
+/* Ogg BITSTREAM PRIMITIVES: decoding **************************/
+
+extern int ogg_sync_init(ogg_sync_state *oy);
+extern int ogg_sync_clear(ogg_sync_state *oy);
+extern int ogg_sync_reset(ogg_sync_state *oy);
+extern int ogg_sync_destroy(ogg_sync_state *oy);
+extern int ogg_sync_check(ogg_sync_state *oy);
+
+extern char *ogg_sync_buffer(ogg_sync_state *oy, long size);
+extern int ogg_sync_wrote(ogg_sync_state *oy, long bytes);
+extern long ogg_sync_pageseek(ogg_sync_state *oy,ogg_page *og);
+extern int ogg_sync_pageout(ogg_sync_state *oy, ogg_page *og);
+extern int ogg_stream_pagein(ogg_stream_state *os, ogg_page *og);
+extern int ogg_stream_packetout(ogg_stream_state *os,ogg_packet *op);
+extern int ogg_stream_packetpeek(ogg_stream_state *os,ogg_packet *op);
+
+/* Ogg BITSTREAM PRIMITIVES: general ***************************/
+
+extern int ogg_stream_init(ogg_stream_state *os,int serialno);
+extern int ogg_stream_clear(ogg_stream_state *os);
+extern int ogg_stream_reset(ogg_stream_state *os);
+extern int ogg_stream_reset_serialno(ogg_stream_state *os,int serialno);
+extern int ogg_stream_destroy(ogg_stream_state *os);
+extern int ogg_stream_check(ogg_stream_state *os);
+extern int ogg_stream_eos(ogg_stream_state *os);
+
+extern void ogg_page_checksum_set(ogg_page *og);
+
+extern int ogg_page_version(const ogg_page *og);
+extern int ogg_page_continued(const ogg_page *og);
+extern int ogg_page_bos(const ogg_page *og);
+extern int ogg_page_eos(const ogg_page *og);
+extern ogg_int64_t ogg_page_granulepos(const ogg_page *og);
+extern int ogg_page_serialno(const ogg_page *og);
+extern long ogg_page_pageno(const ogg_page *og);
+extern int ogg_page_packets(const ogg_page *og);
+
+extern void ogg_packet_clear(ogg_packet *op);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _OGG_H */
diff --git a/lib-x86-32/include/ogg/os_types.h b/lib-x86-32/include/ogg/os_types.h
new file mode 100644
index 00000000..f6f8b381
--- /dev/null
+++ b/lib-x86-32/include/ogg/os_types.h
@@ -0,0 +1,148 @@
+/********************************************************************
+ * *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
+ * *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
+ * by the Xiph.Org Foundation http://www.xiph.org/ *
+ * *
+ ********************************************************************
+
+ function: #ifdef jail to whip a few platforms into the UNIX ideal.
+ last mod: $Id: os_types.h 16649 2009-10-25 00:49:58Z ds $
+
+ ********************************************************************/
+#ifndef _OS_TYPES_H
+#define _OS_TYPES_H
+
+/* make it easy on the folks that want to compile the libs with a
+ different malloc than stdlib */
+#define _ogg_malloc malloc
+#define _ogg_calloc calloc
+#define _ogg_realloc realloc
+#define _ogg_free free
+
+#if defined(_WIN32)
+
+# if defined(__CYGWIN__)
+# include <stdint.h>
+ typedef int16_t ogg_int16_t;
+ typedef uint16_t ogg_uint16_t;
+ typedef int32_t ogg_int32_t;
+ typedef uint32_t ogg_uint32_t;
+ typedef int64_t ogg_int64_t;
+ typedef uint64_t ogg_uint64_t;
+# elif defined(__MINGW32__)
+# include <sys/types.h>
+ typedef short ogg_int16_t;
+ typedef unsigned short ogg_uint16_t;
+ typedef int ogg_int32_t;
+ typedef unsigned int ogg_uint32_t;
+ typedef long long ogg_int64_t;
+ typedef unsigned long long ogg_uint64_t;
+# elif defined(__MWERKS__)
+ typedef long long ogg_int64_t;
+ typedef int ogg_int32_t;
+ typedef unsigned int ogg_uint32_t;
+ typedef short ogg_int16_t;
+ typedef unsigned short ogg_uint16_t;
+# else
+ /* MSVC/Borland */
+ typedef __int64 ogg_int64_t;
+ typedef __int32 ogg_int32_t;
+ typedef unsigned __int32 ogg_uint32_t;
+ typedef __int16 ogg_int16_t;
+ typedef unsigned __int16 ogg_uint16_t;
+# endif
+
+#elif defined(__MACOS__)
+
+# include <sys/types.h>
+ typedef SInt16 ogg_int16_t;
+ typedef UInt16 ogg_uint16_t;
+ typedef SInt32 ogg_int32_t;
+ typedef UInt32 ogg_uint32_t;
+ typedef SInt64 ogg_int64_t;
+
+#elif (defined(__APPLE__) && defined(__MACH__)) /* MacOS X Framework build */
+
+# include <sys/types.h>
+ typedef int16_t ogg_int16_t;
+ typedef u_int16_t ogg_uint16_t;
+ typedef int32_t ogg_int32_t;
+ typedef u_int32_t ogg_uint32_t;
+ typedef int64_t ogg_int64_t;
+
+#elif defined(__HAIKU__)
+
+ /* Haiku */
+# include <sys/types.h>
+ typedef short ogg_int16_t;
+ typedef unsigned short ogg_uint16_t;
+ typedef int ogg_int32_t;
+ typedef unsigned int ogg_uint32_t;
+ typedef long long ogg_int64_t;
+
+#elif defined(__BEOS__)
+
+ /* Be */
+# include <inttypes.h>
+ typedef int16_t ogg_int16_t;
+ typedef u_int16_t ogg_uint16_t;
+ typedef int32_t ogg_int32_t;
+ typedef u_int32_t ogg_uint32_t;
+ typedef int64_t ogg_int64_t;
+
+#elif defined (__EMX__)
+
+ /* OS/2 GCC */
+ typedef short ogg_int16_t;
+ typedef unsigned short ogg_uint16_t;
+ typedef int ogg_int32_t;
+ typedef unsigned int ogg_uint32_t;
+ typedef long long ogg_int64_t;
+
+#elif defined (DJGPP)
+
+ /* DJGPP */
+ typedef short ogg_int16_t;
+ typedef int ogg_int32_t;
+ typedef unsigned int ogg_uint32_t;
+ typedef long long ogg_int64_t;
+
+#elif defined(R5900)
+
+ /* PS2 EE */
+ typedef long ogg_int64_t;
+ typedef int ogg_int32_t;
+ typedef unsigned ogg_uint32_t;
+ typedef short ogg_int16_t;
+
+#elif defined(__SYMBIAN32__)
+
+ /* Symbian GCC */
+ typedef signed short ogg_int16_t;
+ typedef unsigned short ogg_uint16_t;
+ typedef signed int ogg_int32_t;
+ typedef unsigned int ogg_uint32_t;
+ typedef long long int ogg_int64_t;
+
+#elif defined(__TMS320C6X__)
+
+ /* TI C64x compiler */
+ typedef signed short ogg_int16_t;
+ typedef unsigned short ogg_uint16_t;
+ typedef signed int ogg_int32_t;
+ typedef unsigned int ogg_uint32_t;
+ typedef long long int ogg_int64_t;
+
+#else
+
+# include <sys/types.h>
+# include <ogg/config_types.h>
+
+#endif
+
+#endif /* _OS_TYPES_H */
diff --git a/lib-x86-32/include/samplerate.h b/lib-x86-32/include/samplerate.h
new file mode 100644
index 00000000..9651e635
--- /dev/null
+++ b/lib-x86-32/include/samplerate.h
@@ -0,0 +1,197 @@
+/*
+** Copyright (C) 2002-2008 Erik de Castro Lopo <erikd@mega-nerd.com>
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+/*
+** This code is part of Secret Rabibt Code aka libsamplerate. A commercial
+** use license for this code is available, please see:
+** http://www.mega-nerd.com/SRC/procedure.html
+*/
+
+/*
+** API documentation is available here:
+** http://www.mega-nerd.com/SRC/api.html
+*/
+
+#ifndef SAMPLERATE_H
+#define SAMPLERATE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+/* Opaque data type SRC_STATE. */
+typedef struct SRC_STATE_tag SRC_STATE ;
+
+/* SRC_DATA is used to pass data to src_simple() and src_process(). */
+typedef struct
+{ float *data_in, *data_out ;
+
+ long input_frames, output_frames ;
+ long input_frames_used, output_frames_gen ;
+
+ int end_of_input ;
+
+ double src_ratio ;
+} SRC_DATA ;
+
+/* SRC_CB_DATA is used with callback based API. */
+typedef struct
+{ long frames ;
+ float *data_in ;
+} SRC_CB_DATA ;
+
+/*
+** User supplied callback function type for use with src_callback_new()
+** and src_callback_read(). First parameter is the same pointer that was
+** passed into src_callback_new(). Second parameter is pointer to a
+** pointer. The user supplied callback function must modify *data to
+** point to the start of the user supplied float array. The user supplied
+** function must return the number of frames that **data points to.
+*/
+
+typedef long (*src_callback_t) (void *cb_data, float **data) ;
+
+/*
+** Standard initialisation function : return an anonymous pointer to the
+** internal state of the converter. Choose a converter from the enums below.
+** Error returned in *error.
+*/
+
+SRC_STATE* src_new (int converter_type, int channels, int *error) ;
+
+/*
+** Initilisation for callback based API : return an anonymous pointer to the
+** internal state of the converter. Choose a converter from the enums below.
+** The cb_data pointer can point to any data or be set to NULL. Whatever the
+** value, when processing, user supplied function "func" gets called with
+** cb_data as first parameter.
+*/
+
+SRC_STATE* src_callback_new (src_callback_t func, int converter_type, int channels,
+ int *error, void* cb_data) ;
+
+/*
+** Cleanup all internal allocations.
+** Always returns NULL.
+*/
+
+SRC_STATE* src_delete (SRC_STATE *state) ;
+
+/*
+** Standard processing function.
+** Returns non zero on error.
+*/
+
+int src_process (SRC_STATE *state, SRC_DATA *data) ;
+
+/*
+** Callback based processing function. Read up to frames worth of data from
+** the converter int *data and return frames read or -1 on error.
+*/
+long src_callback_read (SRC_STATE *state, double src_ratio, long frames, float *data) ;
+
+/*
+** Simple interface for performing a single conversion from input buffer to
+** output buffer at a fixed conversion ratio.
+** Simple interface does not require initialisation as it can only operate on
+** a single buffer worth of audio.
+*/
+
+int src_simple (SRC_DATA *data, int converter_type, int channels) ;
+
+/*
+** This library contains a number of different sample rate converters,
+** numbered 0 through N.
+**
+** Return a string giving either a name or a more full description of each
+** sample rate converter or NULL if no sample rate converter exists for
+** the given value. The converters are sequentially numbered from 0 to N.
+*/
+
+const char *src_get_name (int converter_type) ;
+const char *src_get_description (int converter_type) ;
+const char *src_get_version (void) ;
+
+/*
+** Set a new SRC ratio. This allows step responses
+** in the conversion ratio.
+** Returns non zero on error.
+*/
+
+int src_set_ratio (SRC_STATE *state, double new_ratio) ;
+
+/*
+** Reset the internal SRC state.
+** Does not modify the quality settings.
+** Does not free any memory allocations.
+** Returns non zero on error.
+*/
+
+int src_reset (SRC_STATE *state) ;
+
+/*
+** Return TRUE if ratio is a valid conversion ratio, FALSE
+** otherwise.
+*/
+
+int src_is_valid_ratio (double ratio) ;
+
+/*
+** Return an error number.
+*/
+
+int src_error (SRC_STATE *state) ;
+
+/*
+** Convert the error number into a string.
+*/
+const char* src_strerror (int error) ;
+
+/*
+** The following enums can be used to set the interpolator type
+** using the function src_set_converter().
+*/
+
+enum
+{
+ SRC_SINC_BEST_QUALITY = 0,
+ SRC_SINC_MEDIUM_QUALITY = 1,
+ SRC_SINC_FASTEST = 2,
+ SRC_ZERO_ORDER_HOLD = 3,
+ SRC_LINEAR = 4,
+} ;
+
+/*
+** Extra helper functions for converting from short to float and
+** back again.
+*/
+
+void src_short_to_float_array (const short *in, float *out, int len) ;
+void src_float_to_short_array (const float *in, short *out, int len) ;
+
+void src_int_to_float_array (const int *in, float *out, int len) ;
+void src_float_to_int_array (const float *in, int *out, int len) ;
+
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* __cplusplus */
+
+#endif /* SAMPLERATE_H */
+
diff --git a/lib-x86-32/include/sndfile.h b/lib-x86-32/include/sndfile.h
new file mode 100644
index 00000000..1b7e1f99
--- /dev/null
+++ b/lib-x86-32/include/sndfile.h
@@ -0,0 +1,665 @@
+/*
+** Copyright (C) 1999-2010 Erik de Castro Lopo <erikd@mega-nerd.com>
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU Lesser General Public License as published by
+** the Free Software Foundation; either version 2.1 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+/*
+** sndfile.h -- system-wide definitions
+**
+** API documentation is in the doc/ directory of the source code tarball
+** and at http://www.mega-nerd.com/libsndfile/api.html.
+*/
+
+#ifndef SNDFILE_H
+#define SNDFILE_H
+
+/* This is the version 1.0.X header file. */
+#define SNDFILE_1
+
+#include <stdio.h>
+#include <sys/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* The following file types can be read and written.
+** A file type would consist of a major type (ie SF_FORMAT_WAV) bitwise
+** ORed with a minor type (ie SF_FORMAT_PCM). SF_FORMAT_TYPEMASK and
+** SF_FORMAT_SUBMASK can be used to separate the major and minor file
+** types.
+*/
+
+enum
+{ /* Major formats. */
+ SF_FORMAT_WAV = 0x010000, /* Microsoft WAV format (little endian default). */
+ SF_FORMAT_AIFF = 0x020000, /* Apple/SGI AIFF format (big endian). */
+ SF_FORMAT_AU = 0x030000, /* Sun/NeXT AU format (big endian). */
+ SF_FORMAT_RAW = 0x040000, /* RAW PCM data. */
+ SF_FORMAT_PAF = 0x050000, /* Ensoniq PARIS file format. */
+ SF_FORMAT_SVX = 0x060000, /* Amiga IFF / SVX8 / SV16 format. */
+ SF_FORMAT_NIST = 0x070000, /* Sphere NIST format. */
+ SF_FORMAT_VOC = 0x080000, /* VOC files. */
+ SF_FORMAT_IRCAM = 0x0A0000, /* Berkeley/IRCAM/CARL */
+ SF_FORMAT_W64 = 0x0B0000, /* Sonic Foundry's 64 bit RIFF/WAV */
+ SF_FORMAT_MAT4 = 0x0C0000, /* Matlab (tm) V4.2 / GNU Octave 2.0 */
+ SF_FORMAT_MAT5 = 0x0D0000, /* Matlab (tm) V5.0 / GNU Octave 2.1 */
+ SF_FORMAT_PVF = 0x0E0000, /* Portable Voice Format */
+ SF_FORMAT_XI = 0x0F0000, /* Fasttracker 2 Extended Instrument */
+ SF_FORMAT_HTK = 0x100000, /* HMM Tool Kit format */
+ SF_FORMAT_SDS = 0x110000, /* Midi Sample Dump Standard */
+ SF_FORMAT_AVR = 0x120000, /* Audio Visual Research */
+ SF_FORMAT_WAVEX = 0x130000, /* MS WAVE with WAVEFORMATEX */
+ SF_FORMAT_SD2 = 0x160000, /* Sound Designer 2 */
+ SF_FORMAT_FLAC = 0x170000, /* FLAC lossless file format */
+ SF_FORMAT_CAF = 0x180000, /* Core Audio File format */
+ SF_FORMAT_WVE = 0x190000, /* Psion WVE format */
+ SF_FORMAT_OGG = 0x200000, /* Xiph OGG container */
+ SF_FORMAT_MPC2K = 0x210000, /* Akai MPC 2000 sampler */
+ SF_FORMAT_RF64 = 0x220000, /* RF64 WAV file */
+
+ /* Subtypes from here on. */
+
+ SF_FORMAT_PCM_S8 = 0x0001, /* Signed 8 bit data */
+ SF_FORMAT_PCM_16 = 0x0002, /* Signed 16 bit data */
+ SF_FORMAT_PCM_24 = 0x0003, /* Signed 24 bit data */
+ SF_FORMAT_PCM_32 = 0x0004, /* Signed 32 bit data */
+
+ SF_FORMAT_PCM_U8 = 0x0005, /* Unsigned 8 bit data (WAV and RAW only) */
+
+ SF_FORMAT_FLOAT = 0x0006, /* 32 bit float data */
+ SF_FORMAT_DOUBLE = 0x0007, /* 64 bit float data */
+
+ SF_FORMAT_ULAW = 0x0010, /* U-Law encoded. */
+ SF_FORMAT_ALAW = 0x0011, /* A-Law encoded. */
+ SF_FORMAT_IMA_ADPCM = 0x0012, /* IMA ADPCM. */
+ SF_FORMAT_MS_ADPCM = 0x0013, /* Microsoft ADPCM. */
+
+ SF_FORMAT_GSM610 = 0x0020, /* GSM 6.10 encoding. */
+ SF_FORMAT_VOX_ADPCM = 0x0021, /* OKI / Dialogix ADPCM */
+
+ SF_FORMAT_G721_32 = 0x0030, /* 32kbs G721 ADPCM encoding. */
+ SF_FORMAT_G723_24 = 0x0031, /* 24kbs G723 ADPCM encoding. */
+ SF_FORMAT_G723_40 = 0x0032, /* 40kbs G723 ADPCM encoding. */
+
+ SF_FORMAT_DWVW_12 = 0x0040, /* 12 bit Delta Width Variable Word encoding. */
+ SF_FORMAT_DWVW_16 = 0x0041, /* 16 bit Delta Width Variable Word encoding. */
+ SF_FORMAT_DWVW_24 = 0x0042, /* 24 bit Delta Width Variable Word encoding. */
+ SF_FORMAT_DWVW_N = 0x0043, /* N bit Delta Width Variable Word encoding. */
+
+ SF_FORMAT_DPCM_8 = 0x0050, /* 8 bit differential PCM (XI only) */
+ SF_FORMAT_DPCM_16 = 0x0051, /* 16 bit differential PCM (XI only) */
+
+ SF_FORMAT_VORBIS = 0x0060, /* Xiph Vorbis encoding. */
+
+ /* Endian-ness options. */
+
+ SF_ENDIAN_FILE = 0x00000000, /* Default file endian-ness. */
+ SF_ENDIAN_LITTLE = 0x10000000, /* Force little endian-ness. */
+ SF_ENDIAN_BIG = 0x20000000, /* Force big endian-ness. */
+ SF_ENDIAN_CPU = 0x30000000, /* Force CPU endian-ness. */
+
+ SF_FORMAT_SUBMASK = 0x0000FFFF,
+ SF_FORMAT_TYPEMASK = 0x0FFF0000,
+ SF_FORMAT_ENDMASK = 0x30000000
+} ;
+
+/*
+** The following are the valid command numbers for the sf_command()
+** interface. The use of these commands is documented in the file
+** command.html in the doc directory of the source code distribution.
+*/
+
+enum
+{ SFC_GET_LIB_VERSION = 0x1000,
+ SFC_GET_LOG_INFO = 0x1001,
+ SFC_GET_CURRENT_SF_INFO = 0x1002,
+
+
+ SFC_GET_NORM_DOUBLE = 0x1010,
+ SFC_GET_NORM_FLOAT = 0x1011,
+ SFC_SET_NORM_DOUBLE = 0x1012,
+ SFC_SET_NORM_FLOAT = 0x1013,
+ SFC_SET_SCALE_FLOAT_INT_READ = 0x1014,
+ SFC_SET_SCALE_INT_FLOAT_WRITE = 0x1015,
+
+ SFC_GET_SIMPLE_FORMAT_COUNT = 0x1020,
+ SFC_GET_SIMPLE_FORMAT = 0x1021,
+
+ SFC_GET_FORMAT_INFO = 0x1028,
+
+ SFC_GET_FORMAT_MAJOR_COUNT = 0x1030,
+ SFC_GET_FORMAT_MAJOR = 0x1031,
+ SFC_GET_FORMAT_SUBTYPE_COUNT = 0x1032,
+ SFC_GET_FORMAT_SUBTYPE = 0x1033,
+
+ SFC_CALC_SIGNAL_MAX = 0x1040,
+ SFC_CALC_NORM_SIGNAL_MAX = 0x1041,
+ SFC_CALC_MAX_ALL_CHANNELS = 0x1042,
+ SFC_CALC_NORM_MAX_ALL_CHANNELS = 0x1043,
+ SFC_GET_SIGNAL_MAX = 0x1044,
+ SFC_GET_MAX_ALL_CHANNELS = 0x1045,
+
+ SFC_SET_ADD_PEAK_CHUNK = 0x1050,
+ SFC_SET_ADD_HEADER_PAD_CHUNK = 0x1051,
+
+ SFC_UPDATE_HEADER_NOW = 0x1060,
+ SFC_SET_UPDATE_HEADER_AUTO = 0x1061,
+
+ SFC_FILE_TRUNCATE = 0x1080,
+
+ SFC_SET_RAW_START_OFFSET = 0x1090,
+
+ SFC_SET_DITHER_ON_WRITE = 0x10A0,
+ SFC_SET_DITHER_ON_READ = 0x10A1,
+
+ SFC_GET_DITHER_INFO_COUNT = 0x10A2,
+ SFC_GET_DITHER_INFO = 0x10A3,
+
+ SFC_GET_EMBED_FILE_INFO = 0x10B0,
+
+ SFC_SET_CLIPPING = 0x10C0,
+ SFC_GET_CLIPPING = 0x10C1,
+
+ SFC_GET_INSTRUMENT = 0x10D0,
+ SFC_SET_INSTRUMENT = 0x10D1,
+
+ SFC_GET_LOOP_INFO = 0x10E0,
+
+ SFC_GET_BROADCAST_INFO = 0x10F0,
+ SFC_SET_BROADCAST_INFO = 0x10F1,
+
+ SFC_GET_CHANNEL_MAP_INFO = 0x1100,
+ SFC_SET_CHANNEL_MAP_INFO = 0x1101,
+
+ SFC_RAW_DATA_NEEDS_ENDSWAP = 0x1110,
+
+ /* Support for Wavex Ambisonics Format */
+ SFC_WAVEX_SET_AMBISONIC = 0x1200,
+ SFC_WAVEX_GET_AMBISONIC = 0x1201,
+
+ SFC_SET_VBR_ENCODING_QUALITY = 0x1300,
+
+ /* Following commands for testing only. */
+ SFC_TEST_IEEE_FLOAT_REPLACE = 0x6001,
+
+ /*
+ ** SFC_SET_ADD_* values are deprecated and will disappear at some
+ ** time in the future. They are guaranteed to be here up to and
+ ** including version 1.0.8 to avoid breakage of existng software.
+ ** They currently do nothing and will continue to do nothing.
+ */
+ SFC_SET_ADD_DITHER_ON_WRITE = 0x1070,
+ SFC_SET_ADD_DITHER_ON_READ = 0x1071
+} ;
+
+
+/*
+** String types that can be set and read from files. Not all file types
+** support this and even the file types which support one, may not support
+** all string types.
+*/
+
+enum
+{ SF_STR_TITLE = 0x01,
+ SF_STR_COPYRIGHT = 0x02,
+ SF_STR_SOFTWARE = 0x03,
+ SF_STR_ARTIST = 0x04,
+ SF_STR_COMMENT = 0x05,
+ SF_STR_DATE = 0x06,
+ SF_STR_ALBUM = 0x07,
+ SF_STR_LICENSE = 0x08,
+ SF_STR_TRACKNUMBER = 0x09,
+ SF_STR_GENRE = 0x10
+} ;
+
+/*
+** Use the following as the start and end index when doing metadata
+** transcoding.
+*/
+
+#define SF_STR_FIRST SF_STR_TITLE
+#define SF_STR_LAST SF_STR_LICENSE
+
+enum
+{ /* True and false */
+ SF_FALSE = 0,
+ SF_TRUE = 1,
+
+ /* Modes for opening files. */
+ SFM_READ = 0x10,
+ SFM_WRITE = 0x20,
+ SFM_RDWR = 0x30,
+
+ SF_AMBISONIC_NONE = 0x40,
+ SF_AMBISONIC_B_FORMAT = 0x41
+} ;
+
+/* Public error values. These are guaranteed to remain unchanged for the duration
+** of the library major version number.
+** There are also a large number of private error numbers which are internal to
+** the library which can change at any time.
+*/
+
+enum
+{ SF_ERR_NO_ERROR = 0,
+ SF_ERR_UNRECOGNISED_FORMAT = 1,
+ SF_ERR_SYSTEM = 2,
+ SF_ERR_MALFORMED_FILE = 3,
+ SF_ERR_UNSUPPORTED_ENCODING = 4
+} ;
+
+
+/* Channel map values (used with SFC_SET/GET_CHANNEL_MAP).
+*/
+
+enum
+{ SF_CHANNEL_MAP_INVALID = 0,
+ SF_CHANNEL_MAP_MONO = 1,
+ SF_CHANNEL_MAP_LEFT, /* Apple calls this 'Left' */
+ SF_CHANNEL_MAP_RIGHT, /* Apple calls this 'Right' */
+ SF_CHANNEL_MAP_CENTER, /* Apple calls this 'Center' */
+ SF_CHANNEL_MAP_FRONT_LEFT,
+ SF_CHANNEL_MAP_FRONT_RIGHT,
+ SF_CHANNEL_MAP_FRONT_CENTER,
+ SF_CHANNEL_MAP_REAR_CENTER, /* Apple calls this 'Center Surround', Msft calls this 'Back Center' */
+ SF_CHANNEL_MAP_REAR_LEFT, /* Apple calls this 'Left Surround', Msft calls this 'Back Left' */
+ SF_CHANNEL_MAP_REAR_RIGHT, /* Apple calls this 'Right Surround', Msft calls this 'Back Right' */
+ SF_CHANNEL_MAP_LFE, /* Apple calls this 'LFEScreen', Msft calls this 'Low Frequency' */
+ SF_CHANNEL_MAP_FRONT_LEFT_OF_CENTER, /* Apple calls this 'Left Center' */
+ SF_CHANNEL_MAP_FRONT_RIGHT_OF_CENTER, /* Apple calls this 'Right Center */
+ SF_CHANNEL_MAP_SIDE_LEFT, /* Apple calls this 'Left Surround Direct' */
+ SF_CHANNEL_MAP_SIDE_RIGHT, /* Apple calls this 'Right Surround Direct' */
+ SF_CHANNEL_MAP_TOP_CENTER, /* Apple calls this 'Top Center Surround' */
+ SF_CHANNEL_MAP_TOP_FRONT_LEFT, /* Apple calls this 'Vertical Height Left' */
+ SF_CHANNEL_MAP_TOP_FRONT_RIGHT, /* Apple calls this 'Vertical Height Right' */
+ SF_CHANNEL_MAP_TOP_FRONT_CENTER, /* Apple calls this 'Vertical Height Center' */
+ SF_CHANNEL_MAP_TOP_REAR_LEFT, /* Apple and MS call this 'Top Back Left' */
+ SF_CHANNEL_MAP_TOP_REAR_RIGHT, /* Apple and MS call this 'Top Back Right' */
+ SF_CHANNEL_MAP_TOP_REAR_CENTER, /* Apple and MS call this 'Top Back Center' */
+
+ SF_CHANNEL_MAP_AMBISONIC_B_W,
+ SF_CHANNEL_MAP_AMBISONIC_B_X,
+ SF_CHANNEL_MAP_AMBISONIC_B_Y,
+ SF_CHANNEL_MAP_AMBISONIC_B_Z,
+
+ SF_CHANNEL_MAP_MAX
+} ;
+
+
+/* A SNDFILE* pointer can be passed around much like stdio.h's FILE* pointer. */
+
+typedef struct SNDFILE_tag SNDFILE ;
+
+/* The following typedef is system specific and is defined when libsndfile is
+** compiled. sf_count_t can be one of loff_t (Linux), off_t (*BSD), off64_t
+** (Solaris), __int64 (Win32) etc. On windows, we need to allow the same
+** header file to be compiler by both GCC and the microsoft compiler.
+*/
+
+#if (defined (_MSCVER) || defined (_MSC_VER))
+typedef __int64 sf_count_t ;
+#define SF_COUNT_MAX 0x7fffffffffffffffi64
+#else
+typedef loff_t sf_count_t ;
+#define SF_COUNT_MAX 0x7FFFFFFFFFFFFFFFLL
+#endif
+
+
+/* A pointer to a SF_INFO structure is passed to sf_open () and filled in.
+** On write, the SF_INFO structure is filled in by the user and passed into
+** sf_open ().
+*/
+
+struct SF_INFO
+{ sf_count_t frames ; /* Used to be called samples. Changed to avoid confusion. */
+ int samplerate ;
+ int channels ;
+ int format ;
+ int sections ;
+ int seekable ;
+} ;
+
+typedef struct SF_INFO SF_INFO ;
+
+/* The SF_FORMAT_INFO struct is used to retrieve information about the sound
+** file formats libsndfile supports using the sf_command () interface.
+**
+** Using this interface will allow applications to support new file formats
+** and encoding types when libsndfile is upgraded, without requiring
+** re-compilation of the application.
+**
+** Please consult the libsndfile documentation (particularly the information
+** on the sf_command () interface) for examples of its use.
+*/
+
+typedef struct
+{ int format ;
+ const char *name ;
+ const char *extension ;
+} SF_FORMAT_INFO ;
+
+/*
+** Enums and typedefs for adding dither on read and write.
+** See the html documentation for sf_command(), SFC_SET_DITHER_ON_WRITE
+** and SFC_SET_DITHER_ON_READ.
+*/
+
+enum
+{ SFD_DEFAULT_LEVEL = 0,
+ SFD_CUSTOM_LEVEL = 0x40000000,
+
+ SFD_NO_DITHER = 500,
+ SFD_WHITE = 501,
+ SFD_TRIANGULAR_PDF = 502
+} ;
+
+typedef struct
+{ int type ;
+ double level ;
+ const char *name ;
+} SF_DITHER_INFO ;
+
+/* Struct used to retrieve information about a file embedded within a
+** larger file. See SFC_GET_EMBED_FILE_INFO.
+*/
+
+typedef struct
+{ sf_count_t offset ;
+ sf_count_t length ;
+} SF_EMBED_FILE_INFO ;
+
+/*
+** Structs used to retrieve music sample information from a file.
+*/
+
+enum
+{ /*
+ ** The loop mode field in SF_INSTRUMENT will be one of the following.
+ */
+ SF_LOOP_NONE = 800,
+ SF_LOOP_FORWARD,
+ SF_LOOP_BACKWARD,
+ SF_LOOP_ALTERNATING
+} ;
+
+typedef struct
+{ int gain ;
+ char basenote, detune ;
+ char velocity_lo, velocity_hi ;
+ char key_lo, key_hi ;
+ int loop_count ;
+
+ struct
+ { int mode ;
+ unsigned int start ;
+ unsigned int end ;
+ unsigned int count ;
+ } loops [16] ; /* make variable in a sensible way */
+} SF_INSTRUMENT ;
+
+
+
+/* Struct used to retrieve loop information from a file.*/
+typedef struct
+{
+ short time_sig_num ; /* any positive integer > 0 */
+ short time_sig_den ; /* any positive power of 2 > 0 */
+ int loop_mode ; /* see SF_LOOP enum */
+
+ int num_beats ; /* this is NOT the amount of quarter notes !!!*/
+ /* a full bar of 4/4 is 4 beats */
+ /* a full bar of 7/8 is 7 beats */
+
+ float bpm ; /* suggestion, as it can be calculated using other fields:*/
+ /* file's lenght, file's sampleRate and our time_sig_den*/
+ /* -> bpms are always the amount of _quarter notes_ per minute */
+
+ int root_key ; /* MIDI note, or -1 for None */
+ int future [6] ;
+} SF_LOOP_INFO ;
+
+
+/* Struct used to retrieve broadcast (EBU) information from a file.
+** Strongly (!) based on EBU "bext" chunk format used in Broadcast WAVE.
+*/
+#define SF_BROADCAST_INFO_VAR(coding_hist_size) \
+ struct \
+ { char description [256] ; \
+ char originator [32] ; \
+ char originator_reference [32] ; \
+ char origination_date [10] ; \
+ char origination_time [8] ; \
+ unsigned int time_reference_low ; \
+ unsigned int time_reference_high ; \
+ short version ; \
+ char umid [64] ; \
+ char reserved [190] ; \
+ unsigned int coding_history_size ; \
+ char coding_history [coding_hist_size] ; \
+ }
+
+/* SF_BROADCAST_INFO is the above struct with coding_history field of 256 bytes. */
+typedef SF_BROADCAST_INFO_VAR (256) SF_BROADCAST_INFO ;
+
+
+/* Virtual I/O functionality. */
+
+typedef sf_count_t (*sf_vio_get_filelen) (void *user_data) ;
+typedef sf_count_t (*sf_vio_seek) (sf_count_t offset, int whence, void *user_data) ;
+typedef sf_count_t (*sf_vio_read) (void *ptr, sf_count_t count, void *user_data) ;
+typedef sf_count_t (*sf_vio_write) (const void *ptr, sf_count_t count, void *user_data) ;
+typedef sf_count_t (*sf_vio_tell) (void *user_data) ;
+
+struct SF_VIRTUAL_IO
+{ sf_vio_get_filelen get_filelen ;
+ sf_vio_seek seek ;
+ sf_vio_read read ;
+ sf_vio_write write ;
+ sf_vio_tell tell ;
+} ;
+
+typedef struct SF_VIRTUAL_IO SF_VIRTUAL_IO ;
+
+
+/* Open the specified file for read, write or both. On error, this will
+** return a NULL pointer. To find the error number, pass a NULL SNDFILE
+** to sf_strerror ().
+** All calls to sf_open() should be matched with a call to sf_close().
+*/
+
+SNDFILE* sf_open (const char *path, int mode, SF_INFO *sfinfo) ;
+
+
+/* Use the existing file descriptor to create a SNDFILE object. If close_desc
+** is TRUE, the file descriptor will be closed when sf_close() is called. If
+** it is FALSE, the descritor will not be closed.
+** When passed a descriptor like this, the library will assume that the start
+** of file header is at the current file offset. This allows sound files within
+** larger container files to be read and/or written.
+** On error, this will return a NULL pointer. To find the error number, pass a
+** NULL SNDFILE to sf_strerror ().
+** All calls to sf_open_fd() should be matched with a call to sf_close().
+
+*/
+
+SNDFILE* sf_open_fd (int fd, int mode, SF_INFO *sfinfo, int close_desc) ;
+
+SNDFILE* sf_open_virtual (SF_VIRTUAL_IO *sfvirtual, int mode, SF_INFO *sfinfo, void *user_data) ;
+
+
+/* sf_error () returns a error number which can be translated to a text
+** string using sf_error_number().
+*/
+
+int sf_error (SNDFILE *sndfile) ;
+
+
+/* sf_strerror () returns to the caller a pointer to the current error message for
+** the given SNDFILE.
+*/
+
+const char* sf_strerror (SNDFILE *sndfile) ;
+
+
+/* sf_error_number () allows the retrieval of the error string for each internal
+** error number.
+**
+*/
+
+const char* sf_error_number (int errnum) ;
+
+
+/* The following two error functions are deprecated but they will remain in the
+** library for the forseeable future. The function sf_strerror() should be used
+** in their place.
+*/
+
+int sf_perror (SNDFILE *sndfile) ;
+int sf_error_str (SNDFILE *sndfile, char* str, size_t len) ;
+
+
+/* Return TRUE if fields of the SF_INFO struct are a valid combination of values. */
+
+int sf_command (SNDFILE *sndfile, int command, void *data, int datasize) ;
+
+
+/* Return TRUE if fields of the SF_INFO struct are a valid combination of values. */
+
+int sf_format_check (const SF_INFO *info) ;
+
+
+/* Seek within the waveform data chunk of the SNDFILE. sf_seek () uses
+** the same values for whence (SEEK_SET, SEEK_CUR and SEEK_END) as
+** stdio.h function fseek ().
+** An offset of zero with whence set to SEEK_SET will position the
+** read / write pointer to the first data sample.
+** On success sf_seek returns the current position in (multi-channel)
+** samples from the start of the file.
+** Please see the libsndfile documentation for moving the read pointer
+** separately from the write pointer on files open in mode SFM_RDWR.
+** On error all of these functions return -1.
+*/
+
+sf_count_t sf_seek (SNDFILE *sndfile, sf_count_t frames, int whence) ;
+
+
+/* Functions for retrieving and setting string data within sound files.
+** Not all file types support this features; AIFF and WAV do. For both
+** functions, the str_type parameter must be one of the SF_STR_* values
+** defined above.
+** On error, sf_set_string() returns non-zero while sf_get_string()
+** returns NULL.
+*/
+
+int sf_set_string (SNDFILE *sndfile, int str_type, const char* str) ;
+
+const char* sf_get_string (SNDFILE *sndfile, int str_type) ;
+
+
+/* Return the library version string. */
+
+const char * sf_version_string (void) ;
+
+
+/* Functions for reading/writing the waveform data of a sound file.
+*/
+
+sf_count_t sf_read_raw (SNDFILE *sndfile, void *ptr, sf_count_t bytes) ;
+sf_count_t sf_write_raw (SNDFILE *sndfile, const void *ptr, sf_count_t bytes) ;
+
+
+/* Functions for reading and writing the data chunk in terms of frames.
+** The number of items actually read/written = frames * number of channels.
+** sf_xxxx_raw read/writes the raw data bytes from/to the file
+** sf_xxxx_short passes data in the native short format
+** sf_xxxx_int passes data in the native int format
+** sf_xxxx_float passes data in the native float format
+** sf_xxxx_double passes data in the native double format
+** All of these read/write function return number of frames read/written.
+*/
+
+sf_count_t sf_readf_short (SNDFILE *sndfile, short *ptr, sf_count_t frames) ;
+sf_count_t sf_writef_short (SNDFILE *sndfile, const short *ptr, sf_count_t frames) ;
+
+sf_count_t sf_readf_int (SNDFILE *sndfile, int *ptr, sf_count_t frames) ;
+sf_count_t sf_writef_int (SNDFILE *sndfile, const int *ptr, sf_count_t frames) ;
+
+sf_count_t sf_readf_float (SNDFILE *sndfile, float *ptr, sf_count_t frames) ;
+sf_count_t sf_writef_float (SNDFILE *sndfile, const float *ptr, sf_count_t frames) ;
+
+sf_count_t sf_readf_double (SNDFILE *sndfile, double *ptr, sf_count_t frames) ;
+sf_count_t sf_writef_double (SNDFILE *sndfile, const double *ptr, sf_count_t frames) ;
+
+
+/* Functions for reading and writing the data chunk in terms of items.
+** Otherwise similar to above.
+** All of these read/write function return number of items read/written.
+*/
+
+sf_count_t sf_read_short (SNDFILE *sndfile, short *ptr, sf_count_t items) ;
+sf_count_t sf_write_short (SNDFILE *sndfile, const short *ptr, sf_count_t items) ;
+
+sf_count_t sf_read_int (SNDFILE *sndfile, int *ptr, sf_count_t items) ;
+sf_count_t sf_write_int (SNDFILE *sndfile, const int *ptr, sf_count_t items) ;
+
+sf_count_t sf_read_float (SNDFILE *sndfile, float *ptr, sf_count_t items) ;
+sf_count_t sf_write_float (SNDFILE *sndfile, const float *ptr, sf_count_t items) ;
+
+sf_count_t sf_read_double (SNDFILE *sndfile, double *ptr, sf_count_t items) ;
+sf_count_t sf_write_double (SNDFILE *sndfile, const double *ptr, sf_count_t items) ;
+
+
+/* Close the SNDFILE and clean up all memory allocations associated with this
+** file.
+** Returns 0 on success, or an error number.
+*/
+
+int sf_close (SNDFILE *sndfile) ;
+
+
+/* If the file is opened SFM_WRITE or SFM_RDWR, call fsync() on the file
+** to force the writing of data to disk. If the file is opened SFM_READ
+** no action is taken.
+*/
+
+void sf_write_sync (SNDFILE *sndfile) ;
+
+
+
+/* The function sf_wchar_open() is Windows Only!
+** Open a file passing in a Windows Unicode filename. Otherwise, this is
+** the same as sf_open().
+**
+** In order for this to work, you need to do the following:
+**
+** #include <windows.h>
+** #define ENABLE_SNDFILE_WINDOWS_PROTOTYPES 1
+** #including <sndfile.h>
+*/
+
+#if ENABLE_SNDFILE_WINDOWS_PROTOTYPES
+SNDFILE* sf_wchar_open (LPCWSTR wpath, int mode, SF_INFO *sfinfo) ;
+#endif
+
+
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* __cplusplus */
+
+#endif /* SNDFILE_H */
+
diff --git a/lib-x86-32/include/vorbis/Makefile.am b/lib-x86-32/include/vorbis/Makefile.am
new file mode 100644
index 00000000..dbba34e5
--- /dev/null
+++ b/lib-x86-32/include/vorbis/Makefile.am
@@ -0,0 +1,7 @@
+## Process this file with automake to produce Makefile.in
+
+vorbisincludedir = $(includedir)/vorbis
+
+vorbisinclude_HEADERS = codec.h vorbisfile.h vorbisenc.h
+
+
diff --git a/lib-x86-32/include/vorbis/codec.h b/lib-x86-32/include/vorbis/codec.h
new file mode 100644
index 00000000..999aa335
--- /dev/null
+++ b/lib-x86-32/include/vorbis/codec.h
@@ -0,0 +1,243 @@
+/********************************************************************
+ * *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
+ * *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 *
+ * by the Xiph.Org Foundation http://www.xiph.org/ *
+
+ ********************************************************************
+
+ function: libvorbis codec headers
+ last mod: $Id: codec.h 17021 2010-03-24 09:29:41Z xiphmont $
+
+ ********************************************************************/
+
+#ifndef _vorbis_codec_h_
+#define _vorbis_codec_h_
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+#include <ogg/ogg.h>
+
+typedef struct vorbis_info{
+ int version;
+ int channels;
+ long rate;
+
+ /* The below bitrate declarations are *hints*.
+ Combinations of the three values carry the following implications:
+
+ all three set to the same value:
+ implies a fixed rate bitstream
+ only nominal set:
+ implies a VBR stream that averages the nominal bitrate. No hard
+ upper/lower limit
+ upper and or lower set:
+ implies a VBR bitstream that obeys the bitrate limits. nominal
+ may also be set to give a nominal rate.
+ none set:
+ the coder does not care to speculate.
+ */
+
+ long bitrate_upper;
+ long bitrate_nominal;
+ long bitrate_lower;
+ long bitrate_window;
+
+ void *codec_setup;
+} vorbis_info;
+
+/* vorbis_dsp_state buffers the current vorbis audio
+ analysis/synthesis state. The DSP state belongs to a specific
+ logical bitstream ****************************************************/
+typedef struct vorbis_dsp_state{
+ int analysisp;
+ vorbis_info *vi;
+
+ float **pcm;
+ float **pcmret;
+ int pcm_storage;
+ int pcm_current;
+ int pcm_returned;
+
+ int preextrapolate;
+ int eofflag;
+
+ long lW;
+ long W;
+ long nW;
+ long centerW;
+
+ ogg_int64_t granulepos;
+ ogg_int64_t sequence;
+
+ ogg_int64_t glue_bits;
+ ogg_int64_t time_bits;
+ ogg_int64_t floor_bits;
+ ogg_int64_t res_bits;
+
+ void *backend_state;
+} vorbis_dsp_state;
+
+typedef struct vorbis_block{
+ /* necessary stream state for linking to the framing abstraction */
+ float **pcm; /* this is a pointer into local storage */
+ oggpack_buffer opb;
+
+ long lW;
+ long W;
+ long nW;
+ int pcmend;
+ int mode;
+
+ int eofflag;
+ ogg_int64_t granulepos;
+ ogg_int64_t sequence;
+ vorbis_dsp_state *vd; /* For read-only access of configuration */
+
+ /* local storage to avoid remallocing; it's up to the mapping to
+ structure it */
+ void *localstore;
+ long localtop;
+ long localalloc;
+ long totaluse;
+ struct alloc_chain *reap;
+
+ /* bitmetrics for the frame */
+ long glue_bits;
+ long time_bits;
+ long floor_bits;
+ long res_bits;
+
+ void *internal;
+
+} vorbis_block;
+
+/* vorbis_block is a single block of data to be processed as part of
+the analysis/synthesis stream; it belongs to a specific logical
+bitstream, but is independent from other vorbis_blocks belonging to
+that logical bitstream. *************************************************/
+
+struct alloc_chain{
+ void *ptr;
+ struct alloc_chain *next;
+};
+
+/* vorbis_info contains all the setup information specific to the
+ specific compression/decompression mode in progress (eg,
+ psychoacoustic settings, channel setup, options, codebook
+ etc). vorbis_info and substructures are in backends.h.
+*********************************************************************/
+
+/* the comments are not part of vorbis_info so that vorbis_info can be
+ static storage */
+typedef struct vorbis_comment{
+ /* unlimited user comment fields. libvorbis writes 'libvorbis'
+ whatever vendor is set to in encode */
+ char **user_comments;
+ int *comment_lengths;
+ int comments;
+ char *vendor;
+
+} vorbis_comment;
+
+
+/* libvorbis encodes in two abstraction layers; first we perform DSP
+ and produce a packet (see docs/analysis.txt). The packet is then
+ coded into a framed OggSquish bitstream by the second layer (see
+ docs/framing.txt). Decode is the reverse process; we sync/frame
+ the bitstream and extract individual packets, then decode the
+ packet back into PCM audio.
+
+ The extra framing/packetizing is used in streaming formats, such as
+ files. Over the net (such as with UDP), the framing and
+ packetization aren't necessary as they're provided by the transport
+ and the streaming layer is not used */
+
+/* Vorbis PRIMITIVES: general ***************************************/
+
+extern void vorbis_info_init(vorbis_info *vi);
+extern void vorbis_info_clear(vorbis_info *vi);
+extern int vorbis_info_blocksize(vorbis_info *vi,int zo);
+extern void vorbis_comment_init(vorbis_comment *vc);
+extern void vorbis_comment_add(vorbis_comment *vc, const char *comment);
+extern void vorbis_comment_add_tag(vorbis_comment *vc,
+ const char *tag, const char *contents);
+extern char *vorbis_comment_query(vorbis_comment *vc, const char *tag, int count);
+extern int vorbis_comment_query_count(vorbis_comment *vc, const char *tag);
+extern void vorbis_comment_clear(vorbis_comment *vc);
+
+extern int vorbis_block_init(vorbis_dsp_state *v, vorbis_block *vb);
+extern int vorbis_block_clear(vorbis_block *vb);
+extern void vorbis_dsp_clear(vorbis_dsp_state *v);
+extern double vorbis_granule_time(vorbis_dsp_state *v,
+ ogg_int64_t granulepos);
+
+extern const char *vorbis_version_string(void);
+
+/* Vorbis PRIMITIVES: analysis/DSP layer ****************************/
+
+extern int vorbis_analysis_init(vorbis_dsp_state *v,vorbis_info *vi);
+extern int vorbis_commentheader_out(vorbis_comment *vc, ogg_packet *op);
+extern int vorbis_analysis_headerout(vorbis_dsp_state *v,
+ vorbis_comment *vc,
+ ogg_packet *op,
+ ogg_packet *op_comm,
+ ogg_packet *op_code);
+extern float **vorbis_analysis_buffer(vorbis_dsp_state *v,int vals);
+extern int vorbis_analysis_wrote(vorbis_dsp_state *v,int vals);
+extern int vorbis_analysis_blockout(vorbis_dsp_state *v,vorbis_block *vb);
+extern int vorbis_analysis(vorbis_block *vb,ogg_packet *op);
+
+extern int vorbis_bitrate_addblock(vorbis_block *vb);
+extern int vorbis_bitrate_flushpacket(vorbis_dsp_state *vd,
+ ogg_packet *op);
+
+/* Vorbis PRIMITIVES: synthesis layer *******************************/
+extern int vorbis_synthesis_idheader(ogg_packet *op);
+extern int vorbis_synthesis_headerin(vorbis_info *vi,vorbis_comment *vc,
+ ogg_packet *op);
+
+extern int vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi);
+extern int vorbis_synthesis_restart(vorbis_dsp_state *v);
+extern int vorbis_synthesis(vorbis_block *vb,ogg_packet *op);
+extern int vorbis_synthesis_trackonly(vorbis_block *vb,ogg_packet *op);
+extern int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb);
+extern int vorbis_synthesis_pcmout(vorbis_dsp_state *v,float ***pcm);
+extern int vorbis_synthesis_lapout(vorbis_dsp_state *v,float ***pcm);
+extern int vorbis_synthesis_read(vorbis_dsp_state *v,int samples);
+extern long vorbis_packet_blocksize(vorbis_info *vi,ogg_packet *op);
+
+extern int vorbis_synthesis_halfrate(vorbis_info *v,int flag);
+extern int vorbis_synthesis_halfrate_p(vorbis_info *v);
+
+/* Vorbis ERRORS and return codes ***********************************/
+
+#define OV_FALSE -1
+#define OV_EOF -2
+#define OV_HOLE -3
+
+#define OV_EREAD -128
+#define OV_EFAULT -129
+#define OV_EIMPL -130
+#define OV_EINVAL -131
+#define OV_ENOTVORBIS -132
+#define OV_EBADHEADER -133
+#define OV_EVERSION -134
+#define OV_ENOTAUDIO -135
+#define OV_EBADPACKET -136
+#define OV_EBADLINK -137
+#define OV_ENOSEEK -138
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
+
diff --git a/lib-x86-32/include/vorbis/vorbisenc.h b/lib-x86-32/include/vorbis/vorbisenc.h
new file mode 100644
index 00000000..02332b50
--- /dev/null
+++ b/lib-x86-32/include/vorbis/vorbisenc.h
@@ -0,0 +1,436 @@
+/********************************************************************
+ * *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
+ * *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 *
+ * by the Xiph.Org Foundation http://www.xiph.org/ *
+ * *
+ ********************************************************************
+
+ function: vorbis encode-engine setup
+ last mod: $Id: vorbisenc.h 17021 2010-03-24 09:29:41Z xiphmont $
+
+ ********************************************************************/
+
+/** \file
+ * Libvorbisenc is a convenient API for setting up an encoding
+ * environment using libvorbis. Libvorbisenc encapsulates the
+ * actions needed to set up the encoder properly.
+ */
+
+#ifndef _OV_ENC_H_
+#define _OV_ENC_H_
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+#include "codec.h"
+
+/**
+ * This is the primary function within libvorbisenc for setting up managed
+ * bitrate modes.
+ *
+ * Before this function is called, the \ref vorbis_info
+ * struct should be initialized by using vorbis_info_init() from the libvorbis
+ * API. After encoding, vorbis_info_clear() should be called.
+ *
+ * The max_bitrate, nominal_bitrate, and min_bitrate settings are used to set
+ * constraints for the encoded file. This function uses these settings to
+ * select the appropriate encoding mode and set it up.
+ *
+ * \param vi Pointer to an initialized \ref vorbis_info struct.
+ * \param channels The number of channels to be encoded.
+ * \param rate The sampling rate of the source audio.
+ * \param max_bitrate Desired maximum bitrate (limit). -1 indicates unset.
+ * \param nominal_bitrate Desired average, or central, bitrate. -1 indicates unset.
+ * \param min_bitrate Desired minimum bitrate. -1 indicates unset.
+ *
+ * \return Zero for success, and negative values for failure.
+ *
+ * \retval 0 Success.
+ * \retval OV_EFAULT Internal logic fault; indicates a bug or heap/stack corruption.
+ * \retval OV_EINVAL Invalid setup request, eg, out of range argument.
+ * \retval OV_EIMPL Unimplemented mode; unable to comply with bitrate request.
+ */
+extern int vorbis_encode_init(vorbis_info *vi,
+ long channels,
+ long rate,
+
+ long max_bitrate,
+ long nominal_bitrate,
+ long min_bitrate);
+
+/**
+ * This function performs step-one of a three-step bitrate-managed encode
+ * setup. It functions similarly to the one-step setup performed by \ref
+ * vorbis_encode_init but allows an application to make further encode setup
+ * tweaks using \ref vorbis_encode_ctl before finally calling \ref
+ * vorbis_encode_setup_init to complete the setup process.
+ *
+ * Before this function is called, the \ref vorbis_info struct should be
+ * initialized by using vorbis_info_init() from the libvorbis API. After
+ * encoding, vorbis_info_clear() should be called.
+ *
+ * The max_bitrate, nominal_bitrate, and min_bitrate settings are used to set
+ * constraints for the encoded file. This function uses these settings to
+ * select the appropriate encoding mode and set it up.
+ *
+ * \param vi Pointer to an initialized vorbis_info struct.
+ * \param channels The number of channels to be encoded.
+ * \param rate The sampling rate of the source audio.
+ * \param max_bitrate Desired maximum bitrate (limit). -1 indicates unset.
+ * \param nominal_bitrate Desired average, or central, bitrate. -1 indicates unset.
+ * \param min_bitrate Desired minimum bitrate. -1 indicates unset.
+ *
+ * \return Zero for success, and negative for failure.
+ *
+ * \retval 0 Success
+ * \retval OV_EFAULT Internal logic fault; indicates a bug or heap/stack corruption.
+ * \retval OV_EINVAL Invalid setup request, eg, out of range argument.
+ * \retval OV_EIMPL Unimplemented mode; unable to comply with bitrate request.
+ */
+extern int vorbis_encode_setup_managed(vorbis_info *vi,
+ long channels,
+ long rate,
+
+ long max_bitrate,
+ long nominal_bitrate,
+ long min_bitrate);
+
+/**
+ * This function performs step-one of a three-step variable bitrate
+ * (quality-based) encode setup. It functions similarly to the one-step setup
+ * performed by \ref vorbis_encode_init_vbr() but allows an application to
+ * make further encode setup tweaks using \ref vorbis_encode_ctl() before
+ * finally calling \ref vorbis_encode_setup_init to complete the setup
+ * process.
+ *
+ * Before this function is called, the \ref vorbis_info struct should be
+ * initialized by using \ref vorbis_info_init() from the libvorbis API. After
+ * encoding, vorbis_info_clear() should be called.
+ *
+ * \param vi Pointer to an initialized vorbis_info struct.
+ * \param channels The number of channels to be encoded.
+ * \param rate The sampling rate of the source audio.
+ * \param quality Desired quality level, currently from -0.1 to 1.0 (lo to hi).
+ *
+ * \return Zero for success, and negative values for failure.
+ *
+ * \retval 0 Success
+ * \retval OV_EFAULT Internal logic fault; indicates a bug or heap/stack corruption.
+ * \retval OV_EINVAL Invalid setup request, eg, out of range argument.
+ * \retval OV_EIMPL Unimplemented mode; unable to comply with quality level request.
+ */
+extern int vorbis_encode_setup_vbr(vorbis_info *vi,
+ long channels,
+ long rate,
+
+ float quality
+ );
+
+/**
+ * This is the primary function within libvorbisenc for setting up variable
+ * bitrate ("quality" based) modes.
+ *
+ *
+ * Before this function is called, the vorbis_info struct should be
+ * initialized by using vorbis_info_init() from the libvorbis API. After
+ * encoding, vorbis_info_clear() should be called.
+ *
+ * \param vi Pointer to an initialized vorbis_info struct.
+ * \param channels The number of channels to be encoded.
+ * \param rate The sampling rate of the source audio.
+ * \param base_quality Desired quality level, currently from -0.1 to 1.0 (lo to hi).
+ *
+ *
+ * \return Zero for success, or a negative number for failure.
+ *
+ * \retval 0 Success
+ * \retval OV_EFAULT Internal logic fault; indicates a bug or heap/stack corruption.
+ * \retval OV_EINVAL Invalid setup request, eg, out of range argument.
+ * \retval OV_EIMPL Unimplemented mode; unable to comply with quality level request.
+ */
+extern int vorbis_encode_init_vbr(vorbis_info *vi,
+ long channels,
+ long rate,
+
+ float base_quality
+ );
+
+/**
+ * This function performs the last stage of three-step encoding setup, as
+ * described in the API overview under managed bitrate modes.
+ *
+ * Before this function is called, the \ref vorbis_info struct should be
+ * initialized by using vorbis_info_init() from the libvorbis API, one of
+ * \ref vorbis_encode_setup_managed() or \ref vorbis_encode_setup_vbr() called to
+ * initialize the high-level encoding setup, and \ref vorbis_encode_ctl()
+ * called if necessary to make encoding setup changes.
+ * vorbis_encode_setup_init() finalizes the highlevel encoding structure into
+ * a complete encoding setup after which the application may make no further
+ * setup changes.
+ *
+ * After encoding, vorbis_info_clear() should be called.
+ *
+ * \param vi Pointer to an initialized \ref vorbis_info struct.
+ *
+ * \return Zero for success, and negative values for failure.
+ *
+ * \retval 0 Success.
+ * \retval OV_EFAULT Internal logic fault; indicates a bug or heap/stack corruption.
+ *
+ * \retval OV_EINVAL Attempt to use vorbis_encode_setup_init() without first
+ * calling one of vorbis_encode_setup_managed() or vorbis_encode_setup_vbr() to
+ * initialize the high-level encoding setup
+ *
+ */
+extern int vorbis_encode_setup_init(vorbis_info *vi);
+
+/**
+ * This function implements a generic interface to miscellaneous encoder
+ * settings similar to the classic UNIX 'ioctl()' system call. Applications
+ * may use vorbis_encode_ctl() to query or set bitrate management or quality
+ * mode details by using one of several \e request arguments detailed below.
+ * vorbis_encode_ctl() must be called after one of
+ * vorbis_encode_setup_managed() or vorbis_encode_setup_vbr(). When used
+ * to modify settings, \ref vorbis_encode_ctl() must be called before \ref
+ * vorbis_encode_setup_init().
+ *
+ * \param vi Pointer to an initialized vorbis_info struct.
+ *
+ * \param number Specifies the desired action; See \ref encctlcodes "the list
+ * of available requests".
+ *
+ * \param arg void * pointing to a data structure matching the request
+ * argument.
+ *
+ * \retval 0 Success. Any further return information (such as the result of a
+ * query) is placed into the storage pointed to by *arg.
+ *
+ * \retval OV_EINVAL Invalid argument, or an attempt to modify a setting after
+ * calling vorbis_encode_setup_init().
+ *
+ * \retval OV_EIMPL Unimplemented or unknown request
+ */
+extern int vorbis_encode_ctl(vorbis_info *vi,int number,void *arg);
+
+/**
+ * \deprecated This is a deprecated interface. Please use vorbis_encode_ctl()
+ * with the \ref ovectl_ratemanage2_arg struct and \ref
+ * OV_ECTL_RATEMANAGE2_GET and \ref OV_ECTL_RATEMANAGE2_SET calls in new code.
+ *
+ * The \ref ovectl_ratemanage_arg structure is used with vorbis_encode_ctl()
+ * and the \ref OV_ECTL_RATEMANAGE_GET, \ref OV_ECTL_RATEMANAGE_SET, \ref
+ * OV_ECTL_RATEMANAGE_AVG, \ref OV_ECTL_RATEMANAGE_HARD calls in order to
+ * query and modify specifics of the encoder's bitrate management
+ * configuration.
+*/
+struct ovectl_ratemanage_arg {
+ int management_active; /**< nonzero if bitrate management is active*/
+/** hard lower limit (in kilobits per second) below which the stream bitrate
+ will never be allowed for any given bitrate_hard_window seconds of time.*/
+ long bitrate_hard_min;
+/** hard upper limit (in kilobits per second) above which the stream bitrate
+ will never be allowed for any given bitrate_hard_window seconds of time.*/
+ long bitrate_hard_max;
+/** the window period (in seconds) used to regulate the hard bitrate minimum
+ and maximum*/
+ double bitrate_hard_window;
+/** soft lower limit (in kilobits per second) below which the average bitrate
+ tracker will start nudging the bitrate higher.*/
+ long bitrate_av_lo;
+/** soft upper limit (in kilobits per second) above which the average bitrate
+ tracker will start nudging the bitrate lower.*/
+ long bitrate_av_hi;
+/** the window period (in seconds) used to regulate the average bitrate
+ minimum and maximum.*/
+ double bitrate_av_window;
+/** Regulates the relative centering of the average and hard windows; in
+ libvorbis 1.0 and 1.0.1, the hard window regulation overlapped but
+ followed the average window regulation. In libvorbis 1.1 a bit-reservoir
+ interface replaces the old windowing interface; the older windowing
+ interface is simulated and this field has no effect.*/
+ double bitrate_av_window_center;
+};
+
+/**
+ * \name struct ovectl_ratemanage2_arg
+ *
+ * The ovectl_ratemanage2_arg structure is used with vorbis_encode_ctl() and
+ * the OV_ECTL_RATEMANAGE2_GET and OV_ECTL_RATEMANAGE2_SET calls in order to
+ * query and modify specifics of the encoder's bitrate management
+ * configuration.
+ *
+*/
+struct ovectl_ratemanage2_arg {
+ int management_active; /**< nonzero if bitrate management is active */
+/** Lower allowed bitrate limit in kilobits per second */
+ long bitrate_limit_min_kbps;
+/** Upper allowed bitrate limit in kilobits per second */
+ long bitrate_limit_max_kbps;
+ long bitrate_limit_reservoir_bits; /**<Size of the bitrate reservoir in bits */
+/** Regulates the bitrate reservoir's preferred fill level in a range from 0.0
+ * to 1.0; 0.0 tries to bank bits to buffer against future bitrate spikes, 1.0
+ * buffers against future sudden drops in instantaneous bitrate. Default is
+ * 0.1
+ */
+ double bitrate_limit_reservoir_bias;
+/** Average bitrate setting in kilobits per second */
+ long bitrate_average_kbps;
+/** Slew rate limit setting for average bitrate adjustment; sets the minimum
+ * time in seconds the bitrate tracker may swing from one extreme to the
+ * other when boosting or damping average bitrate.
+ */
+ double bitrate_average_damping;
+};
+
+
+/**
+ * \name vorbis_encode_ctl() codes
+ *
+ * \anchor encctlcodes
+ *
+ * These values are passed as the \c number parameter of vorbis_encode_ctl().
+ * The type of the referent of that function's \c arg pointer depends on these
+ * codes.
+ */
+/*@{*/
+
+/**
+ * Query the current encoder bitrate management setting.
+ *
+ *Argument: <tt>struct ovectl_ratemanage2_arg *</tt>
+ *
+ * Used to query the current encoder bitrate management setting. Also used to
+ * initialize fields of an ovectl_ratemanage2_arg structure for use with
+ * \ref OV_ECTL_RATEMANAGE2_SET.
+ */
+#define OV_ECTL_RATEMANAGE2_GET 0x14
+
+/**
+ * Set the current encoder bitrate management settings.
+ *
+ * Argument: <tt>struct ovectl_ratemanage2_arg *</tt>
+ *
+ * Used to set the current encoder bitrate management settings to the values
+ * listed in the ovectl_ratemanage2_arg. Passing a NULL pointer will disable
+ * bitrate management.
+*/
+#define OV_ECTL_RATEMANAGE2_SET 0x15
+
+/**
+ * Returns the current encoder hard-lowpass setting (kHz) in the double
+ * pointed to by arg.
+ *
+ * Argument: <tt>double *</tt>
+*/
+#define OV_ECTL_LOWPASS_GET 0x20
+
+/**
+ * Sets the encoder hard-lowpass to the value (kHz) pointed to by arg. Valid
+ * lowpass settings range from 2 to 99.
+ *
+ * Argument: <tt>double *</tt>
+*/
+#define OV_ECTL_LOWPASS_SET 0x21
+
+/**
+ * Returns the current encoder impulse block setting in the double pointed
+ * to by arg.
+ *
+ * Argument: <tt>double *</tt>
+*/
+#define OV_ECTL_IBLOCK_GET 0x30
+
+/**
+ * Sets the impulse block bias to the the value pointed to by arg.
+ *
+ * Argument: <tt>double *</tt>
+ *
+ * Valid range is -15.0 to 0.0 [default]. A negative impulse block bias will
+ * direct to encoder to use more bits when incoding short blocks that contain
+ * strong impulses, thus improving the accuracy of impulse encoding.
+ */
+#define OV_ECTL_IBLOCK_SET 0x31
+
+/**
+ * Returns the current encoder coupling setting in the int pointed
+ * to by arg.
+ *
+ * Argument: <tt>int *</tt>
+*/
+#define OV_ECTL_COUPLING_GET 0x40
+
+/**
+ * Enables/disables channel coupling in multichannel encoding according to arg.
+ *
+ * Argument: <tt>int *</tt>
+ *
+ * Zero disables channel coupling for multichannel inputs, nonzer enables
+ * channel coupling. Setting has no effect on monophonic encoding or
+ * multichannel counts that do not offer coupling. At present, coupling is
+ * available for stereo and 5.1 encoding.
+ */
+#define OV_ECTL_COUPLING_SET 0x41
+
+ /* deprecated rate management supported only for compatibility */
+
+/**
+ * Old interface to querying bitrate management settings.
+ *
+ * Deprecated after move to bit-reservoir style management in 1.1 rendered
+ * this interface partially obsolete.
+
+ * \deprecated Please use \ref OV_ECTL_RATEMANAGE2_GET instead.
+ *
+ * Argument: <tt>struct ovectl_ratemanage_arg *</tt>
+ */
+#define OV_ECTL_RATEMANAGE_GET 0x10
+/**
+ * Old interface to modifying bitrate management settings.
+ *
+ * deprecated after move to bit-reservoir style management in 1.1 rendered
+ * this interface partially obsolete.
+ *
+ * \deprecated Please use \ref OV_ECTL_RATEMANAGE2_SET instead.
+ *
+ * Argument: <tt>struct ovectl_ratemanage_arg *</tt>
+ */
+#define OV_ECTL_RATEMANAGE_SET 0x11
+/**
+ * Old interface to setting average-bitrate encoding mode.
+ *
+ * Deprecated after move to bit-reservoir style management in 1.1 rendered
+ * this interface partially obsolete.
+ *
+ * \deprecated Please use \ref OV_ECTL_RATEMANAGE2_SET instead.
+ *
+ * Argument: <tt>struct ovectl_ratemanage_arg *</tt>
+ */
+#define OV_ECTL_RATEMANAGE_AVG 0x12
+/**
+ * Old interface to setting bounded-bitrate encoding modes.
+ *
+ * deprecated after move to bit-reservoir style management in 1.1 rendered
+ * this interface partially obsolete.
+ *
+ * \deprecated Please use \ref OV_ECTL_RATEMANAGE2_SET instead.
+ *
+ * Argument: <tt>struct ovectl_ratemanage_arg *</tt>
+ */
+#define OV_ECTL_RATEMANAGE_HARD 0x13
+
+/*@}*/
+
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/lib-x86-32/include/vorbis/vorbisfile.h b/lib-x86-32/include/vorbis/vorbisfile.h
new file mode 100644
index 00000000..a865cd09
--- /dev/null
+++ b/lib-x86-32/include/vorbis/vorbisfile.h
@@ -0,0 +1,206 @@
+/********************************************************************
+ * *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
+ * *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007 *
+ * by the Xiph.Org Foundation http://www.xiph.org/ *
+ * *
+ ********************************************************************
+
+ function: stdio-based convenience library for opening/seeking/decoding
+ last mod: $Id: vorbisfile.h 17021 2010-03-24 09:29:41Z xiphmont $
+
+ ********************************************************************/
+
+#ifndef _OV_FILE_H_
+#define _OV_FILE_H_
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+#include <stdio.h>
+#include "codec.h"
+
+/* The function prototypes for the callbacks are basically the same as for
+ * the stdio functions fread, fseek, fclose, ftell.
+ * The one difference is that the FILE * arguments have been replaced with
+ * a void * - this is to be used as a pointer to whatever internal data these
+ * functions might need. In the stdio case, it's just a FILE * cast to a void *
+ *
+ * If you use other functions, check the docs for these functions and return
+ * the right values. For seek_func(), you *MUST* return -1 if the stream is
+ * unseekable
+ */
+typedef struct {
+ size_t (*read_func) (void *ptr, size_t size, size_t nmemb, void *datasource);
+ int (*seek_func) (void *datasource, ogg_int64_t offset, int whence);
+ int (*close_func) (void *datasource);
+ long (*tell_func) (void *datasource);
+} ov_callbacks;
+
+#ifndef OV_EXCLUDE_STATIC_CALLBACKS
+
+/* a few sets of convenient callbacks, especially for use under
+ * Windows where ov_open_callbacks() should always be used instead of
+ * ov_open() to avoid problems with incompatible crt.o version linking
+ * issues. */
+
+static int _ov_header_fseek_wrap(FILE *f,ogg_int64_t off,int whence){
+ if(f==NULL)return(-1);
+
+#ifdef __MINGW32__
+ return fseeko64(f,off,whence);
+#elif defined (_WIN32)
+ return _fseeki64(f,off,whence);
+#else
+ return fseek(f,off,whence);
+#endif
+}
+
+/* These structs below (OV_CALLBACKS_DEFAULT etc) are defined here as
+ * static data. That means that every file which includes this header
+ * will get its own copy of these structs whether it uses them or
+ * not unless it #defines OV_EXCLUDE_STATIC_CALLBACKS.
+ * These static symbols are essential on platforms such as Windows on
+ * which several different versions of stdio support may be linked to
+ * by different DLLs, and we need to be certain we know which one
+ * we're using (the same one as the main application).
+ */
+
+static ov_callbacks OV_CALLBACKS_DEFAULT = {
+ (size_t (*)(void *, size_t, size_t, void *)) fread,
+ (int (*)(void *, ogg_int64_t, int)) _ov_header_fseek_wrap,
+ (int (*)(void *)) fclose,
+ (long (*)(void *)) ftell
+};
+
+static ov_callbacks OV_CALLBACKS_NOCLOSE = {
+ (size_t (*)(void *, size_t, size_t, void *)) fread,
+ (int (*)(void *, ogg_int64_t, int)) _ov_header_fseek_wrap,
+ (int (*)(void *)) NULL,
+ (long (*)(void *)) ftell
+};
+
+static ov_callbacks OV_CALLBACKS_STREAMONLY = {
+ (size_t (*)(void *, size_t, size_t, void *)) fread,
+ (int (*)(void *, ogg_int64_t, int)) NULL,
+ (int (*)(void *)) fclose,
+ (long (*)(void *)) NULL
+};
+
+static ov_callbacks OV_CALLBACKS_STREAMONLY_NOCLOSE = {
+ (size_t (*)(void *, size_t, size_t, void *)) fread,
+ (int (*)(void *, ogg_int64_t, int)) NULL,
+ (int (*)(void *)) NULL,
+ (long (*)(void *)) NULL
+};
+
+#endif
+
+#define NOTOPEN 0
+#define PARTOPEN 1
+#define OPENED 2
+#define STREAMSET 3
+#define INITSET 4
+
+typedef struct OggVorbis_File {
+ void *datasource; /* Pointer to a FILE *, etc. */
+ int seekable;
+ ogg_int64_t offset;
+ ogg_int64_t end;
+ ogg_sync_state oy;
+
+ /* If the FILE handle isn't seekable (eg, a pipe), only the current
+ stream appears */
+ int links;
+ ogg_int64_t *offsets;
+ ogg_int64_t *dataoffsets;
+ long *serialnos;
+ ogg_int64_t *pcmlengths; /* overloaded to maintain binary
+ compatibility; x2 size, stores both
+ beginning and end values */
+ vorbis_info *vi;
+ vorbis_comment *vc;
+
+ /* Decoding working state local storage */
+ ogg_int64_t pcm_offset;
+ int ready_state;
+ long current_serialno;
+ int current_link;
+
+ double bittrack;
+ double samptrack;
+
+ ogg_stream_state os; /* take physical pages, weld into a logical
+ stream of packets */
+ vorbis_dsp_state vd; /* central working state for the packet->PCM decoder */
+ vorbis_block vb; /* local working space for packet->PCM decode */
+
+ ov_callbacks callbacks;
+
+} OggVorbis_File;
+
+
+extern int ov_clear(OggVorbis_File *vf);
+extern int ov_fopen(char *path,OggVorbis_File *vf);
+extern int ov_open(FILE *f,OggVorbis_File *vf,char *initial,long ibytes);
+extern int ov_open_callbacks(void *datasource, OggVorbis_File *vf,
+ char *initial, long ibytes, ov_callbacks callbacks);
+
+extern int ov_test(FILE *f,OggVorbis_File *vf,char *initial,long ibytes);
+extern int ov_test_callbacks(void *datasource, OggVorbis_File *vf,
+ char *initial, long ibytes, ov_callbacks callbacks);
+extern int ov_test_open(OggVorbis_File *vf);
+
+extern long ov_bitrate(OggVorbis_File *vf,int i);
+extern long ov_bitrate_instant(OggVorbis_File *vf);
+extern long ov_streams(OggVorbis_File *vf);
+extern long ov_seekable(OggVorbis_File *vf);
+extern long ov_serialnumber(OggVorbis_File *vf,int i);
+
+extern ogg_int64_t ov_raw_total(OggVorbis_File *vf,int i);
+extern ogg_int64_t ov_pcm_total(OggVorbis_File *vf,int i);
+extern double ov_time_total(OggVorbis_File *vf,int i);
+
+extern int ov_raw_seek(OggVorbis_File *vf,ogg_int64_t pos);
+extern int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos);
+extern int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos);
+extern int ov_time_seek(OggVorbis_File *vf,double pos);
+extern int ov_time_seek_page(OggVorbis_File *vf,double pos);
+
+extern int ov_raw_seek_lap(OggVorbis_File *vf,ogg_int64_t pos);
+extern int ov_pcm_seek_lap(OggVorbis_File *vf,ogg_int64_t pos);
+extern int ov_pcm_seek_page_lap(OggVorbis_File *vf,ogg_int64_t pos);
+extern int ov_time_seek_lap(OggVorbis_File *vf,double pos);
+extern int ov_time_seek_page_lap(OggVorbis_File *vf,double pos);
+
+extern ogg_int64_t ov_raw_tell(OggVorbis_File *vf);
+extern ogg_int64_t ov_pcm_tell(OggVorbis_File *vf);
+extern double ov_time_tell(OggVorbis_File *vf);
+
+extern vorbis_info *ov_info(OggVorbis_File *vf,int link);
+extern vorbis_comment *ov_comment(OggVorbis_File *vf,int link);
+
+extern long ov_read_float(OggVorbis_File *vf,float ***pcm_channels,int samples,
+ int *bitstream);
+extern long ov_read_filter(OggVorbis_File *vf,char *buffer,int length,
+ int bigendianp,int word,int sgned,int *bitstream,
+ void (*filter)(float **pcm,long channels,long samples,void *filter_param),void *filter_param);
+extern long ov_read(OggVorbis_File *vf,char *buffer,int length,
+ int bigendianp,int word,int sgned,int *bitstream);
+extern int ov_crosslap(OggVorbis_File *vf1,OggVorbis_File *vf2);
+
+extern int ov_halfrate(OggVorbis_File *vf,int flag);
+extern int ov_halfrate_p(OggVorbis_File *vf);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
+
diff --git a/lib-x86-32/include/wavpack.h b/lib-x86-32/include/wavpack.h
new file mode 100644
index 00000000..fe66dcbc
--- /dev/null
+++ b/lib-x86-32/include/wavpack.h
@@ -0,0 +1,302 @@
+////////////////////////////////////////////////////////////////////////////
+// **** WAVPACK **** //
+// Hybrid Lossless Wavefile Compressor //
+// Copyright (c) 1998 - 2006 Conifer Software. //
+// All Rights Reserved. //
+// Distributed under the BSD Software License (see license.txt) //
+////////////////////////////////////////////////////////////////////////////
+
+// wavpack.h
+
+#ifndef WAVPACK_H
+#define WAVPACK_H
+
+// This header file contains all the definitions required to use the
+// functions in "wputils.c" to read and write WavPack files and streams.
+
+#include <sys/types.h>
+
+#if defined(_WIN32) && !defined(__MINGW32__)
+#include <stdlib.h>
+typedef unsigned __int64 uint64_t;
+typedef unsigned __int32 uint32_t;
+typedef unsigned __int16 uint16_t;
+typedef unsigned __int8 uint8_t;
+typedef __int64 int64_t;
+typedef __int32 int32_t;
+typedef __int16 int16_t;
+typedef __int8 int8_t;
+typedef float float32_t;
+#else
+#include <inttypes.h>
+#endif
+
+// RIFF / wav header formats (these occur at the beginning of both wav files
+// and pre-4.0 WavPack files that are not in the "raw" mode). Generally, an
+// application using the library to read or write WavPack files will not be
+// concerned with any of these.
+
+typedef struct {
+ char ckID [4];
+ uint32_t ckSize;
+ char formType [4];
+} RiffChunkHeader;
+
+typedef struct {
+ char ckID [4];
+ uint32_t ckSize;
+} ChunkHeader;
+
+#define ChunkHeaderFormat "4L"
+
+typedef struct {
+ unsigned short FormatTag, NumChannels;
+ uint32_t SampleRate, BytesPerSecond;
+ unsigned short BlockAlign, BitsPerSample;
+ unsigned short cbSize, ValidBitsPerSample;
+ int32_t ChannelMask;
+ unsigned short SubFormat;
+ char GUID [14];
+} WaveHeader;
+
+#define WaveHeaderFormat "SSLLSSSSLS"
+
+// This is the ONLY structure that occurs in WavPack files (as of version
+// 4.0), and is the preamble to every block in both the .wv and .wvc
+// files (in little-endian format). Normally, this structure has no use
+// to an application using the library to read or write WavPack files,
+// but if an application needs to manually parse WavPack files then this
+// would be used (with appropriate endian correction).
+
+typedef struct {
+ char ckID [4];
+ uint32_t ckSize;
+ short version;
+ unsigned char track_no, index_no;
+ uint32_t total_samples, block_index, block_samples, flags, crc;
+} WavpackHeader;
+
+#define WavpackHeaderFormat "4LS2LLLLL"
+
+// or-values for WavpackHeader.flags
+#define BYTES_STORED 3 // 1-4 bytes/sample
+#define MONO_FLAG 4 // not stereo
+#define HYBRID_FLAG 8 // hybrid mode
+#define JOINT_STEREO 0x10 // joint stereo
+#define CROSS_DECORR 0x20 // no-delay cross decorrelation
+#define HYBRID_SHAPE 0x40 // noise shape (hybrid mode only)
+#define FLOAT_DATA 0x80 // ieee 32-bit floating point data
+
+#define INT32_DATA 0x100 // special extended int handling
+#define HYBRID_BITRATE 0x200 // bitrate noise (hybrid mode only)
+#define HYBRID_BALANCE 0x400 // balance noise (hybrid stereo mode only)
+
+#define INITIAL_BLOCK 0x800 // initial block of multichannel segment
+#define FINAL_BLOCK 0x1000 // final block of multichannel segment
+
+#define SHIFT_LSB 13
+#define SHIFT_MASK (0x1fL << SHIFT_LSB)
+
+#define MAG_LSB 18
+#define MAG_MASK (0x1fL << MAG_LSB)
+
+#define SRATE_LSB 23
+#define SRATE_MASK (0xfL << SRATE_LSB)
+
+#define FALSE_STEREO 0x40000000 // block is stereo, but data is mono
+
+#define IGNORED_FLAGS 0x18000000 // reserved, but ignore if encountered
+#define NEW_SHAPING 0x20000000 // use IIR filter for negative shaping
+#define UNKNOWN_FLAGS 0x80000000 // also reserved, but refuse decode if
+ // encountered
+
+#define MONO_DATA (MONO_FLAG | FALSE_STEREO)
+
+#define MIN_STREAM_VERS 0x402 // lowest stream version we'll decode
+#define MAX_STREAM_VERS 0x410 // highest stream version we'll decode or encode
+#define CUR_STREAM_VERS 0x407 // stream version we are writing now
+
+// These are the mask bit definitions for the metadata chunk id byte (see format.txt)
+
+#define ID_UNIQUE 0x3f
+#define ID_OPTIONAL_DATA 0x20
+#define ID_ODD_SIZE 0x40
+#define ID_LARGE 0x80
+
+#define ID_DUMMY 0x0
+#define ID_ENCODER_INFO 0x1
+#define ID_DECORR_TERMS 0x2
+#define ID_DECORR_WEIGHTS 0x3
+#define ID_DECORR_SAMPLES 0x4
+#define ID_ENTROPY_VARS 0x5
+#define ID_HYBRID_PROFILE 0x6
+#define ID_SHAPING_WEIGHTS 0x7
+#define ID_FLOAT_INFO 0x8
+#define ID_INT32_INFO 0x9
+#define ID_WV_BITSTREAM 0xa
+#define ID_WVC_BITSTREAM 0xb
+#define ID_WVX_BITSTREAM 0xc
+#define ID_CHANNEL_INFO 0xd
+
+#define ID_RIFF_HEADER (ID_OPTIONAL_DATA | 0x1)
+#define ID_RIFF_TRAILER (ID_OPTIONAL_DATA | 0x2)
+#define ID_REPLAY_GAIN (ID_OPTIONAL_DATA | 0x3) // never used (APEv2)
+#define ID_CUESHEET (ID_OPTIONAL_DATA | 0x4) // never used (APEv2)
+#define ID_CONFIG_BLOCK (ID_OPTIONAL_DATA | 0x5)
+#define ID_MD5_CHECKSUM (ID_OPTIONAL_DATA | 0x6)
+#define ID_SAMPLE_RATE (ID_OPTIONAL_DATA | 0x7)
+
+///////////////////////// WavPack Configuration ///////////////////////////////
+
+// This external structure is used during encode to provide configuration to
+// the encoding engine and during decoding to provide fle information back to
+// the higher level functions. Not all fields are used in both modes.
+
+typedef struct {
+ float bitrate, shaping_weight;
+ int bits_per_sample, bytes_per_sample;
+ int qmode, flags, xmode, num_channels, float_norm_exp;
+ int32_t block_samples, extra_flags, sample_rate, channel_mask;
+ unsigned char md5_checksum [16], md5_read;
+ int num_tag_strings;
+ char **tag_strings;
+} WavpackConfig;
+
+#define CONFIG_HYBRID_FLAG 8 // hybrid mode
+#define CONFIG_JOINT_STEREO 0x10 // joint stereo
+#define CONFIG_HYBRID_SHAPE 0x40 // noise shape (hybrid mode only)
+#define CONFIG_FAST_FLAG 0x200 // fast mode
+#define CONFIG_HIGH_FLAG 0x800 // high quality mode
+#define CONFIG_VERY_HIGH_FLAG 0x1000 // very high
+#define CONFIG_BITRATE_KBPS 0x2000 // bitrate is kbps, not bits / sample
+#define CONFIG_SHAPE_OVERRIDE 0x8000 // shaping mode specified
+#define CONFIG_JOINT_OVERRIDE 0x10000 // joint-stereo mode specified
+#define CONFIG_DYNAMIC_SHAPING 0x20000 // dynamic noise shaping
+#define CONFIG_CREATE_EXE 0x40000 // create executable
+#define CONFIG_CREATE_WVC 0x80000 // create correction file
+#define CONFIG_OPTIMIZE_WVC 0x100000 // maximize bybrid compression
+#define CONFIG_CALC_NOISE 0x800000 // calc noise in hybrid mode
+#define CONFIG_EXTRA_MODE 0x2000000 // extra processing mode
+#define CONFIG_SKIP_WVX 0x4000000 // no wvx stream w/ floats & big ints
+#define CONFIG_MD5_CHECKSUM 0x8000000 // store MD5 signature
+#define CONFIG_MERGE_BLOCKS 0x10000000 // merge blocks of equal redundancy (for lossyWAV)
+#define CONFIG_PAIR_UNDEF_CHANS 0x20000000 // encode undefined channels in stereo pairs
+#define CONFIG_OPTIMIZE_MONO 0x80000000 // optimize for mono streams posing as stereo
+
+////////////// Callbacks used for reading & writing WavPack streams //////////
+
+typedef struct {
+ int32_t (*read_bytes)(void *id, void *data, int32_t bcount);
+ uint32_t (*get_pos)(void *id);
+ int (*set_pos_abs)(void *id, uint32_t pos);
+ int (*set_pos_rel)(void *id, int32_t delta, int mode);
+ int (*push_back_byte)(void *id, int c);
+ uint32_t (*get_length)(void *id);
+ int (*can_seek)(void *id);
+
+ // this callback is for writing edited tags only
+ int32_t (*write_bytes)(void *id, void *data, int32_t bcount);
+} WavpackStreamReader;
+
+typedef int (*WavpackBlockOutput)(void *id, void *data, int32_t bcount);
+
+//////////////////////////// function prototypes /////////////////////////////
+
+// Note: See wputils.c sourcecode for descriptions for using these functions.
+
+typedef void WavpackContext;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+WavpackContext *WavpackOpenFileInputEx (WavpackStreamReader *reader, void *wv_id, void *wvc_id, char *error, int flags, int norm_offset);
+WavpackContext *WavpackOpenFileInput (const char *infilename, char *error, int flags, int norm_offset);
+
+#define OPEN_WVC 0x1 // open/read "correction" file
+#define OPEN_TAGS 0x2 // read ID3v1 / APEv2 tags (seekable file)
+#define OPEN_WRAPPER 0x4 // make audio wrapper available (i.e. RIFF)
+#define OPEN_2CH_MAX 0x8 // open multichannel as stereo (no downmix)
+#define OPEN_NORMALIZE 0x10 // normalize floating point data to +/- 1.0
+#define OPEN_STREAMING 0x20 // "streaming" mode blindly unpacks blocks
+ // w/o regard to header file position info
+#define OPEN_EDIT_TAGS 0x40 // allow editing of tags
+
+int WavpackGetMode (WavpackContext *wpc);
+
+#define MODE_WVC 0x1
+#define MODE_LOSSLESS 0x2
+#define MODE_HYBRID 0x4
+#define MODE_FLOAT 0x8
+#define MODE_VALID_TAG 0x10
+#define MODE_HIGH 0x20
+#define MODE_FAST 0x40
+#define MODE_EXTRA 0x80 // extra mode used, see MODE_XMODE for possible level
+#define MODE_APETAG 0x100
+#define MODE_SFX 0x200
+#define MODE_VERY_HIGH 0x400
+#define MODE_MD5 0x800
+#define MODE_XMODE 0x7000 // mask for extra level (1-6, 0=unknown)
+#define MODE_DNS 0x8000
+
+char *WavpackGetErrorMessage (WavpackContext *wpc);
+int WavpackGetVersion (WavpackContext *wpc);
+uint32_t WavpackUnpackSamples (WavpackContext *wpc, int32_t *buffer, uint32_t samples);
+uint32_t WavpackGetNumSamples (WavpackContext *wpc);
+uint32_t WavpackGetSampleIndex (WavpackContext *wpc);
+int WavpackGetNumErrors (WavpackContext *wpc);
+int WavpackLossyBlocks (WavpackContext *wpc);
+int WavpackSeekSample (WavpackContext *wpc, uint32_t sample);
+WavpackContext *WavpackCloseFile (WavpackContext *wpc);
+uint32_t WavpackGetSampleRate (WavpackContext *wpc);
+int WavpackGetBitsPerSample (WavpackContext *wpc);
+int WavpackGetBytesPerSample (WavpackContext *wpc);
+int WavpackGetNumChannels (WavpackContext *wpc);
+int WavpackGetChannelMask (WavpackContext *wpc);
+int WavpackGetReducedChannels (WavpackContext *wpc);
+int WavpackGetFloatNormExp (WavpackContext *wpc);
+int WavpackGetMD5Sum (WavpackContext *wpc, unsigned char data [16]);
+uint32_t WavpackGetWrapperBytes (WavpackContext *wpc);
+unsigned char *WavpackGetWrapperData (WavpackContext *wpc);
+void WavpackFreeWrapper (WavpackContext *wpc);
+void WavpackSeekTrailingWrapper (WavpackContext *wpc);
+double WavpackGetProgress (WavpackContext *wpc);
+uint32_t WavpackGetFileSize (WavpackContext *wpc);
+double WavpackGetRatio (WavpackContext *wpc);
+double WavpackGetAverageBitrate (WavpackContext *wpc, int count_wvc);
+double WavpackGetInstantBitrate (WavpackContext *wpc);
+int WavpackGetNumTagItems (WavpackContext *wpc);
+int WavpackGetTagItem (WavpackContext *wpc, const char *item, char *value, int size);
+int WavpackGetTagItemIndexed (WavpackContext *wpc, int index, char *item, int size);
+int WavpackGetNumBinaryTagItems (WavpackContext *wpc);
+int WavpackGetBinaryTagItem (WavpackContext *wpc, const char *item, char *value, int size);
+int WavpackGetBinaryTagItemIndexed (WavpackContext *wpc, int index, char *item, int size);
+int WavpackAppendTagItem (WavpackContext *wpc, const char *item, const char *value, int vsize);
+int WavpackAppendBinaryTagItem (WavpackContext *wpc, const char *item, const char *value, int vsize);
+int WavpackDeleteTagItem (WavpackContext *wpc, const char *item);
+int WavpackWriteTag (WavpackContext *wpc);
+
+WavpackContext *WavpackOpenFileOutput (WavpackBlockOutput blockout, void *wv_id, void *wvc_id);
+int WavpackSetConfiguration (WavpackContext *wpc, WavpackConfig *config, uint32_t total_samples);
+int WavpackAddWrapper (WavpackContext *wpc, void *data, uint32_t bcount);
+int WavpackStoreMD5Sum (WavpackContext *wpc, unsigned char data [16]);
+int WavpackPackInit (WavpackContext *wpc);
+int WavpackPackSamples (WavpackContext *wpc, int32_t *sample_buffer, uint32_t sample_count);
+int WavpackFlushSamples (WavpackContext *wpc);
+void WavpackUpdateNumSamples (WavpackContext *wpc, void *first_block);
+void *WavpackGetWrapperLocation (void *first_block, uint32_t *size);
+double WavpackGetEncodedNoise (WavpackContext *wpc, double *peak);
+
+void WavpackFloatNormalize (int32_t *values, int32_t num_values, int delta_exp);
+
+void WavpackLittleEndianToNative (void *data, char *format);
+void WavpackNativeToLittleEndian (void *data, char *format);
+
+uint32_t WavpackGetLibraryVersion (void);
+const char *WavpackGetLibraryVersionString (void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib-x86-32/include/zconf.h b/lib-x86-32/include/zconf.h
new file mode 100644
index 00000000..b2343874
--- /dev/null
+++ b/lib-x86-32/include/zconf.h
@@ -0,0 +1,428 @@
+/* zconf.h -- configuration of the zlib compression library
+ * Copyright (C) 1995-2010 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#ifndef ZCONF_H
+#define ZCONF_H
+
+/*
+ * If you *really* need a unique prefix for all types and library functions,
+ * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
+ * Even better than compiling with -DZ_PREFIX would be to use configure to set
+ * this permanently in zconf.h using "./configure --zprefix".
+ */
+#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */
+
+/* all linked symbols */
+# define _dist_code z__dist_code
+# define _length_code z__length_code
+# define _tr_align z__tr_align
+# define _tr_flush_block z__tr_flush_block
+# define _tr_init z__tr_init
+# define _tr_stored_block z__tr_stored_block
+# define _tr_tally z__tr_tally
+# define adler32 z_adler32
+# define adler32_combine z_adler32_combine
+# define adler32_combine64 z_adler32_combine64
+# define compress z_compress
+# define compress2 z_compress2
+# define compressBound z_compressBound
+# define crc32 z_crc32
+# define crc32_combine z_crc32_combine
+# define crc32_combine64 z_crc32_combine64
+# define deflate z_deflate
+# define deflateBound z_deflateBound
+# define deflateCopy z_deflateCopy
+# define deflateEnd z_deflateEnd
+# define deflateInit2_ z_deflateInit2_
+# define deflateInit_ z_deflateInit_
+# define deflateParams z_deflateParams
+# define deflatePrime z_deflatePrime
+# define deflateReset z_deflateReset
+# define deflateSetDictionary z_deflateSetDictionary
+# define deflateSetHeader z_deflateSetHeader
+# define deflateTune z_deflateTune
+# define deflate_copyright z_deflate_copyright
+# define get_crc_table z_get_crc_table
+# define gz_error z_gz_error
+# define gz_intmax z_gz_intmax
+# define gz_strwinerror z_gz_strwinerror
+# define gzbuffer z_gzbuffer
+# define gzclearerr z_gzclearerr
+# define gzclose z_gzclose
+# define gzclose_r z_gzclose_r
+# define gzclose_w z_gzclose_w
+# define gzdirect z_gzdirect
+# define gzdopen z_gzdopen
+# define gzeof z_gzeof
+# define gzerror z_gzerror
+# define gzflush z_gzflush
+# define gzgetc z_gzgetc
+# define gzgets z_gzgets
+# define gzoffset z_gzoffset
+# define gzoffset64 z_gzoffset64
+# define gzopen z_gzopen
+# define gzopen64 z_gzopen64
+# define gzprintf z_gzprintf
+# define gzputc z_gzputc
+# define gzputs z_gzputs
+# define gzread z_gzread
+# define gzrewind z_gzrewind
+# define gzseek z_gzseek
+# define gzseek64 z_gzseek64
+# define gzsetparams z_gzsetparams
+# define gztell z_gztell
+# define gztell64 z_gztell64
+# define gzungetc z_gzungetc
+# define gzwrite z_gzwrite
+# define inflate z_inflate
+# define inflateBack z_inflateBack
+# define inflateBackEnd z_inflateBackEnd
+# define inflateBackInit_ z_inflateBackInit_
+# define inflateCopy z_inflateCopy
+# define inflateEnd z_inflateEnd
+# define inflateGetHeader z_inflateGetHeader
+# define inflateInit2_ z_inflateInit2_
+# define inflateInit_ z_inflateInit_
+# define inflateMark z_inflateMark
+# define inflatePrime z_inflatePrime
+# define inflateReset z_inflateReset
+# define inflateReset2 z_inflateReset2
+# define inflateSetDictionary z_inflateSetDictionary
+# define inflateSync z_inflateSync
+# define inflateSyncPoint z_inflateSyncPoint
+# define inflateUndermine z_inflateUndermine
+# define inflate_copyright z_inflate_copyright
+# define inflate_fast z_inflate_fast
+# define inflate_table z_inflate_table
+# define uncompress z_uncompress
+# define zError z_zError
+# define zcalloc z_zcalloc
+# define zcfree z_zcfree
+# define zlibCompileFlags z_zlibCompileFlags
+# define zlibVersion z_zlibVersion
+
+/* all zlib typedefs in zlib.h and zconf.h */
+# define Byte z_Byte
+# define Bytef z_Bytef
+# define alloc_func z_alloc_func
+# define charf z_charf
+# define free_func z_free_func
+# define gzFile z_gzFile
+# define gz_header z_gz_header
+# define gz_headerp z_gz_headerp
+# define in_func z_in_func
+# define intf z_intf
+# define out_func z_out_func
+# define uInt z_uInt
+# define uIntf z_uIntf
+# define uLong z_uLong
+# define uLongf z_uLongf
+# define voidp z_voidp
+# define voidpc z_voidpc
+# define voidpf z_voidpf
+
+/* all zlib structs in zlib.h and zconf.h */
+# define gz_header_s z_gz_header_s
+# define internal_state z_internal_state
+
+#endif
+
+#if defined(__MSDOS__) && !defined(MSDOS)
+# define MSDOS
+#endif
+#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
+# define OS2
+#endif
+#if defined(_WINDOWS) && !defined(WINDOWS)
+# define WINDOWS
+#endif
+#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
+# ifndef WIN32
+# define WIN32
+# endif
+#endif
+#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
+# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
+# ifndef SYS16BIT
+# define SYS16BIT
+# endif
+# endif
+#endif
+
+/*
+ * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
+ * than 64k bytes at a time (needed on systems with 16-bit int).
+ */
+#ifdef SYS16BIT
+# define MAXSEG_64K
+#endif
+#ifdef MSDOS
+# define UNALIGNED_OK
+#endif
+
+#ifdef __STDC_VERSION__
+# ifndef STDC
+# define STDC
+# endif
+# if __STDC_VERSION__ >= 199901L
+# ifndef STDC99
+# define STDC99
+# endif
+# endif
+#endif
+#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
+# define STDC
+#endif
+#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
+# define STDC
+#endif
+#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
+# define STDC
+#endif
+#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
+# define STDC
+#endif
+
+#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */
+# define STDC
+#endif
+
+#ifndef STDC
+# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
+# define const /* note: need a more gentle solution here */
+# endif
+#endif
+
+/* Some Mac compilers merge all .h files incorrectly: */
+#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
+# define NO_DUMMY_DECL
+#endif
+
+/* Maximum value for memLevel in deflateInit2 */
+#ifndef MAX_MEM_LEVEL
+# ifdef MAXSEG_64K
+# define MAX_MEM_LEVEL 8
+# else
+# define MAX_MEM_LEVEL 9
+# endif
+#endif
+
+/* Maximum value for windowBits in deflateInit2 and inflateInit2.
+ * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
+ * created by gzip. (Files created by minigzip can still be extracted by
+ * gzip.)
+ */
+#ifndef MAX_WBITS
+# define MAX_WBITS 15 /* 32K LZ77 window */
+#endif
+
+/* The memory requirements for deflate are (in bytes):
+ (1 << (windowBits+2)) + (1 << (memLevel+9))
+ that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
+ plus a few kilobytes for small objects. For example, if you want to reduce
+ the default memory requirements from 256K to 128K, compile with
+ make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
+ Of course this will generally degrade compression (there's no free lunch).
+
+ The memory requirements for inflate are (in bytes) 1 << windowBits
+ that is, 32K for windowBits=15 (default value) plus a few kilobytes
+ for small objects.
+*/
+
+ /* Type declarations */
+
+#ifndef OF /* function prototypes */
+# ifdef STDC
+# define OF(args) args
+# else
+# define OF(args) ()
+# endif
+#endif
+
+/* The following definitions for FAR are needed only for MSDOS mixed
+ * model programming (small or medium model with some far allocations).
+ * This was tested only with MSC; for other MSDOS compilers you may have
+ * to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
+ * just define FAR to be empty.
+ */
+#ifdef SYS16BIT
+# if defined(M_I86SM) || defined(M_I86MM)
+ /* MSC small or medium model */
+# define SMALL_MEDIUM
+# ifdef _MSC_VER
+# define FAR _far
+# else
+# define FAR far
+# endif
+# endif
+# if (defined(__SMALL__) || defined(__MEDIUM__))
+ /* Turbo C small or medium model */
+# define SMALL_MEDIUM
+# ifdef __BORLANDC__
+# define FAR _far
+# else
+# define FAR far
+# endif
+# endif
+#endif
+
+#if defined(WINDOWS) || defined(WIN32)
+ /* If building or using zlib as a DLL, define ZLIB_DLL.
+ * This is not mandatory, but it offers a little performance increase.
+ */
+# ifdef ZLIB_DLL
+# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
+# ifdef ZLIB_INTERNAL
+# define ZEXTERN extern __declspec(dllexport)
+# else
+# define ZEXTERN extern __declspec(dllimport)
+# endif
+# endif
+# endif /* ZLIB_DLL */
+ /* If building or using zlib with the WINAPI/WINAPIV calling convention,
+ * define ZLIB_WINAPI.
+ * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
+ */
+# ifdef ZLIB_WINAPI
+# ifdef FAR
+# undef FAR
+# endif
+# include <windows.h>
+ /* No need for _export, use ZLIB.DEF instead. */
+ /* For complete Windows compatibility, use WINAPI, not __stdcall. */
+# define ZEXPORT WINAPI
+# ifdef WIN32
+# define ZEXPORTVA WINAPIV
+# else
+# define ZEXPORTVA FAR CDECL
+# endif
+# endif
+#endif
+
+#if defined (__BEOS__)
+# ifdef ZLIB_DLL
+# ifdef ZLIB_INTERNAL
+# define ZEXPORT __declspec(dllexport)
+# define ZEXPORTVA __declspec(dllexport)
+# else
+# define ZEXPORT __declspec(dllimport)
+# define ZEXPORTVA __declspec(dllimport)
+# endif
+# endif
+#endif
+
+#ifndef ZEXTERN
+# define ZEXTERN extern
+#endif
+#ifndef ZEXPORT
+# define ZEXPORT
+#endif
+#ifndef ZEXPORTVA
+# define ZEXPORTVA
+#endif
+
+#ifndef FAR
+# define FAR
+#endif
+
+#if !defined(__MACTYPES__)
+typedef unsigned char Byte; /* 8 bits */
+#endif
+typedef unsigned int uInt; /* 16 bits or more */
+typedef unsigned long uLong; /* 32 bits or more */
+
+#ifdef SMALL_MEDIUM
+ /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
+# define Bytef Byte FAR
+#else
+ typedef Byte FAR Bytef;
+#endif
+typedef char FAR charf;
+typedef int FAR intf;
+typedef uInt FAR uIntf;
+typedef uLong FAR uLongf;
+
+#ifdef STDC
+ typedef void const *voidpc;
+ typedef void FAR *voidpf;
+ typedef void *voidp;
+#else
+ typedef Byte const *voidpc;
+ typedef Byte FAR *voidpf;
+ typedef Byte *voidp;
+#endif
+
+#if 1 /* was set to #if 1 by ./configure */
+# define Z_HAVE_UNISTD_H
+#endif
+
+#ifdef STDC
+# include <sys/types.h> /* for off_t */
+#endif
+
+/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and
+ * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even
+ * though the former does not conform to the LFS document), but considering
+ * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as
+ * equivalently requesting no 64-bit operations
+ */
+#if -_LARGEFILE64_SOURCE - -1 == 1
+# undef _LARGEFILE64_SOURCE
+#endif
+
+#if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE)
+# include <unistd.h> /* for SEEK_* and off_t */
+# ifdef VMS
+# include <unixio.h> /* for off_t */
+# endif
+# ifndef z_off_t
+# define z_off_t off_t
+# endif
+#endif
+
+#ifndef SEEK_SET
+# define SEEK_SET 0 /* Seek from beginning of file. */
+# define SEEK_CUR 1 /* Seek from current position. */
+# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
+#endif
+
+#ifndef z_off_t
+# define z_off_t long
+#endif
+
+#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0
+# define z_off64_t off64_t
+#else
+# define z_off64_t z_off_t
+#endif
+
+#if defined(__OS400__)
+# define NO_vsnprintf
+#endif
+
+#if defined(__MVS__)
+# define NO_vsnprintf
+#endif
+
+/* MVS linker does not support external names larger than 8 bytes */
+#if defined(__MVS__)
+ #pragma map(deflateInit_,"DEIN")
+ #pragma map(deflateInit2_,"DEIN2")
+ #pragma map(deflateEnd,"DEEND")
+ #pragma map(deflateBound,"DEBND")
+ #pragma map(inflateInit_,"ININ")
+ #pragma map(inflateInit2_,"ININ2")
+ #pragma map(inflateEnd,"INEND")
+ #pragma map(inflateSync,"INSY")
+ #pragma map(inflateSetDictionary,"INSEDI")
+ #pragma map(compressBound,"CMBND")
+ #pragma map(inflate_table,"INTABL")
+ #pragma map(inflate_fast,"INFA")
+ #pragma map(inflate_copyright,"INCOPY")
+#endif
+
+#endif /* ZCONF_H */
diff --git a/lib-x86-32/include/zlib.h b/lib-x86-32/include/zlib.h
new file mode 100644
index 00000000..bfbba83e
--- /dev/null
+++ b/lib-x86-32/include/zlib.h
@@ -0,0 +1,1613 @@
+/* zlib.h -- interface of the 'zlib' general purpose compression library
+ version 1.2.5, April 19th, 2010
+
+ Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ Jean-loup Gailly Mark Adler
+ jloup@gzip.org madler@alumni.caltech.edu
+
+
+ The data format used by the zlib library is described by RFCs (Request for
+ Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt
+ (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
+*/
+
+#ifndef ZLIB_H
+#define ZLIB_H
+
+#include "zconf.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ZLIB_VERSION "1.2.5"
+#define ZLIB_VERNUM 0x1250
+#define ZLIB_VER_MAJOR 1
+#define ZLIB_VER_MINOR 2
+#define ZLIB_VER_REVISION 5
+#define ZLIB_VER_SUBREVISION 0
+
+/*
+ The 'zlib' compression library provides in-memory compression and
+ decompression functions, including integrity checks of the uncompressed data.
+ This version of the library supports only one compression method (deflation)
+ but other algorithms will be added later and will have the same stream
+ interface.
+
+ Compression can be done in a single step if the buffers are large enough,
+ or can be done by repeated calls of the compression function. In the latter
+ case, the application must provide more input and/or consume the output
+ (providing more output space) before each call.
+
+ The compressed data format used by default by the in-memory functions is
+ the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped
+ around a deflate stream, which is itself documented in RFC 1951.
+
+ The library also supports reading and writing files in gzip (.gz) format
+ with an interface similar to that of stdio using the functions that start
+ with "gz". The gzip format is different from the zlib format. gzip is a
+ gzip wrapper, documented in RFC 1952, wrapped around a deflate stream.
+
+ This library can optionally read and write gzip streams in memory as well.
+
+ The zlib format was designed to be compact and fast for use in memory
+ and on communications channels. The gzip format was designed for single-
+ file compression on file systems, has a larger header than zlib to maintain
+ directory information, and uses a different, slower check method than zlib.
+
+ The library does not install any signal handler. The decoder checks
+ the consistency of the compressed data, so the library should never crash
+ even in case of corrupted input.
+*/
+
+typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
+typedef void (*free_func) OF((voidpf opaque, voidpf address));
+
+struct internal_state;
+
+typedef struct z_stream_s {
+ Bytef *next_in; /* next input byte */
+ uInt avail_in; /* number of bytes available at next_in */
+ uLong total_in; /* total nb of input bytes read so far */
+
+ Bytef *next_out; /* next output byte should be put there */
+ uInt avail_out; /* remaining free space at next_out */
+ uLong total_out; /* total nb of bytes output so far */
+
+ char *msg; /* last error message, NULL if no error */
+ struct internal_state FAR *state; /* not visible by applications */
+
+ alloc_func zalloc; /* used to allocate the internal state */
+ free_func zfree; /* used to free the internal state */
+ voidpf opaque; /* private data object passed to zalloc and zfree */
+
+ int data_type; /* best guess about the data type: binary or text */
+ uLong adler; /* adler32 value of the uncompressed data */
+ uLong reserved; /* reserved for future use */
+} z_stream;
+
+typedef z_stream FAR *z_streamp;
+
+/*
+ gzip header information passed to and from zlib routines. See RFC 1952
+ for more details on the meanings of these fields.
+*/
+typedef struct gz_header_s {
+ int text; /* true if compressed data believed to be text */
+ uLong time; /* modification time */
+ int xflags; /* extra flags (not used when writing a gzip file) */
+ int os; /* operating system */
+ Bytef *extra; /* pointer to extra field or Z_NULL if none */
+ uInt extra_len; /* extra field length (valid if extra != Z_NULL) */
+ uInt extra_max; /* space at extra (only when reading header) */
+ Bytef *name; /* pointer to zero-terminated file name or Z_NULL */
+ uInt name_max; /* space at name (only when reading header) */
+ Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */
+ uInt comm_max; /* space at comment (only when reading header) */
+ int hcrc; /* true if there was or will be a header crc */
+ int done; /* true when done reading gzip header (not used
+ when writing a gzip file) */
+} gz_header;
+
+typedef gz_header FAR *gz_headerp;
+
+/*
+ The application must update next_in and avail_in when avail_in has dropped
+ to zero. It must update next_out and avail_out when avail_out has dropped
+ to zero. The application must initialize zalloc, zfree and opaque before
+ calling the init function. All other fields are set by the compression
+ library and must not be updated by the application.
+
+ The opaque value provided by the application will be passed as the first
+ parameter for calls of zalloc and zfree. This can be useful for custom
+ memory management. The compression library attaches no meaning to the
+ opaque value.
+
+ zalloc must return Z_NULL if there is not enough memory for the object.
+ If zlib is used in a multi-threaded application, zalloc and zfree must be
+ thread safe.
+
+ On 16-bit systems, the functions zalloc and zfree must be able to allocate
+ exactly 65536 bytes, but will not be required to allocate more than this if
+ the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, pointers
+ returned by zalloc for objects of exactly 65536 bytes *must* have their
+ offset normalized to zero. The default allocation function provided by this
+ library ensures this (see zutil.c). To reduce memory requirements and avoid
+ any allocation of 64K objects, at the expense of compression ratio, compile
+ the library with -DMAX_WBITS=14 (see zconf.h).
+
+ The fields total_in and total_out can be used for statistics or progress
+ reports. After compression, total_in holds the total size of the
+ uncompressed data and may be saved for use in the decompressor (particularly
+ if the decompressor wants to decompress everything in a single step).
+*/
+
+ /* constants */
+
+#define Z_NO_FLUSH 0
+#define Z_PARTIAL_FLUSH 1
+#define Z_SYNC_FLUSH 2
+#define Z_FULL_FLUSH 3
+#define Z_FINISH 4
+#define Z_BLOCK 5
+#define Z_TREES 6
+/* Allowed flush values; see deflate() and inflate() below for details */
+
+#define Z_OK 0
+#define Z_STREAM_END 1
+#define Z_NEED_DICT 2
+#define Z_ERRNO (-1)
+#define Z_STREAM_ERROR (-2)
+#define Z_DATA_ERROR (-3)
+#define Z_MEM_ERROR (-4)
+#define Z_BUF_ERROR (-5)
+#define Z_VERSION_ERROR (-6)
+/* Return codes for the compression/decompression functions. Negative values
+ * are errors, positive values are used for special but normal events.
+ */
+
+#define Z_NO_COMPRESSION 0
+#define Z_BEST_SPEED 1
+#define Z_BEST_COMPRESSION 9
+#define Z_DEFAULT_COMPRESSION (-1)
+/* compression levels */
+
+#define Z_FILTERED 1
+#define Z_HUFFMAN_ONLY 2
+#define Z_RLE 3
+#define Z_FIXED 4
+#define Z_DEFAULT_STRATEGY 0
+/* compression strategy; see deflateInit2() below for details */
+
+#define Z_BINARY 0
+#define Z_TEXT 1
+#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */
+#define Z_UNKNOWN 2
+/* Possible values of the data_type field (though see inflate()) */
+
+#define Z_DEFLATED 8
+/* The deflate compression method (the only one supported in this version) */
+
+#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */
+
+#define zlib_version zlibVersion()
+/* for compatibility with versions < 1.0.2 */
+
+
+ /* basic functions */
+
+ZEXTERN const char * ZEXPORT zlibVersion OF((void));
+/* The application can compare zlibVersion and ZLIB_VERSION for consistency.
+ If the first character differs, the library code actually used is not
+ compatible with the zlib.h header file used by the application. This check
+ is automatically made by deflateInit and inflateInit.
+ */
+
+/*
+ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level));
+
+ Initializes the internal stream state for compression. The fields
+ zalloc, zfree and opaque must be initialized before by the caller. If
+ zalloc and zfree are set to Z_NULL, deflateInit updates them to use default
+ allocation functions.
+
+ The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:
+ 1 gives best speed, 9 gives best compression, 0 gives no compression at all
+ (the input data is simply copied a block at a time). Z_DEFAULT_COMPRESSION
+ requests a default compromise between speed and compression (currently
+ equivalent to level 6).
+
+ deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_STREAM_ERROR if level is not a valid compression level, or
+ Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible
+ with the version assumed by the caller (ZLIB_VERSION). msg is set to null
+ if there is no error message. deflateInit does not perform any compression:
+ this will be done by deflate().
+*/
+
+
+ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
+/*
+ deflate compresses as much data as possible, and stops when the input
+ buffer becomes empty or the output buffer becomes full. It may introduce
+ some output latency (reading input without producing any output) except when
+ forced to flush.
+
+ The detailed semantics are as follows. deflate performs one or both of the
+ following actions:
+
+ - Compress more input starting at next_in and update next_in and avail_in
+ accordingly. If not all input can be processed (because there is not
+ enough room in the output buffer), next_in and avail_in are updated and
+ processing will resume at this point for the next call of deflate().
+
+ - Provide more output starting at next_out and update next_out and avail_out
+ accordingly. This action is forced if the parameter flush is non zero.
+ Forcing flush frequently degrades the compression ratio, so this parameter
+ should be set only when necessary (in interactive applications). Some
+ output may be provided even if flush is not set.
+
+ Before the call of deflate(), the application should ensure that at least
+ one of the actions is possible, by providing more input and/or consuming more
+ output, and updating avail_in or avail_out accordingly; avail_out should
+ never be zero before the call. The application can consume the compressed
+ output when it wants, for example when the output buffer is full (avail_out
+ == 0), or after each call of deflate(). If deflate returns Z_OK and with
+ zero avail_out, it must be called again after making room in the output
+ buffer because there might be more output pending.
+
+ Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to
+ decide how much data to accumulate before producing output, in order to
+ maximize compression.
+
+ If the parameter flush is set to Z_SYNC_FLUSH, all pending output is
+ flushed to the output buffer and the output is aligned on a byte boundary, so
+ that the decompressor can get all input data available so far. (In
+ particular avail_in is zero after the call if enough output space has been
+ provided before the call.) Flushing may degrade compression for some
+ compression algorithms and so it should be used only when necessary. This
+ completes the current deflate block and follows it with an empty stored block
+ that is three bits plus filler bits to the next byte, followed by four bytes
+ (00 00 ff ff).
+
+ If flush is set to Z_PARTIAL_FLUSH, all pending output is flushed to the
+ output buffer, but the output is not aligned to a byte boundary. All of the
+ input data so far will be available to the decompressor, as for Z_SYNC_FLUSH.
+ This completes the current deflate block and follows it with an empty fixed
+ codes block that is 10 bits long. This assures that enough bytes are output
+ in order for the decompressor to finish the block before the empty fixed code
+ block.
+
+ If flush is set to Z_BLOCK, a deflate block is completed and emitted, as
+ for Z_SYNC_FLUSH, but the output is not aligned on a byte boundary, and up to
+ seven bits of the current block are held to be written as the next byte after
+ the next deflate block is completed. In this case, the decompressor may not
+ be provided enough bits at this point in order to complete decompression of
+ the data provided so far to the compressor. It may need to wait for the next
+ block to be emitted. This is for advanced applications that need to control
+ the emission of deflate blocks.
+
+ If flush is set to Z_FULL_FLUSH, all output is flushed as with
+ Z_SYNC_FLUSH, and the compression state is reset so that decompression can
+ restart from this point if previous compressed data has been damaged or if
+ random access is desired. Using Z_FULL_FLUSH too often can seriously degrade
+ compression.
+
+ If deflate returns with avail_out == 0, this function must be called again
+ with the same value of the flush parameter and more output space (updated
+ avail_out), until the flush is complete (deflate returns with non-zero
+ avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that
+ avail_out is greater than six to avoid repeated flush markers due to
+ avail_out == 0 on return.
+
+ If the parameter flush is set to Z_FINISH, pending input is processed,
+ pending output is flushed and deflate returns with Z_STREAM_END if there was
+ enough output space; if deflate returns with Z_OK, this function must be
+ called again with Z_FINISH and more output space (updated avail_out) but no
+ more input data, until it returns with Z_STREAM_END or an error. After
+ deflate has returned Z_STREAM_END, the only possible operations on the stream
+ are deflateReset or deflateEnd.
+
+ Z_FINISH can be used immediately after deflateInit if all the compression
+ is to be done in a single step. In this case, avail_out must be at least the
+ value returned by deflateBound (see below). If deflate does not return
+ Z_STREAM_END, then it must be called again as described above.
+
+ deflate() sets strm->adler to the adler32 checksum of all input read
+ so far (that is, total_in bytes).
+
+ deflate() may update strm->data_type if it can make a good guess about
+ the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered
+ binary. This field is only for information purposes and does not affect the
+ compression algorithm in any manner.
+
+ deflate() returns Z_OK if some progress has been made (more input
+ processed or more output produced), Z_STREAM_END if all input has been
+ consumed and all output has been produced (only when flush is set to
+ Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
+ if next_in or next_out was Z_NULL), Z_BUF_ERROR if no progress is possible
+ (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not
+ fatal, and deflate() can be called again with more input and more output
+ space to continue compressing.
+*/
+
+
+ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm));
+/*
+ All dynamically allocated data structures for this stream are freed.
+ This function discards any unprocessed input and does not flush any pending
+ output.
+
+ deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the
+ stream state was inconsistent, Z_DATA_ERROR if the stream was freed
+ prematurely (some input or output was discarded). In the error case, msg
+ may be set but then points to a static string (which must not be
+ deallocated).
+*/
+
+
+/*
+ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
+
+ Initializes the internal stream state for decompression. The fields
+ next_in, avail_in, zalloc, zfree and opaque must be initialized before by
+ the caller. If next_in is not Z_NULL and avail_in is large enough (the
+ exact value depends on the compression method), inflateInit determines the
+ compression method from the zlib header and allocates all data structures
+ accordingly; otherwise the allocation will be deferred to the first call of
+ inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to
+ use default allocation functions.
+
+ inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
+ version assumed by the caller, or Z_STREAM_ERROR if the parameters are
+ invalid, such as a null pointer to the structure. msg is set to null if
+ there is no error message. inflateInit does not perform any decompression
+ apart from possibly reading the zlib header if present: actual decompression
+ will be done by inflate(). (So next_in and avail_in may be modified, but
+ next_out and avail_out are unused and unchanged.) The current implementation
+ of inflateInit() does not process any header information -- that is deferred
+ until inflate() is called.
+*/
+
+
+ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
+/*
+ inflate decompresses as much data as possible, and stops when the input
+ buffer becomes empty or the output buffer becomes full. It may introduce
+ some output latency (reading input without producing any output) except when
+ forced to flush.
+
+ The detailed semantics are as follows. inflate performs one or both of the
+ following actions:
+
+ - Decompress more input starting at next_in and update next_in and avail_in
+ accordingly. If not all input can be processed (because there is not
+ enough room in the output buffer), next_in is updated and processing will
+ resume at this point for the next call of inflate().
+
+ - Provide more output starting at next_out and update next_out and avail_out
+ accordingly. inflate() provides as much output as possible, until there is
+ no more input data or no more space in the output buffer (see below about
+ the flush parameter).
+
+ Before the call of inflate(), the application should ensure that at least
+ one of the actions is possible, by providing more input and/or consuming more
+ output, and updating the next_* and avail_* values accordingly. The
+ application can consume the uncompressed output when it wants, for example
+ when the output buffer is full (avail_out == 0), or after each call of
+ inflate(). If inflate returns Z_OK and with zero avail_out, it must be
+ called again after making room in the output buffer because there might be
+ more output pending.
+
+ The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH,
+ Z_BLOCK, or Z_TREES. Z_SYNC_FLUSH requests that inflate() flush as much
+ output as possible to the output buffer. Z_BLOCK requests that inflate()
+ stop if and when it gets to the next deflate block boundary. When decoding
+ the zlib or gzip format, this will cause inflate() to return immediately
+ after the header and before the first block. When doing a raw inflate,
+ inflate() will go ahead and process the first block, and will return when it
+ gets to the end of that block, or when it runs out of data.
+
+ The Z_BLOCK option assists in appending to or combining deflate streams.
+ Also to assist in this, on return inflate() will set strm->data_type to the
+ number of unused bits in the last byte taken from strm->next_in, plus 64 if
+ inflate() is currently decoding the last block in the deflate stream, plus
+ 128 if inflate() returned immediately after decoding an end-of-block code or
+ decoding the complete header up to just before the first byte of the deflate
+ stream. The end-of-block will not be indicated until all of the uncompressed
+ data from that block has been written to strm->next_out. The number of
+ unused bits may in general be greater than seven, except when bit 7 of
+ data_type is set, in which case the number of unused bits will be less than
+ eight. data_type is set as noted here every time inflate() returns for all
+ flush options, and so can be used to determine the amount of currently
+ consumed input in bits.
+
+ The Z_TREES option behaves as Z_BLOCK does, but it also returns when the
+ end of each deflate block header is reached, before any actual data in that
+ block is decoded. This allows the caller to determine the length of the
+ deflate block header for later use in random access within a deflate block.
+ 256 is added to the value of strm->data_type when inflate() returns
+ immediately after reaching the end of the deflate block header.
+
+ inflate() should normally be called until it returns Z_STREAM_END or an
+ error. However if all decompression is to be performed in a single step (a
+ single call of inflate), the parameter flush should be set to Z_FINISH. In
+ this case all pending input is processed and all pending output is flushed;
+ avail_out must be large enough to hold all the uncompressed data. (The size
+ of the uncompressed data may have been saved by the compressor for this
+ purpose.) The next operation on this stream must be inflateEnd to deallocate
+ the decompression state. The use of Z_FINISH is never required, but can be
+ used to inform inflate that a faster approach may be used for the single
+ inflate() call.
+
+ In this implementation, inflate() always flushes as much output as
+ possible to the output buffer, and always uses the faster approach on the
+ first call. So the only effect of the flush parameter in this implementation
+ is on the return value of inflate(), as noted below, or when it returns early
+ because Z_BLOCK or Z_TREES is used.
+
+ If a preset dictionary is needed after this call (see inflateSetDictionary
+ below), inflate sets strm->adler to the adler32 checksum of the dictionary
+ chosen by the compressor and returns Z_NEED_DICT; otherwise it sets
+ strm->adler to the adler32 checksum of all output produced so far (that is,
+ total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described
+ below. At the end of the stream, inflate() checks that its computed adler32
+ checksum is equal to that saved by the compressor and returns Z_STREAM_END
+ only if the checksum is correct.
+
+ inflate() can decompress and check either zlib-wrapped or gzip-wrapped
+ deflate data. The header type is detected automatically, if requested when
+ initializing with inflateInit2(). Any information contained in the gzip
+ header is not retained, so applications that need that information should
+ instead use raw inflate, see inflateInit2() below, or inflateBack() and
+ perform their own processing of the gzip header and trailer.
+
+ inflate() returns Z_OK if some progress has been made (more input processed
+ or more output produced), Z_STREAM_END if the end of the compressed data has
+ been reached and all uncompressed output has been produced, Z_NEED_DICT if a
+ preset dictionary is needed at this point, Z_DATA_ERROR if the input data was
+ corrupted (input stream not conforming to the zlib format or incorrect check
+ value), Z_STREAM_ERROR if the stream structure was inconsistent (for example
+ next_in or next_out was Z_NULL), Z_MEM_ERROR if there was not enough memory,
+ Z_BUF_ERROR if no progress is possible or if there was not enough room in the
+ output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and
+ inflate() can be called again with more input and more output space to
+ continue decompressing. If Z_DATA_ERROR is returned, the application may
+ then call inflateSync() to look for a good compression block if a partial
+ recovery of the data is desired.
+*/
+
+
+ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm));
+/*
+ All dynamically allocated data structures for this stream are freed.
+ This function discards any unprocessed input and does not flush any pending
+ output.
+
+ inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
+ was inconsistent. In the error case, msg may be set but then points to a
+ static string (which must not be deallocated).
+*/
+
+
+ /* Advanced functions */
+
+/*
+ The following functions are needed only in some special applications.
+*/
+
+/*
+ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
+ int level,
+ int method,
+ int windowBits,
+ int memLevel,
+ int strategy));
+
+ This is another version of deflateInit with more compression options. The
+ fields next_in, zalloc, zfree and opaque must be initialized before by the
+ caller.
+
+ The method parameter is the compression method. It must be Z_DEFLATED in
+ this version of the library.
+
+ The windowBits parameter is the base two logarithm of the window size
+ (the size of the history buffer). It should be in the range 8..15 for this
+ version of the library. Larger values of this parameter result in better
+ compression at the expense of memory usage. The default value is 15 if
+ deflateInit is used instead.
+
+ windowBits can also be -8..-15 for raw deflate. In this case, -windowBits
+ determines the window size. deflate() will then generate raw deflate data
+ with no zlib header or trailer, and will not compute an adler32 check value.
+
+ windowBits can also be greater than 15 for optional gzip encoding. Add
+ 16 to windowBits to write a simple gzip header and trailer around the
+ compressed data instead of a zlib wrapper. The gzip header will have no
+ file name, no extra data, no comment, no modification time (set to zero), no
+ header crc, and the operating system will be set to 255 (unknown). If a
+ gzip stream is being written, strm->adler is a crc32 instead of an adler32.
+
+ The memLevel parameter specifies how much memory should be allocated
+ for the internal compression state. memLevel=1 uses minimum memory but is
+ slow and reduces compression ratio; memLevel=9 uses maximum memory for
+ optimal speed. The default value is 8. See zconf.h for total memory usage
+ as a function of windowBits and memLevel.
+
+ The strategy parameter is used to tune the compression algorithm. Use the
+ value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a
+ filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no
+ string match), or Z_RLE to limit match distances to one (run-length
+ encoding). Filtered data consists mostly of small values with a somewhat
+ random distribution. In this case, the compression algorithm is tuned to
+ compress them better. The effect of Z_FILTERED is to force more Huffman
+ coding and less string matching; it is somewhat intermediate between
+ Z_DEFAULT_STRATEGY and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as
+ fast as Z_HUFFMAN_ONLY, but give better compression for PNG image data. The
+ strategy parameter only affects the compression ratio but not the
+ correctness of the compressed output even if it is not set appropriately.
+ Z_FIXED prevents the use of dynamic Huffman codes, allowing for a simpler
+ decoder for special applications.
+
+ deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_STREAM_ERROR if any parameter is invalid (such as an invalid
+ method), or Z_VERSION_ERROR if the zlib library version (zlib_version) is
+ incompatible with the version assumed by the caller (ZLIB_VERSION). msg is
+ set to null if there is no error message. deflateInit2 does not perform any
+ compression: this will be done by deflate().
+*/
+
+ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
+ const Bytef *dictionary,
+ uInt dictLength));
+/*
+ Initializes the compression dictionary from the given byte sequence
+ without producing any compressed output. This function must be called
+ immediately after deflateInit, deflateInit2 or deflateReset, before any call
+ of deflate. The compressor and decompressor must use exactly the same
+ dictionary (see inflateSetDictionary).
+
+ The dictionary should consist of strings (byte sequences) that are likely
+ to be encountered later in the data to be compressed, with the most commonly
+ used strings preferably put towards the end of the dictionary. Using a
+ dictionary is most useful when the data to be compressed is short and can be
+ predicted with good accuracy; the data can then be compressed better than
+ with the default empty dictionary.
+
+ Depending on the size of the compression data structures selected by
+ deflateInit or deflateInit2, a part of the dictionary may in effect be
+ discarded, for example if the dictionary is larger than the window size
+ provided in deflateInit or deflateInit2. Thus the strings most likely to be
+ useful should be put at the end of the dictionary, not at the front. In
+ addition, the current implementation of deflate will use at most the window
+ size minus 262 bytes of the provided dictionary.
+
+ Upon return of this function, strm->adler is set to the adler32 value
+ of the dictionary; the decompressor may later use this value to determine
+ which dictionary has been used by the compressor. (The adler32 value
+ applies to the whole dictionary even if only a subset of the dictionary is
+ actually used by the compressor.) If a raw deflate was requested, then the
+ adler32 value is not computed and strm->adler is not set.
+
+ deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
+ parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is
+ inconsistent (for example if deflate has already been called for this stream
+ or if the compression method is bsort). deflateSetDictionary does not
+ perform any compression: this will be done by deflate().
+*/
+
+ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
+ z_streamp source));
+/*
+ Sets the destination stream as a complete copy of the source stream.
+
+ This function can be useful when several compression strategies will be
+ tried, for example when there are several ways of pre-processing the input
+ data with a filter. The streams that will be discarded should then be freed
+ by calling deflateEnd. Note that deflateCopy duplicates the internal
+ compression state which can be quite large, so this strategy is slow and can
+ consume lots of memory.
+
+ deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
+ (such as zalloc being Z_NULL). msg is left unchanged in both source and
+ destination.
+*/
+
+ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm));
+/*
+ This function is equivalent to deflateEnd followed by deflateInit,
+ but does not free and reallocate all the internal compression state. The
+ stream will keep the same compression level and any other attributes that
+ may have been set by deflateInit2.
+
+ deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent (such as zalloc or state being Z_NULL).
+*/
+
+ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
+ int level,
+ int strategy));
+/*
+ Dynamically update the compression level and compression strategy. The
+ interpretation of level and strategy is as in deflateInit2. This can be
+ used to switch between compression and straight copy of the input data, or
+ to switch to a different kind of input data requiring a different strategy.
+ If the compression level is changed, the input available so far is
+ compressed with the old level (and may be flushed); the new level will take
+ effect only at the next call of deflate().
+
+ Before the call of deflateParams, the stream state must be set as for
+ a call of deflate(), since the currently available input may have to be
+ compressed and flushed. In particular, strm->avail_out must be non-zero.
+
+ deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source
+ stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR if
+ strm->avail_out was zero.
+*/
+
+ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm,
+ int good_length,
+ int max_lazy,
+ int nice_length,
+ int max_chain));
+/*
+ Fine tune deflate's internal compression parameters. This should only be
+ used by someone who understands the algorithm used by zlib's deflate for
+ searching for the best matching string, and even then only by the most
+ fanatic optimizer trying to squeeze out the last compressed bit for their
+ specific input data. Read the deflate.c source code for the meaning of the
+ max_lazy, good_length, nice_length, and max_chain parameters.
+
+ deflateTune() can be called after deflateInit() or deflateInit2(), and
+ returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream.
+ */
+
+ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm,
+ uLong sourceLen));
+/*
+ deflateBound() returns an upper bound on the compressed size after
+ deflation of sourceLen bytes. It must be called after deflateInit() or
+ deflateInit2(), and after deflateSetHeader(), if used. This would be used
+ to allocate an output buffer for deflation in a single pass, and so would be
+ called before deflate().
+*/
+
+ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm,
+ int bits,
+ int value));
+/*
+ deflatePrime() inserts bits in the deflate output stream. The intent
+ is that this function is used to start off the deflate output with the bits
+ leftover from a previous deflate stream when appending to it. As such, this
+ function can only be used for raw deflate, and must be used before the first
+ deflate() call after a deflateInit2() or deflateReset(). bits must be less
+ than or equal to 16, and that many of the least significant bits of value
+ will be inserted in the output.
+
+ deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent.
+*/
+
+ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm,
+ gz_headerp head));
+/*
+ deflateSetHeader() provides gzip header information for when a gzip
+ stream is requested by deflateInit2(). deflateSetHeader() may be called
+ after deflateInit2() or deflateReset() and before the first call of
+ deflate(). The text, time, os, extra field, name, and comment information
+ in the provided gz_header structure are written to the gzip header (xflag is
+ ignored -- the extra flags are set according to the compression level). The
+ caller must assure that, if not Z_NULL, name and comment are terminated with
+ a zero byte, and that if extra is not Z_NULL, that extra_len bytes are
+ available there. If hcrc is true, a gzip header crc is included. Note that
+ the current versions of the command-line version of gzip (up through version
+ 1.3.x) do not support header crc's, and will report that it is a "multi-part
+ gzip file" and give up.
+
+ If deflateSetHeader is not used, the default gzip header has text false,
+ the time set to zero, and os set to 255, with no extra, name, or comment
+ fields. The gzip header is returned to the default state by deflateReset().
+
+ deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent.
+*/
+
+/*
+ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
+ int windowBits));
+
+ This is another version of inflateInit with an extra parameter. The
+ fields next_in, avail_in, zalloc, zfree and opaque must be initialized
+ before by the caller.
+
+ The windowBits parameter is the base two logarithm of the maximum window
+ size (the size of the history buffer). It should be in the range 8..15 for
+ this version of the library. The default value is 15 if inflateInit is used
+ instead. windowBits must be greater than or equal to the windowBits value
+ provided to deflateInit2() while compressing, or it must be equal to 15 if
+ deflateInit2() was not used. If a compressed stream with a larger window
+ size is given as input, inflate() will return with the error code
+ Z_DATA_ERROR instead of trying to allocate a larger window.
+
+ windowBits can also be zero to request that inflate use the window size in
+ the zlib header of the compressed stream.
+
+ windowBits can also be -8..-15 for raw inflate. In this case, -windowBits
+ determines the window size. inflate() will then process raw deflate data,
+ not looking for a zlib or gzip header, not generating a check value, and not
+ looking for any check values for comparison at the end of the stream. This
+ is for use with other formats that use the deflate compressed data format
+ such as zip. Those formats provide their own check values. If a custom
+ format is developed using the raw deflate format for compressed data, it is
+ recommended that a check value such as an adler32 or a crc32 be applied to
+ the uncompressed data as is done in the zlib, gzip, and zip formats. For
+ most applications, the zlib format should be used as is. Note that comments
+ above on the use in deflateInit2() applies to the magnitude of windowBits.
+
+ windowBits can also be greater than 15 for optional gzip decoding. Add
+ 32 to windowBits to enable zlib and gzip decoding with automatic header
+ detection, or add 16 to decode only the gzip format (the zlib format will
+ return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is a
+ crc32 instead of an adler32.
+
+ inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
+ version assumed by the caller, or Z_STREAM_ERROR if the parameters are
+ invalid, such as a null pointer to the structure. msg is set to null if
+ there is no error message. inflateInit2 does not perform any decompression
+ apart from possibly reading the zlib header if present: actual decompression
+ will be done by inflate(). (So next_in and avail_in may be modified, but
+ next_out and avail_out are unused and unchanged.) The current implementation
+ of inflateInit2() does not process any header information -- that is
+ deferred until inflate() is called.
+*/
+
+ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
+ const Bytef *dictionary,
+ uInt dictLength));
+/*
+ Initializes the decompression dictionary from the given uncompressed byte
+ sequence. This function must be called immediately after a call of inflate,
+ if that call returned Z_NEED_DICT. The dictionary chosen by the compressor
+ can be determined from the adler32 value returned by that call of inflate.
+ The compressor and decompressor must use exactly the same dictionary (see
+ deflateSetDictionary). For raw inflate, this function can be called
+ immediately after inflateInit2() or inflateReset() and before any call of
+ inflate() to set the dictionary. The application must insure that the
+ dictionary that was used for compression is provided.
+
+ inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
+ parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is
+ inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
+ expected one (incorrect adler32 value). inflateSetDictionary does not
+ perform any decompression: this will be done by subsequent calls of
+ inflate().
+*/
+
+ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
+/*
+ Skips invalid compressed data until a full flush point (see above the
+ description of deflate with Z_FULL_FLUSH) can be found, or until all
+ available input is skipped. No output is provided.
+
+ inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR
+ if no more input was provided, Z_DATA_ERROR if no flush point has been
+ found, or Z_STREAM_ERROR if the stream structure was inconsistent. In the
+ success case, the application may save the current current value of total_in
+ which indicates where valid compressed data was found. In the error case,
+ the application may repeatedly call inflateSync, providing more input each
+ time, until success or end of the input data.
+*/
+
+ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest,
+ z_streamp source));
+/*
+ Sets the destination stream as a complete copy of the source stream.
+
+ This function can be useful when randomly accessing a large stream. The
+ first pass through the stream can periodically record the inflate state,
+ allowing restarting inflate at those points when randomly accessing the
+ stream.
+
+ inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
+ (such as zalloc being Z_NULL). msg is left unchanged in both source and
+ destination.
+*/
+
+ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm));
+/*
+ This function is equivalent to inflateEnd followed by inflateInit,
+ but does not free and reallocate all the internal decompression state. The
+ stream will keep attributes that may have been set by inflateInit2.
+
+ inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent (such as zalloc or state being Z_NULL).
+*/
+
+ZEXTERN int ZEXPORT inflateReset2 OF((z_streamp strm,
+ int windowBits));
+/*
+ This function is the same as inflateReset, but it also permits changing
+ the wrap and window size requests. The windowBits parameter is interpreted
+ the same as it is for inflateInit2.
+
+ inflateReset2 returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent (such as zalloc or state being Z_NULL), or if
+ the windowBits parameter is invalid.
+*/
+
+ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm,
+ int bits,
+ int value));
+/*
+ This function inserts bits in the inflate input stream. The intent is
+ that this function is used to start inflating at a bit position in the
+ middle of a byte. The provided bits will be used before any bytes are used
+ from next_in. This function should only be used with raw inflate, and
+ should be used before the first inflate() call after inflateInit2() or
+ inflateReset(). bits must be less than or equal to 16, and that many of the
+ least significant bits of value will be inserted in the input.
+
+ If bits is negative, then the input stream bit buffer is emptied. Then
+ inflatePrime() can be called again to put bits in the buffer. This is used
+ to clear out bits leftover after feeding inflate a block description prior
+ to feeding inflate codes.
+
+ inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent.
+*/
+
+ZEXTERN long ZEXPORT inflateMark OF((z_streamp strm));
+/*
+ This function returns two values, one in the lower 16 bits of the return
+ value, and the other in the remaining upper bits, obtained by shifting the
+ return value down 16 bits. If the upper value is -1 and the lower value is
+ zero, then inflate() is currently decoding information outside of a block.
+ If the upper value is -1 and the lower value is non-zero, then inflate is in
+ the middle of a stored block, with the lower value equaling the number of
+ bytes from the input remaining to copy. If the upper value is not -1, then
+ it is the number of bits back from the current bit position in the input of
+ the code (literal or length/distance pair) currently being processed. In
+ that case the lower value is the number of bytes already emitted for that
+ code.
+
+ A code is being processed if inflate is waiting for more input to complete
+ decoding of the code, or if it has completed decoding but is waiting for
+ more output space to write the literal or match data.
+
+ inflateMark() is used to mark locations in the input data for random
+ access, which may be at bit positions, and to note those cases where the
+ output of a code may span boundaries of random access blocks. The current
+ location in the input stream can be determined from avail_in and data_type
+ as noted in the description for the Z_BLOCK flush parameter for inflate.
+
+ inflateMark returns the value noted above or -1 << 16 if the provided
+ source stream state was inconsistent.
+*/
+
+ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm,
+ gz_headerp head));
+/*
+ inflateGetHeader() requests that gzip header information be stored in the
+ provided gz_header structure. inflateGetHeader() may be called after
+ inflateInit2() or inflateReset(), and before the first call of inflate().
+ As inflate() processes the gzip stream, head->done is zero until the header
+ is completed, at which time head->done is set to one. If a zlib stream is
+ being decoded, then head->done is set to -1 to indicate that there will be
+ no gzip header information forthcoming. Note that Z_BLOCK or Z_TREES can be
+ used to force inflate() to return immediately after header processing is
+ complete and before any actual data is decompressed.
+
+ The text, time, xflags, and os fields are filled in with the gzip header
+ contents. hcrc is set to true if there is a header CRC. (The header CRC
+ was valid if done is set to one.) If extra is not Z_NULL, then extra_max
+ contains the maximum number of bytes to write to extra. Once done is true,
+ extra_len contains the actual extra field length, and extra contains the
+ extra field, or that field truncated if extra_max is less than extra_len.
+ If name is not Z_NULL, then up to name_max characters are written there,
+ terminated with a zero unless the length is greater than name_max. If
+ comment is not Z_NULL, then up to comm_max characters are written there,
+ terminated with a zero unless the length is greater than comm_max. When any
+ of extra, name, or comment are not Z_NULL and the respective field is not
+ present in the header, then that field is set to Z_NULL to signal its
+ absence. This allows the use of deflateSetHeader() with the returned
+ structure to duplicate the header. However if those fields are set to
+ allocated memory, then the application will need to save those pointers
+ elsewhere so that they can be eventually freed.
+
+ If inflateGetHeader is not used, then the header information is simply
+ discarded. The header is always checked for validity, including the header
+ CRC if present. inflateReset() will reset the process to discard the header
+ information. The application would need to call inflateGetHeader() again to
+ retrieve the header from the next gzip stream.
+
+ inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent.
+*/
+
+/*
+ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits,
+ unsigned char FAR *window));
+
+ Initialize the internal stream state for decompression using inflateBack()
+ calls. The fields zalloc, zfree and opaque in strm must be initialized
+ before the call. If zalloc and zfree are Z_NULL, then the default library-
+ derived memory allocation routines are used. windowBits is the base two
+ logarithm of the window size, in the range 8..15. window is a caller
+ supplied buffer of that size. Except for special applications where it is
+ assured that deflate was used with small window sizes, windowBits must be 15
+ and a 32K byte window must be supplied to be able to decompress general
+ deflate streams.
+
+ See inflateBack() for the usage of these routines.
+
+ inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of
+ the paramaters are invalid, Z_MEM_ERROR if the internal state could not be
+ allocated, or Z_VERSION_ERROR if the version of the library does not match
+ the version of the header file.
+*/
+
+typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *));
+typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned));
+
+ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm,
+ in_func in, void FAR *in_desc,
+ out_func out, void FAR *out_desc));
+/*
+ inflateBack() does a raw inflate with a single call using a call-back
+ interface for input and output. This is more efficient than inflate() for
+ file i/o applications in that it avoids copying between the output and the
+ sliding window by simply making the window itself the output buffer. This
+ function trusts the application to not change the output buffer passed by
+ the output function, at least until inflateBack() returns.
+
+ inflateBackInit() must be called first to allocate the internal state
+ and to initialize the state with the user-provided window buffer.
+ inflateBack() may then be used multiple times to inflate a complete, raw
+ deflate stream with each call. inflateBackEnd() is then called to free the
+ allocated state.
+
+ A raw deflate stream is one with no zlib or gzip header or trailer.
+ This routine would normally be used in a utility that reads zip or gzip
+ files and writes out uncompressed files. The utility would decode the
+ header and process the trailer on its own, hence this routine expects only
+ the raw deflate stream to decompress. This is different from the normal
+ behavior of inflate(), which expects either a zlib or gzip header and
+ trailer around the deflate stream.
+
+ inflateBack() uses two subroutines supplied by the caller that are then
+ called by inflateBack() for input and output. inflateBack() calls those
+ routines until it reads a complete deflate stream and writes out all of the
+ uncompressed data, or until it encounters an error. The function's
+ parameters and return types are defined above in the in_func and out_func
+ typedefs. inflateBack() will call in(in_desc, &buf) which should return the
+ number of bytes of provided input, and a pointer to that input in buf. If
+ there is no input available, in() must return zero--buf is ignored in that
+ case--and inflateBack() will return a buffer error. inflateBack() will call
+ out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out()
+ should return zero on success, or non-zero on failure. If out() returns
+ non-zero, inflateBack() will return with an error. Neither in() nor out()
+ are permitted to change the contents of the window provided to
+ inflateBackInit(), which is also the buffer that out() uses to write from.
+ The length written by out() will be at most the window size. Any non-zero
+ amount of input may be provided by in().
+
+ For convenience, inflateBack() can be provided input on the first call by
+ setting strm->next_in and strm->avail_in. If that input is exhausted, then
+ in() will be called. Therefore strm->next_in must be initialized before
+ calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called
+ immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in
+ must also be initialized, and then if strm->avail_in is not zero, input will
+ initially be taken from strm->next_in[0 .. strm->avail_in - 1].
+
+ The in_desc and out_desc parameters of inflateBack() is passed as the
+ first parameter of in() and out() respectively when they are called. These
+ descriptors can be optionally used to pass any information that the caller-
+ supplied in() and out() functions need to do their job.
+
+ On return, inflateBack() will set strm->next_in and strm->avail_in to
+ pass back any unused input that was provided by the last in() call. The
+ return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR
+ if in() or out() returned an error, Z_DATA_ERROR if there was a format error
+ in the deflate stream (in which case strm->msg is set to indicate the nature
+ of the error), or Z_STREAM_ERROR if the stream was not properly initialized.
+ In the case of Z_BUF_ERROR, an input or output error can be distinguished
+ using strm->next_in which will be Z_NULL only if in() returned an error. If
+ strm->next_in is not Z_NULL, then the Z_BUF_ERROR was due to out() returning
+ non-zero. (in() will always be called before out(), so strm->next_in is
+ assured to be defined if out() returns non-zero.) Note that inflateBack()
+ cannot return Z_OK.
+*/
+
+ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm));
+/*
+ All memory allocated by inflateBackInit() is freed.
+
+ inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream
+ state was inconsistent.
+*/
+
+ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void));
+/* Return flags indicating compile-time options.
+
+ Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other:
+ 1.0: size of uInt
+ 3.2: size of uLong
+ 5.4: size of voidpf (pointer)
+ 7.6: size of z_off_t
+
+ Compiler, assembler, and debug options:
+ 8: DEBUG
+ 9: ASMV or ASMINF -- use ASM code
+ 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention
+ 11: 0 (reserved)
+
+ One-time table building (smaller code, but not thread-safe if true):
+ 12: BUILDFIXED -- build static block decoding tables when needed
+ 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed
+ 14,15: 0 (reserved)
+
+ Library content (indicates missing functionality):
+ 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking
+ deflate code when not needed)
+ 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect
+ and decode gzip streams (to avoid linking crc code)
+ 18-19: 0 (reserved)
+
+ Operation variations (changes in library functionality):
+ 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate
+ 21: FASTEST -- deflate algorithm with only one, lowest compression level
+ 22,23: 0 (reserved)
+
+ The sprintf variant used by gzprintf (zero is best):
+ 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format
+ 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure!
+ 26: 0 = returns value, 1 = void -- 1 means inferred string length returned
+
+ Remainder:
+ 27-31: 0 (reserved)
+ */
+
+
+ /* utility functions */
+
+/*
+ The following utility functions are implemented on top of the basic
+ stream-oriented functions. To simplify the interface, some default options
+ are assumed (compression level and memory usage, standard memory allocation
+ functions). The source code of these utility functions can be modified if
+ you need special options.
+*/
+
+ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong sourceLen));
+/*
+ Compresses the source buffer into the destination buffer. sourceLen is
+ the byte length of the source buffer. Upon entry, destLen is the total size
+ of the destination buffer, which must be at least the value returned by
+ compressBound(sourceLen). Upon exit, destLen is the actual size of the
+ compressed buffer.
+
+ compress returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_BUF_ERROR if there was not enough room in the output
+ buffer.
+*/
+
+ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong sourceLen,
+ int level));
+/*
+ Compresses the source buffer into the destination buffer. The level
+ parameter has the same meaning as in deflateInit. sourceLen is the byte
+ length of the source buffer. Upon entry, destLen is the total size of the
+ destination buffer, which must be at least the value returned by
+ compressBound(sourceLen). Upon exit, destLen is the actual size of the
+ compressed buffer.
+
+ compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_BUF_ERROR if there was not enough room in the output buffer,
+ Z_STREAM_ERROR if the level parameter is invalid.
+*/
+
+ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen));
+/*
+ compressBound() returns an upper bound on the compressed size after
+ compress() or compress2() on sourceLen bytes. It would be used before a
+ compress() or compress2() call to allocate the destination buffer.
+*/
+
+ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong sourceLen));
+/*
+ Decompresses the source buffer into the destination buffer. sourceLen is
+ the byte length of the source buffer. Upon entry, destLen is the total size
+ of the destination buffer, which must be large enough to hold the entire
+ uncompressed data. (The size of the uncompressed data must have been saved
+ previously by the compressor and transmitted to the decompressor by some
+ mechanism outside the scope of this compression library.) Upon exit, destLen
+ is the actual size of the uncompressed buffer.
+
+ uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_BUF_ERROR if there was not enough room in the output
+ buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete.
+*/
+
+
+ /* gzip file access functions */
+
+/*
+ This library supports reading and writing files in gzip (.gz) format with
+ an interface similar to that of stdio, using the functions that start with
+ "gz". The gzip format is different from the zlib format. gzip is a gzip
+ wrapper, documented in RFC 1952, wrapped around a deflate stream.
+*/
+
+typedef voidp gzFile; /* opaque gzip file descriptor */
+
+/*
+ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
+
+ Opens a gzip (.gz) file for reading or writing. The mode parameter is as
+ in fopen ("rb" or "wb") but can also include a compression level ("wb9") or
+ a strategy: 'f' for filtered data as in "wb6f", 'h' for Huffman-only
+ compression as in "wb1h", 'R' for run-length encoding as in "wb1R", or 'F'
+ for fixed code compression as in "wb9F". (See the description of
+ deflateInit2 for more information about the strategy parameter.) Also "a"
+ can be used instead of "w" to request that the gzip stream that will be
+ written be appended to the file. "+" will result in an error, since reading
+ and writing to the same gzip file is not supported.
+
+ gzopen can be used to read a file which is not in gzip format; in this
+ case gzread will directly read from the file without decompression.
+
+ gzopen returns NULL if the file could not be opened, if there was
+ insufficient memory to allocate the gzFile state, or if an invalid mode was
+ specified (an 'r', 'w', or 'a' was not provided, or '+' was provided).
+ errno can be checked to determine if the reason gzopen failed was that the
+ file could not be opened.
+*/
+
+ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode));
+/*
+ gzdopen associates a gzFile with the file descriptor fd. File descriptors
+ are obtained from calls like open, dup, creat, pipe or fileno (if the file
+ has been previously opened with fopen). The mode parameter is as in gzopen.
+
+ The next call of gzclose on the returned gzFile will also close the file
+ descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor
+ fd. If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd,
+ mode);. The duplicated descriptor should be saved to avoid a leak, since
+ gzdopen does not close fd if it fails.
+
+ gzdopen returns NULL if there was insufficient memory to allocate the
+ gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not
+ provided, or '+' was provided), or if fd is -1. The file descriptor is not
+ used until the next gz* read, write, seek, or close operation, so gzdopen
+ will not detect if fd is invalid (unless fd is -1).
+*/
+
+ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size));
+/*
+ Set the internal buffer size used by this library's functions. The
+ default buffer size is 8192 bytes. This function must be called after
+ gzopen() or gzdopen(), and before any other calls that read or write the
+ file. The buffer memory allocation is always deferred to the first read or
+ write. Two buffers are allocated, either both of the specified size when
+ writing, or one of the specified size and the other twice that size when
+ reading. A larger buffer size of, for example, 64K or 128K bytes will
+ noticeably increase the speed of decompression (reading).
+
+ The new buffer size also affects the maximum length for gzprintf().
+
+ gzbuffer() returns 0 on success, or -1 on failure, such as being called
+ too late.
+*/
+
+ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
+/*
+ Dynamically update the compression level or strategy. See the description
+ of deflateInit2 for the meaning of these parameters.
+
+ gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not
+ opened for writing.
+*/
+
+ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
+/*
+ Reads the given number of uncompressed bytes from the compressed file. If
+ the input file was not in gzip format, gzread copies the given number of
+ bytes into the buffer.
+
+ After reaching the end of a gzip stream in the input, gzread will continue
+ to read, looking for another gzip stream, or failing that, reading the rest
+ of the input file directly without decompression. The entire input file
+ will be read if gzread is called until it returns less than the requested
+ len.
+
+ gzread returns the number of uncompressed bytes actually read, less than
+ len for end of file, or -1 for error.
+*/
+
+ZEXTERN int ZEXPORT gzwrite OF((gzFile file,
+ voidpc buf, unsigned len));
+/*
+ Writes the given number of uncompressed bytes into the compressed file.
+ gzwrite returns the number of uncompressed bytes written or 0 in case of
+ error.
+*/
+
+ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...));
+/*
+ Converts, formats, and writes the arguments to the compressed file under
+ control of the format string, as in fprintf. gzprintf returns the number of
+ uncompressed bytes actually written, or 0 in case of error. The number of
+ uncompressed bytes written is limited to 8191, or one less than the buffer
+ size given to gzbuffer(). The caller should assure that this limit is not
+ exceeded. If it is exceeded, then gzprintf() will return an error (0) with
+ nothing written. In this case, there may also be a buffer overflow with
+ unpredictable consequences, which is possible only if zlib was compiled with
+ the insecure functions sprintf() or vsprintf() because the secure snprintf()
+ or vsnprintf() functions were not available. This can be determined using
+ zlibCompileFlags().
+*/
+
+ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s));
+/*
+ Writes the given null-terminated string to the compressed file, excluding
+ the terminating null character.
+
+ gzputs returns the number of characters written, or -1 in case of error.
+*/
+
+ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len));
+/*
+ Reads bytes from the compressed file until len-1 characters are read, or a
+ newline character is read and transferred to buf, or an end-of-file
+ condition is encountered. If any characters are read or if len == 1, the
+ string is terminated with a null character. If no characters are read due
+ to an end-of-file or len < 1, then the buffer is left untouched.
+
+ gzgets returns buf which is a null-terminated string, or it returns NULL
+ for end-of-file or in case of error. If there was an error, the contents at
+ buf are indeterminate.
+*/
+
+ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c));
+/*
+ Writes c, converted to an unsigned char, into the compressed file. gzputc
+ returns the value that was written, or -1 in case of error.
+*/
+
+ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
+/*
+ Reads one byte from the compressed file. gzgetc returns this byte or -1
+ in case of end of file or error.
+*/
+
+ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file));
+/*
+ Push one character back onto the stream to be read as the first character
+ on the next read. At least one character of push-back is allowed.
+ gzungetc() returns the character pushed, or -1 on failure. gzungetc() will
+ fail if c is -1, and may fail if a character has been pushed but not read
+ yet. If gzungetc is used immediately after gzopen or gzdopen, at least the
+ output buffer size of pushed characters is allowed. (See gzbuffer above.)
+ The pushed character will be discarded if the stream is repositioned with
+ gzseek() or gzrewind().
+*/
+
+ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush));
+/*
+ Flushes all pending output into the compressed file. The parameter flush
+ is as in the deflate() function. The return value is the zlib error number
+ (see function gzerror below). gzflush is only permitted when writing.
+
+ If the flush parameter is Z_FINISH, the remaining data is written and the
+ gzip stream is completed in the output. If gzwrite() is called again, a new
+ gzip stream will be started in the output. gzread() is able to read such
+ concatented gzip streams.
+
+ gzflush should be called only when strictly necessary because it will
+ degrade compression if called too often.
+*/
+
+/*
+ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file,
+ z_off_t offset, int whence));
+
+ Sets the starting position for the next gzread or gzwrite on the given
+ compressed file. The offset represents a number of bytes in the
+ uncompressed data stream. The whence parameter is defined as in lseek(2);
+ the value SEEK_END is not supported.
+
+ If the file is opened for reading, this function is emulated but can be
+ extremely slow. If the file is opened for writing, only forward seeks are
+ supported; gzseek then compresses a sequence of zeroes up to the new
+ starting position.
+
+ gzseek returns the resulting offset location as measured in bytes from
+ the beginning of the uncompressed stream, or -1 in case of error, in
+ particular if the file is opened for writing and the new starting position
+ would be before the current position.
+*/
+
+ZEXTERN int ZEXPORT gzrewind OF((gzFile file));
+/*
+ Rewinds the given file. This function is supported only for reading.
+
+ gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET)
+*/
+
+/*
+ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file));
+
+ Returns the starting position for the next gzread or gzwrite on the given
+ compressed file. This position represents a number of bytes in the
+ uncompressed data stream, and is zero when starting, even if appending or
+ reading a gzip stream from the middle of a file using gzdopen().
+
+ gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR)
+*/
+
+/*
+ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile file));
+
+ Returns the current offset in the file being read or written. This offset
+ includes the count of bytes that precede the gzip stream, for example when
+ appending or when using gzdopen() for reading. When reading, the offset
+ does not include as yet unused buffered input. This information can be used
+ for a progress indicator. On error, gzoffset() returns -1.
+*/
+
+ZEXTERN int ZEXPORT gzeof OF((gzFile file));
+/*
+ Returns true (1) if the end-of-file indicator has been set while reading,
+ false (0) otherwise. Note that the end-of-file indicator is set only if the
+ read tried to go past the end of the input, but came up short. Therefore,
+ just like feof(), gzeof() may return false even if there is no more data to
+ read, in the event that the last read request was for the exact number of
+ bytes remaining in the input file. This will happen if the input file size
+ is an exact multiple of the buffer size.
+
+ If gzeof() returns true, then the read functions will return no more data,
+ unless the end-of-file indicator is reset by gzclearerr() and the input file
+ has grown since the previous end of file was detected.
+*/
+
+ZEXTERN int ZEXPORT gzdirect OF((gzFile file));
+/*
+ Returns true (1) if file is being copied directly while reading, or false
+ (0) if file is a gzip stream being decompressed. This state can change from
+ false to true while reading the input file if the end of a gzip stream is
+ reached, but is followed by data that is not another gzip stream.
+
+ If the input file is empty, gzdirect() will return true, since the input
+ does not contain a gzip stream.
+
+ If gzdirect() is used immediately after gzopen() or gzdopen() it will
+ cause buffers to be allocated to allow reading the file to determine if it
+ is a gzip file. Therefore if gzbuffer() is used, it should be called before
+ gzdirect().
+*/
+
+ZEXTERN int ZEXPORT gzclose OF((gzFile file));
+/*
+ Flushes all pending output if necessary, closes the compressed file and
+ deallocates the (de)compression state. Note that once file is closed, you
+ cannot call gzerror with file, since its structures have been deallocated.
+ gzclose must not be called more than once on the same file, just as free
+ must not be called more than once on the same allocation.
+
+ gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a
+ file operation error, or Z_OK on success.
+*/
+
+ZEXTERN int ZEXPORT gzclose_r OF((gzFile file));
+ZEXTERN int ZEXPORT gzclose_w OF((gzFile file));
+/*
+ Same as gzclose(), but gzclose_r() is only for use when reading, and
+ gzclose_w() is only for use when writing or appending. The advantage to
+ using these instead of gzclose() is that they avoid linking in zlib
+ compression or decompression code that is not used when only reading or only
+ writing respectively. If gzclose() is used, then both compression and
+ decompression code will be included the application when linking to a static
+ zlib library.
+*/
+
+ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum));
+/*
+ Returns the error message for the last error which occurred on the given
+ compressed file. errnum is set to zlib error number. If an error occurred
+ in the file system and not in the compression library, errnum is set to
+ Z_ERRNO and the application may consult errno to get the exact error code.
+
+ The application must not modify the returned string. Future calls to
+ this function may invalidate the previously returned string. If file is
+ closed, then the string previously returned by gzerror will no longer be
+ available.
+
+ gzerror() should be used to distinguish errors from end-of-file for those
+ functions above that do not distinguish those cases in their return values.
+*/
+
+ZEXTERN void ZEXPORT gzclearerr OF((gzFile file));
+/*
+ Clears the error and end-of-file flags for file. This is analogous to the
+ clearerr() function in stdio. This is useful for continuing to read a gzip
+ file that is being written concurrently.
+*/
+
+
+ /* checksum functions */
+
+/*
+ These functions are not related to compression but are exported
+ anyway because they might be useful in applications using the compression
+ library.
+*/
+
+ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
+/*
+ Update a running Adler-32 checksum with the bytes buf[0..len-1] and
+ return the updated checksum. If buf is Z_NULL, this function returns the
+ required initial value for the checksum.
+
+ An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
+ much faster.
+
+ Usage example:
+
+ uLong adler = adler32(0L, Z_NULL, 0);
+
+ while (read_buffer(buffer, length) != EOF) {
+ adler = adler32(adler, buffer, length);
+ }
+ if (adler != original_adler) error();
+*/
+
+/*
+ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2,
+ z_off_t len2));
+
+ Combine two Adler-32 checksums into one. For two sequences of bytes, seq1
+ and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for
+ each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of
+ seq1 and seq2 concatenated, requiring only adler1, adler2, and len2.
+*/
+
+ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
+/*
+ Update a running CRC-32 with the bytes buf[0..len-1] and return the
+ updated CRC-32. If buf is Z_NULL, this function returns the required
+ initial value for the for the crc. Pre- and post-conditioning (one's
+ complement) is performed within this function so it shouldn't be done by the
+ application.
+
+ Usage example:
+
+ uLong crc = crc32(0L, Z_NULL, 0);
+
+ while (read_buffer(buffer, length) != EOF) {
+ crc = crc32(crc, buffer, length);
+ }
+ if (crc != original_crc) error();
+*/
+
+/*
+ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2));
+
+ Combine two CRC-32 check values into one. For two sequences of bytes,
+ seq1 and seq2 with lengths len1 and len2, CRC-32 check values were
+ calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32
+ check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and
+ len2.
+*/
+
+
+ /* various hacks, don't look :) */
+
+/* deflateInit and inflateInit are macros to allow checking the zlib version
+ * and the compiler's view of z_stream:
+ */
+ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level,
+ const char *version, int stream_size));
+ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm,
+ const char *version, int stream_size));
+ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method,
+ int windowBits, int memLevel,
+ int strategy, const char *version,
+ int stream_size));
+ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits,
+ const char *version, int stream_size));
+ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
+ unsigned char FAR *window,
+ const char *version,
+ int stream_size));
+#define deflateInit(strm, level) \
+ deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream))
+#define inflateInit(strm) \
+ inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream))
+#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
+ deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
+ (strategy), ZLIB_VERSION, sizeof(z_stream))
+#define inflateInit2(strm, windowBits) \
+ inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream))
+#define inflateBackInit(strm, windowBits, window) \
+ inflateBackInit_((strm), (windowBits), (window), \
+ ZLIB_VERSION, sizeof(z_stream))
+
+/* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or
+ * change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if
+ * both are true, the application gets the *64 functions, and the regular
+ * functions are changed to 64 bits) -- in case these are set on systems
+ * without large file support, _LFS64_LARGEFILE must also be true
+ */
+#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0
+ ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
+ ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int));
+ ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile));
+ ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile));
+ ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off64_t));
+ ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t));
+#endif
+
+#if !defined(ZLIB_INTERNAL) && _FILE_OFFSET_BITS-0 == 64 && _LFS64_LARGEFILE-0
+# define gzopen gzopen64
+# define gzseek gzseek64
+# define gztell gztell64
+# define gzoffset gzoffset64
+# define adler32_combine adler32_combine64
+# define crc32_combine crc32_combine64
+# ifdef _LARGEFILE64_SOURCE
+ ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
+ ZEXTERN z_off_t ZEXPORT gzseek64 OF((gzFile, z_off_t, int));
+ ZEXTERN z_off_t ZEXPORT gztell64 OF((gzFile));
+ ZEXTERN z_off_t ZEXPORT gzoffset64 OF((gzFile));
+ ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t));
+ ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t));
+# endif
+#else
+ ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *));
+ ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile, z_off_t, int));
+ ZEXTERN z_off_t ZEXPORT gztell OF((gzFile));
+ ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile));
+ ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t));
+ ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t));
+#endif
+
+/* hack for buggy compilers */
+#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL)
+ struct internal_state {int dummy;};
+#endif
+
+/* undocumented functions */
+ZEXTERN const char * ZEXPORT zError OF((int));
+ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp));
+ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void));
+ZEXTERN int ZEXPORT inflateUndermine OF((z_streamp, int));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ZLIB_H */
diff --git a/lib-x86-32/libFLAC.a b/lib-x86-32/libFLAC.a
new file mode 100644
index 00000000..f9329aee
--- /dev/null
+++ b/lib-x86-32/libFLAC.a
Binary files differ
diff --git a/lib-x86-32/libavcodec.a b/lib-x86-32/libavcodec.a
new file mode 100644
index 00000000..6e429f4a
--- /dev/null
+++ b/lib-x86-32/libavcodec.a
Binary files differ
diff --git a/lib-x86-32/libavcore.a b/lib-x86-32/libavcore.a
new file mode 100644
index 00000000..650b57ed
--- /dev/null
+++ b/lib-x86-32/libavcore.a
Binary files differ
diff --git a/lib-x86-32/libavformat.a b/lib-x86-32/libavformat.a
new file mode 100644
index 00000000..a7adafee
--- /dev/null
+++ b/lib-x86-32/libavformat.a
Binary files differ
diff --git a/lib-x86-32/libavutil.a b/lib-x86-32/libavutil.a
new file mode 100644
index 00000000..e53d807c
--- /dev/null
+++ b/lib-x86-32/libavutil.a
Binary files differ
diff --git a/lib-x86-32/libcddb.a b/lib-x86-32/libcddb.a
new file mode 100644
index 00000000..fed07ff6
--- /dev/null
+++ b/lib-x86-32/libcddb.a
Binary files differ
diff --git a/lib-x86-32/libcdio.a b/lib-x86-32/libcdio.a
new file mode 100644
index 00000000..c491a18e
--- /dev/null
+++ b/lib-x86-32/libcdio.a
Binary files differ
diff --git a/lib-x86-32/libcurl.a b/lib-x86-32/libcurl.a
new file mode 100644
index 00000000..94a7d5a7
--- /dev/null
+++ b/lib-x86-32/libcurl.a
Binary files differ
diff --git a/lib-x86-32/libdbus-1.a b/lib-x86-32/libdbus-1.a
new file mode 100644
index 00000000..956ae037
--- /dev/null
+++ b/lib-x86-32/libdbus-1.a
Binary files differ
diff --git a/lib-x86-32/libexpat.a b/lib-x86-32/libexpat.a
new file mode 100644
index 00000000..7ce1fecc
--- /dev/null
+++ b/lib-x86-32/libexpat.a
Binary files differ
diff --git a/lib-x86-32/libfaad.a b/lib-x86-32/libfaad.a
new file mode 100644
index 00000000..b1bbf9ab
--- /dev/null
+++ b/lib-x86-32/libfaad.a
Binary files differ
diff --git a/lib-x86-32/libidn.a b/lib-x86-32/libidn.a
new file mode 100644
index 00000000..a0829f79
--- /dev/null
+++ b/lib-x86-32/libidn.a
Binary files differ
diff --git a/lib-x86-32/libiso9660.a b/lib-x86-32/libiso9660.a
new file mode 100644
index 00000000..3259699e
--- /dev/null
+++ b/lib-x86-32/libiso9660.a
Binary files differ
diff --git a/lib-x86-32/libmad.a b/lib-x86-32/libmad.a
new file mode 100644
index 00000000..b9b86f27
--- /dev/null
+++ b/lib-x86-32/libmad.a
Binary files differ
diff --git a/lib-x86-32/libogg.a b/lib-x86-32/libogg.a
new file mode 100644
index 00000000..99bf4df0
--- /dev/null
+++ b/lib-x86-32/libogg.a
Binary files differ
diff --git a/lib-x86-32/libopencore-amrnb.a b/lib-x86-32/libopencore-amrnb.a
new file mode 100644
index 00000000..7ce4236c
--- /dev/null
+++ b/lib-x86-32/libopencore-amrnb.a
Binary files differ
diff --git a/lib-x86-32/libopencore-amrwb.a b/lib-x86-32/libopencore-amrwb.a
new file mode 100644
index 00000000..64cef81b
--- /dev/null
+++ b/lib-x86-32/libopencore-amrwb.a
Binary files differ
diff --git a/lib-x86-32/libsamplerate.a b/lib-x86-32/libsamplerate.a
new file mode 100644
index 00000000..9a1e284c
--- /dev/null
+++ b/lib-x86-32/libsamplerate.a
Binary files differ
diff --git a/lib-x86-32/libsndfile.a b/lib-x86-32/libsndfile.a
new file mode 100644
index 00000000..855328d2
--- /dev/null
+++ b/lib-x86-32/libsndfile.a
Binary files differ
diff --git a/lib-x86-32/libudf.a b/lib-x86-32/libudf.a
new file mode 100644
index 00000000..f76f210e
--- /dev/null
+++ b/lib-x86-32/libudf.a
Binary files differ
diff --git a/lib-x86-32/libvorbis.a b/lib-x86-32/libvorbis.a
new file mode 100644
index 00000000..5b54022a
--- /dev/null
+++ b/lib-x86-32/libvorbis.a
Binary files differ
diff --git a/lib-x86-32/libvorbisenc.a b/lib-x86-32/libvorbisenc.a
new file mode 100644
index 00000000..c4ef087e
--- /dev/null
+++ b/lib-x86-32/libvorbisenc.a
Binary files differ
diff --git a/lib-x86-32/libvorbisfile.a b/lib-x86-32/libvorbisfile.a
new file mode 100644
index 00000000..70315863
--- /dev/null
+++ b/lib-x86-32/libvorbisfile.a
Binary files differ
diff --git a/lib-x86-32/libwavpack.a b/lib-x86-32/libwavpack.a
new file mode 100644
index 00000000..a18683f0
--- /dev/null
+++ b/lib-x86-32/libwavpack.a
Binary files differ
diff --git a/lib-x86-32/libz.a b/lib-x86-32/libz.a
new file mode 100644
index 00000000..00810f6e
--- /dev/null
+++ b/lib-x86-32/libz.a
Binary files differ
diff --git a/main.c b/main.c
index c69eb616..d90eeee0 100644
--- a/main.c
+++ b/main.c
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -47,17 +47,13 @@
#include <unistd.h>
#include "gettext.h"
#include "playlist.h"
-#include "playback.h"
#include "threading.h"
#include "messagepump.h"
#include "streamer.h"
#include "conf.h"
#include "volume.h"
#include "plugins.h"
-
-#ifndef PATH_MAX
-#define PATH_MAX 1024 /* max # of characters in a path name */
-#endif
+#include "common.h"
#ifndef PREFIX
#error PREFIX must be defined
@@ -71,8 +67,13 @@
#define trace(fmt,...)
// some common global variables
-char confdir[1024]; // $HOME/.config
-char dbconfdir[1024]; // $HOME/.config/deadbeef
+char sys_install_path[PATH_MAX]; // see deadbeef->get_prefix
+char confdir[PATH_MAX]; // $HOME/.config
+char dbconfdir[PATH_MAX]; // $HOME/.config/deadbeef
+char dbinstalldir[PATH_MAX]; // see deadbeef->get_prefix
+char dbdocdir[PATH_MAX]; // see deadbeef->get_doc_dir
+char dbplugindir[PATH_MAX]; // see deadbeef->get_plugin_dir
+char dbpixmapdir[PATH_MAX]; // see deadbeef->get_pixmap_dir
// client-side commandline support
// -1 error, program must exit with error code -1
@@ -94,6 +95,7 @@ client_exec_command_line (const char *cmdline, int len) {
fprintf (stdout, _(" --play Start playback\n"));
fprintf (stdout, _(" --stop Stop playback\n"));
fprintf (stdout, _(" --pause Pause playback\n"));
+ fprintf (stdout, _(" --toggle-pause Toggle pause\n"));
fprintf (stdout, _(" --next Next song in playlist\n"));
fprintf (stdout, _(" --prev Previous song in playlist\n"));
fprintf (stdout, _(" --random Random song in playlist\n"));
@@ -106,7 +108,7 @@ client_exec_command_line (const char *cmdline, int len) {
return 1;
}
else if (!strcmp (parg, "--version")) {
- fprintf (stdout, "DeaDBeeF " VERSION " Copyright © 2009-2010 Alexey Yakovenko\n");
+ fprintf (stdout, "DeaDBeeF " VERSION " Copyright © 2009-2011 Alexey Yakovenko\n");
return 1;
}
parg += strlen (parg);
@@ -177,27 +179,31 @@ server_exec_command_line (const char *cmdline, int len, char *sendback, int sbsi
}
}
else if (!strcmp (parg, "--next")) {
- messagepump_push (M_NEXTSONG, 0, 0, 0);
+ messagepump_push (M_NEXT, 0, 0, 0);
return 0;
}
else if (!strcmp (parg, "--prev")) {
- messagepump_push (M_PREVSONG, 0, 0, 0);
+ messagepump_push (M_PREV, 0, 0, 0);
return 0;
}
else if (!strcmp (parg, "--play")) {
- messagepump_push (M_PLAYSONG, 0, 0, 0);
+ messagepump_push (M_PLAY_CURRENT, 0, 0, 0);
return 0;
}
else if (!strcmp (parg, "--stop")) {
- messagepump_push (M_STOPSONG, 0, 0, 0);
+ messagepump_push (M_STOP, 0, 0, 0);
return 0;
}
else if (!strcmp (parg, "--pause")) {
- messagepump_push (M_PAUSESONG, 0, 0, 0);
+ messagepump_push (M_PAUSE, 0, 0, 0);
+ return 0;
+ }
+ else if (!strcmp (parg, "--toggle-pause")) {
+ messagepump_push (M_TOGGLE_PAUSE, 0, 0, 0);
return 0;
}
else if (!strcmp (parg, "--random")) {
- messagepump_push (M_PLAYRANDOM, 0, 0, 0);
+ messagepump_push (M_PLAY_RANDOM, 0, 0, 0);
return 0;
}
else if (!strcmp (parg, "--queue")) {
@@ -214,7 +220,8 @@ server_exec_command_line (const char *cmdline, int len, char *sendback, int sbsi
}
if (parg < pend) {
if (conf_get_int ("cli_add_to_specific_playlist", 1)) {
- const char *str = conf_get_str ("cli_add_playlist_name", "Default");
+ char str[200];
+ conf_get_str ("cli_add_playlist_name", "Default", str, sizeof (str));
int idx = plt_find (str);
if (idx < 0) {
idx = plt_add (plt_get_count (), str);
@@ -224,12 +231,13 @@ server_exec_command_line (const char *cmdline, int len, char *sendback, int sbsi
}
}
// add files
- if (!queue && plt_get_curr () != -1) {
+ int curr_plt = plt_get_curr ();
+ if (!queue) {
pl_clear ();
pl_reset_cursor ();
}
if (parg < pend) {
- deadbeef->pl_add_files_begin ();
+ deadbeef->pl_add_files_begin (curr_plt);
}
while (parg < pend) {
char resolved[PATH_MAX];
@@ -249,9 +257,9 @@ server_exec_command_line (const char *cmdline, int len, char *sendback, int sbsi
parg++;
}
deadbeef->pl_add_files_end ();
- messagepump_push (M_PLAYLISTREFRESH, 0, 0, 0);
+ messagepump_push (M_PLAYLIST_REFRESH, 0, 0, 0);
if (!queue) {
- messagepump_push (M_PLAYSONG, 0, 1, 0);
+ messagepump_push (M_PLAY_CURRENT, 0, 1, 0);
return 2; // don't reload playlist at startup
}
}
@@ -350,21 +358,41 @@ server_update (void) {
return 0;
}
+static uintptr_t server_tid;
+static int server_terminate;
+
void
-player_mainloop (void) {
- for (;;) {
- static int srvupd_count = 0;
- if (--srvupd_count <= 0) {
- srvupd_count = 10;
+server_loop (void *ctx) {
+ fd_set rds;
+ int ret;
+ struct timeval timeout = {0, 0};
+
+ FD_ZERO(&rds);
+ while (!server_terminate) {
+ FD_SET(srv_socket, &rds);
+ timeout.tv_usec = 50000;
+ if ((ret = select(srv_socket + 1, &rds, NULL, NULL, &timeout)) < 0 && errno != EINTR) {
+ perror("select");
+ exit (-1);
+ }
+ if (ret > 0) {
if (server_update () < 0) {
messagepump_push (M_TERMINATE, 0, 0, 0);
}
}
+ }
+}
+
+void
+player_mainloop (void) {
+ for (;;) {
uint32_t msg;
uintptr_t ctx;
uint32_t p1;
uint32_t p2;
+ messagepump_wait ();
while (messagepump_pop(&msg, &ctx, &p1, &p2) != -1) {
+ DB_output_t *output = plug_get_output ();
switch (msg) {
case M_REINIT_SOUND:
plug_reinit_sound ();
@@ -372,9 +400,9 @@ player_mainloop (void) {
break;
case M_TERMINATE:
return;
- case M_PLAYSONG:
+ case M_PLAY_CURRENT:
if (p1) {
- p_stop ();
+ output->stop ();
pl_playqueue_clear ();
streamer_set_nextsong (0, 1);
}
@@ -382,49 +410,55 @@ player_mainloop (void) {
streamer_play_current_track ();
}
break;
- case M_PLAYSONGNUM:
- p_stop ();
+ case M_PLAY_NUM:
+ output->stop ();
pl_playqueue_clear ();
streamer_set_nextsong (p1, 1);
break;
- case M_STOPSONG:
+ case M_STOP:
streamer_set_nextsong (-2, 0);
break;
- case M_NEXTSONG:
- p_stop ();
+ case M_NEXT:
+ output->stop ();
streamer_move_to_nextsong (1);
break;
- case M_PREVSONG:
- p_stop ();
+ case M_PREV:
+ output->stop ();
streamer_move_to_prevsong ();
break;
- case M_PAUSESONG:
- if (p_get_state () == OUTPUT_STATE_PAUSED) {
- p_unpause ();
+ case M_PAUSE:
+ if (output->state () != OUTPUT_STATE_PAUSED) {
+ output->pause ();
+ plug_trigger_event_paused (1);
+ }
+ break;
+ case M_TOGGLE_PAUSE:
+ if (output->state () == OUTPUT_STATE_PAUSED) {
+ output->unpause ();
plug_trigger_event_paused (0);
}
else {
- p_pause ();
+ output->pause ();
plug_trigger_event_paused (1);
}
break;
- case M_PLAYRANDOM:
- p_stop ();
+ case M_PLAY_RANDOM:
+ output->stop ();
streamer_move_to_randomsong ();
break;
- case M_PLAYLISTREFRESH:
+ case M_PLAYLIST_REFRESH:
pl_save_current ();
plug_trigger_event_playlistchanged ();
break;
- case M_CONFIGCHANGED:
+ case M_CONFIG_CHANGED:
conf_save ();
streamer_configchanged ();
plug_trigger_event (DB_EV_CONFIGCHANGED, 0);
break;
}
}
- usleep(50000);
- plug_trigger_event (DB_EV_FRAMEUPDATE, 0);
+ //usleep(50000);
+ //plug_trigger_event (DB_EV_FRAMEUPDATE, 0);
}
}
@@ -485,10 +519,11 @@ sigsegv_handler (int sig) {
void
save_resume_state (void) {
playItem_t *trk = streamer_get_playing_track ();
+ DB_output_t *output = plug_get_output ();
float playpos = -1;
int playtrack = -1;
int playlist = streamer_get_current_playlist ();
- int paused = (p_get_state () == OUTPUT_STATE_PAUSED);
+ int paused = (output->state () == OUTPUT_STATE_PAUSED);
if (trk && playlist >= 0) {
playtrack = str_get_idx_of (trk);
playpos = streamer_get_playpos ();
@@ -503,7 +538,8 @@ save_resume_state (void) {
void
restore_resume_state (void) {
- if (conf_get_int ("resume_last_session", 0) && p_isstopped ()) {
+ DB_output_t *output = plug_get_output ();
+ if (conf_get_int ("resume_last_session", 0) && output->state () == OUTPUT_STATE_STOPPED) {
int plt = conf_get_int ("resume.playlist", -1);
int track = conf_get_int ("resume.track", -1);
float pos = conf_get_float ("resume.position", -1);
@@ -531,12 +567,40 @@ main (int argc, char *argv[]) {
bindtextdomain (PACKAGE, LOCALEDIR);
bind_textdomain_codeset (PACKAGE, "UTF-8");
textdomain (PACKAGE);
-#endif
- fprintf (stderr, "starting deadbeef " VERSION "\n");
+#endif
+
+ int staticlink = 0;
+ int portable = 0;
+#if STATICLINK
+ staticlink = 1;
+#endif
+#if PORTABLE
+ portable = 1;
+#endif
+
+ fprintf (stderr, "starting deadbeef " VERSION "%s%s\n", staticlink ? " [static]" : "", portable ? " [portable]" : "");
srand (time (NULL));
#ifdef __linux__
prctl (PR_SET_NAME, "deadbeef-main", 0, 0, 0, 0);
#endif
+
+#if PORTABLE
+ strcpy (dbinstalldir, argv[0]);
+ char *e = dbinstalldir + strlen (dbinstalldir);
+ while (e >= dbinstalldir && *e != '/') {
+ e--;
+ }
+ *e = 0;
+#endif
+
+#if PORTABLE_FULL
+ if (snprintf (confdir, sizeof (confdir), "%s/config", dbinstalldir) > sizeof (confdir)) {
+ fprintf (stderr, "fatal: too long install path %s\n", dbinstalldir);
+ return -1;
+ }
+
+ strcpy (dbconfdir, confdir);
+#else
char *homedir = getenv ("HOME");
if (!homedir) {
fprintf (stderr, "unable to find home directory. stopping.\n");
@@ -556,11 +620,48 @@ main (int argc, char *argv[]) {
return -1;
}
}
- mkdir (confdir, 0755);
if (snprintf (dbconfdir, sizeof (dbconfdir), "%s/deadbeef", confdir) > sizeof (dbconfdir)) {
fprintf (stderr, "fatal: out of memory while configuring\n");
return -1;
}
+ mkdir (confdir, 0755);
+#endif
+
+
+#if PORTABLE
+ if (snprintf (dbdocdir, sizeof (dbdocdir), "%s/doc", dbinstalldir) > sizeof (dbdocdir)) {
+ fprintf (stderr, "fatal: too long install path %s\n", dbinstalldir);
+ return -1;
+ }
+ if (snprintf (dbplugindir, sizeof (dbplugindir), "%s/plugins", dbinstalldir) > sizeof (dbplugindir)) {
+ fprintf (stderr, "fatal: too long install path %s\n", dbinstalldir);
+ return -1;
+ }
+ if (snprintf (dbpixmapdir, sizeof (dbpixmapdir), "%s/pixmaps", dbinstalldir) > sizeof (dbpixmapdir)) {
+ fprintf (stderr, "fatal: too long install path %s\n", dbinstalldir);
+ return -1;
+ }
+ mkdir (dbplugindir, 0755);
+#else
+ if (snprintf (dbdocdir, sizeof (dbdocdir), "%s", DOCDIR) > sizeof (dbdocdir)) {
+ fprintf (stderr, "fatal: too long install path %s\n", dbinstalldir);
+ return -1;
+ }
+ if (snprintf (dbplugindir, sizeof (dbplugindir), "%s/deadbeef", LIBDIR) > sizeof (dbplugindir)) {
+ fprintf (stderr, "fatal: too long install path %s\n", dbinstalldir);
+ return -1;
+ }
+ if (snprintf (dbpixmapdir, sizeof (dbpixmapdir), "%s/share/deadbeef/pixmaps", PREFIX) > sizeof (dbpixmapdir)) {
+ fprintf (stderr, "fatal: too long install path %s\n", dbinstalldir);
+ return -1;
+ }
+#endif
+ trace ("installdir: %s\n", dbinstalldir);
+ trace ("confdir: %s\n", confdir);
+ trace ("docdir: %s\n", dbdocdir);
+ trace ("plugindir: %s\n", dbplugindir);
+ trace ("pixmapdir: %s\n", dbpixmapdir);
+
mkdir (dbconfdir, 0755);
char cmdline[2048];
@@ -679,10 +780,16 @@ main (int argc, char *argv[]) {
pl_init ();
+ conf_init ();
conf_load (); // required by some plugins at startup
+
+ conf_set_str ("deadbeef_version", VERSION);
+
volume_set_db (conf_get_float ("playback.volume", 0)); // volume need to be initialized before plugins start
messagepump_init (); // required to push messages while handling commandline
- plug_load_all (); // required to add files to playlist from commandline
+ if (plug_load_all ()) { // required to add files to playlist from commandline
+ exit (-1);
+ }
pl_load_all ();
plt_set_curr (conf_get_int ("playlist.current", 0));
@@ -716,12 +823,21 @@ main (int argc, char *argv[]) {
streamer_init ();
+ plug_connect_all ();
+
if (!noloadpl) {
restore_resume_state ();
}
+ server_tid = thread_start (server_loop, NULL);
// this runs in main thread (blocks right here)
player_mainloop ();
+ // terminate server and wait for completion
+ if (server_tid) {
+ server_terminate = 1;
+ thread_join (server_tid);
+ server_tid = 0;
+ }
save_resume_state ();
@@ -741,13 +857,15 @@ main (int argc, char *argv[]) {
server_close ();
// stop streaming and playback before unloading plugins
- p_stop ();
+ DB_output_t *output = plug_get_output ();
+ output->stop ();
streamer_free ();
- p_free ();
+ output->free ();
// plugins might still hood references to playitems,
// and query configuration in background
// so unload everything 1st before final cleanup
+ plug_disconnect_all ();
plug_unload_all ();
// at this point we can simply do exit(0), but let's clean up for debugging
diff --git a/messagepump.c b/messagepump.c
index f5eea2ce..931b67db 100644
--- a/messagepump.c
+++ b/messagepump.c
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -34,6 +34,7 @@ static message_t *mfree;
static message_t *mqueue;
static message_t *mqtail;
static uintptr_t mutex;
+static uintptr_t cond;
static void
messagepump_reset (void);
@@ -42,6 +43,7 @@ int
messagepump_init (void) {
messagepump_reset ();
mutex = mutex_create ();
+ cond = cond_create ();
return 0;
}
@@ -51,6 +53,7 @@ messagepump_free () {
messagepump_reset ();
mutex_unlock (mutex);
mutex_free (mutex);
+ cond_free (cond);
}
static void
@@ -88,9 +91,16 @@ messagepump_push (uint32_t id, uintptr_t ctx, uint32_t p1, uint32_t p2) {
msg->p1 = p1;
msg->p2 = p2;
mutex_unlock (mutex);
+ cond_signal (cond);
return 0;
}
+void
+messagepump_wait (void) {
+ cond_wait (cond, mutex);
+ mutex_unlock (mutex);
+}
+
int
messagepump_pop (uint32_t *id, uintptr_t *ctx, uint32_t *p1, uint32_t *p2) {
if (!mqueue) {
diff --git a/messagepump.h b/messagepump.h
index cf1083ab..b22da711 100644
--- a/messagepump.h
+++ b/messagepump.h
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -24,6 +24,6 @@ int messagepump_init (void);
void messagepump_free (void);
int messagepump_push (uint32_t id, uintptr_t ctx, uint32_t p1, uint32_t p2);
int messagepump_pop (uint32_t *id, uintptr_t *ctx, uint32_t *p1, uint32_t *p2);
-//int messagepump_hasmessages (void);
+void messagepump_wait (void);
#endif // __MESSAGEPUMP_H
diff --git a/metacache.c b/metacache.c
index 4b65d2a5..d4e7b128 100644
--- a/metacache.c
+++ b/metacache.c
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
diff --git a/metacache.h b/metacache.h
index 6ad1b5d6..b5187c0f 100644
--- a/metacache.h
+++ b/metacache.h
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
diff --git a/optmath.h b/optmath.h
index 898c0fd7..c655fd17 100644
--- a/optmath.h
+++ b/optmath.h
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
diff --git a/playback.h b/playback.h
deleted file mode 100644
index 21ac74f1..00000000
--- a/playback.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-#ifndef __PLAYBACK_H
-#define __PLAYBACK_H
-
-#define p_init plug_get_output ()->init
-#define p_free plug_get_output ()->free
-#define p_play plug_get_output ()->play
-#define p_stop plug_get_output ()->stop
-#define p_pause plug_get_output ()->pause
-#define p_unpause plug_get_output ()->unpause
-#define p_get_rate plug_get_output ()->samplerate
-#define p_get_state plug_get_output ()->state
-
-#define p_state() (plug_get_output ()->state ())
-#define p_isstopped() (p_state () == OUTPUT_STATE_STOPPED)
-#define p_ispaused() (p_state () == OUTPUT_STATE_PAUSED)
-
-#endif // __PLAYBACK_H
diff --git a/playlist.c b/playlist.c
index 16cb424c..a1ddba17 100644
--- a/playlist.c
+++ b/playlist.c
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -39,7 +39,6 @@
#include "playlist.h"
#include "streamer.h"
#include "messagepump.h"
-#include "playback.h"
#include "plugins.h"
#include "junklib.h"
#include "vfs.h"
@@ -49,6 +48,7 @@
#include "threading.h"
#include "metacache.h"
#include "volume.h"
+#include "pltmeta.h"
#define DISABLE_LOCKING 0
#define DEBUG_LOCKING 0
@@ -93,6 +93,27 @@ static uintptr_t mutex_plt;
static playlist_t dummy_playlist; // used at startup to prevent crashes
+static int pl_order; // mirrors "playback.order" config variable
+
+static int no_remove_notify;
+
+static playlist_t *addfiles_playlist; // current playlist for adding files/folders; set in pl_add_files_begin
+
+void
+pl_set_order (int order) {
+ if (pl_order != order && (pl_order == PLAYBACK_ORDER_SHUFFLE_TRACKS || PLAYBACK_ORDER_SHUFFLE_ALBUMS)) {
+ pl_order = order;
+ for (playlist_t *plt = playlists_head; plt; plt = plt->next) {
+ plt_reshuffle (plt, NULL, NULL);
+ }
+ }
+}
+
+int
+pl_get_order (void) {
+ return pl_order;
+}
+
int
pl_init (void) {
playlist = &dummy_playlist;
@@ -337,7 +358,6 @@ plt_add (int before, const char *title) {
// NOTE: caller must ensure that configuration is saved after that call
void
plt_remove (int plt) {
- trace ("plt_remove %d\n", plt);
int i;
assert (plt >= 0 && plt < playlists_count);
PLT_LOCK;
@@ -350,7 +370,6 @@ plt_remove (int plt) {
p = p->next;
}
streamer_notify_playlist_deleted (p);
-
if (!plt_loading) {
// move files (will decrease number of files by 1)
for (int i = plt+1; i < playlists_count; i++) {
@@ -394,14 +413,29 @@ plt_remove (int plt) {
prev->next = p->next;
}
}
+ playlist_t *next = p->next;
playlist_t *old = playlist;
playlist = p;
pl_clear ();
playlist = old;
if (p == playlist) {
- playlist = prev ? prev : playlists_head;
+ if (next) {
+ playlist = next;
+ }
+ else {
+ playlist = prev ? prev : playlists_head;
+ }
}
free (p->title);
+
+ while (p->meta) {
+ DB_metaInfo_t *m = p->meta;
+ p->meta = m->next;
+ metacache_remove_string (m->key);
+ metacache_remove_string (m->value);
+ free (m);
+ }
+
free (p);
playlists_count--;
PLT_UNLOCK;
@@ -477,49 +511,33 @@ plt_get_idx_of (playlist_t *plt) {
}
int
-plt_get_title (int plt, char *buffer, int bufsize) {
+plt_get_title (playlist_t *p, char *buffer, int bufsize) {
int i;
PLT_LOCK;
- playlist_t *p = playlists_head;
- for (i = 0; p && i <= plt; i++) {
- if (i == plt) {
- if (!buffer) {
- int l = strlen (p->title);
- PLT_UNLOCK;
- return l;
- }
- strncpy (buffer, p->title, bufsize);
- buffer[bufsize-1] = 0;
- PLT_UNLOCK;
- return 0;
- }
- p = p->next;
+ if (!buffer) {
+ int l = strlen (p->title);
+ PLT_UNLOCK;
+ return l;
}
+ strncpy (buffer, p->title, bufsize);
+ buffer[bufsize-1] = 0;
PLT_UNLOCK;
- buffer[0] = 0;
- return -1;
+ return 0;
}
int
-plt_set_title (int plt, const char *title) {
+plt_set_title (playlist_t *p, const char *title) {
int i;
PLT_LOCK;
- playlist_t *p = playlists_head;
- for (i = 0; p && i <= plt; i++) {
- if (i == plt) {
- free (p->title);
- p->title = strdup (title);
- break;
- }
- p = p->next;
- }
- PLT_UNLOCK;
+ free (p->title);
+ p->title = strdup (title);
plt_gen_conf ();
+ PLT_UNLOCK;
conf_save ();
if (!plt_loading) {
plug_trigger_event (DB_EV_PLAYLISTSWITCH, 0);
}
- return i == plt ? 0 : -1;
+ return 0;
}
void
@@ -532,7 +550,7 @@ plt_free (void) {
for (playItem_t *it = playlists_head->head[PL_MAIN]; it; it = it->next[PL_MAIN]) {
if (it->_refc > 1) {
- fprintf (stderr, "\033[0;31mWARNING: playitem %p %s has refc=%d at delete time\033[37;0m\n", it, it->fname, it->_refc);
+ fprintf (stderr, "\033[0;31mWARNING: playitem %p %s has refc=%d at delete time\033[37;0m\n", it, pl_find_meta (it, ":URI"), it->_refc);
}
}
@@ -570,10 +588,11 @@ plt_move (int from, int to) {
return;
}
+ trace ("will rename %s->%s\n", path1, temp);
struct stat st;
int err = stat (path1, &st);
if (!err) {
- trace ("move %s->%s\n", path1, temp);
+ trace ("rename %s->%s\n", path1, temp);
int err = rename (path1, temp);
if (err != 0) {
@@ -600,7 +619,6 @@ plt_move (int from, int to) {
}
// shift files to fill the gap
- trace ("fill gap\n");
for (int i = from; i < playlists_count-1; i++) {
char path2[PATH_MAX];
if (snprintf (path1, sizeof (path1), "%s/playlists/%d.dbpl", dbconfdir, i) > sizeof (path1)) {
@@ -611,9 +629,10 @@ plt_move (int from, int to) {
fprintf (stderr, "error: failed to make path string for playlist file\n");
continue;
}
+ trace ("will rename %s->%s\n", path2, path1);
int err = stat (path2, &st);
if (!err) {
- trace ("move %s->%s\n", path2, path1);
+ trace ("rename %s->%s\n", path2, path1);
int err = rename (path2, path1);
if (err != 0) {
fprintf (stderr, "playlist rename %s->%s failed: %s\n", path2, path1, strerror (errno));
@@ -621,7 +640,6 @@ plt_move (int from, int to) {
}
}
// open new gap
- trace ("open new gap\n");
for (int i = playlists_count-2; i >= to; i--) {
char path2[PATH_MAX];
if (snprintf (path1, sizeof (path1), "%s/playlists/%d.dbpl", dbconfdir, i) > sizeof (path1)) {
@@ -632,9 +650,10 @@ plt_move (int from, int to) {
fprintf (stderr, "error: failed to make path string for playlist file\n");
continue;
}
+ trace ("will rename %s->%s\n", path1, path2);
int err = stat (path1, &st);
if (!err) {
- trace ("move %s->%s\n", path1, path2);
+ trace ("rename %s->%s\n", path1, path2);
int err = rename (path1, path2);
if (err != 0) {
fprintf (stderr, "playlist rename %s->%s failed: %s\n", path1, path2, strerror (errno));
@@ -646,7 +665,7 @@ plt_move (int from, int to) {
fprintf (stderr, "error: failed to make path string for playlist file\n");
}
else {
- int err = stat (path1, &st);
+ int err = stat (temp, &st);
if (!err) {
trace ("move %s->%s\n", temp, path1);
int err = rename (temp, path1);
@@ -683,16 +702,21 @@ plt_move (int from, int to) {
}
void
-pl_clear (void) {
+plt_clear (playlist_t *plt) {
LOCK;
- while (playlist->head[PL_MAIN]) {
- pl_remove_item (playlist->head[PL_MAIN]);
+ while (plt->head[PL_MAIN]) {
+ pl_remove_item (plt->head[PL_MAIN]);
}
- playlist->current_row[PL_MAIN] = -1;
- playlist->current_row[PL_SEARCH] = -1;
+ plt->current_row[PL_MAIN] = -1;
+ plt->current_row[PL_SEARCH] = -1;
UNLOCK;
}
+void
+pl_clear (void) {
+ plt_clear (playlist);
+}
+
static const uint8_t *
pl_str_skipspaces (const uint8_t *p, const uint8_t *end) {
while (p < end && *p <= ' ') {
@@ -774,7 +798,7 @@ pl_cue_parse_time (const char *p) {
}
static playItem_t *
-pl_process_cue_track (playItem_t *after, const char *fname, playItem_t **prev, char *track, char *index00, char *index01, char *pregap, char *title, char *performer, char *albumtitle, char *genre, char *date, char *replaygain_album_gain, char *replaygain_album_peak, char *replaygain_track_gain, char *replaygain_track_peak, const char *decoder_id, const char *ftype, int samplerate) {
+pl_process_cue_track (playItem_t *after, const char *fname, playItem_t **prev, char *track, char *index00, char *index01, char *pregap, char *title, char *albumperformer, char *performer, char *albumtitle, char *genre, char *date, char *replaygain_album_gain, char *replaygain_album_peak, char *replaygain_track_gain, char *replaygain_track_peak, const char *decoder_id, const char *ftype, int samplerate) {
if (!track[0]) {
trace ("pl_process_cue_track: invalid track (file=%s, title=%s)\n", fname, title);
return after;
@@ -819,14 +843,15 @@ pl_process_cue_track (playItem_t *after, const char *fname, playItem_t **prev, c
}
(*prev)->endsample = (prevtime * samplerate) - 1;
pl_set_item_duration (*prev, (float)((*prev)->endsample - (*prev)->startsample + 1) / samplerate);
- if ((*prev)->_duration < 0) {
+ if (pl_get_item_duration (*prev) < 0) {
// might be bad cuesheet file, try to fix
trace ("cuesheet seems to be corrupted, trying workaround\n");
//trace ("[bad:] calc endsample=%d, prevtime=%f, samplerate=%d, prev track duration=%f\n", (*prev)->endsample, prevtime, samplerate, (*prev)->duration);
prevtime = f_index01;
(*prev)->endsample = (prevtime * samplerate) - 1;
- pl_set_item_duration (*prev, (float)((*prev)->endsample - (*prev)->startsample + 1) / samplerate);
- if ((*prev)->_duration > 0) {
+ float dur = (float)((*prev)->endsample - (*prev)->startsample + 1) / samplerate;
+ pl_set_item_duration (*prev, dur);
+ if (dur > 0) {
trace ("success :-D\n");
}
else {
@@ -841,15 +866,19 @@ pl_process_cue_track (playItem_t *after, const char *fname, playItem_t **prev, c
trace ("pl_process_cue_track: invalid index01 (pregap=%s, index01=%s)\n", pregap, index01);
return after;
}
- playItem_t *it = pl_item_alloc ();
- it->decoder_id = plug_get_decoder_id (decoder_id);
- it->fname = strdup (fname);
- it->tracknum = atoi (track);
+ playItem_t *it = pl_item_alloc_init (fname, decoder_id);
+ pl_set_meta_int (it, ":TRACKNUM", atoi (track));
it->startsample = index01[0] ? f_index01 * samplerate : 0;
it->endsample = -1; // will be filled by next read, or by decoder
- it->filetype = ftype;
+ pl_replace_meta (it, ":FILETYPE", ftype);
if (performer[0]) {
pl_add_meta (it, "artist", performer);
+ if (albumperformer[0]) {
+ pl_add_meta (it, "album artist", albumperformer);
+ }
+ }
+ else if (albumperformer[0]) {
+ pl_add_meta (it, "artist", albumperformer);
}
if (albumtitle[0]) {
pl_add_meta (it, "album", albumtitle);
@@ -867,16 +896,16 @@ pl_process_cue_track (playItem_t *after, const char *fname, playItem_t **prev, c
pl_add_meta (it, "year", date);
}
if (replaygain_album_gain[0]) {
- it->replaygain_album_gain = atof (replaygain_album_gain);
+ pl_set_item_replaygain (it, DDB_REPLAYGAIN_ALBUMGAIN, atof (replaygain_album_gain));
}
if (replaygain_album_peak[0]) {
- it->replaygain_album_peak = atof (replaygain_album_peak);
+ pl_set_item_replaygain (it, DDB_REPLAYGAIN_ALBUMPEAK, atof (replaygain_album_peak));
}
if (replaygain_track_gain[0]) {
- it->replaygain_track_gain = atof (replaygain_track_gain);
+ pl_set_item_replaygain (it, DDB_REPLAYGAIN_TRACKGAIN, atof (replaygain_track_gain));
}
if (replaygain_track_peak[0]) {
- it->replaygain_track_peak = atof (replaygain_track_peak);
+ pl_set_item_replaygain (it, DDB_REPLAYGAIN_TRACKPEAK, atof (replaygain_track_peak));
}
it->_flags |= DDB_IS_SUBTRACK | DDB_TAG_CUESHEET;
after = pl_insert_item (after, it);
@@ -890,6 +919,7 @@ pl_insert_cue_from_buffer (playItem_t *after, playItem_t *origin, const uint8_t
LOCK;
playItem_t *ins = after;
trace ("pl_insert_cue_from_buffer numsamples=%d, samplerate=%d\n", numsamples, samplerate);
+ char albumperformer[256] = "";
char performer[256] = "";
char albumtitle[256] = "";
char genre[256] = "";
@@ -927,7 +957,12 @@ pl_insert_cue_from_buffer (playItem_t *after, playItem_t *origin, const uint8_t
p = pl_cue_skipspaces (str);
// trace ("cue line: %s\n", p);
if (!strncmp (p, "PERFORMER ", 10)) {
- pl_get_qvalue_from_cue (p + 10, sizeof (performer), performer);
+ if (!track[0]) {
+ pl_get_qvalue_from_cue (p + 10, sizeof (albumperformer), albumperformer);
+ }
+ else {
+ pl_get_qvalue_from_cue (p + 10, sizeof (performer), performer);
+ }
trace ("cue: got performer: %s\n", performer);
}
else if (!strncmp (p, "TITLE ", 6)) {
@@ -948,9 +983,12 @@ pl_insert_cue_from_buffer (playItem_t *after, playItem_t *origin, const uint8_t
}
else if (!strncmp (p, "TRACK ", 6)) {
trace ("cue: adding track: %s %s %s\n", origin->fname, title, track);
- // add previous track
- after = pl_process_cue_track (after, origin->fname, &prev, track, index00, index01, pregap, title, performer, albumtitle, genre, date, replaygain_album_gain, replaygain_album_peak, replaygain_track_gain, replaygain_track_peak, origin->decoder_id, origin->filetype, samplerate);
- trace ("cue: added %p (%p)\n", after);
+ if (title[0]) {
+ // add previous track
+ const char *filetype = pl_find_meta (origin, ":FILETYPE");
+ after = pl_process_cue_track (after, pl_find_meta (origin, ":URI"), &prev, track, index00, index01, pregap, title, albumperformer, performer, albumtitle, genre, date, replaygain_album_gain, replaygain_album_peak, replaygain_track_gain, replaygain_track_peak, pl_find_meta (origin, ":DECODER"), filetype, samplerate);
+ trace ("cue: added %p (%p)\n", after);
+ }
track[0] = 0;
title[0] = 0;
@@ -959,6 +997,7 @@ pl_insert_cue_from_buffer (playItem_t *after, playItem_t *origin, const uint8_t
index01[0] = 0;
replaygain_track_gain[0] = 0;
replaygain_track_peak[0] = 0;
+ performer[0] = 0;
pl_get_value_from_cue (p + 6, sizeof (track), track);
trace ("cue: got track: %s\n", track);
}
@@ -987,11 +1026,12 @@ pl_insert_cue_from_buffer (playItem_t *after, playItem_t *origin, const uint8_t
// fprintf (stderr, "got unknown line:\n%s\n", p);
}
}
- if (ins == after) {
+ if (!title[0]) {
UNLOCK;
return NULL;
}
- after = pl_process_cue_track (after, origin->fname, &prev, track, index00, index01, pregap, title, performer, albumtitle, genre, date, replaygain_album_gain, replaygain_album_peak, replaygain_track_gain, replaygain_track_peak, origin->decoder_id, origin->filetype, samplerate);
+ const char *filetype = pl_find_meta (origin, ":FILETYPE");
+ after = pl_process_cue_track (after, pl_find_meta (origin, ":URI"), &prev, track, index00, index01, pregap, title, albumperformer, performer, albumtitle, genre, date, replaygain_album_gain, replaygain_album_peak, replaygain_track_gain, replaygain_track_peak, pl_find_meta (origin, ":DECODER"), filetype, samplerate);
if (after) {
trace ("last track endsample: %d\n", numsamples-1);
after->endsample = numsamples-1;
@@ -1017,9 +1057,10 @@ pl_insert_cue_from_buffer (playItem_t *after, playItem_t *origin, const uint8_t
playItem_t *
pl_insert_cue (playItem_t *after, playItem_t *origin, int numsamples, int samplerate) {
trace ("pl_insert_cue numsamples=%d, samplerate=%d\n", numsamples, samplerate);
- int len = strlen (origin->fname);
+ const char *fname = pl_find_meta (origin, ":URI");
+ int len = strlen (fname);
char cuename[len+5];
- strcpy (cuename, origin->fname);
+ strcpy (cuename, fname);
strcpy (cuename+len, ".cue");
FILE *fp = fopen (cuename, "rb");
if (!fp) {
@@ -1064,11 +1105,6 @@ pl_insert_m3u (playItem_t *after, const char *fname, int *pabort, int (*cb)(play
trace ("file %s is too large to be a playlist\n", fname);
return NULL;
}
- if (sz < 30) {
- vfs_fclose (fp);
- trace ("file %s is too small to be a playlist (%d)\n", fname, sz);
- return NULL;
- }
trace ("loading m3u...\n");
uint8_t buffer[sz];
vfs_fread (buffer, 1, sz, fp);
@@ -1132,7 +1168,7 @@ pl_insert_pls (playItem_t *after, const char *fname, int *pabort, int (*cb)(play
trace ("file %s is too large to be a playlist\n", fname);
return NULL;
}
- if (sz < 30) {
+ if (sz < 10) {
vfs_fclose (fp);
trace ("file %s is too small to be a playlist (%d)\n", fname, sz);
return NULL;
@@ -1154,20 +1190,11 @@ pl_insert_pls (playItem_t *after, const char *fname, int *pabort, int (*cb)(play
trace ("file %s finished before numberofentries had been read\n", fname);
return NULL;
}
- if (strncasecmp (p, "numberofentries=", 16)) {
- trace ("can't get number of entries from %s\n", fname);
- return NULL;
- }
- p += 15;
- // ignore numentries - no real need for it here
- while (p < end && *p > 0x20) {
- p++;
- }
- p = pl_str_skipspaces (p, end);
// fetch all tracks
char url[1024] = "";
char title[1024] = "";
char length[20] = "";
+ int lastidx = -1;
LOCK;
while (p < end) {
p = pl_str_skipspaces (p, end);
@@ -1179,8 +1206,15 @@ pl_insert_pls (playItem_t *after, const char *fname, int *pabort, int (*cb)(play
}
const uint8_t *e;
int n;
- if (!strncasecmp (p, "file", 4)) {
- if (url[0]) {
+ if (!strncasecmp (p, "numberofentries=", 16) || !strncasecmp (p, "version=", 8)) {
+ while (p < end && *p >= 0x20) {
+ p++;
+ }
+ continue;
+ }
+ else if (!strncasecmp (p, "file", 4)) {
+ int idx = atoi (p + 4);
+ if (url[0] && idx != lastidx && lastidx != -1) {
// add track
playItem_t *it = pl_insert_file (after, url, pabort, cb, user_data);
if (it) {
@@ -1199,6 +1233,7 @@ pl_insert_pls (playItem_t *after, const char *fname, int *pabort, int (*cb)(play
title[0] = 0;
length[0] = 0;
}
+ lastidx = idx;
p += 4;
while (p < end && *p != '=') {
p++;
@@ -1219,6 +1254,27 @@ pl_insert_pls (playItem_t *after, const char *fname, int *pabort, int (*cb)(play
p = ++e;
}
else if (!strncasecmp (p, "title", 5)) {
+ int idx = atoi (p + 5);
+ if (url[0] && idx != lastidx && lastidx != -1) {
+ // add track
+ playItem_t *it = pl_insert_file (after, url, pabort, cb, user_data);
+ if (it) {
+ after = it;
+ pl_set_item_duration (it, atoi (length));
+ if (title[0]) {
+ pl_delete_all_meta (it);
+ pl_add_meta (it, "title", title);
+ }
+ }
+ if (pabort && *pabort) {
+ UNLOCK;
+ return after;
+ }
+ url[0] = 0;
+ title[0] = 0;
+ length[0] = 0;
+ }
+ lastidx = idx;
p += 5;
while (p < end && *p != '=') {
p++;
@@ -1239,6 +1295,27 @@ pl_insert_pls (playItem_t *after, const char *fname, int *pabort, int (*cb)(play
p = ++e;
}
else if (!strncasecmp (p, "length", 6)) {
+ int idx = atoi (p + 6);
+ if (url[0] && idx != lastidx && lastidx != -1) {
+ // add track
+ playItem_t *it = pl_insert_file (after, url, pabort, cb, user_data);
+ if (it) {
+ after = it;
+ pl_set_item_duration (it, atoi (length));
+ if (title[0]) {
+ pl_delete_all_meta (it);
+ pl_add_meta (it, "title", title);
+ }
+ }
+ if (pabort && *pabort) {
+ UNLOCK;
+ return after;
+ }
+ url[0] = 0;
+ title[0] = 0;
+ length[0] = 0;
+ }
+ lastidx = idx;
p += 6;
// skip =
while (p < end && *p != '=') {
@@ -1255,7 +1332,6 @@ pl_insert_pls (playItem_t *after, const char *fname, int *pabort, int (*cb)(play
n = e-p;
n = min (n, sizeof (length)-1);
memcpy (length, p, n);
- break;
}
else {
trace ("invalid entry in pls file: %s\n", p);
@@ -1281,6 +1357,12 @@ pl_insert_pls (playItem_t *after, const char *fname, int *pabort, int (*cb)(play
return after;
}
+static int follow_symlinks = 0;
+static int ignore_archives = 0;
+
+playItem_t *
+pl_insert_dir_int (DB_vfs_t *vfs, playItem_t *after, const char *dirname, int *pabort, int (*cb)(playItem_t *it, void *data), void *user_data);
+
playItem_t *
pl_insert_file (playItem_t *after, const char *fname, int *pabort, int (*cb)(playItem_t *it, void *data), void *user_data) {
trace ("count: %d\n", playlist->count[PL_MAIN]);
@@ -1289,21 +1371,46 @@ pl_insert_file (playItem_t *after, const char *fname, int *pabort, int (*cb)(pla
return NULL;
}
+ // check if that is supported container format
+ if (!ignore_archives) {
+ DB_vfs_t **vfsplugs = plug_get_vfs_list ();
+ for (int i = 0; vfsplugs[i]; i++) {
+ if (vfsplugs[i]->is_container) {
+ trace ("%s cont test\n", fname);
+ if (vfsplugs[i]->is_container (fname)) {
+ trace ("inserting %s via vfs %s\n", fname, vfsplugs[i]->plugin.id);
+ playItem_t *it = pl_insert_dir_int (vfsplugs[i], after, fname, pabort, cb, user_data);
+ if (it) {
+ return it;
+ }
+ }
+ }
+ }
+ }
+
// detect decoder
- const char *eol = fname + strlen (fname) - 1;
- while (eol > fname && *eol != '.') {
- eol--;
+ const char *eol = strrchr (fname, '.');
+ if (!eol) {
+ return NULL;
}
eol++;
+ const char *fn = strrchr (fname, '/');
+ if (!fn) {
+ fn = fname;
+ }
+ else {
+ fn++;
+ }
+
// detect pls/m3u files
// they must be handled before checking for http://,
// so that remote playlist files referenced from other playlist files could
// be loaded correctly
- if (!memcmp (eol, "m3u", 3)) {
+ if (!strcmp (eol, "m3u") || !strcmp (eol, "m3u8")) {
return pl_insert_m3u (after, fname, pabort, cb, user_data);
}
- else if (!memcmp (eol, "pls", 3)) {
+ else if (!strcmp (eol, "pls")) {
return pl_insert_pls (after, fname, pabort, cb, user_data);
}
@@ -1327,6 +1434,28 @@ pl_insert_file (playItem_t *after, const char *fname, int *pabort, int (*cb)(pla
}
}
+ if (detect_on_access) {
+ // find vfs plugin
+ DB_vfs_t **vfsplugs = plug_get_vfs_list ();
+ for (int i = 0; vfsplugs[i]; i++) {
+ if (vfsplugs[i]->get_schemes) {
+ const char **sch = vfsplugs[i]->get_schemes ();
+ int s = 0;
+ for (s = 0; sch[s]; s++) {
+ if (!strncasecmp (sch[s], fname, strlen (sch[s]))) {
+ break;
+ }
+ }
+ if (sch[s]) {
+ if (!vfsplugs[i]->is_streaming || !vfsplugs[i]->is_streaming()) {
+ detect_on_access = 0;
+ }
+ break;
+ }
+ }
+ }
+ }
+
if (detect_on_access && *p == ':') {
// check for wrong chars like CR/LF, TAB, etc
// they are not allowed and might lead to corrupt display in GUI
@@ -1338,13 +1467,10 @@ pl_insert_file (playItem_t *after, const char *fname, int *pabort, int (*cb)(pla
}
}
- playItem_t *it = pl_item_alloc ();
- it->decoder_id = NULL;
- it->fname = strdup (fname);
- it->filetype = "content";
- it->_duration = -1;
+ playItem_t *it = pl_item_alloc_init (fname, NULL);
+ pl_replace_meta (it, ":FILETYPE", "content");
pl_add_meta (it, "title", NULL);
- after = pl_insert_item (after, it);
+ after = plt_insert_item (addfiles_playlist ? addfiles_playlist : playlist, after, it);
pl_item_unref (it);
return after;
}
@@ -1371,6 +1497,20 @@ pl_insert_file (playItem_t *after, const char *fname, int *pabort, int (*cb)(pla
}
}
}
+ if (decoders[i]->prefixes && decoders[i]->insert) {
+ const char **prefixes = decoders[i]->prefixes;
+ for (int e = 0; prefixes[e]; e++) {
+ if (!strncasecmp (prefixes[e], fn, strlen(prefixes[e])) && *(fn + strlen (prefixes[e])) == '.') {
+ playItem_t *inserted = (playItem_t *)decoders[i]->insert (DB_PLAYITEM (after), fname);
+ if (inserted != NULL) {
+ if (cb && cb (inserted, user_data) < 0) {
+ *pabort = 1;
+ }
+ return inserted;
+ }
+ }
+ }
+ }
}
trace ("no decoder found for %s\n", fname);
return NULL;
@@ -1380,14 +1520,12 @@ static int dirent_alphasort (const struct dirent **a, const struct dirent **b) {
return strcmp ((*a)->d_name, (*b)->d_name);
}
-static int follow_symlinks = 0;
-
playItem_t *
-pl_insert_dir_int (playItem_t *after, const char *dirname, int *pabort, int (*cb)(playItem_t *it, void *data), void *user_data) {
- if (!memcmp (dirname, "file://", 7)) {
+pl_insert_dir_int (DB_vfs_t *vfs, playItem_t *after, const char *dirname, int *pabort, int (*cb)(playItem_t *it, void *data), void *user_data) {
+ if (!strncmp (dirname, "file://", 7)) {
dirname += 7;
}
- if (!follow_symlinks) {
+ if (!follow_symlinks && !vfs) {
struct stat buf;
lstat (dirname, &buf);
if (S_ISLNK(buf.st_mode)) {
@@ -1397,7 +1535,12 @@ pl_insert_dir_int (playItem_t *after, const char *dirname, int *pabort, int (*cb
struct dirent **namelist = NULL;
int n;
- n = scandir (dirname, &namelist, NULL, dirent_alphasort);
+ if (vfs && vfs->scandir) {
+ n = vfs->scandir (dirname, &namelist, NULL, dirent_alphasort);
+ }
+ else {
+ n = scandir (dirname, &namelist, NULL, dirent_alphasort);
+ }
if (n < 0)
{
if (namelist)
@@ -1412,11 +1555,17 @@ pl_insert_dir_int (playItem_t *after, const char *dirname, int *pabort, int (*cb
// no hidden files
if (namelist[i]->d_name[0] != '.')
{
- char fullname[PATH_MAX];
- snprintf (fullname, sizeof (fullname), "%s/%s", dirname, namelist[i]->d_name);
- playItem_t *inserted = pl_insert_dir_int (after, fullname, pabort, cb, user_data);
- if (!inserted) {
- inserted = pl_insert_file (after, fullname, pabort, cb, user_data);
+ playItem_t *inserted = NULL;
+ if (!vfs) {
+ char fullname[PATH_MAX];
+ snprintf (fullname, sizeof (fullname), "%s/%s", dirname, namelist[i]->d_name);
+ inserted = pl_insert_dir_int (vfs, after, fullname, pabort, cb, user_data);
+ if (!inserted) {
+ inserted = pl_insert_file (after, fullname, pabort, cb, user_data);
+ }
+ }
+ else {
+ inserted = pl_insert_file (after, namelist[i]->d_name, pabort, cb, user_data);
}
if (inserted) {
after = inserted;
@@ -1435,13 +1584,19 @@ pl_insert_dir_int (playItem_t *after, const char *dirname, int *pabort, int (*cb
playItem_t *
pl_insert_dir (playItem_t *after, const char *dirname, int *pabort, int (*cb)(playItem_t *it, void *data), void *user_data) {
follow_symlinks = conf_get_int ("add_folders_follow_symlinks", 0);
- return pl_insert_dir_int (after, dirname, pabort, cb, user_data);
+ ignore_archives = conf_get_int ("ignore_archives", 1);
+
+ playItem_t *ret = pl_insert_dir_int (NULL, after, dirname, pabort, cb, user_data);
+
+ ignore_archives = 0;
+
+ return ret;
}
int
pl_add_file (const char *fname, int (*cb)(playItem_t *it, void *data), void *user_data) {
int abort = 0;
- playItem_t *it = pl_insert_file (playlist->tail[PL_MAIN], fname, &abort, cb, user_data);
+ playItem_t *it = pl_insert_file (addfiles_playlist->tail[PL_MAIN], fname, &abort, cb, user_data);
if (it) {
// pl_insert_file doesn't hold reference, don't unref here
return 0;
@@ -1452,7 +1607,7 @@ pl_add_file (const char *fname, int (*cb)(playItem_t *it, void *data), void *use
int
pl_add_dir (const char *dirname, int (*cb)(playItem_t *it, void *data), void *user_data) {
int abort = 0;
- playItem_t *it = pl_insert_dir (playlist->tail[PL_MAIN], dirname, &abort, cb, user_data);
+ playItem_t *it = pl_insert_dir (addfiles_playlist->tail[PL_MAIN], dirname, &abort, cb, user_data);
if (it) {
// pl_insert_file doesn't hold reference, don't unref here
return 0;
@@ -1461,18 +1616,25 @@ pl_add_dir (const char *dirname, int (*cb)(playItem_t *it, void *data), void *us
}
void
-pl_add_files_begin (void) {
+pl_add_files_begin (int plt) {
+ addfiles_playlist = plt_get (plt);
+ printf ("adding to playlist %d (%s)\n", plt, addfiles_playlist->title);
}
void
pl_add_files_end (void) {
+ addfiles_playlist = NULL;
}
int
plt_remove_item (playlist_t *playlist, playItem_t *it) {
if (!it)
return -1;
- streamer_song_removed_notify (it);
+
+ if (!no_remove_notify) {
+ streamer_song_removed_notify (it);
+ }
+
pl_playqueue_remove (it);
// remove from both lists
@@ -1496,8 +1658,9 @@ plt_remove_item (playlist_t *playlist, playItem_t *it) {
}
// totaltime
- if (it->_duration > 0) {
- playlist->totaltime -= it->_duration;
+ float dur = pl_get_item_duration (it);
+ if (dur > 0) {
+ playlist->totaltime -= dur;
if (playlist->totaltime < 0) {
playlist->totaltime = 0;
}
@@ -1610,12 +1773,19 @@ plt_insert_item (playlist_t *playlist, playItem_t *after, playItem_t *it) {
playlist->count[PL_MAIN]++;
// shuffle
- it->shufflerating = rand ();
+ playItem_t *prev = it->prev[PL_MAIN];
+ if (pl_order == PLAYBACK_ORDER_SHUFFLE_ALBUMS && prev && pl_find_meta (prev, "album") == pl_find_meta (it, "album") && pl_find_meta (prev, "artist") == pl_find_meta (it, "artist")) {
+ it->shufflerating = prev->shufflerating;
+ }
+ else {
+ it->shufflerating = rand ();
+ }
it->played = 0;
// totaltime
- if (it->_duration > 0) {
- playlist->totaltime += it->_duration;
+ float dur = pl_get_item_duration (it);
+ if (dur > 0) {
+ playlist->totaltime += dur;
}
GLOBAL_UNLOCK;
@@ -1624,24 +1794,16 @@ plt_insert_item (playlist_t *playlist, playItem_t *after, playItem_t *it) {
playItem_t *
pl_insert_item (playItem_t *after, playItem_t *it) {
- return plt_insert_item (playlist, after, it);
+ return plt_insert_item (addfiles_playlist ? addfiles_playlist : playlist, after, it);
}
void
pl_item_copy (playItem_t *out, playItem_t *it) {
LOCK;
- out->fname = strdup (it->fname);
- out->decoder_id = it->decoder_id;
- out->tracknum = it->tracknum;
out->startsample = it->startsample;
out->endsample = it->endsample;
- pl_set_item_duration (out, it->_duration);
out->shufflerating = it->shufflerating;
- out->filetype = it->filetype;
- out->replaygain_album_gain = it->replaygain_album_gain;
- out->replaygain_album_peak = it->replaygain_album_peak;
- out->replaygain_track_gain = it->replaygain_track_gain;
- out->replaygain_track_peak = it->replaygain_track_peak;
+ out->_duration = it->_duration;
out->started_timestamp = it->started_timestamp;
out->next[PL_MAIN] = it->next[PL_MAIN];
out->prev[PL_MAIN] = it->prev[PL_MAIN];
@@ -1653,6 +1815,7 @@ pl_item_copy (playItem_t *out, playItem_t *it) {
DB_metaInfo_t *meta = it->meta;
while (meta) {
DB_metaInfo_t *m = malloc (sizeof (DB_metaInfo_t));
+ memset (m, 0, sizeof (DB_metaInfo_t));
m->key = metacache_add_string (meta->key);
m->value = metacache_add_string (meta->value);
m->next = NULL;
@@ -1672,17 +1835,23 @@ playItem_t *
pl_item_alloc (void) {
playItem_t *it = malloc (sizeof (playItem_t));
memset (it, 0, sizeof (playItem_t));
- it->replaygain_album_peak = 1;
- it->replaygain_track_peak = 1;
it->_refc = 1;
return it;
}
+playItem_t *
+pl_item_alloc_init (const char *fname, const char *decoder_id) {
+ playItem_t *it = pl_item_alloc ();
+ pl_add_meta (it, ":URI", fname);
+ pl_add_meta (it, ":DECODER", decoder_id);
+ return it;
+}
+
void
pl_item_ref (playItem_t *it) {
LOCK;
it->_refc++;
- //trace ("\033[0;34m+it %p: refc=%d: %s\033[37;0m\n", it, it->_refc, it->fname);
+ //trace ("\033[0;34m+it %p: refc=%d: %s\033[37;0m\n", it, it->_refc, pl_find_meta (it, ":URI"));
UNLOCK;
}
@@ -1690,9 +1859,6 @@ static void
pl_item_free (playItem_t *it) {
LOCK;
if (it) {
- if (it->fname) {
- free (it->fname);
- }
while (it->meta) {
DB_metaInfo_t *m = it->meta;
it->meta = m->next;
@@ -1709,138 +1875,17 @@ void
pl_item_unref (playItem_t *it) {
LOCK;
it->_refc--;
- //trace ("\033[0;31m-it %p: refc=%d: %s\033[37;0m\n", it, it->_refc, it->fname);
+ //trace ("\033[0;31m-it %p: refc=%d: %s\033[37;0m\n", it, it->_refc, pl_find_meta (it, ":URI"));
if (it->_refc < 0) {
trace ("\033[0;31mplaylist: bad refcount on item %p\033[37;0m\n", it);
}
if (it->_refc <= 0) {
- //printf ("\033[0;31mdeleted %s\033[37;0m\n", it->fname);
+ //printf ("\033[0;31mdeleted %s\033[37;0m\n", pl_find_meta (it, ":URI"));
pl_item_free (it);
}
UNLOCK;
}
-void
-pl_add_meta (playItem_t *it, const char *key, const char *value) {
- LOCK;
- // check if it's already set
- DB_metaInfo_t *m = it->meta;
- while (m) {
- if (!strcasecmp (key, m->key)) {
- // duplicate key
- UNLOCK;
- return;
- }
- m = m->next;
- }
- // add
- char str[256];
- if (!value || !*value) {
- if (!strcasecmp (key, "title")) {
- // cut filename without path and extension
- const char *pext = it->fname + strlen (it->fname) - 1;
- while (pext >= it->fname && *pext != '.') {
- pext--;
- }
- const char *pname = pext;
- while (pname >= it->fname && *pname != '/') {
- pname--;
- }
- if (*pname == '/') {
- pname++;
- }
- strncpy (str, pname, pext-pname);
- str[pext-pname] = 0;
- value = str;
- }
- else {
- UNLOCK;
- return;
- }
- }
- m = malloc (sizeof (DB_metaInfo_t));
- m->key = metacache_add_string (key); //key;
- m->value = metacache_add_string (value); //strdup (value);
- m->next = it->meta;
- it->meta = m;
- UNLOCK;
-}
-
-void
-pl_append_meta (playItem_t *it, const char *key, const char *value) {
- const char *old = pl_find_meta (it, key);
- size_t newlen = strlen (value);
- if (!old) {
- pl_add_meta (it, key, value);
- }
- else {
- // check for duplicate data
- const char *str = old;
- int len;
- while (str) {
- char *next = strchr (str, '\n');
-
- if (next) {
- len = next - str;
- next++;
- }
- else {
- len = strlen (str);
- }
-
- if (len == newlen && !memcmp (str, value, len)) {
- return;
- }
-
- str = next;
- }
- int sz = strlen (old) + newlen + 2;
- char out[sz];
- snprintf (out, sz, "%s\n%s", old, value);
- pl_replace_meta (it, key, out);
- }
-}
-
-void
-pl_replace_meta (playItem_t *it, const char *key, const char *value) {
- LOCK;
- // check if it's already set
- DB_metaInfo_t *m = it->meta;
- while (m) {
- if (!strcasecmp (key, m->key)) {
- break;
- }
- m = m->next;
- }
- if (m) {
- metacache_remove_string (m->value);//free (m->value);
- m->value = metacache_add_string (value);//strdup (value);
- UNLOCK;
- return;
- }
- else {
- pl_add_meta (it, key, value);
- }
- UNLOCK;
-}
-
-const char *
-pl_find_meta (playItem_t *it, const char *key) {
- DB_metaInfo_t *m = it->meta;
- while (m) {
- if (!strcasecmp (key, m->key)) {
- return m->value;
- }
- m = m->next;
- }
- return NULL;
-}
-
-DB_metaInfo_t *
-pl_get_metadata (playItem_t *it) {
- return it->meta;
-}
-
int
pl_delete_selected (void) {
GLOBAL_LOCK;
@@ -1881,14 +1926,34 @@ pl_crop_selected (void) {
int
pl_save (const char *fname) {
+ GLOBAL_LOCK;
+ const char *ext = strrchr (fname, '.');
+ if (ext) {
+ DB_playlist_t **plug = deadbeef->plug_get_playlist_list ();
+ for (int i = 0; plug[i]; i++) {
+ if (plug[i]->extensions && plug[i]->load) {
+ const char **exts = plug[i]->extensions;
+ if (exts && plug[i]->save) {
+ for (int e = 0; exts[e]; e++) {
+ if (!strcasecmp (exts[e], ext+1)) {
+ int res = plug[i]->save (fname, (DB_playItem_t *)playlist->head[PL_MAIN], NULL);
+ GLOBAL_UNLOCK;
+ return res;
+ }
+ }
+ }
+ }
+ }
+ }
+
const char magic[] = "DBPL";
uint8_t majorver = PLAYLIST_MAJOR_VER;
uint8_t minorver = PLAYLIST_MINOR_VER;
FILE *fp = fopen (fname, "w+b");
if (!fp) {
+ GLOBAL_UNLOCK;
return -1;
}
- GLOBAL_LOCK;
if (fwrite (magic, 1, 4, fp) != 4) {
goto save_fail;
}
@@ -1905,29 +1970,32 @@ pl_save (const char *fname) {
for (playItem_t *it = playlist->head[PL_MAIN]; it; it = it->next[PL_MAIN]) {
uint16_t l;
uint8_t ll;
- l = strlen (it->fname);
+ const char *fname = pl_find_meta (it, ":URI");
+ l = strlen (fname);
if (fwrite (&l, 1, 2, fp) != 2) {
goto save_fail;
}
- if (fwrite (it->fname, 1, l, fp) != l) {
+ if (fwrite (fname, 1, l, fp) != l) {
goto save_fail;
}
- if (it->decoder_id) {
- ll = strlen (it->decoder_id);
+ const char *decoder_id = pl_find_meta (it, ":DECODER");
+ if (decoder_id) {
+ ll = strlen (decoder_id);
if (fwrite (&ll, 1, 1, fp) != 1) {
goto save_fail;
}
- if (fwrite (it->decoder_id, 1, ll, fp) != ll) {
+ if (fwrite (decoder_id, 1, ll, fp) != ll) {
goto save_fail;
}
}
- else {
+ else
+ {
ll = 0;
if (fwrite (&ll, 1, 1, fp) != 1) {
goto save_fail;
}
}
- l = it->tracknum;
+ l = pl_find_meta_int (it, ":TRACKNUM", 0);
if (fwrite (&l, 1, 2, fp) != 2) {
goto save_fail;
}
@@ -1940,25 +2008,33 @@ pl_save (const char *fname) {
if (fwrite (&it->_duration, 1, 4, fp) != 4) {
goto save_fail;
}
- uint8_t ft = it->filetype ? strlen (it->filetype) : 0;
+ const char *filetype = pl_find_meta (it, ":FILETYPE");
+ if (!filetype) {
+ filetype = "";
+ }
+ uint8_t ft = strlen (filetype);
if (fwrite (&ft, 1, 1, fp) != 1) {
goto save_fail;
}
if (ft) {
- if (fwrite (it->filetype, 1, ft, fp) != ft) {
+ if (fwrite (filetype, 1, ft, fp) != ft) {
goto save_fail;
}
}
- if (fwrite (&it->replaygain_album_gain, 1, 4, fp) != 4) {
+ float rg_albumgain = pl_get_item_replaygain (it, DDB_REPLAYGAIN_ALBUMGAIN);
+ float rg_albumpeak = pl_get_item_replaygain (it, DDB_REPLAYGAIN_ALBUMPEAK);
+ float rg_trackgain = pl_get_item_replaygain (it, DDB_REPLAYGAIN_TRACKGAIN);
+ float rg_trackpeak = pl_get_item_replaygain (it, DDB_REPLAYGAIN_TRACKPEAK);
+ if (fwrite (&rg_albumgain, 1, 4, fp) != 4) {
goto save_fail;
}
- if (fwrite (&it->replaygain_album_peak, 1, 4, fp) != 4) {
+ if (fwrite (&rg_albumpeak, 1, 4, fp) != 4) {
goto save_fail;
}
- if (fwrite (&it->replaygain_track_gain, 1, 4, fp) != 4) {
+ if (fwrite (&rg_trackgain, 1, 4, fp) != 4) {
goto save_fail;
}
- if (fwrite (&it->replaygain_track_peak, 1, 4, fp) != 4) {
+ if (fwrite (&rg_trackpeak, 1, 4, fp) != 4) {
goto save_fail;
}
if (fwrite (&it->_flags, 1, 4, fp) != 4) {
@@ -2001,6 +2077,39 @@ pl_save (const char *fname) {
}
}
}
+
+ // write playlist metadata
+ int16_t nm = 0;
+ DB_metaInfo_t *m;
+ for (m = playlist->meta; m; m = m->next) {
+ nm++;
+ }
+ if (fwrite (&nm, 1, 2, fp) != 2) {
+ goto save_fail;
+ }
+
+ for (m = playlist->meta; m; m = m->next) {
+ uint16_t l;
+ l = strlen (m->key);
+ if (fwrite (&l, 1, 2, fp) != 2) {
+ goto save_fail;
+ }
+ if (l) {
+ if (fwrite (m->key, 1, l, fp) != l) {
+ goto save_fail;
+ }
+ }
+ l = strlen (m->value);
+ if (fwrite (&l, 1, 2, fp) != 2) {
+ goto save_fail;
+ }
+ if (l) {
+ if (fwrite (m->value, 1, l, fp) != l) {
+ goto save_fail;
+ }
+ }
+ }
+
GLOBAL_UNLOCK;
fclose (fp);
return 0;
@@ -2090,7 +2199,27 @@ pl_load (const char *fname) {
return -1;
}
GLOBAL_LOCK;
- pl_clear ();
+ playlist_t *plt = playlist;
+
+ plt_clear (plt);
+
+ // try plugins 1st
+ const char *ext = strrchr (fname, '.');
+ if (ext) {
+ ext++;
+ DB_playlist_t **plug = plug_get_playlist_list ();
+ int p, e;
+ for (p = 0; plug[p]; p++) {
+ for (e = 0; plug[p]->extensions[e]; e++) {
+ if (plug[p]->load && !strcasecmp (ext, plug[p]->extensions[e])) {
+ DB_playItem_t *it = plug[p]->load (it, fname, NULL, NULL, NULL);
+ GLOBAL_UNLOCK;
+ return 0;
+ }
+ }
+ }
+ }
+
uint8_t majorver;
uint8_t minorver;
playItem_t *it = NULL;
@@ -2131,11 +2260,12 @@ pl_load (const char *fname) {
if (fread (&l, 1, 2, fp) != 2) {
goto load_fail;
}
- it->fname = malloc (l+1);
- if (fread (it->fname, 1, l, fp) != l) {
+ char fname[l+1];
+ if (fread (fname, 1, l, fp) != l) {
goto load_fail;
}
- it->fname[l] = 0;
+ fname[l] = 0;
+ pl_add_meta (it, ":URI", fname);
// decoder
uint8_t ll;
if (fread (&ll, 1, 1, fp) != 1) {
@@ -2144,22 +2274,20 @@ pl_load (const char *fname) {
if (ll >= 20) {
goto load_fail;
}
+ char decoder_id[20] = "";
if (ll) {
- char decoder[20];
- if (fread (decoder, 1, ll, fp) != ll) {
+ if (fread (decoder_id, 1, ll, fp) != ll) {
goto load_fail;
}
- decoder[ll] = 0;
- it->decoder_id = plug_get_decoder_id (decoder);
- }
- else {
- it->decoder_id = NULL;
+ decoder_id[ll] = 0;
+ pl_add_meta (it, ":DECODER", decoder_id);
}
// tracknum
- if (fread (&l, 1, 2, fp) != 2) {
+ int16_t tracknum;
+ if (fread (&tracknum, 1, 2, fp) != 2) {
goto load_fail;
}
- it->tracknum = l;
+ pl_set_meta_int (it, ":TRACKNUM", tracknum);
// startsample
if (fread (&it->startsample, 1, 4, fp) != 4) {
goto load_fail;
@@ -2169,12 +2297,14 @@ pl_load (const char *fname) {
goto load_fail;
}
// duration
- float d;
- if (fread (&d, 1, 4, fp) != 4) {
+ if (fread (&it->_duration, 1, 4, fp) != 4) {
goto load_fail;
}
- it->_duration = d;
- // get const filetype string from decoder
+ char s[100];
+ pl_format_time (it->_duration, s, sizeof(s));
+ pl_replace_meta (it, ":DURATION", s);
+
+ // legacy filetype support
uint8_t ft;
if (fread (&ft, 1, 1, fp) != 1) {
goto load_fail;
@@ -2185,64 +2315,70 @@ pl_load (const char *fname) {
goto load_fail;
}
ftype[ft] = 0;
- if (!strcmp (ftype, "content")) {
- it->filetype = "content";
- }
- else if (it->decoder_id) {
- DB_decoder_t *dec = plug_get_decoder_for_id (it->decoder_id);
- if (dec && dec->filetypes) {
- for (int i = 0; dec->filetypes[i]; i++) {
- if (!strcasecmp (dec->filetypes[i], ftype)) {
- it->filetype = dec->filetypes[i];
- break;
- }
- }
- }
- }
+ pl_replace_meta (it, ":FILETYPE", ftype);
}
- if (fread (&it->replaygain_album_gain, 1, 4, fp) != 4) {
+
+ float f;
+
+ if (fread (&f, 1, 4, fp) != 4) {
goto load_fail;
}
- if (fread (&it->replaygain_album_peak, 1, 4, fp) != 4) {
+ if (f != 0) {
+ pl_set_item_replaygain (it, DDB_REPLAYGAIN_ALBUMGAIN, f);
+ }
+
+ if (fread (&f, 1, 4, fp) != 4) {
goto load_fail;
}
- if (it->replaygain_album_peak == 0) {
- it->replaygain_album_peak = 1;
+ if (f == 0) {
+ f = 1;
+ }
+ if (f != 1) {
+ pl_set_item_replaygain (it, DDB_REPLAYGAIN_ALBUMPEAK, f);
}
- if (fread (&it->replaygain_track_gain, 1, 4, fp) != 4) {
+
+ if (fread (&f, 1, 4, fp) != 4) {
goto load_fail;
}
- if (fread (&it->replaygain_track_peak, 1, 4, fp) != 4) {
+ if (f != 0) {
+ pl_set_item_replaygain (it, DDB_REPLAYGAIN_TRACKGAIN, f);
+ }
+
+ if (fread (&f, 1, 4, fp) != 4) {
goto load_fail;
}
- if (it->replaygain_track_peak == 0) {
- it->replaygain_track_peak = 1;
+ if (f == 0) {
+ f = 1;
}
+ if (f != 1) {
+ pl_set_item_replaygain (it, DDB_REPLAYGAIN_TRACKPEAK, f);
+ }
+
+ uint32_t flg = 0;
if (minorver >= 2) {
- if (fread (&it->_flags, 1, 4, fp) != 4) {
+ if (fread (&flg, 1, 4, fp) != 4) {
goto load_fail;
}
}
else {
- if (it->startsample > 0 || it->endsample > 0 || it->tracknum > 0) {
- it->_flags |= DDB_IS_SUBTRACK;
+ if (it->startsample > 0 || it->endsample > 0 || tracknum > 0) {
+ flg |= DDB_IS_SUBTRACK;
}
}
+ pl_set_item_flags (it, flg);
int16_t nm = 0;
if (fread (&nm, 1, 2, fp) != 2) {
goto load_fail;
}
for (int i = 0; i < nm; i++) {
- char key[1024];
- char value[1024];
-
if (fread (&l, 1, 2, fp) != 2) {
goto load_fail;
}
- if (!l || l >= 1024) {
+ if (l < 0 || l >= 20000) {
goto load_fail;
}
+ char key[l+1];
if (fread (key, 1, l, fp) != l) {
goto load_fail;
}
@@ -2250,23 +2386,69 @@ pl_load (const char *fname) {
if (fread (&l, 1, 2, fp) != 2) {
goto load_fail;
}
- if (!l || l >= 1024) {
+ if (l<0 || l >= 20000) {
// skip
fseek (fp, l, SEEK_CUR);
}
else {
- if (fread (value, 1, l, fp) != l) {
+ char value[l+1];
+ int res = fread (value, 1, l, fp);
+ if (res != l) {
+ trace ("read error: requested %d, got %d\n", l, res);
goto load_fail;
}
value[l] = 0;
- pl_add_meta (it, key, value);
+ if (key[0] == ':') {
+ // to avoid storage conflicts -- give more priority to metadata
+ pl_replace_meta (it, key, value);
+ }
+ else {
+ pl_add_meta (it, key, value);
+ }
}
}
- pl_insert_item (playlist->tail[PL_MAIN], it);
+ plt_insert_item (plt, plt->tail[PL_MAIN], it);
pl_item_unref (it);
- trace ("last playlist item refc: %d\n", it->_refc);
it = NULL;
}
+
+ // load playlist metadata
+ int16_t nm = 0;
+ // for backwards format compatibility, don't fail if metadata is not found
+ if (fread (&nm, 1, 2, fp) == 2) {
+ for (int i = 0; i < nm; i++) {
+ int16_t l;
+ if (fread (&l, 1, 2, fp) != 2) {
+ goto load_fail;
+ }
+ if (l < 0 || l >= 20000) {
+ goto load_fail;
+ }
+ char key[l+1];
+ if (fread (key, 1, l, fp) != l) {
+ goto load_fail;
+ }
+ key[l] = 0;
+ if (fread (&l, 1, 2, fp) != 2) {
+ goto load_fail;
+ }
+ if (l<0 || l >= 20000) {
+ // skip
+ fseek (fp, l, SEEK_CUR);
+ }
+ else {
+ char value[l+1];
+ int res = fread (value, 1, l, fp);
+ if (res != l) {
+ trace ("read error: requested %d, got %d\n", l, res);
+ goto load_fail;
+ }
+ value[l] = 0;
+ plt_add_meta (playlist, key, value);
+ }
+ }
+ }
+
GLOBAL_UNLOCK;
if (fp) {
fclose (fp);
@@ -2295,7 +2477,7 @@ pl_load_all (void) {
// fprintf (stderr, "INFO: loading legacy default playlist\n");
// legacy (0.3.3 and earlier)
char defpl[1024]; // $HOME/.config/deadbeef/default.dbpl
- if (snprintf (defpl, sizeof (defpl), "%s/deadbeef/default.dbpl", confdir) > sizeof (defpl)) {
+ if (snprintf (defpl, sizeof (defpl), "%s/default.dbpl", dbconfdir) > sizeof (defpl)) {
fprintf (stderr, "error: cannot make string with default playlist path\n");
return -1;
}
@@ -2355,8 +2537,14 @@ plt_reshuffle (playlist_t *playlist, playItem_t **ppmin, playItem_t **ppmax) {
GLOBAL_LOCK;
playItem_t *pmin = NULL;
playItem_t *pmax = NULL;
+ playItem_t *prev = NULL;
for (playItem_t *it = playlist->head[PL_MAIN]; it; it = it->next[PL_MAIN]) {
- it->shufflerating = rand ();
+ if (pl_order == PLAYBACK_ORDER_SHUFFLE_ALBUMS && prev && pl_find_meta (prev, "album") == pl_find_meta (it, "album") && pl_find_meta (prev, "artist") == pl_find_meta (it, "artist")) {
+ it->shufflerating = prev->shufflerating;
+ }
+ else {
+ it->shufflerating = rand ();
+ }
if (!pmin || it->shufflerating < pmin->shufflerating) {
pmin = it;
}
@@ -2364,6 +2552,7 @@ plt_reshuffle (playlist_t *playlist, playItem_t **ppmin, playItem_t **ppmax) {
pmax = it;
}
it->played = 0;
+ prev = it;
}
if (ppmin) {
*ppmin = pmin;
@@ -2382,14 +2571,26 @@ pl_reshuffle (playItem_t **ppmin, playItem_t **ppmax) {
void
pl_delete_all_meta (playItem_t *it) {
LOCK;
- while (it->meta) {
- DB_metaInfo_t *m = it->meta;
- it->meta = m->next;
- metacache_remove_string (m->key);
- metacache_remove_string (m->value);
- free (m);
+ DB_metaInfo_t *m = it->meta;
+ DB_metaInfo_t *prev = NULL;
+ while (m) {
+ DB_metaInfo_t *next = m->next;
+ if (m->key[0] == ':') {
+ prev = m;
+ }
+ else {
+ if (prev) {
+ prev->next = next;
+ }
+ else {
+ it->meta = next;
+ }
+ metacache_remove_string (m->key);
+ metacache_remove_string (m->value);
+ free (m);
+ }
+ m = next;
}
- it->meta = NULL;
UNLOCK;
}
@@ -2408,19 +2609,61 @@ pl_set_item_duration (playItem_t *it, float duration) {
}
}
it->_duration = duration;
+ char s[100];
+ pl_format_time (it->_duration, s, sizeof(s));
+ pl_replace_meta (it, ":DURATION", s);
GLOBAL_UNLOCK;
}
float
pl_get_item_duration (playItem_t *it) {
- LOCK;
- float d = it->_duration;
- UNLOCK;
- return d;
+ return it->_duration;
+}
+
+static const char *rg_keys[] = {
+ ":REPLAYGAIN_ALBUMGAIN",
+ ":REPLAYGAIN_ALBUMPEAK",
+ ":REPLAYGAIN_TRACKGAIN",
+ ":REPLAYGAIN_TRACKPEAK"
+};
+
+void
+pl_set_item_replaygain (playItem_t *it, int idx, float value) {
+ char s[100];
+ switch (idx) {
+ case DDB_REPLAYGAIN_ALBUMGAIN:
+ case DDB_REPLAYGAIN_TRACKGAIN:
+ snprintf (s, sizeof (s), "%0.2f dB", value);
+ break;
+ case DDB_REPLAYGAIN_ALBUMPEAK:
+ case DDB_REPLAYGAIN_TRACKPEAK:
+ snprintf (s, sizeof (s), "%0.6f", value);
+ break;
+ default:
+ return;
+ }
+ pl_replace_meta (it, rg_keys[idx], s);
+}
+
+float
+pl_get_item_replaygain (playItem_t *it, int idx) {
+ if (idx < 0 || idx > DDB_REPLAYGAIN_TRACKPEAK) {
+ return 0;
+ }
+
+ switch (idx) {
+ case DDB_REPLAYGAIN_ALBUMGAIN:
+ case DDB_REPLAYGAIN_TRACKGAIN:
+ return pl_find_meta_float (it, rg_keys[idx], 0);
+ case DDB_REPLAYGAIN_ALBUMPEAK:
+ case DDB_REPLAYGAIN_TRACKPEAK:
+ return pl_find_meta_float (it, rg_keys[idx], 1);
+ }
}
int
pl_format_item_queue (playItem_t *it, char *s, int size) {
+ LOCK;
*s = 0;
int initsize = size;
const char *val = pl_find_meta (it, "_playing");
@@ -2468,9 +2711,9 @@ pl_format_item_queue (playItem_t *it, char *s, int size) {
}
if (!playqueue_count) {
+ UNLOCK;
return 0;
}
- LOCK;
int qinitsize = size;
int init = 1;
@@ -2527,7 +2770,7 @@ pl_format_duration (playItem_t *it, const char *ret, char *dur, int size) {
if (ret) {
return ret;
}
- pl_format_time (it->_duration, dur, size);
+ pl_format_time (pl_get_item_duration (it), dur, size);
return dur;
}
@@ -2598,9 +2841,28 @@ pl_format_title_int (const char *escape_chars, playItem_t *it, int idx, char *s,
if (*fmt == 0) {
break;
}
- else if (!it && !strchr ("V", *fmt)) {
+ else if (!it && *fmt != 'V') {
// only %V (version) works without track pointer
}
+ else if (*fmt == '@') {
+ const char *e = fmt;
+ e++;
+ while (*e && *e != '@') {
+ e++;
+ }
+ if (*e == '@') {
+ char nm[100];
+ int l = e-fmt-1;
+ l = min (l, sizeof (nm)-1);
+ strncpy (nm, fmt+1, l);
+ nm[l] = 0;
+ meta = pl_find_meta (it, nm);
+ if (!meta) {
+ meta = "?";
+ }
+ fmt = e;
+ }
+ }
else if (*fmt == 'a') {
meta = pl_find_meta (it, "artist");
if (!meta) {
@@ -2610,7 +2872,25 @@ pl_format_title_int (const char *escape_chars, playItem_t *it, int idx, char *s,
else if (*fmt == 't') {
meta = pl_find_meta (it, "title");
if (!meta) {
- meta = "?";
+ const char *f = pl_find_meta (it, ":URI");
+ const char *start = strrchr (f, '/');
+ if (start) {
+ start++;
+ }
+ else {
+ start = f;
+ }
+ const char *end = strrchr (start, '.');
+ if (end) {
+ int n = end-start;
+ n = min (end-start, sizeof (dirname)-1);
+ strncpy (dirname, start, n);
+ dirname[n] = 0;
+ meta = dirname;
+ }
+ else {
+ meta = "?";
+ }
}
}
else if (*fmt == 'b') {
@@ -2621,12 +2901,35 @@ pl_format_title_int (const char *escape_chars, playItem_t *it, int idx, char *s,
}
else if (*fmt == 'B') {
meta = pl_find_meta (it, "band");
+ if (!meta) {
+ meta = pl_find_meta (it, "album artist");
+ if (!meta) {
+ meta = pl_find_meta (it, "albumartist");
+ if (!meta) {
+ meta = pl_find_meta (it, "artist");
+ }
+ }
+ }
}
else if (*fmt == 'C') {
meta = pl_find_meta (it, "composer");
}
else if (*fmt == 'n') {
meta = pl_find_meta (it, "track");
+ if (meta) {
+ // check if it's numbers only
+ const char *p = meta;
+ while (*p) {
+ if (!isdigit (*p)) {
+ break;
+ }
+ p++;
+ }
+ if (!(*p)) {
+ snprintf (fno, sizeof (fno), "%02d", atoi (meta));
+ meta = fno;
+ }
+ }
}
else if (*fmt == 'N') {
meta = pl_find_meta (it, "numtracks");
@@ -2659,16 +2962,18 @@ pl_format_title_int (const char *escape_chars, playItem_t *it, int idx, char *s,
}
}
else if (*fmt == 'f') {
- meta = it->fname + strlen (it->fname) - 1;
- while (meta > it->fname && (*meta) != '/') {
- meta--;
- }
- if (*meta == '/') {
+ const char *f = pl_find_meta (it, ":URI");
+ meta = strrchr (f, '/');
+ if (meta) {
meta++;
}
+ else {
+ meta = f;
+ }
+ printf ("meta: %s\n", meta);
}
else if (*fmt == 'F') {
- meta = it->fname;
+ meta = pl_find_meta (it, ":URI");
}
else if (*fmt == 'T') {
char *t = tags;
@@ -2715,17 +3020,15 @@ pl_format_title_int (const char *escape_chars, playItem_t *it, int idx, char *s,
}
else if (*fmt == 'd') {
// directory
- const char *end = it->fname + strlen (it->fname) - 1;
- while (end > it->fname && (*end) != '/') {
- end--;
- }
- if (*end != '/') {
+ const char *f = pl_find_meta (it, ":URI");
+ const char *end = strrchr (f, '/');
+ if (!end) {
meta = ""; // got relative path without folder (should not happen)
}
else {
const char *start = end;
start--;
- while (start > it->fname && (*start != '/')) {
+ while (start > f && (*start != '/')) {
start--;
}
@@ -2742,19 +3045,17 @@ pl_format_title_int (const char *escape_chars, playItem_t *it, int idx, char *s,
}
}
else if (*fmt == 'D') {
+ const char *f = pl_find_meta (it, ":URI");
// directory with path
- const char *end = it->fname + strlen (it->fname) - 1;
- while (end > it->fname && (*end) != '/') {
- end--;
- }
- if (*end != '/') {
+ const char *end = strrchr (f, '/');
+ if (!end) {
meta = ""; // got relative path without folder (should not happen)
}
else {
// copy
- int len = end - it->fname;
+ int len = end - f;
len = min (len, sizeof (dirname)-1);
- strncpy (dirname, it->fname, len);
+ strncpy (dirname, f, len);
dirname[len] = 0;
meta = dirname;
}
@@ -2845,10 +3146,37 @@ static int pl_sort_ascending;
static int pl_sort_id;
static const char *pl_sort_format;
+int
+strcasecmp_numeric (const char *a, const char *b) {
+ if (isdigit (*a) && isdigit (*b)) {
+ int anum = *a-'0';
+ const char *ae = a+1;
+ while (*ae && isdigit (*ae)) {
+ anum *= 10;
+ anum += *ae-'0';
+ ae++;
+ }
+ int bnum = *b-'0';
+ const char *be = b+1;
+ while (*be && isdigit (*be)) {
+ bnum *= 10;
+ bnum += *be-'0';
+ be++;
+ }
+ if (anum == bnum) {
+ return u8_strcasecmp (ae, be);
+ }
+ return anum - bnum;
+ }
+ return u8_strcasecmp (a,b);
+}
+
static int
pl_sort_compare_str (playItem_t *a, playItem_t *b) {
if (pl_sort_is_duration) {
- return pl_sort_ascending ? b->_duration * 100000 - a->_duration * 100000 : a->_duration * 100000 - b->_duration * 100000;
+ float dur_a = a->_duration * 100000;
+ float dur_b = b->_duration * 100000;
+ return !pl_sort_ascending ? dur_b - dur_a : dur_a - dur_b;
}
else if (pl_sort_is_track) {
int t1;
@@ -2868,14 +3196,18 @@ pl_sort_compare_str (playItem_t *a, playItem_t *b) {
else {
t2 = t ? atoi (t) : -1;
}
- return pl_sort_ascending ? t2 - t1 : t1 - t2;
+ return !pl_sort_ascending ? t2 - t1 : t1 - t2;
}
else {
char tmp1[1024];
char tmp2[1024];
pl_format_title (a, -1, tmp1, sizeof (tmp1), pl_sort_id, pl_sort_format);
pl_format_title (b, -1, tmp2, sizeof (tmp2), pl_sort_id, pl_sort_format);
- return pl_sort_ascending ? strcmp (tmp2, tmp1) : strcmp (tmp1, tmp2);
+ int res = strcasecmp_numeric (tmp1, tmp2);
+ if (!pl_sort_ascending) {
+ res = -res;
+ }
+ return res;
}
}
@@ -2931,6 +3263,9 @@ pl_sort (int iter, int id, const char *format, int ascending) {
}
prev = it;
}
+
+ playlist->tail[iter] = array[playlist->count[iter]-1];
+
free (array);
struct timeval tm2;
@@ -3028,6 +3363,7 @@ pl_set_cursor (int iter, int cursor) {
void
pl_move_items (int iter, int plt_from, playItem_t *drop_before, uint32_t *indexes, int count) {
GLOBAL_LOCK;
+
playlist_t *playlist = playlists_head;
playlist_t *to = plt_get_curr_ptr ();
@@ -3041,6 +3377,9 @@ pl_move_items (int iter, int plt_from, playItem_t *drop_before, uint32_t *indexe
return;
}
+ // don't let streamer think that current song was removed
+ no_remove_notify = 1;
+
// unlink items from playlist, and link together
playItem_t *head = NULL;
playItem_t *tail = NULL;
@@ -3071,6 +3410,7 @@ pl_move_items (int iter, int plt_from, playItem_t *drop_before, uint32_t *indexe
processed++;
}
}
+ no_remove_notify = 0;
GLOBAL_UNLOCK;
}
@@ -3136,7 +3476,7 @@ pl_search_process (const char *text) {
if (*text) {
for (DB_metaInfo_t *m = it->meta; m; m = m->next) {
if (strcasecmp (m->key, "cuesheet") && utfcasestr (m->value, text)) {
- //fprintf (stderr, "%s -> %s match (%s.%s)\n", text, m->value, it->fname, m->key);
+ //fprintf (stderr, "%s -> %s match (%s.%s)\n", text, m->value, pl_find_meta (it, ":URI"), m->key);
// add to list
it->next[PL_SEARCH] = NULL;
if (playlist->tail[PL_SEARCH]) {
@@ -3271,21 +3611,17 @@ pl_playqueue_getcount (void) {
void
pl_items_copy_junk (playItem_t *from, playItem_t *first, playItem_t *last) {
LOCK;
- const char *metainfo[] = {
- "year", "genre", "copyright", "vendor", "comment", "tags", "numtracks", "band", "performer", "composer", "disc", "title", "artist", "album", NULL
- };
- for (int m = 0; metainfo[m]; m++) {
- const char *data = pl_find_meta (from, metainfo[m]);
- if (data) {
- playItem_t *i;
- for (i = first; ; i = i->next[PL_MAIN]) {
- i->_flags = from->_flags; // stupid
- pl_add_meta (i, metainfo[m], data);
- if (i == last) {
- break;
- }
+ DB_metaInfo_t *meta = from->meta;
+ while (meta) {
+ playItem_t *i;
+ for (i = first; ; i = i->next[PL_MAIN]) {
+ i->_flags = from->_flags;
+ pl_add_meta (i, meta->key, meta->value);
+ if (i == last) {
+ break;
}
}
+ meta = meta->next;
}
UNLOCK;
}
@@ -3302,5 +3638,10 @@ void
pl_set_item_flags (playItem_t *it, uint32_t flags) {
LOCK;
it->_flags = flags;
+
+ char s[200];
+ pl_format_title (it, -1, s, sizeof (s), -1, "%T");
+ pl_replace_meta (it, ":TAGS", s);
+ pl_replace_meta (it, ":HAS_EMBEDDED_CUESHEET", (flags & DDB_HAS_EMBEDDED_CUESHEET) ? _("Yes") : _("No"));
UNLOCK;
}
diff --git a/playlist.h b/playlist.h
index d8fdb6c9..c96c1870 100644
--- a/playlist.h
+++ b/playlist.h
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -23,22 +23,20 @@
#define PL_MAX_ITERATORS 2
+// predefined properties stored in metadata for storage unification:
+// :URI - full pathname
+// :DECODER - decoder id
+// :TRACKNUM - subsong index (sid, nsf, cue, etc)
+// :DURATION - length in seconds
+
typedef struct playItem_s {
- char *fname; // full pathname
- const char *decoder_id;
- int tracknum; // used for stuff like sid, nsf, cue (will be ignored by most codecs)
int startsample;
int endsample;
int shufflerating; // sort order for shuffle mode
float playtime; // total playtime
time_t started_timestamp; // result of calling time(NULL)
- const char *filetype; // e.g. MP3 or OGG
- float replaygain_album_gain;
- float replaygain_album_peak;
- float replaygain_track_gain;
- float replaygain_track_peak;
// private area, must not be visible to plugins
- float _duration; // in seconds
+ float _duration;
uint32_t _flags;
int _refc;
struct playItem_s *next[PL_MAX_ITERATORS]; // next item in linked list
@@ -51,12 +49,13 @@ typedef struct playItem_s {
typedef struct playlist_s {
char *title;
+ struct playlist_s *next;
int count[2];
float totaltime;
playItem_t *head[PL_MAX_ITERATORS]; // head of linked list
playItem_t *tail[PL_MAX_ITERATORS]; // tail of linked list
int current_row[PL_MAX_ITERATORS]; // current row (cursor)
- struct playlist_s *next;
+ struct DB_metaInfo_s *meta; // linked list storing metainfo
} playlist_t;
// global playlist control functions
@@ -128,10 +127,10 @@ int
plt_get_idx_of (playlist_t *plt);
int
-plt_get_title (int plt, char *buffer, int bufsize);
+plt_get_title (playlist_t *plt, char *buffer, int bufsize);
int
-plt_set_title (int plt, const char *title);
+plt_set_title (playlist_t *plt, const char *title);
// moves playlist #from to position #to
void
@@ -148,7 +147,7 @@ int
pl_add_file (const char *fname, int (*cb)(playItem_t *it, void *data), void *user_data);
void
-pl_add_files_begin (void);
+pl_add_files_begin (int plt);
void
pl_add_files_end (void);
@@ -162,12 +161,18 @@ pl_insert_file (playItem_t *after, const char *fname, int *pabort, int (*cb)(pla
playItem_t *
pl_insert_item (playItem_t *after, playItem_t *it);
+playItem_t *
+plt_insert_item (playlist_t *playlist, playItem_t *after, playItem_t *it);
+
int
pl_remove_item (playItem_t *i);
playItem_t *
pl_item_alloc (void);
+playItem_t *
+pl_item_alloc_init (const char *fname, const char *decoder_id);
+
void
pl_item_ref (playItem_t *it);
@@ -212,10 +217,25 @@ pl_append_meta (playItem_t *it, const char *key, const char *value);
const char *
pl_find_meta (playItem_t *it, const char *key);
+int
+pl_find_meta_int (playItem_t *it, const char *key, int def);
+
+float
+pl_find_meta_float (playItem_t *it, const char *key, float def);
+
void
pl_replace_meta (playItem_t *it, const char *key, const char *value);
void
+pl_set_meta_int (playItem_t *it, const char *key, int value);
+
+void
+pl_set_meta_float (playItem_t *it, const char *key, float value);
+
+void
+pl_delete_meta (playItem_t *it, const char *key);
+
+void
pl_delete_all_meta (playItem_t *it);
// returns index of 1st deleted item
@@ -259,6 +279,12 @@ pl_set_item_duration (playItem_t *it, float duration);
float
pl_get_item_duration (playItem_t *it);
+void
+pl_set_item_replaygain (playItem_t *it, int idx, float value);
+
+float
+pl_get_item_replaygain (playItem_t *it, int idx);
+
uint32_t
pl_get_item_flags (playItem_t *it);
@@ -347,6 +373,15 @@ void
pl_items_copy_junk (struct playItem_s *from, struct playItem_s *first, struct playItem_s *last);
struct DB_metaInfo_s *
-pl_get_metadata (playItem_t *it);
+pl_get_metadata_head (playItem_t *it);
+
+void
+pl_delete_metadata (playItem_t *it, struct DB_metaInfo_s *meta);
+
+void
+pl_set_order (int order);
+
+int
+pl_get_order (void);
#endif // __PLAYLIST_H
diff --git a/plmeta.c b/plmeta.c
new file mode 100644
index 00000000..ed1329e4
--- /dev/null
+++ b/plmeta.c
@@ -0,0 +1,232 @@
+/*
+ DeaDBeeF - ultimate music player for GNU/Linux systems with X11
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+#include <string.h>
+#include <stdlib.h>
+#include "playlist.h"
+#include "deadbeef.h"
+#include "metacache.h"
+
+#define LOCK {pl_lock();}
+#define UNLOCK {pl_unlock();}
+
+void
+pl_add_meta (playItem_t *it, const char *key, const char *value) {
+ LOCK;
+ // check if it's already set
+ DB_metaInfo_t *tail = NULL;
+ DB_metaInfo_t *m = it->meta;
+ while (m) {
+ if (!strcasecmp (key, m->key)) {
+ // duplicate key
+ UNLOCK;
+ return;
+ }
+ tail = m;
+ m = m->next;
+ }
+ // add
+ char str[256];
+ if (!value || !*value) {
+ UNLOCK;
+ return;
+#if 0
+ if (!strcasecmp (key, "title")) {
+ // cut filename without path and extension
+ const char *pext = pl_find_meta (it, ":URI") + strlen (pl_find_meta (it, ":URI")) - 1;
+ while (pext >= pl_find_meta (it, ":URI") && *pext != '.') {
+ pext--;
+ }
+ const char *pname = pext;
+ while (pname >= pl_find_meta (it, ":URI") && *pname != '/') {
+ pname--;
+ }
+ if (*pname == '/') {
+ pname++;
+ }
+ strncpy (str, pname, pext-pname);
+ str[pext-pname] = 0;
+ value = str;
+ }
+ else {
+ UNLOCK;
+ return;
+ }
+#endif
+ }
+ m = malloc (sizeof (DB_metaInfo_t));
+ memset (m, 0, sizeof (DB_metaInfo_t));
+ m->key = metacache_add_string (key); //key;
+ m->value = metacache_add_string (value); //strdup (value);
+
+ if (tail) {
+ tail->next = m;
+ }
+ else {
+ it->meta = m;
+ }
+ UNLOCK;
+}
+
+void
+pl_append_meta (playItem_t *it, const char *key, const char *value) {
+ const char *old = pl_find_meta (it, key);
+ size_t newlen = strlen (value);
+ if (!old) {
+ pl_add_meta (it, key, value);
+ }
+ else {
+ // check for duplicate data
+ const char *str = old;
+ int len;
+ while (str) {
+ char *next = strchr (str, '\n');
+
+ if (next) {
+ len = next - str;
+ next++;
+ }
+ else {
+ len = strlen (str);
+ }
+
+ if (len == newlen && !memcmp (str, value, len)) {
+ return;
+ }
+
+ str = next;
+ }
+ int sz = strlen (old) + newlen + 2;
+ char out[sz];
+ snprintf (out, sz, "%s\n%s", old, value);
+ pl_replace_meta (it, key, out);
+ }
+}
+
+void
+pl_replace_meta (playItem_t *it, const char *key, const char *value) {
+ LOCK;
+ // check if it's already set
+ DB_metaInfo_t *m = it->meta;
+ while (m) {
+ if (!strcasecmp (key, m->key)) {
+ break;
+ }
+ m = m->next;
+ }
+ if (m) {
+ metacache_remove_string (m->value);
+ m->value = metacache_add_string (value);
+ UNLOCK;
+ return;
+ }
+ else {
+ pl_add_meta (it, key, value);
+ }
+ UNLOCK;
+}
+
+void
+pl_set_meta_int (playItem_t *it, const char *key, int value) {
+ char s[20];
+ snprintf (s, sizeof (s), "%d", value);
+ pl_replace_meta (it, key, s);
+}
+
+void
+pl_set_meta_float (playItem_t *it, const char *key, float value) {
+ char s[20];
+ snprintf (s, sizeof (s), "%f", value);
+ pl_replace_meta (it, key, s);
+}
+
+void
+pl_delete_meta (playItem_t *it, const char *key) {
+ DB_metaInfo_t *prev = NULL;
+ DB_metaInfo_t *m = it->meta;
+ while (m) {
+ if (!strcasecmp (key, m->key)) {
+ if (prev) {
+ prev->next = m->next;
+ }
+ else {
+ it->meta = m->next;
+ }
+ metacache_remove_string (m->key);
+ metacache_remove_string (m->value);
+ free (m);
+ break;
+ }
+ prev = m;
+ m = m->next;
+ }
+}
+
+const char *
+pl_find_meta (playItem_t *it, const char *key) {
+ DB_metaInfo_t *m = it->meta;
+ while (m) {
+ if (!strcasecmp (key, m->key)) {
+ return m->value;
+ }
+ m = m->next;
+ }
+ return NULL;
+}
+
+int
+pl_find_meta_int (playItem_t *it, const char *key, int def) {
+ const char *val = pl_find_meta (it, key);
+ return val ? atoi (val) : def;
+}
+
+float
+pl_find_meta_float (playItem_t *it, const char *key, float def) {
+ const char *val = pl_find_meta (it, key);
+ return val ? atof (val) : def;
+}
+
+DB_metaInfo_t *
+pl_get_metadata_head (playItem_t *it) {
+ return it->meta;
+}
+
+void
+pl_delete_metadata (playItem_t *it, DB_metaInfo_t *meta) {
+ DB_metaInfo_t *prev = NULL;
+ DB_metaInfo_t *m = it->meta;
+ while (m) {
+ if (m == meta) {
+ if (prev) {
+ prev->next = m->next;
+ }
+ else {
+ it->meta = m->next;
+ }
+ metacache_remove_string (m->key);
+ metacache_remove_string (m->value);
+ free (m);
+ break;
+ }
+ prev = m;
+ m = m->next;
+ }
+}
+
+
diff --git a/pltmeta.c b/pltmeta.c
new file mode 100644
index 00000000..b3895b26
--- /dev/null
+++ b/pltmeta.c
@@ -0,0 +1,211 @@
+/*
+ DeaDBeeF - ultimate music player for GNU/Linux systems with X11
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+#include <string.h>
+#include <stdlib.h>
+#include "playlist.h"
+#include "deadbeef.h"
+#include "metacache.h"
+#include "pltmeta.h"
+
+#define LOCK {pl_lock();}
+#define UNLOCK {pl_unlock();}
+
+void
+plt_add_meta (playlist_t *it, const char *key, const char *value) {
+ LOCK;
+ // check if it's already set
+ DB_metaInfo_t *tail = NULL;
+ DB_metaInfo_t *m = it->meta;
+ while (m) {
+ if (!strcasecmp (key, m->key)) {
+ // duplicate key
+ UNLOCK;
+ return;
+ }
+ tail = m;
+ m = m->next;
+ }
+ // add
+ char str[256];
+ if (!value || !*value) {
+ UNLOCK;
+ return;
+ }
+ m = malloc (sizeof (DB_metaInfo_t));
+ memset (m, 0, sizeof (DB_metaInfo_t));
+ m->key = metacache_add_string (key); //key;
+ m->value = metacache_add_string (value); //strdup (value);
+
+ if (tail) {
+ tail->next = m;
+ }
+ else {
+ it->meta = m;
+ }
+ UNLOCK;
+}
+
+void
+plt_append_meta (playlist_t *it, const char *key, const char *value) {
+ const char *old = plt_find_meta (it, key);
+ size_t newlen = strlen (value);
+ if (!old) {
+ plt_add_meta (it, key, value);
+ }
+ else {
+ // check for duplicate data
+ const char *str = old;
+ int len;
+ while (str) {
+ char *next = strchr (str, '\n');
+
+ if (next) {
+ len = next - str;
+ next++;
+ }
+ else {
+ len = strlen (str);
+ }
+
+ if (len == newlen && !memcmp (str, value, len)) {
+ return;
+ }
+
+ str = next;
+ }
+ int sz = strlen (old) + newlen + 2;
+ char out[sz];
+ snprintf (out, sz, "%s\n%s", old, value);
+ plt_replace_meta (it, key, out);
+ }
+}
+
+void
+plt_replace_meta (playlist_t *it, const char *key, const char *value) {
+ LOCK;
+ // check if it's already set
+ DB_metaInfo_t *m = it->meta;
+ while (m) {
+ if (!strcasecmp (key, m->key)) {
+ break;
+ }
+ m = m->next;
+ }
+ if (m) {
+ metacache_remove_string (m->value);
+ m->value = metacache_add_string (value);
+ UNLOCK;
+ return;
+ }
+ else {
+ plt_add_meta (it, key, value);
+ }
+ UNLOCK;
+}
+
+void
+plt_set_meta_int (playlist_t *it, const char *key, int value) {
+ char s[20];
+ snprintf (s, sizeof (s), "%d", value);
+ plt_replace_meta (it, key, s);
+}
+
+void
+plt_set_meta_float (playlist_t *it, const char *key, float value) {
+ char s[20];
+ snprintf (s, sizeof (s), "%f", value);
+ plt_replace_meta (it, key, s);
+}
+
+void
+plt_delete_meta (playlist_t *it, const char *key) {
+ DB_metaInfo_t *prev = NULL;
+ DB_metaInfo_t *m = it->meta;
+ while (m) {
+ if (!strcasecmp (key, m->key)) {
+ if (prev) {
+ prev->next = m->next;
+ }
+ else {
+ it->meta = m->next;
+ }
+ metacache_remove_string (m->key);
+ metacache_remove_string (m->value);
+ free (m);
+ break;
+ }
+ prev = m;
+ m = m->next;
+ }
+}
+
+const char *
+plt_find_meta (playlist_t *it, const char *key) {
+ DB_metaInfo_t *m = it->meta;
+ while (m) {
+ if (!strcasecmp (key, m->key)) {
+ return m->value;
+ }
+ m = m->next;
+ }
+ return NULL;
+}
+
+int
+plt_find_meta_int (playlist_t *it, const char *key, int def) {
+ const char *val = plt_find_meta (it, key);
+ return val ? atoi (val) : def;
+}
+
+float
+plt_find_meta_float (playlist_t *it, const char *key, float def) {
+ const char *val = plt_find_meta (it, key);
+ return val ? atof (val) : def;
+}
+
+DB_metaInfo_t *
+plt_get_metadata_head (playlist_t *it) {
+ return it->meta;
+}
+
+void
+plt_delete_metadata (playlist_t *it, DB_metaInfo_t *meta) {
+ DB_metaInfo_t *prev = NULL;
+ DB_metaInfo_t *m = it->meta;
+ while (m) {
+ if (m == meta) {
+ if (prev) {
+ prev->next = m->next;
+ }
+ else {
+ it->meta = m->next;
+ }
+ metacache_remove_string (m->key);
+ metacache_remove_string (m->value);
+ free (m);
+ break;
+ }
+ prev = m;
+ m = m->next;
+ }
+}
+
+
+
diff --git a/pltmeta.h b/pltmeta.h
new file mode 100644
index 00000000..594d40db
--- /dev/null
+++ b/pltmeta.h
@@ -0,0 +1,55 @@
+/*
+ DeaDBeeF - ultimate music player for GNU/Linux systems with X11
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+#ifndef __PLMETA_H
+#define __PLMETA_H
+
+void
+plt_add_meta (playlist_t *it, const char *key, const char *value);
+
+void
+plt_append_meta (playlist_t *it, const char *key, const char *value);
+
+void
+plt_replace_meta (playlist_t *it, const char *key, const char *value);
+
+void
+plt_set_meta_int (playlist_t *it, const char *key, int value);
+
+void
+plt_set_meta_float (playlist_t *it, const char *key, float value);
+
+void
+plt_delete_meta (playlist_t *it, const char *key);
+
+const char *
+plt_find_meta (playlist_t *it, const char *key);
+
+int
+plt_find_meta_int (playlist_t *it, const char *key, int def);
+
+float
+plt_find_meta_float (playlist_t *it, const char *key, float def);
+
+DB_metaInfo_t *
+plt_get_metadata_head (playlist_t *it);
+
+void
+plt_delete_metadata (playlist_t *it, DB_metaInfo_t *meta);
+
+#endif
diff --git a/plugins.c b/plugins.c
index 331baab9..09f83c43 100644
--- a/plugins.c
+++ b/plugins.c
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@@ -38,11 +38,13 @@
#include "playlist.h"
#include "volume.h"
#include "streamer.h"
-#include "playback.h"
#include "common.h"
#include "conf.h"
#include "junklib.h"
#include "vfs.h"
+#include "premix.h"
+#include "dsppreset.h"
+#include "pltmeta.h"
#define trace(...) { fprintf(stderr, __VA_ARGS__); }
//#define trace(fmt,...)
@@ -68,12 +70,6 @@ static DB_functions_t deadbeef_api = {
.md5_append = (void (*)(DB_md5_t *s, const uint8_t *daya, int nbytes))md5_append,
.md5_finish = (void (*)(DB_md5_t *s, uint8_t digest[16]))md5_finish,
.get_output = plug_get_output,
- .playback_next = plug_playback_next,
- .playback_prev = plug_playback_prev,
- .playback_pause = plug_playback_pause,
- .playback_stop = plug_playback_stop,
- .playback_play = plug_playback_play,
- .playback_random = plug_playback_random,
.playback_get_pos = plug_playback_get_pos,
.playback_set_pos = plug_playback_set_pos,
// streamer access
@@ -88,13 +84,21 @@ static DB_functions_t deadbeef_api = {
.streamer_get_apx_bitrate = streamer_get_apx_bitrate,
.streamer_get_current_fileinfo = streamer_get_current_fileinfo,
.streamer_get_current_playlist = streamer_get_current_playlist,
- // process control
+ .streamer_get_dsp_chain = streamer_get_dsp_chain,
+ .streamer_set_dsp_chain = streamer_set_dsp_chain,
+ .streamer_dsp_refresh = streamer_dsp_refresh,
+ // folders
.get_config_dir = plug_get_config_dir,
- .quit = plug_quit,
+ .get_prefix = plug_get_prefix,
+ .get_doc_dir = plug_get_doc_dir,
+ .get_plugin_dir = plug_get_plugin_dir,
+ .get_pixmap_dir = plug_get_pixmap_dir,
// threading
.thread_start = thread_start,
.thread_start_low_priority = thread_start_low_priority,
.thread_join = thread_join,
+ .thread_detach = thread_detach,
+ .thread_exit = thread_exit,
.mutex_create = mutex_create,
.mutex_create_nonrecursive = mutex_create_nonrecursive,
.mutex_free = mutex_free,
@@ -111,18 +115,29 @@ static DB_functions_t deadbeef_api = {
.plt_get_sel_count = plt_get_sel_count,
.plt_add = plt_add,
.plt_remove = plt_remove,
- .plt_free = plt_free,
.plt_set_curr = plt_set_curr,
.plt_get_curr = plt_get_curr,
- .plt_get_title = plt_get_title,
- .plt_set_title = plt_set_title,
.plt_move = plt_move,
+ .plt_get_handle = (void *(*)(int idx))plt_get,
+ .plt_get_title = (int (*)(void *handle, char *buffer, int sz))plt_get_title,
+ .plt_set_title = (int (*)(void *handle, const char *buffer))plt_set_title,
+
+ // playlist metadata
+ .plt_add_meta = (void (*) (void *handle, const char *key, const char *value))plt_add_meta,
+ .plt_replace_meta = (void (*) (void *handle, const char *key, const char *value))plt_replace_meta,
+ .plt_append_meta = (void (*) (void *handle, const char *key, const char *value))plt_append_meta,
+ .plt_set_meta_int = (void (*) (void *handle, const char *key, int value))plt_set_meta_int,
+ .plt_set_meta_float = (void (*) (void *handle, const char *key, float value))plt_set_meta_float,
+ .plt_find_meta = (const char *(*) (void *handle, const char *key))plt_find_meta,
+ .plt_get_metadata_head = (DB_metaInfo_t * (*) (void *handle))plt_get_metadata_head,
+
// playlist access
.pl_lock = pl_lock,
.pl_unlock = pl_unlock,
.plt_lock = plt_lock,
.plt_unlock = plt_unlock,
.pl_item_alloc = (DB_playItem_t* (*)(void))pl_item_alloc,
+ .pl_item_alloc_init = (DB_playItem_t* (*)(const char *fname, const char *decoder_id))pl_item_alloc_init,
.pl_item_ref = (void (*)(DB_playItem_t *))pl_item_ref,
.pl_item_unref = (void (*)(DB_playItem_t *))pl_item_unref,
.pl_item_copy = (void (*)(DB_playItem_t *, DB_playItem_t *))pl_item_copy,
@@ -143,6 +158,8 @@ static DB_functions_t deadbeef_api = {
.pl_set_item_flags = (void (*) (DB_playItem_t *it, uint32_t flags))pl_set_item_flags,
.pl_sort = pl_sort,
.pl_items_copy_junk = (void (*)(DB_playItem_t *from, DB_playItem_t *first, DB_playItem_t *last))pl_items_copy_junk,
+ .pl_set_item_replaygain = (void (*)(DB_playItem_t *it, int idx, float value))pl_set_item_replaygain,
+ .pl_get_item_replaygain = (float (*)(DB_playItem_t *it, int idx))pl_get_item_replaygain,
.pl_get_totaltime = pl_get_totaltime,
.pl_getcount = pl_getcount,
.pl_delete_selected = pl_delete_selected,
@@ -172,10 +189,16 @@ static DB_functions_t deadbeef_api = {
// metainfo
.pl_add_meta = (void (*) (DB_playItem_t *, const char *, const char *))pl_add_meta,
.pl_append_meta = (void (*) (DB_playItem_t *, const char *, const char *))pl_append_meta,
+ .pl_set_meta_int = (void (*) (DB_playItem_t *it, const char *key, int value))pl_set_meta_int,
+ .pl_set_meta_float = (void (*) (DB_playItem_t *it, const char *key, float value))pl_set_meta_float,
+ .pl_delete_meta = (void (*)(DB_playItem_t *, const char *key))pl_delete_meta,
.pl_find_meta = (const char *(*) (DB_playItem_t *, const char *))pl_find_meta,
+ .pl_find_meta_int = (int (*) (DB_playItem_t *it, const char *key, int def))pl_find_meta_int,
+ .pl_find_meta_float = (float (*) (DB_playItem_t *it, const char *key, float def))pl_find_meta_float,
.pl_replace_meta = (void (*) (DB_playItem_t *, const char *, const char *))pl_replace_meta,
.pl_delete_all_meta = (void (*) (DB_playItem_t *it))pl_delete_all_meta,
- .pl_get_metadata = (DB_metaInfo_t *(*)(DB_playItem_t *it))pl_get_metadata,
+ .pl_get_metadata_head = (DB_metaInfo_t *(*)(DB_playItem_t *it))pl_get_metadata_head,
+ .pl_delete_metadata = (void (*)(DB_playItem_t *, DB_metaInfo_t *))pl_delete_metadata,
// cuesheet support
.pl_insert_cue_from_buffer = (DB_playItem_t *(*) (DB_playItem_t *after, DB_playItem_t *origin, const uint8_t *buffer, int buffersize, int numsamples, int samplerate))pl_insert_cue_from_buffer,
.pl_insert_cue = (DB_playItem_t *(*)(DB_playItem_t *after, DB_playItem_t *origin, int numsamples, int samplerate))pl_insert_cue,
@@ -234,21 +257,28 @@ static DB_functions_t deadbeef_api = {
// message passing
.sendmessage = messagepump_push,
// configuration access
+ .conf_lock = conf_lock,
+ .conf_unlock = conf_unlock,
+ .conf_get_str_fast = conf_get_str_fast,
.conf_get_str = conf_get_str,
.conf_get_float = conf_get_float,
.conf_get_int = conf_get_int,
+ .conf_get_int64 = conf_get_int64,
.conf_set_str = conf_set_str,
.conf_set_int = conf_set_int,
+ .conf_set_int64 = conf_set_int64,
.conf_set_float = conf_set_float,
.conf_find = conf_find,
.conf_remove_items = conf_remove_items,
.conf_save = conf_save,
// plugin communication
.plug_get_decoder_list = plug_get_decoder_list,
+ .plug_get_vfs_list = plug_get_vfs_list,
.plug_get_output_list = plug_get_output_list,
.plug_get_dsp_list = plug_get_dsp_list,
+ .plug_get_playlist_list = plug_get_playlist_list,
.plug_get_list = plug_get_list,
- .plug_activate = plug_activate,
+ .plug_get_gui_names = plug_get_gui_names,
.plug_get_decoder_id = plug_get_decoder_id,
.plug_remove_decoder_id = plug_remove_decoder_id,
.plug_get_for_id = plug_get_for_id,
@@ -258,6 +288,12 @@ static DB_functions_t deadbeef_api = {
.plug_trigger_event_playlistchanged = plug_trigger_event_playlistchanged,
// misc utilities
.is_local_file = plug_is_local_file,
+ // pcm utilities
+ .pcm_convert = pcm_convert,
+ // dsp preset management
+ .dsp_preset_load = dsp_preset_load,
+ .dsp_preset_save = dsp_preset_save,
+ .dsp_preset_free = dsp_preset_free
};
DB_functions_t *deadbeef = &deadbeef_api;
@@ -267,6 +303,26 @@ plug_get_config_dir (void) {
return dbconfdir;
}
+const char *
+plug_get_prefix (void) {
+ return dbinstalldir;
+}
+
+const char *
+plug_get_doc_dir (void) {
+ return dbdocdir;
+}
+
+const char *
+plug_get_plugin_dir (void) {
+ return dbplugindir;
+}
+
+const char *
+plug_get_pixmap_dir (void) {
+ return dbpixmapdir;
+}
+
void
plug_volume_set_db (float db) {
volume_set_db (db);
@@ -282,6 +338,10 @@ plug_volume_set_amp (float amp) {
#define MAX_PLUGINS 100
DB_plugin_t *g_plugins[MAX_PLUGINS+1];
+#define MAX_GUI_PLUGINS 10
+char *g_gui_names[MAX_GUI_PLUGINS+1];
+int g_num_gui_names;
+
DB_decoder_t *g_decoder_plugins[MAX_DECODER_PLUGINS+1];
#define MAX_VFS_PLUGINS 10
@@ -294,6 +354,9 @@ DB_dsp_t *g_dsp_plugins[MAX_DSP_PLUGINS+1];
DB_output_t *g_output_plugins[MAX_OUTPUT_PLUGINS+1];
DB_output_t *output_plugin = NULL;
+#define MAX_PLAYLIST_PLUGINS 10
+DB_playlist_t *g_playlist_plugins[MAX_PLAYLIST_PLUGINS+1];
+
void
plug_md5 (uint8_t sig[16], const char *in, int len) {
md5_state_t st;
@@ -366,40 +429,11 @@ plug_ev_unsubscribe (DB_plugin_t *plugin, int ev, DB_callback_t callback, uintpt
mutex_unlock (mutex);
}
-void
-plug_playback_next (void) {
- messagepump_push (M_NEXTSONG, 0, 0, 0);
-}
-
-void
-plug_playback_prev (void) {
- messagepump_push (M_PREVSONG, 0, 0, 0);
-}
-
-void
-plug_playback_pause (void) {
- messagepump_push (M_PAUSESONG, 0, 0, 0);
-}
-
-void
-plug_playback_stop (void) {
- messagepump_push (M_STOPSONG, 0, 0, 0);
-}
-
-void
-plug_playback_play (void) {
- messagepump_push (M_PLAYSONG, 0, 0, 0);
-}
-
-void
-plug_playback_random (void) {
- messagepump_push (M_PLAYRANDOM, 0, 0, 0);
-}
-
float
plug_playback_get_pos (void) {
playItem_t *trk = streamer_get_playing_track ();
- if (!trk || trk->_duration <= 0) {
+ float dur = pl_get_item_duration (trk);
+ if (!trk || dur <= 0) {
if (trk) {
pl_item_unref (trk);
}
@@ -408,31 +442,26 @@ plug_playback_get_pos (void) {
if (trk) {
pl_item_unref (trk);
}
- return streamer_get_playpos () * 100 / trk->_duration;
+ return streamer_get_playpos () * 100 / dur;
}
void
plug_playback_set_pos (float pos) {
playItem_t *trk = streamer_get_playing_track ();
- if (!trk || trk->_duration <= 0) {
+ float dur = pl_get_item_duration (trk);
+ if (!trk || dur <= 0) {
if (trk) {
pl_item_unref (trk);
}
return;
}
- float t = pos * trk->_duration / 100.f;
+ float t = pos * dur / 100.f;
if (trk) {
pl_item_unref (trk);
}
streamer_set_seek (t);
}
-void
-plug_quit (void) {
- // FIXME progress_abort ();
- messagepump_push (M_TERMINATE, 0, 0, 0);
-}
-
/////// non-api functions (plugin support)
void
plug_event_call (DB_event_t *ev) {
@@ -444,7 +473,7 @@ plug_event_call (DB_event_t *ev) {
mutex_lock (mutex);
for (int i = 0; i < MAX_HANDLERS; i++) {
- if (handlers[ev->event][i].plugin && !handlers[ev->event][i].plugin->inactive) {
+ if (handlers[ev->event][i].plugin) {
handlers[ev->event][i].callback (ev, handlers[ev->event][i].data);
}
}
@@ -556,24 +585,249 @@ static int dirent_alphasort (const struct dirent **a, const struct dirent **b) {
return strcmp ((*a)->d_name, (*b)->d_name);
}
+void
+plug_remove_plugin (void *p) {
+ int i;
+ for (i = 0; g_plugins[i]; i++) {
+ if (g_plugins[i] == p) {
+ memmove (&g_plugins[i], &g_plugins[i+1], (MAX_PLUGINS+1-i-1) * sizeof (void*));
+ }
+ }
+ for (i = 0; g_decoder_plugins[i]; i++) {
+ if (g_decoder_plugins[i] == p) {
+ memmove (&g_decoder_plugins[i], &g_decoder_plugins[i+1], (MAX_DECODER_PLUGINS+1-i-1) * sizeof (void*));
+ }
+ }
+ for (i = 0; g_vfs_plugins[i]; i++) {
+ if (g_vfs_plugins[i] == p) {
+ memmove (&g_vfs_plugins[i], &g_vfs_plugins[i+1], (MAX_VFS_PLUGINS+1-i-1) * sizeof (void*));
+ }
+ }
+ for (i = 0; g_dsp_plugins[i]; i++) {
+ if (g_dsp_plugins[i] == p) {
+ memmove (&g_dsp_plugins[i], &g_dsp_plugins[i+1], (MAX_DSP_PLUGINS+1-i-1) * sizeof (void*));
+ }
+ }
+ for (i = 0; g_output_plugins[i]; i++) {
+ if (g_output_plugins[i] == p) {
+ memmove (&g_output_plugins[i], &g_output_plugins[i+1], (MAX_OUTPUT_PLUGINS+1-i-1) * sizeof (void*));
+ }
+ }
+ for (i = 0; g_playlist_plugins[i]; i++) {
+ if (g_playlist_plugins[i] == p) {
+ memmove (&g_playlist_plugins[i], &g_playlist_plugins[i+1], (MAX_PLAYLIST_PLUGINS+1-i-1) * sizeof (void*));
+ }
+ }
+}
+
+// d_name must be writable w/o sideeffects; contain valid .so name
+// l must be strlen(d_name)
+static int
+load_plugin (const char *plugdir, char *d_name, int l) {
+ char fullname[PATH_MAX];
+ snprintf (fullname, PATH_MAX, "%s/%s", plugdir, d_name);
+ trace ("loading plugin %s/%s\n", plugdir, d_name);
+ void *handle = dlopen (fullname, RTLD_NOW);
+ if (!handle) {
+ trace ("dlopen error: %s\n", dlerror ());
+#ifdef ANDROID
+ break;
+#else
+ strcpy (fullname + strlen(fullname) - 3, ".fallback.so");
+ trace ("trying %s...\n", fullname);
+ handle = dlopen (fullname, RTLD_NOW);
+ if (!handle) {
+ trace ("dlopen error: %s\n", dlerror ());
+ return -1;
+ }
+ else {
+ fprintf (stderr, "successfully started fallback plugin %s\n", fullname);
+ }
+#endif
+ }
+ d_name[l-3] = 0;
+ strcat (d_name, "_load");
+#ifndef ANDROID
+ DB_plugin_t *(*plug_load)(DB_functions_t *api) = dlsym (handle, d_name);
+#else
+ DB_plugin_t *(*plug_load)(DB_functions_t *api) = dlsym (handle, d_name+3);
+#endif
+ if (!plug_load) {
+ trace ("dlsym error: %s\n", dlerror ());
+ dlclose (handle);
+ return -1;
+ }
+ if (plug_init_plugin (plug_load, handle) < 0) {
+ d_name[l-3] = 0;
+ trace ("plugin %s is incompatible with current version of deadbeef, please upgrade the plugin\n", d_name);
+ dlclose (handle);
+ return -1;
+ }
+ return 0;
+}
+
+static int
+load_gui_plugin (const char **plugdirs) {
+ char conf_gui_plug[100];
+ conf_get_str ("gui_plugin", "GTK2", conf_gui_plug, sizeof (conf_gui_plug));
+ char name[100];
+
+ // try to load selected plugin
+ for (int i = 0; g_gui_names[i]; i++) {
+ trace ("checking GUI plugin: %s\n", g_gui_names[i]);
+ if (!strcmp (g_gui_names[i], conf_gui_plug)) {
+ trace ("found selected GUI plugin: %s\n", g_gui_names[i]);
+ for (int n = 0; plugdirs[n]; n++) {
+ snprintf (name, sizeof (name), "ddb_gui_%s.so", conf_gui_plug);
+ if (!load_plugin (plugdirs[n], name, strlen (name))) {
+ return 0;
+ }
+ snprintf (name, sizeof (name), "ddb_gui_%s.fallback.so", conf_gui_plug);
+ if (!load_plugin (plugdirs[n], name, strlen (name))) {
+ return 0;
+ }
+ }
+ break;
+ }
+ }
+
+ // try any plugin
+ for (int i = 0; g_gui_names[i]; i++) {
+ for (int n = 0; plugdirs[n]; n++) {
+ snprintf (name, sizeof (name), "ddb_gui_%s.so", g_gui_names[i]);
+ if (!load_plugin (plugdirs[n], name, strlen (name))) {
+ return 0;
+ }
+ snprintf (name, sizeof (name), "ddb_gui_%s.fallback.so", g_gui_names[i]);
+ if (!load_plugin (plugdirs[n], name, strlen (name))) {
+ return 0;
+ }
+ }
+ }
+ return -1;
+}
+
+int
+load_plugin_dir (const char *plugdir) {
+ int n = 0;
+ char conf_blacklist_plugins[1000];
+ conf_get_str ("blacklist_plugins", "", conf_blacklist_plugins, sizeof (conf_blacklist_plugins));
+ trace ("loading plugins from %s\n", plugdir);
+ struct dirent **namelist = NULL;
+ n = scandir (plugdir, &namelist, NULL, dirent_alphasort);
+ if (n < 0)
+ {
+ if (namelist) {
+ free (namelist);
+ }
+ return 0;
+ }
+ else
+ {
+ trace ("plug_load_all: scandir found %d files\n", n);
+ int i;
+ for (i = 0; i < n; i++)
+ {
+ // skip hidden files and fallback plugins
+ while (namelist[i]->d_name[0] != '.'
+#ifndef ANDROID
+ && !strstr (namelist[i]->d_name, ".fallback.")
+#else
+ && !strstr (namelist[i]->d_name, "libdeadbeef")
+#endif
+ )
+ {
+ int l = strlen (namelist[i]->d_name);
+ if (l < 3) {
+ break;
+ }
+ if (strcasecmp (&namelist[i]->d_name[l-3], ".so")) {
+ break;
+ }
+ char d_name[256];
+ memcpy (d_name, namelist[i]->d_name, l+1);
+#ifndef ANDROID
+ // no blacklisted
+ const uint8_t *p = conf_blacklist_plugins;
+ while (*p) {
+ const uint8_t *e = p;
+ while (*e && *e > 0x20) {
+ e++;
+ }
+ if (l-3 == e-p) {
+ if (!strncmp (p, d_name, e-p)) {
+ p = NULL;
+ break;
+ }
+ }
+ p = e;
+ while (*p && *p <= 0x20) {
+ p++;
+ }
+ }
+ if (!p) {
+ trace ("plugin %s is blacklisted in config file\n", d_name);
+ break;
+ }
+#endif
+
+ // FIXME: don't load duplicates (by names)
+
+ // add gui plugin names
+ if (!strncmp (d_name, "ddb_gui_", 8)) {
+ trace ("found gui plugin %s\n", d_name);
+ if (g_num_gui_names >= MAX_GUI_PLUGINS) {
+ fprintf (stderr, "too many gui plugins\n");
+ break; // no more gui plugins allowed
+ }
+ char *nm = d_name + 8;
+ char *e = strrchr (nm, '.');
+ if (!e) {
+ break;
+ }
+ if (strcmp (e, ".so")) {
+ break;
+ }
+ *e = 0;
+ // ignore fallbacks
+ e = strrchr (nm, '.');
+ if (e && !strcasecmp (e, ".fallback")) {
+ break;
+ }
+ // add to list
+ g_gui_names[g_num_gui_names++] = strdup (nm);
+ g_gui_names[g_num_gui_names] = NULL;
+ trace ("added %s gui plugin\n", nm);
+ break;
+ }
+
+ load_plugin (plugdir, d_name, l);
+ break;
+ }
+ free (namelist[i]);
+ }
+ free (namelist);
+ }
+ return 0;
+}
+
int
plug_load_all (void) {
#if DISABLE_VERSIONCHECK
trace ("\033[0;31mDISABLE_VERSIONCHECK=1! do not distribute!\033[0;m\n");
#endif
-#if !TARGET_ANDROID
- const char *conf_blacklist_plugins = conf_get_str ("blacklist_plugins", "");
trace ("plug: mutex_create\n");
mutex = mutex_create ();
- const char *dirname = LIBDIR "/deadbeef";
- struct dirent **namelist = NULL;
+#ifndef ANDROID
+ const char *dirname = deadbeef->get_plugin_dir ();
char *xdg_local_home = getenv ("XDG_LOCAL_HOME");
char xdg_plugin_dir[1024];
if (xdg_local_home) {
- strcpy (xdg_plugin_dir, xdg_local_home);
+ strncpy (xdg_plugin_dir, xdg_local_home, sizeof (xdg_plugin_dir));
+ xdg_plugin_dir[sizeof(xdg_plugin_dir)-1] = 0;
} else {
char *homedir = getenv ("HOME");
@@ -591,93 +845,51 @@ plug_load_all (void) {
}
const char *plugins_dirs[] = { dirname, xdg_plugin_dir, NULL };
+#else
+ const char *plugins_dirs[] = { dirname, NULL };
+#endif
- int k = 0, n;
+ int k = 0;
while (plugins_dirs[k]) {
const char *plugdir = plugins_dirs[k++];
if (!(*plugdir)) {
continue;
}
- trace ("loading plugins from %s\n", plugdir);
- namelist = NULL;
- n = scandir (plugdir, &namelist, NULL, dirent_alphasort);
- if (n < 0)
- {
- if (namelist) {
- free (namelist);
- }
+ load_plugin_dir (plugdir);
+ }
+
+#ifdef ANDROID
+ char plugin_path[1000];
+ strncpy (plugin_path, conf_get_str ("android.plugin_path", ""), sizeof (plugin_path)-1);
+ plugin_path[sizeof(plugin_path)-1] = 0;
+ char *p = plugin_path;
+ while (*p) {
+ while (*p == ':') {
+ p++;
+ }
+ if (!(*p)) {
break;
}
- else
- {
- int i;
- for (i = 0; i < n; i++)
- {
- // no hidden files
- while (namelist[i]->d_name[0] != '.')
- {
- int l = strlen (namelist[i]->d_name);
- if (l < 3) {
- break;
- }
- if (strcasecmp (&namelist[i]->d_name[l-3], ".so")) {
- break;
- }
- char d_name[256];
- memcpy (d_name, namelist[i]->d_name, l+1);
- // no blacklisted
- const uint8_t *p = conf_blacklist_plugins;
- while (*p) {
- const uint8_t *e = p;
- while (*e && *e > 0x20) {
- e++;
- }
- if (l-3 == e-p) {
- if (!strncmp (p, d_name, e-p)) {
- p = NULL;
- break;
- }
- }
- p = e;
- while (*p && *p <= 0x20) {
- p++;
- }
- }
- if (!p) {
- trace ("plugin %s is blacklisted in config file\n", d_name);
- break;
- }
- char fullname[PATH_MAX];
- snprintf (fullname, PATH_MAX, "%s/%s", plugdir, d_name);
- trace ("loading plugin %s\n", d_name);
- void *handle = dlopen (fullname, RTLD_NOW);
- if (!handle) {
- trace ("dlopen error: %s\n", dlerror ());
- break;
- }
- d_name[l-3] = 0;
- strcat (d_name, "_load");
- DB_plugin_t *(*plug_load)(DB_functions_t *api) = dlsym (handle, d_name);
- if (!plug_load) {
- trace ("dlsym error: %s\n", dlerror ());
- dlclose (handle);
- break;
- }
- if (plug_init_plugin (plug_load, handle) < 0) {
- d_name[l-3] = 0;
- trace ("plugin %s is incompatible with current version of deadbeef, please upgrade the plugin\n", d_name);
- dlclose (handle);
- break;
- }
- break;
- }
- free (namelist[i]);
- }
- free (namelist);
+ char *e = strchr (p, ':');
+ if (e) {
+ *e = 0;
}
+
+ char path[PATH_MAX];
+ snprintf (path, sizeof (path), "/data/data/%s/lib", p);
+ load_plugin_dir (path);
+ if (!e) {
+ break;
+ }
+ p = e+1;
}
#endif
+
+
+ // load gui plugin
+ load_gui_plugin (plugins_dirs);
+
// load all compiled-in modules
#define PLUG(n) extern DB_plugin_t * n##_load (DB_functions_t *api);
#include "moduleconf.h"
@@ -685,7 +897,7 @@ plug_load_all (void) {
#define PLUG(n) plug_init_plugin (n##_load, NULL);
#include "moduleconf.h"
#undef PLUG
-#if TARGET_ANDROID
+#ifdef ANDROID
#define PLUG(n) extern DB_plugin_t * n##_load (DB_functions_t *api);
#include "moduleconf-android.h"
#undef PLUG
@@ -701,6 +913,7 @@ plug_load_all (void) {
int numvfs = 0;
int numoutput = 0;
int numdsp = 0;
+ int numplaylist = 0;
for (plug = plugins; plug; plug = plug->next) {
g_plugins[numplugins++] = plug->plugin;
if (plug->plugin->type == DB_PLUGIN_DECODER) {
@@ -731,29 +944,48 @@ plug_load_all (void) {
}
g_dsp_plugins[numdsp++] = (DB_dsp_t *)plug->plugin;
}
+ else if (plug->plugin->type == DB_PLUGIN_PLAYLIST) {
+ if (numplaylist >= MAX_PLAYLIST_PLUGINS) {
+ break;
+ }
+ g_playlist_plugins[numplaylist++] = (DB_playlist_t *)plug->plugin;
+ }
}
// start plugins
- for (plug = plugins; plug; plug = plug->next) {
+ plugin_t *prev = NULL;
+ for (plug = plugins; plug;) {
if (plug->plugin->start) {
if (plug->plugin->start () < 0) {
- plug->plugin->inactive = 1;
- }
- }
- }
- // connect plugins
- for (plug = plugins; plug; plug = plug->next) {
- if (plug->plugin->connect) {
- if (plug->plugin->connect () < 0) {
- plug->plugin->inactive = 1;
+ fprintf (stderr, "plugin %s failed to start, deactivated.\n", plug->plugin->name);
+ if (plug->plugin->stop) {
+ plug->plugin->stop ();
+ }
+ if (plug->handle) {
+ dlclose (plug->handle);
+ }
+ plug_remove_plugin (plug->plugin);
+ if (prev) {
+ prev->next = plug->next;
+ }
+ else {
+ plugins = plug->next;
+ }
+ plugin_t *next = plug->next;
+ free (plug);
+ plug = next;
+ continue;
}
}
+ prev = plug;
+ plug = plug->next;
}
-
// trace ("numplugins: %d, numdecoders: %d, numvfs: %d\n", numplugins, numdecoders, numvfs);
g_plugins[numplugins] = NULL;
g_decoder_plugins[numdecoders] = NULL;
g_vfs_plugins[numvfs] = NULL;
g_output_plugins[numoutput] = NULL;
+ g_dsp_plugins[numdsp] = NULL;
+ g_playlist_plugins[numplaylist] = NULL;
// select output plugin
if (plug_select_output () < 0) {
@@ -764,6 +996,60 @@ plug_load_all (void) {
}
void
+plug_connect_all (void) {
+ plugin_t *plug;
+ plugin_t *prev = NULL;
+ for (plug = plugins; plug;) {
+ if (plug->plugin->connect) {
+ if (plug->plugin->connect () < 0) {
+ fprintf (stderr, "plugin %s failed to connect to dependencies, deactivated.\n", plug->plugin->name);
+
+ if (plug->plugin->disconnect) {
+ plug->plugin->disconnect ();
+ }
+ if (plug->plugin->stop) {
+ plug->plugin->stop ();
+ }
+ if (plug->handle) {
+ dlclose (plug->handle);
+ }
+ plug_remove_plugin (plug->plugin);
+
+ if (prev) {
+ prev->next = plug->next;
+ }
+ else {
+ plugins = plug->next;
+ }
+ plugin_t *next = plug->next;
+ free (plug);
+ plug = next;
+ continue;
+ }
+ }
+ prev = plug;
+ plug = plug->next;
+ }
+
+}
+
+void
+plug_disconnect_all (void) {
+ trace ("plug_disconnect_all\n");
+ plugin_t *plug;
+ plugin_t *prev = NULL;
+ for (plug = plugins; plug;) {
+ if (plug->plugin->disconnect) {
+ if (plug->plugin->disconnect () < 0) {
+ trace ("plugin %s failed to disconnect\n", plug->plugin->name);
+ }
+ }
+ prev = plug;
+ plug = plug->next;
+ }
+}
+
+void
plug_unload_all (void) {
trace ("plug_unload_all\n");
plugin_t *p;
@@ -777,7 +1063,7 @@ plug_unload_all (void) {
trace ("stopped all plugins\n");
while (plugins) {
plugin_t *next = plugins->next;
-#if !TARGET_ANDROID
+#ifndef ANDROID
if (plugins->handle) {
dlclose (plugins->handle);
}
@@ -785,6 +1071,10 @@ plug_unload_all (void) {
free (plugins);
plugins = next;
}
+ for (int i = 0; g_gui_names[i]; i++) {
+ free (g_gui_names[i]);
+ g_gui_names[i] = NULL;
+ }
plugins_tail = NULL;
trace ("all plugins had been unloaded\n");
}
@@ -803,64 +1093,34 @@ plug_get_decoder_list (void) {
return g_decoder_plugins;
}
-struct DB_output_s **
-plug_get_output_list (void) {
- return g_output_plugins;
-}
-
struct DB_vfs_s **
plug_get_vfs_list (void) {
return g_vfs_plugins;
}
+struct DB_output_s **
+plug_get_output_list (void) {
+ return g_output_plugins;
+}
+
struct DB_dsp_s **
plug_get_dsp_list (void) {
return g_dsp_plugins;
}
+struct DB_playlist_s **
+plug_get_playlist_list (void) {
+ return g_playlist_plugins;
+}
+
struct DB_plugin_s **
plug_get_list (void) {
return g_plugins;
}
-int
-plug_activate (DB_plugin_t *plug, int activate) {
- if (plug->inactive && !activate) {
- return -1;
- }
- if (!plug->inactive && activate) {
- return -1;
- }
- if (activate) {
- if (plug->start) {
- if (!plug->start ()) {
- plug->inactive = 0;
- }
- else {
- trace ("failed to start plugin %s\n", plug->name);
- return -1;
- }
- return 0;
- }
- else {
- return -1;
- }
- }
- else {
- if (plug->stop) {
- if (!plug->stop ()) {
- plug->inactive = 1;
- }
- else {
- trace ("failed to stop plugin %s\n", plug->name);
- return -1;
- }
- return 0;
- }
- else {
- return -1;
- }
- }
+const char **
+plug_get_gui_names (void) {
+ return (const char **)g_gui_names;
}
DB_output_t *
@@ -870,7 +1130,11 @@ plug_get_output (void) {
int
plug_select_output (void) {
- const char *outplugname = conf_get_str ("output_plugin", _("ALSA output plugin"));
+#ifdef ANDROID
+ return 0;
+#else
+ char outplugname[100];
+ conf_get_str ("output_plugin", "ALSA output plugin", outplugname, sizeof (outplugname));
for (int i = 0; g_output_plugins[i]; i++) {
DB_output_t *p = g_output_plugins[i];
if (!strcmp (p->plugin.name, outplugname)) {
@@ -891,28 +1155,40 @@ plug_select_output (void) {
}
plug_trigger_event (DB_EV_OUTPUTCHANGED, 0);
return 0;
+#endif
}
void
plug_reinit_sound (void) {
- int state = p_get_state ();
+ DB_output_t *prev = plug_get_output ();
+ int state = OUTPUT_STATE_STOPPED;
- p_free ();
+ ddb_waveformat_t fmt = {0};
+
+ if (prev) {
+ state = prev->state ();
+ memcpy (&fmt, &prev->fmt, sizeof (fmt));
+ prev->free ();
+ }
- DB_output_t *prev = plug_get_output ();
if (plug_select_output () < 0) {
- const char *outplugname = conf_get_str ("output_plugin", "ALSA output plugin");
+ char outplugname[100];
+ conf_get_str ("output_plugin", "ALSA output plugin", outplugname, sizeof (outplugname));
trace ("failed to select output plugin %s\nreverted to %s\n", outplugname, prev->plugin.name);
output_plugin = prev;
}
- streamer_reset (1);
- if (p_init () < 0) {
+ DB_output_t *output = plug_get_output ();
+ if (fmt.channels) {
+ output->setformat (&fmt);
+ }
+ if (output->init () < 0) {
+ streamer_reset (1);
streamer_set_nextsong (-2, 0);
return;
}
if (state != OUTPUT_STATE_PAUSED && state != OUTPUT_STATE_STOPPED) {
- if (p_play () < 0) {
+ if (output->play () < 0) {
trace ("failed to reinit sound output\n");
streamer_set_nextsong (-2, 0);
}
diff --git a/plugins.h b/plugins.h
index 231eaf1f..8451a2cf 100644
--- a/plugins.h
+++ b/plugins.h
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@@ -31,6 +31,12 @@ void
plug_unload_all (void);
void
+plug_connect_all (void);
+
+void
+plug_disconnect_all (void);
+
+void
plug_cleanup (void);
void
@@ -63,27 +69,6 @@ plug_md5 (uint8_t sig[16], const char *in, int len);
void
plug_md5_to_str (char *str, const uint8_t sig[16]);
-void
-plug_playback_next (void);
-
-void
-plug_playback_prev (void);
-
-void
-plug_playback_pause (void);
-
-void
-plug_playback_stop (void);
-
-void
-plug_playback_play (void);
-
-void
-plug_playback_random (void);
-
-void
-plug_quit (void);
-
float
plug_playback_get_pos (void);
@@ -105,6 +90,9 @@ plug_get_vfs_list (void);
struct DB_dsp_s **
plug_get_dsp_list (void);
+struct DB_playlist_s **
+plug_get_playlist_list (void);
+
void
plug_volume_set_db (float db);
@@ -113,6 +101,14 @@ plug_volume_set_amp (float amp);
const char *
plug_get_config_dir (void);
+const char *
+plug_get_prefix (void);
+const char *
+plug_get_doc_dir (void);
+const char *
+plug_get_plugin_dir (void);
+const char *
+plug_get_pixmap_dir (void);
int
plug_activate (DB_plugin_t *plug, int activate);
@@ -144,4 +140,7 @@ plug_get_for_id (const char *id);
int
plug_is_local_file (const char *fname);
+const char **
+plug_get_gui_names (void);
+
#endif // __PLUGINS_H
diff --git a/plugins/aac/aac.c b/plugins/aac/aac.c
index f7925b82..33418593 100644
--- a/plugins/aac/aac.c
+++ b/plugins/aac/aac.c
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@@ -19,11 +19,13 @@
#include <string.h>
#include <stdio.h>
+#include <unistd.h>
#include <neaacdec.h>
#ifdef HAVE_CONFIG_H
#include "../../config.h"
#endif
#include <stdlib.h>
+#include <math.h>
#include "../../deadbeef.h"
#include "aac_parser.h"
@@ -54,12 +56,26 @@ static DB_functions_t *deadbeef;
#define MP4FILE_CB MP4FileProvider
#endif
+
+// aac channel mapping
+// 0: Defined in AOT Specifc Config
+// 1: 1 channel: front-center
+// 2: 2 channels: front-left, front-right
+// 3: 3 channels: front-center, front-left, front-right
+// 4: 4 channels: front-center, front-left, front-right, back-center
+// 5: 5 channels: front-center, front-left, front-right, back-left, back-right
+// 6: 6 channels: front-center, front-left, front-right, back-left, back-right, LFE-channel
+// 7: 8 channels: front-center, front-left, front-right, side-left, side-right, back-left, back-right, LFE-channel
+// 8-15: Reserved
+
+
typedef struct {
DB_fileinfo_t info;
NeAACDecHandle dec;
DB_FILE *file;
MP4FILE mp4file;
MP4FILE_CB mp4reader;
+ NeAACDecFrameInfo frame_info; // last frame info
int32_t timescale;
uint32_t maxSampleSize;
int mp4track;
@@ -72,16 +88,17 @@ typedef struct {
int currentsample;
char buffer[AAC_BUFFER_SIZE];
int remaining;
- int faad_channels;
char out_buffer[OUT_BUFFER_SIZE];
int out_remaining;
int num_errors;
char *samplebuffer;
+ int remap[10];
+ int noremap;
} aac_info_t;
// allocate codec control structure
static DB_fileinfo_t *
-aac_open (void) {
+aac_open (uint32_t hints) {
DB_fileinfo_t *_info = malloc (sizeof (aac_info_t));
aac_info_t *info = (aac_info_t *)_info;
memset (info, 0, sizeof (aac_info_t));
@@ -101,6 +118,7 @@ aac_fs_seek (void *user_data, uint64_t position) {
DB_FILE *fp = (DB_FILE *)user_data;
return deadbeef->fseek (fp, position, SEEK_SET);
}
+
#else
static void *
aac_fs_open (const char *fname, MP4FileMode mode) {
@@ -134,7 +152,7 @@ parse_aac_stream(DB_FILE *fp, int *psamplerate, int *pchannels, float *pduration
int firstframepos = -1;
int fsize = -1;
int offs = 0;
- if (!fp->vfs->streaming) {
+ if (!fp->vfs->is_streaming ()) {
int skip = deadbeef->junk_get_leading_size (fp);
if (skip >= 0) {
deadbeef->fseek (fp, skip, SEEK_SET);
@@ -158,7 +176,7 @@ parse_aac_stream(DB_FILE *fp, int *psamplerate, int *pchannels, float *pduration
int frame = 0;
int scanframes = 1000;
- if (fp->vfs->streaming) {
+ if (fp->vfs->is_streaming ()) {
scanframes = 1;
}
@@ -183,7 +201,7 @@ parse_aac_stream(DB_FILE *fp, int *psamplerate, int *pchannels, float *pduration
continue;
}
else {
- trace ("aac: frame #%d sync: %d %d %d %d %d\n", frame, channels, samplerate, bitrate, samples, size);
+ trace ("aac: frame #%d sync: %dch %d %d %d %d\n", frame, channels, samplerate, bitrate, samples, size);
frame++;
nsamples += samples;
if (!stream_sr) {
@@ -200,7 +218,7 @@ parse_aac_stream(DB_FILE *fp, int *psamplerate, int *pchannels, float *pduration
// *pchannels = stream_ch;
// }
framepos += size;
- if (deadbeef->fseek (fp, size-sizeof(buf), SEEK_CUR) == -1) {
+ if (deadbeef->fseek (fp, size-(int)sizeof(buf), SEEK_CUR) == -1) {
trace ("parse_aac_stream: invalid seek %d\n", size-sizeof(buf));
break;
}
@@ -213,6 +231,7 @@ parse_aac_stream(DB_FILE *fp, int *psamplerate, int *pchannels, float *pduration
}
*psamplerate = stream_sr;
+
*pchannels = stream_ch;
if (ptotalsamples) {
@@ -227,6 +246,12 @@ parse_aac_stream(DB_FILE *fp, int *psamplerate, int *pchannels, float *pduration
trace ("aac: duration=%f (%d samples @ %d Hz), fsize=%d\n", *pduration, totalsamples, stream_sr, fsize);
}
+ if (*psamplerate <= 24000) {
+ *psamplerate *= 2;
+ if (ptotalsamples) {
+ *ptotalsamples *= 2;
+ }
+ }
return firstframepos;
}
@@ -287,7 +312,9 @@ aac_probe (DB_FILE *fp, const char *fname, MP4FILE_CB *cb, float *duration, int
}
*channels = mp4ff_get_channel_count (mp4, i);
int samples = mp4ff_num_samples(mp4, i) * 1024;
- trace ("mp4 nsamples=%d, samplerate=%d\n", samples, *samplerate);
+ samples = (int64_t)samples * (*samplerate) / mp4ff_time_scale (mp4, i);
+
+ trace ("mp4 nsamples=%d, samplerate=%d, timescale=%d, duration=%lld\n", samples, *samplerate, mp4ff_time_scale(mp4, i), mp4ff_get_track_duration(mp4, i));
*duration = (float)samples / (*samplerate);
if (totalsamples) {
@@ -368,7 +395,7 @@ static int
aac_init (DB_fileinfo_t *_info, DB_playItem_t *it) {
aac_info_t *info = (aac_info_t *)_info;
- info->file = deadbeef->fopen (it->fname);
+ info->file = deadbeef->fopen (deadbeef->pl_find_meta (it, ":URI"));
if (!info->file) {
return -1;
}
@@ -380,7 +407,7 @@ aac_init (DB_fileinfo_t *_info, DB_playItem_t *it) {
int totalsamples = -1;
int offs = -1;
- if (!info->file->vfs->streaming) {
+ if (!info->file->vfs->is_streaming ()) {
int skip = deadbeef->junk_get_leading_size (info->file);
if (skip >= 0) {
deadbeef->fseek (info->file, skip, SEEK_SET);
@@ -406,9 +433,9 @@ aac_init (DB_fileinfo_t *_info, DB_playItem_t *it) {
info->mp4reader.close = aac_fs_close;
#endif
- if (!info->file->vfs->streaming) {
+ if (!info->file->vfs->is_streaming ()) {
#ifdef USE_MP4FF
- trace ("aac_init: mp4ff_open_read %s\n", it->fname);
+ trace ("aac_init: mp4ff_open_read %s\n", deadbeef->pl_find_meta (it, ":URI"));
info->mp4file = mp4ff_open_read (&info->mp4reader);
if (info->mp4file) {
int ntracks = mp4ff_total_tracks (info->mp4file);
@@ -446,7 +473,6 @@ aac_init (DB_fileinfo_t *_info, DB_playItem_t *it) {
trace ("NeAACDecInit2 returned error\n");
return -1;
}
- info->faad_channels = ch;
samplerate = srate;
channels = ch;
NeAACDecConfigurationPtr conf = NeAACDecGetCurrentConfiguration (info->dec);
@@ -478,8 +504,8 @@ aac_init (DB_fileinfo_t *_info, DB_playItem_t *it) {
}
}
#else
- trace ("aac_init: MP4ReadProvider %s\n", it->fname);
- info->mp4file = MP4ReadProvider (it->fname, 0, &info->mp4reader);
+ trace ("aac_init: MP4ReadProvider %s\n", deadbeef->pl_find_meta (it, ":URI"));
+ info->mp4file = MP4ReadProvider (deadbeef->pl_find_meta (it, ":URI"), 0, &info->mp4reader);
info->mp4track = MP4FindTrackId(info->mp4file, 0, "audio", 0);
trace ("aac_init: MP4FindTrackId returned %d\n", info->mp4track);
if (info->mp4track >= 0) {
@@ -494,7 +520,6 @@ aac_init (DB_fileinfo_t *_info, DB_playItem_t *it) {
if (rc >= 0) {
_info->samplerate = mp4ASC.samplingFrequency;
_info->channels = MP4GetTrackAudioChannels (info->mp4file, info->mp4track);
- info->faad_channels = _info->channels;
totalsamples = MP4GetTrackNumberOfSamples (info->mp4file, info->mp4track) * 1024 * _info->channels;
// init mp4 decoding
@@ -505,7 +530,6 @@ aac_init (DB_fileinfo_t *_info, DB_playItem_t *it) {
trace ("NeAACDecInit2 returned error\n");
return -1;
}
- info->faad_channels = ch;
samplerate = srate;
channels = ch;
NeAACDecConfigurationPtr conf = NeAACDecGetCurrentConfiguration (info->dec);
@@ -551,8 +575,8 @@ aac_init (DB_fileinfo_t *_info, DB_playItem_t *it) {
trace ("found aac stream\n");
}
- _info->channels = channels;
- _info->samplerate = samplerate;
+ _info->fmt.channels = channels;
+ _info->fmt.samplerate = samplerate;
}
else {
// sync before attempting to init
@@ -563,17 +587,16 @@ aac_init (DB_fileinfo_t *_info, DB_playItem_t *it) {
trace ("aac: parse_aac_stream failed\n");
return -1;
}
- _info->channels = channels;
- _info->samplerate = samplerate*2;
trace("parse_aac_stream returned %x\n", offs);
}
+
if (offs >= 0) {
deadbeef->fseek (info->file, offs, SEEK_SET);
}
// duration = (float)totalsamples / samplerate;
// deadbeef->pl_set_item_duration (it, duration);
- _info->bps = 16;
+ _info->fmt.bps = 16;
_info->plugin = &plugin;
if (!info->mp4file) {
@@ -586,7 +609,7 @@ aac_init (DB_fileinfo_t *_info, DB_playItem_t *it) {
info->remaining = deadbeef->fread (info->buffer, 1, AAC_BUFFER_SIZE, info->file);
NeAACDecConfigurationPtr conf = NeAACDecGetCurrentConfiguration (info->dec);
- conf->dontUpSampleImplicitSBR = 1;
+// conf->dontUpSampleImplicitSBR = 1;
NeAACDecSetConfiguration (info->dec, conf);
unsigned long srate;
unsigned char ch;
@@ -608,11 +631,11 @@ aac_init (DB_fileinfo_t *_info, DB_playItem_t *it) {
memmove (info->buffer, info->buffer + consumed, info->remaining - consumed);
info->remaining -= consumed;
}
- info->faad_channels = ch;
- _info->channels = ch;
+ _info->fmt.channels = ch;
+ _info->fmt.samplerate = srate;
}
- if (!info->file->vfs->streaming) {
+ if (!info->file->vfs->is_streaming ()) {
if (it->endsample > 0) {
info->startsample = it->startsample;
info->endsample = it->endsample;
@@ -624,6 +647,11 @@ aac_init (DB_fileinfo_t *_info, DB_playItem_t *it) {
}
}
+ for (int i = 0; i < _info->fmt.channels; i++) {
+ _info->fmt.channelmask |= 1 << i;
+ }
+ info->noremap = 0;
+ info->remap[0] = -1;
trace ("init success\n");
return 0;
@@ -651,13 +679,14 @@ aac_free (DB_fileinfo_t *_info) {
}
static int
-aac_read_int16 (DB_fileinfo_t *_info, char *bytes, int size) {
+aac_read (DB_fileinfo_t *_info, char *bytes, int size) {
aac_info_t *info = (aac_info_t *)_info;
- int out_ch = min (_info->channels, 2);
- if (!info->file->vfs->streaming) {
- if (info->currentsample + size / (2 * out_ch) > info->endsample) {
- size = (info->endsample - info->currentsample + 1) * 2 * out_ch;
+ int samplesize = _info->fmt.channels * _info->fmt.bps / 8;
+ if (!info->file->vfs->is_streaming ()) {
+ if (info->currentsample + size / samplesize > info->endsample) {
+ size = (info->endsample - info->currentsample + 1) * samplesize;
if (size <= 0) {
+ trace ("aac_read: eof");
return 0;
}
}
@@ -665,41 +694,105 @@ aac_read_int16 (DB_fileinfo_t *_info, char *bytes, int size) {
int initsize = size;
int eof = 0;
- int sample_size = out_ch * (_info->bps >> 3);
while (size > 0) {
if (info->skipsamples > 0 && info->out_remaining > 0) {
int skip = min (info->out_remaining, info->skipsamples);
if (skip < info->out_remaining) {
- memmove (info->out_buffer, info->out_buffer + skip * 2 * info->faad_channels, (info->out_remaining - skip) * 2 * info->faad_channels);
+ memmove (info->out_buffer, info->out_buffer + skip * samplesize, (info->out_remaining - skip) * samplesize);
}
info->out_remaining -= skip;
info->skipsamples -= skip;
}
if (info->out_remaining > 0) {
- int n = size / sample_size;
+ int n = size / samplesize;
n = min (info->out_remaining, n);
char *src = info->out_buffer;
- for (int i = 0; i < n; i++) {
- memcpy (bytes, src, sample_size);
- bytes += sample_size;
- src += info->faad_channels * 2;
+ if (info->noremap) {
+ memcpy (bytes, src, n * samplesize);
+ bytes += n * samplesize;
+ src += n * samplesize;
}
+ else {
+ int i, j;
+ if (info->remap[0] == -1) {
+ // build remap mtx
+
+ // FIXME: should build channelmask 1st; then remap based on channelmask
+ for (i = 0; i < _info->fmt.channels; i++) {
+ switch (info->frame_info.channel_position[i]) {
+ case FRONT_CHANNEL_CENTER:
+ trace ("FC->%d\n", i);
+ info->remap[2] = i;
+ break;
+ case FRONT_CHANNEL_LEFT:
+ trace ("FL->%d\n", i);
+ info->remap[0] = i;
+ break;
+ case FRONT_CHANNEL_RIGHT:
+ trace ("FR->%d\n", i);
+ info->remap[1] = i;
+ break;
+ case SIDE_CHANNEL_LEFT:
+ trace ("SL->%d\n", i);
+ info->remap[6] = i;
+ break;
+ case SIDE_CHANNEL_RIGHT:
+ trace ("SR->%d\n", i);
+ info->remap[7] = i;
+ break;
+ case BACK_CHANNEL_LEFT:
+ trace ("RL->%d\n", i);
+ info->remap[4] = i;
+ break;
+ case BACK_CHANNEL_RIGHT:
+ trace ("RR->%d\n", i);
+ info->remap[5] = i;
+ break;
+ case BACK_CHANNEL_CENTER:
+ trace ("BC->%d\n", i);
+ info->remap[8] = i;
+ break;
+ case LFE_CHANNEL:
+ trace ("LFE->%d\n", i);
+ info->remap[3] = i;
+ break;
+ default:
+ trace ("aac: unknown ch(%d)->%d\n", info->frame_info.channel_position[i], i);
+ break;
+ }
+ }
+ if (info->remap[0] == -1) {
+ info->remap[0] = 0;
+ }
+ if ((_info->fmt.channels == 1 && info->remap[0] == FRONT_CHANNEL_CENTER)
+ || (_info->fmt.channels == 2 && info->remap[0] == FRONT_CHANNEL_LEFT && info->remap[1] == FRONT_CHANNEL_RIGHT)) {
+ info->noremap = 1;
+ }
+ }
+
+ for (i = 0; i < n; i++) {
+ for (j = 0; j < _info->fmt.channels; j++) {
+ ((int16_t *)bytes)[info->remap[j]] = ((int16_t *)src)[j];
+ }
+ src += samplesize;
+ bytes += samplesize;
+ }
+ }
+ size -= n * samplesize;
- size -= n * sample_size;
if (n == info->out_remaining) {
info->out_remaining = 0;
}
else {
- memmove (info->out_buffer, src, (info->out_remaining - n) * info->faad_channels * 2);
+ memmove (info->out_buffer, src, (info->out_remaining - n) * samplesize);
info->out_remaining -= n;
}
continue;
}
char *samples = NULL;
- NeAACDecFrameInfo frame_info;
if (info->mp4file) {
unsigned char *buffer = NULL;
@@ -732,7 +825,7 @@ aac_read_int16 (DB_fileinfo_t *_info, char *bytes, int size) {
break;
}
info->mp4sample++;
- samples = NeAACDecDecode(info->dec, &frame_info, buffer, buffer_size);
+ samples = NeAACDecDecode(info->dec, &info->frame_info, buffer, buffer_size);
if (buffer) {
free (buffer);
@@ -750,11 +843,11 @@ aac_read_int16 (DB_fileinfo_t *_info, char *bytes, int size) {
info->remaining += res;
}
- samples = NeAACDecDecode (info->dec, &frame_info, info->buffer, info->remaining);
+ samples = NeAACDecDecode (info->dec, &info->frame_info, info->buffer, info->remaining);
if (!samples) {
- trace ("NeAACDecDecode failed, consumed=%d\n", frame_info.bytesconsumed);
+ trace ("NeAACDecDecode failed, consumed=%d\n", info->frame_info.bytesconsumed);
if (info->num_errors > 10) {
- trace ("NeAACDecDecode failed 10 times, interrupting\n");
+ trace ("NeAACDecDecode failed %d times, interrupting\n", info->num_errors);
break;
}
info->num_errors++;
@@ -762,7 +855,7 @@ aac_read_int16 (DB_fileinfo_t *_info, char *bytes, int size) {
continue;
}
info->num_errors=0;
- int consumed = frame_info.bytesconsumed;
+ int consumed = info->frame_info.bytesconsumed;
if (consumed > info->remaining) {
trace ("NeAACDecDecode consumed more than available! wtf?\n");
break;
@@ -776,26 +869,19 @@ aac_read_int16 (DB_fileinfo_t *_info, char *bytes, int size) {
}
}
- if (frame_info.samples > 0) {
- memcpy (info->out_buffer, samples, frame_info.samples * 2);
- info->out_remaining = frame_info.samples / frame_info.channels;
+ if (info->frame_info.samples > 0) {
+ memcpy (info->out_buffer, samples, info->frame_info.samples * 2);
+ info->out_remaining = info->frame_info.samples / info->frame_info.channels;
}
}
- info->currentsample += (initsize-size) / sample_size;
+ info->currentsample += (initsize-size) / samplesize;
return initsize-size;
}
// returns -1 on error, 0 on success
int
seek_raw_aac (aac_info_t *info, int sample) {
- deadbeef->rewind (info->file);
- int skip = deadbeef->junk_get_leading_size (info->file);
- if (skip >= 0) {
- deadbeef->fseek (info->file, skip, SEEK_SET);
- }
-
- int offs = deadbeef->ftell (info->file);
uint8_t buf[ADTS_HEADER_SIZE*8];
int nsamples = 0;
@@ -828,14 +914,17 @@ seek_raw_aac (aac_info_t *info, int sample) {
continue;
}
else {
- //trace ("aac: frame #%d sync: %d %d %d %d %d\n", frame, channels, samplerate, bitrate, samples, size);
+ //trace ("aac: frame #%d(%d/%d) sync: %d %d %d %d %d\n", frame, curr_sample, sample, channels, samplerate, bitrate, frame_samples, size);
frame++;
- if (deadbeef->fseek (info->file, size-sizeof(buf), SEEK_CUR) == -1) {
+ if (deadbeef->fseek (info->file, size-(int)sizeof(buf), SEEK_CUR) == -1) {
trace ("seek_raw_aac: invalid seek %d\n", size-sizeof(buf));
break;
}
bufsize = 0;
}
+ if (samplerate <= 24000) {
+ frame_samples *= 2;
+ }
} while (curr_sample + frame_samples < sample);
if (curr_sample + frame_samples < sample) {
@@ -855,6 +944,16 @@ aac_seek_sample (DB_fileinfo_t *_info, int sample) {
info->skipsamples = sample - info->mp4sample * (info->mp4framesize-1);
}
else {
+ if (sample < info->currentsample, 1) {
+ int skip = deadbeef->junk_get_leading_size (info->file);
+ if (skip >= 0) {
+ deadbeef->fseek (info->file, skip, SEEK_SET);
+ }
+ else {
+ deadbeef->fseek (info->file, 0, SEEK_SET);
+ }
+ }
+
int res = seek_raw_aac (info, sample);
if (res < 0) {
return -1;
@@ -864,13 +963,13 @@ aac_seek_sample (DB_fileinfo_t *_info, int sample) {
info->remaining = 0;
info->out_remaining = 0;
info->currentsample = sample;
- _info->readpos = (float)(info->currentsample - info->startsample) / _info->samplerate;
+ _info->readpos = (float)(info->currentsample - info->startsample) / _info->fmt.samplerate;
return 0;
}
static int
aac_seek (DB_fileinfo_t *_info, float t) {
- return aac_seek_sample (_info, t * _info->samplerate);
+ return aac_seek_sample (_info, t * _info->fmt.samplerate);
}
#ifdef USE_MP4FF
@@ -910,24 +1009,20 @@ aac_load_tags (DB_playItem_t *it, mp4ff_t *mp4) {
free (s);
}
}
- it->replaygain_track_gain = 0;
- it->replaygain_track_peak = 1;
- it->replaygain_album_gain = 0;
- it->replaygain_album_peak = 1;
if (mp4ff_meta_find_by_name(mp4, "replaygain_track_gain", &s)) {
- it->replaygain_track_gain = atof (s);
+ deadbeef->pl_set_item_replaygain (it, DDB_REPLAYGAIN_TRACKGAIN, atof (s));
free (s);
}
if (mp4ff_meta_find_by_name(mp4, "replaygain_track_peak", &s)) {
- it->replaygain_track_peak = atof (s);
+ deadbeef->pl_set_item_replaygain (it, DDB_REPLAYGAIN_TRACKPEAK, atof (s));
free (s);
}
if (mp4ff_meta_find_by_name(mp4, "replaygain_album_gain", &s)) {
- it->replaygain_album_gain = atof (s);
+ deadbeef->pl_set_item_replaygain (it, DDB_REPLAYGAIN_ALBUMGAIN, atof (s));
free (s);
}
if (mp4ff_meta_find_by_name(mp4, "replaygain_album_peak", &s)) {
- it->replaygain_album_peak = atof (s);
+ deadbeef->pl_set_item_replaygain (it, DDB_REPLAYGAIN_ALBUMPEAK, atof (s));
free (s);
}
deadbeef->pl_add_meta (it, "title", NULL);
@@ -938,12 +1033,12 @@ aac_load_tags (DB_playItem_t *it, mp4ff_t *mp4) {
int
aac_read_metadata (DB_playItem_t *it) {
#ifdef USE_MP4FF
- DB_FILE *fp = deadbeef->fopen (it->fname);
+ DB_FILE *fp = deadbeef->fopen (deadbeef->pl_find_meta (it, ":URI"));
if (!fp) {
return -1;
}
- if (fp->vfs->streaming) {
+ if (fp->vfs->is_streaming ()) {
deadbeef->fclose (fp);
return -1;
}
@@ -971,8 +1066,91 @@ aac_read_metadata (DB_playItem_t *it) {
}
deadbeef->fclose (fp);
#endif
+ return 0;
}
+#ifdef USE_MP4FF
+#if 0
+static uint32_t
+mp4ff_read_cb (void *user_data, void *buffer, uint32_t length) {
+// trace ("aac_fs_read %d\n", length);
+ FILE *fp = (FILE *)user_data;
+ return fread (buffer, 1, length, fp);
+}
+static uint32_t
+mp4ff_seek_cb (void *user_data, uint64_t position) {
+// trace ("aac_fs_seek\n");
+ FILE *fp = (FILE *)user_data;
+ return fseek (fp, position, SEEK_SET);
+}
+static uint32_t
+mp4ff_write_cb(void *user_data, void *buffer, uint32_t length) {
+ FILE *fp = (FILE *)user_data;
+ return fwrite (buffer, 1, length, fp);
+}
+
+static uint32_t
+mp4ff_truncate_cb(void *user_data)
+{
+ FILE *fp = (FILE *)user_data;
+ ftruncate(fileno(fp), ftello(fp));
+ return 0;
+}
+#endif
+#endif
+
+#ifdef USE_MP4FF
+#if 0
+static int
+aac_write_metadata (DB_playItem_t *it) {
+ mp4ff_metadata_t md;
+ memset (&md, 0, sizeof (md));
+ deadbeef->pl_lock ();
+ DB_metaInfo_t *meta = deadbeef->pl_get_metadata_head (it);
+
+ // find numtags 1st
+ while (meta) {
+ if (meta->key[0] != ':') {
+ md.count++;
+ }
+ meta = meta->next;
+ }
+
+ // fill tags
+ if (md.count) {
+ md.tags = malloc (sizeof (mp4ff_tag_t) * md.count);
+ int n = 0;
+ meta = deadbeef->pl_get_metadata_head (it);
+ while (meta) {
+ if (meta->key[0] != ':') {
+ md.tags[n].item = "";//(char *)meta->key;
+ md.tags[n].value = (char *)meta->value;
+ n++;
+ }
+ meta = meta->next;
+ }
+ }
+
+ mp4ff_callback_t f = {
+ .read = mp4ff_read_cb,
+ .write = mp4ff_write_cb,
+ .seek = mp4ff_seek_cb,
+ .truncate = mp4ff_truncate_cb,
+ };
+
+ FILE *fp = fopen (deadbeef->pl_find_meta (it, ":URI"), "w");
+ f.user_data = fp;
+
+ mp4ff_meta_update (&f, &md);
+ if (md.tags) {
+ free (md.tags);
+ }
+ deadbeef->pl_unlock ();
+ return 0;
+}
+#endif
+#endif
+
static DB_playItem_t *
aac_insert (DB_playItem_t *after, const char *fname) {
trace ("adding %s\n", fname);
@@ -986,11 +1164,12 @@ aac_insert (DB_playItem_t *after, const char *fname) {
float duration = -1;
int totalsamples = 0;
int samplerate = 0;
+ int channels = 0;
int mp4track = -1;
MP4FILE mp4 = NULL;
- if (fp->vfs->streaming) {
+ if (fp->vfs->is_streaming ()) {
trace ("streaming aac (%s)\n", fname);
ftype = plugin.filetypes[0];
}
@@ -1000,8 +1179,6 @@ aac_insert (DB_playItem_t *after, const char *fname) {
deadbeef->fseek (fp, skip, SEEK_SET);
}
- int channels;
-
// slowwww!
MP4FILE_CB cb = {
#ifdef USE_MP4FF
@@ -1032,12 +1209,10 @@ aac_insert (DB_playItem_t *after, const char *fname) {
}
}
- DB_playItem_t *it = deadbeef->pl_item_alloc ();
- it->decoder_id = deadbeef->plug_get_decoder_id (plugin.plugin.id);
- it->fname = strdup (fname);
- it->filetype = ftype;
+ DB_playItem_t *it = deadbeef->pl_item_alloc_init (fname, plugin.plugin.id);
+ deadbeef->pl_add_meta (it, ":FILETYPE", ftype);
deadbeef->pl_set_item_duration (it, duration);
-// trace ("duration: %f sec\n", duration);
+ trace ("duration: %f sec\n", duration);
// read tags
if (mp4) {
@@ -1083,9 +1258,22 @@ aac_insert (DB_playItem_t *after, const char *fname) {
deadbeef->pl_add_meta (it, "title", NULL);
}
+ int64_t fsize = deadbeef->fgetlength (fp);
+
deadbeef->fclose (fp);
if (duration > 0) {
+ char s[100];
+ snprintf (s, sizeof (s), "%lld", fsize);
+ deadbeef->pl_add_meta (it, ":FILE_SIZE", s);
+ deadbeef->pl_add_meta (it, ":BPS", "16");
+ snprintf (s, sizeof (s), "%d", channels);
+ deadbeef->pl_add_meta (it, ":CHANNELS", s);
+ snprintf (s, sizeof (s), "%d", samplerate);
+ deadbeef->pl_add_meta (it, ":SAMPLERATE", s);
+ int br = (int)roundf(fsize / duration * 8 / 1000);
+ snprintf (s, sizeof (s), "%d", br);
+ deadbeef->pl_add_meta (it, ":BITRATE", s);
// embedded cue
deadbeef->pl_lock ();
const char *cuesheet = deadbeef->pl_find_meta (it, "cuesheet");
@@ -1123,23 +1311,45 @@ static const char *filetypes[] = { "RAW AAC", "MP4 AAC", NULL };
// define plugin interface
static DB_decoder_t plugin = {
DB_PLUGIN_SET_API_VERSION
- .plugin.version_major = 0,
- .plugin.version_minor = 1,
+ .plugin.version_major = 1,
+ .plugin.version_minor = 0,
.plugin.type = DB_PLUGIN_DECODER,
.plugin.id = "aac",
- .plugin.name = "AAC decoder based on FAAD2",
- .plugin.descr = "aac (m4a, mp4, ...) player",
- .plugin.author = "Alexey Yakovenko",
- .plugin.email = "waker@users.sourceforge.net",
+ .plugin.name = "AAC player",
+ .plugin.descr = "plays aac files, supports raw aac files, as well as mp4 container",
+ .plugin.copyright =
+ "Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>\n"
+ "\n"
+ "Uses modified libmp4ff (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com\n"
+ "\n"
+ "This program is free software; you can redistribute it and/or\n"
+ "modify it under the terms of the GNU General Public License\n"
+ "as published by the Free Software Foundation; either version 2\n"
+ "of the License, or (at your option) any later version.\n"
+ "\n"
+ "This program is distributed in the hope that it will be useful,\n"
+ "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+ "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+ "GNU General Public License for more details.\n"
+ "\n"
+ "You should have received a copy of the GNU General Public License\n"
+ "along with this program; if not, write to the Free Software\n"
+ "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n"
+ ,
.plugin.website = "http://deadbeef.sf.net",
.open = aac_open,
.init = aac_init,
.free = aac_free,
- .read_int16 = aac_read_int16,
+ .read = aac_read,
.seek = aac_seek,
.seek_sample = aac_seek_sample,
.insert = aac_insert,
.read_metadata = aac_read_metadata,
+#ifdef USE_MP4FF
+ // mp4ff metadata writer doesn't work
+ // .write_metadata = aac_write_metadata,
+#else
+#endif
.exts = exts,
.filetypes = filetypes
};
diff --git a/plugins/aac/aac_parser.c b/plugins/aac/aac_parser.c
index 230dec9e..07c1ca6a 100644
--- a/plugins/aac/aac_parser.c
+++ b/plugins/aac/aac_parser.c
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@@ -77,7 +77,7 @@ aac_sync(const uint8_t *buf, int *channels, int *sample_rate, int *bit_rate, int
//trace ("invalid channels\n");
return 0;
}
- trace ("channels %d\n", aac_channels[channel_conf]);
+ trace ("channels %d (#%d)\n", aac_channels[channel_conf], channel_conf);
int orig_copy = (buf[3] & 0x20) >> 5;
int home = (buf[3] & 0x10) >> 4;
int copyright_ident_bit = (buf[3] & 0x08) >> 3;
diff --git a/plugins/aac/aac_parser.h b/plugins/aac/aac_parser.h
index 53e7916d..7d3b886e 100644
--- a/plugins/aac/aac_parser.h
+++ b/plugins/aac/aac_parser.h
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
diff --git a/plugins/adplug/Makefile.am b/plugins/adplug/Makefile.am
index a75f38b5..393f2d59 100644
--- a/plugins/adplug/Makefile.am
+++ b/plugins/adplug/Makefile.am
@@ -5,11 +5,12 @@ adlibdir = $(libdir)/$(PACKAGE)
pkglib_LTLIBRARIES = adplug.la
AM_CFLAGS = $(CFLAGS) -std=c99 -I$(adplugpath)/adplug -I$(adplugpath)/libbinio
+adplug_la_LDFLAGS = -module -nostdlib -lsupc++
-AM_CPPFLAGS = $(CXXFLAGS) -Dstricmp=strcasecmp -DVERSION=\"2.1\" -I$(adplugpath)/adplug -I$(adplugpath)/libbinio
+AM_CPPFLAGS = $(CXXFLAGS) -Dstricmp=strcasecmp -DVERSION=\"2.1\" -I$(adplugpath)/adplug -I$(adplugpath)/libbinio -fno-exceptions -fno-rtti -nostdlib -fno-unwind-tables
-adplug_la_SOURCES = adplug-db.cpp\
- plugin.c\
+adplug_la_SOURCES = plugin.c\
+ adplug-db.cpp\
libbinio/binfile.h\
libbinio/binio.h\
libbinio/binstr.h\
@@ -134,5 +135,4 @@ adplug_la_SOURCES = adplug-db.cpp\
# adplug/database.cpp
# adplug/database.h
-adplug_la_LDFLAGS = -module
endif
diff --git a/plugins/adplug/adplug-db.cpp b/plugins/adplug/adplug-db.cpp
index 567d55ca..a25f3ffe 100644
--- a/plugins/adplug/adplug-db.cpp
+++ b/plugins/adplug/adplug-db.cpp
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@@ -31,11 +31,22 @@
//#define trace(...) { fprintf (stderr, __VA_ARGS__); }
#define trace(fmt,...)
+int _Unwind_Resume_or_Rethrow;
+int _Unwind_RaiseException;
+int _Unwind_GetLanguageSpecificData;
+int _Unwind_Resume;
+int _Unwind_DeleteException;
+int _Unwind_GetTextRelBase;
+int _Unwind_SetIP;
+int _Unwind_GetDataRelBase;
+int _Unwind_GetRegionStart;
+int _Unwind_SetGR;
+int _Unwind_GetIPInfo;
+
extern "C" {
extern DB_decoder_t adplug_plugin;
-static DB_functions_t *deadbeef;
-
+DB_functions_t *deadbeef;
const char *adplug_exts[] = { "A2M", "ADL", "AMD", "BAM", "CFF", "CMF", "D00", "DFM", "DMO", "DRO", "DTM", "HSC", "HSP", "IMF", "KSM", "LAA", "LDS", "M", "MAD", "MKJ", "MSC", "MTK", "RAD", "RAW", "RIX", "ROL", "S3M", "SA2", "SAT", "SCI", "SNG", "XAD", "XMS", "XSM", "JBM", NULL };
@@ -53,7 +64,7 @@ typedef struct {
} adplug_info_t;
DB_fileinfo_t *
-adplug_open (void) {
+adplug_open (uint32_t hints) {
adplug_info_t *info = (adplug_info_t *)malloc (sizeof (adplug_info_t));
DB_fileinfo_t *_info = (DB_fileinfo_t *)info;
memset (info, 0, sizeof (adplug_info_t));
@@ -67,17 +78,17 @@ adplug_init (DB_fileinfo_t *_info, DB_playItem_t *it) {
adplug_info_t *info = (adplug_info_t *)_info;
int samplerate = deadbeef->conf_get_int ("synth.samplerate", 44100);
- int bps = deadbeef->get_output ()->bitspersample ();
+ int bps = 16; // NOTE: there's no need to support 8bit input, because adplug simply downgrades 16bit signal to 8bits
int channels = 2;
- info->opl = new CEmuopl (samplerate, true, channels == 2);
+ info->opl = new CEmuopl (samplerate, bps == 16 ? true : false, channels == 2);
// opl->settype (Copl::TYPE_OPL2);
- info->decoder = CAdPlug::factory (it->fname, info->opl, CAdPlug::players);
+ info->decoder = CAdPlug::factory (deadbeef->pl_find_meta (it, ":URI"), info->opl, CAdPlug::players);
if (!info->decoder) {
- trace ("adplug: failed to open %s\n", it->fname);
+ trace ("adplug: failed to open %s\n", deadbeef->pl_find_meta (it, ":URI"));
return -1;
}
- info->subsong = it->tracknum;
+ info->subsong = deadbeef->pl_find_meta_int (it, ":TRACKNUM", 0);
info->decoder->rewind (info->subsong);
float dur = deadbeef->pl_get_item_duration (it);
info->totalsamples = dur * samplerate;
@@ -86,9 +97,10 @@ adplug_init (DB_fileinfo_t *_info, DB_playItem_t *it) {
// fill in mandatory plugin fields
_info->plugin = &adplug_plugin;
- _info->bps = bps;
- _info->channels = channels;
- _info->samplerate = samplerate;
+ _info->fmt.bps = bps;
+ _info->fmt.channels = channels;
+ _info->fmt.samplerate = samplerate;
+ _info->fmt.channelmask = _info->fmt.channels == 1 ? DDB_SPEAKER_FRONT_LEFT : (DDB_SPEAKER_FRONT_LEFT | DDB_SPEAKER_FRONT_RIGHT);
_info->readpos = 0;
trace ("adplug_init ok (songlength=%d, duration=%f, totalsamples=%d)\n", info->decoder->songlength (info->subsong), deadbeef->pl_get_item_duration (it), info->totalsamples);
@@ -112,16 +124,16 @@ adplug_free (DB_fileinfo_t *_info) {
}
int
-adplug_read_int16 (DB_fileinfo_t *_info, char *bytes, int size) {
+adplug_read (DB_fileinfo_t *_info, char *bytes, int size) {
// try decode `size' bytes
// return number of decoded bytes
// return 0 on EOF
adplug_info_t *info = (adplug_info_t *)_info;
bool playing = true;
int i;
- int sampsize = (_info->bps >> 3) * _info->channels;
+ int sampsize = (_info->fmt.bps / 8) * _info->fmt.channels;
- if (info->currentsample + size/4 >= info->totalsamples) {
+ if (info->currentsample + size/sampsize >= info->totalsamples) {
// clip
size = (info->totalsamples - info->currentsample) * sampsize;
trace ("adplug: clipped to %d\n", size);
@@ -139,11 +151,11 @@ adplug_read_int16 (DB_fileinfo_t *_info, char *bytes, int size) {
{
while (info->toadd < 0)
{
- info->toadd += _info->samplerate;
+ info->toadd += _info->fmt.samplerate;
playing = info->decoder->update ();
// decoder->time_ms += 1000 / plr.p->getrefresh ();
}
- i = min (towrite, (long) (info->toadd / info->decoder->getrefresh () + 4) & ~3);
+ i = min (towrite, (long) (info->toadd / info->decoder->getrefresh () + sampsize) & ~(sampsize-1));
info->opl->update ((short *) sndbufpos, i);
sndbufpos += i * sampsize;
size -= i * sampsize;
@@ -152,7 +164,7 @@ adplug_read_int16 (DB_fileinfo_t *_info, char *bytes, int size) {
info->toadd -= (long) (info->decoder->getrefresh () * i);
}
info->currentsample += size/4;
- _info->readpos = (float)info->currentsample / _info->samplerate;
+ _info->readpos = (float)info->currentsample / _info->fmt.samplerate;
return initsize-size;
}
@@ -172,7 +184,7 @@ adplug_seek_sample (DB_fileinfo_t *_info, int sample) {
while (info->currentsample < sample) {
info->decoder->update ();
- int framesize = _info->samplerate / info->decoder->getrefresh ();
+ int framesize = _info->fmt.samplerate / info->decoder->getrefresh ();
info->currentsample += framesize;
}
@@ -183,7 +195,7 @@ adplug_seek_sample (DB_fileinfo_t *_info, int sample) {
info->toadd = 0;
trace ("adplug: new position after seek: %d of %d\n", info->currentsample, info->totalsamples);
- _info->readpos = (float)info->currentsample / _info->samplerate;
+ _info->readpos = (float)info->currentsample / _info->fmt.samplerate;
return 0;
}
@@ -193,7 +205,7 @@ adplug_seek (DB_fileinfo_t *_info, float time) {
// seek to specified time in seconds
// return 0 on success
// return -1 on failure
- return adplug_seek_sample (_info, time * _info->samplerate);
+ return adplug_seek_sample (_info, time * _info->fmt.samplerate);
}
static const char *
@@ -252,11 +264,9 @@ adplug_insert (DB_playItem_t *after, const char *fname) {
if (dur < 0.1) {
continue;
}
- DB_playItem_t *it = deadbeef->pl_item_alloc ();
- it->decoder_id = deadbeef->plug_get_decoder_id (adplug_plugin.plugin.id);
- it->fname = strdup (fname);
- it->filetype = adplug_get_extension (fname);
- it->tracknum = i;
+ DB_playItem_t *it = deadbeef->pl_item_alloc_init (fname, adplug_plugin.plugin.id);
+ deadbeef->pl_add_meta (it, ":FILETYPE", adplug_get_extension (fname));
+ deadbeef->pl_set_meta_int (it, ":TRACKNUM", i);
deadbeef->pl_set_item_duration (it, dur);
#if 0
// add metainfo
diff --git a/plugins/adplug/libbinio/binfile.cpp b/plugins/adplug/libbinio/binfile.cpp
index 336f1b3b..a20315ac 100644
--- a/plugins/adplug/libbinio/binfile.cpp
+++ b/plugins/adplug/libbinio/binfile.cpp
@@ -22,6 +22,8 @@
#include "binfile.h"
+extern DB_functions_t *deadbeef;
+
/***** binfbase *****/
binfbase::binfbase()
@@ -37,7 +39,8 @@ binfbase::~binfbase()
void binfbase::close()
{
if(f != NULL) {
- if(fclose(f) == EOF) err |= Fatal; else f = NULL;
+ deadbeef->fclose(f);
+ f = NULL;
} else
err |= NotOpen;
}
@@ -49,9 +52,9 @@ void binfbase::seek(long pos, Offset offs)
if(f == NULL) { err |= NotOpen; return; }
switch(offs) {
- case Set: error = fseek(f, pos, SEEK_SET); break;
- case Add: error = fseek(f, pos, SEEK_CUR); break;
- case End: error = fseek(f, pos, SEEK_END); break;
+ case Set: error = deadbeef->fseek(f, pos, SEEK_SET); break;
+ case Add: error = deadbeef->fseek(f, pos, SEEK_CUR); break;
+ case End: error = deadbeef->fseek(f, pos, SEEK_END); break;
}
if(error == -1) err |= Fatal;
@@ -63,7 +66,7 @@ long binfbase::pos()
if(f == NULL) { err |= NotOpen; return 0; }
- pos = ftell(f);
+ pos = deadbeef->ftell(f);
if(pos == -1) {
err |= Fatal;
@@ -96,7 +99,7 @@ binifstream::~binifstream()
void binifstream::open(const char *filename, const Mode mode)
{
- f = fopen(filename, "rb");
+ f = deadbeef->fopen(filename);
if(f == NULL)
switch(errno) {
@@ -118,8 +121,9 @@ binifstream::Byte binifstream::getByte()
int read;
if(f != NULL) {
- read = fgetc(f);
- if(read == EOF) err |= Eof;
+ if (1 != deadbeef->fread (&read, 1, 1, f)) {
+ err |= Eof;
+ }
return (Byte)read;
} else {
err |= NotOpen;
@@ -151,6 +155,7 @@ binofstream::~binofstream()
void binofstream::open(const char *filename, const Mode mode)
{
+#if 0
const char *modestr = "wb";
// Check if append mode is desired
@@ -168,6 +173,7 @@ void binofstream::open(const char *filename, const Mode mode)
case ENOENT: err |= NotFound; break;
default: err |= NotOpen; break;
}
+#endif
}
#if BINIO_ENABLE_STRING
@@ -179,10 +185,12 @@ void binofstream::open(const std::string &filename, const Mode mode)
void binofstream::putByte(Byte b)
{
+#if 0
if(f == NULL) { err |= NotOpen; return; }
if(fputc(b, f) == EOF)
err |= Fatal;
+#endif
}
/***** binfstream *****/
@@ -220,11 +228,11 @@ void binfstream::open(const char *filename, const Mode mode)
if(mode & Append) // Create & append
modestr = "a+b";
- f = fopen(filename, modestr);
+ f = deadbeef->fopen(filename);
// NoCreate & append (emulated -- not possible with standard C fopen())
if(f != NULL && (mode & Append) && (mode & NoCreate))
- ferror = fseek(f, 0, SEEK_END);
+ ferror = deadbeef->fseek(f, 0, SEEK_END);
if(f == NULL || ferror == -1) {
switch(errno) {
diff --git a/plugins/adplug/libbinio/binfile.h b/plugins/adplug/libbinio/binfile.h
index ad24baee..013e5777 100644
--- a/plugins/adplug/libbinio/binfile.h
+++ b/plugins/adplug/libbinio/binfile.h
@@ -24,6 +24,8 @@
#include "binio.h"
+#include "../../../deadbeef.h"
+
class binfbase: virtual public binio
{
public:
@@ -47,7 +49,7 @@ public:
virtual long pos();
protected:
- FILE *f;
+ DB_FILE *f;
};
class binifstream: public binistream, virtual public binfbase
diff --git a/plugins/adplug/plugin.c b/plugins/adplug/plugin.c
index c4e8e04c..0b53da31 100644
--- a/plugins/adplug/plugin.c
+++ b/plugins/adplug/plugin.c
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@@ -26,13 +26,13 @@ extern const char *adplug_exts[];
extern const char *adplug_filetypes[];
DB_fileinfo_t *
-adplug_open (void);
+adplug_open (uint32_t hints);
int
adplug_init (DB_fileinfo_t *_info, DB_playItem_t *it);
void
adplug_free (DB_fileinfo_t *);
int
-adplug_read_int16 (DB_fileinfo_t *, char *bytes, int size);
+adplug_read (DB_fileinfo_t *, char *bytes, int size);
int
adplug_seek_sample (DB_fileinfo_t *, int sample);
int
@@ -47,21 +47,40 @@ adplug_stop (void);
// define plugin interface
DB_decoder_t adplug_plugin = {
DB_PLUGIN_SET_API_VERSION
- .plugin.version_major = 0,
- .plugin.version_minor = 1,
+ .plugin.version_major = 1,
+ .plugin.version_minor = 0,
.plugin.type = DB_PLUGIN_DECODER,
.plugin.id = "adplug",
.plugin.name = "Adplug player",
.plugin.descr = "Adplug player (ADLIB OPL2/OPL3 emulator)",
- .plugin.author = "Alexey Yakovenko",
- .plugin.email = "waker@users.sourceforge.net",
+ .plugin.copyright =
+ "Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>\n"
+ "\n"
+ "Uses modified AdPlug library\n"
+ "Copyright (C) 1999 - 2010 Simon Peter, et al.\n"
+ "http://adplug.sourceforge.net/\n"
+ "\n"
+ "This program is free software; you can redistribute it and/or\n"
+ "modify it under the terms of the GNU General Public License\n"
+ "as published by the Free Software Foundation; either version 2\n"
+ "of the License, or (at your option) any later version.\n"
+ "\n"
+ "This program is distributed in the hope that it will be useful,\n"
+ "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+ "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+ "GNU General Public License for more details.\n"
+ "\n"
+ "You should have received a copy of the GNU General Public License\n"
+ "along with this program; if not, write to the Free Software\n"
+ "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n"
+ ,
.plugin.website = "http://deadbeef.sf.net",
.plugin.start = adplug_start,
.plugin.stop = adplug_stop,
.open = adplug_open,
.init = adplug_init,
.free = adplug_free,
- .read_int16 = adplug_read_int16,
+ .read = adplug_read,
.seek = adplug_seek,
.seek_sample = adplug_seek_sample,
.insert = adplug_insert,
diff --git a/plugins/alsa/alsa.c b/plugins/alsa/alsa.c
index 96d7645b..809cb7ed 100644
--- a/plugins/alsa/alsa.c
+++ b/plugins/alsa/alsa.c
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -23,8 +23,8 @@
#include "../../deadbeef.h"
#include "../../config.h"
-//#define trace(...) { fprintf(stderr, __VA_ARGS__); }
-#define trace(fmt,...)
+#define trace(...) { fprintf(stderr, __VA_ARGS__); }
+//#define trace(fmt,...)
#define min(x,y) ((x)<(y)?(x):(y))
@@ -41,8 +41,7 @@ DB_functions_t *deadbeef;
static snd_pcm_t *audio;
static int alsa_terminate;
-static int requested_rate = -1;
-static int alsa_rate = 44100;
+static ddb_waveformat_t requested_fmt;
static int state; // one of output_state_t
static uintptr_t mutex;
static intptr_t alsa_tid;
@@ -53,7 +52,6 @@ static snd_pcm_uframes_t period_size;
static snd_pcm_uframes_t req_buffer_size;
static snd_pcm_uframes_t req_period_size;
-static int conf_alsa_resample = 0;
static char conf_alsa_soundcard[100] = "default";
//static snd_async_handler_t *pcm_callback;
@@ -91,7 +89,7 @@ static int
palsa_free (void);
static int
-palsa_change_rate (int rate);
+palsa_setformat (ddb_waveformat_t *fmt);
static int
palsa_play (void);
@@ -106,12 +104,6 @@ static int
palsa_unpause (void);
static int
-palsa_get_rate (void);
-
-static int
-palsa_get_bps (void);
-
-static int
palsa_get_channels (void);
static int
@@ -121,11 +113,21 @@ static void
palsa_enum_soundcards (void (*callback)(const char *name, const char *desc, void*), void *userdata);
static int
-palsa_set_hw_params (int samplerate) {
+palsa_set_hw_params (ddb_waveformat_t *fmt) {
snd_pcm_hw_params_t *hw_params = NULL;
-// int alsa_resample = conf_get_int ("alsa.resample", 0);
int err = 0;
+ memcpy (&plugin.fmt, fmt, sizeof (ddb_waveformat_t));
+ if (!plugin.fmt.channels) {
+ // generic format
+ plugin.fmt.bps = 16;
+ plugin.fmt.is_float = 0;
+ plugin.fmt.channels = 2;
+ plugin.fmt.samplerate = 44100;
+ plugin.fmt.channelmask = 3;
+ }
+retry:
+
if ((err = snd_pcm_hw_params_malloc (&hw_params)) < 0) {
fprintf (stderr, "cannot allocate hardware parameter structure (%s)\n",
snd_strerror (err));
@@ -144,25 +146,87 @@ palsa_set_hw_params (int samplerate) {
goto error;
}
- snd_pcm_format_t fmt;
+ snd_pcm_format_t sample_fmt;
+
+ switch (plugin.fmt.bps) {
+ case 8:
+ sample_fmt = SND_PCM_FORMAT_S8;
+ break;
+ case 16:
#if WORDS_BIGENDIAN
- fmt = SND_PCM_FORMAT_S16_BE;
+ sample_fmt = SND_PCM_FORMAT_S16_BE;
#else
- fmt = SND_PCM_FORMAT_S16_LE;
+ sample_fmt = SND_PCM_FORMAT_S16_LE;
#endif
- if ((err = snd_pcm_hw_params_set_format (audio, hw_params, fmt)) < 0) {
- fprintf (stderr, "cannot set sample format (%s)\n",
- snd_strerror (err));
- goto error;
+ break;
+ case 24:
+#if WORDS_BIGENDIAN
+ sample_fmt = SND_PCM_FORMAT_S24_3BE;
+#else
+ sample_fmt = SND_PCM_FORMAT_S24_3LE;
+#endif
+ break;
+ case 32:
+ if (plugin.fmt.is_float) {
+#if WORDS_BIGENDIAN
+ sample_fmt = SND_PCM_FORMAT_FLOAT_BE;
+#else
+ sample_fmt = SND_PCM_FORMAT_FLOAT_LE;
+#endif
+ }
+ else {
+#if WORDS_BIGENDIAN
+ sample_fmt = SND_PCM_FORMAT_S32_BE;
+#else
+ sample_fmt = SND_PCM_FORMAT_S32_LE;
+#endif
+ }
+ break;
+ };
+
+ if ((err = snd_pcm_hw_params_set_format (audio, hw_params, sample_fmt)) < 0) {
+ fprintf (stderr, "cannot set sample format (%s), trying all supported formats\n", snd_strerror (err));
+
+ int fmt_cnt[] = { 16, 24, 32, 32, 8 };
+#if WORDS_BIGENDIAN
+ int fmt[] = { SND_PCM_FORMAT_S16_BE, SND_PCM_FORMAT_S24_3BE, SND_PCM_FORMAT_S32_BE, SND_PCM_FORMAT_FLOAT_BE, SND_PCM_FORMAT_S8, -1 };
+#else
+ int fmt[] = { SND_PCM_FORMAT_S16_LE, SND_PCM_FORMAT_S24_3LE, SND_PCM_FORMAT_S32_LE, SND_PCM_FORMAT_FLOAT_LE, SND_PCM_FORMAT_S8, -1 };
+#endif
+
+ // 1st try formats with higher bps
+ int i = 0;
+ for (i = 0; fmt[i] != -1; i++) {
+ if (fmt[i] != sample_fmt && fmt_cnt[i] > plugin.fmt.bps) {
+ if (snd_pcm_hw_params_set_format (audio, hw_params, fmt[i]) >= 0) {
+ break;
+ }
+ }
+ }
+ if (fmt[i] == -1) {
+ // next try formats with lower bps
+ i = 0;
+ for (i = 0; fmt[i] != -1; i++) {
+ if (fmt[i] != sample_fmt && fmt_cnt[i] < plugin.fmt.bps) {
+ if (snd_pcm_hw_params_set_format (audio, hw_params, fmt[i]) >= 0) {
+ break;
+ }
+ }
+ }
+ }
+
+ if (fmt[i] == -1) {
+ goto error;
+ }
}
- snd_pcm_hw_params_get_format (hw_params, &fmt);
- trace ("chosen sample format: %04Xh\n", (int)fmt);
+ snd_pcm_hw_params_get_format (hw_params, &sample_fmt);
+ trace ("chosen sample format: %04Xh\n", (int)sample_fmt);
- int val = samplerate;
+ int val = plugin.fmt.samplerate;
int ret = 0;
- if ((err = snd_pcm_hw_params_set_rate_resample (audio, hw_params, conf_alsa_resample)) < 0) {
+ if ((err = snd_pcm_hw_params_set_rate_resample (audio, hw_params, 1)) < 0) {
fprintf (stderr, "cannot setup resampling (%s)\n",
snd_strerror (err));
goto error;
@@ -173,10 +237,10 @@ palsa_set_hw_params (int samplerate) {
snd_strerror (err));
goto error;
}
- alsa_rate = val;
- trace ("chosen samplerate: %d Hz\n", alsa_rate);
+ plugin.fmt.samplerate = val;
+ trace ("chosen samplerate: %d Hz\n", val);
- if ((err = snd_pcm_hw_params_set_channels (audio, hw_params, 2)) < 0) {
+ if ((err = snd_pcm_hw_params_set_channels (audio, hw_params, plugin.fmt.channels)) < 0) {
fprintf (stderr, "cannot set channel count (%s)\n",
snd_strerror (err));
goto error;
@@ -201,8 +265,70 @@ palsa_set_hw_params (int samplerate) {
fprintf (stderr, "cannot set parameters (%s)\n",
snd_strerror (err));
goto error;
+
+// if (plugin.fmt.channels > 2 && plugin.fmt.samplerate >= 96000) {
+// plugin.fmt.samplerate = 48000;
+// fprintf (stderr, "falling back to 48000KHz\n");
+// goto retry;
+// }
+ }
+
+ plugin.fmt.is_float = 0;
+ switch (sample_fmt) {
+ case SND_PCM_FORMAT_S8:
+ plugin.fmt.bps = 8;
+ break;
+ case SND_PCM_FORMAT_S16_BE:
+ case SND_PCM_FORMAT_S16_LE:
+ plugin.fmt.bps = 16;
+ break;
+ case SND_PCM_FORMAT_S24_3BE:
+ case SND_PCM_FORMAT_S24_3LE:
+ plugin.fmt.bps = 24;
+ break;
+ case SND_PCM_FORMAT_S32_BE:
+ case SND_PCM_FORMAT_S32_LE:
+ plugin.fmt.bps = 32;
+ break;
+ case SND_PCM_FORMAT_FLOAT_LE:
+ case SND_PCM_FORMAT_FLOAT_BE:
+ plugin.fmt.bps = 32;
+ plugin.fmt.is_float = 1;
+ break;
+ }
+
+ trace ("chosen bps: %d (%s)\n", plugin.fmt.bps, plugin.fmt.is_float ? "float" : "int");
+
+ plugin.fmt.channels = nchan;
+ plugin.fmt.channelmask = 0;
+ if (nchan == 1) {
+ plugin.fmt.channelmask = DDB_SPEAKER_FRONT_LEFT;
+ }
+ if (nchan == 2) {
+ plugin.fmt.channelmask = DDB_SPEAKER_FRONT_LEFT | DDB_SPEAKER_FRONT_RIGHT;
+ }
+ if (nchan == 3) {
+ plugin.fmt.channelmask = DDB_SPEAKER_FRONT_LEFT | DDB_SPEAKER_FRONT_RIGHT | DDB_SPEAKER_LOW_FREQUENCY;
+ }
+ if (nchan == 4) {
+ plugin.fmt.channelmask = DDB_SPEAKER_FRONT_LEFT | DDB_SPEAKER_FRONT_RIGHT | DDB_SPEAKER_BACK_LEFT | DDB_SPEAKER_BACK_RIGHT;
+ }
+ if (nchan == 5) {
+ plugin.fmt.channelmask = DDB_SPEAKER_FRONT_LEFT | DDB_SPEAKER_FRONT_RIGHT | DDB_SPEAKER_BACK_LEFT | DDB_SPEAKER_BACK_RIGHT | DDB_SPEAKER_FRONT_CENTER;
+ }
+ if (nchan == 6) {
+ plugin.fmt.channelmask = DDB_SPEAKER_FRONT_LEFT | DDB_SPEAKER_FRONT_RIGHT | DDB_SPEAKER_BACK_LEFT | DDB_SPEAKER_BACK_RIGHT | DDB_SPEAKER_FRONT_CENTER | DDB_SPEAKER_LOW_FREQUENCY;
+ }
+ if (nchan == 7) {
+ plugin.fmt.channelmask = DDB_SPEAKER_FRONT_LEFT | DDB_SPEAKER_FRONT_RIGHT | DDB_SPEAKER_BACK_LEFT | DDB_SPEAKER_BACK_RIGHT | DDB_SPEAKER_FRONT_CENTER | DDB_SPEAKER_SIDE_LEFT | DDB_SPEAKER_SIDE_RIGHT;
+ }
+ if (nchan == 8) {
+ plugin.fmt.channelmask = DDB_SPEAKER_FRONT_LEFT | DDB_SPEAKER_FRONT_RIGHT | DDB_SPEAKER_BACK_LEFT | DDB_SPEAKER_BACK_RIGHT | DDB_SPEAKER_FRONT_CENTER | DDB_SPEAKER_SIDE_LEFT | DDB_SPEAKER_SIDE_RIGHT | DDB_SPEAKER_LOW_FREQUENCY;
}
error:
+ if (err < 0) {
+ memset (&plugin.fmt, 0, sizeof (ddb_waveformat_t));
+ }
if (hw_params) {
snd_pcm_hw_params_free (hw_params);
}
@@ -216,10 +342,8 @@ palsa_init (void) {
mutex = 0;
// get and cache conf variables
- strcpy (conf_alsa_soundcard, deadbeef->conf_get_str ("alsa_soundcard", "default"));
- conf_alsa_resample = deadbeef->conf_get_int ("alsa.resample", 0);
+ deadbeef->conf_get_str ("alsa_soundcard", "default", conf_alsa_soundcard, sizeof (conf_alsa_soundcard));
trace ("alsa_soundcard: %s\n", conf_alsa_soundcard);
- trace ("alsa.resample: %d\n", conf_alsa_resample);
snd_pcm_sw_params_t *sw_params = NULL;
state = OUTPUT_STATE_STOPPED;
@@ -232,11 +356,11 @@ palsa_init (void) {
mutex = deadbeef->mutex_create ();
- if (requested_rate != -1) {
- alsa_rate = requested_rate;
+ if (requested_fmt.samplerate != 0) {
+ memcpy (&plugin.fmt, &requested_fmt, sizeof (ddb_waveformat_t));
}
- if (palsa_set_hw_params (alsa_rate) < 0) {
+ if (palsa_set_hw_params (&plugin.fmt) < 0) {
goto open_error;
}
@@ -309,27 +433,61 @@ open_error:
}
int
-palsa_change_rate (int rate) {
- trace ("palsa_change_rate: %d\n", rate);
- requested_rate = rate;
+palsa_setformat (ddb_waveformat_t *fmt) {
+ memcpy (&requested_fmt, fmt, sizeof (ddb_waveformat_t));
+ trace ("palsa_setformat %dbit %s %dch %dHz channelmask=%X\n", fmt->bps, fmt->is_float ? "float" : "int", fmt->channels, fmt->samplerate, fmt->channelmask);
if (!audio) {
- return alsa_rate;
+ return -1;
}
- if (rate == alsa_rate) {
- trace ("palsa_change_rate %d: ignored\n", rate);
- return rate;
+ if (!memcmp (fmt, &plugin.fmt, sizeof (ddb_waveformat_t))) {
+ trace ("palsa_setformat ignored\n");
+ return 0;
}
- state = OUTPUT_STATE_STOPPED;
+#if 0
+ else {
+ trace ("switching format:\n"
+ "bps %d -> %d\n"
+ "is_float %d -> %d\n"
+ "is_multichannel %d -> %d\n"
+ "channels %d -> %d\n"
+ "samplerate %d -> %d\n"
+ "channelmask %d -> %d\n"
+ , fmt->bps, plugin.fmt.bps
+ , fmt->is_float, plugin.fmt.is_float
+ , fmt->is_multichannel, plugin.fmt.is_multichannel
+ , fmt->channels, plugin.fmt.channels
+ , fmt->samplerate, plugin.fmt.samplerate
+ , fmt->channelmask, plugin.fmt.channelmask
+ );
+ }
+#endif
LOCK;
+ int s = state;
+ state = OUTPUT_STATE_STOPPED;
snd_pcm_drop (audio);
- int ret = palsa_set_hw_params (rate);
+ int ret = palsa_set_hw_params (fmt);
UNLOCK;
if (ret < 0) {
- trace ("palsa_change_rate: impossible to set samplerate to %d\n", rate);
- return alsa_rate;
+ trace ("palsa_change_rate: impossible to set requested format\n");
+ return -1;
}
- trace ("chosen samplerate: %d\n", alsa_rate);
- return alsa_rate;
+ trace ("new format %dbit %s %dch %dHz channelmask=%X\n", plugin.fmt.bps, plugin.fmt.is_float ? "float" : "int", plugin.fmt.channels, plugin.fmt.samplerate, plugin.fmt.channelmask);
+
+ switch (s) {
+ case OUTPUT_STATE_STOPPED:
+ return palsa_stop ();
+ case OUTPUT_STATE_PLAYING:
+ return palsa_play ();
+ case OUTPUT_STATE_PAUSED:
+ if (0 != palsa_play ()) {
+ return -1;
+ }
+ if (0 != palsa_pause ()) {
+ return -1;
+ }
+ break;
+ }
+ return 0;
}
int
@@ -453,33 +611,6 @@ palsa_unpause (void) {
return 0;
}
-int
-palsa_get_rate (void) {
- if (!audio) {
- palsa_init ();
- }
- return alsa_rate;
-}
-
-int
-palsa_get_bps (void) {
- return 16;
-}
-
-int
-palsa_get_channels (void) {
- return 2;
-}
-
-static int
-palsa_get_endianness (void) {
-#if WORDS_BIGENDIAN
- return 1;
-#else
- return 0;
-#endif
-}
-
static void
palsa_thread (void *context) {
prctl (PR_SET_NAME, "deadbeef-alsa", 0, 0, 0, 0);
@@ -500,10 +631,10 @@ palsa_thread (void *context) {
break;
}
err = 0;
- char buf[period_size * 4];
- int bytes_to_write = palsa_callback (buf, period_size * 4);
+ char buf[period_size * (plugin.fmt.bps>>3) * plugin.fmt.channels];
+ int bytes_to_write = palsa_callback (buf, period_size * (plugin.fmt.bps>>3) * plugin.fmt.channels);
- if ( bytes_to_write >= 4 ) {
+ if (bytes_to_write >= (plugin.fmt.bps>>3) * plugin.fmt.channels) {
err = snd_pcm_writei (audio, buf, snd_pcm_bytes_to_frames(audio, bytes_to_write));
}
else {
@@ -541,68 +672,29 @@ palsa_thread (void *context) {
frames_to_deliver = snd_pcm_avail_update (audio);
}
UNLOCK;
- usleep (period_size * 1000000 / alsa_rate / 2);
+ usleep (period_size * 1000000 / plugin.fmt.samplerate / 2);
}
}
static int
palsa_callback (char *stream, int len) {
- int bytesread = deadbeef->streamer_read (stream, len);
-
-// FIXME: move volume control to streamer_read for copy optimization
-#if 0
- int16_t vol[4];
- vol[0] = volume_get_amp () * 255; // that will be extra 8 bits
- // pack 4 times
- vol[1] = vol[2] = vol[3] = vol[0];
-
- // apply volume with mmx
- __asm__ volatile(
- " mov %0, %%ecx\n\t"
- " shr $4, %%ecx\n\t"
- " mov %1, %%eax\n\t"
- " movq %2, %mm1\n\t"
- "1:\n\t"
- " movq [%%eax], %mm0\n\t"
- " movq %mm0, %mm2\n\t"
- " movq %mm0, %mm3\n\t"
- " pmullw %mm1, %mm2\n\t"
- " pmulhw %mm1, %mm3\n\t"
- " psrlw $8, %mm2\n\t" // discard lowest 8 bits
- " psllw $8, %mm3\n\t" // shift left 8 lsbs of hiwords
- " por %mm3, %mm2\n\t" // OR them together
- " movq %mm3, [%%eax]\n\t" // load back to memory
- " add $8, %%eax\n\t"
- " dec %%ecx\n\t"
- " jnz 1b\n\t"
- :
- : "r"(len), "r"(stream), "r"(vol)
- : "%ecx", "%eax"
- );
-
-#else
- int16_t ivolume = deadbeef->volume_get_amp () * 1000;
- for (int i = 0; i < bytesread/2; i++) {
- ((int16_t*)stream)[i] = (int16_t)(((int32_t)(((int16_t*)stream)[i])) * ivolume / 1000);
- }
-#endif
- return bytesread;
+ return deadbeef->streamer_read (stream, len);
}
static int
palsa_configchanged (DB_event_t *ev, uintptr_t data) {
- int alsa_resample = deadbeef->conf_get_int ("alsa.resample", 0);
- const char *alsa_soundcard = deadbeef->conf_get_str ("alsa_soundcard", "default");
+ deadbeef->conf_lock ();
+ const char *alsa_soundcard = deadbeef->conf_get_str_fast ("alsa_soundcard", "default");
int buffer = deadbeef->conf_get_int ("alsa.buffer", DEFAULT_BUFFER_SIZE);
int period = deadbeef->conf_get_int ("alsa.period", DEFAULT_PERIOD_SIZE);
if (audio &&
- (alsa_resample != conf_alsa_resample
- || strcmp (alsa_soundcard, conf_alsa_soundcard)
+ (strcmp (alsa_soundcard, conf_alsa_soundcard)
|| buffer != req_buffer_size
|| period != req_period_size)) {
trace ("alsa: config option changed, restarting\n");
deadbeef->sendmessage (M_REINIT_SOUND, 0, 0, 0);
}
+ deadbeef->conf_unlock ();
return 0;
}
@@ -659,7 +751,6 @@ alsa_load (DB_functions_t *api) {
}
static const char settings_dlg[] =
- "property \"Use ALSA resampling\" checkbox alsa.resample 0;\n"
"property \"Release device while stopped\" checkbox alsa.freeonstop 0;\n"
"property \"Preferred buffer size\" entry alsa.buffer " DEFAULT_BUFFER_SIZE_STR ";\n"
"property \"Preferred period size\" entry alsa.period " DEFAULT_PERIOD_SIZE_STR ";\n"
@@ -668,29 +759,40 @@ static const char settings_dlg[] =
// define plugin interface
static DB_output_t plugin = {
DB_PLUGIN_SET_API_VERSION
- .plugin.version_major = 0,
- .plugin.version_minor = 1,
- .plugin.nostop = 1,
+ .plugin.version_major = 1,
+ .plugin.version_minor = 0,
.plugin.type = DB_PLUGIN_OUTPUT,
+ .plugin.id = "alsa",
.plugin.name = "ALSA output plugin",
.plugin.descr = "plays sound through linux standard alsa library",
- .plugin.author = "Alexey Yakovenko",
- .plugin.email = "waker@users.sourceforge.net",
+ .plugin.copyright =
+ "Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>\n"
+ "\n"
+ "This program is free software; you can redistribute it and/or\n"
+ "modify it under the terms of the GNU General Public License\n"
+ "as published by the Free Software Foundation; either version 2\n"
+ "of the License, or (at your option) any later version.\n"
+ "\n"
+ "This program is distributed in the hope that it will be useful,\n"
+ "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+ "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+ "GNU General Public License for more details.\n"
+ "\n"
+ "You should have received a copy of the GNU General Public License\n"
+ "along with this program; if not, write to the Free Software\n"
+ "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n"
+ ,
.plugin.website = "http://deadbeef.sf.net",
.plugin.start = alsa_start,
.plugin.stop = alsa_stop,
.plugin.configdialog = settings_dlg,
.init = palsa_init,
.free = palsa_free,
- .change_rate = palsa_change_rate,
+ .setformat = palsa_setformat,
.play = palsa_play,
.stop = palsa_stop,
.pause = palsa_pause,
.unpause = palsa_unpause,
.state = palsa_get_state,
- .samplerate = palsa_get_rate,
- .bitspersample = palsa_get_bps,
- .channels = palsa_get_channels,
- .endianness = palsa_get_endianness,
.enum_soundcards = palsa_enum_soundcards,
};
diff --git a/plugins/ao/Makefile b/plugins/ao/Makefile
new file mode 100644
index 00000000..5e0b3f3f
--- /dev/null
+++ b/plugins/ao/Makefile
@@ -0,0 +1,32 @@
+OUT=ao.so
+
+CC=gcc
+
+ZLIB_LIBS=-lz
+
+CFLAGS?=-O2 -fomit-frame-pointer
+CFLAGS+=-Wall -fPIC -DPATH_MAX=1024 -DHAS_PSXCPU=1 -I../.. -I./ -Ieng_ssf -Ieng_qsf -Ieng_dsf
+
+LDFLAGS+=-module -shared $(ZLIB_LIBS) -lm
+
+SOURCES=plugin.c main.c corlett.c\
+eng_dsf/eng_dsf.c eng_dsf/dc_hw.c eng_dsf/aica.c eng_dsf/aicadsp.c eng_dsf/arm7.c eng_dsf/arm7i.c\
+eng_ssf/m68kcpu.c eng_ssf/m68kopac.c eng_ssf/m68kopdm.c eng_ssf/m68kopnz.c eng_ssf/m68kops.c \
+eng_ssf/scsp.c eng_ssf/scspdsp.c eng_ssf/sat_hw.c eng_ssf/eng_ssf.c\
+eng_qsf/eng_qsf.c eng_qsf/kabuki.c eng_qsf/qsound.c eng_qsf/z80.c eng_qsf/z80dasm.c\
+eng_psf/eng_psf.c eng_psf/psx.c eng_psf/psx_hw.c eng_psf/peops/spu.c \
+eng_psf/eng_psf2.c eng_psf/peops2/spu2.c eng_psf/peops2/dma2.c eng_psf/peops2/registers2.c\
+eng_psf/eng_spu.c
+
+OBJECTS=$(SOURCES:.c=.o)
+
+all: $(SOURCES) $(OUT)
+
+$(OUT): $(OBJECTS)
+ $(CC) $(LDFLAGS) $(OBJECTS) -o $@
+
+.c.o:
+ $(CC) $(CFLAGS) $< -c -o $@
+
+clean:
+ rm $(OBJECTS) $(OUT)
diff --git a/plugins/ao/Makefile.am b/plugins/ao/Makefile.am
deleted file mode 100644
index 39ccd749..00000000
--- a/plugins/ao/Makefile.am
+++ /dev/null
@@ -1,27 +0,0 @@
-if HAVE_AO
-aodir = $(libdir)/$(PACKAGE)
-pkglib_LTLIBRARIES = ao.la
-ao_la_SOURCES = plugin.c main.c corlett.c\
-eng_dsf/eng_dsf.c eng_dsf/dc_hw.c eng_dsf/aica.c eng_dsf/aicadsp.c eng_dsf/arm7.c eng_dsf/arm7i.c\
-eng_ssf/m68kcpu.c eng_ssf/m68kopac.c eng_ssf/m68kopdm.c eng_ssf/m68kopnz.c eng_ssf/m68kops.c \
-eng_ssf/scsp.c eng_ssf/scspdsp.c eng_ssf/sat_hw.c eng_ssf/eng_ssf.c\
-eng_qsf/eng_qsf.c eng_qsf/kabuki.c eng_qsf/qsound.c eng_qsf/z80.c eng_qsf/z80dasm.c\
-eng_psf/eng_psf.c eng_psf/psx.c eng_psf/psx_hw.c eng_psf/peops/spu.c \
-eng_psf/eng_psf2.c eng_psf/peops2/spu2.c eng_psf/peops2/dma2.c eng_psf/peops2/registers2.c\
-eng_psf/eng_spu.c\
-ao.h corlett.h cpuintrf.h eng_protos.h mem.h osd_cpu.h\
-eng_dsf/aicadsp.h eng_dsf/aica.h eng_dsf/arm7.h eng_dsf/arm7i.h eng_dsf/arm7thumb.h eng_dsf/dc_hw.h\
-eng_ssf/m68kconf.h eng_ssf/m68kcpu.h eng_ssf/m68k.h eng_ssf/m68kmame.h eng_ssf/m68kops.h eng_ssf/sat_hw.h eng_ssf/scspdsp.h eng_ssf/scsp.h \
-eng_qsf/qsound.h eng_qsf/z80dasm.h eng_qsf/z80.h\
-eng_psf/cpuintrf.h eng_psf/mamemem.h eng_psf/psx.h\
-eng_psf/peops/adsr.h eng_psf/peops/dma.h eng_psf/peops/externals.h eng_psf/peops/gauss_i.h eng_psf/peops/registers.h eng_psf/peops/regs.h eng_psf/peops/spu.h eng_psf/peops/stdafx.h\
-eng_psf/peops2/adsr.h eng_psf/peops2/dma.h eng_psf/peops2/externals.h eng_psf/peops2/gauss_i.h eng_psf/peops2/psemuxa.h eng_psf/peops2/registers.h eng_psf/peops2/regs.h eng_psf/peops2/reverb.h eng_psf/peops2/spu.h eng_psf/peops2/stdafx.h
-
-ao_la_LDFLAGS = -module -fPIC
-
-EXTRA_DIST=eng_psf/peops/reverb.c eng_psf/peops/adsr.c eng_psf/peops/registers.c eng_psf/peops/dma.c eng_psf/peops2/spu2.c eng_psf/peops2/reverb2.c eng_psf/peops2/adsr2.c eng_dsf/arm7memil.c eng_dsf/aicalfo.c eng_ssf/scsplfo.c
-
-ao_la_LIBADD = $(LDADD)
-AM_CFLAGS = $(CFLAGS) -Wall -DPATH_MAX=1024 -DHAS_PSXCPU=1 -I.. -Ieng_ssf -Ieng_qsf -Ieng_dsf -lm $(ZLIB_LIBS)
-endif
-
diff --git a/plugins/ao/eng_ssf/m68kcpu.c b/plugins/ao/eng_ssf/m68kcpu.c
index 9624ea5c..f9b442bc 100644
--- a/plugins/ao/eng_ssf/m68kcpu.c
+++ b/plugins/ao/eng_ssf/m68kcpu.c
@@ -37,8 +37,6 @@ static const char* copyright_notice =
#include "m68kops.h"
#include "m68kcpu.h"
-#pragma GCC optimize("O0")
-
/* ======================================================================== */
/* ================================= DATA ================================= */
/* ======================================================================== */
diff --git a/plugins/ao/plugin.c b/plugins/ao/plugin.c
index 2e29c4e0..02f70ef2 100644
--- a/plugins/ao/plugin.c
+++ b/plugins/ao/plugin.c
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@@ -48,7 +48,7 @@ typedef struct {
} aoplug_info_t;
static DB_fileinfo_t *
-aoplug_open (void) {
+aoplug_open (uint32_t hints) {
DB_fileinfo_t *_info = malloc (sizeof (aoplug_info_t));
aoplug_info_t *info = (aoplug_info_t *)_info;
memset (info, 0, sizeof (aoplug_info_t));
@@ -59,16 +59,17 @@ static int
aoplug_init (DB_fileinfo_t *_info, DB_playItem_t *it) {
aoplug_info_t *info = (aoplug_info_t *)_info;
- _info->bps = 16;
- _info->channels = 2;
- _info->samplerate = 44100;
+ _info->fmt.bps = 16;
+ _info->fmt.channels = 2;
+ _info->fmt.samplerate = deadbeef->conf_get_int ("synth.samplerate", 44100);
+ _info->fmt.channelmask = _info->fmt.channels == 1 ? DDB_SPEAKER_FRONT_LEFT : (DDB_SPEAKER_FRONT_LEFT | DDB_SPEAKER_FRONT_RIGHT);
_info->readpos = 0;
_info->plugin = &plugin;
info->duration = deadbeef->pl_get_item_duration (it);
- DB_FILE *file = deadbeef->fopen (it->fname);
+ DB_FILE *file = deadbeef->fopen (deadbeef->pl_find_meta (it, ":URI"));
if (!file) {
- trace ("psf: failed to fopen %s\n", it->fname);
+ trace ("psf: failed to fopen %s\n", deadbeef->pl_find_meta (it, ":URI"));
return -1;
}
@@ -81,7 +82,7 @@ aoplug_init (DB_fileinfo_t *_info, DB_playItem_t *it) {
}
if (deadbeef->fread(info->filebuffer, 1, info->filesize, file) != info->filesize) {
- fprintf(stderr, "psf: file read error: %s\n", it->fname);
+ fprintf(stderr, "psf: file read error: %s\n", deadbeef->pl_find_meta (it, ":URI"));
deadbeef->fclose (file);
return -1;
}
@@ -93,7 +94,7 @@ aoplug_init (DB_fileinfo_t *_info, DB_playItem_t *it) {
return -1;
}
- info->decoder = ao_start (info->type, it->fname, (uint8 *)info->filebuffer, info->filesize);
+ info->decoder = ao_start (info->type, deadbeef->pl_find_meta (it, ":URI"), (uint8 *)info->filebuffer, info->filesize);
if (!info->decoder) {
fprintf (stderr, "psf: ao_start failed\n");
return -1;
@@ -116,11 +117,11 @@ aoplug_free (DB_fileinfo_t *_info) {
}
static int
-aoplug_read_int16 (DB_fileinfo_t *_info, char *bytes, int size) {
+aoplug_read (DB_fileinfo_t *_info, char *bytes, int size) {
aoplug_info_t *info = (aoplug_info_t *)_info;
// printf ("aoplug_read_int16 %d samples, curr %d, end %d\n", size/4, info->currentsample, (int)(info->duration * _info->samplerate));
- if (info->currentsample >= info->duration * _info->samplerate) {
+ if (info->currentsample >= info->duration * _info->fmt.samplerate) {
return 0;
}
@@ -152,7 +153,8 @@ aoplug_read_int16 (DB_fileinfo_t *_info, char *bytes, int size) {
info->remaining = 735;
}
}
- info->currentsample += (initsize-size) / (_info->channels * _info->bps/8);
+ info->currentsample += (initsize-size) / (_info->fmt.channels * _info->fmt.bps/8);
+ _info->readpos = (float)info->currentsample / _info->fmt.samplerate;
return initsize-size;
}
@@ -168,13 +170,13 @@ aoplug_seek_sample (DB_fileinfo_t *_info, int sample) {
info->skipsamples = sample;
}
info->currentsample = sample;
- _info->readpos = (float)sample / _info->samplerate;
+ _info->readpos = (float)sample / _info->fmt.samplerate;
return 0;
}
static int
aoplug_seek (DB_fileinfo_t *_info, float time) {
- return aoplug_seek_sample (_info, time * _info->samplerate);
+ return aoplug_seek_sample (_info, time * _info->fmt.samplerate);
}
static void
@@ -250,9 +252,7 @@ aoplug_insert (DB_playItem_t *after, const char *fname) {
free (buffer);
- DB_playItem_t *it = deadbeef->pl_item_alloc ();
- it->decoder_id = deadbeef->plug_get_decoder_id (plugin.plugin.id);
- it->fname = strdup (fname);
+ DB_playItem_t *it = deadbeef->pl_item_alloc_init (fname, plugin.plugin.id);
const char *ext = fname + strlen (fname);
while (*ext != '.' && ext > fname) {
ext--;
@@ -260,38 +260,44 @@ aoplug_insert (DB_playItem_t *after, const char *fname) {
if (*ext == '.') {
ext++;
if (!strcasecmp (ext, "psf") || !strcasecmp (ext, "minipsf")) {
- it->filetype = filetypes[0];
+ deadbeef->pl_add_meta (it, ":FILETYPE", filetypes[0]);
}
else if (!strcasecmp (ext, "psf2") || !strcasecmp (ext, "minipsf2")) {
- it->filetype = filetypes[1];
+ deadbeef->pl_add_meta (it, ":FILETYPE", filetypes[1]);
}
else if (!strcasecmp (ext, "spu")) {
- it->filetype = filetypes[2];
+ deadbeef->pl_add_meta (it, ":FILETYPE", filetypes[2]);
}
else if (!strcasecmp (ext, "ssf") || !strcasecmp (ext, "minissf")) {
- it->filetype = filetypes[3];
- }
- else if (!strcasecmp (ext, "dsf") || !strcasecmp (ext, "minidsf")) {
- it->filetype = filetypes[5];
+ deadbeef->pl_add_meta (it, ":FILETYPE", filetypes[3]);
}
else if (!strcasecmp (ext, "qsf") || !strcasecmp (ext, "miniqsf")) {
- it->filetype = filetypes[4];
+ deadbeef->pl_add_meta (it, ":FILETYPE", filetypes[4]);
+ }
+ else if (!strcasecmp (ext, "dsf") || !strcasecmp (ext, "minidsf")) {
+ deadbeef->pl_add_meta (it, ":FILETYPE", filetypes[5]);
}
}
else {
- it->filetype = filetypes[0];
+ deadbeef->pl_add_meta (it, ":FILETYPE", filetypes[0]);
}
float duration = 120;
+ float fade = 0;
if (have_info) {
int i;
for (i = 1; i < 9; i++) {
if (!strncasecmp (info.title[i], "Length: ", 8)) {
- int min, sec;
- if (sscanf (info.info[i], "%d:%d", &min, &sec) == 2) {
+ printf ("len: %s\n", info.info[i]);
+ int min;
+ float sec;
+ if (sscanf (info.info[i], "%d:%f", &min, &sec) == 2) {
duration = min * 60 + sec;
}
+ else if (sscanf (info.info[i], "%f", &sec) == 1) {
+ duration = sec;
+ }
aoplug_add_meta (it, NULL, info.info[i], info.title[i]);
}
else if (!strncasecmp (info.title[i], "Name: ", 6) || !strncasecmp (info.title[i], "Song: ", 6)) {
@@ -312,12 +318,16 @@ aoplug_insert (DB_playItem_t *after, const char *fname) {
else if (!strncasecmp (info.title[i], "Ripper: ", 8)) {
aoplug_add_meta (it, "vendor", info.info[i], info.title[i]);
}
+ else if (!strncasecmp (info.title[i], "Fade: ", 6)) {
+ fade = atof (info.info[i]);
+ aoplug_add_meta (it, NULL, info.info[i], info.title[i]);
+ }
else {
aoplug_add_meta (it, NULL, info.info[i], info.title[i]);
}
}
}
- deadbeef->pl_set_item_duration (it, duration);
+ deadbeef->pl_set_item_duration (it, duration+fade);
deadbeef->pl_add_meta (it, "title", NULL);
after = deadbeef->pl_insert_item (after, it);
deadbeef->pl_item_unref (it);
@@ -336,21 +346,40 @@ aoplug_stop (void) {
static DB_decoder_t plugin = {
DB_PLUGIN_SET_API_VERSION
- .plugin.version_major = 0,
- .plugin.version_minor = 1,
+ .plugin.version_major = 1,
+ .plugin.version_minor = 0,
.plugin.type = DB_PLUGIN_DECODER,
.plugin.id = "psf",
.plugin.name = "Audio Overload plugin",
.plugin.descr = "psf, psf2, spu, ssf, minidsf player based on Audio Overload library",
- .plugin.author = "Alexey Yakovenko",
- .plugin.email = "waker@users.sourceforge.net",
+ .plugin.copyright =
+ "Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>\n"
+ "\n"
+ "Uses modified aosdk-1.4.8 - library for playing .PSF (Sony PlayStation), .SPU (Sony PlayStation), .PSF2 (Sony PlayStation 2), .SSF (Sega Saturn), .DSF (Sega Dreamcast), and .QSF (Capcom QSound) audio file formats,\n"
+ "http://rbelmont.mameworld.info/?page_id=221\n"
+ "Copyright © 2007-2009 R. Belmont and Richard Bannister.\n"
+ "\n"
+ "This program is free software; you can redistribute it and/or\n"
+ "modify it under the terms of the GNU General Public License\n"
+ "as published by the Free Software Foundation; either version 2\n"
+ "of the License, or (at your option) any later version.\n"
+ "\n"
+ "This program is distributed in the hope that it will be useful,\n"
+ "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+ "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+ "GNU General Public License for more details.\n"
+ "\n"
+ "You should have received a copy of the GNU General Public License\n"
+ "along with this program; if not, write to the Free Software\n"
+ "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n"
+ ,
.plugin.website = "http://deadbeef.sf.net",
.plugin.start = aoplug_start,
.plugin.stop = aoplug_stop,
.open = aoplug_open,
.init = aoplug_init,
.free = aoplug_free,
- .read_int16 = aoplug_read_int16,
+ .read = aoplug_read,
.seek = aoplug_seek,
.seek_sample = aoplug_seek_sample,
.insert = aoplug_insert,
diff --git a/plugins/artwork/Makefile.am b/plugins/artwork/Makefile.am
index b60c86cb..8f9ea166 100644
--- a/plugins/artwork/Makefile.am
+++ b/plugins/artwork/Makefile.am
@@ -5,6 +5,6 @@ artwork_la_SOURCES = artwork.c artwork.h albumartorg.c albumartorg.h lastfm.c la
artwork_la_LDFLAGS = -module
-artwork_la_LIBADD = $(LDADD) $(ARTWORK_DEPS_LIBS)
-AM_CFLAGS = -std=c99 $(ARTWORK_DEPS_CFLAGS)
+artwork_la_LIBADD = $(LDADD) $(ARTWORK_DEPS_LIBS) $(IMLIB2_DEPS_LIBS)
+AM_CFLAGS = -std=c99 $(ARTWORK_DEPS_CFLAGS) $(IMLIB2_DEPS_CFLAGS)
endif
diff --git a/plugins/artwork/albumartorg.c b/plugins/artwork/albumartorg.c
index 71b640de..ada7179f 100644
--- a/plugins/artwork/albumartorg.c
+++ b/plugins/artwork/albumartorg.c
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
diff --git a/plugins/artwork/albumartorg.h b/plugins/artwork/albumartorg.h
index 4d1d494a..49231b04 100644
--- a/plugins/artwork/albumartorg.h
+++ b/plugins/artwork/albumartorg.h
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
diff --git a/plugins/artwork/artwork.c b/plugins/artwork/artwork.c
index fbbe71d9..b29db8f2 100644
--- a/plugins/artwork/artwork.c
+++ b/plugins/artwork/artwork.c
@@ -6,6 +6,8 @@
#include <dirent.h>
#include <unistd.h>
#include <fnmatch.h>
+#include <inttypes.h>
+#include <Imlib2.h>
#include "../../deadbeef.h"
#include "artwork.h"
#include "lastfm.h"
@@ -16,8 +18,8 @@
//#define trace(...) { fprintf(stderr, __VA_ARGS__); }
#define trace(...)
-#define DEFAULT_COVER_PATH (PREFIX "/share/deadbeef/pixmaps/noartwork.jpg")
-#define DEFAULT_FILEMASK "*cover*.jpg;*front*.jpg"
+static char default_cover[PATH_MAX];
+#define DEFAULT_FILEMASK "*cover*.jpg;*front*.jpg;*folder*.jpg"
static DB_artwork_plugin_t plugin;
DB_functions_t *deadbeef;
@@ -28,6 +30,7 @@ typedef struct cover_query_s {
char *fname;
char *artist;
char *album;
+ int size;
artwork_callback callback;
void *user_data;
struct cover_query_s *next;
@@ -36,44 +39,50 @@ typedef struct cover_query_s {
static cover_query_t *queue;
static cover_query_t *queue_tail;
static uintptr_t mutex;
+static uintptr_t imlib_mutex;
static uintptr_t cond;
static volatile int terminate;
static volatile int clear_queue;
static intptr_t tid;
-int artwork_enable_embedded;
-int artwork_enable_local;
-int artwork_enable_lfm;
-int artwork_enable_aao;
-int artwork_reset_time;
-char artwork_filemask[200];
+static int artwork_enable_embedded;
+static int artwork_enable_local;
+static int artwork_enable_lfm;
+static int artwork_enable_aao;
+static time_t artwork_reset_time;
+static char artwork_filemask[200];
-void
-make_cache_dir_path (char *path, int size, const char *album, const char *artist) {
- int sz = snprintf (path, size, "%s/artcache/", deadbeef->get_config_dir ());
- size -= sz;
+static const char *get_default_cover (void) {
+ return default_cover;
+}
+
+int
+make_cache_dir_path (char *path, int size, const char *artist, int img_size) {
+ const char *cache = getenv ("XDG_CACHE_HOME");
+
+ int sz;
+
+ if (img_size == -1) {
+ sz = snprintf (path, size, cache ? "%s/deadbeef/covers/" : "%s/.cache/deadbeef/covers/", cache ? cache : getenv ("HOME"));
+ }
+ else {
+ sz = snprintf (path, size, cache ? "%s/deadbeef/covers-%d/" : "%s/.cache/deadbeef/covers-%d/", cache ? cache : getenv ("HOME"), img_size);
+ }
path += sz;
- sz = snprintf (path, size, "%s", artist);
+ sz += snprintf (path, size-sz, "%s", artist);
for (char *p = path; *p; p++) {
if (*p == '/') {
*p = '_';
}
}
+ return sz;
}
void
-make_cache_path (char *path, int size, const char *album, const char *artist) {
- int sz = snprintf (path, size, "%s/artcache/", deadbeef->get_config_dir ());
- size -= sz;
- path += sz;
-
- sz = snprintf (path, size, "%s", artist);
- for (char *p = path; *p; p++) {
- if (*p == '/') {
- *p = '_';
- }
- }
+make_cache_path (char *path, int size, const char *album, const char *artist, int img_size) {
+ char *p = path;
+ int sz = make_cache_dir_path (path, size, artist, img_size);
size -= sz;
path += sz;
sz = snprintf (path, size, "/%s.jpg", album);
@@ -85,7 +94,7 @@ make_cache_path (char *path, int size, const char *album, const char *artist) {
}
void
-queue_add (const char *fname, const char *artist, const char *album, artwork_callback callback, void *user_data) {
+queue_add (const char *fname, const char *artist, const char *album, int img_size, artwork_callback callback, void *user_data) {
if (!artist) {
artist = "";
}
@@ -106,6 +115,7 @@ queue_add (const char *fname, const char *artist, const char *album, artwork_cal
q->fname = strdup (fname);
q->artist = strdup (artist);
q->album = strdup (album);
+ q->size = img_size;
q->callback = callback;
q->user_data = user_data;
if (queue_tail) {
@@ -166,8 +176,64 @@ check_dir (const char *dir, mode_t mode)
#define BUFFER_SIZE 4096
static int
-copy_file (const char *in, const char *out) {
+copy_file (const char *in, const char *out, int img_size) {
trace ("copying %s to %s\n", in, out);
+
+ if (img_size != -1) {
+ deadbeef->mutex_lock (imlib_mutex);
+ // need to scale, use imlib2
+ Imlib_Image img = imlib_load_image_immediately (in);
+ if (!img) {
+ trace ("file %s not found, or imlib2 can't load it\n", in);
+ deadbeef->mutex_unlock (imlib_mutex);
+ return -1;
+ }
+ imlib_context_set_image(img);
+ int w = imlib_image_get_width ();
+ int h = imlib_image_get_height ();
+ int sw, sh;
+ if (deadbeef->conf_get_int ("artwork.scale_towards_longer", 1)) {
+ if (w > h) {
+ sh = img_size;
+ sw = img_size * w / h;
+ }
+ else {
+ sw = img_size;
+ sh = img_size * h / w;
+ }
+ }
+ else {
+ if (w < h) {
+ sh = img_size;
+ sw = img_size * w / h;
+ }
+ else {
+ sw = img_size;
+ sh = img_size * h / w;
+ }
+ }
+ Imlib_Image scaled = imlib_create_image (sw, sh);
+ imlib_context_set_image (scaled);
+ imlib_blend_image_onto_image (img, 1, 0, 0, w, h, 0, 0, sw, sh);
+ Imlib_Load_Error err = 0;
+ imlib_image_set_format ("jpg");
+ imlib_save_image_with_error_return (out, &err);
+ if (err != 0) {
+ trace ("imlib save %s returned %d\n", out, err);
+ imlib_free_image ();
+ imlib_context_set_image(img);
+ imlib_free_image ();
+ deadbeef->mutex_unlock (imlib_mutex);
+ return -1;
+ }
+ imlib_free_image ();
+ imlib_context_set_image(img);
+ imlib_free_image ();
+ deadbeef->mutex_unlock (imlib_mutex);
+
+ return 0;
+ }
+
FILE *fin = fopen (in, "rb");
if (!fin) {
trace ("artwork: failed to open file %s for reading\n", in);
@@ -287,19 +353,31 @@ fetcher_thread (void *none)
deadbeef->mutex_unlock (mutex);
while (!terminate && queue && !clear_queue) {
cover_query_t *param = queue;
- char path [1024];
+ char path [PATH_MAX];
struct dirent **files;
int files_count;
- make_cache_dir_path (path, sizeof (path), param->album, param->artist);
+ make_cache_dir_path (path, sizeof (path), param->artist, -1);
trace ("cache folder: %s\n", path);
if (!check_dir (path, 0755)) {
queue_pop ();
trace ("failed to create folder for %s %s\n", param->album, param->artist);
continue;
}
+ if (param->size != -1) {
+ make_cache_dir_path (path, sizeof (path), param->artist, param->size);
+ trace ("cache folder: %s\n", path);
+ if (!check_dir (path, 0755)) {
+ queue_pop ();
+ trace ("failed to create folder for %s %s\n", param->album, param->artist);
+ continue;
+ }
+ }
trace ("fetching cover for %s %s\n", param->album, param->artist);
+ char cache_path[1024];
+ make_cache_path (cache_path, sizeof (cache_path), param->album, param->artist, -1);
+ int got_pic = 0;
// try to load embedded from id3v2
if (deadbeef->is_local_file (param->fname)) {
@@ -309,7 +387,6 @@ fetcher_thread (void *none)
memset (&tag, 0, sizeof (tag));
DB_FILE *fp = deadbeef->fopen (param->fname);
current_file = fp;
- int got_id3v2_pic = 0;
if (fp) {
int res = deadbeef->junk_id3v2_read_full (NULL, &tag, fp);
if (!res) {
@@ -349,8 +426,6 @@ fetcher_thread (void *none)
int sz = f->size - (data - f->data);
char tmp_path[1024];
- char cache_path[1024];
- make_cache_path (cache_path, sizeof (cache_path), param->album, param->artist);
trace ("will write id3v2 APIC into %s\n", cache_path);
snprintf (tmp_path, sizeof (tmp_path), "%s.part", cache_path);
FILE *out = fopen (tmp_path, "w+b");
@@ -372,107 +447,90 @@ fetcher_thread (void *none)
break;
}
unlink (tmp_path);
- got_id3v2_pic = 1;
+ got_pic = 1;
break;
}
}
}
- if (got_id3v2_pic) {
- if (param->callback) {
- param->callback (param->fname, param->artist, param->album, param->user_data);
- }
- queue_pop ();
- continue;
- }
deadbeef->junk_id3v2_free (&tag);
current_file = NULL;
deadbeef->fclose (fp);
}
- }
- }
- // try to load embedded from apev2
- if (deadbeef->is_local_file (param->fname)) {
- if (artwork_enable_embedded) {
- trace ("trying to load artwork from apev2 tag for %s\n", param->fname);
- DB_apev2_tag_t tag;
- memset (&tag, 0, sizeof (tag));
- DB_FILE *fp = deadbeef->fopen (param->fname);
- current_file = fp;
- int got_apev2_pic = 0;
- if (fp) {
- int res = deadbeef->junk_apev2_read_full (NULL, &tag, fp);
- if (!res) {
- for (DB_apev2_frame_t *f = tag.frames; f; f = f->next) {
- if (!strcasecmp (f->key, "cover art (front)")) {
- uint8_t *name = f->data, *ext = f->data, *data = f->data;
- uint8_t *end = f->data + f->size;
- while (data < end && *data)
- data++;
- if (data == end) {
- trace ("artwork: apev2 cover art frame has no name\n");
- continue;
- }
- int sz = end - ++data;
- if (sz < 20) {
- trace ("artwork: apev2 cover art frame is too small\n");
- continue;
- }
- ext = strrchr (name, '.');
- if (!ext || !*++ext) {
- trace ("artwork: apev2 cover art name has no extension\n");
- continue;
- }
- if (strcasecmp (ext, "jpeg") && strcasecmp (ext, "jpg") && strcasecmp (ext, "png")) {
- trace ("artwork: unsupported file type: %s\n", ext);
- continue;
- }
- trace ("found apev2 cover art of %d bytes (%s)\n", sz, ext);
- char tmp_path[1024];
- char cache_path[1024];
- make_cache_path (cache_path, sizeof (cache_path), param->album, param->artist);
- trace ("will write apev2 cover art into %s\n", cache_path);
- snprintf (tmp_path, sizeof (tmp_path), "%s.part", cache_path);
- FILE *out = fopen (tmp_path, "w+b");
- if (!out) {
- trace ("artwork: failed to open %s for writing\n", tmp_path);
- break;
- }
- if (fwrite (data, 1, sz, out) != sz) {
- trace ("artwork: failed to write apev2 picture into %s\n", tmp_path);
+ // try to load embedded from apev2
+ {
+ trace ("trying to load artwork from apev2 tag for %s\n", param->fname);
+ DB_apev2_tag_t tag;
+ memset (&tag, 0, sizeof (tag));
+ DB_FILE *fp = deadbeef->fopen (param->fname);
+ current_file = fp;
+ if (fp) {
+ int res = deadbeef->junk_apev2_read_full (NULL, &tag, fp);
+ if (!res) {
+ for (DB_apev2_frame_t *f = tag.frames; f; f = f->next) {
+ if (!strcasecmp (f->key, "cover art (front)")) {
+ uint8_t *name = f->data, *ext = f->data, *data = f->data;
+ uint8_t *end = f->data + f->size;
+ while (data < end && *data)
+ data++;
+ if (data == end) {
+ trace ("artwork: apev2 cover art frame has no name\n");
+ continue;
+ }
+ int sz = end - ++data;
+ if (sz < 20) {
+ trace ("artwork: apev2 cover art frame is too small\n");
+ continue;
+ }
+ ext = strrchr (name, '.');
+ if (!ext || !*++ext) {
+ trace ("artwork: apev2 cover art name has no extension\n");
+ continue;
+ }
+ if (strcasecmp (ext, "jpeg") && strcasecmp (ext, "jpg") && strcasecmp (ext, "png")) {
+ trace ("artwork: unsupported file type: %s\n", ext);
+ continue;
+ }
+ trace ("found apev2 cover art of %d bytes (%s)\n", sz, ext);
+ char tmp_path[1024];
+ char cache_path[1024];
+ make_cache_path (cache_path, sizeof (cache_path), param->album, param->artist, -1);
+ trace ("will write apev2 cover art into %s\n", cache_path);
+ snprintf (tmp_path, sizeof (tmp_path), "%s.part", cache_path);
+ FILE *out = fopen (tmp_path, "w+b");
+ if (!out) {
+ trace ("artwork: failed to open %s for writing\n", tmp_path);
+ break;
+ }
+ if (fwrite (data, 1, sz, out) != sz) {
+ trace ("artwork: failed to write apev2 picture into %s\n", tmp_path);
+ fclose (out);
+ unlink (tmp_path);
+ break;
+ }
fclose (out);
+ int err = rename (tmp_path, cache_path);
+ if (err != 0) {
+ trace ("Failed not move %s to %s: %s\n", tmp_path, cache_path, strerror (err));
+ unlink (tmp_path);
+ break;
+ }
unlink (tmp_path);
+ got_pic = 1;
break;
}
- fclose (out);
- int err = rename (tmp_path, cache_path);
- if (err != 0) {
- trace ("Failed not move %s to %s: %s\n", tmp_path, cache_path, strerror (err));
- unlink (tmp_path);
- break;
- }
- unlink (tmp_path);
- got_apev2_pic = 1;
- break;
}
}
- }
- if (got_apev2_pic) {
- if (param->callback) {
- param->callback (param->fname, param->artist, param->album, param->user_data);
- }
- queue_pop ();
- continue;
+ deadbeef->junk_apev2_free (&tag);
+ current_file = NULL;
+ deadbeef->fclose (fp);
}
- deadbeef->junk_apev2_free (&tag);
- current_file = NULL;
- deadbeef->fclose (fp);
}
}
- if (artwork_enable_local) {
+ if (!got_pic && artwork_enable_local) {
/* Searching in track directory */
strncpy (path, param->fname, sizeof (path));
char *slash = strrchr (path, '/');
@@ -492,48 +550,50 @@ fetcher_thread (void *none)
strcat (path, files[0]->d_name);
char cache_path[1024];
char tmp_path[1024];
- make_cache_path (cache_path, sizeof (cache_path), param->album, param->artist);
+ make_cache_path (cache_path, sizeof (cache_path), param->album, param->artist, -1);
snprintf (tmp_path, sizeof (tmp_path), "%s.part", cache_path);
- copy_file (path, tmp_path);
+ copy_file (path, tmp_path, -1);
int err = rename (tmp_path, cache_path);
if (err != 0) {
- trace ("Failed not move %s to %s: %s\n", tmp_path, cache_path, strerror (err));
+ trace ("Failed to move %s to %s: %s\n", tmp_path, cache_path, strerror (err));
unlink (tmp_path);
}
int i;
for (i = 0; i < files_count; i++) {
free (files [i]);
}
- if (param->callback) {
- param->callback (param->fname, param->artist, param->album, param->user_data);
- }
- queue_pop ();
- continue;
+ got_pic = 1;
}
}
}
}
- make_cache_path (path, sizeof (path), param->album, param->artist);
-
- if (artwork_enable_lfm && !fetch_from_lastfm (param->artist, param->album, path)) {
- trace ("art found on last.fm for %s %s\n", param->album, param->artist);
- }
- else if (artwork_enable_aao && !fetch_from_albumart_org (param->artist, param->album, path)) {
- trace ("art found on albumart.org for %s %s\n", param->album, param->artist);
- }
- else {
- trace ("art not found for %s %s\n", param->album, param->artist);
-// if (param->callback) {
-// param->callback (DEFAULT_COVER_PATH, param->artist, param->album, param->user_data);
-// }
- queue_pop ();
- continue;
+ if (!got_pic) {
+ if (artwork_enable_lfm && !fetch_from_lastfm (param->artist, param->album, cache_path)) {
+ got_pic = 1;
+ }
+ else if (artwork_enable_aao && !fetch_from_albumart_org (param->artist, param->album, cache_path)) {
+ got_pic = 1;
+ }
}
- trace ("downloaded art for %s %s\n", param->album, param->artist);
- if (param->callback) {
- param->callback (param->fname, param->artist, param->album, param->user_data);
+ if (got_pic) {
+ trace ("downloaded art for %s %s\n", param->album, param->artist);
+ if (param->size != -1) {
+ make_cache_dir_path (path, sizeof (path), param->artist, param->size);
+ trace ("cache folder: %s\n", path);
+ if (!check_dir (path, 0755)) {
+ trace ("failed to create folder %s\n", path);
+ queue_pop ();
+ continue;
+ }
+ char scaled_path[1024];
+ make_cache_path (scaled_path, sizeof (scaled_path), param->album, param->artist, param->size);
+ copy_file (cache_path, scaled_path, param->size);
+ }
+ if (param->callback) {
+ param->callback (param->fname, param->artist, param->album, param->user_data);
+ }
}
queue_pop ();
}
@@ -552,8 +612,27 @@ fetcher_thread (void *none)
}
}
+static char *
+find_image (const char *path) {
+ struct stat stat_buf;
+ if (0 == stat (path, &stat_buf)) {
+ int cache_period = deadbeef->conf_get_int ("artwork.cache.period", 48);
+ time_t tm = time (NULL);
+ // invalidate cache every 2 days
+ if ((cache_period > 0 && (tm - stat_buf.st_mtime > cache_period * 60 * 60))
+ || artwork_reset_time > stat_buf.st_mtime) {
+ trace ("reloading cached file %s\n", path);
+ unlink (path);
+ return NULL;
+ }
+
+ return strdup (path);
+ }
+ return NULL;
+}
+
char*
-get_album_art (const char *fname, const char *artist, const char *album, artwork_callback callback, void *user_data)
+get_album_art (const char *fname, const char *artist, const char *album, int size, artwork_callback callback, void *user_data)
{
// trace ("get_album_art: %s (%s - %s)\n", fname, artist, album);
char path [1024];
@@ -568,33 +647,42 @@ get_album_art (const char *fname, const char *artist, const char *album, artwork
if (!*artist || !*album)
{
//give up
- return strdup (DEFAULT_COVER_PATH);
+ return size == -1 ? strdup (get_default_cover ()) : NULL;
}
if (!deadbeef->is_local_file (fname)) {
- return strdup (DEFAULT_COVER_PATH);
- }
-
- make_cache_path (path, sizeof (path), album, artist);
- struct stat stat_buf;
- if (0 == stat (path, &stat_buf)) {
- int cache_period = deadbeef->conf_get_int ("artwork.cache.period", 48);
- time_t tm = time (NULL);
- // invalidate cache every 2 days
- if ((cache_period > 0 && (tm - stat_buf.st_mtime > cache_period * 60 * 60))
- || artwork_reset_time > stat_buf.st_mtime) {
- trace ("reloading cached file %s\n", path);
- unlink (path);
- queue_add (fname, artist, album, callback, user_data);
- return strdup (DEFAULT_COVER_PATH);
+ return size == -1 ? strdup (get_default_cover ()) : NULL;
+ }
+
+ make_cache_path (path, sizeof (path), album, artist, size);
+ char *p = find_image (path);
+ if (p) {
+ return p;
+ }
+
+ if (size != -1) {
+ // check if we have unscaled image
+ char unscaled_path[1024];
+ make_cache_path (unscaled_path, sizeof (unscaled_path), album, artist, -1);
+ p = find_image (unscaled_path);
+ if (p) {
+ free (p);
+ char dir[1024];
+ make_cache_dir_path (dir, sizeof (dir), artist, size);
+ if (!check_dir (dir, 0755)) {
+ trace ("failed to create folder for %s\n", dir);
+ }
+ else {
+ int res = copy_file (unscaled_path, path, size);
+ if (!res) {
+ return strdup (path);
+ }
+ }
}
-
- trace ("found %s in cache\n", path);
- return strdup (path);
}
- queue_add (fname, artist, album, callback, user_data);
- return strdup (DEFAULT_COVER_PATH);
+ queue_add (fname, artist, album, size, callback, user_data);
+ return size == -1 ? strdup (get_default_cover ()) : NULL;
}
DB_plugin_t *
@@ -639,23 +727,25 @@ artwork_on_configchanged (DB_event_t *ev, uintptr_t data) {
int new_artwork_enable_local = deadbeef->conf_get_int ("artwork.enable_localfolder", 1);
int new_artwork_enable_lfm = deadbeef->conf_get_int ("artwork.enable_lastfm", 0);
int new_artwork_enable_aao = deadbeef->conf_get_int ("artwork.enable_albumartorg", 0);
+
char new_artwork_filemask[200];
- strncpy (new_artwork_filemask, deadbeef->conf_get_str ("artwork.filemask", DEFAULT_FILEMASK), sizeof (new_artwork_filemask));
- new_artwork_filemask[sizeof(new_artwork_filemask)-1] = 0;
+ deadbeef->conf_get_str ("artwork.filemask", DEFAULT_FILEMASK, new_artwork_filemask, sizeof (new_artwork_filemask));
if (new_artwork_enable_embedded != artwork_enable_embedded
|| new_artwork_enable_local != artwork_enable_local
|| new_artwork_enable_lfm != artwork_enable_lfm
|| new_artwork_enable_aao != artwork_enable_aao
|| strcmp (new_artwork_filemask, artwork_filemask)) {
+ trace ("artwork config changed, invalidating cache...\n");
artwork_enable_embedded = new_artwork_enable_embedded;
artwork_enable_local = new_artwork_enable_local;
artwork_enable_lfm = new_artwork_enable_lfm;
artwork_enable_aao = new_artwork_enable_aao;
artwork_reset_time = time (NULL);
strcpy (artwork_filemask, new_artwork_filemask);
- deadbeef->conf_set_int ("artwork.cache_reset_time", artwork_reset_time);
- deadbeef->sendmessage (M_PLAYLISTREFRESH, 0, 0, 0);
+ deadbeef->conf_set_int64 ("artwork.cache_reset_time", artwork_reset_time);
+ artwork_reset (0);
+ deadbeef->sendmessage (M_PLAYLIST_REFRESH, 0, 0, 0);
}
return 0;
@@ -664,20 +754,33 @@ artwork_on_configchanged (DB_event_t *ev, uintptr_t data) {
static int
artwork_plugin_start (void)
{
+ deadbeef->conf_lock ();
+
+ const char *def_art = deadbeef->conf_get_str_fast ("gtkui.nocover_pixmap", NULL);
+ if (!def_art) {
+ snprintf (default_cover, sizeof (default_cover), "%s/noartwork.jpg", deadbeef->get_pixmap_dir ());
+ }
+ else {
+ strcpy (default_cover, def_art);
+ }
terminate = 0;
artwork_enable_embedded = deadbeef->conf_get_int ("artwork.enable_embedded", 1);
artwork_enable_local = deadbeef->conf_get_int ("artwork.enable_localfolder", 1);
artwork_enable_lfm = deadbeef->conf_get_int ("artwork.enable_lastfm", 0);
artwork_enable_aao = deadbeef->conf_get_int ("artwork.enable_albumartorg", 0);
- artwork_reset_time = deadbeef->conf_get_int ("artwork.cache_reset_time", 0);
+ artwork_reset_time = deadbeef->conf_get_int64 ("artwork.cache_reset_time", 0);
+
+ deadbeef->conf_get_str ("artwork.filemask", DEFAULT_FILEMASK, artwork_filemask, sizeof (artwork_filemask));
+
+ deadbeef->conf_unlock ();
- strncpy (artwork_filemask, deadbeef->conf_get_str ("artwork.filemask", DEFAULT_FILEMASK), sizeof (artwork_filemask));
artwork_filemask[sizeof(artwork_filemask)-1] = 0;
deadbeef->ev_subscribe (DB_PLUGIN (&plugin), DB_EV_CONFIGCHANGED, DB_CALLBACK (artwork_on_configchanged), 0);
mutex = deadbeef->mutex_create_nonrecursive ();
+ imlib_mutex = deadbeef->mutex_create_nonrecursive ();
cond = deadbeef->cond_create ();
tid = deadbeef->thread_start_low_priority (fetcher_thread, NULL);
@@ -704,6 +807,10 @@ artwork_plugin_stop (void)
deadbeef->mutex_free (mutex);
mutex = 0;
}
+ if (imlib_mutex) {
+ deadbeef->mutex_free (imlib_mutex);
+ imlib_mutex = 0;
+ }
if (cond) {
deadbeef->cond_free (cond);
cond = 0;
@@ -719,21 +826,42 @@ static const char settings_dlg[] =
"property \"Local cover file mask\" entry artwork.filemask \"" DEFAULT_FILEMASK "\";\n"
"property \"Fetch from last.fm\" checkbox artwork.enable_lastfm 0;\n"
"property \"Fetch from albumart.org\" checkbox artwork.enable_albumartorg 0;\n"
+ "property \"Scale artwork towards longer side\" checkbox artwork.scale_towards_longer 1;\n"
;
+
// define plugin interface
static DB_artwork_plugin_t plugin = {
.plugin.plugin.api_vmajor = DB_API_VERSION_MAJOR,
.plugin.plugin.api_vminor = DB_API_VERSION_MINOR,
+ .plugin.plugin.version_major = 1,
+ .plugin.plugin.version_minor = 0,
.plugin.plugin.type = DB_PLUGIN_MISC,
- .plugin.plugin.id = "cover_loader",
+ .plugin.plugin.id = "artwork",
.plugin.plugin.name = "Album Artwork",
.plugin.plugin.descr = "Loads album artwork either from local directories or from internet",
- .plugin.plugin.author = "Viktor Semykin, Alexey Yakovenko",
- .plugin.plugin.email = "thesame.ml@gmail.com, waker@users.sourceforge.net",
+ .plugin.plugin.copyright =
+ "Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>\n"
+ "Copyright (C) 2009-2011 Viktor Semykin <thesame.ml@gmail.com>\n"
+ "\n"
+ "This program is free software; you can redistribute it and/or\n"
+ "modify it under the terms of the GNU General Public License\n"
+ "as published by the Free Software Foundation; either version 2\n"
+ "of the License, or (at your option) any later version.\n"
+ "\n"
+ "This program is distributed in the hope that it will be useful,\n"
+ "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+ "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+ "GNU General Public License for more details.\n"
+ "\n"
+ "You should have received a copy of the GNU General Public License\n"
+ "along with this program; if not, write to the Free Software\n"
+ "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n"
+ ,
.plugin.plugin.website = "http://deadbeef.sf.net",
.plugin.plugin.start = artwork_plugin_start,
.plugin.plugin.stop = artwork_plugin_stop,
.plugin.plugin.configdialog = settings_dlg,
.get_album_art = get_album_art,
.reset = artwork_reset,
+ .get_default_cover = get_default_cover,
};
diff --git a/plugins/artwork/artwork.h b/plugins/artwork/artwork.h
index ab0fead6..130bf3fe 100644
--- a/plugins/artwork/artwork.h
+++ b/plugins/artwork/artwork.h
@@ -10,10 +10,11 @@ typedef void (*artwork_callback) (const char *fname, const char *artist, const c
typedef struct {
DB_misc_t plugin;
// returns filename of cached image, or NULL
- char* (*get_album_art) (const char *fname, const char *artist, const char *album, artwork_callback callback, void *user_data);
+ char* (*get_album_art) (const char *fname, const char *artist, const char *album, int size, artwork_callback callback, void *user_data);
// this has to be called to clear queue on exit, before caller terminates
// `fast=1' means "don't wait, just flush queue"
void (*reset) (int fast);
+ const char *(*get_default_cover) (void);
} DB_artwork_plugin_t;
#endif /*__ARTWORK_H*/
diff --git a/plugins/artwork/escape.h b/plugins/artwork/escape.h
index d87cf0a1..75d24091 100644
--- a/plugins/artwork/escape.h
+++ b/plugins/artwork/escape.h
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
diff --git a/plugins/artwork/lastfm.c b/plugins/artwork/lastfm.c
index ce95e9d4..2e78fd87 100644
--- a/plugins/artwork/lastfm.c
+++ b/plugins/artwork/lastfm.c
@@ -36,7 +36,7 @@ fetch_from_lastfm (const char *artist, const char *album, const char *dest)
char buffer[1000];
memset (buffer, 0, sizeof (buffer));
char *img = NULL;
- int size = deadbeef->fread (buffer, 1, sizeof (buffer), fp);
+ int size = deadbeef->fread (buffer, 1, sizeof (buffer)-1, fp);
if (size > 0) {
img = strstr (buffer, searchstr);
}
diff --git a/plugins/artwork/lastfm.h b/plugins/artwork/lastfm.h
index 09ec817c..cef71919 100644
--- a/plugins/artwork/lastfm.h
+++ b/plugins/artwork/lastfm.h
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
diff --git a/plugins/cdda/cdda.c b/plugins/cdda/cdda.c
index 2ed54b51..b49c0cea 100644
--- a/plugins/cdda/cdda.c
+++ b/plugins/cdda/cdda.c
@@ -57,8 +57,6 @@ typedef struct {
unsigned int current_sample;
} cdda_info_t;
-static uintptr_t mutex;
-static intptr_t cddb_tid;
struct cddb_thread_params
{
DB_playItem_t *items[100];
@@ -71,7 +69,7 @@ min (int a, int b) {
}
static DB_fileinfo_t *
-cda_open (void) {
+cda_open (uint32_t hints) {
DB_fileinfo_t *_info = malloc (sizeof (cdda_info_t));
memset (_info, 0, sizeof (cdda_info_t));
return _info;
@@ -81,18 +79,18 @@ static int
cda_init (DB_fileinfo_t *_info, DB_playItem_t *it) {
cdda_info_t *info = (cdda_info_t *)_info;
- trace ("cdda: init %s\n", it->fname);
+ trace ("cdda: init %s\n", deadbeef->pl_find_meta (it, ":URI"));
- size_t l = strlen (it->fname);
+ size_t l = strlen (deadbeef->pl_find_meta (it, ":URI"));
char location[l+1];
- memcpy (location, it->fname, l+1);
+ memcpy (location, deadbeef->pl_find_meta (it, ":URI"), l+1);
char *nr = strchr (location, '#');
if (nr) {
*nr = 0; nr++;
}
else {
- trace ("cdda: bad name: %s\n", it->fname);
+ trace ("cdda: bad name: %s\n", deadbeef->pl_find_meta (it, ":URI"));
return -1;
}
int track_nr = atoi (nr);
@@ -115,9 +113,10 @@ cda_init (DB_fileinfo_t *_info, DB_playItem_t *it) {
trace ("cdio nchannels: %d\n", channels);
_info->plugin = &plugin;
- _info->bps = 16,
- _info->channels = 2,
- _info->samplerate = 44100,
+ _info->fmt.bps = 16;
+ _info->fmt.channels = 2;
+ _info->fmt.samplerate = 44100;
+ _info->fmt.channelmask = DDB_SPEAKER_FRONT_LEFT | DDB_SPEAKER_FRONT_RIGHT;
_info->readpos = 0;
info->first_sector = cdio_get_track_lsn (info->cdio, track_nr);
@@ -129,7 +128,7 @@ cda_init (DB_fileinfo_t *_info, DB_playItem_t *it) {
}
int
-cda_read_int16 (DB_fileinfo_t *_info, char *bytes, int size) {
+cda_read (DB_fileinfo_t *_info, char *bytes, int size) {
cdda_info_t *info = (cdda_info_t *)_info;
int extrasize = 0;
@@ -181,7 +180,7 @@ cda_read_int16 (DB_fileinfo_t *_info, char *bytes, int size) {
retsize += extrasize;
// trace ("requested: %d; tail_len: %d; size: %d; sectors_to_read: %d; return: %d\n", initsize, tail_len, size, sectors_to_read, retsize);
info->current_sample += retsize / SAMPLESIZE;
- _info->readpos = (float)info->current_sample / _info->samplerate;
+ _info->readpos = (float)info->current_sample / _info->fmt.samplerate;
return retsize;
}
@@ -211,14 +210,14 @@ cda_seek_sample (DB_fileinfo_t *_info, int sample)
memcpy (info->tail, buf + offset, SECTORSIZE - offset);
info->current_sector = sector;
info->current_sample = sample;
- _info->readpos = (float)info->current_sample / _info->samplerate;
+ _info->readpos = (float)info->current_sample / _info->fmt.samplerate;
return 0;
}
static int
cda_seek (DB_fileinfo_t *_info, float sec)
{
- return cda_seek_sample (_info, sec * _info->samplerate);
+ return cda_seek_sample (_info, sec * _info->fmt.samplerate);
}
cddb_disc_t*
@@ -244,7 +243,8 @@ resolve_disc (CdIo_t *cdio)
conn = cddb_new();
- cddb_set_server_name (conn, deadbeef->conf_get_str ("cdda.freedb.host", DEFAULT_SERVER));
+ deadbeef->conf_lock ();
+ cddb_set_server_name (conn, deadbeef->conf_get_str_fast ("cdda.freedb.host", DEFAULT_SERVER));
cddb_set_server_port (conn, deadbeef->conf_get_int ("cdda.freedb.port", DEFAULT_PORT));
if (!deadbeef->conf_get_int ("cdda.protocol", DEFAULT_PROTOCOL))
@@ -253,9 +253,10 @@ resolve_disc (CdIo_t *cdio)
if (deadbeef->conf_get_int ("network.proxy", 0))
{
cddb_set_server_port(conn, deadbeef->conf_get_int ("network.proxy.port", 8080));
- cddb_set_server_name(conn, deadbeef->conf_get_str ("network.proxy.address", ""));
+ cddb_set_server_name(conn, deadbeef->conf_get_str_fast ("network.proxy.address", ""));
}
}
+ deadbeef->conf_unlock ();
int matches = cddb_query (conn, disc);
if (matches == -1)
@@ -286,10 +287,8 @@ insert_single_track (CdIo_t* cdio, DB_playItem_t *after, const char* file, int t
int sector_count = cdio_get_track_sec_count (cdio, track_nr);
- DB_playItem_t *it = deadbeef->pl_item_alloc ();
- it->decoder_id = deadbeef->plug_get_decoder_id (plugin.plugin.id);
- it->fname = strdup (tmp);
- it->filetype = "cdda";
+ DB_playItem_t *it = deadbeef->pl_item_alloc_init (tmp, plugin.plugin.id);
+ deadbeef->pl_add_meta (it, ":FILETYPE", "cdda");
deadbeef->pl_set_item_duration (it, (float)sector_count / 75.0);
snprintf (tmp, sizeof (tmp), "CD Track %02d", track_nr);
@@ -320,9 +319,7 @@ cddb_thread (void *items_i)
DB_playItem_t **items = params->items;
trace ("calling resolve_disc\n");
- deadbeef->mutex_lock (mutex);
cddb_disc_t* disc = resolve_disc (params->cdio);
- deadbeef->mutex_unlock (mutex);
if (!disc)
{
trace ("disc not resolved\n");
@@ -334,7 +331,6 @@ cddb_thread (void *items_i)
}
trace ("disc resolved\n");
- deadbeef->mutex_lock (mutex);
const char *disc_title = cddb_disc_get_title (disc);
const char *artist = cddb_disc_get_artist (disc);
trace ("disc_title=%s, disk_artist=%s\n", disc_title, artist);
@@ -359,9 +355,7 @@ cddb_thread (void *items_i)
deadbeef->plug_trigger_event_trackinfochanged (items[i]);
}
cddb_disc_destroy (disc);
- deadbeef->mutex_unlock (mutex);
cleanup_thread_params (params);
- cddb_tid = 0;
deadbeef->plug_trigger_event_playlistchanged ();
}
@@ -508,10 +502,8 @@ cda_insert (DB_playItem_t *after, const char *fname) {
if ((!got_cdtext || !prefer_cdtext) && enable_cddb)
{
trace ("cdda: querying freedb...\n");
- if (cddb_tid) {
- deadbeef->thread_join (cddb_tid);
- }
- cddb_tid = deadbeef->thread_start (cddb_thread, p); //will destroy cdio
+ intptr_t tid = deadbeef->thread_start (cddb_thread, p); //will destroy cdio
+ deadbeef->thread_detach (tid);
}
else
cleanup_thread_params (p);
@@ -530,27 +522,12 @@ cda_insert (DB_playItem_t *after, const char *fname) {
}
static int
-cda_start (void) {
- mutex = deadbeef->mutex_create ();
- return 0;
-}
-
-static int
-cda_stop (void) {
- if (cddb_tid) {
- trace ("cdda: waiting cddb query to end\n");
- deadbeef->thread_join (cddb_tid);
- }
- deadbeef->mutex_free (mutex);
- return 0;
-}
-
-static int
cda_action_add_cd (DB_plugin_action_t *act, DB_playItem_t *it)
{
+ deadbeef->pl_add_files_begin (deadbeef->plt_get_curr ());
deadbeef->pl_add_file ("all.cda", NULL, NULL);
- //Wtf?
- //playlist_refresh ();
+ deadbeef->pl_add_files_end ();
+ deadbeef->plug_trigger_event_playlistchanged ();
}
static DB_plugin_action_t add_cd_action = {
@@ -581,23 +558,37 @@ static const char settings_dlg[] =
// define plugin interface
static DB_decoder_t plugin = {
DB_PLUGIN_SET_API_VERSION
- .plugin.version_major = 0,
- .plugin.version_minor = 1,
+ .plugin.version_major = 1,
+ .plugin.version_minor = 0,
.plugin.type = DB_PLUGIN_DECODER,
.plugin.id = "cda",
.plugin.name = "Audio CD player",
- .plugin.descr = "Audio CD plugins using libcdio and libcddb",
- .plugin.author = "Viktor Semykin, Alexey Yakovenko",
- .plugin.email = "thesame.ml@gmail.com, waker@users.sourceforge.net",
+ .plugin.descr = "Audio CD plugin using libcdio and libcddb",
+ .plugin.copyright =
+ "Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>\n"
+ "Copyright (C) 2009-2011 Viktor Semykin <thesame.ml@gmail.com>\n"
+ "\n"
+ "This program is free software; you can redistribute it and/or\n"
+ "modify it under the terms of the GNU General Public License\n"
+ "as published by the Free Software Foundation; either version 2\n"
+ "of the License, or (at your option) any later version.\n"
+ "\n"
+ "This program is distributed in the hope that it will be useful,\n"
+ "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+ "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+ "GNU General Public License for more details.\n"
+ "\n"
+ "You should have received a copy of the GNU General Public License\n"
+ "along with this program; if not, write to the Free Software\n"
+ "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n"
+ ,
.plugin.website = "http://deadbeef.sf.net",
- .plugin.start = cda_start,
- .plugin.stop = cda_stop,
.plugin.configdialog = settings_dlg,
.plugin.get_actions = cda_get_actions,
.open = cda_open,
.init = cda_init,
.free = cda_free,
- .read_int16 = cda_read_int16,
+ .read = cda_read,
.seek = cda_seek,
.seek_sample = cda_seek_sample,
.insert = cda_insert,
diff --git a/plugins/converter/Makefile b/plugins/converter/Makefile
new file mode 100644
index 00000000..7cd742a0
--- /dev/null
+++ b/plugins/converter/Makefile
@@ -0,0 +1,32 @@
+CONVERTER_OUT=converter.so
+GUI_OUT=converter_gtkui.so
+
+CC=gcc
+
+CFLAGS+=-Wall -D_GNU_SOURCE -std=c99 -fPIC -g -I../..
+
+LDFLAGS+=-module -shared
+
+CONVERTER_SOURCES=converter.c
+GUI_SOURCES=convgui.c interface.c support.c
+
+CONVERTER_OBJECTS=$(CONVERTER_SOURCES:.c=.o)
+GUI_OBJECTS=$(GUI_SOURCES:.c=.o)
+
+all: $(CONVERTER_SOURCES) $(CONVERTER_OUT) $(GUI_SOURCES) $(GUI_OUT)
+
+$(CONVERTER_OUT): $(CONVERTER_OBJECTS)
+ $(CC) $(LDFLAGS) $(CONVERTER_OBJECTS) -o $@
+
+GTK_CFLAGS=`pkg-config --cflags gtk+-2.0`
+GTK_LIBS=`pkg-config --libs gtk+-2.0`
+
+$(GUI_OUT): $(GUI_OBJECTS)
+ $(CC) $(LDFLAGS) $(GUI_OBJECTS) $(GTK_LIBS) -o $@
+
+.c.o:
+ $(CC) $(CFLAGS) $(GTK_CFLAGS) $< -c -o $@
+
+clean:
+ rm $(CONVERTER_OBJECTS) $(CONVERTER_OUT) $(GUI_OBJECTS) $(GUI_OUT)
+
diff --git a/plugins/converter/callbacks.c b/plugins/converter/callbacks.c
new file mode 100644
index 00000000..b8fb56d3
--- /dev/null
+++ b/plugins/converter/callbacks.c
@@ -0,0 +1,11 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gtk/gtk.h>
+
+#include "callbacks.h"
+#include "interface.h"
+#include "support.h"
+
+
diff --git a/plugins/converter/callbacks.h b/plugins/converter/callbacks.h
new file mode 100644
index 00000000..7e323527
--- /dev/null
+++ b/plugins/converter/callbacks.h
@@ -0,0 +1,124 @@
+#include <gtk/gtk.h>
+
+void
+on_converter_encoder_changed (GtkComboBox *combobox,
+ gpointer user_data);
+
+void
+on_presets_cursor_changed (GtkTreeView *treeview,
+ gpointer user_data);
+
+void
+on_dsp_preset_add_plugin_clicked (GtkButton *button,
+ gpointer user_data);
+
+void
+on_dsp_preset_remove_plugin_clicked (GtkButton *button,
+ gpointer user_data);
+
+void
+on_converter_dsp_preset_changed (GtkComboBox *combobox,
+ gpointer user_data);
+
+void
+on_dsp_preset_plugin_configure_clicked (GtkButton *button,
+ gpointer user_data);
+
+void
+on_dsp_preset_plugin_up_clicked (GtkButton *button,
+ gpointer user_data);
+
+void
+on_dsp_preset_plugin_down_clicked (GtkButton *button,
+ gpointer user_data);
+
+void
+on_converter_output_format_changed (GtkComboBox *combobox,
+ gpointer user_data);
+
+GtkWidget*
+encoder_cmdline_help_link_create (gchar *widget_name, gchar *string1, gchar *string2,
+ gint int1, gint int2);
+
+
+void
+on_edit_encoder_presets_clicked (GtkButton *button,
+ gpointer user_data);
+
+void
+on_edit_dsp_presets_clicked (GtkButton *button,
+ gpointer user_data);
+
+void
+on_converter_output_browse_clicked (GtkButton *button,
+ gpointer user_data);
+
+void
+on_converter_cancel_clicked (GtkButton *button,
+ gpointer user_data);
+
+void
+on_converter_ok_clicked (GtkButton *button,
+ gpointer user_data);
+
+void
+on_converterdlg_close (GtkDialog *dialog,
+ gpointer user_data);
+
+void
+on_converterdlg_response (GtkDialog *dialog,
+ gint response_id,
+ gpointer user_data);
+
+gboolean
+on_converterdlg_delete_event (GtkWidget *widget,
+ GdkEvent *event,
+ gpointer user_data);
+
+GtkWidget*
+title_formatting_help_link_create (gchar *widget_name, gchar *string1, gchar *string2,
+ gint int1, gint int2);
+
+void
+on_output_folder_changed (GtkEditable *editable,
+ gpointer user_data);
+
+void
+on_numthreads_changed (GtkEditable *editable,
+ gpointer user_data);
+
+void
+on_overwrite_action_changed (GtkComboBox *combobox,
+ gpointer user_data);
+
+void
+on_encoder_changed (GtkEditable *editable,
+ gpointer user_data);
+
+void
+on_preserve_folder_browse_clicked (GtkButton *button,
+ gpointer user_data);
+
+void
+on_fname_changed (GtkEditable *editable,
+ gpointer user_data);
+
+void
+on_checkbutton1_toggled (GtkToggleButton *togglebutton,
+ gpointer user_data);
+
+void
+on_preserve_folders_toggled (GtkToggleButton *togglebutton,
+ gpointer user_data);
+
+void
+on_output_file_changed (GtkEditable *editable,
+ gpointer user_data);
+
+void
+on_preserve_folder_root_changed (GtkEditable *editable,
+ gpointer user_data);
+
+void
+on_preserve_root_folder_changed (GtkEditable *editable,
+ gpointer user_data);
diff --git a/plugins/converter/converter.c b/plugins/converter/converter.c
new file mode 100644
index 00000000..99d3b04b
--- /dev/null
+++ b/plugins/converter/converter.c
@@ -0,0 +1,906 @@
+/*
+ DeaDBeeF - ultimate music player for GNU/Linux systems with X11
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <unistd.h>
+#include "converter.h"
+#include <deadbeef.h>
+
+#define trace(...) { fprintf(stderr, __VA_ARGS__); }
+//#define trace(fmt,...)
+
+static ddb_converter_t plugin;
+static DB_functions_t *deadbeef;
+
+static ddb_encoder_preset_t *encoder_presets;
+static ddb_dsp_preset_t *dsp_presets;
+
+ddb_encoder_preset_t *
+encoder_preset_alloc (void) {
+ ddb_encoder_preset_t *p = malloc (sizeof (ddb_encoder_preset_t));
+ if (!p) {
+ fprintf (stderr, "failed to alloc ddb_encoder_preset_t\n");
+ return NULL;
+ }
+ memset (p, 0, sizeof (ddb_encoder_preset_t));
+ return p;
+}
+
+void
+encoder_preset_free (ddb_encoder_preset_t *p) {
+ if (p) {
+ if (p->title) {
+ free (p->title);
+ }
+ if (p->ext) {
+ free (p->ext);
+ }
+ if (p->encoder) {
+ free (p->encoder);
+ }
+ free (p);
+ }
+}
+
+ddb_encoder_preset_t *
+encoder_preset_load (const char *fname) {
+ int err = 1;
+ FILE *fp = fopen (fname, "rt");
+ if (!fp) {
+ return NULL;
+ }
+ ddb_encoder_preset_t *p = encoder_preset_alloc ();
+
+ char str[1024];
+ while (fgets (str, sizeof (str), fp)) {
+ // chomp
+ char *cr = str + strlen (str) - 1;
+ while (*cr == '\n') {
+ cr--;
+ }
+ cr++;
+ *cr = 0;
+
+ char *sp = strchr (str, ' ');
+ if (!sp) {
+ continue;
+ }
+
+ *sp = 0;
+ char *item = sp + 1;
+
+ if (!strcmp (str, "title")) {
+ p->title = strdup (item);
+ }
+ else if (!strcmp (str, "ext")) {
+ p->ext = strdup (item);
+ }
+ else if (!strcmp (str, "encoder")) {
+ p->encoder = strdup (item);
+ }
+ else if (!strcmp (str, "method")) {
+ p->method = atoi (item);
+ }
+ else if (!strcmp (str, "id3v2_version")) {
+ p->id3v2_version = atoi (item);
+ }
+ else if (!strcmp (str, "tag_id3v2")) {
+ p->tag_id3v2 = atoi (item);
+ }
+ else if (!strcmp (str, "tag_id3v1")) {
+ p->tag_id3v1 = atoi (item);
+ }
+ else if (!strcmp (str, "tag_apev2")) {
+ p->tag_apev2 = atoi (item);
+ }
+ else if (!strcmp (str, "tag_flac")) {
+ p->tag_flac = atoi (item);
+ }
+ else if (!strcmp (str, "tag_oggvorbis")) {
+ p->tag_oggvorbis = atoi (item);
+ }
+ }
+
+ if (!p->title) {
+ p->title = strdup ("Untitled");
+ }
+ if (!p->ext) {
+ p->ext = strdup ("");
+ }
+ if (!p->encoder) {
+ p->encoder = strdup ("");
+ }
+
+ err = 0;
+
+ if (err) {
+ encoder_preset_free (p);
+ p = NULL;
+ }
+ if (fp) {
+ fclose (fp);
+ }
+ return p;
+}
+
+// @return -1 on path/write error, -2 if file already exists
+int
+encoder_preset_save (ddb_encoder_preset_t *p, int overwrite) {
+ const char *confdir = deadbeef->get_config_dir ();
+ char path[1024];
+ if (snprintf (path, sizeof (path), "%s/presets", confdir) < 0) {
+ return -1;
+ }
+ mkdir (path, 0755);
+ if (snprintf (path, sizeof (path), "%s/presets/encoders", confdir) < 0) {
+ return -1;
+ }
+ mkdir (path, 0755);
+ if (snprintf (path, sizeof (path), "%s/presets/encoders/%s.txt", confdir, p->title) < 0) {
+ return -1;
+ }
+
+ if (!overwrite) {
+ FILE *fp = fopen (path, "rb");
+ if (fp) {
+ fclose (fp);
+ return -2;
+ }
+ }
+
+ FILE *fp = fopen (path, "w+b");
+ if (!fp) {
+ return -1;
+ }
+
+ fprintf (fp, "title %s\n", p->title);
+ fprintf (fp, "ext %s\n", p->ext);
+ fprintf (fp, "encoder %s\n", p->encoder);
+ fprintf (fp, "method %d\n", p->method);
+ fprintf (fp, "id3v2_version %d\n", p->id3v2_version);
+ fprintf (fp, "tag_id3v2 %d\n", p->tag_id3v2);
+ fprintf (fp, "tag_id3v1 %d\n", p->tag_id3v1);
+ fprintf (fp, "tag_apev2 %d\n", p->tag_apev2);
+ fprintf (fp, "tag_flac %d\n", p->tag_flac);
+ fprintf (fp, "tag_oggvorbis %d\n", p->tag_oggvorbis);
+
+ fclose (fp);
+ return 0;
+}
+
+void
+encoder_preset_copy (ddb_encoder_preset_t *to, ddb_encoder_preset_t *from) {
+ to->title = strdup (from->title);
+ to->ext = strdup (from->ext);
+ to->encoder = strdup (from->encoder);
+ to->method = from->method;
+ to->tag_id3v2 = from->tag_id3v2;
+ to->tag_id3v1 = from->tag_id3v1;
+ to->tag_apev2 = from->tag_apev2;
+ to->tag_flac = from->tag_flac;
+ to->tag_oggvorbis = from->tag_oggvorbis;
+ to->tag_mp3xing = from->tag_mp3xing;
+ to->id3v2_version = from->id3v2_version;
+}
+
+ddb_encoder_preset_t *
+encoder_preset_get_list (void) {
+ return encoder_presets;
+}
+
+ddb_encoder_preset_t *
+encoder_preset_get_for_idx (int idx) {
+ ddb_encoder_preset_t *p = encoder_presets;
+ while (p && idx--) {
+ p = p->next;
+ }
+ return p;
+}
+
+void
+encoder_preset_append (ddb_encoder_preset_t *p) {
+ // append
+ ddb_encoder_preset_t *tail = encoder_presets;
+ while (tail && tail->next) {
+ tail = tail->next;
+ }
+ if (tail) {
+ tail->next = p;
+ }
+ else {
+ encoder_presets = p;
+ }
+}
+
+void
+encoder_preset_remove (ddb_encoder_preset_t *p) {
+ ddb_encoder_preset_t *prev = encoder_presets;
+ while (prev && prev->next != p) {
+ prev = prev->next;
+ }
+ if (prev) {
+ prev->next = p->next;
+ }
+ else {
+ encoder_presets = p->next;
+ }
+}
+
+void
+encoder_preset_replace (ddb_encoder_preset_t *from, ddb_encoder_preset_t *to) {
+ ddb_encoder_preset_t *prev = encoder_presets;
+ while (prev && prev->next != from) {
+ prev = prev->next;
+ }
+ if (prev) {
+ prev->next = to;
+ }
+ else {
+ encoder_presets = to;
+ }
+ to->next = from->next;
+}
+
+ddb_dsp_preset_t *
+dsp_preset_alloc (void) {
+ ddb_dsp_preset_t *p = malloc (sizeof (ddb_dsp_preset_t));
+ if (!p) {
+ fprintf (stderr, "failed to alloc ddb_dsp_preset_t\n");
+ return NULL;
+ }
+ memset (p, 0, sizeof (ddb_dsp_preset_t));
+ return p;
+}
+
+void
+dsp_preset_free (ddb_dsp_preset_t *p) {
+ if (p) {
+ if (p->title) {
+ free (p->title);
+ }
+ deadbeef->dsp_preset_free (p->chain);
+ free (p);
+ }
+}
+
+void
+dsp_preset_copy (ddb_dsp_preset_t *to, ddb_dsp_preset_t *from) {
+ to->title = strdup (from->title);
+ ddb_dsp_context_t *tail = NULL;
+ ddb_dsp_context_t *dsp = from->chain;
+ while (dsp) {
+ ddb_dsp_context_t *i = dsp->plugin->open ();
+ if (dsp->plugin->num_params) {
+ int n = dsp->plugin->num_params ();
+ for (int j = 0; j < n; j++) {
+ char s[1000] = "";
+ dsp->plugin->get_param (dsp, j, s, sizeof (s));
+ i->plugin->set_param (i, j, s);
+ }
+ }
+ if (tail) {
+ tail->next = i;
+ tail = i;
+ }
+ else {
+ to->chain = tail = i;
+ }
+ dsp = dsp->next;
+ }
+}
+
+ddb_dsp_preset_t *
+dsp_preset_get_list (void) {
+ return dsp_presets;
+}
+
+ddb_dsp_preset_t *
+dsp_preset_load (const char *fname) {
+ ddb_dsp_preset_t *p = dsp_preset_alloc ();
+ if (!p) {
+ return NULL;
+ }
+ memset (p, 0, sizeof (ddb_dsp_preset_t));
+ const char *end = strrchr (fname, '.');
+ if (!end) {
+ end = fname + strlen (fname);
+ }
+ const char *start = strrchr (fname, '/');
+ if (!start) {
+ start = fname;
+ }
+ else {
+ start++;
+ }
+
+ p->title = malloc (end-start+1);
+ memcpy (p->title, start, end-start);
+ p->title[end-start] = 0;
+ int err = deadbeef->dsp_preset_load (fname, &p->chain);
+ if (err != 0) {
+ dsp_preset_free (p);
+ return NULL;
+ }
+ return p;
+}
+
+int
+dsp_preset_save (ddb_dsp_preset_t *p, int overwrite) {
+ const char *confdir = deadbeef->get_config_dir ();
+ char path[1024];
+ if (snprintf (path, sizeof (path), "%s/presets", confdir) < 0) {
+ return -1;
+ }
+ mkdir (path, 0755);
+ if (snprintf (path, sizeof (path), "%s/presets/dsp", confdir) < 0) {
+ return -1;
+ }
+ mkdir (path, 0755);
+ if (snprintf (path, sizeof (path), "%s/presets/dsp/%s.txt", confdir, p->title) < 0) {
+ return -1;
+ }
+
+ if (!overwrite) {
+ FILE *fp = fopen (path, "rb");
+ if (fp) {
+ fclose (fp);
+ return -2;
+ }
+ }
+
+ return deadbeef->dsp_preset_save (path, p->chain);
+}
+
+static int dirent_alphasort (const struct dirent **a, const struct dirent **b) {
+ return strcmp ((*a)->d_name, (*b)->d_name);
+}
+
+int
+scandir_preset_filter (const struct dirent *ent) {
+ char *ext = strrchr (ent->d_name, '.');
+ if (ext && !strcasecmp (ext, ".txt")) {
+ return 1;
+ }
+ return 0;
+}
+
+int
+load_encoder_presets (void) {
+ ddb_encoder_preset_t *tail = NULL;
+ char path[1024];
+ if (snprintf (path, sizeof (path), "%s/presets/encoders", deadbeef->get_config_dir ()) < 0) {
+ return -1;
+ }
+ struct dirent **namelist = NULL;
+ int n = scandir (path, &namelist, scandir_preset_filter, dirent_alphasort);
+ int i;
+ for (i = 0; i < n; i++) {
+ char s[1024];
+ if (snprintf (s, sizeof (s), "%s/%s", path, namelist[i]->d_name) > 0){
+ ddb_encoder_preset_t *p = encoder_preset_load (s);
+ if (p) {
+ if (tail) {
+ tail->next = p;
+ tail = p;
+ }
+ else {
+ encoder_presets = tail = p;
+ }
+ }
+ }
+ free (namelist[i]);
+ }
+ free (namelist);
+ return 0;
+}
+
+int
+load_dsp_presets (void) {
+ ddb_dsp_preset_t *tail = NULL;
+ char path[1024];
+ if (snprintf (path, sizeof (path), "%s/presets/dsp", deadbeef->get_config_dir ()) < 0) {
+ return -1;
+ }
+ struct dirent **namelist = NULL;
+ int n = scandir (path, &namelist, scandir_preset_filter, dirent_alphasort);
+ int i;
+ for (i = 0; i < n; i++) {
+ char s[1024];
+ if (snprintf (s, sizeof (s), "%s/%s", path, namelist[i]->d_name) > 0){
+ ddb_dsp_preset_t *p = dsp_preset_load (s);
+ if (p) {
+ if (tail) {
+ tail->next = p;
+ tail = p;
+ }
+ else {
+ dsp_presets = tail = p;
+ }
+ }
+ }
+ free (namelist[i]);
+ }
+ free (namelist);
+ return 0;
+}
+
+ddb_dsp_preset_t *
+dsp_preset_get_for_idx (int idx) {
+ ddb_dsp_preset_t *p = dsp_presets;
+ while (p && idx--) {
+ p = p->next;
+ }
+ return p;
+}
+
+void
+dsp_preset_append (ddb_dsp_preset_t *p) {
+ // append
+ ddb_dsp_preset_t *tail = dsp_presets;
+ while (tail && tail->next) {
+ tail = tail->next;
+ }
+ if (tail) {
+ tail->next = p;
+ }
+ else {
+ dsp_presets = p;
+ }
+}
+
+void
+dsp_preset_remove (ddb_dsp_preset_t *p) {
+ ddb_dsp_preset_t *prev = dsp_presets;
+ while (prev && prev->next != p) {
+ prev = prev->next;
+ }
+ if (prev) {
+ prev->next = p->next;
+ }
+ else {
+ dsp_presets = p->next;
+ }
+}
+
+void
+dsp_preset_replace (ddb_dsp_preset_t *from, ddb_dsp_preset_t *to) {
+ ddb_dsp_preset_t *prev = dsp_presets;
+ while (prev && prev->next != from) {
+ prev = prev->next;
+ }
+ if (prev) {
+ prev->next = to;
+ }
+ else {
+ dsp_presets = to;
+ }
+ to->next = from->next;
+}
+
+static void
+get_output_path (DB_playItem_t *it, const char *outfolder, const char *outfile, ddb_encoder_preset_t *encoder_preset, char *out, int sz) {
+ char fname[PATH_MAX];
+ int idx = deadbeef->pl_get_idx_of (it);
+ deadbeef->pl_format_title (it, idx, fname, sizeof (fname), -1, outfile);
+ // replace invalid chars
+ char *p = fname;
+ char invalid[] = "/\\?%*:|\"<>";
+ while (*p) {
+ if (strchr (invalid, *p)) {
+ *p = '_';
+ }
+ p++;
+ }
+ snprintf (out, sz, "%s/%s.%s", outfolder, fname, encoder_preset->ext);
+
+}
+
+int
+convert (DB_playItem_t *it, const char *outfolder, const char *outfile, int output_bps, int output_is_float, int preserve_folder_structure, const char *root_folder, ddb_encoder_preset_t *encoder_preset, ddb_dsp_preset_t *dsp_preset, int *abort) {
+ int err = -1;
+ FILE *enc_pipe = NULL;
+ FILE *temp_file = NULL;
+ DB_decoder_t *dec = NULL;
+ DB_fileinfo_t *fileinfo = NULL;
+ char out[PATH_MAX] = ""; // full path to output file
+ char input_file_name[PATH_MAX] = "";
+ dec = (DB_decoder_t *)deadbeef->plug_get_for_id (deadbeef->pl_find_meta (it, ":DECODER"));
+
+ if (dec) {
+ fileinfo = dec->open (0);
+ if (fileinfo && dec->init (fileinfo, DB_PLAYITEM (it)) != 0) {
+ deadbeef->pl_lock ();
+ fprintf (stderr, "converter: failed to decode file %s\n", deadbeef->pl_find_meta (it, ":URI"));
+ deadbeef->pl_unlock ();
+ goto error;
+ }
+ if (fileinfo) {
+ if (output_bps == -1) {
+ output_bps = fileinfo->fmt.bps;
+ output_is_float = fileinfo->fmt.is_float;
+ }
+
+ get_output_path (it, outfolder, outfile, encoder_preset, out, sizeof (out));
+ if (encoder_preset->method == DDB_ENCODER_METHOD_FILE) {
+ const char *tmp = getenv ("TMPDIR");
+ if (!tmp) {
+ tmp = "/tmp";
+ }
+ snprintf (input_file_name, sizeof (input_file_name), "%s/ddbconvXXXXXX", tmp);
+ mktemp (input_file_name);
+ strcat (input_file_name, ".wav");
+ }
+ else {
+ strcpy (input_file_name, "-");
+ }
+
+ char enc[2000];
+
+ // formatting: %o = outfile, %i = infile
+ char *e = encoder_preset->encoder;
+ char *o = enc;
+ *o = 0;
+ int len = sizeof (enc);
+ while (e && *e) {
+ if (len <= 0) {
+ fprintf (stderr, "converter: failed to assemble encoder command line - buffer is not big enough, try to shorten your parameters. max allowed length is %d characters\n", sizeof (enc));
+ goto error;
+ }
+ if (e[0] == '%' && e[1]) {
+ if (e[1] == 'o') {
+ int l = snprintf (o, len, "\"%s\"", out);
+ o += l;
+ len -= l;
+ }
+ else if (e[1] == 'i') {
+ int l = snprintf (o, len, "\"%s\"", input_file_name);
+ o += l;
+ len -= l;
+ }
+ else {
+ strncpy (o, e, 2);
+ o += 2;
+ len -= 2;
+ }
+ e += 2;
+ }
+ else {
+ *o++ = *e++;
+ *o = 0;
+ len--;
+ }
+ }
+
+ fprintf (stderr, "converter: will encode using: %s\n", enc);
+
+ if (!encoder_preset->encoder[0]) {
+ // write to wave file
+ temp_file = fopen (out, "w+b");
+ if (!temp_file) {
+ fprintf (stderr, "converter: failed to open output wave file %s\n", out);
+ goto error;
+ }
+ }
+ else if (encoder_preset->method == DDB_ENCODER_METHOD_FILE) {
+ temp_file = fopen (input_file_name, "w+b");
+ if (!temp_file) {
+ fprintf (stderr, "converter: failed to open temp file %s\n", input_file_name);
+ goto error;
+ }
+ }
+ else {
+ enc_pipe = popen (enc, "w");
+ if (!enc_pipe) {
+ fprintf (stderr, "converter: failed to open encoder\n");
+ goto error;
+ }
+ }
+
+ if (!temp_file) {
+ temp_file = enc_pipe;
+ }
+
+ // write wave header
+ char wavehdr_int[] = {
+ 0x52, 0x49, 0x46, 0x46, 0x24, 0x70, 0x0d, 0x00, 0x57, 0x41, 0x56, 0x45, 0x66, 0x6d, 0x74, 0x20, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x44, 0xac, 0x00, 0x00, 0x10, 0xb1, 0x02, 0x00, 0x04, 0x00, 0x10, 0x00, 0x64, 0x61, 0x74, 0x61
+ };
+ char wavehdr_float[] = {
+ 0x52, 0x49, 0x46, 0x46, 0x2a, 0xdf, 0x02, 0x00, 0x57, 0x41, 0x56, 0x45, 0x66, 0x6d, 0x74, 0x20, 0x28, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x02, 0x00, 0x40, 0x1f, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x00, 0x08, 0x00, 0x20, 0x00, 0x16, 0x00, 0x20, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71, 0x66, 0x61, 0x63, 0x74, 0x04, 0x00, 0x00, 0x00, 0xc5, 0x5b, 0x00, 0x00, 0x64, 0x61, 0x74, 0x61
+ };
+ char *wavehdr = output_is_float ? wavehdr_float : wavehdr_int;
+ int wavehdr_size = output_is_float ? sizeof (wavehdr_float) : sizeof (wavehdr_int);
+ int header_written = 0;
+ uint32_t outsize = 0;
+ uint32_t outsr = fileinfo->fmt.samplerate;
+ uint16_t outch = fileinfo->fmt.channels;
+
+ int samplesize = fileinfo->fmt.channels * fileinfo->fmt.bps / 8;
+ int bs = 10250 * samplesize;
+ char buffer[bs * 4];
+ int dspsize = bs / samplesize * sizeof (float) * fileinfo->fmt.channels;
+ char dspbuffer[dspsize * 4];
+ int eof = 0;
+ for (;;) {
+ if (eof) {
+ break;
+ }
+ if (abort && *abort) {
+ break;
+ }
+ int sz = dec->read (fileinfo, buffer, bs);
+
+ if (sz != bs) {
+ eof = 1;
+ }
+ if (dsp_preset) {
+ ddb_waveformat_t fmt;
+ ddb_waveformat_t outfmt;
+ memcpy (&fmt, &fileinfo->fmt, sizeof (fmt));
+ memcpy (&outfmt, &fileinfo->fmt, sizeof (fmt));
+ fmt.bps = 32;
+ fmt.is_float = 1;
+ deadbeef->pcm_convert (&fileinfo->fmt, buffer, &fmt, dspbuffer, sz);
+
+ ddb_dsp_context_t *dsp = dsp_preset->chain;
+ int frames = sz / samplesize;
+ while (dsp) {
+ frames = dsp->plugin->process (dsp, (float *)dspbuffer, frames, sizeof (dspbuffer) / (fmt.channels * 4), &fmt, NULL);
+ dsp = dsp->next;
+ }
+
+ outsr = fmt.samplerate;
+ outch = fmt.channels;
+
+ outfmt.bps = output_bps;
+ outfmt.is_float = output_is_float;
+ outfmt.channels = outch;
+ outfmt.samplerate = outsr;
+
+ int n = deadbeef->pcm_convert (&fmt, dspbuffer, &outfmt, buffer, frames * sizeof (float) * fmt.channels);
+ sz = n;
+ }
+ else if (fileinfo->fmt.bps != output_bps || fileinfo->fmt.is_float != output_is_float) {
+ ddb_waveformat_t outfmt;
+ memcpy (&outfmt, &fileinfo->fmt, sizeof (outfmt));
+ outfmt.bps = output_bps;
+ outfmt.is_float = output_is_float;
+ outfmt.channels = outch;
+ outfmt.samplerate = outsr;
+
+ int frames = sz / samplesize;
+ int n = deadbeef->pcm_convert (&fileinfo->fmt, buffer, &outfmt, dspbuffer, frames * samplesize);
+ memcpy (buffer, dspbuffer, n);
+ sz = n;
+ }
+ outsize += sz;
+
+ if (!header_written) {
+ uint32_t size = (it->endsample-it->startsample) * outch * output_bps / 8;
+ if (!size) {
+ size = deadbeef->pl_get_item_duration (it) * fileinfo->fmt.samplerate * outch * output_bps / 8;
+
+ }
+
+ if (outsr != fileinfo->fmt.samplerate) {
+ uint64_t temp = size;
+ temp *= outsr;
+ temp /= fileinfo->fmt.samplerate;
+ size = temp;
+ }
+
+ memcpy (&wavehdr[22], &outch, 2);
+ memcpy (&wavehdr[24], &outsr, 4);
+ uint16_t blockalign = outch * output_bps / 8;
+ memcpy (&wavehdr[32], &blockalign, 2);
+ memcpy (&wavehdr[34], &output_bps, 2);
+
+ fwrite (wavehdr, 1, wavehdr_size, temp_file);
+ fwrite (&size, 1, sizeof (size), temp_file);
+ header_written = 1;
+ }
+
+ if (sz != fwrite (buffer, 1, sz, temp_file)) {
+ fprintf (stderr, "converter: write error\n");
+ goto error;
+ }
+ }
+ if (abort && *abort) {
+ goto error;
+ }
+ if (temp_file && temp_file != enc_pipe) {
+ fseek (temp_file, wavehdr_size, SEEK_SET);
+ fwrite (&outsize, 1, 4, temp_file);
+
+ fclose (temp_file);
+ temp_file = NULL;
+ }
+
+ if (encoder_preset->encoder[0] && encoder_preset->method == DDB_ENCODER_METHOD_FILE) {
+ enc_pipe = popen (enc, "w");
+ }
+ }
+ }
+ err = 0;
+error:
+ if (temp_file && temp_file != enc_pipe) {
+ fclose (temp_file);
+ temp_file = NULL;
+ }
+ if (enc_pipe) {
+ pclose (enc_pipe);
+ enc_pipe = NULL;
+ }
+ if (dec && fileinfo) {
+ dec->free (fileinfo);
+ fileinfo = NULL;
+ }
+ if (abort && *abort && out[0]) {
+ unlink (out);
+ }
+ if (input_file_name[0] && strcmp (input_file_name, "-")) {
+ unlink (input_file_name);
+ }
+
+ // write junklib tags
+ uint32_t tagflags = JUNK_STRIP_ID3V2 | JUNK_STRIP_APEV2 | JUNK_STRIP_ID3V1;
+ if (encoder_preset->tag_id3v2) {
+ tagflags |= JUNK_WRITE_ID3V2;
+ }
+ if (encoder_preset->tag_id3v1) {
+ tagflags |= JUNK_WRITE_ID3V1;
+ }
+ if (encoder_preset->tag_apev2) {
+ tagflags |= JUNK_WRITE_APEV2;
+ }
+ DB_playItem_t *out_it = deadbeef->pl_item_alloc ();
+ deadbeef->pl_item_copy (out_it, it);
+ deadbeef->pl_replace_meta (out_it, ":URI", out);
+ deadbeef->pl_delete_meta (out_it, "cuesheet");
+
+ deadbeef->junk_rewrite_tags (out_it, tagflags, encoder_preset->id3v2_version + 3, "iso8859-1");
+
+ // write flac tags
+ if (encoder_preset->tag_flac) {
+ // find flac decoder plugin
+ DB_decoder_t **plugs = deadbeef->plug_get_decoder_list ();
+ DB_decoder_t *flac = NULL;
+ for (int i = 0; plugs[i]; i++) {
+ if (!strcmp (plugs[i]->plugin.id, "stdflac")) {
+ flac = plugs[i];
+ break;
+ }
+ }
+ if (!flac) {
+ fprintf (stderr, "converter: flac plugin not found, cannot write flac metadata\n");
+ }
+ else {
+ if (0 != flac->write_metadata (out_it)) {
+ fprintf (stderr, "converter: failed to write flac metadata, not a flac file?\n");
+ }
+ }
+ }
+
+ // write vorbis tags
+ if (encoder_preset->tag_oggvorbis) {
+ // find flac decoder plugin
+ DB_decoder_t **plugs = deadbeef->plug_get_decoder_list ();
+ DB_decoder_t *ogg = NULL;
+ for (int i = 0; plugs[i]; i++) {
+ if (!strcmp (plugs[i]->plugin.id, "stdogg")) {
+ ogg = plugs[i];
+ break;
+ }
+ }
+ if (!ogg) {
+ fprintf (stderr, "converter: ogg plugin not found, cannot write ogg metadata\n");
+ }
+ else {
+ if (0 != ogg->write_metadata (out_it)) {
+ fprintf (stderr, "converter: failed to write ogg metadata, not an ogg file?\n");
+ }
+ }
+ }
+
+ deadbeef->pl_item_unref (out_it);
+
+
+ return err;
+}
+
+int
+converter_cmd (int cmd, ...) {
+ return -1;
+}
+
+int
+converter_start (void) {
+ load_encoder_presets ();
+ load_dsp_presets ();
+
+ return 0;
+}
+
+int
+converter_stop (void) {
+ return 0;
+}
+
+// define plugin interface
+static ddb_converter_t plugin = {
+ .misc.plugin.api_vmajor = DB_API_VERSION_MAJOR,
+ .misc.plugin.api_vminor = DB_API_VERSION_MINOR,
+ .misc.plugin.version_major = 1,
+ .misc.plugin.version_minor = 0,
+ .misc.plugin.type = DB_PLUGIN_MISC,
+ .misc.plugin.name = "Converter",
+ .misc.plugin.id = "converter",
+ .misc.plugin.descr = "Converts any supported formats to other formats.\n"
+ "Requires separate GUI plugin, e.g. Converter GTK UI\n",
+ .misc.plugin.copyright =
+ "Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>\n"
+ "\n"
+ "This program is free software; you can redistribute it and/or\n"
+ "modify it under the terms of the GNU General Public License\n"
+ "as published by the Free Software Foundation; either version 2\n"
+ "of the License, or (at your option) any later version.\n"
+ "\n"
+ "This program is distributed in the hope that it will be useful,\n"
+ "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+ "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+ "GNU General Public License for more details.\n"
+ "\n"
+ "You should have received a copy of the GNU General Public License\n"
+ "along with this program; if not, write to the Free Software\n"
+ "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n"
+ ,
+ .misc.plugin.website = "http://deadbeef.sf.net",
+ .misc.plugin.start = converter_start,
+ .misc.plugin.stop = converter_stop,
+ .misc.plugin.command = converter_cmd,
+ .encoder_preset_alloc = encoder_preset_alloc,
+ .encoder_preset_free = encoder_preset_free,
+ .encoder_preset_load = encoder_preset_load,
+ .encoder_preset_save = encoder_preset_save,
+ .encoder_preset_copy = encoder_preset_copy,
+ .encoder_preset_get_list = encoder_preset_get_list,
+ .encoder_preset_get_for_idx = encoder_preset_get_for_idx,
+ .encoder_preset_append = encoder_preset_append,
+ .encoder_preset_remove = encoder_preset_remove,
+ .encoder_preset_replace = encoder_preset_replace,
+ .dsp_preset_alloc = dsp_preset_alloc,
+ .dsp_preset_free = dsp_preset_free,
+ .dsp_preset_load = dsp_preset_load,
+ .dsp_preset_save = dsp_preset_save,
+ .dsp_preset_copy = dsp_preset_copy,
+ .dsp_preset_get_list = dsp_preset_get_list,
+ .dsp_preset_get_for_idx = dsp_preset_get_for_idx,
+ .dsp_preset_append = dsp_preset_append,
+ .dsp_preset_remove = dsp_preset_remove,
+ .dsp_preset_replace = dsp_preset_replace,
+ .get_output_path = get_output_path,
+ .convert = convert,
+};
+
+DB_plugin_t *
+converter_load (DB_functions_t *api) {
+ deadbeef = api;
+ return DB_PLUGIN (&plugin);
+}
diff --git a/plugins/converter/converter.glade b/plugins/converter/converter.glade
new file mode 100644
index 00000000..fce698c5
--- /dev/null
+++ b/plugins/converter/converter.glade
@@ -0,0 +1,1839 @@
+<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
+<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
+
+<glade-interface>
+
+<widget class="GtkDialog" id="converterdlg">
+ <property name="visible">True</property>
+ <property name="title" translatable="yes">Converter</property>
+ <property name="type">GTK_WINDOW_TOPLEVEL</property>
+ <property name="window_position">GTK_WIN_POS_NONE</property>
+ <property name="modal">True</property>
+ <property name="resizable">True</property>
+ <property name="destroy_with_parent">True</property>
+ <property name="decorated">True</property>
+ <property name="skip_taskbar_hint">False</property>
+ <property name="skip_pager_hint">False</property>
+ <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+ <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+ <property name="focus_on_map">True</property>
+ <property name="urgency_hint">False</property>
+ <property name="has_separator">False</property>
+
+ <child internal-child="vbox">
+ <widget class="GtkVBox" id="dialog-vbox6">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child internal-child="action_area">
+ <widget class="GtkHButtonBox" id="dialog-action_area5">
+ <property name="visible">True</property>
+ <property name="layout_style">GTK_BUTTONBOX_END</property>
+
+ <child>
+ <widget class="GtkButton" id="converter_cancel">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-cancel</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="response_id">-6</property>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="converter_ok">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-ok</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="response_id">-5</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">GTK_PACK_END</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkVBox" id="vbox26">
+ <property name="border_width">12</property>
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">8</property>
+
+ <child>
+ <widget class="GtkHBox" id="hbox67">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">8</property>
+
+ <child>
+ <widget class="GtkLabel" id="label103">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Output folder:</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHBox" id="hbox68">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkEntry" id="output_folder">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="editable">True</property>
+ <property name="visibility">True</property>
+ <property name="max_length">0</property>
+ <property name="text" translatable="yes"></property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char">●</property>
+ <property name="activates_default">False</property>
+ <signal name="changed" handler="on_output_folder_changed" last_modification_time="Sun, 13 Mar 2011 11:25:59 GMT"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="converter_output_browse">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">...</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <signal name="clicked" handler="on_converter_output_browse_clicked" last_modification_time="Thu, 02 Dec 2010 19:59:50 GMT"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHBox" id="hbox100">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">8</property>
+
+ <child>
+ <widget class="GtkLabel" id="label122">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Output file name:</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHBox" id="hbox101">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkEntry" id="output_file">
+ <property name="visible">True</property>
+ <property name="tooltip" translatable="yes">Extension (e.g. .mp3) will be appended automatically.
+Leave the field empty for default (%a - %t).</property>
+ <property name="can_focus">True</property>
+ <property name="editable">True</property>
+ <property name="visibility">True</property>
+ <property name="max_length">0</property>
+ <property name="text" translatable="yes"></property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char">•</property>
+ <property name="activates_default">False</property>
+ <signal name="changed" handler="on_output_file_changed" last_modification_time="Sun, 13 Mar 2011 20:02:34 GMT"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="Custom" id="custom6">
+ <property name="visible">True</property>
+ <property name="creation_function">title_formatting_help_link_create</property>
+ <property name="int1">0</property>
+ <property name="int2">0</property>
+ <property name="last_modification_time">Fri, 03 Dec 2010 20:39:24 GMT</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHBox" id="hbox69">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">8</property>
+
+ <child>
+ <widget class="GtkLabel" id="label104">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Encoder:</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHBox" id="hbox90">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkComboBox" id="encoder">
+ <property name="visible">True</property>
+ <property name="add_tearoffs">False</property>
+ <property name="focus_on_click">True</property>
+ <signal name="changed" handler="on_converter_encoder_changed" last_modification_time="Mon, 06 Dec 2010 20:55:31 GMT"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="edit_encoder_presets">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <signal name="clicked" handler="on_edit_encoder_presets_clicked" last_modification_time="Sat, 04 Dec 2010 15:20:49 GMT"/>
+
+ <child>
+ <widget class="GtkImage" id="image469">
+ <property name="visible">True</property>
+ <property name="stock">gtk-edit</property>
+ <property name="icon_size">4</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHBox" id="hbox86">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">8</property>
+
+ <child>
+ <widget class="GtkLabel" id="label114">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">DSP preset:</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHBox" id="hbox91">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkComboBox" id="dsp_preset">
+ <property name="visible">True</property>
+ <property name="items" translatable="yes"></property>
+ <property name="add_tearoffs">False</property>
+ <property name="focus_on_click">True</property>
+ <signal name="changed" handler="on_converter_dsp_preset_changed" last_modification_time="Wed, 08 Dec 2010 21:22:19 GMT"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="edit_dsp_presets">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <signal name="clicked" handler="on_edit_dsp_presets_clicked" last_modification_time="Sat, 04 Dec 2010 15:20:53 GMT"/>
+
+ <child>
+ <widget class="GtkImage" id="image470">
+ <property name="visible">True</property>
+ <property name="stock">gtk-edit</property>
+ <property name="icon_size">4</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHBox" id="hbox88">
+ <property name="homogeneous">False</property>
+ <property name="spacing">8</property>
+
+ <child>
+ <widget class="GtkLabel" id="label116">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Number of threads:</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkSpinButton" id="numthreads">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="climb_rate">1</property>
+ <property name="digits">0</property>
+ <property name="numeric">False</property>
+ <property name="update_policy">GTK_UPDATE_ALWAYS</property>
+ <property name="snap_to_ticks">False</property>
+ <property name="wrap">False</property>
+ <property name="adjustment">1 0 100 1 10 0</property>
+ <signal name="changed" handler="on_numthreads_changed" last_modification_time="Sun, 13 Mar 2011 11:26:21 GMT"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHBox" id="hbox89">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">8</property>
+
+ <child>
+ <widget class="GtkLabel" id="label117">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Output sample format:</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkComboBox" id="output_format">
+ <property name="visible">True</property>
+ <property name="items" translatable="yes">Keep source format
+8 bit signed int
+16 bit signed int
+24 bit signed int
+32 bit signed int
+32 bit float</property>
+ <property name="add_tearoffs">False</property>
+ <property name="focus_on_click">True</property>
+ <signal name="changed" handler="on_converter_output_format_changed" last_modification_time="Sun, 12 Dec 2010 16:55:42 GMT"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHBox" id="hbox99">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">8</property>
+
+ <child>
+ <widget class="GtkLabel" id="label121">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">When file exists:</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkComboBox" id="overwrite_action">
+ <property name="visible">True</property>
+ <property name="items" translatable="yes">Prompt
+Overwrite</property>
+ <property name="add_tearoffs">False</property>
+ <property name="focus_on_click">True</property>
+ <signal name="changed" handler="on_overwrite_action_changed" last_modification_time="Sun, 13 Mar 2011 11:26:30 GMT"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkCheckButton" id="preserve_folders">
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">Preserve folder structure, starting from:</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="active">False</property>
+ <property name="inconsistent">False</property>
+ <property name="draw_indicator">True</property>
+ <signal name="toggled" handler="on_preserve_folders_toggled" last_modification_time="Sun, 13 Mar 2011 12:34:49 GMT"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHBox" id="hbox102">
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkEntry" id="preserve_root_folder">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="editable">True</property>
+ <property name="visibility">True</property>
+ <property name="max_length">0</property>
+ <property name="text" translatable="yes"></property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char">•</property>
+ <property name="activates_default">False</property>
+ <signal name="changed" handler="on_preserve_root_folder_changed" last_modification_time="Mon, 14 Mar 2011 21:00:54 GMT"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="preserve_folder_browse">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">...</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <signal name="clicked" handler="on_preserve_folder_browse_clicked" last_modification_time="Sun, 13 Mar 2011 12:29:48 GMT"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+</widget>
+
+<widget class="GtkDialog" id="convpreset_editor">
+ <property name="visible">True</property>
+ <property name="title" translatable="yes">Edit Encoder Preset</property>
+ <property name="type">GTK_WINDOW_TOPLEVEL</property>
+ <property name="window_position">GTK_WIN_POS_NONE</property>
+ <property name="modal">True</property>
+ <property name="resizable">True</property>
+ <property name="destroy_with_parent">False</property>
+ <property name="decorated">True</property>
+ <property name="skip_taskbar_hint">False</property>
+ <property name="skip_pager_hint">False</property>
+ <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+ <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+ <property name="focus_on_map">True</property>
+ <property name="urgency_hint">False</property>
+ <property name="has_separator">True</property>
+
+ <child internal-child="vbox">
+ <widget class="GtkVBox" id="dialog-vbox7">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child internal-child="action_area">
+ <widget class="GtkHButtonBox" id="dialog-action_area6">
+ <property name="visible">True</property>
+ <property name="layout_style">GTK_BUTTONBOX_END</property>
+
+ <child>
+ <widget class="GtkButton" id="convpreset_cancel">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-cancel</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="response_id">-6</property>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="convpreset_ok">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-ok</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="response_id">-5</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">GTK_PACK_END</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkVBox" id="vbox27">
+ <property name="border_width">12</property>
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">8</property>
+
+ <child>
+ <widget class="GtkHBox" id="hbox70">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">8</property>
+
+ <child>
+ <widget class="GtkLabel" id="label105">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Title:</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkEntry" id="title">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="editable">True</property>
+ <property name="visibility">True</property>
+ <property name="max_length">0</property>
+ <property name="text" translatable="yes">Untitled Encoder</property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char">●</property>
+ <property name="activates_default">True</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHBox" id="hbox96">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">9</property>
+
+ <child>
+ <widget class="GtkLabel" id="label120">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Output file extension:</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkEntry" id="ext">
+ <property name="visible">True</property>
+ <property name="tooltip" translatable="yes">E.g. mp3</property>
+ <property name="can_focus">True</property>
+ <property name="editable">True</property>
+ <property name="visibility">True</property>
+ <property name="max_length">0</property>
+ <property name="text" translatable="yes"></property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char">●</property>
+ <property name="activates_default">True</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHBox" id="hbox72">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">8</property>
+
+ <child>
+ <widget class="GtkLabel" id="label106">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Command line:</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHBox" id="hbox93">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkEntry" id="encoder">
+ <property name="visible">True</property>
+ <property name="tooltip" translatable="yes">Example: lame - %o
+%i for input file, %o for output file, - for stdin</property>
+ <property name="can_focus">True</property>
+ <property name="editable">True</property>
+ <property name="visibility">True</property>
+ <property name="max_length">0</property>
+ <property name="text" translatable="yes"></property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char">●</property>
+ <property name="activates_default">True</property>
+ <signal name="changed" handler="on_encoder_changed" last_modification_time="Sun, 13 Mar 2011 11:48:10 GMT"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="Custom" id="custom4">
+ <property name="visible">True</property>
+ <property name="creation_function">encoder_cmdline_help_link_create</property>
+ <property name="int1">0</property>
+ <property name="int2">0</property>
+ <property name="last_modification_time">Sat, 04 Dec 2010 15:30:13 GMT</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label124">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">&lt;small&gt;%o - output file name
+%i - temporary input file name&lt;/small&gt;</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">True</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHBox" id="hbox73">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">8</property>
+
+ <child>
+ <widget class="GtkLabel" id="label107">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Method:</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkComboBox" id="method">
+ <property name="visible">True</property>
+ <property name="items" translatable="yes">Pipe
+Temporary file</property>
+ <property name="add_tearoffs">False</property>
+ <property name="focus_on_click">True</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkFrame" id="frame9">
+ <property name="visible">True</property>
+ <property name="label_xalign">0</property>
+ <property name="label_yalign">0.5</property>
+ <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
+
+ <child>
+ <widget class="GtkAlignment" id="alignment21">
+ <property name="visible">True</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xscale">1</property>
+ <property name="yscale">1</property>
+ <property name="top_padding">0</property>
+ <property name="bottom_padding">0</property>
+ <property name="left_padding">12</property>
+ <property name="right_padding">0</property>
+
+ <child>
+ <widget class="GtkTable" id="table2">
+ <property name="border_width">8</property>
+ <property name="visible">True</property>
+ <property name="n_rows">2</property>
+ <property name="n_columns">3</property>
+ <property name="homogeneous">False</property>
+ <property name="row_spacing">0</property>
+ <property name="column_spacing">8</property>
+
+ <child>
+ <widget class="GtkCheckButton" id="apev2">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">APEv2</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="active">False</property>
+ <property name="inconsistent">False</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">0</property>
+ <property name="bottom_attach">1</property>
+ <property name="x_options">fill</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkCheckButton" id="id3v1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">ID3v1</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="active">False</property>
+ <property name="inconsistent">False</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="right_attach">3</property>
+ <property name="top_attach">0</property>
+ <property name="bottom_attach">1</property>
+ <property name="x_options">fill</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkCheckButton" id="oggvorbis">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">OggVorbis</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="active">False</property>
+ <property name="inconsistent">False</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="right_attach">3</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">fill</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkCheckButton" id="flac">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">FLAC</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="active">False</property>
+ <property name="inconsistent">False</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">fill</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHBox" id="hbox104">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkCheckButton" id="id3v2">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">ID3v2</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="active">False</property>
+ <property name="inconsistent">False</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkComboBox" id="id3v2_version">
+ <property name="visible">True</property>
+ <property name="items" translatable="yes">2.3
+2.4</property>
+ <property name="add_tearoffs">False</property>
+ <property name="focus_on_click">True</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="right_attach">1</property>
+ <property name="top_attach">0</property>
+ <property name="bottom_attach">1</property>
+ <property name="y_options">fill</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label125">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">&lt;b&gt;Tag writer&lt;/b&gt;</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">True</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="type">label_item</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+</widget>
+
+<widget class="GtkDialog" id="dsppreset_editor">
+ <property name="width_request">468</property>
+ <property name="height_request">254</property>
+ <property name="visible">True</property>
+ <property name="title" translatable="yes">DSP Preset Editor</property>
+ <property name="type">GTK_WINDOW_TOPLEVEL</property>
+ <property name="window_position">GTK_WIN_POS_NONE</property>
+ <property name="modal">True</property>
+ <property name="resizable">True</property>
+ <property name="destroy_with_parent">False</property>
+ <property name="decorated">True</property>
+ <property name="skip_taskbar_hint">False</property>
+ <property name="skip_pager_hint">False</property>
+ <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+ <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+ <property name="focus_on_map">True</property>
+ <property name="urgency_hint">False</property>
+ <property name="has_separator">True</property>
+
+ <child internal-child="vbox">
+ <widget class="GtkVBox" id="dialog-vbox9">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child internal-child="action_area">
+ <widget class="GtkHButtonBox" id="dialog-action_area8">
+ <property name="visible">True</property>
+ <property name="layout_style">GTK_BUTTONBOX_END</property>
+
+ <child>
+ <widget class="GtkButton" id="cancelbutton6">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-cancel</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="response_id">-6</property>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="okbutton6">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-ok</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="response_id">-5</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">GTK_PACK_END</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkVBox" id="vbox30">
+ <property name="border_width">12</property>
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">8</property>
+
+ <child>
+ <widget class="GtkHBox" id="hbox81">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">8</property>
+
+ <child>
+ <widget class="GtkLabel" id="label111">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Title</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkEntry" id="title">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="editable">True</property>
+ <property name="visibility">True</property>
+ <property name="max_length">0</property>
+ <property name="text" translatable="yes">Untitled DSP Preset</property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char">●</property>
+ <property name="activates_default">True</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkVBox" id="vbox29">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">8</property>
+
+ <child>
+ <widget class="GtkHBox" id="hbox82">
+ <property name="visible">True</property>
+ <property name="homogeneous">True</property>
+ <property name="spacing">8</property>
+
+ <child>
+ <widget class="GtkButton" id="add">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">Add</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <signal name="clicked" handler="on_dsp_preset_add_plugin_clicked" last_modification_time="Tue, 07 Dec 2010 20:11:31 GMT"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="remove">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">Remove</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <signal name="clicked" handler="on_dsp_preset_remove_plugin_clicked" last_modification_time="Tue, 07 Dec 2010 20:12:20 GMT"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="configure">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">Configure</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <signal name="clicked" handler="on_dsp_preset_plugin_configure_clicked" last_modification_time="Thu, 09 Dec 2010 20:31:42 GMT"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHBox" id="hbox98">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">8</property>
+
+ <child>
+ <widget class="GtkScrolledWindow" id="scrolledwindow7">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="shadow_type">GTK_SHADOW_IN</property>
+ <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+
+ <child>
+ <widget class="GtkTreeView" id="plugins">
+ <property name="width_request">196</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="headers_visible">False</property>
+ <property name="rules_hint">False</property>
+ <property name="reorderable">False</property>
+ <property name="enable_search">True</property>
+ <property name="fixed_height_mode">False</property>
+ <property name="hover_selection">False</property>
+ <property name="hover_expand">False</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkVBox" id="vbox34">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">8</property>
+
+ <child>
+ <widget class="GtkButton" id="up">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-go-up</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <signal name="clicked" handler="on_dsp_preset_plugin_up_clicked" last_modification_time="Sun, 12 Dec 2010 13:42:49 GMT"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="down">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-go-down</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <signal name="clicked" handler="on_dsp_preset_plugin_down_clicked" last_modification_time="Sun, 12 Dec 2010 13:42:59 GMT"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+</widget>
+
+<widget class="GtkDialog" id="select_dsp_plugin">
+ <property name="visible">True</property>
+ <property name="title" translatable="yes">Select DSP Plugin</property>
+ <property name="type">GTK_WINDOW_TOPLEVEL</property>
+ <property name="window_position">GTK_WIN_POS_NONE</property>
+ <property name="modal">True</property>
+ <property name="resizable">True</property>
+ <property name="destroy_with_parent">False</property>
+ <property name="decorated">True</property>
+ <property name="skip_taskbar_hint">False</property>
+ <property name="skip_pager_hint">False</property>
+ <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+ <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+ <property name="focus_on_map">True</property>
+ <property name="urgency_hint">False</property>
+ <property name="has_separator">True</property>
+
+ <child internal-child="vbox">
+ <widget class="GtkVBox" id="dialog-vbox10">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child internal-child="action_area">
+ <widget class="GtkHButtonBox" id="dialog-action_area9">
+ <property name="visible">True</property>
+ <property name="layout_style">GTK_BUTTONBOX_END</property>
+
+ <child>
+ <widget class="GtkButton" id="cancelbutton7">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-cancel</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="response_id">-6</property>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="okbutton7">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-ok</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="response_id">-5</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">GTK_PACK_END</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkVBox" id="vbox31">
+ <property name="border_width">12</property>
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">8</property>
+
+ <child>
+ <widget class="GtkHBox" id="hbox85">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">8</property>
+
+ <child>
+ <widget class="GtkLabel" id="label113">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Plugin</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkComboBox" id="plugin">
+ <property name="visible">True</property>
+ <property name="add_tearoffs">False</property>
+ <property name="focus_on_click">True</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+</widget>
+
+<widget class="GtkDialog" id="preset_list">
+ <property name="visible">True</property>
+ <property name="title" translatable="yes">Presets</property>
+ <property name="type">GTK_WINDOW_TOPLEVEL</property>
+ <property name="window_position">GTK_WIN_POS_NONE</property>
+ <property name="modal">True</property>
+ <property name="resizable">True</property>
+ <property name="destroy_with_parent">False</property>
+ <property name="decorated">True</property>
+ <property name="skip_taskbar_hint">False</property>
+ <property name="skip_pager_hint">False</property>
+ <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+ <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+ <property name="focus_on_map">True</property>
+ <property name="urgency_hint">False</property>
+ <property name="has_separator">True</property>
+
+ <child internal-child="vbox">
+ <widget class="GtkVBox" id="dialog-vbox11">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child internal-child="action_area">
+ <widget class="GtkHButtonBox" id="dialog-action_area10">
+ <property name="visible">True</property>
+ <property name="layout_style">GTK_BUTTONBOX_END</property>
+
+ <child>
+ <widget class="GtkButton" id="okbutton8">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-close</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="response_id">-7</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">GTK_PACK_END</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkVBox" id="vbox33">
+ <property name="border_width">12</property>
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">8</property>
+
+ <child>
+ <widget class="GtkHBox" id="hbox94">
+ <property name="visible">True</property>
+ <property name="homogeneous">True</property>
+ <property name="spacing">8</property>
+
+ <child>
+ <widget class="GtkButton" id="add">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-add</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="remove">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-remove</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="edit">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-edit</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkScrolledWindow" id="scrolledwindow8">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="shadow_type">GTK_SHADOW_IN</property>
+ <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+
+ <child>
+ <widget class="GtkTreeView" id="presets">
+ <property name="width_request">400</property>
+ <property name="height_request">176</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="headers_visible">False</property>
+ <property name="rules_hint">False</property>
+ <property name="reorderable">False</property>
+ <property name="enable_search">True</property>
+ <property name="fixed_height_mode">False</property>
+ <property name="hover_selection">False</property>
+ <property name="hover_expand">False</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+</widget>
+
+</glade-interface>
diff --git a/plugins/converter/converter.gladep b/plugins/converter/converter.gladep
new file mode 100644
index 00000000..fc0e5ab2
--- /dev/null
+++ b/plugins/converter/converter.gladep
@@ -0,0 +1,11 @@
+<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
+<!DOCTYPE glade-project SYSTEM "http://glade.gnome.org/glade-project-2.0.dtd">
+
+<glade-project>
+ <name>converter</name>
+ <program_name>converter</program_name>
+ <source_directory></source_directory>
+ <gnome_support>FALSE</gnome_support>
+ <output_main_file>FALSE</output_main_file>
+ <output_build_files>FALSE</output_build_files>
+</glade-project>
diff --git a/plugins/converter/converter.h b/plugins/converter/converter.h
new file mode 100644
index 00000000..173d35b4
--- /dev/null
+++ b/plugins/converter/converter.h
@@ -0,0 +1,150 @@
+/*
+ DeaDBeeF - ultimate music player for GNU/Linux systems with X11
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+#ifndef __CONVERTER_H
+#define __CONVERTER_H
+
+#include <stdint.h>
+#include <deadbeef.h>
+
+enum {
+ DDB_ENCODER_METHOD_PIPE = 0,
+ DDB_ENCODER_METHOD_FILE = 1,
+};
+
+enum {
+ DDB_ENCODER_FMT_8BIT = 0x1,
+ DDB_ENCODER_FMT_16BIT = 0x2,
+ DDB_ENCODER_FMT_24BIT = 0x4,
+ DDB_ENCODER_FMT_32BIT = 0x8,
+ DDB_ENCODER_FMT_32BITFLOAT = 0x10,
+};
+
+typedef struct ddb_preset_s {
+ char *title;
+ struct ddb_preset_s *next;
+} ddb_preset_t;
+
+typedef struct ddb_encoder_preset_s {
+ char *title;
+ struct ddb_encoder_preset_s *next;
+ char *ext;
+ char *encoder;
+ int method; // pipe or file
+ int tag_id3v2;
+ int tag_id3v1;
+ int tag_apev2;
+ int tag_flac;
+ int tag_oggvorbis;
+ int tag_mp3xing;
+ int id3v2_version;
+} ddb_encoder_preset_t;
+
+typedef struct ddb_dsp_preset_s {
+ char *title;
+ struct ddb_dsp_preset_s *next;
+ ddb_dsp_context_t *chain;
+} ddb_dsp_preset_t;
+
+typedef struct {
+ DB_misc_t misc;
+
+ /////////////////////////////
+ // encoder preset management
+ /////////////////////////////
+
+ ddb_encoder_preset_t *
+ (*encoder_preset_alloc) (void);
+
+ void
+ (*encoder_preset_free) (ddb_encoder_preset_t *p);
+
+ ddb_encoder_preset_t *
+ (*encoder_preset_load) (const char *fname);
+
+ // @return -1 on path/write error, -2 if file already exists
+ int
+ (*encoder_preset_save) (ddb_encoder_preset_t *p, int overwrite);
+
+ void
+ (*encoder_preset_copy) (ddb_encoder_preset_t *to, ddb_encoder_preset_t *from);
+
+ ddb_encoder_preset_t *
+ (*encoder_preset_get_list) (void);
+
+ ddb_encoder_preset_t *
+ (*encoder_preset_get_for_idx) (int idx);
+
+ void
+ (*encoder_preset_append) (ddb_encoder_preset_t *p);
+
+ void
+ (*encoder_preset_remove) (ddb_encoder_preset_t *p);
+
+ void
+ (*encoder_preset_replace) (ddb_encoder_preset_t *from, ddb_encoder_preset_t *to);
+
+ /////////////////////////////
+ // dsp preset management
+ /////////////////////////////
+
+ ddb_dsp_preset_t *
+ (*dsp_preset_alloc) (void);
+
+ void
+ (*dsp_preset_free) (ddb_dsp_preset_t *p);
+
+ ddb_dsp_preset_t *
+ (*dsp_preset_load) (const char *fname);
+
+ // @return -1 on path/write error, -2 if file already exists
+ int
+ (*dsp_preset_save) (ddb_dsp_preset_t *p, int overwrite);
+
+ void
+ (*dsp_preset_copy) (ddb_dsp_preset_t *to, ddb_dsp_preset_t *from);
+
+ ddb_dsp_preset_t *
+ (*dsp_preset_get_list) (void);
+
+ ddb_dsp_preset_t *
+ (*dsp_preset_get_for_idx) (int idx);
+
+ void
+ (*dsp_preset_append) (ddb_dsp_preset_t *p);
+
+ void
+ (*dsp_preset_remove) (ddb_dsp_preset_t *p);
+
+ void
+ (*dsp_preset_replace) (ddb_dsp_preset_t *from, ddb_dsp_preset_t *to);
+
+ /////////////////////////////
+ // converter
+ /////////////////////////////
+
+
+ void
+ (*get_output_path) (DB_playItem_t *it, const char *outfolder, const char *outfile, ddb_encoder_preset_t *encoder_preset, char *out, int sz);
+
+ int
+ (*convert) (DB_playItem_t *it, const char *outfolder, const char *outfile, int output_bps, int output_is_float, int preserve_folder_structure, const char *root_folder, ddb_encoder_preset_t *encoder_preset, ddb_dsp_preset_t *dsp_preset, int *abort);
+
+} ddb_converter_t;
+
+#endif
diff --git a/plugins/converter/convgui.c b/plugins/converter/convgui.c
new file mode 100644
index 00000000..286bfdd4
--- /dev/null
+++ b/plugins/converter/convgui.c
@@ -0,0 +1,1301 @@
+/*
+ DeaDBeeF - ultimate music player for GNU/Linux systems with X11
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+#include <string.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include "converter.h"
+#include "support.h"
+#include "interface.h"
+#include "../gtkui/gtkui_api.h"
+
+DB_functions_t *deadbeef;
+
+ddb_converter_t *converter_plugin;
+ddb_gtkui_t *gtkui_plugin;
+
+typedef struct {
+ GtkWidget *converter;
+ ddb_encoder_preset_t *current_encoder_preset;
+ ddb_dsp_preset_t *current_dsp_preset;
+
+ DB_playItem_t **convert_items;
+ int convert_items_count;
+ char *outfolder;
+ char *outfile;
+ int preserve_folder_structure;
+ char *preserve_root_folder;
+ int output_bps;
+ int output_is_float;
+ int overwrite_action;
+ ddb_encoder_preset_t *encoder_preset;
+ ddb_dsp_preset_t *dsp_preset;
+ GtkWidget *progress;
+ GtkWidget *progress_entry;
+ int cancelled;
+ char *progress_text;
+} converter_ctx_t;
+
+converter_ctx_t *current_ctx;
+
+void
+fill_presets (GtkListStore *mdl, ddb_preset_t *head) {
+ ddb_preset_t *p = head;
+ while (p) {
+ GtkTreeIter iter;
+ gtk_list_store_append (mdl, &iter);
+ gtk_list_store_set (mdl, &iter, 0, p->title, -1);
+ p = p->next;
+ }
+}
+
+void
+on_converter_progress_cancel (GtkDialog *dialog, gint response_id, gpointer user_data) {
+ converter_ctx_t *ctx = user_data;
+ ctx->cancelled = 1;
+}
+
+typedef struct {
+ GtkWidget *entry;
+ char *text;
+} update_progress_info_t;
+
+static gboolean
+update_progress_cb (gpointer ctx) {
+ update_progress_info_t *info = ctx;
+ gtk_entry_set_text (GTK_ENTRY (info->entry), info->text);
+ free (info->text);
+ g_object_unref (info->entry);
+ free (info);
+ return FALSE;
+}
+
+static gboolean
+destroy_progress_cb (gpointer ctx) {
+ gtk_widget_destroy (ctx);
+ return FALSE;
+}
+
+struct overwrite_prompt_ctx {
+ char *fname;
+ uintptr_t mutex;
+ uintptr_t cond;
+ int result;
+};
+
+static gboolean
+overwrite_prompt_cb (void *ctx) {
+ struct overwrite_prompt_ctx *ctl = ctx;
+ GtkWidget *mainwin = gtkui_plugin->get_mainwin ();
+ GtkWidget *dlg = gtk_message_dialog_new (GTK_WINDOW (mainwin), GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING, GTK_BUTTONS_YES_NO, _("The file already exists. Overwrite?"));
+ gtk_window_set_transient_for (GTK_WINDOW (dlg), GTK_WINDOW (mainwin));
+ gtk_window_set_title (GTK_WINDOW (dlg), _("Converter warning"));
+ gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dlg), ctl->fname);
+
+ int response = gtk_dialog_run (GTK_DIALOG (dlg));
+ gtk_widget_destroy (dlg);
+ ctl->result = response == GTK_RESPONSE_YES ? 1 : 0;
+ deadbeef->cond_signal (ctl->cond);
+ return FALSE;
+}
+
+static void
+converter_worker (void *ctx) {
+ converter_ctx_t *conv = ctx;
+
+ for (int n = 0; n < conv->convert_items_count; n++) {
+ update_progress_info_t *info = malloc (sizeof (update_progress_info_t));
+ info->entry = conv->progress_entry;
+ g_object_ref (info->entry);
+ info->text = strdup (deadbeef->pl_find_meta (conv->convert_items[n], ":URI"));
+ g_idle_add (update_progress_cb, info);
+
+ char outpath[2000];
+ converter_plugin->get_output_path (conv->convert_items[n], conv->outfolder, conv->outfile, conv->encoder_preset, outpath, sizeof (outpath));
+
+ int skip = 0;
+ struct stat st;
+ int res = stat(outpath, &st);
+ if (res == 0) {
+ if (conv->overwrite_action > 1 || conv->overwrite_action < 0) {
+ conv->overwrite_action = 0;
+ }
+ if (conv->overwrite_action == 0) {
+ // prompt if file exists
+ struct overwrite_prompt_ctx ctl;
+ ctl.mutex = deadbeef->mutex_create ();
+ ctl.cond = deadbeef->cond_create ();
+ ctl.fname = outpath;
+ ctl.result = 0;
+ gdk_threads_add_idle (overwrite_prompt_cb, &ctl);
+ deadbeef->cond_wait (ctl.cond, ctl.mutex);
+ deadbeef->cond_free (ctl.cond);
+ deadbeef->mutex_free (ctl.mutex);
+ if (ctl.result) {
+ unlink (outpath);
+ }
+ else {
+ skip = 1;
+ }
+ }
+ else if (conv->overwrite_action == 1) {
+ unlink (outpath);
+ }
+ }
+
+ if (!skip) {
+ converter_plugin->convert (conv->convert_items[n], conv->outfolder, conv->outfile, conv->output_bps, conv->output_is_float, conv->preserve_folder_structure, conv->preserve_root_folder, conv->encoder_preset, conv->dsp_preset, &conv->cancelled);
+ }
+ if (conv->cancelled) {
+ for (; n < conv->convert_items_count; n++) {
+ deadbeef->pl_item_unref (conv->convert_items[n]);
+ }
+ break;
+ }
+ deadbeef->pl_item_unref (conv->convert_items[n]);
+ }
+ g_idle_add (destroy_progress_cb, conv->progress);
+ if (conv->convert_items) {
+ free (conv->convert_items);
+ }
+ free (conv->outfolder);
+ converter_plugin->encoder_preset_free (conv->encoder_preset);
+ converter_plugin->dsp_preset_free (conv->dsp_preset);
+ free (conv);
+}
+
+int
+converter_process (converter_ctx_t *conv)
+{
+ conv->outfolder = strdup (gtk_entry_get_text (GTK_ENTRY (lookup_widget (conv->converter, "output_folder"))));
+ const char *outfile = gtk_entry_get_text (GTK_ENTRY (lookup_widget (conv->converter, "output_file")));
+ if (outfile[0] == 0) {
+ outfile = "%a - %t";
+ }
+ conv->outfile = strdup (outfile);
+ conv->preserve_folder_structure = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (lookup_widget (conv->converter, "preserve_folders")));
+ conv->preserve_root_folder = strdup (gtk_entry_get_text (GTK_ENTRY (lookup_widget (conv->converter, "preserve_root_folder"))));
+ conv->overwrite_action = gtk_combo_box_get_active (GTK_COMBO_BOX (lookup_widget (conv->converter, "overwrite_action")));
+
+ GtkComboBox *combo = GTK_COMBO_BOX (lookup_widget (conv->converter, "output_format"));
+ int selected_format = gtk_combo_box_get_active (combo);
+ switch (selected_format) {
+ case 1 ... 4:
+ conv->output_bps = selected_format * 8;
+ conv->output_is_float = 0;
+ break;
+ case 5:
+ conv->output_bps = 32;
+ conv->output_is_float = 1;
+ break;
+ default:
+ conv->output_bps = -1; // same as input, or encoder default
+ break;
+ }
+
+ combo = GTK_COMBO_BOX (lookup_widget (conv->converter, "encoder"));
+ int enc_preset = gtk_combo_box_get_active (combo);
+ ddb_encoder_preset_t *encoder_preset = NULL;
+
+ if (enc_preset >= 0) {
+ encoder_preset = converter_plugin->encoder_preset_get_for_idx (enc_preset);
+ }
+ if (!encoder_preset) {
+ GtkWidget *dlg = gtk_message_dialog_new (GTK_WINDOW (conv->converter), GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("Please select encoder"));
+ gtk_window_set_transient_for (GTK_WINDOW (dlg), GTK_WINDOW (conv->converter));
+ gtk_window_set_title (GTK_WINDOW (dlg), _("Converter error"));
+
+ gtk_dialog_run (GTK_DIALOG (dlg));
+ gtk_widget_destroy (dlg);
+ return -1;
+ }
+
+ combo = GTK_COMBO_BOX (lookup_widget (conv->converter, "dsp_preset"));
+ int dsp_idx = gtk_combo_box_get_active (combo) - 1;
+
+ ddb_dsp_preset_t *dsp_preset = NULL;
+ if (dsp_idx >= 0) {
+ dsp_preset = converter_plugin->dsp_preset_get_for_idx (dsp_idx);
+ }
+
+ if (encoder_preset) {
+ conv->encoder_preset = converter_plugin->encoder_preset_alloc ();
+ converter_plugin->encoder_preset_copy (conv->encoder_preset, encoder_preset);
+ }
+ if (dsp_preset) {
+ conv->dsp_preset = converter_plugin->dsp_preset_alloc ();
+ converter_plugin->dsp_preset_copy (conv->dsp_preset, dsp_preset);
+ }
+
+ GtkWidget *progress = gtk_dialog_new_with_buttons (_("Converting..."), GTK_WINDOW (gtkui_plugin->get_mainwin ()), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, NULL);
+ GtkWidget *vbox = GTK_DIALOG (progress)->vbox;
+ GtkWidget *entry = gtk_entry_new ();
+ gtk_widget_set_size_request (entry, 400, -1);
+ gtk_editable_set_editable (GTK_EDITABLE (entry), FALSE);
+ gtk_widget_show (entry);
+ gtk_box_pack_start (GTK_BOX (vbox), entry, TRUE, TRUE, 12);
+
+ g_signal_connect ((gpointer)progress, "response", G_CALLBACK (on_converter_progress_cancel), conv);
+
+ gtk_widget_show (progress);
+
+ conv->progress = progress;
+ conv->progress_entry = entry;
+ intptr_t tid = deadbeef->thread_start (converter_worker, conv);
+ deadbeef->thread_detach (tid);
+ return 0;
+}
+
+static int
+converter_show (DB_plugin_action_t *act, DB_playItem_t *it) {
+ converter_ctx_t *conv = malloc (sizeof (converter_ctx_t));
+ current_ctx = conv;
+ memset (conv, 0, sizeof (converter_ctx_t));
+
+ deadbeef->pl_lock ();
+ // copy list
+ int nsel = deadbeef->pl_getselcount ();
+ conv->convert_items_count = nsel;
+ if (0 < nsel) {
+ conv->convert_items = malloc (sizeof (DB_playItem_t *) * nsel);
+ if (conv->convert_items) {
+ int n = 0;
+ DB_playItem_t *it = deadbeef->pl_get_first (PL_MAIN);
+ while (it) {
+ if (deadbeef->pl_is_selected (it)) {
+ assert (n < nsel);
+ deadbeef->pl_item_ref (it);
+ conv->convert_items[n++] = it;
+ }
+ DB_playItem_t *next = deadbeef->pl_get_next (it, PL_MAIN);
+ deadbeef->pl_item_unref (it);
+ it = next;
+ }
+ }
+ }
+ deadbeef->pl_unlock ();
+
+ conv->converter = create_converterdlg ();
+ deadbeef->conf_lock ();
+ gtk_entry_set_text (GTK_ENTRY (lookup_widget (conv->converter, "output_folder")), deadbeef->conf_get_str_fast ("converter.output_folder", ""));
+ gtk_entry_set_text (GTK_ENTRY (lookup_widget (conv->converter, "output_file")), deadbeef->conf_get_str_fast ("converter.output_file", ""));
+ gtk_entry_set_text (GTK_ENTRY (lookup_widget (conv->converter, "preserve_root_folder")), deadbeef->conf_get_str_fast ("converter.preserve_root_folder", ""));
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (lookup_widget (conv->converter, "preserve_folders")), deadbeef->conf_get_int ("converter.preserve_folder_structure", 0));
+ gtk_combo_box_set_active (GTK_COMBO_BOX (lookup_widget (conv->converter, "overwrite_action")), deadbeef->conf_get_int ("converter.overwrite_action", 0));
+ deadbeef->conf_unlock ();
+
+ GtkComboBox *combo;
+ // fill encoder presets
+ combo = GTK_COMBO_BOX (lookup_widget (conv->converter, "encoder"));
+ GtkListStore *mdl = GTK_LIST_STORE (gtk_combo_box_get_model (combo));
+ fill_presets (mdl, (ddb_preset_t *)converter_plugin->encoder_preset_get_list ());
+ gtk_combo_box_set_active (combo, deadbeef->conf_get_int ("converter.encoder_preset", 0));
+
+ // fill dsp presets
+ combo = GTK_COMBO_BOX (lookup_widget (conv->converter, "dsp_preset"));
+ mdl = GTK_LIST_STORE (gtk_combo_box_get_model (combo));
+ GtkTreeIter iter;
+ gtk_list_store_append (mdl, &iter);
+ gtk_list_store_set (mdl, &iter, 0, "Pass through", -1);
+ fill_presets (mdl, (ddb_preset_t *)converter_plugin->dsp_preset_get_list ());
+
+ gtk_combo_box_set_active (combo, deadbeef->conf_get_int ("converter.dsp_preset", -1) + 1);
+
+ // select output format
+ combo = GTK_COMBO_BOX (lookup_widget (conv->converter, "output_format"));
+ gtk_combo_box_set_active (combo, deadbeef->conf_get_int ("converter.output_format", 0));
+
+ // overwrite action
+ combo = GTK_COMBO_BOX (lookup_widget (conv->converter, "overwrite_action"));
+ gtk_combo_box_set_active (combo, deadbeef->conf_get_int ("converter.overwrite_action", 0));
+
+ for (;;) {
+ int response = gtk_dialog_run (GTK_DIALOG (conv->converter));
+ if (response == GTK_RESPONSE_OK) {
+ int err = converter_process (conv);
+ if (err != 0) {
+ continue;
+ }
+ gtk_widget_destroy (conv->converter);
+ }
+ else {
+ // FIXME: clean up properly
+ gtk_widget_destroy (conv->converter);
+ if (conv->convert_items) {
+ for (int n = 0; n < conv->convert_items_count; n++) {
+ deadbeef->pl_item_unref (conv->convert_items[n]);
+ }
+ free (conv->convert_items);
+ }
+ free (conv);
+ }
+ current_ctx = NULL;
+ break;
+ }
+ return 0;
+}
+
+void
+on_converter_encoder_changed (GtkComboBox *combobox,
+ gpointer user_data)
+{
+ GtkComboBox *combo = GTK_COMBO_BOX (lookup_widget (current_ctx->converter, "encoder"));
+ int act = gtk_combo_box_get_active (combo);
+ deadbeef->conf_set_int ("converter.encoder_preset", act);
+}
+
+void
+on_converter_dsp_preset_changed (GtkComboBox *combobox,
+ gpointer user_data)
+{
+ GtkComboBox *combo = GTK_COMBO_BOX (lookup_widget (current_ctx->converter, "dsp_preset"));
+ int act = gtk_combo_box_get_active (combo);
+ deadbeef->conf_set_int ("converter.dsp_preset", act-1);
+}
+
+void
+on_converter_output_browse_clicked (GtkButton *button,
+ gpointer user_data)
+{
+ GtkWidget *dlg = gtk_file_chooser_dialog_new (_("Select folder..."), GTK_WINDOW (current_ctx->converter), GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_OK, NULL);
+ gtk_window_set_transient_for (GTK_WINDOW (dlg), GTK_WINDOW (current_ctx->converter));
+
+ gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dlg), FALSE);
+ // restore folder
+ deadbeef->conf_lock ();
+ gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER (dlg), deadbeef->conf_get_str_fast ("filechooser.lastdir", ""));
+ deadbeef->conf_unlock ();
+ int response = gtk_dialog_run (GTK_DIALOG (dlg));
+ // store folder
+ gchar *folder = gtk_file_chooser_get_current_folder_uri (GTK_FILE_CHOOSER (dlg));
+ if (folder) {
+ deadbeef->conf_set_str ("filechooser.lastdir", folder);
+ g_free (folder);
+ deadbeef->sendmessage (M_CONFIG_CHANGED, 0, 0, 0);
+ }
+ if (response == GTK_RESPONSE_OK) {
+ folder = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dlg));
+ gtk_widget_destroy (dlg);
+ if (folder) {
+ GtkWidget *entry = lookup_widget (current_ctx->converter, "output_folder");
+ gtk_entry_set_text (GTK_ENTRY (entry), folder);
+ g_free (folder);
+ }
+ }
+ else {
+ gtk_widget_destroy (dlg);
+ }
+}
+
+
+void
+on_output_folder_changed (GtkEntry *entry,
+ gpointer user_data)
+{
+ deadbeef->conf_set_str ("converter.output_folder", gtk_entry_get_text (entry));
+ deadbeef->conf_save ();
+}
+
+
+void
+on_numthreads_changed (GtkEditable *editable,
+ gpointer user_data)
+{
+ deadbeef->conf_set_int ("converter.threads", gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (editable)));
+ deadbeef->conf_save ();
+}
+
+void
+on_overwrite_action_changed (GtkComboBox *combobox,
+ gpointer user_data)
+{
+ deadbeef->conf_set_int ("converter.overwrite_action", gtk_combo_box_get_active (combobox));
+ deadbeef->conf_save ();
+}
+
+void
+on_encoder_changed (GtkEditable *editable,
+ gpointer user_data)
+{
+ gtk_widget_set_has_tooltip (GTK_WIDGET (editable), TRUE);
+
+ char enc[2000];
+ const char *e = gtk_entry_get_text (GTK_ENTRY (editable));
+ char *o = enc;
+ *o = 0;
+ int len = sizeof (enc);
+ while (e && *e) {
+ if (len <= 0) {
+ break;
+ }
+ if (e[0] == '%' && e[1]) {
+ if (e[1] == 'o') {
+ int l = snprintf (o, len, "\"OUTPUT_FILE_NAME\"");
+ o += l;
+ len -= l;
+ }
+ else if (e[1] == 'i') {
+ int l = snprintf (o, len, "\"TEMP_FILE_NAME\"");
+ o += l;
+ len -= l;
+ }
+ else {
+ strncpy (o, e, 2);
+ o += 2;
+ len -= 2;
+ }
+ e += 2;
+ }
+ else {
+ *o++ = *e++;
+ *o = 0;
+ len--;
+ }
+ }
+
+ gtk_widget_set_tooltip_text (GTK_WIDGET (editable), enc);
+}
+
+void
+on_preserve_folder_browse_clicked (GtkButton *button,
+ gpointer user_data)
+{
+ GtkWidget *dlg = gtk_file_chooser_dialog_new (_("Select folder..."), GTK_WINDOW (current_ctx->converter), GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_OK, NULL);
+ gtk_window_set_transient_for (GTK_WINDOW (dlg), GTK_WINDOW (current_ctx->converter));
+
+ gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dlg), FALSE);
+ // restore folder
+ deadbeef->conf_lock ();
+ gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER (dlg), deadbeef->conf_get_str_fast ("filechooser.lastdir", ""));
+ deadbeef->conf_unlock ();
+ int response = gtk_dialog_run (GTK_DIALOG (dlg));
+ // store folder
+ gchar *folder = gtk_file_chooser_get_current_folder_uri (GTK_FILE_CHOOSER (dlg));
+ if (folder) {
+ deadbeef->conf_set_str ("filechooser.lastdir", folder);
+ g_free (folder);
+ deadbeef->sendmessage (M_CONFIG_CHANGED, 0, 0, 0);
+ }
+ if (response == GTK_RESPONSE_OK) {
+ folder = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dlg));
+ gtk_widget_destroy (dlg);
+ if (folder) {
+ GtkWidget *entry = lookup_widget (current_ctx->converter, "preserve_root_folder");
+ gtk_entry_set_text (GTK_ENTRY (entry), folder);
+ g_free (folder);
+ }
+ }
+ else {
+ gtk_widget_destroy (dlg);
+ }
+}
+
+void
+on_output_file_changed (GtkEntry *entry,
+ gpointer user_data)
+{
+ deadbeef->conf_set_str ("converter.output_file", gtk_entry_get_text (entry));
+ deadbeef->conf_save ();
+}
+
+void
+on_preserve_folders_toggled (GtkToggleButton *togglebutton,
+ gpointer user_data)
+{
+ deadbeef->conf_set_int ("converter.preserve_folder_structure", gtk_toggle_button_get_active (togglebutton));
+ deadbeef->conf_save ();
+}
+
+void
+on_preserve_root_folder_changed (GtkEntry *entry,
+ gpointer user_data)
+{
+ deadbeef->conf_set_str ("converter.preserve_root_folder", gtk_entry_get_text (entry));
+ deadbeef->conf_save ();
+}
+
+DB_decoder_t *
+plug_get_decoder_for_id (const char *id) {
+ DB_decoder_t **plugins = deadbeef->plug_get_decoder_list ();
+ for (int c = 0; plugins[c]; c++) {
+ if (!strcmp (id, plugins[c]->plugin.id)) {
+ return plugins[c];
+ }
+ }
+ return NULL;
+}
+
+void
+init_encoder_preset_from_dlg (GtkWidget *dlg, ddb_encoder_preset_t *p) {
+ p->title = strdup (gtk_entry_get_text (GTK_ENTRY (lookup_widget (dlg, "title"))));
+ p->ext = strdup (gtk_entry_get_text (GTK_ENTRY (lookup_widget (dlg, "ext"))));
+ p->encoder = strdup (gtk_entry_get_text (GTK_ENTRY (lookup_widget (dlg, "encoder"))));
+ int method_idx = gtk_combo_box_get_active (GTK_COMBO_BOX (lookup_widget (dlg, "method")));
+ switch (method_idx) {
+ case 0:
+ p->method = DDB_ENCODER_METHOD_PIPE;
+ break;
+ case 1:
+ p->method = DDB_ENCODER_METHOD_FILE;
+ break;
+ }
+
+ p->id3v2_version = gtk_combo_box_get_active (GTK_COMBO_BOX (lookup_widget (dlg, "id3v2_version")));
+ p->tag_id3v2 = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (lookup_widget (dlg, "id3v2")));
+ p->tag_id3v1 = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (lookup_widget (dlg, "id3v1")));
+ p->tag_apev2 = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (lookup_widget (dlg, "apev2")));
+ p->tag_flac = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (lookup_widget (dlg, "flac")));
+ p->tag_oggvorbis = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (lookup_widget (dlg, "oggvorbis")));
+}
+
+int
+edit_encoder_preset (char *title, GtkWidget *toplevel, int overwrite) {
+ GtkWidget *dlg = create_convpreset_editor ();
+ gtk_window_set_title (GTK_WINDOW (dlg), title);
+ gtk_dialog_set_default_response (GTK_DIALOG (dlg), GTK_RESPONSE_OK);
+
+ gtk_window_set_transient_for (GTK_WINDOW (dlg), GTK_WINDOW (toplevel));
+
+ ddb_encoder_preset_t *p = current_ctx->current_encoder_preset;
+
+ if (p->title) {
+ gtk_entry_set_text (GTK_ENTRY (lookup_widget (dlg, "title")), p->title);
+ }
+ if (p->ext) {
+ gtk_entry_set_text (GTK_ENTRY (lookup_widget (dlg, "ext")), p->ext);
+ }
+ if (p->encoder) {
+ gtk_entry_set_text (GTK_ENTRY (lookup_widget (dlg, "encoder")), p->encoder);
+ }
+ gtk_combo_box_set_active (GTK_COMBO_BOX (lookup_widget (dlg, "method")), p->method);
+
+ gtk_combo_box_set_active (GTK_COMBO_BOX (lookup_widget (dlg, "id3v2_version")), p->id3v2_version);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (lookup_widget (dlg, "id3v2")), p->tag_id3v2);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (lookup_widget (dlg, "id3v1")), p->tag_id3v1);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (lookup_widget (dlg, "apev2")), p->tag_apev2);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (lookup_widget (dlg, "flac")), p->tag_flac);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (lookup_widget (dlg, "oggvorbis")), p->tag_oggvorbis);
+
+ ddb_encoder_preset_t *old = p;
+ int r = GTK_RESPONSE_CANCEL;
+ for (;;) {
+ r = gtk_dialog_run (GTK_DIALOG (dlg));
+ if (r == GTK_RESPONSE_OK) {
+ ddb_encoder_preset_t *p = converter_plugin->encoder_preset_alloc ();
+ if (p) {
+ init_encoder_preset_from_dlg (dlg, p);
+ int err = converter_plugin->encoder_preset_save (p, overwrite);
+ if (!err) {
+ if (old->title && strcmp (p->title, old->title)) {
+ char path[1024];
+ if (snprintf (path, sizeof (path), "%s/presets/encoders/%s.txt", deadbeef->get_config_dir (), old->title) > 0) {
+ unlink (path);
+ }
+ }
+ free (old->title);
+ free (old->ext);
+ free (old->encoder);
+
+ converter_plugin->encoder_preset_copy (old, p);
+ converter_plugin->encoder_preset_free (p);
+ }
+ else {
+ GtkWidget *warndlg = gtk_message_dialog_new (GTK_WINDOW (gtkui_plugin->get_mainwin ()), GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("Failed to save encoder preset"));
+ gtk_window_set_transient_for (GTK_WINDOW (warndlg), GTK_WINDOW (dlg));
+ gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (warndlg), err == -1 ? _("Check preset folder permissions, try to pick different title, or free up some disk space") : _("Preset with the same name already exists. Try to pick another title."));
+ gtk_window_set_title (GTK_WINDOW (warndlg), _("Error"));
+
+ /*int response = */gtk_dialog_run (GTK_DIALOG (warndlg));
+ gtk_widget_destroy (warndlg);
+ continue;
+ }
+ }
+ }
+ break;
+ }
+
+ gtk_widget_destroy (dlg);
+ return r;
+}
+
+void
+refresh_encoder_lists (GtkComboBox *combo, GtkTreeView *list) {
+ // presets list view
+ GtkListStore *mdl = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (list)));
+
+ GtkTreePath *path;
+ GtkTreeViewColumn *col;
+ gtk_tree_view_get_cursor (GTK_TREE_VIEW (list), &path, &col);
+ int idx = -1;
+ if (path && col) {
+ int *indices = gtk_tree_path_get_indices (path);
+ idx = *indices;
+ g_free (indices);
+ }
+
+ gtk_list_store_clear (mdl);
+ fill_presets (mdl, (ddb_preset_t *)converter_plugin->encoder_preset_get_list ());
+ if (idx != -1) {
+ path = gtk_tree_path_new_from_indices (idx, -1);
+ gtk_tree_view_set_cursor (GTK_TREE_VIEW (list), path, col, FALSE);
+ gtk_tree_path_free (path);
+ }
+
+ // presets combo box
+ int act = gtk_combo_box_get_active (combo);
+ mdl = GTK_LIST_STORE (gtk_combo_box_get_model (combo));
+ gtk_list_store_clear (mdl);
+ fill_presets (mdl, (ddb_preset_t *)converter_plugin->encoder_preset_get_list ());
+ gtk_combo_box_set_active (combo, act);
+}
+
+void
+on_encoder_preset_add (GtkButton *button,
+ gpointer user_data)
+{
+ GtkWidget *toplevel = gtk_widget_get_toplevel (GTK_WIDGET (button));
+
+ current_ctx->current_encoder_preset = converter_plugin->encoder_preset_alloc ();
+
+ if (GTK_RESPONSE_OK == edit_encoder_preset (_("Add new encoder"), toplevel, 0)) {
+ printf ("added new enc preset\n");
+ converter_plugin->encoder_preset_append (current_ctx->current_encoder_preset);
+ GtkComboBox *combo = GTK_COMBO_BOX (lookup_widget (current_ctx->converter, "encoder"));
+ GtkWidget *list = lookup_widget (toplevel, "presets");
+ printf ("refresh list\n");
+ refresh_encoder_lists (combo, GTK_TREE_VIEW (list));
+ }
+
+ current_ctx->current_encoder_preset = NULL;
+}
+
+void
+on_encoder_preset_edit (GtkButton *button,
+ gpointer user_data)
+{
+ GtkWidget *toplevel = gtk_widget_get_toplevel (GTK_WIDGET (button));
+ GtkWidget *list = lookup_widget (toplevel, "presets");
+ GtkTreePath *path;
+ GtkTreeViewColumn *col;
+ gtk_tree_view_get_cursor (GTK_TREE_VIEW (list), &path, &col);
+ if (!path || !col) {
+ // nothing selected
+ return;
+ }
+ int *indices = gtk_tree_path_get_indices (path);
+ int idx = *indices;
+ g_free (indices);
+
+ ddb_encoder_preset_t *p = converter_plugin->encoder_preset_get_for_idx (idx);
+ current_ctx->current_encoder_preset = p;
+
+ int r = edit_encoder_preset (_("Edit encoder"), toplevel, 1);
+ if (r == GTK_RESPONSE_OK) {
+ GtkComboBox *combo = GTK_COMBO_BOX (lookup_widget (current_ctx->converter, "encoder"));
+ refresh_encoder_lists (combo, GTK_TREE_VIEW (list));
+ }
+
+ current_ctx->current_encoder_preset = NULL;
+}
+
+void
+on_encoder_preset_remove (GtkButton *button,
+ gpointer user_data)
+{
+
+ GtkWidget *toplevel = gtk_widget_get_toplevel (GTK_WIDGET (button));
+ GtkWidget *list = lookup_widget (toplevel, "presets");
+ GtkTreePath *path;
+ GtkTreeViewColumn *col;
+ gtk_tree_view_get_cursor (GTK_TREE_VIEW (list), &path, &col);
+ if (!path || !col) {
+ // nothing selected
+ return;
+ }
+ int *indices = gtk_tree_path_get_indices (path);
+ int idx = *indices;
+ g_free (indices);
+
+ ddb_encoder_preset_t *p = converter_plugin->encoder_preset_get_for_idx (idx);
+ if (!p) {
+ return;
+ }
+
+ GtkWidget *dlg = gtk_message_dialog_new (GTK_WINDOW (gtkui_plugin->get_mainwin ()), GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING, GTK_BUTTONS_YES_NO, _("Remove preset"));
+ gtk_window_set_transient_for (GTK_WINDOW (dlg), GTK_WINDOW (toplevel));
+ gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dlg), _("This action will delete the selected preset. Are you sure?"));
+ gtk_window_set_title (GTK_WINDOW (dlg), _("Warning"));
+
+ int response = gtk_dialog_run (GTK_DIALOG (dlg));
+ gtk_widget_destroy (dlg);
+ if (response == GTK_RESPONSE_YES) {
+ char path[1024];
+ if (snprintf (path, sizeof (path), "%s/presets/encoders/%s.txt", deadbeef->get_config_dir (), p->title) > 0) {
+ unlink (path);
+ }
+
+ converter_plugin->encoder_preset_remove (p);
+ converter_plugin->encoder_preset_free (p);
+
+ GtkComboBox *combo = GTK_COMBO_BOX (lookup_widget (current_ctx->converter, "encoder"));
+ refresh_encoder_lists (combo, GTK_TREE_VIEW (list));
+ }
+}
+
+void
+on_edit_encoder_presets_clicked (GtkButton *button,
+ gpointer user_data)
+{
+ GtkWidget *dlg = create_preset_list ();
+ gtk_window_set_title (GTK_WINDOW (dlg), _("Encoders"));
+ gtk_window_set_transient_for (GTK_WINDOW (dlg), GTK_WINDOW (current_ctx->converter));
+ g_signal_connect ((gpointer)lookup_widget (dlg, "add"), "clicked", G_CALLBACK (on_encoder_preset_add), NULL);
+ g_signal_connect ((gpointer)lookup_widget (dlg, "remove"), "clicked", G_CALLBACK (on_encoder_preset_remove), NULL);
+ g_signal_connect ((gpointer)lookup_widget (dlg, "edit"), "clicked", G_CALLBACK (on_encoder_preset_edit), NULL);
+
+ GtkWidget *list = lookup_widget (dlg, "presets");
+ GtkCellRenderer *title_cell = gtk_cell_renderer_text_new ();
+ GtkTreeViewColumn *col = gtk_tree_view_column_new_with_attributes (_("Title"), title_cell, "text", 0, NULL);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (list), GTK_TREE_VIEW_COLUMN (col));
+ GtkListStore *mdl = gtk_list_store_new (1, G_TYPE_STRING);
+ gtk_tree_view_set_model (GTK_TREE_VIEW (list), GTK_TREE_MODEL (mdl));
+ fill_presets (mdl, (ddb_preset_t *)converter_plugin->encoder_preset_get_list ());
+ int curr = deadbeef->conf_get_int ("converter.encoder_preset", -1);
+ if (curr != -1) {
+ GtkTreePath *path = gtk_tree_path_new_from_indices (curr, -1);
+ if (path && gtk_tree_path_get_depth (path) > 0) {
+ gtk_tree_view_set_cursor (GTK_TREE_VIEW (list), path, col, FALSE);
+ gtk_tree_path_free (path);
+ }
+ }
+ gtk_dialog_run (GTK_DIALOG (dlg));
+ gtk_widget_destroy (dlg);
+}
+
+///// dsp preset gui
+
+void
+fill_dsp_plugin_list (GtkListStore *mdl) {
+ struct DB_dsp_s **dsp = deadbeef->plug_get_dsp_list ();
+ int i;
+ for (i = 0; dsp[i]; i++) {
+ GtkTreeIter iter;
+ gtk_list_store_append (mdl, &iter);
+ gtk_list_store_set (mdl, &iter, 0, dsp[i]->plugin.name, -1);
+ }
+}
+
+void
+fill_dsp_preset_chain (GtkListStore *mdl) {
+ ddb_dsp_context_t *dsp = current_ctx->current_dsp_preset->chain;
+ while (dsp) {
+ GtkTreeIter iter;
+ gtk_list_store_append (mdl, &iter);
+ gtk_list_store_set (mdl, &iter, 0, dsp->plugin->plugin.name, -1);
+ dsp = dsp->next;
+ }
+}
+
+void
+on_dsp_preset_add_plugin_clicked (GtkButton *button,
+ gpointer user_data)
+{
+ GtkWidget *dlg = create_select_dsp_plugin ();
+ GtkWidget *toplevel = gtk_widget_get_toplevel (GTK_WIDGET (button));
+ gtk_window_set_transient_for (GTK_WINDOW (dlg), GTK_WINDOW (toplevel));
+ gtk_window_set_title (GTK_WINDOW (dlg), _("Add plugin to DSP chain"));
+
+ GtkComboBox *combo;
+ // fill encoder presets
+ combo = GTK_COMBO_BOX (lookup_widget (dlg, "plugin"));
+ GtkListStore *mdl = GTK_LIST_STORE (gtk_combo_box_get_model (combo));
+ fill_dsp_plugin_list (mdl);
+ gtk_combo_box_set_active (combo, deadbeef->conf_get_int ("converter.last_selected_dsp", 0));
+
+ int r = gtk_dialog_run (GTK_DIALOG (dlg));
+ if (r == GTK_RESPONSE_OK) {
+ // create new instance of the selected plugin
+ int idx = gtk_combo_box_get_active (combo);
+ struct DB_dsp_s **dsp = deadbeef->plug_get_dsp_list ();
+ int i;
+ ddb_dsp_context_t *inst = NULL;
+ for (i = 0; dsp[i]; i++) {
+ if (i == idx) {
+ inst = dsp[i]->open ();
+ break;
+ }
+ }
+ if (inst) {
+ // append to DSP chain
+ ddb_dsp_context_t *tail = current_ctx->current_dsp_preset->chain;
+ while (tail && tail->next) {
+ tail = tail->next;
+ }
+ if (tail) {
+ tail->next = inst;
+ }
+ else {
+ current_ctx->current_dsp_preset->chain = inst;
+ }
+
+ // reinit list of instances
+ GtkWidget *list = lookup_widget (toplevel, "plugins");
+ GtkListStore *mdl = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW(list)));
+ gtk_list_store_clear (mdl);
+ fill_dsp_preset_chain (mdl);
+ }
+ else {
+ fprintf (stderr, "converter: failed to add DSP plugin to chain\n");
+ }
+ }
+ gtk_widget_destroy (dlg);
+}
+
+
+void
+on_dsp_preset_remove_plugin_clicked (GtkButton *button,
+ gpointer user_data)
+{
+ GtkWidget *toplevel = gtk_widget_get_toplevel (GTK_WIDGET (button));
+ GtkWidget *list = lookup_widget (toplevel, "plugins");
+ GtkTreePath *path;
+ GtkTreeViewColumn *col;
+ gtk_tree_view_get_cursor (GTK_TREE_VIEW (list), &path, &col);
+ if (!path || !col) {
+ // nothing selected
+ return;
+ }
+ int *indices = gtk_tree_path_get_indices (path);
+ int idx = *indices;
+ g_free (indices);
+ if (idx == -1) {
+ return;
+ }
+
+ ddb_dsp_context_t *p = current_ctx->current_dsp_preset->chain;
+ ddb_dsp_context_t *prev = NULL;
+ int i = idx;
+ while (p && i--) {
+ prev = p;
+ p = p->next;
+ }
+ if (p) {
+ if (prev) {
+ prev->next = p->next;
+ }
+ else {
+ current_ctx->current_dsp_preset->chain = p->next;
+ }
+ p->plugin->close (p);
+ GtkListStore *mdl = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW(list)));
+ gtk_list_store_clear (mdl);
+ fill_dsp_preset_chain (mdl);
+ path = gtk_tree_path_new_from_indices (idx, -1);
+ gtk_tree_view_set_cursor (GTK_TREE_VIEW (list), path, col, FALSE);
+ gtk_tree_path_free (path);
+ }
+}
+
+static ddb_dsp_context_t *current_dsp_context = NULL;
+
+void
+dsp_ctx_set_param (const char *key, const char *value) {
+ current_dsp_context->plugin->set_param (current_dsp_context, atoi (key), value);
+}
+
+void
+dsp_ctx_get_param (const char *key, char *value, int len, const char *def) {
+ strncpy (value, def, len);
+ current_dsp_context->plugin->get_param (current_dsp_context, atoi (key), value, len);
+}
+
+void
+on_dsp_preset_plugin_configure_clicked (GtkButton *button,
+ gpointer user_data)
+{
+ GtkWidget *toplevel = gtk_widget_get_toplevel (GTK_WIDGET (button));
+ GtkWidget *list = lookup_widget (toplevel, "plugins");
+ GtkTreePath *path;
+ GtkTreeViewColumn *col;
+ gtk_tree_view_get_cursor (GTK_TREE_VIEW (list), &path, &col);
+ if (!path || !col) {
+ // nothing selected
+ return;
+ }
+ int *indices = gtk_tree_path_get_indices (path);
+ int idx = *indices;
+ g_free (indices);
+ if (idx == -1) {
+ return;
+ }
+ ddb_dsp_context_t *p = current_ctx->current_dsp_preset->chain;
+ int i = idx;
+ while (p && i--) {
+ p = p->next;
+ }
+ if (!p || !p->plugin->configdialog) {
+ return;
+ }
+ current_dsp_context = p;
+ ddb_dialog_t conf = {
+ .title = p->plugin->plugin.name,
+ .layout = p->plugin->configdialog,
+ .set_param = dsp_ctx_set_param,
+ .get_param = dsp_ctx_get_param,
+ };
+ gtkui_plugin->gui.run_dialog (&conf, 0, NULL, NULL);
+ current_dsp_context = NULL;
+}
+
+void
+on_dsp_preset_plugin_up_clicked (GtkButton *button,
+ gpointer user_data)
+{
+
+}
+
+
+void
+on_dsp_preset_plugin_down_clicked (GtkButton *button,
+ gpointer user_data)
+{
+
+}
+
+
+int
+edit_dsp_preset (const char *title, GtkWidget *toplevel, int overwrite) {
+ int r = GTK_RESPONSE_CANCEL;
+
+ GtkWidget *dlg = create_dsppreset_editor ();
+ gtk_dialog_set_default_response (GTK_DIALOG (dlg), GTK_RESPONSE_OK);
+ gtk_window_set_transient_for (GTK_WINDOW (dlg), GTK_WINDOW (toplevel));
+ gtk_window_set_title (GTK_WINDOW (dlg), title);
+
+
+ // title
+ if (current_ctx->current_dsp_preset->title) {
+ gtk_entry_set_text (GTK_ENTRY (lookup_widget (dlg, "title")), current_ctx->current_dsp_preset->title);
+ }
+
+ {
+ GtkWidget *list = lookup_widget (dlg, "plugins");
+ GtkCellRenderer *title_cell = gtk_cell_renderer_text_new ();
+ GtkTreeViewColumn *col = gtk_tree_view_column_new_with_attributes (_("Plugin"), title_cell, "text", 0, NULL);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (list), GTK_TREE_VIEW_COLUMN (col));
+ GtkListStore *mdl = gtk_list_store_new (1, G_TYPE_STRING);
+ gtk_tree_view_set_model (GTK_TREE_VIEW (list), GTK_TREE_MODEL (mdl));
+
+ fill_dsp_preset_chain (mdl);
+ }
+
+ for (;;) {
+ r = gtk_dialog_run (GTK_DIALOG (dlg));
+
+ if (r == GTK_RESPONSE_OK) {
+ if (current_ctx->current_dsp_preset->title) {
+ free (current_ctx->current_dsp_preset->title);
+ }
+ current_ctx->current_dsp_preset->title = strdup (gtk_entry_get_text (GTK_ENTRY (lookup_widget (dlg, "title"))));
+ int err = converter_plugin->dsp_preset_save (current_ctx->current_dsp_preset, overwrite);
+ if (err < 0) {
+ GtkWidget *warndlg = gtk_message_dialog_new (GTK_WINDOW (gtkui_plugin->get_mainwin ()), GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("Failed to save DSP preset"));
+ gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (warndlg), err == -1 ? _("Check preset folder permissions, try to pick different title, or free up some disk space") : _("Preset with the same name already exists. Try to pick another title."));
+ gtk_window_set_title (GTK_WINDOW (warndlg), _("Error"));
+
+ gtk_window_set_transient_for (GTK_WINDOW (warndlg), GTK_WINDOW (dlg));
+ /*int response = */gtk_dialog_run (GTK_DIALOG (warndlg));
+ gtk_widget_destroy (warndlg);
+ continue;
+ }
+
+ }
+
+ break;
+ }
+
+ gtk_widget_destroy (dlg);
+ return r;
+}
+
+void
+refresh_dsp_lists (GtkComboBox *combo, GtkTreeView *list) {
+ // presets list view
+ GtkListStore *mdl = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (list)));
+
+ GtkTreePath *path;
+ GtkTreeViewColumn *col;
+ int idx = -1;
+
+ gtk_tree_view_get_cursor (GTK_TREE_VIEW (list), &path, &col);
+ if (path && col) {
+ int *indices = gtk_tree_path_get_indices (path);
+ idx = *indices;
+ g_free (indices);
+ }
+
+ gtk_list_store_clear (mdl);
+ fill_presets (mdl, (ddb_preset_t *)converter_plugin->dsp_preset_get_list ());
+ if (idx != -1) {
+ path = gtk_tree_path_new_from_indices (idx, -1);
+ gtk_tree_view_set_cursor (GTK_TREE_VIEW (list), path, col, FALSE);
+ gtk_tree_path_free (path);
+ }
+
+ // presets combo box
+ int act = gtk_combo_box_get_active (combo);
+ mdl = GTK_LIST_STORE (gtk_combo_box_get_model (combo));
+ gtk_list_store_clear (mdl);
+ GtkTreeIter iter;
+ gtk_list_store_append (mdl, &iter);
+ gtk_list_store_set (mdl, &iter, 0, "Pass through", -1);
+ fill_presets (mdl, (ddb_preset_t *)converter_plugin->dsp_preset_get_list ());
+ gtk_combo_box_set_active (combo, act);
+}
+
+
+void
+on_dsp_preset_add (GtkButton *button,
+ gpointer user_data)
+{
+
+ current_ctx->current_dsp_preset = converter_plugin->dsp_preset_alloc ();
+
+ GtkWidget *toplevel = gtk_widget_get_toplevel (GTK_WIDGET (button));
+
+ if (GTK_RESPONSE_OK == edit_dsp_preset (_("New DSP Preset"), toplevel, 0)) {
+ converter_plugin->dsp_preset_append (current_ctx->current_dsp_preset);
+ GtkComboBox *combo = GTK_COMBO_BOX (lookup_widget (current_ctx->converter, "dsp_preset"));
+ GtkWidget *list = lookup_widget (toplevel, "presets");
+ refresh_dsp_lists (combo, GTK_TREE_VIEW (list));
+ }
+ else {
+ converter_plugin->dsp_preset_free (current_ctx->current_dsp_preset);
+ }
+
+ current_ctx->current_dsp_preset = NULL;
+}
+
+void
+on_dsp_preset_remove (GtkButton *button,
+ gpointer user_data)
+{
+ GtkWidget *toplevel = gtk_widget_get_toplevel (GTK_WIDGET (button));
+ GtkWidget *list = lookup_widget (toplevel, "presets");
+ GtkTreePath *path;
+ GtkTreeViewColumn *col;
+ gtk_tree_view_get_cursor (GTK_TREE_VIEW (list), &path, &col);
+ if (!path || !col) {
+ // nothing selected
+ return;
+ }
+ int *indices = gtk_tree_path_get_indices (path);
+ int idx = *indices;
+ g_free (indices);
+
+ ddb_dsp_preset_t *p = converter_plugin->dsp_preset_get_for_idx (idx);
+ if (!p) {
+ return;
+ }
+
+ GtkWidget *dlg = gtk_message_dialog_new (GTK_WINDOW (gtkui_plugin->get_mainwin ()), GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING, GTK_BUTTONS_YES_NO, _("Remove preset"));
+ gtk_window_set_transient_for (GTK_WINDOW (dlg), GTK_WINDOW (toplevel));
+ gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dlg), _("This action will delete the selected preset. Are you sure?"));
+ gtk_window_set_title (GTK_WINDOW (dlg), _("Warning"));
+
+ int response = gtk_dialog_run (GTK_DIALOG (dlg));
+ gtk_widget_destroy (dlg);
+ if (response == GTK_RESPONSE_YES) {
+ char path[1024];
+ if (snprintf (path, sizeof (path), "%s/presets/dsp/%s.txt", deadbeef->get_config_dir (), p->title) > 0) {
+ unlink (path);
+ }
+
+ converter_plugin->dsp_preset_remove (p);
+ converter_plugin->dsp_preset_free (p);
+
+ GtkComboBox *combo = GTK_COMBO_BOX (lookup_widget (current_ctx->converter, "dsp_preset"));
+ refresh_dsp_lists (combo, GTK_TREE_VIEW (list));
+ }
+}
+
+void
+on_dsp_preset_edit (GtkButton *button,
+ gpointer user_data)
+{
+ GtkWidget *toplevel = gtk_widget_get_toplevel (GTK_WIDGET (button));
+
+ GtkWidget *list = lookup_widget (toplevel, "presets");
+ GtkTreePath *path;
+ GtkTreeViewColumn *col;
+ gtk_tree_view_get_cursor (GTK_TREE_VIEW (list), &path, &col);
+ if (!path || !col) {
+ // nothing selected
+ return;
+ }
+ int *indices = gtk_tree_path_get_indices (path);
+ int idx = *indices;
+ g_free (indices);
+ if (idx == -1) {
+ return;
+ }
+ if (idx == 0) {
+ return;
+ }
+
+ ddb_dsp_preset_t *p = converter_plugin->dsp_preset_get_for_idx (idx);
+ if (!p) {
+ return;
+ }
+
+ current_ctx->current_dsp_preset = converter_plugin->dsp_preset_alloc ();
+ converter_plugin->dsp_preset_copy (current_ctx->current_dsp_preset, p);
+
+ int r = edit_dsp_preset (_("Edit DSP Preset"), toplevel, 1);
+ if (r == GTK_RESPONSE_OK) {
+ // replace preset
+ converter_plugin->dsp_preset_replace (p, current_ctx->current_dsp_preset);
+ converter_plugin->dsp_preset_free (p);
+ GtkComboBox *combo = GTK_COMBO_BOX (lookup_widget (current_ctx->converter, "dsp_preset"));
+ refresh_dsp_lists (combo, GTK_TREE_VIEW (list));
+ }
+ else {
+ converter_plugin->dsp_preset_free (current_ctx->current_dsp_preset);
+ }
+
+ current_ctx->current_dsp_preset = NULL;
+}
+
+void
+on_edit_dsp_presets_clicked (GtkButton *button,
+ gpointer user_data)
+{
+ GtkWidget *dlg = create_preset_list ();
+ gtk_window_set_title (GTK_WINDOW (dlg), _("DSP Presets"));
+ gtk_window_set_transient_for (GTK_WINDOW (dlg), GTK_WINDOW (current_ctx->converter));
+ g_signal_connect ((gpointer)lookup_widget (dlg, "add"), "clicked", G_CALLBACK (on_dsp_preset_add), NULL);
+ g_signal_connect ((gpointer)lookup_widget (dlg, "remove"), "clicked", G_CALLBACK (on_dsp_preset_remove), NULL);
+ g_signal_connect ((gpointer)lookup_widget (dlg, "edit"), "clicked", G_CALLBACK (on_dsp_preset_edit), NULL);
+
+ GtkWidget *list = lookup_widget (dlg, "presets");
+ GtkCellRenderer *title_cell = gtk_cell_renderer_text_new ();
+ GtkTreeViewColumn *col = gtk_tree_view_column_new_with_attributes (_("Title"), title_cell, "text", 0, NULL);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (list), GTK_TREE_VIEW_COLUMN (col));
+ GtkListStore *mdl = gtk_list_store_new (1, G_TYPE_STRING);
+ gtk_tree_view_set_model (GTK_TREE_VIEW (list), GTK_TREE_MODEL (mdl));
+ fill_presets (mdl, (ddb_preset_t *)converter_plugin->dsp_preset_get_list ());
+ int curr = deadbeef->conf_get_int ("converter.dsp_preset", -1);
+ if (curr >= 0) {
+ GtkTreePath *path = gtk_tree_path_new_from_indices (curr, -1);
+ gtk_tree_view_set_cursor (GTK_TREE_VIEW (list), path, col, FALSE);
+ gtk_tree_path_free (path);
+ }
+ gtk_dialog_run (GTK_DIALOG (dlg));
+ gtk_widget_destroy (dlg);
+}
+
+
+void
+on_converter_output_format_changed (GtkComboBox *combobox,
+ gpointer user_data)
+{
+ int idx = gtk_combo_box_get_active (combobox);
+ deadbeef->conf_set_int ("converter.output_format", idx);
+}
+
+GtkWidget*
+title_formatting_help_link_create (gchar *widget_name, gchar *string1, gchar *string2,
+ gint int1, gint int2)
+{
+ GtkWidget *link = gtk_link_button_new_with_label ("http://sourceforge.net/apps/mediawiki/deadbeef/index.php?title=Title_Formatting", "Help");
+ return link;
+}
+
+GtkWidget*
+encoder_cmdline_help_link_create (gchar *widget_name, gchar *string1, gchar *string2,
+ gint int1, gint int2)
+{
+ GtkWidget *link = gtk_link_button_new_with_label ("http://sourceforge.net/apps/mediawiki/deadbeef/index.php?title=Encoder_Command_Line", "Help");
+ return link;
+}
+
+static DB_plugin_action_t convert_action = {
+ .title = "Convert",
+ .name = "convert",
+ .flags = DB_ACTION_CAN_MULTIPLE_TRACKS | DB_ACTION_ALLOW_MULTIPLE_TRACKS | DB_ACTION_SINGLE_TRACK,
+ .callback = converter_show,
+ .next = NULL
+};
+
+static DB_plugin_action_t *
+convgui_get_actions (DB_playItem_t *it)
+{
+ return &convert_action;
+}
+
+int
+convgui_connect (void) {
+ gtkui_plugin = (ddb_gtkui_t *)deadbeef->plug_get_for_id ("gtkui");
+ converter_plugin = (ddb_converter_t *)deadbeef->plug_get_for_id ("converter");
+ if (!gtkui_plugin || !converter_plugin) {
+ return -1;
+ }
+ return 0;
+}
+
+DB_misc_t plugin = {
+ DB_PLUGIN_SET_API_VERSION
+ .plugin.version_major = 1,
+ .plugin.version_minor = 0,
+ .plugin.type = DB_PLUGIN_MISC,
+ .plugin.name = "Converter GTK UI",
+ .plugin.descr = "GTK2 User interface for the Converter plugin\n"
+ "Usage:\n"
+ "· select some tracks in playlist\n"
+ "· right click\n"
+ "· select «Convert»",
+ .plugin.copyright =
+ "Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>\n"
+ "\n"
+ "This program is free software; you can redistribute it and/or\n"
+ "modify it under the terms of the GNU General Public License\n"
+ "as published by the Free Software Foundation; either version 2\n"
+ "of the License, or (at your option) any later version.\n"
+ "\n"
+ "This program is distributed in the hope that it will be useful,\n"
+ "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+ "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+ "GNU General Public License for more details.\n"
+ "\n"
+ "You should have received a copy of the GNU General Public License\n"
+ "along with this program; if not, write to the Free Software\n"
+ "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n"
+ ,
+ .plugin.website = "http://deadbeef.sf.net",
+ .plugin.get_actions = convgui_get_actions,
+ .plugin.connect = convgui_connect,
+};
+
+DB_plugin_t *
+converter_gtkui_load (DB_functions_t *api) {
+ deadbeef = api;
+ return DB_PLUGIN (&plugin);
+}
+
diff --git a/plugins/converter/interface.c b/plugins/converter/interface.c
new file mode 100644
index 00000000..5045a79d
--- /dev/null
+++ b/plugins/converter/interface.c
@@ -0,0 +1,890 @@
+/*
+ * DO NOT EDIT THIS FILE - it is generated by Glade.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdio.h>
+
+#include <gdk/gdkkeysyms.h>
+#include <gtk/gtk.h>
+
+#include "callbacks.h"
+#include "interface.h"
+#include "support.h"
+
+#define GLADE_HOOKUP_OBJECT(component,widget,name) \
+ g_object_set_data_full (G_OBJECT (component), name, \
+ gtk_widget_ref (widget), (GDestroyNotify) gtk_widget_unref)
+
+#define GLADE_HOOKUP_OBJECT_NO_REF(component,widget,name) \
+ g_object_set_data (G_OBJECT (component), name, widget)
+
+GtkWidget*
+create_converterdlg (void)
+{
+ GtkWidget *converterdlg;
+ GtkWidget *dialog_vbox6;
+ GtkWidget *vbox26;
+ GtkWidget *hbox67;
+ GtkWidget *label103;
+ GtkWidget *hbox68;
+ GtkWidget *output_folder;
+ GtkWidget *converter_output_browse;
+ GtkWidget *hbox100;
+ GtkWidget *label122;
+ GtkWidget *hbox101;
+ GtkWidget *output_file;
+ GtkWidget *custom6;
+ GtkWidget *hbox69;
+ GtkWidget *label104;
+ GtkWidget *hbox90;
+ GtkWidget *encoder;
+ GtkWidget *edit_encoder_presets;
+ GtkWidget *image469;
+ GtkWidget *hbox86;
+ GtkWidget *label114;
+ GtkWidget *hbox91;
+ GtkWidget *dsp_preset;
+ GtkWidget *edit_dsp_presets;
+ GtkWidget *image470;
+ GtkWidget *hbox88;
+ GtkWidget *label116;
+ GtkObject *numthreads_adj;
+ GtkWidget *numthreads;
+ GtkWidget *hbox89;
+ GtkWidget *label117;
+ GtkWidget *output_format;
+ GtkWidget *hbox99;
+ GtkWidget *label121;
+ GtkWidget *overwrite_action;
+ GtkWidget *preserve_folders;
+ GtkWidget *hbox102;
+ GtkWidget *preserve_root_folder;
+ GtkWidget *preserve_folder_browse;
+ GtkWidget *dialog_action_area5;
+ GtkWidget *converter_cancel;
+ GtkWidget *converter_ok;
+ GtkTooltips *tooltips;
+
+ tooltips = gtk_tooltips_new ();
+
+ converterdlg = gtk_dialog_new ();
+ gtk_window_set_title (GTK_WINDOW (converterdlg), _("Converter"));
+ gtk_window_set_modal (GTK_WINDOW (converterdlg), TRUE);
+ gtk_window_set_destroy_with_parent (GTK_WINDOW (converterdlg), TRUE);
+ gtk_window_set_type_hint (GTK_WINDOW (converterdlg), GDK_WINDOW_TYPE_HINT_DIALOG);
+ gtk_dialog_set_has_separator (GTK_DIALOG (converterdlg), FALSE);
+
+ dialog_vbox6 = GTK_DIALOG (converterdlg)->vbox;
+ gtk_widget_show (dialog_vbox6);
+
+ vbox26 = gtk_vbox_new (FALSE, 8);
+ gtk_widget_show (vbox26);
+ gtk_box_pack_start (GTK_BOX (dialog_vbox6), vbox26, TRUE, TRUE, 0);
+ gtk_container_set_border_width (GTK_CONTAINER (vbox26), 12);
+
+ hbox67 = gtk_hbox_new (FALSE, 8);
+ gtk_widget_show (hbox67);
+ gtk_box_pack_start (GTK_BOX (vbox26), hbox67, FALSE, TRUE, 0);
+
+ label103 = gtk_label_new (_("Output folder:"));
+ gtk_widget_show (label103);
+ gtk_box_pack_start (GTK_BOX (hbox67), label103, FALSE, FALSE, 0);
+
+ hbox68 = gtk_hbox_new (FALSE, 0);
+ gtk_widget_show (hbox68);
+ gtk_box_pack_start (GTK_BOX (hbox67), hbox68, TRUE, TRUE, 0);
+
+ output_folder = gtk_entry_new ();
+ gtk_widget_show (output_folder);
+ gtk_box_pack_start (GTK_BOX (hbox68), output_folder, TRUE, TRUE, 0);
+ gtk_entry_set_invisible_char (GTK_ENTRY (output_folder), 9679);
+
+ converter_output_browse = gtk_button_new_with_mnemonic (_("..."));
+ gtk_widget_show (converter_output_browse);
+ gtk_box_pack_start (GTK_BOX (hbox68), converter_output_browse, FALSE, FALSE, 0);
+
+ hbox100 = gtk_hbox_new (FALSE, 8);
+ gtk_widget_show (hbox100);
+ gtk_box_pack_start (GTK_BOX (vbox26), hbox100, TRUE, TRUE, 0);
+
+ label122 = gtk_label_new (_("Output file name:"));
+ gtk_widget_show (label122);
+ gtk_box_pack_start (GTK_BOX (hbox100), label122, FALSE, FALSE, 0);
+
+ hbox101 = gtk_hbox_new (FALSE, 0);
+ gtk_widget_show (hbox101);
+ gtk_box_pack_start (GTK_BOX (hbox100), hbox101, TRUE, TRUE, 0);
+
+ output_file = gtk_entry_new ();
+ gtk_widget_show (output_file);
+ gtk_box_pack_start (GTK_BOX (hbox101), output_file, TRUE, TRUE, 0);
+ gtk_tooltips_set_tip (tooltips, output_file, _("Extension (e.g. .mp3) will be appended automatically.\nLeave the field empty for default (%a - %t)."), NULL);
+ gtk_entry_set_invisible_char (GTK_ENTRY (output_file), 8226);
+
+ custom6 = title_formatting_help_link_create ("custom6", "", "", 0, 0);
+ gtk_widget_show (custom6);
+ gtk_box_pack_start (GTK_BOX (hbox101), custom6, TRUE, TRUE, 0);
+ GTK_WIDGET_UNSET_FLAGS (custom6, GTK_CAN_FOCUS);
+ GTK_WIDGET_UNSET_FLAGS (custom6, GTK_CAN_DEFAULT);
+
+ hbox69 = gtk_hbox_new (FALSE, 8);
+ gtk_widget_show (hbox69);
+ gtk_box_pack_start (GTK_BOX (vbox26), hbox69, FALSE, FALSE, 0);
+
+ label104 = gtk_label_new (_("Encoder:"));
+ gtk_widget_show (label104);
+ gtk_box_pack_start (GTK_BOX (hbox69), label104, FALSE, FALSE, 0);
+
+ hbox90 = gtk_hbox_new (FALSE, 0);
+ gtk_widget_show (hbox90);
+ gtk_box_pack_start (GTK_BOX (hbox69), hbox90, TRUE, TRUE, 0);
+
+ encoder = gtk_combo_box_new_text ();
+ gtk_widget_show (encoder);
+ gtk_box_pack_start (GTK_BOX (hbox90), encoder, TRUE, TRUE, 0);
+
+ edit_encoder_presets = gtk_button_new ();
+ gtk_widget_show (edit_encoder_presets);
+ gtk_box_pack_start (GTK_BOX (hbox90), edit_encoder_presets, FALSE, FALSE, 0);
+
+ image469 = gtk_image_new_from_stock ("gtk-edit", GTK_ICON_SIZE_BUTTON);
+ gtk_widget_show (image469);
+ gtk_container_add (GTK_CONTAINER (edit_encoder_presets), image469);
+
+ hbox86 = gtk_hbox_new (FALSE, 8);
+ gtk_widget_show (hbox86);
+ gtk_box_pack_start (GTK_BOX (vbox26), hbox86, FALSE, TRUE, 0);
+
+ label114 = gtk_label_new (_("DSP preset:"));
+ gtk_widget_show (label114);
+ gtk_box_pack_start (GTK_BOX (hbox86), label114, FALSE, FALSE, 0);
+
+ hbox91 = gtk_hbox_new (FALSE, 0);
+ gtk_widget_show (hbox91);
+ gtk_box_pack_start (GTK_BOX (hbox86), hbox91, TRUE, TRUE, 0);
+
+ dsp_preset = gtk_combo_box_new_text ();
+ gtk_widget_show (dsp_preset);
+ gtk_box_pack_start (GTK_BOX (hbox91), dsp_preset, TRUE, TRUE, 0);
+
+ edit_dsp_presets = gtk_button_new ();
+ gtk_widget_show (edit_dsp_presets);
+ gtk_box_pack_start (GTK_BOX (hbox91), edit_dsp_presets, FALSE, FALSE, 0);
+
+ image470 = gtk_image_new_from_stock ("gtk-edit", GTK_ICON_SIZE_BUTTON);
+ gtk_widget_show (image470);
+ gtk_container_add (GTK_CONTAINER (edit_dsp_presets), image470);
+
+ hbox88 = gtk_hbox_new (FALSE, 8);
+ gtk_box_pack_start (GTK_BOX (vbox26), hbox88, FALSE, TRUE, 0);
+
+ label116 = gtk_label_new (_("Number of threads:"));
+ gtk_widget_show (label116);
+ gtk_box_pack_start (GTK_BOX (hbox88), label116, FALSE, FALSE, 0);
+
+ numthreads_adj = gtk_adjustment_new (1, 0, 100, 1, 10, 0);
+ numthreads = gtk_spin_button_new (GTK_ADJUSTMENT (numthreads_adj), 1, 0);
+ gtk_widget_show (numthreads);
+ gtk_box_pack_start (GTK_BOX (hbox88), numthreads, TRUE, TRUE, 0);
+
+ hbox89 = gtk_hbox_new (FALSE, 8);
+ gtk_widget_show (hbox89);
+ gtk_box_pack_start (GTK_BOX (vbox26), hbox89, FALSE, TRUE, 0);
+
+ label117 = gtk_label_new (_("Output sample format:"));
+ gtk_widget_show (label117);
+ gtk_box_pack_start (GTK_BOX (hbox89), label117, FALSE, FALSE, 0);
+
+ output_format = gtk_combo_box_new_text ();
+ gtk_widget_show (output_format);
+ gtk_box_pack_start (GTK_BOX (hbox89), output_format, TRUE, TRUE, 0);
+ gtk_combo_box_append_text (GTK_COMBO_BOX (output_format), _("Keep source format"));
+ gtk_combo_box_append_text (GTK_COMBO_BOX (output_format), _("8 bit signed int"));
+ gtk_combo_box_append_text (GTK_COMBO_BOX (output_format), _("16 bit signed int"));
+ gtk_combo_box_append_text (GTK_COMBO_BOX (output_format), _("24 bit signed int"));
+ gtk_combo_box_append_text (GTK_COMBO_BOX (output_format), _("32 bit signed int"));
+ gtk_combo_box_append_text (GTK_COMBO_BOX (output_format), _("32 bit float"));
+
+ hbox99 = gtk_hbox_new (FALSE, 8);
+ gtk_widget_show (hbox99);
+ gtk_box_pack_start (GTK_BOX (vbox26), hbox99, TRUE, TRUE, 0);
+
+ label121 = gtk_label_new (_("When file exists:"));
+ gtk_widget_show (label121);
+ gtk_box_pack_start (GTK_BOX (hbox99), label121, FALSE, FALSE, 0);
+
+ overwrite_action = gtk_combo_box_new_text ();
+ gtk_widget_show (overwrite_action);
+ gtk_box_pack_start (GTK_BOX (hbox99), overwrite_action, TRUE, TRUE, 0);
+ gtk_combo_box_append_text (GTK_COMBO_BOX (overwrite_action), _("Prompt"));
+ gtk_combo_box_append_text (GTK_COMBO_BOX (overwrite_action), _("Overwrite"));
+
+ preserve_folders = gtk_check_button_new_with_mnemonic (_("Preserve folder structure, starting from:"));
+ gtk_box_pack_start (GTK_BOX (vbox26), preserve_folders, FALSE, FALSE, 0);
+
+ hbox102 = gtk_hbox_new (FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (vbox26), hbox102, TRUE, TRUE, 0);
+
+ preserve_root_folder = gtk_entry_new ();
+ gtk_widget_show (preserve_root_folder);
+ gtk_box_pack_start (GTK_BOX (hbox102), preserve_root_folder, TRUE, TRUE, 0);
+ gtk_entry_set_invisible_char (GTK_ENTRY (preserve_root_folder), 8226);
+
+ preserve_folder_browse = gtk_button_new_with_mnemonic (_("..."));
+ gtk_widget_show (preserve_folder_browse);
+ gtk_box_pack_start (GTK_BOX (hbox102), preserve_folder_browse, FALSE, FALSE, 0);
+
+ dialog_action_area5 = GTK_DIALOG (converterdlg)->action_area;
+ gtk_widget_show (dialog_action_area5);
+ gtk_button_box_set_layout (GTK_BUTTON_BOX (dialog_action_area5), GTK_BUTTONBOX_END);
+
+ converter_cancel = gtk_button_new_from_stock ("gtk-cancel");
+ gtk_widget_show (converter_cancel);
+ gtk_dialog_add_action_widget (GTK_DIALOG (converterdlg), converter_cancel, GTK_RESPONSE_CANCEL);
+ GTK_WIDGET_SET_FLAGS (converter_cancel, GTK_CAN_DEFAULT);
+
+ converter_ok = gtk_button_new_from_stock ("gtk-ok");
+ gtk_widget_show (converter_ok);
+ gtk_dialog_add_action_widget (GTK_DIALOG (converterdlg), converter_ok, GTK_RESPONSE_OK);
+ GTK_WIDGET_SET_FLAGS (converter_ok, GTK_CAN_DEFAULT);
+
+ g_signal_connect ((gpointer) output_folder, "changed",
+ G_CALLBACK (on_output_folder_changed),
+ NULL);
+ g_signal_connect ((gpointer) converter_output_browse, "clicked",
+ G_CALLBACK (on_converter_output_browse_clicked),
+ NULL);
+ g_signal_connect ((gpointer) output_file, "changed",
+ G_CALLBACK (on_output_file_changed),
+ NULL);
+ g_signal_connect ((gpointer) encoder, "changed",
+ G_CALLBACK (on_converter_encoder_changed),
+ NULL);
+ g_signal_connect ((gpointer) edit_encoder_presets, "clicked",
+ G_CALLBACK (on_edit_encoder_presets_clicked),
+ NULL);
+ g_signal_connect ((gpointer) dsp_preset, "changed",
+ G_CALLBACK (on_converter_dsp_preset_changed),
+ NULL);
+ g_signal_connect ((gpointer) edit_dsp_presets, "clicked",
+ G_CALLBACK (on_edit_dsp_presets_clicked),
+ NULL);
+ g_signal_connect ((gpointer) numthreads, "changed",
+ G_CALLBACK (on_numthreads_changed),
+ NULL);
+ g_signal_connect ((gpointer) output_format, "changed",
+ G_CALLBACK (on_converter_output_format_changed),
+ NULL);
+ g_signal_connect ((gpointer) overwrite_action, "changed",
+ G_CALLBACK (on_overwrite_action_changed),
+ NULL);
+ g_signal_connect ((gpointer) preserve_folders, "toggled",
+ G_CALLBACK (on_preserve_folders_toggled),
+ NULL);
+ g_signal_connect ((gpointer) preserve_root_folder, "changed",
+ G_CALLBACK (on_preserve_root_folder_changed),
+ NULL);
+ g_signal_connect ((gpointer) preserve_folder_browse, "clicked",
+ G_CALLBACK (on_preserve_folder_browse_clicked),
+ NULL);
+
+ /* Store pointers to all widgets, for use by lookup_widget(). */
+ GLADE_HOOKUP_OBJECT_NO_REF (converterdlg, converterdlg, "converterdlg");
+ GLADE_HOOKUP_OBJECT_NO_REF (converterdlg, dialog_vbox6, "dialog_vbox6");
+ GLADE_HOOKUP_OBJECT (converterdlg, vbox26, "vbox26");
+ GLADE_HOOKUP_OBJECT (converterdlg, hbox67, "hbox67");
+ GLADE_HOOKUP_OBJECT (converterdlg, label103, "label103");
+ GLADE_HOOKUP_OBJECT (converterdlg, hbox68, "hbox68");
+ GLADE_HOOKUP_OBJECT (converterdlg, output_folder, "output_folder");
+ GLADE_HOOKUP_OBJECT (converterdlg, converter_output_browse, "converter_output_browse");
+ GLADE_HOOKUP_OBJECT (converterdlg, hbox100, "hbox100");
+ GLADE_HOOKUP_OBJECT (converterdlg, label122, "label122");
+ GLADE_HOOKUP_OBJECT (converterdlg, hbox101, "hbox101");
+ GLADE_HOOKUP_OBJECT (converterdlg, output_file, "output_file");
+ GLADE_HOOKUP_OBJECT (converterdlg, custom6, "custom6");
+ GLADE_HOOKUP_OBJECT (converterdlg, hbox69, "hbox69");
+ GLADE_HOOKUP_OBJECT (converterdlg, label104, "label104");
+ GLADE_HOOKUP_OBJECT (converterdlg, hbox90, "hbox90");
+ GLADE_HOOKUP_OBJECT (converterdlg, encoder, "encoder");
+ GLADE_HOOKUP_OBJECT (converterdlg, edit_encoder_presets, "edit_encoder_presets");
+ GLADE_HOOKUP_OBJECT (converterdlg, image469, "image469");
+ GLADE_HOOKUP_OBJECT (converterdlg, hbox86, "hbox86");
+ GLADE_HOOKUP_OBJECT (converterdlg, label114, "label114");
+ GLADE_HOOKUP_OBJECT (converterdlg, hbox91, "hbox91");
+ GLADE_HOOKUP_OBJECT (converterdlg, dsp_preset, "dsp_preset");
+ GLADE_HOOKUP_OBJECT (converterdlg, edit_dsp_presets, "edit_dsp_presets");
+ GLADE_HOOKUP_OBJECT (converterdlg, image470, "image470");
+ GLADE_HOOKUP_OBJECT (converterdlg, hbox88, "hbox88");
+ GLADE_HOOKUP_OBJECT (converterdlg, label116, "label116");
+ GLADE_HOOKUP_OBJECT (converterdlg, numthreads, "numthreads");
+ GLADE_HOOKUP_OBJECT (converterdlg, hbox89, "hbox89");
+ GLADE_HOOKUP_OBJECT (converterdlg, label117, "label117");
+ GLADE_HOOKUP_OBJECT (converterdlg, output_format, "output_format");
+ GLADE_HOOKUP_OBJECT (converterdlg, hbox99, "hbox99");
+ GLADE_HOOKUP_OBJECT (converterdlg, label121, "label121");
+ GLADE_HOOKUP_OBJECT (converterdlg, overwrite_action, "overwrite_action");
+ GLADE_HOOKUP_OBJECT (converterdlg, preserve_folders, "preserve_folders");
+ GLADE_HOOKUP_OBJECT (converterdlg, hbox102, "hbox102");
+ GLADE_HOOKUP_OBJECT (converterdlg, preserve_root_folder, "preserve_root_folder");
+ GLADE_HOOKUP_OBJECT (converterdlg, preserve_folder_browse, "preserve_folder_browse");
+ GLADE_HOOKUP_OBJECT_NO_REF (converterdlg, dialog_action_area5, "dialog_action_area5");
+ GLADE_HOOKUP_OBJECT (converterdlg, converter_cancel, "converter_cancel");
+ GLADE_HOOKUP_OBJECT (converterdlg, converter_ok, "converter_ok");
+ GLADE_HOOKUP_OBJECT_NO_REF (converterdlg, tooltips, "tooltips");
+
+ return converterdlg;
+}
+
+GtkWidget*
+create_convpreset_editor (void)
+{
+ GtkWidget *convpreset_editor;
+ GtkWidget *dialog_vbox7;
+ GtkWidget *vbox27;
+ GtkWidget *hbox70;
+ GtkWidget *label105;
+ GtkWidget *title;
+ GtkWidget *hbox96;
+ GtkWidget *label120;
+ GtkWidget *ext;
+ GtkWidget *hbox72;
+ GtkWidget *label106;
+ GtkWidget *hbox93;
+ GtkWidget *encoder;
+ GtkWidget *custom4;
+ GtkWidget *label124;
+ GtkWidget *hbox73;
+ GtkWidget *label107;
+ GtkWidget *method;
+ GtkWidget *frame9;
+ GtkWidget *alignment21;
+ GtkWidget *table2;
+ GtkWidget *apev2;
+ GtkWidget *id3v1;
+ GtkWidget *oggvorbis;
+ GtkWidget *flac;
+ GtkWidget *hbox104;
+ GtkWidget *id3v2;
+ GtkWidget *id3v2_version;
+ GtkWidget *label125;
+ GtkWidget *dialog_action_area6;
+ GtkWidget *convpreset_cancel;
+ GtkWidget *convpreset_ok;
+ GtkTooltips *tooltips;
+
+ tooltips = gtk_tooltips_new ();
+
+ convpreset_editor = gtk_dialog_new ();
+ gtk_window_set_title (GTK_WINDOW (convpreset_editor), _("Edit Encoder Preset"));
+ gtk_window_set_modal (GTK_WINDOW (convpreset_editor), TRUE);
+ gtk_window_set_type_hint (GTK_WINDOW (convpreset_editor), GDK_WINDOW_TYPE_HINT_DIALOG);
+
+ dialog_vbox7 = GTK_DIALOG (convpreset_editor)->vbox;
+ gtk_widget_show (dialog_vbox7);
+
+ vbox27 = gtk_vbox_new (FALSE, 8);
+ gtk_widget_show (vbox27);
+ gtk_box_pack_start (GTK_BOX (dialog_vbox7), vbox27, TRUE, TRUE, 0);
+ gtk_container_set_border_width (GTK_CONTAINER (vbox27), 12);
+
+ hbox70 = gtk_hbox_new (FALSE, 8);
+ gtk_widget_show (hbox70);
+ gtk_box_pack_start (GTK_BOX (vbox27), hbox70, FALSE, TRUE, 0);
+
+ label105 = gtk_label_new (_("Title:"));
+ gtk_widget_show (label105);
+ gtk_box_pack_start (GTK_BOX (hbox70), label105, FALSE, FALSE, 0);
+
+ title = gtk_entry_new ();
+ gtk_widget_show (title);
+ gtk_box_pack_start (GTK_BOX (hbox70), title, TRUE, TRUE, 0);
+ gtk_entry_set_text (GTK_ENTRY (title), _("Untitled Encoder"));
+ gtk_entry_set_invisible_char (GTK_ENTRY (title), 9679);
+ gtk_entry_set_activates_default (GTK_ENTRY (title), TRUE);
+
+ hbox96 = gtk_hbox_new (FALSE, 9);
+ gtk_widget_show (hbox96);
+ gtk_box_pack_start (GTK_BOX (vbox27), hbox96, FALSE, TRUE, 0);
+
+ label120 = gtk_label_new (_("Output file extension:"));
+ gtk_widget_show (label120);
+ gtk_box_pack_start (GTK_BOX (hbox96), label120, FALSE, FALSE, 0);
+
+ ext = gtk_entry_new ();
+ gtk_widget_show (ext);
+ gtk_box_pack_start (GTK_BOX (hbox96), ext, TRUE, TRUE, 0);
+ gtk_tooltips_set_tip (tooltips, ext, _("E.g. mp3"), NULL);
+ gtk_entry_set_invisible_char (GTK_ENTRY (ext), 9679);
+ gtk_entry_set_activates_default (GTK_ENTRY (ext), TRUE);
+
+ hbox72 = gtk_hbox_new (FALSE, 8);
+ gtk_widget_show (hbox72);
+ gtk_box_pack_start (GTK_BOX (vbox27), hbox72, FALSE, TRUE, 0);
+
+ label106 = gtk_label_new (_("Command line:"));
+ gtk_widget_show (label106);
+ gtk_box_pack_start (GTK_BOX (hbox72), label106, FALSE, FALSE, 0);
+
+ hbox93 = gtk_hbox_new (FALSE, 0);
+ gtk_widget_show (hbox93);
+ gtk_box_pack_start (GTK_BOX (hbox72), hbox93, TRUE, TRUE, 0);
+
+ encoder = gtk_entry_new ();
+ gtk_widget_show (encoder);
+ gtk_box_pack_start (GTK_BOX (hbox93), encoder, TRUE, TRUE, 0);
+ gtk_tooltips_set_tip (tooltips, encoder, _("Example: lame - %o\n%i for input file, %o for output file, - for stdin"), NULL);
+ gtk_entry_set_invisible_char (GTK_ENTRY (encoder), 9679);
+ gtk_entry_set_activates_default (GTK_ENTRY (encoder), TRUE);
+
+ custom4 = encoder_cmdline_help_link_create ("custom4", "", "", 0, 0);
+ gtk_widget_show (custom4);
+ gtk_box_pack_start (GTK_BOX (hbox93), custom4, TRUE, TRUE, 0);
+ GTK_WIDGET_UNSET_FLAGS (custom4, GTK_CAN_FOCUS);
+ GTK_WIDGET_UNSET_FLAGS (custom4, GTK_CAN_DEFAULT);
+
+ label124 = gtk_label_new (_("<small>%o - output file name\n%i - temporary input file name</small>"));
+ gtk_widget_show (label124);
+ gtk_box_pack_start (GTK_BOX (vbox27), label124, FALSE, FALSE, 0);
+ gtk_label_set_use_markup (GTK_LABEL (label124), TRUE);
+
+ hbox73 = gtk_hbox_new (FALSE, 8);
+ gtk_widget_show (hbox73);
+ gtk_box_pack_start (GTK_BOX (vbox27), hbox73, FALSE, TRUE, 0);
+
+ label107 = gtk_label_new (_("Method:"));
+ gtk_widget_show (label107);
+ gtk_box_pack_start (GTK_BOX (hbox73), label107, FALSE, FALSE, 0);
+
+ method = gtk_combo_box_new_text ();
+ gtk_widget_show (method);
+ gtk_box_pack_start (GTK_BOX (hbox73), method, TRUE, TRUE, 0);
+ gtk_combo_box_append_text (GTK_COMBO_BOX (method), _("Pipe"));
+ gtk_combo_box_append_text (GTK_COMBO_BOX (method), _("Temporary file"));
+
+ frame9 = gtk_frame_new (NULL);
+ gtk_widget_show (frame9);
+ gtk_box_pack_start (GTK_BOX (vbox27), frame9, FALSE, FALSE, 0);
+
+ alignment21 = gtk_alignment_new (0.5, 0.5, 1, 1);
+ gtk_widget_show (alignment21);
+ gtk_container_add (GTK_CONTAINER (frame9), alignment21);
+ gtk_alignment_set_padding (GTK_ALIGNMENT (alignment21), 0, 0, 12, 0);
+
+ table2 = gtk_table_new (2, 3, FALSE);
+ gtk_widget_show (table2);
+ gtk_container_add (GTK_CONTAINER (alignment21), table2);
+ gtk_container_set_border_width (GTK_CONTAINER (table2), 8);
+ gtk_table_set_col_spacings (GTK_TABLE (table2), 8);
+
+ apev2 = gtk_check_button_new_with_mnemonic (_("APEv2"));
+ gtk_widget_show (apev2);
+ gtk_table_attach (GTK_TABLE (table2), apev2, 1, 2, 0, 1,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+
+ id3v1 = gtk_check_button_new_with_mnemonic (_("ID3v1"));
+ gtk_widget_show (id3v1);
+ gtk_table_attach (GTK_TABLE (table2), id3v1, 2, 3, 0, 1,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+
+ oggvorbis = gtk_check_button_new_with_mnemonic (_("OggVorbis"));
+ gtk_widget_show (oggvorbis);
+ gtk_table_attach (GTK_TABLE (table2), oggvorbis, 2, 3, 1, 2,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+
+ flac = gtk_check_button_new_with_mnemonic (_("FLAC"));
+ gtk_widget_show (flac);
+ gtk_table_attach (GTK_TABLE (table2), flac, 1, 2, 1, 2,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+
+ hbox104 = gtk_hbox_new (FALSE, 0);
+ gtk_widget_show (hbox104);
+ gtk_table_attach (GTK_TABLE (table2), hbox104, 0, 1, 0, 1,
+ (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
+ (GtkAttachOptions) (GTK_FILL), 0, 0);
+
+ id3v2 = gtk_check_button_new_with_mnemonic (_("ID3v2"));
+ gtk_widget_show (id3v2);
+ gtk_box_pack_start (GTK_BOX (hbox104), id3v2, FALSE, FALSE, 0);
+
+ id3v2_version = gtk_combo_box_new_text ();
+ gtk_widget_show (id3v2_version);
+ gtk_box_pack_start (GTK_BOX (hbox104), id3v2_version, TRUE, TRUE, 0);
+ gtk_combo_box_append_text (GTK_COMBO_BOX (id3v2_version), _("2.3"));
+ gtk_combo_box_append_text (GTK_COMBO_BOX (id3v2_version), _("2.4"));
+
+ label125 = gtk_label_new (_("<b>Tag writer</b>"));
+ gtk_widget_show (label125);
+ gtk_frame_set_label_widget (GTK_FRAME (frame9), label125);
+ gtk_label_set_use_markup (GTK_LABEL (label125), TRUE);
+
+ dialog_action_area6 = GTK_DIALOG (convpreset_editor)->action_area;
+ gtk_widget_show (dialog_action_area6);
+ gtk_button_box_set_layout (GTK_BUTTON_BOX (dialog_action_area6), GTK_BUTTONBOX_END);
+
+ convpreset_cancel = gtk_button_new_from_stock ("gtk-cancel");
+ gtk_widget_show (convpreset_cancel);
+ gtk_dialog_add_action_widget (GTK_DIALOG (convpreset_editor), convpreset_cancel, GTK_RESPONSE_CANCEL);
+ GTK_WIDGET_SET_FLAGS (convpreset_cancel, GTK_CAN_DEFAULT);
+
+ convpreset_ok = gtk_button_new_from_stock ("gtk-ok");
+ gtk_widget_show (convpreset_ok);
+ gtk_dialog_add_action_widget (GTK_DIALOG (convpreset_editor), convpreset_ok, GTK_RESPONSE_OK);
+ GTK_WIDGET_SET_FLAGS (convpreset_ok, GTK_CAN_DEFAULT);
+
+ g_signal_connect ((gpointer) encoder, "changed",
+ G_CALLBACK (on_encoder_changed),
+ NULL);
+
+ /* Store pointers to all widgets, for use by lookup_widget(). */
+ GLADE_HOOKUP_OBJECT_NO_REF (convpreset_editor, convpreset_editor, "convpreset_editor");
+ GLADE_HOOKUP_OBJECT_NO_REF (convpreset_editor, dialog_vbox7, "dialog_vbox7");
+ GLADE_HOOKUP_OBJECT (convpreset_editor, vbox27, "vbox27");
+ GLADE_HOOKUP_OBJECT (convpreset_editor, hbox70, "hbox70");
+ GLADE_HOOKUP_OBJECT (convpreset_editor, label105, "label105");
+ GLADE_HOOKUP_OBJECT (convpreset_editor, title, "title");
+ GLADE_HOOKUP_OBJECT (convpreset_editor, hbox96, "hbox96");
+ GLADE_HOOKUP_OBJECT (convpreset_editor, label120, "label120");
+ GLADE_HOOKUP_OBJECT (convpreset_editor, ext, "ext");
+ GLADE_HOOKUP_OBJECT (convpreset_editor, hbox72, "hbox72");
+ GLADE_HOOKUP_OBJECT (convpreset_editor, label106, "label106");
+ GLADE_HOOKUP_OBJECT (convpreset_editor, hbox93, "hbox93");
+ GLADE_HOOKUP_OBJECT (convpreset_editor, encoder, "encoder");
+ GLADE_HOOKUP_OBJECT (convpreset_editor, custom4, "custom4");
+ GLADE_HOOKUP_OBJECT (convpreset_editor, label124, "label124");
+ GLADE_HOOKUP_OBJECT (convpreset_editor, hbox73, "hbox73");
+ GLADE_HOOKUP_OBJECT (convpreset_editor, label107, "label107");
+ GLADE_HOOKUP_OBJECT (convpreset_editor, method, "method");
+ GLADE_HOOKUP_OBJECT (convpreset_editor, frame9, "frame9");
+ GLADE_HOOKUP_OBJECT (convpreset_editor, alignment21, "alignment21");
+ GLADE_HOOKUP_OBJECT (convpreset_editor, table2, "table2");
+ GLADE_HOOKUP_OBJECT (convpreset_editor, apev2, "apev2");
+ GLADE_HOOKUP_OBJECT (convpreset_editor, id3v1, "id3v1");
+ GLADE_HOOKUP_OBJECT (convpreset_editor, oggvorbis, "oggvorbis");
+ GLADE_HOOKUP_OBJECT (convpreset_editor, flac, "flac");
+ GLADE_HOOKUP_OBJECT (convpreset_editor, hbox104, "hbox104");
+ GLADE_HOOKUP_OBJECT (convpreset_editor, id3v2, "id3v2");
+ GLADE_HOOKUP_OBJECT (convpreset_editor, id3v2_version, "id3v2_version");
+ GLADE_HOOKUP_OBJECT (convpreset_editor, label125, "label125");
+ GLADE_HOOKUP_OBJECT_NO_REF (convpreset_editor, dialog_action_area6, "dialog_action_area6");
+ GLADE_HOOKUP_OBJECT (convpreset_editor, convpreset_cancel, "convpreset_cancel");
+ GLADE_HOOKUP_OBJECT (convpreset_editor, convpreset_ok, "convpreset_ok");
+ GLADE_HOOKUP_OBJECT_NO_REF (convpreset_editor, tooltips, "tooltips");
+
+ return convpreset_editor;
+}
+
+GtkWidget*
+create_dsppreset_editor (void)
+{
+ GtkWidget *dsppreset_editor;
+ GtkWidget *dialog_vbox9;
+ GtkWidget *vbox30;
+ GtkWidget *hbox81;
+ GtkWidget *label111;
+ GtkWidget *title;
+ GtkWidget *vbox29;
+ GtkWidget *hbox82;
+ GtkWidget *add;
+ GtkWidget *remove;
+ GtkWidget *configure;
+ GtkWidget *hbox98;
+ GtkWidget *scrolledwindow7;
+ GtkWidget *plugins;
+ GtkWidget *vbox34;
+ GtkWidget *up;
+ GtkWidget *down;
+ GtkWidget *dialog_action_area8;
+ GtkWidget *cancelbutton6;
+ GtkWidget *okbutton6;
+
+ dsppreset_editor = gtk_dialog_new ();
+ gtk_widget_set_size_request (dsppreset_editor, 468, 254);
+ gtk_window_set_title (GTK_WINDOW (dsppreset_editor), _("DSP Preset Editor"));
+ gtk_window_set_modal (GTK_WINDOW (dsppreset_editor), TRUE);
+ gtk_window_set_type_hint (GTK_WINDOW (dsppreset_editor), GDK_WINDOW_TYPE_HINT_DIALOG);
+
+ dialog_vbox9 = GTK_DIALOG (dsppreset_editor)->vbox;
+ gtk_widget_show (dialog_vbox9);
+
+ vbox30 = gtk_vbox_new (FALSE, 8);
+ gtk_widget_show (vbox30);
+ gtk_box_pack_start (GTK_BOX (dialog_vbox9), vbox30, TRUE, TRUE, 0);
+ gtk_container_set_border_width (GTK_CONTAINER (vbox30), 12);
+
+ hbox81 = gtk_hbox_new (FALSE, 8);
+ gtk_widget_show (hbox81);
+ gtk_box_pack_start (GTK_BOX (vbox30), hbox81, FALSE, TRUE, 0);
+
+ label111 = gtk_label_new (_("Title"));
+ gtk_widget_show (label111);
+ gtk_box_pack_start (GTK_BOX (hbox81), label111, FALSE, FALSE, 0);
+
+ title = gtk_entry_new ();
+ gtk_widget_show (title);
+ gtk_box_pack_start (GTK_BOX (hbox81), title, TRUE, TRUE, 0);
+ gtk_entry_set_text (GTK_ENTRY (title), _("Untitled DSP Preset"));
+ gtk_entry_set_invisible_char (GTK_ENTRY (title), 9679);
+ gtk_entry_set_activates_default (GTK_ENTRY (title), TRUE);
+
+ vbox29 = gtk_vbox_new (FALSE, 8);
+ gtk_widget_show (vbox29);
+ gtk_box_pack_start (GTK_BOX (vbox30), vbox29, TRUE, TRUE, 0);
+
+ hbox82 = gtk_hbox_new (TRUE, 8);
+ gtk_widget_show (hbox82);
+ gtk_box_pack_start (GTK_BOX (vbox29), hbox82, FALSE, TRUE, 0);
+
+ add = gtk_button_new_with_mnemonic (_("Add"));
+ gtk_widget_show (add);
+ gtk_box_pack_start (GTK_BOX (hbox82), add, TRUE, TRUE, 0);
+
+ remove = gtk_button_new_with_mnemonic (_("Remove"));
+ gtk_widget_show (remove);
+ gtk_box_pack_start (GTK_BOX (hbox82), remove, TRUE, TRUE, 0);
+
+ configure = gtk_button_new_with_mnemonic (_("Configure"));
+ gtk_widget_show (configure);
+ gtk_box_pack_start (GTK_BOX (hbox82), configure, TRUE, TRUE, 0);
+
+ hbox98 = gtk_hbox_new (FALSE, 8);
+ gtk_widget_show (hbox98);
+ gtk_box_pack_start (GTK_BOX (vbox29), hbox98, TRUE, TRUE, 0);
+
+ scrolledwindow7 = gtk_scrolled_window_new (NULL, NULL);
+ gtk_widget_show (scrolledwindow7);
+ gtk_box_pack_start (GTK_BOX (hbox98), scrolledwindow7, TRUE, TRUE, 0);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow7), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow7), GTK_SHADOW_IN);
+
+ plugins = gtk_tree_view_new ();
+ gtk_widget_show (plugins);
+ gtk_container_add (GTK_CONTAINER (scrolledwindow7), plugins);
+ gtk_widget_set_size_request (plugins, 196, -1);
+ gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (plugins), FALSE);
+
+ vbox34 = gtk_vbox_new (FALSE, 8);
+ gtk_widget_show (vbox34);
+ gtk_box_pack_start (GTK_BOX (hbox98), vbox34, FALSE, FALSE, 0);
+
+ up = gtk_button_new_from_stock ("gtk-go-up");
+ gtk_widget_show (up);
+ gtk_box_pack_start (GTK_BOX (vbox34), up, FALSE, FALSE, 0);
+
+ down = gtk_button_new_from_stock ("gtk-go-down");
+ gtk_widget_show (down);
+ gtk_box_pack_start (GTK_BOX (vbox34), down, FALSE, FALSE, 0);
+
+ dialog_action_area8 = GTK_DIALOG (dsppreset_editor)->action_area;
+ gtk_widget_show (dialog_action_area8);
+ gtk_button_box_set_layout (GTK_BUTTON_BOX (dialog_action_area8), GTK_BUTTONBOX_END);
+
+ cancelbutton6 = gtk_button_new_from_stock ("gtk-cancel");
+ gtk_widget_show (cancelbutton6);
+ gtk_dialog_add_action_widget (GTK_DIALOG (dsppreset_editor), cancelbutton6, GTK_RESPONSE_CANCEL);
+ GTK_WIDGET_SET_FLAGS (cancelbutton6, GTK_CAN_DEFAULT);
+
+ okbutton6 = gtk_button_new_from_stock ("gtk-ok");
+ gtk_widget_show (okbutton6);
+ gtk_dialog_add_action_widget (GTK_DIALOG (dsppreset_editor), okbutton6, GTK_RESPONSE_OK);
+ GTK_WIDGET_SET_FLAGS (okbutton6, GTK_CAN_DEFAULT);
+
+ g_signal_connect ((gpointer) add, "clicked",
+ G_CALLBACK (on_dsp_preset_add_plugin_clicked),
+ NULL);
+ g_signal_connect ((gpointer) remove, "clicked",
+ G_CALLBACK (on_dsp_preset_remove_plugin_clicked),
+ NULL);
+ g_signal_connect ((gpointer) configure, "clicked",
+ G_CALLBACK (on_dsp_preset_plugin_configure_clicked),
+ NULL);
+ g_signal_connect ((gpointer) up, "clicked",
+ G_CALLBACK (on_dsp_preset_plugin_up_clicked),
+ NULL);
+ g_signal_connect ((gpointer) down, "clicked",
+ G_CALLBACK (on_dsp_preset_plugin_down_clicked),
+ NULL);
+
+ /* Store pointers to all widgets, for use by lookup_widget(). */
+ GLADE_HOOKUP_OBJECT_NO_REF (dsppreset_editor, dsppreset_editor, "dsppreset_editor");
+ GLADE_HOOKUP_OBJECT_NO_REF (dsppreset_editor, dialog_vbox9, "dialog_vbox9");
+ GLADE_HOOKUP_OBJECT (dsppreset_editor, vbox30, "vbox30");
+ GLADE_HOOKUP_OBJECT (dsppreset_editor, hbox81, "hbox81");
+ GLADE_HOOKUP_OBJECT (dsppreset_editor, label111, "label111");
+ GLADE_HOOKUP_OBJECT (dsppreset_editor, title, "title");
+ GLADE_HOOKUP_OBJECT (dsppreset_editor, vbox29, "vbox29");
+ GLADE_HOOKUP_OBJECT (dsppreset_editor, hbox82, "hbox82");
+ GLADE_HOOKUP_OBJECT (dsppreset_editor, add, "add");
+ GLADE_HOOKUP_OBJECT (dsppreset_editor, remove, "remove");
+ GLADE_HOOKUP_OBJECT (dsppreset_editor, configure, "configure");
+ GLADE_HOOKUP_OBJECT (dsppreset_editor, hbox98, "hbox98");
+ GLADE_HOOKUP_OBJECT (dsppreset_editor, scrolledwindow7, "scrolledwindow7");
+ GLADE_HOOKUP_OBJECT (dsppreset_editor, plugins, "plugins");
+ GLADE_HOOKUP_OBJECT (dsppreset_editor, vbox34, "vbox34");
+ GLADE_HOOKUP_OBJECT (dsppreset_editor, up, "up");
+ GLADE_HOOKUP_OBJECT (dsppreset_editor, down, "down");
+ GLADE_HOOKUP_OBJECT_NO_REF (dsppreset_editor, dialog_action_area8, "dialog_action_area8");
+ GLADE_HOOKUP_OBJECT (dsppreset_editor, cancelbutton6, "cancelbutton6");
+ GLADE_HOOKUP_OBJECT (dsppreset_editor, okbutton6, "okbutton6");
+
+ return dsppreset_editor;
+}
+
+GtkWidget*
+create_select_dsp_plugin (void)
+{
+ GtkWidget *select_dsp_plugin;
+ GtkWidget *dialog_vbox10;
+ GtkWidget *vbox31;
+ GtkWidget *hbox85;
+ GtkWidget *label113;
+ GtkWidget *plugin;
+ GtkWidget *dialog_action_area9;
+ GtkWidget *cancelbutton7;
+ GtkWidget *okbutton7;
+
+ select_dsp_plugin = gtk_dialog_new ();
+ gtk_window_set_title (GTK_WINDOW (select_dsp_plugin), _("Select DSP Plugin"));
+ gtk_window_set_modal (GTK_WINDOW (select_dsp_plugin), TRUE);
+ gtk_window_set_type_hint (GTK_WINDOW (select_dsp_plugin), GDK_WINDOW_TYPE_HINT_DIALOG);
+
+ dialog_vbox10 = GTK_DIALOG (select_dsp_plugin)->vbox;
+ gtk_widget_show (dialog_vbox10);
+
+ vbox31 = gtk_vbox_new (FALSE, 8);
+ gtk_widget_show (vbox31);
+ gtk_box_pack_start (GTK_BOX (dialog_vbox10), vbox31, TRUE, TRUE, 0);
+ gtk_container_set_border_width (GTK_CONTAINER (vbox31), 12);
+
+ hbox85 = gtk_hbox_new (FALSE, 8);
+ gtk_widget_show (hbox85);
+ gtk_box_pack_start (GTK_BOX (vbox31), hbox85, FALSE, FALSE, 0);
+
+ label113 = gtk_label_new (_("Plugin"));
+ gtk_widget_show (label113);
+ gtk_box_pack_start (GTK_BOX (hbox85), label113, FALSE, FALSE, 0);
+
+ plugin = gtk_combo_box_new_text ();
+ gtk_widget_show (plugin);
+ gtk_box_pack_start (GTK_BOX (hbox85), plugin, TRUE, TRUE, 0);
+
+ dialog_action_area9 = GTK_DIALOG (select_dsp_plugin)->action_area;
+ gtk_widget_show (dialog_action_area9);
+ gtk_button_box_set_layout (GTK_BUTTON_BOX (dialog_action_area9), GTK_BUTTONBOX_END);
+
+ cancelbutton7 = gtk_button_new_from_stock ("gtk-cancel");
+ gtk_widget_show (cancelbutton7);
+ gtk_dialog_add_action_widget (GTK_DIALOG (select_dsp_plugin), cancelbutton7, GTK_RESPONSE_CANCEL);
+ GTK_WIDGET_SET_FLAGS (cancelbutton7, GTK_CAN_DEFAULT);
+
+ okbutton7 = gtk_button_new_from_stock ("gtk-ok");
+ gtk_widget_show (okbutton7);
+ gtk_dialog_add_action_widget (GTK_DIALOG (select_dsp_plugin), okbutton7, GTK_RESPONSE_OK);
+ GTK_WIDGET_SET_FLAGS (okbutton7, GTK_CAN_DEFAULT);
+
+ /* Store pointers to all widgets, for use by lookup_widget(). */
+ GLADE_HOOKUP_OBJECT_NO_REF (select_dsp_plugin, select_dsp_plugin, "select_dsp_plugin");
+ GLADE_HOOKUP_OBJECT_NO_REF (select_dsp_plugin, dialog_vbox10, "dialog_vbox10");
+ GLADE_HOOKUP_OBJECT (select_dsp_plugin, vbox31, "vbox31");
+ GLADE_HOOKUP_OBJECT (select_dsp_plugin, hbox85, "hbox85");
+ GLADE_HOOKUP_OBJECT (select_dsp_plugin, label113, "label113");
+ GLADE_HOOKUP_OBJECT (select_dsp_plugin, plugin, "plugin");
+ GLADE_HOOKUP_OBJECT_NO_REF (select_dsp_plugin, dialog_action_area9, "dialog_action_area9");
+ GLADE_HOOKUP_OBJECT (select_dsp_plugin, cancelbutton7, "cancelbutton7");
+ GLADE_HOOKUP_OBJECT (select_dsp_plugin, okbutton7, "okbutton7");
+
+ return select_dsp_plugin;
+}
+
+GtkWidget*
+create_preset_list (void)
+{
+ GtkWidget *preset_list;
+ GtkWidget *dialog_vbox11;
+ GtkWidget *vbox33;
+ GtkWidget *hbox94;
+ GtkWidget *add;
+ GtkWidget *remove;
+ GtkWidget *edit;
+ GtkWidget *scrolledwindow8;
+ GtkWidget *presets;
+ GtkWidget *dialog_action_area10;
+ GtkWidget *okbutton8;
+
+ preset_list = gtk_dialog_new ();
+ gtk_window_set_title (GTK_WINDOW (preset_list), _("Presets"));
+ gtk_window_set_modal (GTK_WINDOW (preset_list), TRUE);
+ gtk_window_set_type_hint (GTK_WINDOW (preset_list), GDK_WINDOW_TYPE_HINT_DIALOG);
+
+ dialog_vbox11 = GTK_DIALOG (preset_list)->vbox;
+ gtk_widget_show (dialog_vbox11);
+
+ vbox33 = gtk_vbox_new (FALSE, 8);
+ gtk_widget_show (vbox33);
+ gtk_box_pack_start (GTK_BOX (dialog_vbox11), vbox33, TRUE, TRUE, 0);
+ gtk_container_set_border_width (GTK_CONTAINER (vbox33), 12);
+
+ hbox94 = gtk_hbox_new (TRUE, 8);
+ gtk_widget_show (hbox94);
+ gtk_box_pack_start (GTK_BOX (vbox33), hbox94, FALSE, TRUE, 0);
+
+ add = gtk_button_new_from_stock ("gtk-add");
+ gtk_widget_show (add);
+ gtk_box_pack_start (GTK_BOX (hbox94), add, FALSE, TRUE, 0);
+
+ remove = gtk_button_new_from_stock ("gtk-remove");
+ gtk_widget_show (remove);
+ gtk_box_pack_start (GTK_BOX (hbox94), remove, FALSE, TRUE, 0);
+
+ edit = gtk_button_new_from_stock ("gtk-edit");
+ gtk_widget_show (edit);
+ gtk_box_pack_start (GTK_BOX (hbox94), edit, FALSE, TRUE, 0);
+
+ scrolledwindow8 = gtk_scrolled_window_new (NULL, NULL);
+ gtk_widget_show (scrolledwindow8);
+ gtk_box_pack_start (GTK_BOX (vbox33), scrolledwindow8, TRUE, TRUE, 0);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow8), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow8), GTK_SHADOW_IN);
+
+ presets = gtk_tree_view_new ();
+ gtk_widget_show (presets);
+ gtk_container_add (GTK_CONTAINER (scrolledwindow8), presets);
+ gtk_widget_set_size_request (presets, 400, 176);
+ gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (presets), FALSE);
+
+ dialog_action_area10 = GTK_DIALOG (preset_list)->action_area;
+ gtk_widget_show (dialog_action_area10);
+ gtk_button_box_set_layout (GTK_BUTTON_BOX (dialog_action_area10), GTK_BUTTONBOX_END);
+
+ okbutton8 = gtk_button_new_from_stock ("gtk-close");
+ gtk_widget_show (okbutton8);
+ gtk_dialog_add_action_widget (GTK_DIALOG (preset_list), okbutton8, GTK_RESPONSE_CLOSE);
+ GTK_WIDGET_SET_FLAGS (okbutton8, GTK_CAN_DEFAULT);
+
+ /* Store pointers to all widgets, for use by lookup_widget(). */
+ GLADE_HOOKUP_OBJECT_NO_REF (preset_list, preset_list, "preset_list");
+ GLADE_HOOKUP_OBJECT_NO_REF (preset_list, dialog_vbox11, "dialog_vbox11");
+ GLADE_HOOKUP_OBJECT (preset_list, vbox33, "vbox33");
+ GLADE_HOOKUP_OBJECT (preset_list, hbox94, "hbox94");
+ GLADE_HOOKUP_OBJECT (preset_list, add, "add");
+ GLADE_HOOKUP_OBJECT (preset_list, remove, "remove");
+ GLADE_HOOKUP_OBJECT (preset_list, edit, "edit");
+ GLADE_HOOKUP_OBJECT (preset_list, scrolledwindow8, "scrolledwindow8");
+ GLADE_HOOKUP_OBJECT (preset_list, presets, "presets");
+ GLADE_HOOKUP_OBJECT_NO_REF (preset_list, dialog_action_area10, "dialog_action_area10");
+ GLADE_HOOKUP_OBJECT (preset_list, okbutton8, "okbutton8");
+
+ return preset_list;
+}
+
diff --git a/plugins/converter/interface.h b/plugins/converter/interface.h
new file mode 100644
index 00000000..346f63af
--- /dev/null
+++ b/plugins/converter/interface.h
@@ -0,0 +1,9 @@
+/*
+ * DO NOT EDIT THIS FILE - it is generated by Glade.
+ */
+
+GtkWidget* create_converterdlg (void);
+GtkWidget* create_convpreset_editor (void);
+GtkWidget* create_dsppreset_editor (void);
+GtkWidget* create_select_dsp_plugin (void);
+GtkWidget* create_preset_list (void);
diff --git a/plugins/converter/support.c b/plugins/converter/support.c
new file mode 100644
index 00000000..00aff298
--- /dev/null
+++ b/plugins/converter/support.c
@@ -0,0 +1,144 @@
+/*
+ * DO NOT EDIT THIS FILE - it is generated by Glade.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdio.h>
+
+#include <gtk/gtk.h>
+
+#include "support.h"
+
+GtkWidget*
+lookup_widget (GtkWidget *widget,
+ const gchar *widget_name)
+{
+ GtkWidget *parent, *found_widget;
+
+ for (;;)
+ {
+ if (GTK_IS_MENU (widget))
+ parent = gtk_menu_get_attach_widget (GTK_MENU (widget));
+ else
+ parent = widget->parent;
+ if (!parent)
+ parent = (GtkWidget*) g_object_get_data (G_OBJECT (widget), "GladeParentKey");
+ if (parent == NULL)
+ break;
+ widget = parent;
+ }
+
+ found_widget = (GtkWidget*) g_object_get_data (G_OBJECT (widget),
+ widget_name);
+ if (!found_widget)
+ g_warning ("Widget not found: %s", widget_name);
+ return found_widget;
+}
+
+static GList *pixmaps_directories = NULL;
+
+/* Use this function to set the directory containing installed pixmaps. */
+void
+add_pixmap_directory (const gchar *directory)
+{
+ pixmaps_directories = g_list_prepend (pixmaps_directories,
+ g_strdup (directory));
+}
+
+/* This is an internally used function to find pixmap files. */
+static gchar*
+find_pixmap_file (const gchar *filename)
+{
+ GList *elem;
+
+ /* We step through each of the pixmaps directory to find it. */
+ elem = pixmaps_directories;
+ while (elem)
+ {
+ gchar *pathname = g_strdup_printf ("%s%s%s", (gchar*)elem->data,
+ G_DIR_SEPARATOR_S, filename);
+ if (g_file_test (pathname, G_FILE_TEST_EXISTS))
+ return pathname;
+ g_free (pathname);
+ elem = elem->next;
+ }
+ return NULL;
+}
+
+/* This is an internally used function to create pixmaps. */
+GtkWidget*
+create_pixmap (GtkWidget *widget,
+ const gchar *filename)
+{
+ gchar *pathname = NULL;
+ GtkWidget *pixmap;
+
+ if (!filename || !filename[0])
+ return gtk_image_new ();
+
+ pathname = find_pixmap_file (filename);
+
+ if (!pathname)
+ {
+ g_warning (_("Couldn't find pixmap file: %s"), filename);
+ return gtk_image_new ();
+ }
+
+ pixmap = gtk_image_new_from_file (pathname);
+ g_free (pathname);
+ return pixmap;
+}
+
+/* This is an internally used function to create pixmaps. */
+GdkPixbuf*
+create_pixbuf (const gchar *filename)
+{
+ gchar *pathname = NULL;
+ GdkPixbuf *pixbuf;
+ GError *error = NULL;
+
+ if (!filename || !filename[0])
+ return NULL;
+
+ pathname = find_pixmap_file (filename);
+
+ if (!pathname)
+ {
+ g_warning (_("Couldn't find pixmap file: %s"), filename);
+ return NULL;
+ }
+
+ pixbuf = gdk_pixbuf_new_from_file (pathname, &error);
+ if (!pixbuf)
+ {
+ fprintf (stderr, "Failed to load pixbuf file: %s: %s\n",
+ pathname, error->message);
+ g_error_free (error);
+ }
+ g_free (pathname);
+ return pixbuf;
+}
+
+/* This is used to set ATK action descriptions. */
+void
+glade_set_atk_action_description (AtkAction *action,
+ const gchar *action_name,
+ const gchar *description)
+{
+ gint n_actions, i;
+
+ n_actions = atk_action_get_n_actions (action);
+ for (i = 0; i < n_actions; i++)
+ {
+ if (!strcmp (atk_action_get_name (action, i), action_name))
+ atk_action_set_description (action, i, description);
+ }
+}
+
diff --git a/plugins/converter/support.h b/plugins/converter/support.h
new file mode 100644
index 00000000..a32649e5
--- /dev/null
+++ b/plugins/converter/support.h
@@ -0,0 +1,69 @@
+/*
+ * DO NOT EDIT THIS FILE - it is generated by Glade.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gtk/gtk.h>
+
+/*
+ * Standard gettext macros.
+ */
+#ifdef ENABLE_NLS
+# include <libintl.h>
+# undef _
+# define _(String) dgettext (PACKAGE, String)
+# define Q_(String) g_strip_context ((String), gettext (String))
+# ifdef gettext_noop
+# define N_(String) gettext_noop (String)
+# else
+# define N_(String) (String)
+# endif
+#else
+# define textdomain(String) (String)
+# define gettext(String) (String)
+# define dgettext(Domain,Message) (Message)
+# define dcgettext(Domain,Message,Type) (Message)
+# define bindtextdomain(Domain,Directory) (Domain)
+# define _(String) (String)
+# define Q_(String) g_strip_context ((String), (String))
+# define N_(String) (String)
+#endif
+
+
+/*
+ * Public Functions.
+ */
+
+/*
+ * This function returns a widget in a component created by Glade.
+ * Call it with the toplevel widget in the component (i.e. a window/dialog),
+ * or alternatively any widget in the component, and the name of the widget
+ * you want returned.
+ */
+GtkWidget* lookup_widget (GtkWidget *widget,
+ const gchar *widget_name);
+
+
+/* Use this function to set the directory containing installed pixmaps. */
+void add_pixmap_directory (const gchar *directory);
+
+
+/*
+ * Private Functions.
+ */
+
+/* This is used to create the pixmaps used in the interface. */
+GtkWidget* create_pixmap (GtkWidget *widget,
+ const gchar *filename);
+
+/* This is used to create the pixbufs used in the interface. */
+GdkPixbuf* create_pixbuf (const gchar *filename);
+
+/* This is used to set ATK action descriptions. */
+void glade_set_atk_action_description (AtkAction *action,
+ const gchar *action_name,
+ const gchar *description);
+
diff --git a/plugins/dca/Makefile.am b/plugins/dca/Makefile.am
index 0ae4734c..9819c5aa 100644
--- a/plugins/dca/Makefile.am
+++ b/plugins/dca/Makefile.am
@@ -8,7 +8,6 @@ gettimeofday.c\
parse.c\
bitstream.c\
downmix.c\
-convert2s16.c\
audio_out.h\
dca.h\
dts.h\
@@ -26,6 +25,6 @@ bitstream.h
dca_la_LDFLAGS = -module
dca_la_LIBADD = $(LDADD) -lm
-AM_CFLAGS = $(CFLAGS) -fPIC
+AM_CFLAGS = $(CFLAGS) -fPIC -std=c99
endif
diff --git a/plugins/dca/convert2s16.c b/plugins/dca/convert2s16.c
deleted file mode 100644
index b0647eae..00000000
--- a/plugins/dca/convert2s16.c
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
- * convert2s16.c
- * Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org>
- * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
- *
- * This file is part of a52dec, a free ATSC A-52 stream decoder.
- * See http://liba52.sourceforge.net/ for updates.
- *
- * a52dec is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * a52dec is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the
- * Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include "config.h"
-
-#include <inttypes.h>
-
-#include "dca.h"
-
-#include <stdio.h>
-
-#ifdef LIBDCA_DOUBLE
-typedef float convert_t;
-#else
-typedef sample_t convert_t;
-#endif
-
-static inline int16_t convert (int32_t i)
-{
-#ifdef LIBDCA_FIXED
- i >>= 15;
-#else
- i -= 0x43c00000;
-#endif
- return (i > 32767) ? 32767 : ((i < -32768) ? -32768 : i);
-}
-
-void convert2s16_1 (convert_t * _f, int16_t * s16)
-{
- int i;
- int32_t * f = (int32_t *) _f;
-
- for (i = 0; i < 256; i++) {
- s16[i] = convert (f[i]);
- }
-}
-
-void convert2s16_2 (convert_t * _f, int16_t * s16)
-{
- int i;
- int32_t * f = (int32_t *) _f;
-
- for (i = 0; i < 256; i++) {
- s16[2*i] = convert (f[i]);
- s16[2*i+1] = convert (f[i+256]);
- }
-}
-
-void convert2s16_3 (convert_t * _f, int16_t * s16)
-{
- int i;
- int32_t * f = (int32_t *) _f;
-
- for (i = 0; i < 256; i++) {
- s16[3*i] = convert (f[i]);
- s16[3*i+1] = convert (f[i+256]);
- s16[3*i+2] = convert (f[i+512]);
- }
-}
-
-void convert2s16_4 (convert_t * _f, int16_t * s16)
-{
- int i;
- int32_t * f = (int32_t *) _f;
-
- for (i = 0; i < 256; i++) {
- s16[4*i] = convert (f[i]);
- s16[4*i+1] = convert (f[i+256]);
- s16[4*i+2] = convert (f[i+512]);
- s16[4*i+3] = convert (f[i+768]);
- }
-}
-
-void convert2s16_5 (convert_t * _f, int16_t * s16)
-{
- int i;
- int32_t * f = (int32_t *) _f;
-
- for (i = 0; i < 256; i++) {
- s16[5*i] = convert (f[i]);
- s16[5*i+1] = convert (f[i+256]);
- s16[5*i+2] = convert (f[i+512]);
- s16[5*i+3] = convert (f[i+768]);
- s16[5*i+4] = convert (f[i+1024]);
- }
-}
-
-int channels_multi (int flags)
-{
- if (flags & DCA_LFE)
- return 6;
- else if (flags & 1) /* center channel */
- return 5;
- else if ((flags & DCA_CHANNEL_MASK) == DCA_2F2R)
- return 4;
- else
- return 2;
-}
-
-void convert2s16_multi (convert_t * _f, int16_t * s16, int flags)
-{
- int i;
- int32_t * f = (int32_t *) _f;
-
- switch (flags) {
- case DCA_MONO:
- for (i = 0; i < 256; i++) {
- s16[5*i] = s16[5*i+1] = s16[5*i+2] = s16[5*i+3] = 0;
- s16[5*i+4] = convert (f[i]);
- }
- break;
- case DCA_CHANNEL:
- case DCA_STEREO:
- case DCA_DOLBY:
- convert2s16_2 (_f, s16);
- break;
- case DCA_3F:
- for (i = 0; i < 256; i++) {
- s16[5*i] = convert (f[i]);
- s16[5*i+1] = convert (f[i+512]);
- s16[5*i+2] = s16[5*i+3] = 0;
- s16[5*i+4] = convert (f[i+256]);
- }
- break;
- case DCA_2F2R:
- convert2s16_4 (_f, s16);
- break;
- case DCA_3F2R:
- convert2s16_5 (_f, s16);
- break;
- case DCA_MONO | DCA_LFE:
- for (i = 0; i < 256; i++) {
- s16[6*i] = s16[6*i+1] = s16[6*i+2] = s16[6*i+3] = 0;
- s16[6*i+4] = convert (f[i+256]);
- s16[6*i+5] = convert (f[i]);
- }
- break;
- case DCA_CHANNEL | DCA_LFE:
- case DCA_STEREO | DCA_LFE:
- case DCA_DOLBY | DCA_LFE:
- for (i = 0; i < 256; i++) {
- s16[6*i] = convert (f[i+256]);
- s16[6*i+1] = convert (f[i+512]);
- s16[6*i+2] = s16[6*i+3] = s16[6*i+4] = 0;
- s16[6*i+5] = convert (f[i]);
- }
- break;
- case DCA_3F | DCA_LFE:
- for (i = 0; i < 256; i++) {
- s16[6*i] = convert (f[i+256]);
- s16[6*i+1] = convert (f[i+768]);
- s16[6*i+2] = s16[6*i+3] = 0;
- s16[6*i+4] = convert (f[i+512]);
- s16[6*i+5] = convert (f[i]);
- }
- break;
- case DCA_2F2R | DCA_LFE:
- for (i = 0; i < 256; i++) {
- s16[6*i] = convert (f[i+256]);
- s16[6*i+1] = convert (f[i+512]);
- s16[6*i+2] = convert (f[i+768]);
- s16[6*i+3] = convert (f[i+1024]);
- s16[6*i+4] = 0;
- s16[6*i+5] = convert (f[i]);
- }
- break;
- case DCA_3F2R | DCA_LFE:
- for (i = 0; i < 256; i++) {
- s16[6*i] = convert (f[i+256]);
- s16[6*i+1] = convert (f[i+768]);
- s16[6*i+2] = convert (f[i+1024]);
- s16[6*i+3] = convert (f[i+1280]);
- s16[6*i+4] = convert (f[i+512]);
- s16[6*i+5] = convert (f[i]);
- }
- break;
- }
-}
-
-void s16_swap (int16_t * s16, int channels)
-{
- int i;
- uint16_t * u16 = (uint16_t *) s16;
-
- for (i = 0; i < 256 * channels; i++)
- u16[i] = (u16[i] >> 8) | (u16[i] << 8);
-}
-
-void s32_swap (int32_t * s32, int channels)
-{
- int i;
- uint32_t * u32 = (uint32_t *) s32;
-
- for (i = 0; i < 256 * channels; i++)
- u32[i] = (u32[i] << 24) | ((u32[i] << 8)&0xFF0000) |
- ((u32[i] >> 8)&0xFF00) | (u32[i] >> 24);
-}
diff --git a/plugins/dca/dcaplug.c b/plugins/dca/dcaplug.c
index 9d7f251f..84a876ab 100644
--- a/plugins/dca/dcaplug.c
+++ b/plugins/dca/dcaplug.c
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@@ -73,7 +73,7 @@ static DB_decoder_t plugin;
DB_functions_t *deadbeef;
#define BUFFER_SIZE 24576
-#define OUT_BUFFER_SIZE 100000 // one block may be up to 22K samples, which is 88Kb for stereo
+#define OUT_BUFFER_SIZE 25000 // one block may be up to 22K samples, which is 88Kb for stereo
#define HEADER_SIZE 14
typedef struct {
DB_fileinfo_t info;
@@ -82,7 +82,6 @@ typedef struct {
int startsample;
int endsample;
int currentsample;
- int wavchannels;
dca_state_t * state;
int disable_adjust;// = 0;
float gain;// = 1;
@@ -95,7 +94,7 @@ typedef struct {
int flags;
int bit_rate;
int frame_byte_size;
- char output_buffer[OUT_BUFFER_SIZE];
+ int16_t output_buffer[OUT_BUFFER_SIZE*6];
int remaining;
int skipsamples;
} ddb_dca_state_t;
@@ -157,32 +156,35 @@ static int wav_channels (int flags, uint32_t * speaker_flags)
return chans;
}
+static inline int16_t convert (int32_t i)
+{
+#ifdef LIBDCA_FIXED
+ i >>= 15;
+#else
+ i -= 0x43c00000;
+#endif
+ return (i > 32767) ? 32767 : ((i < -32768) ? -32768 : i);
+}
+
static int
convert_samples (ddb_dca_state_t *state, int flags)
{
sample_t *_samples = dca_samples (state->state);
- int chans, size;
- uint32_t speaker_flags;
- int16_t int16_samples[256*6];
- convert_t * samples = _samples;
- chans = channels_multi (flags);
- flags &= DCA_CHANNEL_MASK | DCA_LFE;
+ int samplesize = state->info.fmt.channels * state->info.fmt.bps / 8;
- convert2s16_multi (samples, int16_samples, flags);
+ int n, i, c;
+ n = 256;
+ int16_t *dst = state->output_buffer + state->remaining * state->info.fmt.channels;
- int16_t *dest = (int16_t*)(state->output_buffer + state->remaining * sizeof (int16_t) * 2);
- int i;
- for (i = 0; i < 256; i++) {
- *dest = int16_samples[i * chans + 0];
- dest++;
- *dest = int16_samples[i * chans + 1];
- dest++;
+ for (i = 0; i < n; i++) {
+ for (c = 0; c < state->info.fmt.channels; c++) {
+ *dst++ = convert (*((int32_t*)(_samples + 256 * c)));
+ }
+ _samples ++;
}
- state->remaining += 256;
- //trace ("wrote %d bytes (chans=%d)\n", size, chans);
- //fwrite (&ordered_samples, 1, size, out);
+ state->remaining += 256;
return 0;
}
@@ -318,7 +320,7 @@ dts_open_wav (DB_FILE *fp, wavfmt_t *fmt, int64_t *totalsamples) {
return -1;
}
- deadbeef->fseek (fp, fmtsize - sizeof (wavfmt_t), SEEK_CUR);
+ deadbeef->fseek (fp, (int)fmtsize - (int)sizeof (wavfmt_t), SEEK_CUR);
// data subchunk
@@ -343,7 +345,7 @@ dts_open_wav (DB_FILE *fp, wavfmt_t *fmt, int64_t *totalsamples) {
}
static DB_fileinfo_t *
-dts_open (void) {
+dts_open (uint32_t hints) {
DB_fileinfo_t *_info = malloc (sizeof (ddb_dca_state_t));
ddb_dca_state_t *info = (ddb_dca_state_t *)_info;
memset (info, 0, sizeof (ddb_dca_state_t));
@@ -354,9 +356,9 @@ static int
dts_init (DB_fileinfo_t *_info, DB_playItem_t *it) {
ddb_dca_state_t *info = (ddb_dca_state_t *)_info;
- info->file = deadbeef->fopen (it->fname);
+ info->file = deadbeef->fopen (deadbeef->pl_find_meta (it, ":URI"));
if (!info->file) {
- trace ("dca: failed to open %s\n", it->fname);
+ trace ("dca: failed to open %s\n", deadbeef->pl_find_meta (it, ":URI"));
return -1;
}
@@ -364,17 +366,15 @@ dts_init (DB_fileinfo_t *_info, DB_playItem_t *it) {
int64_t totalsamples = -1;
// WAV format
if ((info->offset = dts_open_wav (info->file, &fmt, &totalsamples)) == -1) {
- // try raw DTS @ 48KHz
+ // raw dts, leave detection to libdca
info->offset = 0;
totalsamples = -1;
- info->wavchannels = 2;
- _info->bps = 16;
+ _info->fmt.bps = 16;
}
else {
- _info->bps = fmt.wBitsPerSample;
- _info->channels = fmt.nChannels;
- info->wavchannels = fmt.nChannels;
- _info->samplerate = fmt.nSamplesPerSec;
+ _info->fmt.bps = fmt.wBitsPerSample;
+ _info->fmt.channels = fmt.nChannels;
+ _info->fmt.samplerate = fmt.nSamplesPerSec;
}
_info->plugin = &plugin;
@@ -400,40 +400,48 @@ dts_init (DB_fileinfo_t *_info, DB_playItem_t *it) {
int flags = info->flags &~ (DCA_LFE | DCA_ADJUST_LEVEL);
switch (flags) {
case DCA_MONO:
- _info->channels = 1;
+ _info->fmt.channels = 1;
+ _info->fmt.channelmask = DDB_SPEAKER_FRONT_LEFT;
break;
case DCA_CHANNEL:
case DCA_STEREO:
case DCA_DOLBY:
case DCA_STEREO_SUMDIFF:
case DCA_STEREO_TOTAL:
- _info->channels = 2;
+ _info->fmt.channels = 2;
+ _info->fmt.channelmask = (DDB_SPEAKER_FRONT_LEFT | DDB_SPEAKER_FRONT_RIGHT);
break;
case DCA_3F:
case DCA_2F1R:
- _info->channels = 3;
+ _info->fmt.channels = 3;
+ _info->fmt.channelmask = (DDB_SPEAKER_FRONT_LEFT | DDB_SPEAKER_FRONT_RIGHT | DDB_SPEAKER_FRONT_CENTER);
break;
case DCA_2F2R:
case DCA_3F1R:
- _info->channels = 4;
+ _info->fmt.channels = 4;
+ _info->fmt.channelmask = (DDB_SPEAKER_FRONT_LEFT | DDB_SPEAKER_FRONT_RIGHT | DDB_SPEAKER_BACK_LEFT | DDB_SPEAKER_BACK_RIGHT);
break;
case DCA_3F2R:
- _info->channels = 5;
+ _info->fmt.channels = 5;
+ _info->fmt.channelmask = (DDB_SPEAKER_FRONT_LEFT | DDB_SPEAKER_FRONT_RIGHT | DDB_SPEAKER_BACK_LEFT | DDB_SPEAKER_BACK_RIGHT | DDB_SPEAKER_FRONT_CENTER);
break;
case DCA_4F2R:
- _info->channels = 6;
+ _info->fmt.channels = 6;
+ _info->fmt.channelmask = (DDB_SPEAKER_FRONT_LEFT | DDB_SPEAKER_FRONT_RIGHT | DDB_SPEAKER_BACK_LEFT | DDB_SPEAKER_BACK_RIGHT | DDB_SPEAKER_SIDE_LEFT | DDB_SPEAKER_SIDE_RIGHT);
break;
}
if (info->flags & DCA_LFE) {
- _info->channels++;
+ _info->fmt.channelmask |= DDB_SPEAKER_LOW_FREQUENCY;
+ _info->fmt.channels++;
}
- if (!_info->channels) {
+
+ if (!_info->fmt.channels) {
trace ("dts: invalid numchannels\n");
return -1;
}
- _info->samplerate = info->sample_rate;
+ _info->fmt.samplerate = info->sample_rate;
if (it->endsample > 0) {
info->startsample = it->startsample;
@@ -445,7 +453,7 @@ dts_init (DB_fileinfo_t *_info, DB_playItem_t *it) {
info->endsample = totalsamples-1;
}
- trace ("dca_init: nchannels: %d, samplerate: %d\n", _info->channels, _info->samplerate);
+ trace ("dca_init: nchannels: %d, samplerate: %d\n", _info->fmt.channels, _info->fmt.samplerate);
return 0;
}
@@ -464,11 +472,12 @@ dts_free (DB_fileinfo_t *_info) {
}
static int
-dts_read_int16 (DB_fileinfo_t *_info, char *bytes, int size) {
+dts_read (DB_fileinfo_t *_info, char *bytes, int size) {
ddb_dca_state_t *info = (ddb_dca_state_t *)_info;
+ int samplesize = _info->fmt.channels * _info->fmt.bps / 8;
if (info->endsample >= 0) {
- if (info->currentsample + size / (2 * _info->channels) > info->endsample) {
- size = (info->endsample - info->currentsample + 1) * 2 * _info->channels;
+ if (info->currentsample + size / samplesize > info->endsample) {
+ size = (info->endsample - info->currentsample + 1) * samplesize;
if (size <= 0) {
return 0;
}
@@ -476,30 +485,25 @@ dts_read_int16 (DB_fileinfo_t *_info, char *bytes, int size) {
}
int initsize = size;
- int out_channels = _info->channels;
- if (out_channels > 2) {
- out_channels = 2;
- }
- int sample_size = ((_info->bps >> 3) * out_channels);
while (size > 0) {
if (info->skipsamples > 0 && info->remaining > 0) {
int skip = min (info->remaining, info->skipsamples);
- int sample_size = _info->bps/8 * info->wavchannels;
if (skip < info->remaining) {
- memmove (info->output_buffer, info->output_buffer + skip * sample_size, (info->remaining - skip) * sample_size);
+ memmove (info->output_buffer, info->output_buffer + skip * _info->fmt.channels, (info->remaining - skip) * samplesize);
}
info->remaining -= skip;
info->skipsamples -= skip;
}
if (info->remaining > 0) {
- int n = size / sample_size;
+ int n = size / samplesize;
n = min (n, info->remaining);
- memcpy (bytes, info->output_buffer, n * sample_size);
+ memcpy (bytes, info->output_buffer, n * samplesize);
+
if (info->remaining > n) {
- memmove (info->output_buffer, info->output_buffer + n * sample_size, (info->remaining - n) * sample_size);
+ memmove (info->output_buffer, info->output_buffer + n * _info->fmt.channels, (info->remaining - n) * samplesize);
}
- bytes += n * sample_size;
- size -= n * sample_size;
+ bytes += n * samplesize;
+ size -= n * samplesize;
info->remaining -= n;
// trace ("dca: write %d samples\n", n);
}
@@ -514,7 +518,7 @@ dts_read_int16 (DB_fileinfo_t *_info, char *bytes, int size) {
}
}
- info->currentsample += (initsize-size) / sample_size;
+ info->currentsample += (initsize-size) / samplesize;
deadbeef->streamer_set_bitrate (info->bit_rate/1000);
return initsize-size;
}
@@ -532,14 +536,14 @@ dts_seek_sample (DB_fileinfo_t *_info, int sample) {
info->skipsamples = sample - nframe * info->frame_length;
info->currentsample = sample;
- _info->readpos = (float)(sample - info->startsample) / _info->samplerate;
+ _info->readpos = (float)(sample - info->startsample) / _info->fmt.samplerate;
return 0;
}
static int
dts_seek (DB_fileinfo_t *_info, float time) {
ddb_dca_state_t *info = (ddb_dca_state_t *)_info;
- return dts_seek_sample (_info, time * _info->samplerate);
+ return dts_seek_sample (_info, time * _info->fmt.samplerate);
}
static DB_playItem_t *
@@ -576,6 +580,7 @@ dts_insert (DB_playItem_t *after, const char *fname) {
// it's dts
uint8_t buffer[BUFFER_SIZE];
size_t size = deadbeef->fread (buffer, 1, sizeof (buffer), fp);
+ trace ("got size: %d (requested %d)\n", size, sizeof (buffer));
ddb_dca_state_t state;
memset (&state, 0, sizeof (state));
state.state = dca_init (0);
@@ -602,10 +607,8 @@ dts_insert (DB_playItem_t *after, const char *fname) {
dur = (float)totalsamples / state.sample_rate;
}
- DB_playItem_t *it = deadbeef->pl_item_alloc ();
- it->decoder_id = deadbeef->plug_get_decoder_id (plugin.plugin.id);
- it->fname = strdup (fname);
- it->filetype = filetype;
+ DB_playItem_t *it = deadbeef->pl_item_alloc_init (fname, plugin.plugin.id);
+ deadbeef->pl_add_meta (it, ":FILETYPE", filetype);
deadbeef->pl_set_item_duration (it, dur);
deadbeef->fclose (fp);
@@ -644,22 +647,39 @@ dts_stop (void) {
// define plugin interface
static DB_decoder_t plugin = {
DB_PLUGIN_SET_API_VERSION
- .plugin.version_major = 0,
- .plugin.version_minor = 1,
+ .plugin.version_major = 1,
+ .plugin.version_minor = 0,
.plugin.type = DB_PLUGIN_DECODER,
.plugin.id = "dts",
.plugin.name = "dts decoder",
- .plugin.descr = "dts decoder using libdca from VLC project",
- .plugin.author = "Alexey Yakovenko",
- .plugin.email = "waker@users.sourceforge.net",
+ .plugin.descr = "plays dts-encoded files using libdca from VLC project",
+ .plugin.copyright =
+ "Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>\n"
+ "\n"
+ "Uses modified libdca from VLC Player project,\n"
+ "developed by Gildas Bazin <gbazin@videolan.org>"
+ "\n"
+ "This program is free software; you can redistribute it and/or\n"
+ "modify it under the terms of the GNU General Public License\n"
+ "as published by the Free Software Foundation; either version 2\n"
+ "of the License, or (at your option) any later version.\n"
+ "\n"
+ "This program is distributed in the hope that it will be useful,\n"
+ "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+ "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+ "GNU General Public License for more details.\n"
+ "\n"
+ "You should have received a copy of the GNU General Public License\n"
+ "along with this program; if not, write to the Free Software\n"
+ "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n"
+ ,
.plugin.website = "http://deadbeef.sf.net",
.plugin.start = dts_start,
.plugin.stop = dts_stop,
.open = dts_open,
.init = dts_init,
.free = dts_free,
- .read_int16 = dts_read_int16,
-// .read_float32 = dts_read_float32,
+ .read = dts_read,
.seek = dts_seek,
.seek_sample = dts_seek_sample,
.insert = dts_insert,
diff --git a/plugins/dsp_libsrc/Makefile.am b/plugins/dsp_libsrc/Makefile.am
new file mode 100644
index 00000000..42c6a347
--- /dev/null
+++ b/plugins/dsp_libsrc/Makefile.am
@@ -0,0 +1,12 @@
+if HAVE_DSP_SRC
+pkglib_LTLIBRARIES = dsp_libsrc.la
+
+dsp_libsrc_la_SOURCES = src.c src.h
+
+dsp_libsrc_la_LDFLAGS = -module
+
+dsp_libsrc_la_LIBADD = $(LIBADD) $(LIBSAMPLERATE_DEPS_LIBS)
+
+dsp_libsrc_la_CFLAGS = $(CFLAGS) $(LIBSAMPLERATE_DEPS_CFLAGS) -std=c99
+
+endif
diff --git a/plugins/dsp_libsrc/src.c b/plugins/dsp_libsrc/src.c
new file mode 100644
index 00000000..be9c350e
--- /dev/null
+++ b/plugins/dsp_libsrc/src.c
@@ -0,0 +1,286 @@
+/*
+ DeaDBeeF - ultimate music player for GNU/Linux systems with X11
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+#include <samplerate.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include "conf.h"
+#include "threading.h"
+#include "deadbeef.h"
+#include "src.h"
+
+//#define trace(...) { fprintf(stderr, __VA_ARGS__); }
+#define trace(fmt,...)
+
+static DB_functions_t *deadbeef;
+
+#define SRC_BUFFER 16000
+#define SRC_MAX_CHANNELS 8
+
+static DB_dsp_t plugin;
+
+typedef struct {
+ ddb_dsp_context_t ctx;
+
+ int channels;
+ int quality;
+ float samplerate;
+ SRC_STATE *src;
+ SRC_DATA srcdata;
+ int remaining; // number of input samples in SRC buffer
+ __attribute__((__aligned__(16))) char in_fbuffer[sizeof(float)*SRC_BUFFER*SRC_MAX_CHANNELS];
+ unsigned quality_changed : 1;
+ unsigned need_reset : 1;
+} ddb_src_libsamplerate_t;
+
+ddb_dsp_context_t*
+ddb_src_open (void) {
+ ddb_src_libsamplerate_t *src = malloc (sizeof (ddb_src_libsamplerate_t));
+ DDB_INIT_DSP_CONTEXT (src,ddb_src_libsamplerate_t,&plugin);
+
+ src->samplerate = 44100;
+ src->quality = 2;
+ src->channels = -1;
+ return (ddb_dsp_context_t *)src;
+}
+
+void
+ddb_src_close (ddb_dsp_context_t *_src) {
+ ddb_src_libsamplerate_t *src = (ddb_src_libsamplerate_t*)_src;
+ if (src->src) {
+ src_delete (src->src);
+ src->src = NULL;
+ }
+ free (src);
+}
+
+void
+ddb_src_reset (ddb_dsp_context_t *_src) {
+ ddb_src_libsamplerate_t *src = (ddb_src_libsamplerate_t*)_src;
+ src->need_reset = 1;
+}
+
+
+void
+ddb_src_set_ratio (ddb_dsp_context_t *_src, float ratio) {
+ ddb_src_libsamplerate_t *src = (ddb_src_libsamplerate_t*)_src;
+ if (src->srcdata.src_ratio != ratio) {
+ src->srcdata.src_ratio = ratio;
+ src_set_ratio (src->src, ratio);
+ }
+}
+
+int
+ddb_src_process (ddb_dsp_context_t *_src, float *samples, int nframes, int maxframes, ddb_waveformat_t *fmt, float *r) {
+ ddb_src_libsamplerate_t *src = (ddb_src_libsamplerate_t*)_src;
+
+ if (fmt->samplerate == src->samplerate) {
+ return nframes;
+ }
+
+ if (src->need_reset || src->channels != fmt->channels || src->quality_changed || !src->src) {
+ src->quality_changed = 0;
+ src->remaining = 0;
+ if (src->src) {
+ src_delete (src->src);
+ src->src = NULL;
+ }
+ src->channels = fmt->channels;
+ src->src = src_new (src->quality, src->channels, NULL);
+ src->need_reset = 0;
+ }
+
+ float ratio = src->samplerate / fmt->samplerate;
+ ddb_src_set_ratio (_src, ratio);
+ fmt->samplerate = src->samplerate;
+
+ int numoutframes = 0;
+ int outsize = nframes*24;
+ float outbuf[outsize*fmt->channels];
+ memset (outbuf, 0, sizeof (outbuf));
+ char *output = (char *)outbuf;
+ float *input = samples;
+ int inputsize = nframes;
+
+ int samplesize = fmt->channels * sizeof (float);
+
+ do {
+ // add more frames to input SRC buffer
+ int n = inputsize;
+ if (n >= SRC_BUFFER - src->remaining) {
+ n = SRC_BUFFER - src->remaining;
+ }
+
+ if (n > 0) {
+ memcpy (&src->in_fbuffer[src->remaining*samplesize], samples, n * samplesize);
+
+ src->remaining += n;
+ samples += n * fmt->channels;
+ }
+ if (!src->remaining) {
+ trace ("WARNING: SRC input buffer starved\n");
+ break;
+ }
+
+ // call libsamplerate
+ src->srcdata.data_in = (float *)src->in_fbuffer;
+ src->srcdata.data_out = (float *)output;
+ src->srcdata.input_frames = src->remaining;
+ src->srcdata.output_frames = outsize;
+ src->srcdata.end_of_input = 0;
+ trace ("src input: %d, ratio %f, buffersize: %d\n", src->srcdata.input_frames, src->srcdata.src_ratio, sizeof (outbuf));
+ int src_err = src_process (src->src, &src->srcdata);
+ trace ("src output: %d, used: %d\n", src->srcdata.output_frames_gen, src->srcdata.input_frames_used);
+
+ if (src_err) {
+ const char *err = src_strerror (src_err) ;
+ fprintf (stderr, "src_process error %s\n"
+ "srcdata.data_in=%p, srcdata.data_out=%p, srcdata.input_frames=%d, srcdata.output_frames=%d, srcdata.src_ratio=%f", err, src->srcdata.data_in, src->srcdata.data_out, (int)src->srcdata.input_frames, (int)src->srcdata.output_frames, src->srcdata.src_ratio);
+ return nframes;
+ }
+
+ inputsize -= n;
+ output += src->srcdata.output_frames_gen * samplesize;
+ numoutframes += src->srcdata.output_frames_gen;
+ outsize -= src->srcdata.output_frames_gen;
+
+ // calculate how many unused input samples left
+ src->remaining -= src->srcdata.input_frames_used;
+ // copy spare samples for next update
+ if (src->remaining > 0 && src->srcdata.input_frames_used > 0) {
+ memmove (src->in_fbuffer, &src->in_fbuffer[src->srcdata.input_frames_used*samplesize], src->remaining * samplesize);
+ }
+ if (src->srcdata.output_frames_gen == 0) {
+ trace ("src: output_frames_gen=0, interrupt\n");
+ break;
+ }
+ } while (inputsize > 0 && outsize > 0);
+
+ memcpy (input, outbuf, numoutframes * fmt->channels * sizeof (float));
+ //static FILE *out = NULL;
+ //if (!out) {
+ // out = fopen ("out.raw", "w+b");
+ //}
+ //fwrite (input, 1, numoutframes*sizeof(float)*(*nchannels), out);
+
+ fmt->samplerate = src->samplerate;
+ trace ("src: ratio=%f, in=%d, out=%d\n", ratio, nframes, numoutframes);
+ return numoutframes;
+}
+
+int
+ddb_src_num_params (void) {
+ return SRC_PARAM_COUNT;
+}
+
+const char *
+ddb_src_get_param_name (int p) {
+ switch (p) {
+ case SRC_PARAM_QUALITY:
+ return "Quality";
+ case SRC_PARAM_SAMPLERATE:
+ return "Samplerate";
+ default:
+ fprintf (stderr, "ddb_src_get_param_name: invalid param index (%d)\n", p);
+ }
+}
+
+void
+ddb_src_set_param (ddb_dsp_context_t *ctx, int p, const char *val) {
+ switch (p) {
+ case SRC_PARAM_SAMPLERATE:
+ ((ddb_src_libsamplerate_t*)ctx)->samplerate = atof (val);
+ if (((ddb_src_libsamplerate_t*)ctx)->samplerate < 8000) {
+ ((ddb_src_libsamplerate_t*)ctx)->samplerate = 8000;
+ }
+ if (((ddb_src_libsamplerate_t*)ctx)->samplerate > 192000) {
+ ((ddb_src_libsamplerate_t*)ctx)->samplerate = 192000;
+ }
+ break;
+ case SRC_PARAM_QUALITY:
+ ((ddb_src_libsamplerate_t*)ctx)->quality = atoi (val);
+ ((ddb_src_libsamplerate_t*)ctx)->quality_changed = 1;
+ break;
+ default:
+ fprintf (stderr, "ddb_src_set_param: invalid param index (%d)\n", p);
+ }
+}
+
+void
+ddb_src_get_param (ddb_dsp_context_t *ctx, int p, char *val, int sz) {
+ switch (p) {
+ case SRC_PARAM_SAMPLERATE:
+ snprintf (val, sz, "%f", ((ddb_src_libsamplerate_t*)ctx)->samplerate);
+ break;
+ case SRC_PARAM_QUALITY:
+ snprintf (val, sz, "%d", ((ddb_src_libsamplerate_t*)ctx)->quality);
+ break;
+ default:
+ fprintf (stderr, "ddb_src_get_param: invalid param index (%d)\n", p);
+ }
+}
+
+static const char settings_dlg[] =
+ "property \"Target Samplerate\" spinbtn[8192,192000,1] 0 48000;\n"
+ "property \"Quality / Algorythm\" select[5] 1 2 SINC_BEST_QUALITY SINC_MEDIUM_QUALITY SINC_FASTEST ZERO_ORDER_HOLD LINEAR;\n"
+;
+
+static DB_dsp_t plugin = {
+ .plugin.api_vmajor = DB_API_VERSION_MAJOR,
+ .plugin.api_vminor = DB_API_VERSION_MINOR,
+ .open = ddb_src_open,
+ .close = ddb_src_close,
+ .process = ddb_src_process,
+ .plugin.version_major = 0,
+ .plugin.version_minor = 1,
+ .plugin.type = DB_PLUGIN_DSP,
+ .plugin.id = "SRC",
+ .plugin.name = "Resampler (Secret Rabbit Code)",
+ .plugin.descr = "High quality samplerate converter using libsamplerate, http://www.mega-nerd.com/SRC/",
+ .plugin.copyright =
+ "Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>\n"
+ "\n"
+ "This program is free software; you can redistribute it and/or\n"
+ "modify it under the terms of the GNU General Public License\n"
+ "as published by the Free Software Foundation; either version 2\n"
+ "of the License, or (at your option) any later version.\n"
+ "\n"
+ "This program is distributed in the hope that it will be useful,\n"
+ "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+ "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+ "GNU General Public License for more details.\n"
+ "\n"
+ "You should have received a copy of the GNU General Public License\n"
+ "along with this program; if not, write to the Free Software\n"
+ "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n"
+ ,
+ .plugin.website = "http://deadbeef.sf.net",
+ .num_params = ddb_src_num_params,
+ .get_param_name = ddb_src_get_param_name,
+ .set_param = ddb_src_set_param,
+ .get_param = ddb_src_get_param,
+ .reset = ddb_src_reset,
+ .configdialog = settings_dlg,
+};
+
+DB_plugin_t *
+dsp_libsrc_load (DB_functions_t *f) {
+ deadbeef = f;
+ return &plugin.plugin;
+}
diff --git a/plugins/dsp_libsrc/src.h b/plugins/dsp_libsrc/src.h
new file mode 100644
index 00000000..bb9a15e2
--- /dev/null
+++ b/plugins/dsp_libsrc/src.h
@@ -0,0 +1,28 @@
+/*
+ DeaDBeeF - ultimate music player for GNU/Linux systems with X11
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+#ifndef __SRC_H
+#define __SRC_H
+
+enum {
+ SRC_PARAM_SAMPLERATE = 0,
+ SRC_PARAM_QUALITY = 1,
+ SRC_PARAM_COUNT
+};
+
+#endif
diff --git a/plugins/dumb/Makefile.am b/plugins/dumb/Makefile
index de165bdd..e9b05233 100644
--- a/plugins/dumb/Makefile.am
+++ b/plugins/dumb/Makefile
@@ -1,14 +1,12 @@
-if HAVE_DUMB
-dumbpath=@top_srcdir@/plugins/dumb/dumb-kode54
+CC=gcc
-EXTRA_DIST = $(dumbpath)/readme.txt $(dumbpath)/ChangeLog $(dumbpath)/licence.txt $(dumbpath)/release.txt $(dumbpath)/todo.txt
+dumbpath=dumb-kode54
-pkglib_LTLIBRARIES = dumb.la
+CFLAGS+=-Wall -fPIC -D_GNU_SOURCE -I$(dumbpath)/include -std=c99
-AM_CFLAGS = $(CFLAGS) -I$(dumbpath)/include
-dumb_la_LDFLAGS = -module -lm
+LDFLAGS+=-module -shared -lm
-dumb_la_SOURCES =\
+SOURCES=\
dumb-kode54/src/it/readam.c\
dumb-kode54/src/it/readstm.c\
dumb-kode54/src/it/loads3m.c\
@@ -79,29 +77,20 @@ dumb-kode54/src/helpers/riff.c\
dumb-kode54/src/helpers/memfile.c\
dumb-kode54/src/helpers/sampbuf.c\
dumb-kode54/src/helpers/barray.c\
-dumb-kode54/studio/include/guitop.h\
-dumb-kode54/studio/include/dumbgui.h\
-dumb-kode54/studio/include/options.h\
-dumb-kode54/studio/include/subclip.h\
-dumb-kode54/studio/include/main.h\
-dumb-kode54/studio/include/guiproc.h\
-dumb-kode54/studio/include/dumbmenu.h\
-dumb-kode54/studio/include/dumbdesk.h\
-dumb-kode54/src/tools/it/modulus.h\
-dumb-kode54/include/internal/it.h\
-dumb-kode54/include/internal/dumb.h\
-dumb-kode54/include/internal/barray.h\
-dumb-kode54/include/internal/riff.h\
-dumb-kode54/include/internal/aldumb.h\
-dumb-kode54/include/dumb.h\
-dumb-kode54/include/aldumb.h\
-dumb-kode54/winamp/in_duh.h\
-dumb-kode54/winamp/in2.h\
-dumb-kode54/winamp/resource.h\
-dumb-kode54/winamp/out.h\
-dumb-kode54/winamp/gui.h\
-dumb-kode54/src/helpers/resample.inc\
-dumb-kode54/src/helpers/resamp2.inc\
-dumb-kode54/src/helpers/resamp3.inc\
cdumb.c
-endif
+
+OBJECTS=$(SOURCES:.c=.o)
+
+OUT=dumb.so
+
+all: $(SOURCES) $(OUT)
+
+$(OUT): $(OBJECTS)
+ $(CC) $(LDFLAGS) $(OBJECTS) -o $@
+
+.c.o:
+ $(CC) $(CFLAGS) $< -c -o $@
+
+clean:
+ rm $(OBJECTS) $(OUT)
+
diff --git a/plugins/dumb/cdumb.c b/plugins/dumb/cdumb.c
index b8189eeb..b5367640 100644
--- a/plugins/dumb/cdumb.c
+++ b/plugins/dumb/cdumb.c
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -51,7 +51,7 @@ static DUH*
open_module(const char *fname, const char *ext, int *start_order, int *is_it, int *is_dos, const char **filetype);
static DB_fileinfo_t *
-cdumb_open (void) {
+cdumb_open (uint32_t hints) {
DB_fileinfo_t *_info = malloc (sizeof (dumb_info_t));
memset (_info, 0, sizeof (dumb_info_t));
return _info;
@@ -59,26 +59,27 @@ cdumb_open (void) {
static int
cdumb_init (DB_fileinfo_t *_info, DB_playItem_t *it) {
- trace ("cdumb_init %s\n", it->fname);
+ trace ("cdumb_init %s\n", deadbeef->pl_find_meta (it, ":URI"));
dumb_info_t *info = (dumb_info_t *)_info;
int start_order = 0;
int is_dos, is_it;
- const char *ext = it->fname + strlen (it->fname) - 1;
- while (*ext != '.' && ext > it->fname) {
+ const char *ext = deadbeef->pl_find_meta (it, ":URI") + strlen (deadbeef->pl_find_meta (it, ":URI")) - 1;
+ while (*ext != '.' && ext > deadbeef->pl_find_meta (it, ":URI")) {
ext--;
}
ext++;
const char *ftype;
- info->duh = open_module(it->fname, ext, &start_order, &is_it, &is_dos, &ftype);
+ info->duh = open_module(deadbeef->pl_find_meta (it, ":URI"), ext, &start_order, &is_it, &is_dos, &ftype);
dumb_it_do_initial_runthrough (info->duh);
_info->plugin = &plugin;
- _info->bps = 16;
- _info->channels = 2;
- _info->samplerate = deadbeef->conf_get_int ("synth.samplerate", 44100);
+ _info->fmt.bps = deadbeef->conf_get_int ("dumb.8bitoutput", 0) ? 8 : 16;
+ _info->fmt.channels = 2;
+ _info->fmt.samplerate = deadbeef->conf_get_int ("synth.samplerate", 44100);
_info->readpos = 0;
+ _info->fmt.channelmask = _info->fmt.channels == 1 ? DDB_SPEAKER_FRONT_LEFT : (DDB_SPEAKER_FRONT_LEFT | DDB_SPEAKER_FRONT_RIGHT);
if (cdumb_startrenderer (_info) < 0) {
return -1;
@@ -139,12 +140,13 @@ static int
cdumb_read (DB_fileinfo_t *_info, char *bytes, int size) {
trace ("cdumb_read req %d\n", size);
dumb_info_t *info = (dumb_info_t *)_info;
- int length = size / 4;
+ int samplesize = (_info->fmt.bps >> 3) * _info->fmt.channels;
+ int length = size / samplesize;
long ret;
- ret = duh_render (info->renderer, 16, 0, 1, 65536.f / _info->samplerate, length, bytes);
- _info->readpos += ret / (float)_info->samplerate;
- trace ("cdumb_read %d\n", ret*4);
- return ret*4;
+ ret = duh_render (info->renderer, _info->fmt.bps, 0, 1, 65536.f / _info->fmt.samplerate, length, bytes);
+ _info->readpos += ret / (float)_info->fmt.samplerate;
+ trace ("cdumb_read %d\n", ret*samplesize);
+ return ret*samplesize;
}
static int
@@ -159,8 +161,8 @@ cdumb_seek (DB_fileinfo_t *_info, float time) {
else {
time -= _info->readpos;
}
- int pos = time * _info->samplerate;
- duh_sigrenderer_generate_samples (info->renderer, 0, 65536.0f / _info->samplerate, pos, NULL);
+ int pos = time * _info->fmt.samplerate;
+ duh_sigrenderer_generate_samples (info->renderer, 0, 65536.0f / _info->fmt.samplerate, pos, NULL);
_info->readpos = duh_sigrenderer_get_position (info->renderer) / 65536.f;
return 0;
}
@@ -691,8 +693,8 @@ static DUH * open_module(const char *fname, const char *ext, int *start_order, i
return duh;
}
-static const char *convstr (const char* str, int sz) {
- static char out[2048];
+static const char *
+convstr (const char* str, int sz, char *out, int out_sz) {
int i;
for (i = 0; i < sz; i++) {
if (str[i] != ' ') {
@@ -705,11 +707,11 @@ static const char *convstr (const char* str, int sz) {
}
// check for utf8 (hack)
- if (deadbeef->junk_iconv (str, sz, out, sizeof (out), "utf-8", "utf-8") >= 0) {
+ if (deadbeef->junk_iconv (str, sz, out, out_sz, "utf-8", "utf-8") >= 0) {
return out;
}
- if (deadbeef->junk_iconv (str, sz, out, sizeof (out), "utf-8", "iso8859-1") >= 0) {
+ if (deadbeef->junk_iconv (str, sz, out, out_sz, "cp1252", "utf-8") >= 0) {
return out;
}
@@ -717,25 +719,10 @@ static const char *convstr (const char* str, int sz) {
return NULL;
}
-static DB_playItem_t *
-cdumb_insert (DB_playItem_t *after, const char *fname) {
- const char *ext = fname + strlen (fname) - 1;
- while (*ext != '.' && ext > fname) {
- ext--;
- }
- ext++;
- int start_order = 0;
- int is_it;
- int is_dos;
- const char *ftype;
- DUH* duh = open_module(fname, ext, &start_order, &is_it, &is_dos, &ftype);
- if (!duh) {
- return NULL;
- }
- DB_playItem_t *it = deadbeef->pl_item_alloc ();
- it->decoder_id = deadbeef->plug_get_decoder_id (plugin.plugin.id);
- it->fname = strdup (fname);
- DUMB_IT_SIGDATA * itsd = duh_get_it_sigdata(duh);
+static void
+read_metadata_internal (DB_playItem_t *it, DUMB_IT_SIGDATA *itsd) {
+ char temp[2048];
+
if (itsd->name[0]) {
int tl = sizeof(itsd->name);
int i;
@@ -744,15 +731,90 @@ cdumb_insert (DB_playItem_t *after, const char *fname) {
deadbeef->pl_add_meta (it, "title", NULL);
}
else {
- deadbeef->pl_add_meta (it, "title", convstr ((char*)&itsd->name, sizeof(itsd->name)));
+ deadbeef->pl_add_meta (it, "title", convstr ((char*)&itsd->name, sizeof(itsd->name), temp, sizeof (temp)));
}
}
else {
deadbeef->pl_add_meta (it, "title", NULL);
}
+ int i;
+ for (i = 0; i < itsd->n_instruments; i++) {
+ char key[100];
+ snprintf (key, sizeof (key), "INST%03d", i);
+ deadbeef->pl_add_meta (it, key, convstr ((char *)&itsd->instrument[i].name, sizeof (itsd->instrument[i].name), temp, sizeof (temp)));
+ }
+ for (i = 0; i < itsd->n_samples; i++) {
+ char key[100];
+ snprintf (key, sizeof (key), "SAMP%03d", i);
+ deadbeef->pl_add_meta (it, key, convstr ((char *)&itsd->sample[i].name, sizeof (itsd->sample[i].name), temp, sizeof (temp)));
+ }
+
+ char s[100];
+
+ snprintf (s, sizeof (s), "%d", itsd->n_orders);
+ deadbeef->pl_add_meta (it, ":MOD_ORDERS", s);
+ snprintf (s, sizeof (s), "%d", itsd->n_instruments);
+ deadbeef->pl_add_meta (it, ":MOD_INSTRUMENTS", s);
+ snprintf (s, sizeof (s), "%d", itsd->n_samples);
+ deadbeef->pl_add_meta (it, ":MOD_SAMPLES", s);
+ snprintf (s, sizeof (s), "%d", itsd->n_patterns);
+ deadbeef->pl_add_meta (it, ":MOD_PATTERNS", s);
+ snprintf (s, sizeof (s), "%d", itsd->n_pchannels);
+ deadbeef->pl_add_meta (it, ":MOD_CHANNELS", s);
+}
+
+static int
+cdumb_read_metadata (DB_playItem_t *it) {
+ const char *fname = deadbeef->pl_find_meta (it, ":URI");
+ const char *ext = strrchr (fname, '.');
+ if (ext) {
+ ext++;
+ }
+ else {
+ ext = "";
+ }
+ int start_order = 0;
+ int is_it;
+ int is_dos;
+ const char *ftype;
+ DUH* duh = open_module(fname, ext, &start_order, &is_it, &is_dos, &ftype);
+ if (!duh) {
+ unload_duh (duh);
+ return -1;
+ }
+ DUMB_IT_SIGDATA * itsd = duh_get_it_sigdata(duh);
+
+ deadbeef->pl_delete_all_meta (it);
+ read_metadata_internal (it, itsd);
+ unload_duh (duh);
+ return 0;
+}
+
+static DB_playItem_t *
+cdumb_insert (DB_playItem_t *after, const char *fname) {
+ const char *ext = strrchr (fname, '.');
+ if (ext) {
+ ext++;
+ }
+ else {
+ ext = "";
+ }
+ int start_order = 0;
+ int is_it;
+ int is_dos;
+ const char *ftype;
+ DUH* duh = open_module(fname, ext, &start_order, &is_it, &is_dos, &ftype);
+ if (!duh) {
+ return NULL;
+ }
+ DB_playItem_t *it = deadbeef->pl_item_alloc_init (fname, plugin.plugin.id);
+ DUMB_IT_SIGDATA * itsd = duh_get_it_sigdata(duh);
+
+ read_metadata_internal (it, itsd);
+
dumb_it_do_initial_runthrough (duh);
deadbeef->pl_set_item_duration (it, duh_get_length (duh)/65536.0f);
- it->filetype = ftype;
+ deadbeef->pl_add_meta (it, ":FILETYPE", ftype);
// printf ("duration: %f\n", _info->duration);
after = deadbeef->pl_insert_item (after, it);
deadbeef->pl_item_unref (it);
@@ -811,18 +873,39 @@ static const char *filetypes[] = { "IT", "XM", "S3M", "STM", "669", "PTM", "PSM"
static const char settings_dlg[] =
"property \"Resampling quality (0..2, higher is better)\" entry dumb.resampling_quality 2;\n"
+ "property \"8-bit output (default is 16)\" checkbox dumb.8bitoutput 0;\n"
;
+
// define plugin interface
static DB_decoder_t plugin = {
DB_PLUGIN_SET_API_VERSION
- .plugin.version_major = 0,
- .plugin.version_minor = 1,
+ .plugin.version_major = 1,
+ .plugin.version_minor = 0,
.plugin.type = DB_PLUGIN_DECODER,
.plugin.id = "stddumb",
.plugin.name = "DUMB module player",
.plugin.descr = "module player based on DUMB library",
- .plugin.author = "Alexey Yakovenko",
- .plugin.email = "waker@users.sourceforge.net",
+ .plugin.copyright =
+ "Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>\n"
+ "\n"
+ "Uses a fork of DUMB (Dynamic Universal Music Bibliotheque), Version 0.9.3\n"
+ "Copyright (C) 2001-2005 Ben Davis, Robert J Ohannessian and Julien Cugniere\n"
+ "Uses code from kode54's foobar2000 plugin, http://kode54.foobar2000.org/\n"
+ "\n"
+ "This program is free software; you can redistribute it and/or\n"
+ "modify it under the terms of the GNU General Public License\n"
+ "as published by the Free Software Foundation; either version 2\n"
+ "of the License, or (at your option) any later version.\n"
+ "\n"
+ "This program is distributed in the hope that it will be useful,\n"
+ "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+ "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+ "GNU General Public License for more details.\n"
+ "\n"
+ "You should have received a copy of the GNU General Public License\n"
+ "along with this program; if not, write to the Free Software\n"
+ "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n"
+ ,
.plugin.website = "http://deadbeef.sf.net",
.plugin.start = cgme_start,
.plugin.stop = cgme_stop,
@@ -830,9 +913,10 @@ static DB_decoder_t plugin = {
.open = cdumb_open,
.init = cdumb_init,
.free = cdumb_free,
- .read_int16 = cdumb_read,
+ .read = cdumb_read,
.seek = cdumb_seek,
.insert = cdumb_insert,
+ .read_metadata = cdumb_read_metadata,
.exts = exts,
.filetypes = filetypes
};
diff --git a/plugins/dumb/dumb-kode54/src/it/loadmod.c b/plugins/dumb/dumb-kode54/src/it/loadmod.c
index 0b7dc618..dd43b611 100644
--- a/plugins/dumb/dumb-kode54/src/it/loadmod.c
+++ b/plugins/dumb/dumb-kode54/src/it/loadmod.c
@@ -26,7 +26,7 @@
* pointer to the DUH struct. When you have finished with it, you must
* pass the pointer to unload_duh() so that the memory can be freed.
*/
-DUH *dumb_load_mod_quick(const char *filename, int restrict)
+DUH *dumb_load_mod_quick(const char *filename, int restr)
{
DUH *duh;
DUMBFILE *f = dumbfile_open(filename);
@@ -34,7 +34,7 @@ DUH *dumb_load_mod_quick(const char *filename, int restrict)
if (!f)
return NULL;
- duh = dumb_read_mod_quick(f, restrict);
+ duh = dumb_read_mod_quick(f, restr);
dumbfile_close(f);
diff --git a/plugins/dumb/dumb-kode54/src/it/loadmod2.c b/plugins/dumb/dumb-kode54/src/it/loadmod2.c
index 7847d19f..c1f46e4c 100644
--- a/plugins/dumb/dumb-kode54/src/it/loadmod2.c
+++ b/plugins/dumb/dumb-kode54/src/it/loadmod2.c
@@ -21,9 +21,9 @@
-DUH *dumb_load_mod(const char *filename, int restrict)
+DUH *dumb_load_mod(const char *filename, int restr)
{
- DUH *duh = dumb_load_mod_quick(filename, restrict);
+ DUH *duh = dumb_load_mod_quick(filename, restr);
dumb_it_do_initial_runthrough(duh);
return duh;
}
diff --git a/plugins/dumb/dumb-kode54/src/it/readmod.c b/plugins/dumb/dumb-kode54/src/it/readmod.c
index a934af40..538d86ba 100644
--- a/plugins/dumb/dumb-kode54/src/it/readmod.c
+++ b/plugins/dumb/dumb-kode54/src/it/readmod.c
@@ -439,7 +439,7 @@ static DUMBFILE *dumbfile_buffer_mod_2(DUMBFILE *f, long *remain)
}
-static DUMB_IT_SIGDATA *it_mod_load_sigdata(DUMBFILE *f, int restrict)
+static DUMB_IT_SIGDATA *it_mod_load_sigdata(DUMBFILE *f, int restr)
{
DUMB_IT_SIGDATA *sigdata;
int n_channels;
@@ -554,7 +554,7 @@ static DUMB_IT_SIGDATA *it_mod_load_sigdata(DUMBFILE *f, int restrict)
}
// moo
- if ( restrict && sigdata->n_samples == 15 )
+ if ( restr && sigdata->n_samples == 15 )
{
free(sigdata);
dumbfile_close(f);
@@ -760,13 +760,13 @@ static DUMB_IT_SIGDATA *it_mod_load_sigdata(DUMBFILE *f, int restrict)
return sigdata;
}
-DUH *dumb_read_mod_quick(DUMBFILE *f, int restrict)
+DUH *dumb_read_mod_quick(DUMBFILE *f, int restr)
{
sigdata_t *sigdata;
DUH_SIGTYPE_DESC *descptr = &_dumb_sigtype_it;
- sigdata = it_mod_load_sigdata(f, restrict);
+ sigdata = it_mod_load_sigdata(f, restr);
if (!sigdata)
return NULL;
diff --git a/plugins/dumb/dumb-kode54/src/it/readmod2.c b/plugins/dumb/dumb-kode54/src/it/readmod2.c
index 102ead12..299c584e 100644
--- a/plugins/dumb/dumb-kode54/src/it/readmod2.c
+++ b/plugins/dumb/dumb-kode54/src/it/readmod2.c
@@ -21,9 +21,9 @@
-DUH *dumb_read_mod(DUMBFILE *f, int restrict)
+DUH *dumb_read_mod(DUMBFILE *f, int restr)
{
- DUH *duh = dumb_read_mod_quick(f, restrict);
+ DUH *duh = dumb_read_mod_quick(f, restr);
dumb_it_do_initial_runthrough(duh);
return duh;
}
diff --git a/plugins/ffap/ffap.c b/plugins/ffap/ffap.c
index deaa06dc..7abf0103 100644
--- a/plugins/ffap/ffap.c
+++ b/plugins/ffap/ffap.c
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
based on apedec from FFMpeg Copyright (c) 2007 Benjamin Zores <ben@geexbox.org>
based upon libdemac from Dave Chapman.
@@ -36,6 +36,7 @@
#include <stdlib.h>
//#include <alloca.h>
#include <assert.h>
+#include <math.h>
#include "../../deadbeef.h"
#ifdef TARGET_ANDROID
@@ -678,7 +679,7 @@ ffap_free (DB_fileinfo_t *_info)
}
static DB_fileinfo_t *
-ffap_open (void) {
+ffap_open (uint32_t hints) {
DB_fileinfo_t *_info = malloc (sizeof (ape_info_t));
memset (_info, 0, sizeof (ape_info_t));
return _info;
@@ -689,7 +690,7 @@ ffap_init (DB_fileinfo_t *_info, DB_playItem_t *it)
{
ape_info_t *info = (ape_info_t*)_info;
- info->fp = deadbeef->fopen (it->fname);
+ info->fp = deadbeef->fopen (deadbeef->pl_find_meta (it, ":URI"));
if (!info->fp) {
return -1;
}
@@ -726,9 +727,10 @@ ffap_init (DB_fileinfo_t *_info, DB_playItem_t *it)
}
_info->plugin = &plugin;
- _info->bps = info->ape_ctx.bps;
- _info->samplerate = info->ape_ctx.samplerate;
- _info->channels = info->ape_ctx.channels;
+ _info->fmt.bps = info->ape_ctx.bps;
+ _info->fmt.samplerate = info->ape_ctx.samplerate;
+ _info->fmt.channels = info->ape_ctx.channels;
+ _info->fmt.channelmask = _info->fmt.channels == 1 ? DDB_SPEAKER_FRONT_LEFT : (DDB_SPEAKER_FRONT_LEFT | DDB_SPEAKER_FRONT_RIGHT);
_info->readpos = 0;
if (it->endsample > 0) {
info->startsample = it->startsample;
@@ -1560,16 +1562,16 @@ ape_decode_frame(DB_fileinfo_t *_info, void *data, int *data_size)
{
ape_info_t *info = (ape_info_t*)_info;
APEContext *s = &info->ape_ctx;
- int16_t *samples = data;
+ char *samples = data;
int nblocks;
int i, n;
int blockstodecode;
int bytes_used;
- int samplesize = _info->bps>>3;
+ int samplesize = _info->fmt.bps/8 * s->channels;;
/* should not happen but who knows */
- if (BLOCKS_PER_LOOP * samplesize * s->channels > *data_size) {
- fprintf (stderr, "ape: Packet size is too big! (max is %d where you have %d)\n", *data_size, BLOCKS_PER_LOOP * samplesize * s->channels);
+ if (BLOCKS_PER_LOOP * samplesize > *data_size) {
+ fprintf (stderr, "ape: Packet size is too big! (max is %d where you have %d)\n", *data_size, BLOCKS_PER_LOOP * samplesize);
return -1;
}
@@ -1665,17 +1667,58 @@ ape_decode_frame(DB_fileinfo_t *_info, void *data, int *data_size)
int skip = min (s->samplestoskip, blockstodecode);
i = skip;
- for (; i < blockstodecode; i++) {
- *samples++ = (int16_t)(s->decoded0[i]>>(_info->bps-16));
- if(s->channels == 2) {
- *samples++ = (int16_t)(s->decoded1[i]>>(_info->bps-16));
+ if (_info->fmt.bps == 32) {
+ for (; i < blockstodecode; i++) {
+ *((int32_t*)samples) = s->decoded0[i];
+ samples += 4;
+ if(s->channels > 1) {
+ *((int32_t*)samples) = s->decoded1[i];
+ samples += 4;
+ }
+ }
+ }
+ else if (_info->fmt.bps == 24) {
+ for (; i < blockstodecode; i++) {
+ int32_t sample = s->decoded0[i];
+
+ samples[0] = sample&0xff;
+ samples[1] = (sample&0xff00)>>8;
+ samples[2] = (sample&0xff0000)>>16;
+ samples += 3;
+ if(s->channels > 1) {
+ sample = s->decoded1[i];
+ samples[0] = sample&0xff;
+ samples[1] = (sample&0xff00)>>8;
+ samples[2] = (sample&0xff0000)>>16;
+ samples += 3;
+ }
+ }
+ }
+ else if (_info->fmt.bps == 16) {
+ for (; i < blockstodecode; i++) {
+ *((int16_t*)samples) = (int16_t)s->decoded0[i];
+ samples += 2;
+ if(s->channels > 1) {
+ *((int16_t*)samples) = (int16_t)s->decoded1[i];
+ samples += 2;
+ }
+ }
+ }
+ else if (_info->fmt.bps == 8) {
+ for (; i < blockstodecode; i++) {
+ *samples = (int16_t)s->decoded0[i];
+ samples++;
+ if(s->channels > 1) {
+ *samples = (int16_t)s->decoded1[i];
+ samples++;
+ }
}
}
s->samplestoskip -= skip;
s->samples -= blockstodecode;
- *data_size = (blockstodecode - skip) * 2 * s->channels;
+ *data_size = (blockstodecode - skip) * samplesize;
// ape_ctx.currentsample += blockstodecode - skip;
bytes_used = s->samples ? s->ptr - s->last_ptr : s->packet_remaining;
@@ -1699,6 +1742,9 @@ ffap_insert (DB_playItem_t *after, const char *fname) {
if (!fp) {
return NULL;
}
+
+ int64_t fsize = deadbeef->fgetlength (fp);
+
int skip = deadbeef->junk_get_leading_size (fp);
if (skip > 0) {
deadbeef->fseek (fp, skip, SEEK_SET);
@@ -1718,10 +1764,8 @@ ffap_insert (DB_playItem_t *after, const char *fname) {
float duration = ape_ctx.totalsamples / (float)ape_ctx.samplerate;
DB_playItem_t *it = NULL;
- it = deadbeef->pl_item_alloc ();
- it->decoder_id = deadbeef->plug_get_decoder_id (plugin.plugin.id);
- it->fname = strdup (fname);
- it->filetype = "APE";
+ it = deadbeef->pl_item_alloc_init (fname, plugin.plugin.id);
+ deadbeef->pl_add_meta (it, ":FILETYPE", "APE");
deadbeef->pl_set_item_duration (it, duration);
/*int v2err = */deadbeef->junk_id3v2_read (it, fp);
@@ -1752,6 +1796,19 @@ ffap_insert (DB_playItem_t *after, const char *fname) {
}
deadbeef->pl_unlock ();
+ char s[100];
+ snprintf (s, sizeof (s), "%lld", fsize);
+ deadbeef->pl_add_meta (it, ":FILE_SIZE", s);
+ snprintf (s, sizeof (s), "%d", ape_ctx.bps);
+ deadbeef->pl_add_meta (it, ":BPS", s);
+ snprintf (s, sizeof (s), "%d", ape_ctx.channels);
+ deadbeef->pl_add_meta (it, ":CHANNELS", s);
+ snprintf (s, sizeof (s), "%d", ape_ctx.samplerate);
+ deadbeef->pl_add_meta (it, ":SAMPLERATE", s);
+ int br = (int)roundf(fsize / duration * 8 / 1000);
+ snprintf (s, sizeof (s), "%d", br);
+ deadbeef->pl_add_meta (it, ":BITRATE", s);
+
cue = deadbeef->pl_insert_cue (after, it, ape_ctx.totalsamples, ape_ctx.samplerate);
if (cue) {
deadbeef->pl_item_unref (it);
@@ -1760,6 +1817,7 @@ ffap_insert (DB_playItem_t *after, const char *fname) {
}
deadbeef->pl_add_meta (it, "title", NULL);
+
after = deadbeef->pl_insert_item (after, it);
deadbeef->pl_item_unref (it);
@@ -1767,11 +1825,14 @@ ffap_insert (DB_playItem_t *after, const char *fname) {
}
static int
-ffap_read_int16 (DB_fileinfo_t *_info, char *buffer, int size) {
+ffap_read (DB_fileinfo_t *_info, char *buffer, int size) {
ape_info_t *info = (ape_info_t*)_info;
- if (info->ape_ctx.currentsample + size / ((info->info.bps / 8) * info->ape_ctx.channels) > info->endsample) {
- size = (info->endsample - info->ape_ctx.currentsample + 1) * (info->info.bps / 8) * info->ape_ctx.channels;
- trace ("size truncated to %d bytes (%d samples), cursample=%d, info->endsample=%d, totalsamples=%d\n", size, size / (info->info.bps / 8) / info->ape_ctx.channels, info->ape_ctx.currentsample, info->endsample, info->ape_ctx.totalsamples);
+
+ int samplesize = _info->fmt.bps / 8 * info->ape_ctx.channels;
+
+ if (info->ape_ctx.currentsample + size / samplesize > info->endsample) {
+ size = (info->endsample - info->ape_ctx.currentsample + 1) * samplesize;
+ trace ("size truncated to %d bytes (%d samples), cursample=%d, info->endsample=%d, totalsamples=%d\n", size, size / samplesize, info->ape_ctx.currentsample, info->endsample, info->ape_ctx.totalsamples);
if (size <= 0) {
return 0;
}
@@ -1808,8 +1869,8 @@ ffap_read_int16 (DB_fileinfo_t *_info, char *buffer, int size) {
}
info->ape_ctx.remaining -= sz;
}
- info->ape_ctx.currentsample += (inits - size) / (2 * info->ape_ctx.channels);
- _info->readpos = (info->ape_ctx.currentsample-info->startsample) / (float)_info->samplerate;
+ info->ape_ctx.currentsample += (inits - size) / samplesize;
+ _info->readpos = (info->ape_ctx.currentsample-info->startsample) / (float)_info->fmt.samplerate;
return inits - size;
}
@@ -1844,12 +1905,12 @@ ffap_seek_sample (DB_fileinfo_t *_info, int sample) {
static int
ffap_seek (DB_fileinfo_t *_info, float seconds) {
- return ffap_seek_sample (_info, seconds * _info->samplerate);
+ return ffap_seek_sample (_info, seconds * _info->fmt.samplerate);
}
static int ffap_read_metadata (DB_playItem_t *it) {
- DB_FILE *fp = deadbeef->fopen (it->fname);
+ DB_FILE *fp = deadbeef->fopen (deadbeef->pl_find_meta (it, ":URI"));
if (!fp) {
return -1;
}
@@ -1899,19 +1960,37 @@ static const char *filetypes[] = { "APE", NULL };
// define plugin interface
static DB_decoder_t plugin = {
DB_PLUGIN_SET_API_VERSION
- .plugin.version_major = 0,
- .plugin.version_minor = 1,
+ .plugin.version_major = 1,
+ .plugin.version_minor = 0,
.plugin.type = DB_PLUGIN_DECODER,
.plugin.id = "ffap",
.plugin.name = "Monkey's Audio (APE) decoder",
.plugin.descr = "APE player based on code from libavc and rockbox",
- .plugin.author = "Alexey Yakovenko",
- .plugin.email = "waker@users.sourceforge.net",
+ .plugin.copyright =
+ "Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>\n"
+ "\n"
+ "based on apedec from FFMpeg Copyright (c) 2007 Benjamin Zores <ben@geexbox.org>\n"
+ "based upon libdemac from Dave Chapman.\n"
+ "\n"
+ "This program is free software; you can redistribute it and/or\n"
+ "modify it under the terms of the GNU General Public License\n"
+ "as published by the Free Software Foundation; either version 2\n"
+ "of the License, or (at your option) any later version.\n"
+ "\n"
+ "This program is distributed in the hope that it will be useful,\n"
+ "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+ "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+ "GNU General Public License for more details.\n"
+ "\n"
+ "You should have received a copy of the GNU General Public License\n"
+ "along with this program; if not, write to the Free Software\n"
+ "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n"
+ ,
.plugin.website = "http://deadbeef.sf.net",
.open = ffap_open,
.init = ffap_init,
.free = ffap_free,
- .read_int16 = ffap_read_int16,
+ .read = ffap_read,
.seek = ffap_seek,
.seek_sample = ffap_seek_sample,
.insert = ffap_insert,
diff --git a/plugins/ffmpeg/ChangeLog b/plugins/ffmpeg/ChangeLog
new file mode 100644
index 00000000..f3179866
--- /dev/null
+++ b/plugins/ffmpeg/ChangeLog
@@ -0,0 +1,5 @@
+version 1.2
+ Added AMR support via libopencore
+
+version 1.1
+ Switched to ffmpeg commit 25472
diff --git a/plugins/ffmpeg/ffmpeg.c b/plugins/ffmpeg/ffmpeg.c
index f27e403b..020f2a1c 100644
--- a/plugins/ffmpeg/ffmpeg.c
+++ b/plugins/ffmpeg/ffmpeg.c
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@@ -55,7 +55,11 @@
static DB_decoder_t plugin;
static DB_functions_t *deadbeef;
-static const char * exts[] = { "m4a", "wma", "aa3", "oma", "ac3", "vqf", NULL };
+#define DEFAULT_EXTS "m4a;wma;aa3;oma;ac3;vqf;amr"
+
+#define EXT_MAX 100
+
+static char * exts[EXT_MAX] = {NULL};
enum {
FT_ALAC = 0,
@@ -63,10 +67,11 @@ enum {
FT_ATRAC3 = 2,
FT_VQF = 3,
FT_AC3 = 4,
+ FT_AMR = 5,
FT_UNKNOWN = 5
};
-static const char *filetypes[] = { "ALAC", "WMA", "ATRAC3", "VQF", "AC3", "FFMPEG (unknown)", NULL };
+static const char *filetypes[] = { "FFMPEG", NULL };
#define FF_PROTOCOL_NAME "deadbeef"
@@ -93,7 +98,7 @@ static DB_playItem_t *current_track;
static DB_fileinfo_t *current_info;
static DB_fileinfo_t *
-ffmpeg_open (void) {
+ffmpeg_open (uint32_t hints) {
DB_fileinfo_t *_info = malloc (sizeof (ffmpeg_info_t));
memset (_info, 0, sizeof (ffmpeg_info_t));
return _info;
@@ -102,19 +107,19 @@ ffmpeg_open (void) {
static int
ffmpeg_init (DB_fileinfo_t *_info, DB_playItem_t *it) {
ffmpeg_info_t *info = (ffmpeg_info_t *)_info;
- trace ("ffmpeg init %s\n", it->fname);
+ trace ("ffmpeg init %s\n", deadbeef->pl_find_meta (it, ":URI"));
// prepare to decode the track
// return -1 on failure
int ret;
- int l = strlen (it->fname);
+ int l = strlen (deadbeef->pl_find_meta (it, ":URI"));
char *uri = alloca (l + sizeof (FF_PROTOCOL_NAME) + 1);
int i;
// construct uri
memcpy (uri, FF_PROTOCOL_NAME, sizeof (FF_PROTOCOL_NAME)-1);
memcpy (uri + sizeof (FF_PROTOCOL_NAME)-1, ":", 1);
- memcpy (uri + sizeof (FF_PROTOCOL_NAME), it->fname, l);
+ memcpy (uri + sizeof (FF_PROTOCOL_NAME), deadbeef->pl_find_meta (it, ":URI"), l);
uri[sizeof (FF_PROTOCOL_NAME) + l] = 0;
trace ("ffmpeg: uri: %s\n", uri);
@@ -149,10 +154,10 @@ ffmpeg_init (DB_fileinfo_t *_info, DB_playItem_t *it) {
if (info->codec == NULL)
{
- trace ("ffmpeg can't decode %s\n", it->fname);
+ trace ("ffmpeg can't decode %s\n", deadbeef->pl_find_meta (it, ":URI"));
return -1;
}
- trace ("ffmpeg can decode %s\n", it->fname);
+ trace ("ffmpeg can decode %s\n", deadbeef->pl_find_meta (it, ":URI"));
trace ("ffmpeg: codec=%s, stream=%d\n", info->codec->name, i);
if (avcodec_open (info->ctx, info->codec) < 0) {
@@ -160,18 +165,7 @@ ffmpeg_init (DB_fileinfo_t *_info, DB_playItem_t *it) {
return -1;
}
- if (!strcasecmp (info->codec->name, "alac")) {
- it->filetype = filetypes[FT_ALAC];
- }
- else if (strcasestr (info->codec->name, "wma")) {
- it->filetype = filetypes[FT_WMA];
- }
- else if (strcasestr (info->codec->name, "ac3")) {
- it->filetype = filetypes[FT_AC3];
- }
- else {
- it->filetype = filetypes[FT_UNKNOWN];
- }
+ deadbeef->pl_replace_meta (it, ":FILETYPE", info->codec->name);
int bps = av_get_bits_per_sample_format (info->ctx->sample_fmt);
int samplerate = info->ctx->sample_rate;
@@ -196,9 +190,20 @@ ffmpeg_init (DB_fileinfo_t *_info, DB_playItem_t *it) {
// fill in mandatory plugin fields
_info->plugin = &plugin;
_info->readpos = 0;
- _info->bps = bps;
- _info->channels = info->ctx->channels;
- _info->samplerate = samplerate;
+ _info->fmt.bps = bps;
+ _info->fmt.channels = info->ctx->channels;
+ _info->fmt.samplerate = samplerate;
+
+
+ int64_t layout = info->ctx->channel_layout;
+ if (layout != 0, 0) {
+ _info->fmt.channelmask = layout;
+ }
+ else {
+ for (int i = 0; i < _info->fmt.channels; i++) {
+ _info->fmt.channelmask |= 1 << i;
+ }
+ }
// subtrack info
info->currentsample = 0;
@@ -222,7 +227,7 @@ ffmpeg_free (DB_fileinfo_t *_info) {
if (info->buffer) {
free (info->buffer);
}
- // free everything allocated in _init and _read_int16
+ // free everything allocated in _init and _read
if (info->have_packet) {
av_free_packet (&info->pkt);
}
@@ -237,14 +242,14 @@ ffmpeg_free (DB_fileinfo_t *_info) {
}
static int
-ffmpeg_read_int16 (DB_fileinfo_t *_info, char *bytes, int size) {
+ffmpeg_read (DB_fileinfo_t *_info, char *bytes, int size) {
trace ("ffmpeg_read_int16 %d\n", size);
ffmpeg_info_t *info = (ffmpeg_info_t*)_info;
- int out_ch = min (2, _info->channels);
+ int samplesize = _info->fmt.channels * _info->fmt.bps / 8;
- if (info->endsample >= 0 && info->currentsample + size / (2 * out_ch) > info->endsample) {
- size = (info->endsample - info->currentsample + 1) * 2 * out_ch;
+ if (info->endsample >= 0 && info->currentsample + size / samplesize > info->endsample) {
+ size = (info->endsample - info->currentsample + 1) * samplesize;
if (size <= 0) {
return 0;
}
@@ -259,20 +264,13 @@ ffmpeg_read_int16 (DB_fileinfo_t *_info, char *bytes, int size) {
if (info->left_in_buffer > 0) {
// int sz = min (size, info->left_in_buffer);
- int nsamples = size / out_ch / 2;
- int nsamples_buf = info->left_in_buffer / 2 / _info->channels;
+ int nsamples = size / samplesize;
+ int nsamples_buf = info->left_in_buffer / samplesize;
nsamples = min (nsamples, nsamples_buf);
- int sz = nsamples * 2 * _info->channels;
- for (int i = 0; i < nsamples; i++) {
- *((int16_t*)bytes) = ((int16_t*)info->buffer)[i * _info->channels + 0];
- bytes += 2;
- size -= 2;
- if (out_ch > 1) {
- *((int16_t*)bytes) = ((int16_t*)info->buffer)[i * _info->channels + 1];
- bytes += 2;
- size -= 2;
- }
- }
+ int sz = nsamples * samplesize;
+ memcpy (bytes, info->buffer, nsamples*samplesize);
+ bytes += nsamples * samplesize;
+ size -= nsamples * samplesize;
if (sz != info->left_in_buffer) {
memmove (info->buffer, info->buffer+sz, info->left_in_buffer-sz);
}
@@ -359,8 +357,8 @@ ffmpeg_read_int16 (DB_fileinfo_t *_info, char *bytes, int size) {
}
}
- info->currentsample += (initsize-size) / (2 * out_ch);
- _info->readpos = (float)info->currentsample / _info->samplerate;
+ info->currentsample += (initsize-size) / samplesize;
+ _info->readpos = (float)info->currentsample / _info->fmt.samplerate;
return initsize-size;
}
@@ -376,7 +374,7 @@ ffmpeg_seek_sample (DB_fileinfo_t *_info, int sample) {
info->have_packet = 0;
}
sample += info->startsample;
- int64_t tm = (int64_t)sample/ _info->samplerate * AV_TIME_BASE;
+ int64_t tm = (int64_t)sample/ _info->fmt.samplerate * AV_TIME_BASE;
trace ("ffmpeg: seek to sample: %d, t: %d\n", sample, (int)tm);
info->left_in_packet = 0;
info->left_in_buffer = 0;
@@ -387,7 +385,7 @@ ffmpeg_seek_sample (DB_fileinfo_t *_info, int sample) {
// update readpos
info->currentsample = sample;
- _info->readpos = (float)(sample - info->startsample) / _info->samplerate;
+ _info->readpos = (float)(sample - info->startsample) / _info->fmt.samplerate;
return 0;
}
@@ -397,7 +395,7 @@ ffmpeg_seek (DB_fileinfo_t *_info, float time) {
// seek to specified time in seconds
// return 0 on success
// return -1 on failure
- return ffmpeg_seek_sample (_info, time * _info->samplerate);
+ return ffmpeg_seek_sample (_info, time * _info->fmt.samplerate);
}
static const char *map[] = {
@@ -529,13 +527,11 @@ ffmpeg_insert (DB_playItem_t *after, const char *fname) {
int totalsamples = fctx->duration * samplerate / AV_TIME_BASE;
- DB_playItem_t *it = deadbeef->pl_item_alloc ();
- it->decoder_id = deadbeef->plug_get_decoder_id (plugin.plugin.id);
- it->fname = strdup (fname);
+ DB_playItem_t *it = deadbeef->pl_item_alloc_init (fname, plugin.plugin.id);
// FIXME: get proper codec
- it->filetype = filetypes[FT_UNKNOWN];
+ deadbeef->pl_replace_meta (it, ":FILETYPE", codec->name);
- if (!deadbeef->is_local_file (it->fname)) {
+ if (!deadbeef->is_local_file (deadbeef->pl_find_meta (it, ":URI"))) {
deadbeef->pl_set_item_duration (it, -1);
}
else {
@@ -544,6 +540,32 @@ ffmpeg_insert (DB_playItem_t *after, const char *fname) {
// add metainfo
ffmpeg_read_metadata_internal (it, fctx);
+
+ int64_t fsize = -1;
+
+ DB_FILE *fp = deadbeef->fopen (deadbeef->pl_find_meta (it, ":URI"));
+ if (fp) {
+ if (!fp->vfs->is_streaming ()) {
+ fsize = deadbeef->fgetlength (fp);
+ }
+ deadbeef->fclose (fp);
+ }
+
+ if (fsize >= 0 && duration > 0) {
+ char s[100];
+ snprintf (s, sizeof (s), "%lld", fsize);
+ deadbeef->pl_add_meta (it, ":FILE_SIZE", s);
+ snprintf (s, sizeof (s), "%d", av_get_bits_per_sample_format (ctx->sample_fmt));
+ deadbeef->pl_add_meta (it, ":BPS", s);
+ snprintf (s, sizeof (s), "%d", ctx->channels);
+ deadbeef->pl_add_meta (it, ":CHANNELS", s);
+ snprintf (s, sizeof (s), "%d", samplerate);
+ deadbeef->pl_add_meta (it, ":SAMPLERATE", s);
+ int br = (int)roundf(fsize / duration * 8 / 1000);
+ snprintf (s, sizeof (s), "%d", br);
+ deadbeef->pl_add_meta (it, ":BITRATE", s);
+ }
+
// free decoder
avcodec_close (ctx);
av_close_input_file(fctx);
@@ -576,7 +598,7 @@ ffmpeg_vfs_open(URLContext *h, const char *filename, int flags)
if (f == NULL)
return -ENOENT;
- if (f->vfs->streaming) {
+ if (f->vfs->is_streaming ()) {
deadbeef->fset_track (f, current_track);
if (current_info) {
current_info->file = f;
@@ -608,9 +630,9 @@ ffmpeg_vfs_seek(URLContext *h, int64_t pos, int whence)
DB_FILE *f = h->priv_data;
if (whence == AVSEEK_SIZE) {
- return f->vfs->streaming ? -1 : deadbeef->fgetlength (h->priv_data);
+ return f->vfs->is_streaming () ? -1 : deadbeef->fgetlength (h->priv_data);
}
- else if (f->vfs->streaming) {
+ else if (f->vfs->is_streaming ()) {
return -1;
}
else {
@@ -636,12 +658,50 @@ static URLProtocol vfswrapper = {
.url_close = ffmpeg_vfs_close,
};
+static void
+ffmpeg_init_exts (void) {
+ deadbeef->conf_lock ();
+ const char *new_exts = deadbeef->conf_get_str_fast ("ffmpeg.extensions", DEFAULT_EXTS);
+ for (int i = 0; exts[i]; i++) {
+ free (exts[i]);
+ }
+ exts[0] = NULL;
+
+ int n = 0;
+ while (*new_exts) {
+ if (n >= EXT_MAX) {
+ fprintf (stderr, "ffmpeg: too many extensions, max is %d\n", EXT_MAX);
+ break;
+ }
+ const char *e = new_exts;
+ while (*e && *e != ';') {
+ e++;
+ }
+ if (e != new_exts) {
+ char *ext = malloc (e-new_exts+1);
+ memcpy (ext, new_exts, e-new_exts);
+ ext[e-new_exts] = 0;
+ exts[n++] = ext;
+ }
+ if (*e == 0) {
+ break;
+ }
+ new_exts = e+1;
+ }
+ exts[n] = NULL;
+ deadbeef->conf_unlock ();
+}
+
+static int
+ffmpeg_on_configchanged (DB_event_t *ev, uintptr_t data) {
+ ffmpeg_init_exts ();
+ return 0;
+}
+
static int
ffmpeg_start (void) {
- // do one-time plugin initialization here
- // e.g. starting threads for background processing, subscribing to events, etc
- // return 0 on success
- // return -1 on failure
+ ffmpeg_init_exts ();
+ deadbeef->ev_subscribe (DB_PLUGIN (&plugin), DB_EV_CONFIGCHANGED, DB_CALLBACK (ffmpeg_on_configchanged), 0);
avcodec_init ();
av_register_all ();
av_register_protocol (&vfswrapper);
@@ -650,28 +710,29 @@ ffmpeg_start (void) {
static int
ffmpeg_stop (void) {
- // undo everything done in _start here
- // return 0 on success
- // return -1 on failure
- trace ("ffmpeg stop\n");
+ deadbeef->ev_unsubscribe (DB_PLUGIN (&plugin), DB_EV_CONFIGCHANGED, DB_CALLBACK (ffmpeg_on_configchanged), 0);
+ for (int i = 0; exts[i]; i++) {
+ free (exts[i]);
+ }
+ exts[0] = NULL;
return 0;
}
int
ffmpeg_read_metadata (DB_playItem_t *it) {
- trace ("ffmpeg_read_metadata: fname %s\n", it->fname);
+ trace ("ffmpeg_read_metadata: fname %s\n", deadbeef->pl_find_meta (it, ":URI"));
AVCodec *codec = NULL;
AVCodecContext *ctx = NULL;
AVFormatContext *fctx = NULL;
int ret;
- int l = strlen (it->fname);
+ int l = strlen (deadbeef->pl_find_meta (it, ":URI"));
char *uri = alloca (l + sizeof (FF_PROTOCOL_NAME) + 1);
int i;
// construct uri
memcpy (uri, FF_PROTOCOL_NAME, sizeof (FF_PROTOCOL_NAME)-1);
memcpy (uri + sizeof (FF_PROTOCOL_NAME)-1, ":", 1);
- memcpy (uri + sizeof (FF_PROTOCOL_NAME), it->fname, l);
+ memcpy (uri + sizeof (FF_PROTOCOL_NAME), deadbeef->pl_find_meta (it, ":URI"), l);
uri[sizeof (FF_PROTOCOL_NAME) + l] = 0;
trace ("ffmpeg: uri: %s\n", uri);
@@ -694,7 +755,7 @@ ffmpeg_read_metadata (DB_playItem_t *it) {
}
if (codec == NULL)
{
- trace ("ffmpeg can't decode %s\n", it->fname);
+ trace ("ffmpeg can't decode %s\n", deadbeef->pl_find_meta (it, ":URI"));
av_close_input_file(fctx);
return -1;
}
@@ -711,30 +772,49 @@ ffmpeg_read_metadata (DB_playItem_t *it) {
return 0;
}
+static const char settings_dlg[] =
+ "property \"File Extensions (separate with ';')\" entry ffmpeg.extensions \"" DEFAULT_EXTS "\";\n"
+;
+
// define plugin interface
static DB_decoder_t plugin = {
DB_PLUGIN_SET_API_VERSION
- .plugin.version_major = 0,
- .plugin.version_minor = 1,
+ .plugin.version_major = 1,
+ .plugin.version_minor = 2,
.plugin.type = DB_PLUGIN_DECODER,
.plugin.id = "ffmpeg",
.plugin.name = "FFMPEG audio player",
.plugin.descr = "decodes audio formats using FFMPEG libavcodec",
- .plugin.author = "Alexey Yakovenko",
- .plugin.email = "waker@users.sourceforge.net",
+ .plugin.copyright =
+ "Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>\n"
+ "\n"
+ "This program is free software; you can redistribute it and/or\n"
+ "modify it under the terms of the GNU General Public License\n"
+ "as published by the Free Software Foundation; either version 2\n"
+ "of the License, or (at your option) any later version.\n"
+ "\n"
+ "This program is distributed in the hope that it will be useful,\n"
+ "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+ "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+ "GNU General Public License for more details.\n"
+ "\n"
+ "You should have received a copy of the GNU General Public License\n"
+ "along with this program; if not, write to the Free Software\n"
+ "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n"
+ ,
.plugin.website = "http://deadbeef.sf.net",
.plugin.start = ffmpeg_start,
.plugin.stop = ffmpeg_stop,
+ .plugin.configdialog = settings_dlg,
.open = ffmpeg_open,
.init = ffmpeg_init,
.free = ffmpeg_free,
- .read_int16 = ffmpeg_read_int16,
-// .read_float32 = ffmpeg_read_float32,
+ .read = ffmpeg_read,
.seek = ffmpeg_seek,
.seek_sample = ffmpeg_seek_sample,
.insert = ffmpeg_insert,
.read_metadata = ffmpeg_read_metadata,
- .exts = exts,
+ .exts = (const char **)exts,
.filetypes = filetypes
};
diff --git a/plugins/flac/flac.c b/plugins/flac/flac.c
index 00cdf598..6c136e9d 100644
--- a/plugins/flac/flac.c
+++ b/plugins/flac/flac.c
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -20,6 +20,7 @@
#include <stdlib.h>
#include <FLAC/stream_decoder.h>
#include <FLAC/metadata.h>
+#include <math.h>
#include "../../deadbeef.h"
static DB_decoder_t plugin;
@@ -38,12 +39,13 @@ typedef struct {
FLAC__StreamDecoder *decoder;
char *buffer; // this buffer always has float samples
int remaining; // bytes remaining in buffer from last read
- int startsample;
- int endsample;
- int currentsample;
- int totalsamples;
+ int64_t startsample;
+ int64_t endsample;
+ int64_t currentsample;
+ int64_t totalsamples;
int flac_critical_error;
int init_stop_decoding;
+ int tagsize;
DB_FILE *file;
// used only on insert
@@ -104,24 +106,52 @@ cflac_write_callback (const FLAC__StreamDecoder *decoder, const FLAC__Frame *fra
if (info->bitrate > 0) {
deadbeef->streamer_set_bitrate (info->bitrate);
}
+ int samplesize = _info->fmt.channels * _info->fmt.bps / 8;
int bufsize = BUFFERSIZE - info->remaining;
- int bufsamples = bufsize / (_info->channels * _info->bps / 8);
+ int bufsamples = bufsize / samplesize;
int nsamples = min (bufsamples, frame->header.blocksize);
char *bufptr = &info->buffer[info->remaining];
- float mul = 1.f/ ((1 << (_info->bps-1))-1);
- int channels = _info->channels;
- if (channels > 2) {
- channels = 2;
- }
- int readbytes = frame->header.blocksize * channels * _info->bps / 8;
+ int readbytes = frame->header.blocksize * samplesize;
- for (int i = 0; i < nsamples; i++) {
- for (int c = 0; c < channels; c++) {
- int32_t sample = inputbuffer[c][i];
- *((float*)bufptr) = sample * mul;
- bufptr += sizeof (float);
- info->remaining += sizeof (float);
+ if (_info->fmt.bps == 32) {
+ for (int i = 0; i < nsamples; i++) {
+ for (int c = 0; c < _info->fmt.channels; c++) {
+ int32_t sample = inputbuffer[c][i];
+ *((int32_t*)bufptr) = sample;
+ bufptr += 4;
+ info->remaining += 4;
+ }
+ }
+ }
+ else if (_info->fmt.bps == 24) {
+ for (int i = 0; i < nsamples; i++) {
+ for (int c = 0; c < _info->fmt.channels; c++) {
+ int32_t sample = inputbuffer[c][i];
+ *bufptr++ = sample&0xff;
+ *bufptr++ = (sample&0xff00)>>8;
+ *bufptr++ = (sample&0xff0000)>>16;
+ info->remaining += 3;
+ }
+ }
+ }
+ else if (_info->fmt.bps == 16) {
+ for (int i = 0; i < nsamples; i++) {
+ for (int c = 0; c < _info->fmt.channels; c++) {
+ int32_t sample = inputbuffer[c][i];
+ *bufptr++ = sample&0xff;
+ *bufptr++ = (sample&0xff00)>>8;
+ info->remaining += 2;
+ }
+ }
+ }
+ else if (_info->fmt.bps == 8) {
+ for (int i = 0; i < nsamples; i++) {
+ for (int c = 0; c < _info->fmt.channels; c++) {
+ int32_t sample = inputbuffer[c][i];
+ *bufptr++ = sample&0xff;
+ info->remaining += 1;
+ }
}
}
if (readbytes > bufsize) {
@@ -136,10 +166,12 @@ cflac_metadata_callback(const FLAC__StreamDecoder *decoder, const FLAC__StreamMe
DB_fileinfo_t *_info = (DB_fileinfo_t *)client_data;
flac_info_t *info = (flac_info_t *)_info;
info->totalsamples = metadata->data.stream_info.total_samples;
- _info->samplerate = metadata->data.stream_info.sample_rate;
- _info->channels = metadata->data.stream_info.channels;
- _info->bps = metadata->data.stream_info.bits_per_sample;
-
+ _info->fmt.samplerate = metadata->data.stream_info.sample_rate;
+ _info->fmt.channels = metadata->data.stream_info.channels;
+ _info->fmt.bps = metadata->data.stream_info.bits_per_sample;
+ for (int i = 0; i < _info->fmt.channels; i++) {
+ _info->fmt.channelmask |= 1 << i;
+ }
}
static void
@@ -164,7 +196,7 @@ cflac_init_error_callback(const FLAC__StreamDecoder *decoder, FLAC__StreamDecode
}
static DB_fileinfo_t *
-cflac_open (void) {
+cflac_open (uint32_t hints) {
DB_fileinfo_t *_info = malloc (sizeof (flac_info_t));
memset (_info, 0, sizeof (flac_info_t));
return _info;
@@ -172,10 +204,10 @@ cflac_open (void) {
static int
cflac_init (DB_fileinfo_t *_info, DB_playItem_t *it) {
- trace ("cflac_init %s\n", it->fname);
+ trace ("cflac_init %s\n", deadbeef->pl_find_meta (it, ":URI"));
flac_info_t *info = (flac_info_t *)_info;
- info->file = deadbeef->fopen (it->fname);
+ info->file = deadbeef->fopen (deadbeef->pl_find_meta (it, ":URI"));
if (!info->file) {
trace ("cflac_init failed to open file\n");
return -1;
@@ -183,8 +215,8 @@ cflac_init (DB_fileinfo_t *_info, DB_playItem_t *it) {
info->flac_critical_error = 0;
- const char *ext = it->fname + strlen (it->fname);
- while (ext > it->fname && *ext != '/' && *ext != '.') {
+ const char *ext = deadbeef->pl_find_meta (it, ":URI") + strlen (deadbeef->pl_find_meta (it, ":URI"));
+ while (ext > deadbeef->pl_find_meta (it, ":URI") && *ext != '/' && *ext != '.') {
ext--;
}
if (*ext == '.') {
@@ -237,7 +269,7 @@ cflac_init (DB_fileinfo_t *_info, DB_playItem_t *it) {
trace ("cflac_init bad decoder status\n");
return -1;
}
- //_info->samplerate = -1;
+ //_info->fmt.samplerate = -1;
if (!FLAC__stream_decoder_process_until_end_of_metadata (info->decoder)) {
trace ("cflac_init metadata failed\n");
return -1;
@@ -247,7 +279,7 @@ cflac_init (DB_fileinfo_t *_info, DB_playItem_t *it) {
_info->plugin = &plugin;
_info->readpos = 0;
- if (_info->samplerate <= 0) { // not a FLAC stream
+ if (_info->fmt.samplerate <= 0) { // not a FLAC stream
fprintf (stderr, "corrupted/invalid flac stream\n");
return -1;
}
@@ -259,14 +291,24 @@ cflac_init (DB_fileinfo_t *_info, DB_playItem_t *it) {
if (res) {
fsize -= position;
}
- FLAC__uint64 flac_totalsamples = FLAC__stream_decoder_get_total_samples (info->decoder);
- float sec = flac_totalsamples / _info->samplerate;
+ int64_t totalsamples = FLAC__stream_decoder_get_total_samples (info->decoder);
+ if (totalsamples <= 0) {
+ return -1;
+ }
+ float sec = totalsamples / (float)_info->fmt.samplerate;
if (sec > 0) {
info->bitrate = fsize / sec * 8 / 1000;
}
else {
info->bitrate = -1;
}
+ const char *channelmask = deadbeef->pl_find_meta (it, "WAVEFORMAT_EXTENSIBLE_CHANNELMASK");
+ if (channelmask) {
+ uint32_t cm = 0;
+ if (1 == sscanf (channelmask, "0x%X", &cm)) {
+ _info->fmt.channelmask = cm;
+ }
+ }
info->buffer = malloc (BUFFERSIZE);
info->remaining = 0;
@@ -304,53 +346,39 @@ cflac_free (DB_fileinfo_t *_info) {
if (info->buffer) {
free (info->buffer);
}
+ if (info->file) {
+ deadbeef->fclose (info->file);
+ }
free (_info);
}
}
static int
-cflac_read_int16 (DB_fileinfo_t *_info, char *bytes, int size) {
+cflac_read (DB_fileinfo_t *_info, char *bytes, int size) {
flac_info_t *info = (flac_info_t *)_info;
- if (size / (2 * _info->channels) + info->currentsample > info->endsample) {
- size = (info->endsample - info->currentsample + 1) * 2 * _info->channels;
+ int samplesize = _info->fmt.channels * _info->fmt.bps / 8;
+ if (size / samplesize + info->currentsample > info->endsample) {
+ size = (info->endsample - info->currentsample + 1) * samplesize;
trace ("size truncated to %d bytes, cursample=%d, endsample=%d\n", size, info->currentsample, info->endsample);
if (size <= 0) {
return 0;
}
}
- int n_output_channels = _info->channels;
- if (n_output_channels > 2) {
- n_output_channels = 2;
- }
int initsize = size;
do {
if (info->remaining) {
- int n_input_frames = info->remaining / sizeof (float) / n_output_channels;
- int n_output_frames = size / n_output_channels / sizeof (int16_t);
- int n = min (n_input_frames, n_output_frames);
+ int sz = min(size, info->remaining);
+ memcpy (bytes, info->buffer, sz);
-// trace ("flac: [1] if=%d, of=%d, n=%d, rem=%d, size=%d\n", n_input_frames, n_output_frames, n, info->remaining, size);
- // convert from float to int16
- float *in = (float *)info->buffer;
- for (int i = 0; i < n; i++) {
- *((int16_t *)bytes) = (int16_t)((*in) * 0x7fff);
- size -= sizeof (int16_t);
- bytes += sizeof (int16_t);
- if (n_output_channels == 2) {
- *((int16_t *)bytes) = (int16_t)((*(in+1)) * 0x7fff);
- size -= sizeof (int16_t);
- bytes += sizeof (int16_t);
- }
- in += n_output_channels;
- }
- int sz = n * sizeof (float) * n_output_channels;
+ size -= sz;
+ bytes += sz;
if (sz < info->remaining) {
memmove (info->buffer, &info->buffer[sz], info->remaining - sz);
}
info->remaining -= sz;
- info->currentsample += n;
- _info->readpos += (float)n / _info->samplerate;
-// trace ("flac: [2] if=%d, of=%d, n=%d, rem=%d, size=%d\n", n_input_frames, n_output_frames, n, info->remaining, size);
+ int n = sz / samplesize;
+ info->currentsample += sz / samplesize;
+ _info->readpos += (float)n / _info->fmt.samplerate;
}
if (!size) {
break;
@@ -372,17 +400,18 @@ cflac_read_int16 (DB_fileinfo_t *_info, char *bytes, int size) {
return initsize - size;
}
+#if 0
static int
cflac_read_float32 (DB_fileinfo_t *_info, char *bytes, int size) {
flac_info_t *info = (flac_info_t *)_info;
- if (size / (4 * _info->channels) + info->currentsample > info->endsample) {
- size = (info->endsample - info->currentsample + 1) * 4 * _info->channels;
+ if (size / (4 * _info->fmt.channels) + info->currentsample > info->endsample) {
+ size = (info->endsample - info->currentsample + 1) * 4 * _info->fmt.channels;
trace ("size truncated to %d bytes, cursample=%d, endsample=%d\n", size, info->currentsample, info->endsample);
if (size <= 0) {
return 0;
}
}
- int n_output_channels = _info->channels;
+ int n_output_channels = _info->fmt.channels;
if (n_output_channels > 2) {
n_output_channels = 2;
}
@@ -411,7 +440,7 @@ cflac_read_float32 (DB_fileinfo_t *_info, char *bytes, int size) {
}
info->remaining -= sz;
info->currentsample += n;
- _info->readpos += (float)n / _info->samplerate;
+ _info->readpos += (float)n / _info->fmt.samplerate;
}
if (!size) {
break;
@@ -432,6 +461,7 @@ cflac_read_float32 (DB_fileinfo_t *_info, char *bytes, int size) {
return initsize - size;
}
+#endif
static int
cflac_seek_sample (DB_fileinfo_t *_info, int sample) {
@@ -442,13 +472,13 @@ cflac_seek_sample (DB_fileinfo_t *_info, int sample) {
if (!FLAC__stream_decoder_seek_absolute (info->decoder, (FLAC__uint64)(sample))) {
return -1;
}
- _info->readpos = (float)(sample - info->startsample)/ _info->samplerate;
+ _info->readpos = (float)(sample - info->startsample)/ _info->fmt.samplerate;
return 0;
}
static int
cflac_seek (DB_fileinfo_t *_info, float time) {
- return cflac_seek_sample (_info, time * _info->samplerate);
+ return cflac_seek_sample (_info, time * _info->fmt.samplerate);
}
static FLAC__StreamDecoderWriteStatus
@@ -493,13 +523,53 @@ static const char *metainfo[] = {
"DISCNUMBER", "disc",
"COPYRIGHT", "copyright",
"TOTALTRACKS", "numtracks",
+ "TRACKTOTAL", "numtracks",
"ALBUM ARTIST", "band",
NULL
};
static void
+cflac_add_metadata (DB_playItem_t *it, char *s, int length) {
+ int m;
+ for (m = 0; metainfo[m]; m += 2) {
+ int l = strlen (metainfo[m]);
+ if (length > l && !strncasecmp (metainfo[m], s, l) && s[l] == '=') {
+ deadbeef->pl_append_meta (it, metainfo[m+1], s + l + 1);
+ break;
+ }
+ }
+ if (!metainfo[m]) {
+ if (!strncasecmp (s, "CUESHEET=", 9)) {
+ deadbeef->pl_add_meta (it, "cuesheet", s + 9);
+ }
+ else if (!strncasecmp (s, "replaygain_album_gain=", 22)) {
+ deadbeef->pl_set_item_replaygain (it, DDB_REPLAYGAIN_ALBUMGAIN, atof (s+22));
+ }
+ else if (!strncasecmp (s, "replaygain_album_peak=", 22)) {
+ deadbeef->pl_set_item_replaygain (it, DDB_REPLAYGAIN_ALBUMPEAK, atof (s+22));
+ }
+ else if (!strncasecmp (s, "replaygain_track_gain=", 22)) {
+ deadbeef->pl_set_item_replaygain (it, DDB_REPLAYGAIN_TRACKGAIN, atof (s+22));
+ }
+ else if (!strncasecmp (s, "replaygain_track_peak=", 22)) {
+ deadbeef->pl_set_item_replaygain (it, DDB_REPLAYGAIN_TRACKPEAK, atof (s+22));
+ }
+ else {
+ const char *eq = strchr (s, '=');
+ if (eq) {
+ char key[eq - s+1];
+ strncpy (key, s, eq-s);
+ key[eq-s] = 0;
+ deadbeef->pl_append_meta (it, key, eq+1);
+ }
+ }
+ }
+}
+
+static void
cflac_init_metadata_callback(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data) {
flac_info_t *info = (flac_info_t *)client_data;
+ info->tagsize += metadata->length;
DB_fileinfo_t *_info = &info->info;
if (info->init_stop_decoding) {
trace ("error flag is set, ignoring init_metadata callback..\n");
@@ -508,9 +578,10 @@ cflac_init_metadata_callback(const FLAC__StreamDecoder *decoder, const FLAC__Str
DB_playItem_t *it = info->it;
//it->tracknum = 0;
if (metadata->type == FLAC__METADATA_TYPE_STREAMINFO) {
- trace ("flac: samplerate=%d, channels=%d\n", metadata->data.stream_info.sample_rate, metadata->data.stream_info.channels);
- _info->samplerate = metadata->data.stream_info.sample_rate;
- _info->channels = metadata->data.stream_info.channels;
+ trace ("flac: samplerate=%d, channels=%d, totalsamples=%d\n", metadata->data.stream_info.sample_rate, metadata->data.stream_info.channels, metadata->data.stream_info.total_samples);
+ _info->fmt.samplerate = metadata->data.stream_info.sample_rate;
+ _info->fmt.channels = metadata->data.stream_info.channels;
+ _info->fmt.bps = metadata->data.stream_info.bits_per_sample;
info->totalsamples = metadata->data.stream_info.total_samples;
deadbeef->pl_set_item_duration (it, metadata->data.stream_info.total_samples / (float)metadata->data.stream_info.sample_rate);
}
@@ -520,30 +591,7 @@ cflac_init_metadata_callback(const FLAC__StreamDecoder *decoder, const FLAC__Str
const FLAC__StreamMetadata_VorbisComment_Entry *c = &vc->comments[i];
if (c->length > 0) {
char *s = c->entry;
- int m;
- for (m = 0; metainfo[m]; m += 2) {
- int l = strlen (metainfo[m]);
- if (c->length > l && !strncasecmp (metainfo[m], s, l) && s[l] == '=') {
- deadbeef->pl_append_meta (it, metainfo[m+1], s + l + 1);
- }
- }
- if (!metainfo[m]) {
- if (!strncasecmp (s, "CUESHEET=", 9)) {
- deadbeef->pl_add_meta (it, "cuesheet", s + 9);
- }
- else if (!strncasecmp (s, "replaygain_album_gain=", 22)) {
- it->replaygain_album_gain = atof (s + 22);
- }
- else if (!strncasecmp (s, "replaygain_album_peak=", 22)) {
- it->replaygain_album_peak = atof (s + 22);
- }
- else if (!strncasecmp (s, "replaygain_track_gain=", 22)) {
- it->replaygain_track_gain = atof (s + 22);
- }
- else if (!strncasecmp (s, "replaygain_track_peak=", 22)) {
- it->replaygain_track_peak = atof (s + 22);
- }
- }
+ cflac_add_metadata (it, s, c->length);
}
}
deadbeef->pl_add_meta (it, "title", NULL);
@@ -621,9 +669,7 @@ cflac_insert (DB_playItem_t *after, const char *fname) {
// read all metadata
FLAC__stream_decoder_set_md5_checking(decoder, 0);
FLAC__stream_decoder_set_metadata_respond_all (decoder);
- it = deadbeef->pl_item_alloc ();
- it->decoder_id = deadbeef->plug_get_decoder_id (plugin.plugin.id);
- it->fname = strdup (fname);
+ it = deadbeef->pl_item_alloc_init (fname, plugin.plugin.id);
info.it = it;
if (skip > 0) {
deadbeef->fseek (info.file, skip, SEEK_SET);
@@ -648,12 +694,25 @@ cflac_insert (DB_playItem_t *after, const char *fname) {
}
FLAC__stream_decoder_delete(decoder);
decoder = NULL;
- it->filetype = isogg ? "OggFLAC" : "FLAC";
+ deadbeef->pl_add_meta (it, ":FILETYPE", isogg ? "OggFLAC" : "FLAC");
+
+ char s[100];
+ int64_t fsize = deadbeef->fgetlength (info.file);
+ snprintf (s, sizeof (s), "%lld", fsize);
+ deadbeef->pl_add_meta (it, ":FILE_SIZE", s);
+ snprintf (s, sizeof (s), "%d", info.info.fmt.channels);
+ deadbeef->pl_add_meta (it, ":CHANNELS", s);
+ snprintf (s, sizeof (s), "%d", info.info.fmt.bps);
+ deadbeef->pl_add_meta (it, ":BPS", s);
+ snprintf (s, sizeof (s), "%d", info.info.fmt.samplerate);
+ deadbeef->pl_add_meta (it, ":SAMPLERATE", s);
+ snprintf (s, sizeof (s), "%d", (int)roundf((fsize-info.tagsize) / deadbeef->pl_get_item_duration (it) * 8 / 1000));
+ deadbeef->pl_add_meta (it, ":BITRATE", s);
// try embedded cue
const char *cuesheet = deadbeef->pl_find_meta (it, "cuesheet");
if (cuesheet) {
- DB_playItem_t *last = deadbeef->pl_insert_cue_from_buffer (after, it, cuesheet, strlen (cuesheet), info.totalsamples, info.info.samplerate);
+ DB_playItem_t *last = deadbeef->pl_insert_cue_from_buffer (after, it, cuesheet, strlen (cuesheet), info.totalsamples, info.info.fmt.samplerate);
if (last) {
deadbeef->pl_item_unref (it);
deadbeef->pl_item_unref (last);
@@ -662,7 +721,7 @@ cflac_insert (DB_playItem_t *after, const char *fname) {
}
// try external cue
- DB_playItem_t *cue_after = deadbeef->pl_insert_cue (after, it, info.totalsamples, info.info.samplerate);
+ DB_playItem_t *cue_after = deadbeef->pl_insert_cue (after, it, info.totalsamples, info.info.fmt.samplerate);
if (cue_after) {
if (info.file) {
deadbeef->fclose (info.file);
@@ -702,7 +761,7 @@ cflac_read_metadata (DB_playItem_t *it) {
trace ("cflac_read_metadata: FLAC__metadata_chain_new failed\n");
return -1;
}
- FLAC__bool res = FLAC__metadata_chain_read (chain, it->fname);
+ FLAC__bool res = FLAC__metadata_chain_read (chain, deadbeef->pl_find_meta (it, ":URI"));
if (!res) {
trace ("cflac_read_metadata: FLAC__metadata_chain_read failed\n");
goto error;
@@ -719,17 +778,20 @@ cflac_read_metadata (DB_playItem_t *it) {
do {
FLAC__StreamMetadata *data = FLAC__metadata_iterator_get_block (iter);
if (data && data->type == FLAC__METADATA_TYPE_VORBIS_COMMENT) {
- // delete all crap
- for (int m = 0; metainfo[m]; m += 2) {
- int offs = 0;
- do {
- offs = FLAC__metadata_object_vorbiscomment_find_entry_from (data, offs, metainfo[m]);
- if (offs != -1) {
- FLAC__StreamMetadata_VorbisComment_Entry *comm = &data->data.vorbis_comment.comments[offs];
- deadbeef->pl_append_meta (it, metainfo[m+1], comm->entry + strlen (metainfo[m])+1);
- offs++;
- }
- } while (offs != -1);
+ const FLAC__StreamMetadata_VorbisComment *vc = &data->data.vorbis_comment;
+ for (int i = 0; i < vc->num_comments; i++) {
+ const FLAC__StreamMetadata_VorbisComment_Entry *c = &vc->comments[i];
+ if (c->length > 0) {
+ char *s = c->entry;
+ cflac_add_metadata (it, s, c->length);
+ }
+ }
+ deadbeef->pl_add_meta (it, "title", NULL);
+ if (vc->num_comments > 0) {
+ uint32_t f = deadbeef->pl_get_item_flags (it);
+ f &= ~DDB_TAG_MASK;
+ f |= DDB_TAG_VORBISCOMMENTS;
+ deadbeef->pl_set_item_flags (it, f);
}
}
} while (FLAC__metadata_iterator_next (iter));
@@ -764,7 +826,7 @@ cflac_write_metadata (DB_playItem_t *it) {
trace ("cflac_write_metadata: FLAC__metadata_chain_new failed\n");
return -1;
}
- FLAC__bool res = FLAC__metadata_chain_read (chain, it->fname);
+ FLAC__bool res = FLAC__metadata_chain_read (chain, deadbeef->pl_find_meta (it, ":URI"));
if (!res) {
trace ("cflac_write_metadata: FLAC__metadata_chain_read failed\n");
goto error;
@@ -776,53 +838,80 @@ cflac_write_metadata (DB_playItem_t *it) {
trace ("cflac_write_metadata: FLAC__metadata_iterator_new failed\n");
goto error;
}
+ FLAC__StreamMetadata *data = NULL;
+ // find existing vorbiscomment block
FLAC__metadata_iterator_init (iter, chain);
do {
- FLAC__StreamMetadata *data = FLAC__metadata_iterator_get_block (iter);
+ data = FLAC__metadata_iterator_get_block (iter);
if (data && data->type == FLAC__METADATA_TYPE_VORBIS_COMMENT) {
- for (int m = 0; metainfo[m]; m += 2) {
- const char *val = deadbeef->pl_find_meta (it, metainfo[m+1]);
- if (val) {
- do {} while (1 == FLAC__metadata_object_vorbiscomment_remove_entry_matching (data, metainfo[m]));
+ break;
+ }
+ } while (FLAC__metadata_iterator_next (iter));
+
+ if (data) {
+ // delete all comments
+ FLAC__metadata_object_vorbiscomment_resize_comments (data, 0);
+ }
+ else {
+ // create new and add to chain
+ data = FLAC__metadata_object_new(FLAC__METADATA_TYPE_VORBIS_COMMENT);
+ if (!data) {
+ fprintf (stderr, "flac: failed to allocate new vorbis comment block\n");
+ goto error;
+ }
+ if(!FLAC__metadata_iterator_insert_block_after(iter, data)) {
+ fprintf (stderr, "flac: failed to append vorbis comment block to chain\n");
+ goto error;
+ }
+ }
+
+ DB_metaInfo_t *m = deadbeef->pl_get_metadata_head (it);
+ while (m) {
+ if (m->key[0] != ':') {
+ int i;
+ for (i = 0; metainfo[i]; i += 2) {
+ if (!strcasecmp (metainfo[i+1], m->key)) {
+ break;
}
- if (val && *val) {
- while (val) {
- const char *next = strchr (val, '\n');
- int l;
- if (next) {
- l = next - val;
- next++;
- }
- else {
- l = strlen (val);
- }
- if (l > 0) {
- char s[100+l+1];
- int n = snprintf (s, sizeof (s), "%s=", metainfo[m]);
- strncpy (s+n, val, l);
- *(s+n+l) = 0;
- FLAC__StreamMetadata_VorbisComment_Entry ent = {
- .length = strlen (s),
- .entry = (FLAC__byte*)s
- };
- //FLAC__metadata_object_vorbiscomment_replace_comment (data, ent, 1, 1);
- FLAC__metadata_object_vorbiscomment_append_comment (data, ent, 1);
- }
- val = next;
+ }
+ const char *val = m->value;
+ if (val && *val) {
+ while (val) {
+ const char *next = strchr (val, '\n');
+ int l;
+ if (next) {
+ l = next - val;
+ next++;
+ }
+ else {
+ l = strlen (val);
+ }
+ if (l > 0) {
+ char s[100+l+1];
+ int n = snprintf (s, sizeof (s), "%s=", metainfo[i] ? metainfo[i] : m->key);
+ strncpy (s+n, val, l);
+ *(s+n+l) = 0;
+ FLAC__StreamMetadata_VorbisComment_Entry ent = {
+ .length = strlen (s),
+ .entry = (FLAC__byte*)s
+ };
+ FLAC__metadata_object_vorbiscomment_append_comment (data, ent, 1);
}
+ val = next;
}
}
}
- } while (FLAC__metadata_iterator_next (iter));
+ m = m->next;
+ }
- FLAC__metadata_iterator_delete (iter);
if (!FLAC__metadata_chain_write (chain, 1, 0)) {
trace ("cflac_write_metadata: FLAC__metadata_chain_write failed\n");
goto error;
}
err = 0;
error:
+ FLAC__metadata_iterator_delete (iter);
if (chain) {
FLAC__metadata_chain_delete (chain);
}
@@ -837,20 +926,35 @@ static const char *filetypes[] = { "FLAC", "OggFLAC", NULL };
// define plugin interface
static DB_decoder_t plugin = {
DB_PLUGIN_SET_API_VERSION
- .plugin.version_major = 0,
- .plugin.version_minor = 1,
+ .plugin.version_major = 1,
+ .plugin.version_minor = 0,
.plugin.type = DB_PLUGIN_DECODER,
.plugin.id = "stdflac",
.plugin.name = "FLAC decoder",
.plugin.descr = "FLAC decoder using libFLAC",
- .plugin.author = "Alexey Yakovenko",
- .plugin.email = "waker@users.sourceforge.net",
+ .plugin.copyright =
+ "Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>\n"
+ "\n"
+ "This program is free software; you can redistribute it and/or\n"
+ "modify it under the terms of the GNU General Public License\n"
+ "as published by the Free Software Foundation; either version 2\n"
+ "of the License, or (at your option) any later version.\n"
+ "\n"
+ "This program is distributed in the hope that it will be useful,\n"
+ "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+ "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+ "GNU General Public License for more details.\n"
+ "\n"
+ "You should have received a copy of the GNU General Public License\n"
+ "along with this program; if not, write to the Free Software\n"
+ "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n"
+ ,
.plugin.website = "http://deadbeef.sf.net",
.open = cflac_open,
.init = cflac_init,
.free = cflac_free,
- .read_int16 = cflac_read_int16,
- .read_float32 = cflac_read_float32,
+ .read = cflac_read,
+// .read_float32 = cflac_read_float32,
.seek = cflac_seek,
.seek_sample = cflac_seek_sample,
.insert = cflac_insert,
diff --git a/plugins/gme/Makefile.am b/plugins/gme/Makefile.am
index 61351f9c..b325cbdf 100644
--- a/plugins/gme/Makefile.am
+++ b/plugins/gme/Makefile.am
@@ -112,8 +112,9 @@ game-music-emu-0.5.5/gme/Ym2413_Emu.h\
game-music-emu-0.5.5/gme/Ym2612_Emu.h\
game-music-emu-0.5.5/gme/gme_types.h
-gme_la_LDFLAGS = -module
+gme_la_LDFLAGS = -module -nostdlib -lsupc++
+gme_la_LIBADD = $(ZLIB_LIBS)
-gme_la_LIBADD = $(LDADD) -lstdc++
-AM_CFLAGS = $(CFLAGS) -I$(gmepath) -std=c99 -DGME_VERSION_055
+AM_CFLAGS = $(CFLAGS) $(ZLIB_CFLAGS) -I$(gmepath) -std=c99 -DGME_VERSION_055
+AM_CPPFLAGS = $(CXXFLAGS) -fno-exceptions -fno-rtti -nostdlib -fno-unwind-tables
endif
diff --git a/plugins/gme/cgme.c b/plugins/gme/cgme.c
index 5d2920f0..8eb6d8d3 100644
--- a/plugins/gme/cgme.c
+++ b/plugins/gme/cgme.c
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -19,8 +19,21 @@
#include <stdlib.h>
#include <string.h>
#include "gme/gme.h"
+#include <zlib.h>
#include "../../deadbeef.h"
+int _Unwind_Resume_or_Rethrow;
+int _Unwind_RaiseException;
+int _Unwind_GetLanguageSpecificData;
+int _Unwind_Resume;
+int _Unwind_DeleteException;
+int _Unwind_GetTextRelBase;
+int _Unwind_SetIP;
+int _Unwind_GetDataRelBase;
+int _Unwind_GetRegionStart;
+int _Unwind_SetGR;
+int _Unwind_GetIPInfo;
+
//#define trace(...) { fprintf(stderr, __VA_ARGS__); }
#define trace(fmt,...)
@@ -36,35 +49,124 @@ typedef struct {
} gme_fileinfo_t;
static DB_fileinfo_t *
-cgme_open (void) {
+cgme_open (uint32_t hint) {
DB_fileinfo_t *_info = malloc (sizeof (gme_fileinfo_t));
memset (_info, 0, sizeof (gme_fileinfo_t));
return _info;
}
static int
+read_gzfile (const char *fname, char **buffer, int *size) {
+ FILE *fp = fopen (fname, "rb");
+ if (!fp) {
+ trace ("failed to fopen %s\n", fname);
+ return -1;
+ }
+ fseek (fp, 0, SEEK_END);
+ size_t sz = ftell (fp);
+ fclose (fp);
+
+ sz *= 2;
+ int readsize = sz;
+ *buffer = malloc (sz);
+ if (!(*buffer)) {
+ return -1;
+ }
+
+ gzFile gz = gzopen (fname, "rb");
+ if (!gz) {
+ trace ("failed to gzopen %s\n", fname);
+ return -1;
+ }
+ *size = 0;
+ int nb;
+ int pos = 0;
+ do {
+ nb = gzread (gz, *buffer + pos, readsize);
+ if (nb < 0) {
+ free (*buffer);
+ trace ("failed to gzread from %s\n", fname);
+ return -1;
+ }
+ if (nb > 0) {
+ pos += nb;
+ *size += nb;
+ }
+ if (nb != readsize) {
+ break;
+ }
+ else {
+ readsize = sz;
+ sz *= 2;
+ *buffer = realloc (*buffer, sz);
+ }
+ } while (nb > 0);
+ gzclose (gz);
+ trace ("got %d bytes from %s\n", *size, fname);
+
+ return 0;
+}
+
+static int
cgme_init (DB_fileinfo_t *_info, DB_playItem_t *it) {
gme_fileinfo_t *info = (gme_fileinfo_t*)_info;
int samplerate = deadbeef->conf_get_int ("synth.samplerate", 44100);
- if (gme_open_file (it->fname, &info->emu, samplerate)) {
+
+ gme_err_t res;
+ const char *ext = strrchr (deadbeef->pl_find_meta (it, ":URI"), '.');
+ if (ext && !strcasecmp (ext, ".vgz")) {
+ trace ("opening gzipped vgm...\n");
+ char *buffer;
+ int sz;
+ if (!read_gzfile (deadbeef->pl_find_meta (it, ":URI"), &buffer, &sz)) {
+ res = gme_open_data (buffer, sz, &info->emu, samplerate);
+ free (buffer);
+ }
+ }
+ else {
+ DB_FILE *f = deadbeef->fopen (deadbeef->pl_find_meta (it, ":URI"));
+ int64_t sz = deadbeef->fgetlength (f);
+ if (sz <= 0) {
+ deadbeef->fclose (f);
+ return -1;
+ }
+ char *buf = malloc (sz);
+ if (!buf) {
+ deadbeef->fclose (f);
+ return -1;
+ }
+ int64_t rb = deadbeef->fread (buf, 1, sz, f);
+ deadbeef->fclose(f);
+ if (rb != sz) {
+ free (buf);
+ return -1;
+ }
+
+ res = gme_open_data (buf, sz, &info->emu, samplerate);
+ free (buf);
+ }
+
+ if (res) {
+ trace ("failed with error %d\n", res);
return -1;
}
gme_mute_voices (info->emu, info->cgme_voicemask);
- gme_start_track (info->emu, it->tracknum);
+ gme_start_track (info->emu, deadbeef->pl_find_meta_int (it, ":TRACKNUM", 0));
#ifdef GME_VERSION_055
gme_info_t *inf;
- gme_track_info (info->emu, &inf, it->tracknum);
+ gme_track_info (info->emu, &inf, deadbeef->pl_find_meta_int (it, ":TRACKNUM", 0));
#else
track_info_t _inf;
- gme_track_info (info->emu, &inf, it->tracknum);
+ gme_track_info (info->emu, &inf, deadbeef->pl_find_meta_int (it, ":TRACKNUM", 0));
track_info_t *inf = &_inf;
#endif
_info->plugin = &plugin;
- _info->bps = 16;
- _info->channels = 2;
- _info->samplerate = samplerate;
+ _info->fmt.bps = 16;
+ _info->fmt.channels = 2;
+ _info->fmt.samplerate = samplerate;
+ _info->fmt.channelmask = _info->fmt.channels == 1 ? DDB_SPEAKER_FRONT_LEFT : (DDB_SPEAKER_FRONT_LEFT | DDB_SPEAKER_FRONT_RIGHT);
info->duration = deadbeef->pl_get_item_duration (it);
info->reallength = inf->length;
_info->readpos = 0;
@@ -83,7 +185,7 @@ cgme_free (DB_fileinfo_t *_info) {
static int
cgme_read (DB_fileinfo_t *_info, char *bytes, int size) {
gme_fileinfo_t *info = (gme_fileinfo_t*)_info;
- float t = (size/4) / (float)_info->samplerate;
+ float t = (size/4) / (float)_info->fmt.samplerate;
if (_info->readpos + t >= info->duration) {
t = info->duration - _info->readpos;
if (t <= 0) {
@@ -114,11 +216,76 @@ cgme_seek (DB_fileinfo_t *_info, float time) {
return 0;
}
+static void
+cgme_add_meta (DB_playItem_t *it, const char *key, const char *value) {
+ if (!value) {
+ return;
+ }
+ char len = strlen (value);
+ char out[1024];
+ // check for utf8 (hack)
+ if (deadbeef->junk_iconv (value, len, out, sizeof (out), "utf-8", "utf-8") >= 0) {
+ deadbeef->pl_add_meta (it, key, out);
+ return;
+ }
+
+ if (deadbeef->junk_iconv (value, len, out, sizeof (out), "iso8859-1", "utf-8") >= 0) {
+ deadbeef->pl_add_meta (it, key, out);
+ return;
+ }
+
+ if (deadbeef->junk_iconv (value, len, out, sizeof (out), "SHIFT-JIS", "utf-8") >= 0) {
+ deadbeef->pl_add_meta (it, key, out);
+ return;
+ }
+
+ // FIXME: try other encodings?
+
+ return;
+}
+
static DB_playItem_t *
cgme_insert (DB_playItem_t *after, const char *fname) {
Music_Emu *emu;
trace ("gme_open_file %s\n", fname);
- if (!gme_open_file (fname, &emu, gme_info_only)) {
+
+ gme_err_t res;
+
+ const char *ext = strrchr (fname, '.');
+ if (ext && !strcasecmp (ext, ".vgz")) {
+ trace ("opening gzipped vgm...\n");
+ char *buffer;
+ int sz;
+ if (!read_gzfile (fname, &buffer, &sz)) {
+ res = gme_open_data (buffer, sz, &emu, gme_info_only);
+ free (buffer);
+ }
+ }
+ else {
+ DB_FILE *f = deadbeef->fopen (fname);
+ int64_t sz = deadbeef->fgetlength (f);
+ if (sz <= 0) {
+ deadbeef->fclose (f);
+ return NULL;
+ }
+ char *buf = malloc (sz);
+ if (!buf) {
+ deadbeef->fclose (f);
+ return NULL;
+ }
+ int64_t rb = deadbeef->fread (buf, 1, sz, f);
+ deadbeef->fclose(f);
+ if (rb != sz) {
+ free (buf);
+ return NULL;
+ }
+
+ res = gme_open_data (buf, sz, &emu, gme_info_only);
+ free (buf);
+ }
+
+
+ if (!res) {
int cnt = gme_track_count (emu);
trace ("track cnt %d\n", cnt);
for (int i = 0; i < cnt; i++) {
@@ -131,9 +298,7 @@ cgme_insert (DB_playItem_t *after, const char *fname) {
track_info_t *inf = &_inf;
#endif
if (!ret) {
- DB_playItem_t *it = deadbeef->pl_item_alloc ();
- it->decoder_id = deadbeef->plug_get_decoder_id (plugin.plugin.id);
- it->fname = strdup (fname);
+ DB_playItem_t *it = deadbeef->pl_item_alloc_init (fname, plugin.plugin.id);
char str[1024];
if (inf->song[0]) {
snprintf (str, 1024, "%d %s - %s", i, inf->game, inf->song);
@@ -142,11 +307,11 @@ cgme_insert (DB_playItem_t *after, const char *fname) {
snprintf (str, 1024, "%d %s - ?", i, inf->game);
}
trace ("track subtune %d %s, length=%d\n", i, str, inf->length);
- it->tracknum = i;
+ deadbeef->pl_set_meta_int (it, ":TRACKNUM", i);
// add metadata
- deadbeef->pl_add_meta (it, "system", inf->system);
- deadbeef->pl_add_meta (it, "album", inf->game);
+ cgme_add_meta (it, "system", inf->system);
+ cgme_add_meta (it, "album", inf->game);
int tl = sizeof (inf->song);
int n;
for (n = 0; i < tl && inf->song[n] && inf->song[n] == ' '; n++);
@@ -154,16 +319,16 @@ cgme_insert (DB_playItem_t *after, const char *fname) {
deadbeef->pl_add_meta (it, "title", NULL);
}
else {
- deadbeef->pl_add_meta (it, "title", inf->song);
+ cgme_add_meta (it, "title", inf->song);
}
- deadbeef->pl_add_meta (it, "artist", inf->author);
- deadbeef->pl_add_meta (it, "copyright", inf->copyright);
- deadbeef->pl_add_meta (it, "comment", inf->comment);
- deadbeef->pl_add_meta (it, "dumper", inf->dumper);
+ cgme_add_meta (it, "artist", inf->author);
+ cgme_add_meta (it, "copyright", inf->copyright);
+ cgme_add_meta (it, "comment", inf->comment);
+ cgme_add_meta (it, "dumper", inf->dumper);
char trk[10];
snprintf (trk, 10, "%d", i+1);
- deadbeef->pl_add_meta (it, "track", trk);
- if (inf->length == -1) {
+ cgme_add_meta (it, "track", trk);
+ if (inf->length == -1 || inf->length == 0) {
float songlength = deadbeef->conf_get_float ("gme.songlength", 3);
deadbeef->pl_set_item_duration (it, songlength * 60.f);
}
@@ -174,12 +339,12 @@ cgme_insert (DB_playItem_t *after, const char *fname) {
while (ext >= fname && *ext != '.') {
ext--;
}
- it->filetype = NULL;
if (*ext == '.') {
ext++;
for (int i = 0; plugin.exts[i]; i++) {
if (!strcasecmp (ext, plugin.exts[i])) {
- it->filetype = plugin.exts[i];
+ deadbeef->pl_add_meta (it, ":FILETYPE", plugin.exts[i]);
+ break;
}
}
}
@@ -187,7 +352,7 @@ cgme_insert (DB_playItem_t *after, const char *fname) {
deadbeef->pl_item_unref (it);
}
else {
- printf ("gme error: %s\n", ret);
+ trace ("gme error: %s\n", ret);
}
}
if (emu) {
@@ -195,7 +360,7 @@ cgme_insert (DB_playItem_t *after, const char *fname) {
}
}
else {
- printf ("error adding %s\n", fname);
+ trace ("gme_open_file/data failed\n");
}
return after;
}
@@ -241,14 +406,31 @@ static const char settings_dlg[] =
// define plugin interface
static DB_decoder_t plugin = {
DB_PLUGIN_SET_API_VERSION
- .plugin.version_major = 0,
- .plugin.version_minor = 1,
+ .plugin.version_major = 1,
+ .plugin.version_minor = 0,
.plugin.type = DB_PLUGIN_DECODER,
.plugin.id = "stdgme",
.plugin.name = "Game_Music_Emu decoder",
.plugin.descr = "chiptune music player based on GME",
- .plugin.author = "Alexey Yakovenko",
- .plugin.email = "waker@users.sourceforge.net",
+ .plugin.copyright =
+ "Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>\n"
+ "\n"
+ "Uses Game-Music-Emu v0.5.5 by Shay Green <gblargg@gmail.com>, http://www.slack.net/~ant/libs\n"
+ "\n"
+ "This program is free software; you can redistribute it and/or\n"
+ "modify it under the terms of the GNU General Public License\n"
+ "as published by the Free Software Foundation; either version 2\n"
+ "of the License, or (at your option) any later version.\n"
+ "\n"
+ "This program is distributed in the hope that it will be useful,\n"
+ "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+ "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+ "GNU General Public License for more details.\n"
+ "\n"
+ "You should have received a copy of the GNU General Public License\n"
+ "along with this program; if not, write to the Free Software\n"
+ "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n"
+ ,
.plugin.website = "http://deadbeef.sf.net",
.plugin.start = cgme_start,
.plugin.stop = cgme_stop,
@@ -256,7 +438,7 @@ static DB_decoder_t plugin = {
.open = cgme_open,
.init = cgme_init,
.free = cgme_free,
- .read_int16 = cgme_read,
+ .read = cgme_read,
.seek = cgme_seek,
.insert = cgme_insert,
.exts = exts,
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Sap_Apu.cpp b/plugins/gme/game-music-emu-0.5.5/gme/Sap_Apu.cpp
index fa9bc4b1..fb56f5dc 100644
--- a/plugins/gme/game-music-emu-0.5.5/gme/Sap_Apu.cpp
+++ b/plugins/gme/game-music-emu-0.5.5/gme/Sap_Apu.cpp
@@ -90,7 +90,7 @@ void Sap_Apu::reset( Sap_Apu_Impl* new_impl )
memset( &oscs [i], 0, offsetof (osc_t,output) );
}
-inline void Sap_Apu::calc_periods()
+void Sap_Apu::calc_periods()
{
// 15/64 kHz clock
int divider = 28;
diff --git a/plugins/gtkui/Makefile.am b/plugins/gtkui/Makefile.am
index 609917ed..3cfc1cce 100644
--- a/plugins/gtkui/Makefile.am
+++ b/plugins/gtkui/Makefile.am
@@ -1,10 +1,7 @@
if HAVE_GTKUI
gtkuidir = $(libdir)/$(PACKAGE)
-pkglib_LTLIBRARIES = gtkui.la
-
gtkui_VALASOURCES = ddbequalizer.vala ddbseekbar.vala ddbcellrenderertextmultiline.vala
gtkui_VALABUILTSOURCES = $(gtkui_VALASOURCES:.vala=.c) ddbequalizer.h ddbseekbar.h ddbcellrenderertextmultiline.h
-
if MAINTAINER_MODE
BUILT_SOURCES = vala.stamp
vala.stamp: $(gtkui_VALASOURCES)
@@ -12,10 +9,13 @@ vala.stamp: $(gtkui_VALASOURCES)
$(VALAC) -C -H ddbequalizer.h --library ddbequalizer gtkui.vapi --pkg=gtk+-2.0 ddbequalizer.vala
$(VALAC) -C -H ddbseekbar.h --library ddbseekbar gtkui.vapi --pkg=gtk+-2.0 ddbseekbar.vala
touch $@
+
+CLEANFILES = \
+ $(BUILT_SOURCES) \
+ $(gtkui_VALABUILTSOURCES)
endif
-gtkui_la_SOURCES = $(gtkui_VALABUILTSOURCES)\
- gtkui.c gtkui.h\
+GTKUI_SOURCES = gtkui.c gtkui.h\
callbacks.c interface.c support.c callbacks.h interface.h support.h\
ddblistview.c ddblistview.h\
mainplaylist.c mainplaylist.h\
@@ -32,18 +32,39 @@ gtkui_la_SOURCES = $(gtkui_VALABUILTSOURCES)\
plcommon.c plcommon.h\
prefwin.c\
eq.c eq.h\
- actions.c actions.h
-
-gtkui_la_LDFLAGS = -module
+ actions.c actions.h\
+ dspconfig.c dspconfig.h\
+ tagwritersettings.c tagwritersettings.h\
+ wingeom.c wingeom.h
-gtkui_la_LIBADD = $(LDADD) $(GTKUI_DEPS_LIBS) $(NOTIFY_DEPS_LIBS)
-AM_CFLAGS = -std=c99 $(GTKUI_DEPS_CFLAGS) $(NOTIFY_DEPS_CFLAGS)
+sdkdir = $(pkgincludedir)
+sdk_HEADERS = gtkui_api.h
EXTRA_DIST = $(gtkui_VALASOURCES) deadbeef.glade
-if MAINTAINER_MODE
-CLEANFILES = \
- $(BUILT_SOURCES) \
- $(gtkui_VALABUILTSOURCES)
+if STATICLINK
+pkglib_LTLIBRARIES = ddb_gui_GTK2.la ddb_gui_GTK2.fallback.la
+else
+pkglib_LTLIBRARIES = ddb_gui_GTK2.la
endif
+
+# normal lib
+ddb_gui_GTK2_la_SOURCES = $(gtkui_VALABUILTSOURCES) $(GTKUI_SOURCES)
+ddb_gui_GTK2_la_LDFLAGS = -module
+ddb_gui_GTK2_la_LIBADD = $(LDADD) $(GTKUI_DEPS_LIBS)
+ddb_gui_GTK2_la_CFLAGS = -std=c99 $(GTKUI_DEPS_CFLAGS)
+
+# fallback lib
+if STATICLINK
+GTK_ROOT=../../../deadbeef-deps/gtk-debian/usr
+
+ddb_gui_GTK2_fallback_la_SOURCES = $(gtkui_VALABUILTSOURCES) $(GTKUI_SOURCES)
+ddb_gui_GTK2_fallback_la_LDFLAGS = -module
+
+ddb_gui_GTK2_fallback_la_LIBADD = $(LDADD) -L$(GTK_ROOT)/lib $(GTK_ROOT)/lib/libgtk-x11-2.0.la $(GTK_ROOT)/lib/libgdk-x11-2.0.la $(GTK_ROOT)/lib/libpangoft2-1.0.la $(GTK_ROOT)/lib/libpangocairo-1.0.la $(GTK_ROOT)/lib/libgdk_pixbuf-2.0.la -lm $(GTK_ROOT)/lib/libcairo.la $(GTK_ROOT)/lib/libpango-1.0.la $(GTK_ROOT)/lib/libgobject-2.0.la $(GTK_ROOT)/lib/libgmodule-2.0.la $(GTK_ROOT)/lib/libgthread-2.0.la -lrt $(GTK_ROOT)/lib/libglib-2.0.la
+
+ddb_gui_GTK2_fallback_la_CFLAGS = -std=c99 -I $(GTK_ROOT)/include -I $(GTK_ROOT)/lib/gtk-2.0/include -I $(GTK_ROOT)/include/glib-2.0 -I $(GTK_ROOT)/include/gtk-2.0 -I $(GTK_ROOT)/include/cairo -I $(GTK_ROOT)/lib/glib-2.0/include/ -I $(GTK_ROOT)/include/pango-1.0 -I $(GTK_ROOT)/include/atk-1.0 -DULTRA_COMPATIBLE=1
+
+endif
+
endif
diff --git a/plugins/gtkui/actions.c b/plugins/gtkui/actions.c
index ac2904d2..0ddbdceb 100644
--- a/plugins/gtkui/actions.c
+++ b/plugins/gtkui/actions.c
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>,
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>,
Viktor Semykin <thesame.ml@gmail.com>
This program is free software; you can redistribute it and/or
diff --git a/plugins/gtkui/actions.h b/plugins/gtkui/actions.h
index b064647f..aacff34b 100644
--- a/plugins/gtkui/actions.h
+++ b/plugins/gtkui/actions.h
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>,
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>,
Viktor Semykin <thesame.ml@gmail.com>
This program is free software; you can redistribute it and/or
diff --git a/plugins/gtkui/callbacks.c b/plugins/gtkui/callbacks.c
index dd26a422..3c775f16 100644
--- a/plugins/gtkui/callbacks.c
+++ b/plugins/gtkui/callbacks.c
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -43,6 +43,7 @@
#include "parser.h"
#include "drawing.h"
#include "eq.h"
+#include "wingeom.h"
//#define trace(...) { fprintf (stderr, __VA_ARGS__); }
#define trace(fmt,...)
@@ -58,26 +59,37 @@ extern DB_functions_t *deadbeef; // defined in gtkui.c
static gboolean
file_filter_func (const GtkFileFilterInfo *filter_info, gpointer data) {
// get ext
- const char *p = filter_info->filename + strlen (filter_info->filename)-1;
- while (p >= filter_info->filename) {
- if (*p == '.') {
- break;
- }
- p--;
- }
- if (*p != '.') {
+ const char *p = strrchr (filter_info->filename, '.');
+ if (!p) {
return FALSE;
}
p++;
+
+ // get beginning of fname
+ const char *fn = strrchr (filter_info->filename, '/');
+ if (!fn) {
+ fn = filter_info->filename;
+ }
+ else {
+ fn++;
+ }
+
+
DB_decoder_t **codecs = deadbeef->plug_get_decoder_list ();
for (int i = 0; codecs[i]; i++) {
if (codecs[i]->exts && codecs[i]->insert) {
const char **exts = codecs[i]->exts;
- if (exts) {
- for (int e = 0; exts[e]; e++) {
- if (!strcasecmp (exts[e], p)) {
- return TRUE;
- }
+ for (int e = 0; exts[e]; e++) {
+ if (!strcasecmp (exts[e], p)) {
+ return TRUE;
+ }
+ }
+ }
+ if (codecs[i]->prefixes && codecs[i]->insert) {
+ const char **prefixes = codecs[i]->prefixes;
+ for (int e = 0; prefixes[e]; e++) {
+ if (!strncasecmp (prefixes[e], fn, strlen(prefixes[e])) && *(fn + strlen (prefixes[e])) == '.') {
+ return TRUE;
}
}
}
@@ -88,6 +100,18 @@ file_filter_func (const GtkFileFilterInfo *filter_info, gpointer data) {
if (!strcasecmp (p, "m3u")) {
return TRUE;
}
+
+ // test container (vfs) formats
+ DB_vfs_t **vfsplugs = deadbeef->plug_get_vfs_list ();
+ for (int i = 0; vfsplugs[i]; i++) {
+ if (vfsplugs[i]->is_container) {
+ if (vfsplugs[i]->is_container (filter_info->filename)) {
+ return TRUE;
+ }
+ }
+ }
+
+
return FALSE;
}
@@ -121,7 +145,9 @@ on_open_activate (GtkMenuItem *menuitem,
gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dlg), TRUE);
// restore folder
- gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER (dlg), deadbeef->conf_get_str ("filechooser.lastdir", ""));
+ deadbeef->conf_lock ();
+ gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER (dlg), deadbeef->conf_get_str_fast ("filechooser.lastdir", ""));
+ deadbeef->conf_unlock ();
int response = gtk_dialog_run (GTK_DIALOG (dlg));
// store folder
gchar *folder = gtk_file_chooser_get_current_folder_uri (GTK_FILE_CHOOSER (dlg));
@@ -155,7 +181,9 @@ on_add_files_activate (GtkMenuItem *menuitem,
gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dlg), TRUE);
// restore folder
- gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER (dlg), deadbeef->conf_get_str ("filechooser.lastdir", ""));
+ deadbeef->conf_lock ();
+ gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER (dlg), deadbeef->conf_get_str_fast ("filechooser.lastdir", ""));
+ deadbeef->conf_unlock ();
int response = gtk_dialog_run (GTK_DIALOG (dlg));
// store folder
gchar *folder = gtk_file_chooser_get_current_folder_uri (GTK_FILE_CHOOSER (dlg));
@@ -189,19 +217,26 @@ on_add_folders_activate (GtkMenuItem *menuitem,
{
GtkWidget *dlg = gtk_file_chooser_dialog_new (_("Add folder(s) to playlist..."), GTK_WINDOW (mainwin), GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_OK, NULL);
+ GtkWidget *box = gtk_hbox_new (FALSE, 8);
+ gtk_widget_show (box);
+
GtkWidget *check = gtk_check_button_new_with_mnemonic (_("Follow symlinks"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check), deadbeef->conf_get_int ("add_folders_follow_symlinks", 0));
g_signal_connect ((gpointer) check, "toggled",
G_CALLBACK (on_follow_symlinks_toggled),
NULL);
gtk_widget_show (check);
- gtk_file_chooser_set_extra_widget (GTK_FILE_CHOOSER (dlg), check);
+ gtk_box_pack_start (GTK_BOX (box), check, FALSE, FALSE, 0);
+
+ gtk_file_chooser_set_extra_widget (GTK_FILE_CHOOSER (dlg), box);
set_file_filter (dlg, NULL);
gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dlg), TRUE);
// restore folder
- gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER (dlg), deadbeef->conf_get_str ("filechooser.lastdir", ""));
+ deadbeef->conf_lock ();
+ gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER (dlg), deadbeef->conf_get_str_fast ("filechooser.lastdir", ""));
+ deadbeef->conf_unlock ();
int response = gtk_dialog_run (GTK_DIALOG (dlg));
// store folder
gchar *folder = gtk_file_chooser_get_current_folder_uri (GTK_FILE_CHOOSER (dlg));
@@ -248,10 +283,10 @@ on_select_all1_activate (GtkMenuItem *menuitem,
{
deadbeef->pl_select_all ();
DdbListview *pl = DDB_LISTVIEW (lookup_widget (mainwin, "playlist"));
- ddb_listview_refresh (pl, DDB_REFRESH_LIST | DDB_EXPOSE_LIST);
+ ddb_listview_refresh (pl, DDB_REFRESH_LIST);
pl = DDB_LISTVIEW (lookup_widget (searchwin, "searchlist"));
if (pl) {
- ddb_listview_refresh (pl, DDB_REFRESH_LIST | DDB_EXPOSE_LIST);
+ ddb_listview_refresh (pl, DDB_REFRESH_LIST);
}
}
@@ -263,7 +298,7 @@ void
on_stopbtn_clicked (GtkButton *button,
gpointer user_data)
{
- deadbeef->sendmessage (M_STOPSONG, 0, 0, 0);
+ deadbeef->sendmessage (M_STOP, 0, 0, 0);
}
@@ -271,7 +306,7 @@ void
on_playbtn_clicked (GtkButton *button,
gpointer user_data)
{
- deadbeef->sendmessage (M_PLAYSONG, 0, 0, 0);
+ deadbeef->sendmessage (M_PLAY_CURRENT, 0, 0, 0);
}
@@ -279,7 +314,7 @@ void
on_pausebtn_clicked (GtkButton *button,
gpointer user_data)
{
- deadbeef->sendmessage (M_PAUSESONG, 0, 0, 0);
+ deadbeef->sendmessage (M_TOGGLE_PAUSE, 0, 0, 0);
}
@@ -287,7 +322,7 @@ void
on_prevbtn_clicked (GtkButton *button,
gpointer user_data)
{
- deadbeef->sendmessage (M_PREVSONG, 0, 0, 0);
+ deadbeef->sendmessage (M_PREV, 0, 0, 0);
}
@@ -295,7 +330,7 @@ void
on_nextbtn_clicked (GtkButton *button,
gpointer user_data)
{
- deadbeef->sendmessage (M_NEXTSONG, 0, 0, 0);
+ deadbeef->sendmessage (M_NEXT, 0, 0, 0);
}
@@ -303,7 +338,7 @@ void
on_playrand_clicked (GtkButton *button,
gpointer user_data)
{
- deadbeef->sendmessage (M_PLAYRANDOM, 0, 0, 0);
+ deadbeef->sendmessage (M_PLAY_RANDOM, 0, 0, 0);
}
gboolean
@@ -314,7 +349,7 @@ on_mainwin_key_press_event (GtkWidget *widget,
uint32_t maskedstate = (event->state &~ (GDK_LOCK_MASK | GDK_MOD2_MASK | GDK_MOD3_MASK | GDK_MOD5_MASK)) & 0xfff;
if ((maskedstate == GDK_MOD1_MASK || maskedstate == 0) && event->keyval == GDK_n) {
// button for that one is not in toolbar anymore, so handle it manually
- deadbeef->sendmessage (M_PLAYRANDOM, 0, 0, 0);
+ deadbeef->sendmessage (M_PLAY_RANDOM, 0, 0, 0);
}
else if ((maskedstate == GDK_MOD1_MASK || maskedstate == 0) && event->keyval >= GDK_1 && event->keyval <= GDK_9) {
int pl = event->keyval - GDK_1;
@@ -334,7 +369,8 @@ void
on_order_linear_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
- deadbeef->conf_set_int ("playback.order", 0);
+ deadbeef->conf_set_int ("playback.order", PLAYBACK_ORDER_LINEAR);
+ deadbeef->sendmessage (M_CONFIG_CHANGED, 0, 0, 0);
}
@@ -342,15 +378,24 @@ void
on_order_shuffle_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
- deadbeef->conf_set_int ("playback.order", 1);
+ deadbeef->conf_set_int ("playback.order", PLAYBACK_ORDER_SHUFFLE_TRACKS);
+ deadbeef->sendmessage (M_CONFIG_CHANGED, 0, 0, 0);
}
+void
+on_order_shuffle_albums_activate (GtkMenuItem *menuitem,
+ gpointer user_data)
+{
+ deadbeef->conf_set_int ("playback.order", PLAYBACK_ORDER_SHUFFLE_ALBUMS);
+ deadbeef->sendmessage (M_CONFIG_CHANGED, 0, 0, 0);
+}
void
on_order_random_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
- deadbeef->conf_set_int ("playback.order", 2);
+ deadbeef->conf_set_int ("playback.order", PLAYBACK_ORDER_RANDOM);
+ deadbeef->sendmessage (M_CONFIG_CHANGED, 0, 0, 0);
}
@@ -601,21 +646,7 @@ on_mainwin_configure_event (GtkWidget *widget,
GdkEventConfigure *event,
gpointer user_data)
{
-#if GTK_CHECK_VERSION(2,2,0)
- GdkWindowState window_state = gdk_window_get_state (GDK_WINDOW (widget->window));
-#else
- GdkWindowState window_state = gdk_window_get_state (G_OBJECT (widget));
-#endif
- if (!(window_state & GDK_WINDOW_STATE_MAXIMIZED) && gtk_widget_get_visible (widget)) {
- int x, y;
- int w, h;
- gtk_window_get_position (GTK_WINDOW (widget), &x, &y);
- gtk_window_get_size (GTK_WINDOW (widget), &w, &h);
- deadbeef->conf_set_int ("mainwin.geometry.x", x);
- deadbeef->conf_set_int ("mainwin.geometry.y", y);
- deadbeef->conf_set_int ("mainwin.geometry.w", w);
- deadbeef->conf_set_int ("mainwin.geometry.h", h);
- }
+ wingeom_save (widget, "mainwin");
return FALSE;
}
@@ -633,7 +664,6 @@ on_find_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
search_start ();
- search_restore_attrs ();
}
void
@@ -689,7 +719,7 @@ on_help1_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
char fname[PATH_MAX];
- snprintf (fname, sizeof (fname), DOCDIR "/%s", _("help.txt"));
+ snprintf (fname, sizeof (fname), "%s/%s", deadbeef->get_doc_dir (), _("help.txt"));
show_info_window (fname, _("Help"), &helpwindow);
}
@@ -702,7 +732,7 @@ on_about1_activate (GtkMenuItem *menuitem,
char s[200];
snprintf (s, sizeof (s), _("About DeaDBeeF %s"), VERSION);
char fname[PATH_MAX];
- snprintf (fname, sizeof (fname), DOCDIR "/%s", "about.txt");
+ snprintf (fname, sizeof (fname), "%s/%s", deadbeef->get_doc_dir (), "about.txt");
show_info_window (fname, s, &aboutwindow);
}
@@ -715,7 +745,7 @@ on_changelog1_activate (GtkMenuItem *menuitem,
char s[200];
snprintf (s, sizeof (s), _("DeaDBeeF %s ChangeLog"), VERSION);
char fname[PATH_MAX];
- snprintf (fname, sizeof (fname), DOCDIR "/%s", "ChangeLog");
+ snprintf (fname, sizeof (fname), "%s/%s", deadbeef->get_doc_dir (), "ChangeLog");
show_info_window (fname, s, &changelogwindow);
}
@@ -726,7 +756,7 @@ on_gpl1_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
char fname[PATH_MAX];
- snprintf (fname, sizeof (fname), DOCDIR "/%s", "COPYING.GPLv2");
+ snprintf (fname, sizeof (fname), "%s/%s", deadbeef->get_doc_dir (), "COPYING.GPLv2");
show_info_window (fname, "GNU GENERAL PUBLIC LICENSE Version 2", &gplwindow);
}
@@ -737,7 +767,7 @@ on_lgpl1_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
char fname[PATH_MAX];
- snprintf (fname, sizeof (fname), DOCDIR "/%s", "COPYING.LGPLv2.1");
+ snprintf (fname, sizeof (fname), "%s/%s", deadbeef->get_doc_dir (), "COPYING.LGPLv2.1");
show_info_window (fname, "GNU LESSER GENERAL PUBLIC LICENSE Version 2.1", &lgplwindow);
}
@@ -781,26 +811,7 @@ on_mainwin_window_state_event (GtkWidget *widget,
GdkEventWindowState *event,
gpointer user_data)
{
- // based on pidgin maximization handler
-#if GTK_CHECK_VERSION(2,2,0)
- if (event->changed_mask & GDK_WINDOW_STATE_MAXIMIZED) {
- if (event->new_window_state & GDK_WINDOW_STATE_MAXIMIZED) {
- deadbeef->conf_set_int ("mainwin.geometry.maximized", 1);
- }
- else {
- deadbeef->conf_set_int ("mainwin.geometry.maximized", 0);
- }
- }
-#else
- GdkWindowState new_window_state = gdk_window_get_state(G_OBJECT(widget));
-
- if (new_window_state & GDK_WINDOW_STATE_MAXIMIZED) {
- deadbeef->conf_set_int ("mainwin.geometry.maximized", 1);
- }
- else {
- deadbeef->conf_set_int ("mainwin.geometry.maximized", 0);
- }
-#endif
+ wingeom_save_max (event, widget, "mainwin");
return FALSE;
}
@@ -935,10 +946,10 @@ on_deselect_all1_activate (GtkMenuItem *menuitem,
}
deadbeef->pl_unlock ();
DdbListview *pl = DDB_LISTVIEW (lookup_widget (mainwin, "playlist"));
- ddb_listview_refresh (pl, DDB_REFRESH_LIST | DDB_EXPOSE_LIST);
+ ddb_listview_refresh (pl, DDB_REFRESH_LIST);
pl = DDB_LISTVIEW (lookup_widget (searchwin, "searchlist"));
if (pl) {
- ddb_listview_refresh (pl, DDB_REFRESH_LIST | DDB_EXPOSE_LIST);
+ ddb_listview_refresh (pl, DDB_REFRESH_LIST);
}
}
@@ -962,7 +973,7 @@ on_invert_selection1_activate (GtkMenuItem *menuitem,
}
deadbeef->pl_unlock ();
DdbListview *pl = DDB_LISTVIEW (lookup_widget (mainwin, "playlist"));
- ddb_listview_refresh (pl, DDB_REFRESH_LIST | DDB_EXPOSE_LIST);
+ ddb_listview_refresh (pl, DDB_REFRESH_LIST);
}
@@ -1079,7 +1090,96 @@ on_translators1_activate (GtkMenuItem *menuitem,
char s[200];
snprintf (s, sizeof (s), _("DeaDBeeF Translators"));
char fname[PATH_MAX];
- snprintf (fname, sizeof (fname), DOCDIR "/%s", "translators.txt");
+ snprintf (fname, sizeof (fname), "%s/%s", deadbeef->get_doc_dir (), "translators.txt");
show_info_window (fname, s, &translatorswindow);
}
+
+GtkWidget*
+title_formatting_help_link_create (gchar *widget_name, gchar *string1, gchar *string2,
+ gint int1, gint int2)
+{
+ GtkWidget *link = gtk_link_button_new_with_label ("http://sourceforge.net/apps/mediawiki/deadbeef/index.php?title=Title_Formatting", "Help");
+ return link;
+}
+
+
+void
+on_album1_activate (GtkMenuItem *menuitem,
+ gpointer user_data)
+{
+
+}
+
+
+void
+on_artist1_activate (GtkMenuItem *menuitem,
+ gpointer user_data)
+{
+
+}
+
+
+void
+on_date1_activate (GtkMenuItem *menuitem,
+ gpointer user_data)
+{
+
+}
+
+void
+on_custom2_activate (GtkMenuItem *menuitem,
+ gpointer user_data)
+{
+ GtkWidget *dlg = create_sortbydlg ();
+ gtk_dialog_set_default_response (GTK_DIALOG (dlg), GTK_RESPONSE_OK);
+
+ GtkComboBox *combo = GTK_COMBO_BOX (lookup_widget (dlg, "sortorder"));
+ GtkEntry *entry = GTK_ENTRY (lookup_widget (dlg, "sortfmt"));
+
+ gtk_combo_box_set_active (combo, deadbeef->conf_get_int ("gtkui.sortby_order", 0));
+ deadbeef->conf_lock ();
+ gtk_entry_set_text (entry, deadbeef->conf_get_str_fast ("gtkui.sortby_fmt", ""));
+ deadbeef->conf_unlock ();
+
+ int r = gtk_dialog_run (GTK_DIALOG (dlg));
+
+ if (r == GTK_RESPONSE_OK) {
+ GtkComboBox *combo = GTK_COMBO_BOX (lookup_widget (dlg, "sortorder"));
+ GtkEntry *entry = GTK_ENTRY (lookup_widget (dlg, "sortfmt"));
+ int order = gtk_combo_box_get_active (combo);
+ const char *fmt = gtk_entry_get_text (entry);
+
+ deadbeef->conf_set_int ("gtkui.sortby_order", order);
+ deadbeef->conf_set_str ("gtkui.sortby_fmt", fmt);
+
+ deadbeef->pl_sort (PL_MAIN, -1, fmt, order == 0 ? 1 : 0);
+
+ DdbListview *pl = DDB_LISTVIEW (lookup_widget (mainwin, "playlist"));
+ ddb_listview_clear_sort (pl);
+ ddb_listview_refresh (pl, DDB_REFRESH_LIST);
+ }
+
+ gtk_widget_destroy (dlg);
+ dlg = NULL;
+}
+
+
+void
+on_sortfmt_activate (GtkEntry *entry,
+ gpointer user_data)
+{
+ GtkWidget *toplevel = gtk_widget_get_toplevel (GTK_WIDGET (entry));
+ gtk_dialog_response (GTK_DIALOG (toplevel), GTK_RESPONSE_OK);
+}
+
+
+
+GtkWidget*
+create_plugin_weblink (gchar *widget_name, gchar *string1, gchar *string2,
+ gint int1, gint int2)
+{
+ GtkWidget *link = gtk_link_button_new_with_label ("", "WWW");
+ gtk_widget_set_sensitive (link, FALSE);
+ return link;
+}
diff --git a/plugins/gtkui/callbacks.h b/plugins/gtkui/callbacks.h
index b88df53c..4f15d342 100644
--- a/plugins/gtkui/callbacks.h
+++ b/plugins/gtkui/callbacks.h
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -291,16 +291,6 @@ void
volumebar_expose (GtkWidget *widget, int x, int y, int w, int h);
-
-void
-on_progress_abort (GtkButton *button,
- gpointer user_data);
-
-gboolean
-on_addprogress_delete_event (GtkWidget *widget,
- GdkEvent *event,
- gpointer user_data);
-
gboolean
on_volumebar_scroll_event (GtkWidget *widget,
GdkEventScroll *event,
@@ -983,3 +973,157 @@ on_jump_to_current_track1_activate (GtkMenuItem *menuitem,
void
on_translators1_activate (GtkMenuItem *menuitem,
gpointer user_data);
+
+
+GtkWidget*
+title_formatting_help_link_create (gchar *widget_name, gchar *string1, gchar *string2,
+ gint int1, gint int2);
+
+void
+on_album1_activate (GtkMenuItem *menuitem,
+ gpointer user_data);
+
+void
+on_artist1_activate (GtkMenuItem *menuitem,
+ gpointer user_data);
+
+void
+on_date1_activate (GtkMenuItem *menuitem,
+ gpointer user_data);
+
+void
+on_custom2_activate (GtkMenuItem *menuitem,
+ gpointer user_data);
+
+void
+on_sortfmt_activate (GtkEntry *entry,
+ gpointer user_data);
+
+void
+gtkui_dialog_response_ok (GtkEntry *entry,
+ gpointer user_data);
+
+
+void
+on_shuffle_albums1_activate (GtkMenuItem *menuitem,
+ gpointer user_data);
+
+void
+on_order_shuffle_albums_activate (GtkMenuItem *menuitem,
+ gpointer user_data);
+
+void
+on_dsp_add_clicked (GtkButton *button,
+ gpointer user_data);
+
+void
+on_dsp_remove_clicked (GtkButton *button,
+ gpointer user_data);
+
+void
+on_dsp_configure_clicked (GtkButton *button,
+ gpointer user_data);
+
+void
+on_dsp_up_clicked (GtkButton *button,
+ gpointer user_data);
+
+void
+on_dsp_down_clicked (GtkButton *button,
+ gpointer user_data);
+
+void
+on_auto_name_playlist_from_folder_toggled
+ (GtkToggleButton *togglebutton,
+ gpointer user_data);
+
+void
+on_dsp_preset_changed (GtkComboBox *combobox,
+ gpointer user_data);
+
+void
+on_dsp_preset_save_clicked (GtkButton *button,
+ gpointer user_data);
+
+void
+on_dsp_preset_load_clicked (GtkButton *button,
+ gpointer user_data);
+
+void
+on_plug_copyright_clicked (GtkButton *button,
+ gpointer user_data);
+
+GtkWidget*
+create_plugin_weblink (gchar *widget_name, gchar *string1, gchar *string2,
+ gint int1, gint int2);
+
+gboolean
+on_metalist_button_press_event (GtkWidget *widget,
+ GdkEventButton *event,
+ gpointer user_data);
+
+void
+on_tagwriter_settings_clicked (GtkButton *button,
+ gpointer user_data);
+
+gboolean
+on_trackproperties_configure_event (GtkWidget *widget,
+ GdkEventConfigure *event,
+ gpointer user_data);
+
+void
+on_trackproperties_state_changed (GtkWidget *widget,
+ GtkStateType state,
+ gpointer user_data);
+
+gboolean
+on_trackproperties_window_state_event (GtkWidget *widget,
+ GdkEventWindowState *event,
+ gpointer user_data);
+
+gboolean
+on_prefwin_configure_event (GtkWidget *widget,
+ GdkEventConfigure *event,
+ gpointer user_data);
+
+gboolean
+on_prefwin_window_state_event (GtkWidget *widget,
+ GdkEventWindowState *event,
+ gpointer user_data);
+
+void
+on_prefwin_realize (GtkWidget *widget,
+ gpointer user_data);
+
+gboolean
+on_prefwin_map_event (GtkWidget *widget,
+ GdkEvent *event,
+ gpointer user_data);
+
+void
+on_replaygain_preamp_value_changed (GtkRange *range,
+ gpointer user_data);
+
+void
+on_tabstrip_text_color_set (GtkColorButton *colorbutton,
+ gpointer user_data);
+
+void
+on_gui_plugin_changed (GtkComboBox *combobox,
+ gpointer user_data);
+
+void
+on_seekbar_fps_value_changed (GtkRange *range,
+ gpointer user_data);
+
+void
+on_gui_fps_value_changed (GtkRange *range,
+ gpointer user_data);
+
+void
+on_add_from_archives_toggled (GtkToggleButton *togglebutton,
+ gpointer user_data);
+
+void
+on_ignore_archives_toggled (GtkToggleButton *togglebutton,
+ gpointer user_data);
diff --git a/plugins/gtkui/coverart.c b/plugins/gtkui/coverart.c
index 7fb50554..4118aa66 100644
--- a/plugins/gtkui/coverart.c
+++ b/plugins/gtkui/coverart.c
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@@ -21,12 +21,11 @@
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
+#include <sys/stat.h>
#include "coverart.h"
#include "../artwork/artwork.h"
#include "gtkui.h"
-#define DEFAULT_COVER_PATH (PREFIX "/share/deadbeef/pixmaps/noartwork.jpg")
-
//#define trace(...) { fprintf(stderr, __VA_ARGS__); }
#define trace(...)
@@ -38,6 +37,7 @@ extern DB_artwork_plugin_t *coverart_plugin;
typedef struct {
struct timeval tm;
char *fname;
+ time_t filetime;
int width;
GdkPixbuf *pixbuf;
} cached_pixbuf_t;
@@ -140,10 +140,13 @@ loading_thread (void *none) {
usleep (500000);
continue;
}
-
-// GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file (queue->fname, NULL);
+ struct stat stat_buf;
+ if (stat (queue->fname, &stat_buf) < 0) {
+ trace ("failed to stat file %s\n", queue->fname);
+ }
+ GdkPixbuf *pixbuf = NULL;
GError *error = NULL;
- GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file_at_scale (queue->fname, queue->width, queue->width, TRUE, &error);
+ pixbuf = gdk_pixbuf_new_from_file_at_scale (queue->fname, queue->width, queue->width, TRUE, &error);
if (!pixbuf) {
unlink (queue->fname);
fprintf (stderr, "gdk_pixbuf_new_from_file_at_scale %s %d failed, error: %s\n", queue->fname, queue->width, error->message);
@@ -151,9 +154,13 @@ loading_thread (void *none) {
g_error_free (error);
error = NULL;
}
- pixbuf = gdk_pixbuf_new_from_file_at_scale (DEFAULT_COVER_PATH, queue->width, queue->width, TRUE, &error);
+ const char *defpath = coverart_plugin->get_default_cover ();
+ if (stat (defpath, &stat_buf) < 0) {
+ trace ("failed to stat file %s\n", queue->fname);
+ }
+ pixbuf = gdk_pixbuf_new_from_file_at_scale (defpath, queue->width, queue->width, TRUE, &error);
if (!pixbuf) {
- fprintf (stderr, "gdk_pixbuf_new_from_file_at_scale %s %d failed, error: %s\n", DEFAULT_COVER_PATH, queue->width, error->message);
+ fprintf (stderr, "gdk_pixbuf_new_from_file_at_scale %s %d failed, error: %s\n", defpath, queue->width, error->message);
}
}
if (error) {
@@ -163,43 +170,16 @@ loading_thread (void *none) {
if (!pixbuf) {
// make default empty image
pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, 2, 2);
+ stat_buf.st_mtime = 0;
}
-#if 0
- else {
- int w, h;
- w = gdk_pixbuf_get_width (pixbuf);
- h = gdk_pixbuf_get_height (pixbuf);
- int width = queue->width;
- if (w != width) {
- int height;
- if (w > h) {
- height = width * h / w;
- }
- else if (h > w) {
- height = width;
- width = height * w / h;
- }
- else {
- height = width;
- }
- if (width < 5 || height < 5) {
- trace ("will not scale to %dx%d\n", width, height);
- queue_pop ();
- continue;
- }
- trace ("scaling %dx%d -> %dx%d\n", w, h, width, height);
- GdkPixbuf *scaled = gdk_pixbuf_scale_simple (pixbuf, width, height, GDK_INTERP_BILINEAR);
- g_object_unref (pixbuf);
- pixbuf = scaled;
- }
- }
-#endif
if (cache_min != -1) {
deadbeef->mutex_lock (mutex);
+ cache[cache_min].filetime = stat_buf.st_mtime;
cache[cache_min].pixbuf = pixbuf;
cache[cache_min].fname = strdup (queue->fname);
gettimeofday (&cache[cache_min].tm, NULL);
cache[cache_min].width = queue->width;
+ struct stat stat_buf;
deadbeef->mutex_unlock (mutex);
}
queue_pop ();
@@ -231,11 +211,15 @@ get_pixbuf (const char *fname, int width) {
for (int i = 0; i < CACHE_SIZE; i++) {
if (cache[i].pixbuf) {
if (!strcmp (fname, cache[i].fname) && cache[i].width == width) {
- gettimeofday (&cache[i].tm, NULL);
- GdkPixbuf *pb = cache[i].pixbuf;
- g_object_ref (pb);
- deadbeef->mutex_unlock (mutex);
- return pb;
+ // check if cached filetime hasn't changed
+ struct stat stat_buf;
+ if (!stat (fname, &stat_buf) && stat_buf.st_mtime == cache[i].filetime) {
+ gettimeofday (&cache[i].tm, NULL);
+ GdkPixbuf *pb = cache[i].pixbuf;
+ g_object_ref (pb);
+ deadbeef->mutex_unlock (mutex);
+ return pb;
+ }
}
}
}
@@ -257,7 +241,7 @@ get_cover_art (const char *fname, const char *artist, const char *album, int wid
if (!coverart_plugin) {
return NULL;
}
- char *image_fname = coverart_plugin->get_album_art (fname, artist, album, cover_avail_callback, (void *)(intptr_t)width);
+ char *image_fname = coverart_plugin->get_album_art (fname, artist, album, -1, cover_avail_callback, (void *)(intptr_t)width);
if (image_fname) {
GdkPixbuf *pb = get_pixbuf (image_fname, width);
free (image_fname);
diff --git a/plugins/gtkui/coverart.h b/plugins/gtkui/coverart.h
index 75a96429..689e0f80 100644
--- a/plugins/gtkui/coverart.h
+++ b/plugins/gtkui/coverart.h
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
diff --git a/plugins/gtkui/ddbcellrenderertextmultiline.c b/plugins/gtkui/ddbcellrenderertextmultiline.c
index 867c70e4..a6e95853 100644
--- a/plugins/gtkui/ddbcellrenderertextmultiline.c
+++ b/plugins/gtkui/ddbcellrenderertextmultiline.c
@@ -1,4 +1,4 @@
-/* ddbcellrenderertextmultiline.c generated by valac 0.10.0, the Vala compiler
+/* ddbcellrenderertextmultiline.c generated by valac 0.10.2, the Vala compiler
* generated from ddbcellrenderertextmultiline.vala, do not modify */
/*
@@ -52,6 +52,7 @@ typedef struct _DdbCellRendererTextMultiline DdbCellRendererTextMultiline;
typedef struct _DdbCellRendererTextMultilineClass DdbCellRendererTextMultilineClass;
typedef struct _DdbCellRendererTextMultilinePrivate DdbCellRendererTextMultilinePrivate;
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
+#define _gtk_tree_path_free0(var) ((var == NULL) ? NULL : (var = (gtk_tree_path_free (var), NULL)))
struct _DdbCellEditableTextView {
GtkTextView parent_instance;
@@ -213,7 +214,7 @@ static void ddb_cell_renderer_text_multiline_gtk_cell_renderer_text_editing_done
buf = _g_object_ref0 (gtk_text_view_get_buffer ((GtkTextView*) entry));
gtk_text_buffer_get_iter_at_offset (buf, &begin, 0);
gtk_text_buffer_get_iter_at_offset (buf, &end, -1);
- new_text = g_strdup (gtk_text_buffer_get_text (buf, &begin, &end, TRUE));
+ new_text = gtk_text_buffer_get_text (buf, &begin, &end, TRUE);
g_signal_emit_by_name ((GtkCellRendererText*) _self_, "edited", entry->tree_path, new_text);
_g_free0 (new_text);
_g_object_unref0 (buf);
@@ -236,12 +237,20 @@ static GtkCellEditable* ddb_cell_renderer_text_multiline_real_start_editing (Gtk
DdbCellRendererTextMultiline * self;
GtkCellEditable* result = NULL;
gboolean _tmp0_;
- DdbCellEditableTextView* _tmp1_;
- char* _tmp2_;
- GtkTextBuffer* buf;
- char* _tmp3_ = NULL;
+ GtkTreePath* p;
+ GtkTreeView* tv;
+ GtkListStore* store;
+ GtkTreeIter iter = {0};
+ GValue v = {0};
+ GValue _tmp1_ = {0};
+ GValue _tmp2_;
+ gint mult;
+ DdbCellEditableTextView* _tmp3_;
char* _tmp4_;
- gboolean _tmp5_;
+ GtkTextBuffer* buf;
+ char* _tmp5_ = NULL;
+ char* _tmp6_;
+ gboolean _tmp7_;
self = (DdbCellRendererTextMultiline*) base;
g_return_val_if_fail (event != NULL, NULL);
g_return_val_if_fail (widget != NULL, NULL);
@@ -250,14 +259,24 @@ static GtkCellEditable* ddb_cell_renderer_text_multiline_real_start_editing (Gtk
result = GTK_CELL_EDITABLE (NULL);
return result;
}
- self->priv->entry = (_tmp1_ = g_object_ref_sink (ddb_cell_editable_text_view_new ()), _g_object_unref0 (self->priv->entry), _tmp1_);
- self->priv->entry->tree_path = (_tmp2_ = g_strdup (path), _g_free0 (self->priv->entry->tree_path), _tmp2_);
+ p = gtk_tree_path_new_from_string (path);
+ tv = _g_object_ref0 (GTK_TREE_VIEW (widget));
+ store = _g_object_ref0 (GTK_LIST_STORE (gtk_tree_view_get_model (tv)));
+ gtk_tree_model_get_iter ((GtkTreeModel*) store, &iter, p);
+ gtk_tree_model_get_value ((GtkTreeModel*) store, &iter, 3, &_tmp1_);
+ v = (_tmp2_ = _tmp1_, G_IS_VALUE (&v) ? (g_value_unset (&v), NULL) : NULL, _tmp2_);
+ mult = g_value_get_int (&v);
+ self->priv->entry = (_tmp3_ = g_object_ref_sink (ddb_cell_editable_text_view_new ()), _g_object_unref0 (self->priv->entry), _tmp3_);
+ if (mult != 0) {
+ g_object_set ((GtkCellRendererText*) self, "text", "", NULL);
+ }
+ self->priv->entry->tree_path = (_tmp4_ = g_strdup (path), _g_free0 (self->priv->entry->tree_path), _tmp4_);
buf = gtk_text_buffer_new (NULL);
- if ((_tmp5_ = (_tmp4_ = (g_object_get ((GtkCellRendererText*) self, "text", &_tmp3_, NULL), _tmp3_)) != NULL, _g_free0 (_tmp4_), _tmp5_)) {
- char* _tmp6_ = NULL;
- char* _tmp7_;
- gtk_text_buffer_set_text (buf, _tmp7_ = (g_object_get ((GtkCellRendererText*) self, "text", &_tmp6_, NULL), _tmp6_), -1);
- _g_free0 (_tmp7_);
+ if ((_tmp7_ = (_tmp6_ = (g_object_get ((GtkCellRendererText*) self, "text", &_tmp5_, NULL), _tmp5_)) != NULL, _g_free0 (_tmp6_), _tmp7_)) {
+ char* _tmp8_ = NULL;
+ char* _tmp9_;
+ gtk_text_buffer_set_text (buf, _tmp9_ = (g_object_get ((GtkCellRendererText*) self, "text", &_tmp8_, NULL), _tmp8_), -1);
+ _g_free0 (_tmp9_);
}
gtk_text_view_set_buffer ((GtkTextView*) self->priv->entry, buf);
g_signal_connect (self->priv->entry, "editing-done", (GCallback) ddb_cell_renderer_text_multiline_gtk_cell_renderer_text_editing_done, self);
@@ -266,6 +285,10 @@ static GtkCellEditable* ddb_cell_renderer_text_multiline_real_start_editing (Gtk
gtk_widget_show ((GtkWidget*) self->priv->entry);
result = GTK_CELL_EDITABLE (self->priv->entry);
_g_object_unref0 (buf);
+ G_IS_VALUE (&v) ? (g_value_unset (&v), NULL) : NULL;
+ _g_object_unref0 (store);
+ _g_object_unref0 (tv);
+ _gtk_tree_path_free0 (p);
return result;
}
diff --git a/plugins/gtkui/ddbcellrenderertextmultiline.h b/plugins/gtkui/ddbcellrenderertextmultiline.h
index 787beb50..2fec6b26 100644
--- a/plugins/gtkui/ddbcellrenderertextmultiline.h
+++ b/plugins/gtkui/ddbcellrenderertextmultiline.h
@@ -1,4 +1,4 @@
-/* ddbcellrenderertextmultiline.h generated by valac 0.10.0, the Vala compiler, do not modify */
+/* ddbcellrenderertextmultiline.h generated by valac 0.10.2, the Vala compiler, do not modify */
#ifndef __DDBCELLRENDERERTEXTMULTILINE_H__
diff --git a/plugins/gtkui/ddbcellrenderertextmultiline.vala b/plugins/gtkui/ddbcellrenderertextmultiline.vala
index 75e7bdc9..4587cff9 100644
--- a/plugins/gtkui/ddbcellrenderertextmultiline.vala
+++ b/plugins/gtkui/ddbcellrenderertextmultiline.vala
@@ -79,7 +79,21 @@ namespace Ddb {
if (!editable) {
return (Gtk.CellEditable)null;
}
+
+ Gtk.TreePath p = new Gtk.TreePath.from_string (path);
+ Gtk.TreeView tv = (Gtk.TreeView)widget;
+ Gtk.ListStore store = (Gtk.ListStore)tv.get_model();
+ Gtk.TreeIter iter;
+ store.get_iter (out iter, p);
+ GLib.Value v;
+ store.get_value (iter, 3, out v);
+ int mult = v.get_int ();
+
entry = new CellEditableTextView ();
+ if (mult != 0) {
+ text = "";
+ }
+
entry.tree_path = path;
Gtk.TextBuffer buf = new Gtk.TextBuffer (null);
if (text != null) {
diff --git a/plugins/gtkui/ddbequalizer.c b/plugins/gtkui/ddbequalizer.c
index 201277ad..7cd9ee4f 100644
--- a/plugins/gtkui/ddbequalizer.c
+++ b/plugins/gtkui/ddbequalizer.c
@@ -1,4 +1,4 @@
-/* ddbequalizer.c generated by valac 0.10.0, the Vala compiler
+/* ddbequalizer.c generated by valac 0.10.2, the Vala compiler
* generated from ddbequalizer.vala, do not modify */
/*
diff --git a/plugins/gtkui/ddbequalizer.h b/plugins/gtkui/ddbequalizer.h
index 19f98c23..2ce2ba5c 100644
--- a/plugins/gtkui/ddbequalizer.h
+++ b/plugins/gtkui/ddbequalizer.h
@@ -1,4 +1,4 @@
-/* ddbequalizer.h generated by valac 0.10.0, the Vala compiler, do not modify */
+/* ddbequalizer.h generated by valac 0.10.2, the Vala compiler, do not modify */
#ifndef __DDBEQUALIZER_H__
diff --git a/plugins/gtkui/ddblistview.c b/plugins/gtkui/ddblistview.c
index 89a27cff..479c03c8 100644
--- a/plugins/gtkui/ddblistview.c
+++ b/plugins/gtkui/ddblistview.c
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -88,20 +88,19 @@ static void ddb_listview_destroy(GtkObject *object);
// fwd decls
void
ddb_listview_free_groups (DdbListview *listview);
-static inline void
-draw_drawable (GdkDrawable *window, GdkGC *gc, GdkDrawable *drawable, int x1, int y1, int x2, int y2, int w, int h);
+
+//static inline void
+//draw_drawable (GdkDrawable *window, GdkGC *gc, GdkDrawable *drawable, int x1, int y1, int x2, int y2, int w, int h);
////// list functions ////
void
ddb_listview_list_render (DdbListview *ps, int x, int y, int w, int h);
void
-ddb_listview_list_expose (DdbListview *ps, int x, int y, int w, int h);
-void
ddb_listview_list_render_row_background (DdbListview *ps, DdbListviewIter it, int even, int cursor, int x, int y, int w, int h);
void
ddb_listview_list_render_row_foreground (DdbListview *ps, DdbListviewIter it, DdbListviewIter group_it, int even, int cursor, int group_y, int x, int y, int w, int h);
-void
-ddb_listview_list_render_row (DdbListview *ps, int row, DdbListviewIter it, int expose);
+//void
+//ddb_listview_list_render_row (DdbListview *ps, int row, DdbListviewIter it);
void
ddb_listview_list_track_dragdrop (DdbListview *ps, int y);
int
@@ -122,8 +121,6 @@ ddb_listview_get_row_pos (DdbListview *listview, int pos);
////// header functions ////
void
ddb_listview_header_render (DdbListview *ps);
-void
-ddb_listview_header_expose (DdbListview *ps, int x, int y, int w, int h);
////// column management functions ////
void
@@ -282,8 +279,9 @@ static void
ddb_listview_init(DdbListview *listview)
{
// init instance - create all subwidgets, and insert into table
+ draw_init_font (GTK_WIDGET(listview)->style);
- listview->rowheight = draw_get_font_size () + 12;
+ listview->rowheight = draw_get_listview_rowheight ();
listview->col_movepos = -1;
listview->drag_motion_y = -1;
@@ -470,18 +468,6 @@ ddb_listview_destroy(GtkObject *object)
gdk_cursor_unref (listview->cursor_drag);
listview->cursor_drag = NULL;
}
- if (listview->backbuf) {
- g_object_unref (listview->backbuf);
- listview->backbuf = NULL;
- }
- if (listview->backbuf_header) {
- g_object_unref (listview->backbuf_header);
- listview->backbuf_header = NULL;
- }
-
-// if (G_OBJECT_CLASS (ddb_listview_parent_class)) {
-// G_OBJECT_CLASS (ddb_listview_parent_class)->destroy (object);
-// }
}
void
@@ -492,7 +478,7 @@ ddb_listview_refresh (DdbListview *listview, uint32_t flags) {
if (height != listview->fullheight) {
flags |= DDB_REFRESH_VSCROLL;
}
- ddb_listview_list_render (listview, 0, 0, listview->list->allocation.width, listview->list->allocation.height);
+ gtk_widget_queue_draw (listview->list);
}
if (flags & DDB_REFRESH_VSCROLL) {
ddb_listview_list_setup_vscroll (listview);
@@ -501,13 +487,7 @@ ddb_listview_refresh (DdbListview *listview, uint32_t flags) {
ddb_listview_list_setup_hscroll (listview);
}
if (flags & DDB_REFRESH_COLUMNS) {
- ddb_listview_header_render (listview);
- }
- if (flags & DDB_EXPOSE_COLUMNS) {
- ddb_listview_header_expose (listview, 0, 0, listview->header->allocation.width, listview->header->allocation.height);
- }
- if (flags & DDB_EXPOSE_LIST) {
- ddb_listview_list_expose (listview, 0, 0, listview->list->allocation.width, listview->list->allocation.height);
+ gtk_widget_queue_draw (listview->header);
}
}
@@ -516,9 +496,9 @@ ddb_listview_list_realize (GtkWidget *widget,
gpointer user_data)
{
GtkTargetEntry entry = {
- .target = "STRING",
+ .target = "DDB_URI_LIST",
.flags = GTK_TARGET_SAME_APP,
- TARGET_SAMEWIDGET
+ .info = TARGET_SAMEWIDGET
};
// setup drag-drop target
gtk_drag_dest_set (widget, GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_DROP, &entry, 1, GDK_ACTION_COPY | GDK_ACTION_MOVE);
@@ -534,7 +514,7 @@ ddb_listview_list_configure_event (GtkWidget *widget,
DdbListview *ps = DDB_LISTVIEW (g_object_get_data (G_OBJECT (widget), "owner"));
draw_init_font (widget->style);
- int height = draw_get_font_size () + 12;
+ int height = draw_get_listview_rowheight ();
if (height != ps->rowheight) {
ps->rowheight = height;
ddb_listview_build_groups (ps);
@@ -543,13 +523,7 @@ ddb_listview_list_configure_event (GtkWidget *widget,
ddb_listview_list_setup_vscroll (ps);
ddb_listview_list_setup_hscroll (ps);
widget = ps->list;
- if (ps->backbuf) {
- g_object_unref (ps->backbuf);
- ps->backbuf = NULL;
- }
- ps->backbuf = gdk_pixmap_new (widget->window, widget->allocation.width, widget->allocation.height, -1);
- ddb_listview_list_render (ps, 0, 0, widget->allocation.width, widget->allocation.height);
return FALSE;
}
@@ -608,9 +582,6 @@ ddb_listview_list_pickpoint_y (DdbListview *listview, int y, DdbListviewGroup **
void
ddb_listview_list_render (DdbListview *listview, int x, int y, int w, int h) {
- if (!listview->backbuf) {
- return;
- }
GtkWidget *treeview = theme_treeview;
if (treeview->style->depth == -1) {
return; // drawing was called too early
@@ -627,7 +598,7 @@ ddb_listview_list_render (DdbListview *listview, int x, int y, int w, int h) {
abs_idx += grp->num_items;
grp = grp->next;
}
- draw_begin ((uintptr_t)listview->backbuf);
+ draw_begin ((uintptr_t)listview->list->window);
int ii = 0;
while (grp && grp_y < y + h + listview->scrollpos) {
@@ -641,7 +612,7 @@ ddb_listview_list_render (DdbListview *listview, int x, int y, int w, int h) {
if (grp_y + listview->grouptitle_height >= y + listview->scrollpos && grp_y < y + h + listview->scrollpos) {
ddb_listview_list_render_row_background (listview, NULL, idx & 1, 0, -listview->hscrollpos, grp_y - listview->scrollpos, listview->totalwidth, listview->grouptitle_height);
if (listview->binding->draw_group_title && listview->grouptitle_height > 0) {
- listview->binding->draw_group_title (listview, listview->backbuf, it, -listview->hscrollpos, grp_y - listview->scrollpos, listview->totalwidth, listview->grouptitle_height);
+ listview->binding->draw_group_title (listview, listview->list->window, it, -listview->hscrollpos, grp_y - listview->scrollpos, listview->totalwidth, listview->grouptitle_height);
}
}
for (int i = 0; i < grp->num_items; i++) {
@@ -654,7 +625,7 @@ ddb_listview_list_render (DdbListview *listview, int x, int y, int w, int h) {
}
if (grp_y + listview->grouptitle_height + (i+1) * listview->rowheight >= y + listview->scrollpos
&& grp_y + listview->grouptitle_height + i * listview->rowheight < y + h + listview->scrollpos) {
- gdk_draw_rectangle (listview->backbuf, listview->list->style->bg_gc[GTK_STATE_NORMAL], TRUE, -listview->hscrollpos, grp_y + listview->grouptitle_height + i * listview->rowheight - listview->scrollpos, listview->totalwidth, listview->rowheight);
+ gdk_draw_rectangle (listview->list->window, listview->list->style->bg_gc[GTK_STATE_NORMAL], TRUE, -listview->hscrollpos, grp_y + listview->grouptitle_height + i * listview->rowheight - listview->scrollpos, listview->totalwidth, listview->rowheight);
ddb_listview_list_render_row_background (listview, it, (idx + 1 + i) & 1, (abs_idx+i) == listview->binding->cursor () ? 1 : 0, -listview->hscrollpos, grp_y + listview->grouptitle_height + i * listview->rowheight - listview->scrollpos, listview->totalwidth, listview->rowheight);
ddb_listview_list_render_row_foreground (listview, it, grp->head, (idx + 1 + i) & 1, (idx+i) == listview->binding->cursor () ? 1 : 0, i * listview->rowheight, -listview->hscrollpos, grp_y + listview->grouptitle_height + i * listview->rowheight - listview->scrollpos, listview->totalwidth, listview->rowheight);
}
@@ -675,13 +646,13 @@ ddb_listview_list_render (DdbListview *listview, int x, int y, int w, int h) {
if (filler > 0) {
int theming = !gtkui_override_listview_colors ();
if (theming) {
- gtk_paint_flat_box (treeview->style, listview->backbuf, GTK_STATE_NORMAL, GTK_SHADOW_NONE, NULL, treeview, "cell_even_ruled", x, grp_y - listview->scrollpos + listview->grouptitle_height + listview->rowheight * grp->num_items, w, filler);
+ gtk_paint_flat_box (treeview->style, listview->list->window, GTK_STATE_NORMAL, GTK_SHADOW_NONE, NULL, treeview, "cell_even_ruled", x, grp_y - listview->scrollpos + listview->grouptitle_height + listview->rowheight * grp->num_items, w, filler);
}
else {
GdkColor clr;
- GdkGC *gc = gdk_gc_new (listview->backbuf);
+ GdkGC *gc = gdk_gc_new (listview->list->window);
gdk_gc_set_rgb_fg_color (gc, (gtkui_get_listview_even_row_color (&clr), &clr));
- gdk_draw_rectangle (listview->backbuf, gc, TRUE, x, grp_y - listview->scrollpos + listview->grouptitle_height + listview->rowheight * grp->num_items, w, filler);
+ gdk_draw_rectangle (listview->list->window, gc, TRUE, x, grp_y - listview->scrollpos + listview->grouptitle_height + listview->rowheight * grp->num_items, w, filler);
g_object_unref (gc);
}
@@ -694,16 +665,16 @@ ddb_listview_list_render (DdbListview *listview, int x, int y, int w, int h) {
}
if (grp_y < y + h + listview->scrollpos) {
int hh = y + h - (grp_y - listview->scrollpos);
-// gdk_draw_rectangle (listview->backbuf, listview->list->style->bg_gc[GTK_STATE_NORMAL], TRUE, x, grp_y - listview->scrollpos, w, hh);
+// gdk_draw_rectangle (listview->list->window, listview->list->style->bg_gc[GTK_STATE_NORMAL], TRUE, x, grp_y - listview->scrollpos, w, hh);
int theming = !gtkui_override_listview_colors ();
if (theming) {
- gtk_paint_flat_box (treeview->style, listview->backbuf, GTK_STATE_NORMAL, GTK_SHADOW_NONE, NULL, treeview, "cell_even_ruled", x, grp_y - listview->scrollpos, w, hh);
+ gtk_paint_flat_box (treeview->style, listview->list->window, GTK_STATE_NORMAL, GTK_SHADOW_NONE, NULL, treeview, "cell_even_ruled", x, grp_y - listview->scrollpos, w, hh);
}
else {
GdkColor clr;
- GdkGC *gc = gdk_gc_new (listview->backbuf);
+ GdkGC *gc = gdk_gc_new (listview->list->window);
gdk_gc_set_rgb_fg_color (gc, (gtkui_get_listview_even_row_color (&clr), &clr));
- gdk_draw_rectangle (listview->backbuf, gc, TRUE, x, grp_y - listview->scrollpos, w, hh);
+ gdk_draw_rectangle (listview->list->window, gc, TRUE, x, grp_y - listview->scrollpos, w, hh);
g_object_unref (gc);
}
}
@@ -711,16 +682,6 @@ ddb_listview_list_render (DdbListview *listview, int x, int y, int w, int h) {
draw_end ();
}
-gboolean
-ddb_listview_list_expose_event (GtkWidget *widget,
- GdkEventExpose *event,
- gpointer user_data)
-{
- DdbListview *ps = DDB_LISTVIEW (g_object_get_data (G_OBJECT (widget), "owner"));
- ddb_listview_list_expose (ps, event->area.x, event->area.y, event->area.width, event->area.height);
- return FALSE;
-}
-
static void
ddb_listview_draw_dnd_marker (DdbListview *ps) {
if (ps->drag_motion_y < 0) {
@@ -740,15 +701,20 @@ ddb_listview_draw_dnd_marker (DdbListview *ps) {
}
-void
-ddb_listview_list_expose (DdbListview *listview, int x, int y, int w, int h) {
- GtkWidget *widget = listview->list;
- if (widget->window && listview->backbuf) {
- draw_drawable (widget->window, widget->style->black_gc, listview->backbuf, x, y, x, y, w, h);
+gboolean
+ddb_listview_list_expose_event (GtkWidget *widget,
+ GdkEventExpose *event,
+ gpointer user_data)
+{
+ DdbListview *ps = DDB_LISTVIEW (g_object_get_data (G_OBJECT (widget), "owner"));
+ widget = ps->list;
+ if (widget->window) {
+ ddb_listview_list_render (ps, event->area.x, event->area.y, event->area.width, event->area.height);
}
- if (listview->drag_motion_y >= 0 && listview->drag_motion_y-listview->scrollpos-3 < y+h && listview->drag_motion_y-listview->scrollpos+3 >= y) {
- ddb_listview_draw_dnd_marker (listview);
+ if (ps->drag_motion_y >= 0 && ps->drag_motion_y-ps->scrollpos-3 < event->area.y+event->area.height && ps->drag_motion_y-ps->scrollpos+3 >= event->area.y) {
+ ddb_listview_draw_dnd_marker (ps);
}
+ return FALSE;
}
gboolean
@@ -795,19 +761,23 @@ ddb_listview_vscroll_value_changed (GtkRange *widget,
if (di > 0) {
// scroll down
// copy scrolled part of buffer
- draw_drawable (ps->backbuf, widget->style->black_gc, ps->backbuf, 0, d, 0, 0, widget->allocation.width, widget->allocation.height-d);
+ gdk_draw_drawable (ps->list->window, widget->style->black_gc, ps->list->window, 0, d, 0, 0, widget->allocation.width, widget->allocation.height-d);
+// draw_drawable (ps->list->window, widget->style->black_gc, ps->list->window, 0, d, 0, 0, widget->allocation.width, widget->allocation.height-d);
// redraw other part
int start = height-d-1;
ps->scrollpos = newscroll;
- ddb_listview_list_render (ps, 0, start, ps->list->allocation.width, widget->allocation.height-start);
+ gtk_widget_queue_draw_area (ps->list, 0, start, ps->list->allocation.width, widget->allocation.height-start);
+// ddb_listview_list_render (ps, 0, start, ps->list->allocation.width, widget->allocation.height-start);
}
else {
// scroll up
// copy scrolled part of buffer
- draw_drawable (ps->backbuf, widget->style->black_gc, ps->backbuf, 0, 0, 0, d, widget->allocation.width, widget->allocation.height-d);
+ gdk_draw_drawable (ps->list->window, widget->style->black_gc, ps->list->window, 0, 0, 0, d, widget->allocation.width, widget->allocation.height-d);
+ //draw_drawable (ps->list->window, widget->style->black_gc, ps->list->window, 0, 0, 0, d, widget->allocation.width, widget->allocation.height-d);
// redraw other part
ps->scrollpos = newscroll;
- ddb_listview_list_render (ps, 0, 0, ps->list->allocation.width, d+1);
+ gtk_widget_queue_draw_area (ps->list, 0, 0, ps->list->allocation.width, d+1);
+ //ddb_listview_list_render (ps, 0, 0, ps->list->allocation.width, d+1);
}
}
else {
@@ -815,7 +785,8 @@ ddb_listview_vscroll_value_changed (GtkRange *widget,
ps->scrollpos = newscroll;
ddb_listview_list_render (ps, 0, 0, widget->allocation.width, widget->allocation.height);
}
- draw_drawable (widget->window, widget->style->black_gc, ps->backbuf, 0, 0, 0, 0, widget->allocation.width, widget->allocation.height);
+ gtk_widget_queue_draw (ps->list);
+// draw_drawable (widget->window, widget->style->black_gc, ps->list->window, 0, 0, 0, 0, widget->allocation.width, widget->allocation.height);
}
}
@@ -877,17 +848,6 @@ ddb_listview_list_drag_drop (GtkWidget *widget,
gpointer user_data)
{
return TRUE;
-#if 0
- if (drag_context->targets) {
- GdkAtom target_type = GDK_POINTER_TO_ATOM (g_list_nth_data (drag_context->targets, TARGET_SAMEWIDGET));
- if (!target_type) {
- return FALSE;
- }
-// gtk_drag_get_data (widget, drag_context, target_type, time);
- return TRUE;
- }
- return FALSE;
-#endif
}
@@ -942,6 +902,7 @@ ddb_listview_list_drag_data_received (GtkWidget *widget,
guint time,
gpointer user_data)
{
+ printf ("target_type: %d, format: %d\n", target_type, data->format);
DdbListview *ps = DDB_LISTVIEW (g_object_get_data (G_OBJECT (widget), "owner"));
ps->scroll_direction = 0; // interrupt autoscrolling, if on
ps->scroll_active = 0;
@@ -972,7 +933,7 @@ ddb_listview_list_drag_data_received (GtkWidget *widget,
UNREF (it);
}
}
- else if (target_type == 1) {
+ else if (target_type == 1 && data->format == 32) { // list of 32bit ints, DDB_URI_LIST target
uint32_t *d= (uint32_t *)ptr;
int plt = *d;
d++;
@@ -1013,17 +974,17 @@ ddb_listview_list_drag_leave (GtkWidget *widget,
}
// debug function for gdk_draw_drawable
-static inline void
-draw_drawable (GdkDrawable *window, GdkGC *gc, GdkDrawable *drawable, int x1, int y1, int x2, int y2, int w, int h) {
- gint width1, height1;
- gint width2, height2;
- gdk_drawable_get_size (window, &width1, &height1);
- gdk_drawable_get_size (drawable, &width2, &height2);
-// assert (y1 >= 0 && y1 + h < height2);
-// assert (y2 >= 0 && y2 + h < height1);
-// printf ("dd: %p %p %p %d %d %d %d %d %d\n", window, gc, drawable, x1, y1, x2, y2, w, h);
- gdk_draw_drawable (window, gc, drawable, x1, y1, x2, y2, w, h);
-}
+//static inline void
+//draw_drawable (GdkDrawable *window, GdkGC *gc, GdkDrawable *drawable, int x1, int y1, int x2, int y2, int w, int h) {
+// gint width1, height1;
+// gint width2, height2;
+// gdk_drawable_get_size (window, &width1, &height1);
+// gdk_drawable_get_size (drawable, &width2, &height2);
+//// assert (y1 >= 0 && y1 + h < height2);
+//// assert (y2 >= 0 && y2 + h < height1);
+//// printf ("dd: %p %p %p %d %d %d %d %d %d\n", window, gc, drawable, x1, y1, x2, y2, w, h);
+// gdk_draw_drawable (window, gc, drawable, x1, y1, x2, y2, w, h);
+//}
int
ddb_listview_get_vscroll_pos (DdbListview *listview) {
@@ -1117,8 +1078,7 @@ ddb_listview_list_setup_vscroll (DdbListview *ps) {
if (ps->fullheight <= ps->list->allocation.height) {
gtk_widget_hide (scroll);
ps->scrollpos = 0;
- ddb_listview_list_render (ps, 0, 0, list->allocation.width, list->allocation.height);
- ddb_listview_list_expose (ps, 0, 0, list->allocation.width, list->allocation.height);
+ gtk_widget_queue_draw (ps->list);
}
else {
gtk_widget_show (scroll);
@@ -1194,8 +1154,9 @@ ddb_listview_list_get_drawinfo (DdbListview *listview, int row, DdbListviewGroup
return -1;
}
+#if 0
void
-ddb_listview_list_render_row (DdbListview *listview, int row, DdbListviewIter it, int expose) {
+ddb_listview_list_render_row (DdbListview *listview, int row, DdbListviewIter it) {
DdbListviewGroup *grp;
int even;
int cursor;
@@ -1213,20 +1174,34 @@ ddb_listview_list_render_row (DdbListview *listview, int row, DdbListviewIter it
return;
}
- draw_begin ((uintptr_t)listview->backbuf);
+ draw_begin ((uintptr_t)listview->list->window);
ddb_listview_list_render_row_background (listview, it, even, cursor, x, y, w, h);
if (it) {
ddb_listview_list_render_row_foreground (listview, it, grp->head, even, cursor, group_y, x, y, w, h);
}
draw_end ();
- if (expose) {
- draw_drawable (listview->list->window, listview->list->style->black_gc, listview->backbuf, 0, y, 0, y, listview->list->allocation.width, h);
- }
}
+#endif
void
ddb_listview_draw_row (DdbListview *listview, int row, DdbListviewIter it) {
- ddb_listview_list_render_row (listview, row, it, 1);
+ DdbListviewGroup *grp;
+ int even;
+ int cursor;
+ int x, y, w, h;
+ int group_y;
+ if (ddb_listview_list_get_drawinfo (listview, row, &grp, &even, &cursor, &group_y, &x, &y, &w, &h) == -1) {
+ return;
+ }
+
+ if (y + h <= 0) {
+ return;
+ }
+
+ if (y > GTK_WIDGET (listview)->allocation.height) {
+ return;
+ }
+ gtk_widget_queue_draw_area (listview->list, 0, y, listview->list->allocation.width, h);
}
// coords passed are window-relative
@@ -1247,26 +1222,26 @@ ddb_listview_list_render_row_background (DdbListview *ps, DdbListviewIter it, in
if (theming || !sel) {
if (theming) {
// draw background for selection -- workaround for New Wave theme (translucency)
- gtk_paint_flat_box (treeview->style, ps->backbuf, GTK_STATE_NORMAL, GTK_SHADOW_NONE, NULL, treeview, even ? "cell_even_ruled" : "cell_odd_ruled", x, y, w, h);
+ gtk_paint_flat_box (treeview->style, ps->list->window, GTK_STATE_NORMAL, GTK_SHADOW_NONE, NULL, treeview, even ? "cell_even_ruled" : "cell_odd_ruled", x, y, w, h);
}
else {
GdkColor clr;
- GdkGC *gc = gdk_gc_new (ps->backbuf);
+ GdkGC *gc = gdk_gc_new (ps->list->window);
gdk_gc_set_rgb_fg_color (gc, even ? (gtkui_get_listview_even_row_color (&clr), &clr) : (gtkui_get_listview_odd_row_color (&clr), &clr));
- gdk_draw_rectangle (ps->backbuf, gc, TRUE, x, y, w, h);
+ gdk_draw_rectangle (ps->list->window, gc, TRUE, x, y, w, h);
g_object_unref (gc);
}
}
if (sel) {
if (theming) {
- gtk_paint_flat_box (treeview->style, ps->backbuf, GTK_STATE_SELECTED, GTK_SHADOW_NONE, NULL, treeview, even ? "cell_even_ruled" : "cell_odd_ruled", x, y, w, h);
+ gtk_paint_flat_box (treeview->style, ps->list->window, GTK_STATE_SELECTED, GTK_SHADOW_NONE, NULL, treeview, even ? "cell_even_ruled" : "cell_odd_ruled", x, y, w, h);
}
else {
GdkColor clr;
- GdkGC *gc = gdk_gc_new (ps->backbuf);
+ GdkGC *gc = gdk_gc_new (ps->list->window);
gdk_gc_set_rgb_fg_color (gc, (gtkui_get_listview_selection_color (&clr), &clr));
- gdk_draw_rectangle (ps->backbuf, gc, TRUE, x, y, w, h);
+ gdk_draw_rectangle (ps->list->window, gc, TRUE, x, y, w, h);
g_object_unref (gc);
}
}
@@ -1275,9 +1250,9 @@ ddb_listview_list_render_row_background (DdbListview *ps, DdbListviewIter it, in
// but we want it anyway
//treeview->style->fg_gc[GTK_STATE_NORMAL]
GdkColor clr;
- GdkGC *gc = gdk_gc_new (ps->backbuf);
+ GdkGC *gc = gdk_gc_new (ps->list->window);
gdk_gc_set_rgb_fg_color (gc, (gtkui_get_listview_cursor_color (&clr), &clr));
- gdk_draw_rectangle (ps->backbuf, gc, FALSE, x, y, w-1, h-1);
+ gdk_draw_rectangle (ps->list->window, gc, FALSE, x, y, w-1, h-1);
g_object_unref (gc);
}
}
@@ -1285,7 +1260,7 @@ ddb_listview_list_render_row_background (DdbListview *ps, DdbListviewIter it, in
void
ddb_listview_list_render_row_foreground (DdbListview *ps, DdbListviewIter it, DdbListviewIter group_it, int even, int cursor, int group_y, int x, int y, int w, int h) {
int width, height;
- draw_get_canvas_size ((uintptr_t)ps->backbuf, &width, &height);
+ draw_get_canvas_size ((uintptr_t)ps->list->window, &width, &height);
if (it && ps->binding->is_selected (it)) {
GdkColor *clr = &theme_treeview->style->fg[GTK_STATE_SELECTED];
float rgb[3] = { clr->red/65535.f, clr->green/65535.f, clr->blue/65535.f };
@@ -1300,7 +1275,7 @@ ddb_listview_list_render_row_foreground (DdbListview *ps, DdbListviewIter it, Dd
int cidx = 0;
for (c = ps->columns; c; c = c->next, cidx++) {
int cw = c->width;
- ps->binding->draw_column_data (ps, ps->backbuf, it, ps->grouptitle_height > 0 ? group_it : NULL, cidx, group_y, x, y, cw, h);
+ ps->binding->draw_column_data (ps, ps->list->window, it, ps->grouptitle_height > 0 ? group_it : NULL, cidx, group_y, x, y, cw, h);
x += cw;
}
}
@@ -1308,8 +1283,7 @@ ddb_listview_list_render_row_foreground (DdbListview *ps, DdbListviewIter it, Dd
void
ddb_listview_header_expose (DdbListview *ps, int x, int y, int w, int h) {
- GtkWidget *widget = ps->header;
- draw_drawable (widget->window, widget->style->black_gc, ps->backbuf_header, x, y, x, y, w, h);
+ ddb_listview_header_render (ps);
}
void
@@ -1347,7 +1321,7 @@ ddb_listview_select_single (DdbListview *ps, int sel) {
}
UNREF (it);
if (nchanged >= NUM_CHANGED_ROWS_BEFORE_FULL_REDRAW) {
- ddb_listview_refresh (ps, DDB_REFRESH_LIST | DDB_EXPOSE_LIST);
+ ddb_listview_refresh (ps, DDB_REFRESH_LIST);
ps->binding->selection_changed (it, -1); // that means "selection changed a lot, redraw everything"
}
ps->area_selection_start = sel;
@@ -1587,7 +1561,7 @@ ddb_listview_list_mouse1_released (DdbListview *ps, int state, int ex, int ey, d
#if 0
void
ddb_listview_list_dbg_draw_areasel (GtkWidget *widget, int x, int y) {
- // erase previous rect using 4 blits from ps->backbuffer
+ // erase previous rect using 4 blits from ps->list->windowfer
if (areaselect_dx != -1) {
int sx = min (areaselect_x, areaselect_dx);
int sy = min (areaselect_y, areaselect_dy);
@@ -1595,11 +1569,11 @@ ddb_listview_list_dbg_draw_areasel (GtkWidget *widget, int x, int y) {
int dy = max (areaselect_y, areaselect_dy);
int w = dx - sx + 1;
int h = dy - sy + 1;
- //draw_drawable (widget->window, widget->style->black_gc, ps->backbuf, sx, sy, sx, sy, dx - sx + 1, dy - sy + 1);
- draw_drawable (widget->window, widget->style->black_gc, ps->backbuf, sx, sy, sx, sy, w, 1);
- draw_drawable (widget->window, widget->style->black_gc, ps->backbuf, sx, sy, sx, sy, 1, h);
- draw_drawable (widget->window, widget->style->black_gc, ps->backbuf, sx, sy + h - 1, sx, sy + h - 1, w, 1);
- draw_drawable (widget->window, widget->style->black_gc, ps->backbuf, sx + w - 1, sy, sx + w - 1, sy, 1, h);
+ //draw_drawable (widget->window, widget->style->black_gc, ps->list->window, sx, sy, sx, sy, dx - sx + 1, dy - sy + 1);
+ draw_drawable (widget->window, widget->style->black_gc, ps->list->window, sx, sy, sx, sy, w, 1);
+ draw_drawable (widget->window, widget->style->black_gc, ps->list->window, sx, sy, sx, sy, 1, h);
+ draw_drawable (widget->window, widget->style->black_gc, ps->list->window, sx, sy + h - 1, sx, sy + h - 1, w, 1);
+ draw_drawable (widget->window, widget->style->black_gc, ps->list->window, sx + w - 1, sy, sx + w - 1, sy, 1, h);
}
areaselect_dx = x;
areaselect_dy = y;
@@ -1675,7 +1649,7 @@ ddb_listview_list_mousemove (DdbListview *ps, GdkEventMotion *ev, int ex, int ey
ps->dragwait = 0;
ps->drag_source_playlist = deadbeef->plt_get_curr ();
GtkTargetEntry entry = {
- .target = "STRING",
+ .target = "DDB_URI_LIST",
.flags = GTK_TARGET_SAME_WIDGET,
.info = TARGET_SAMEWIDGET
};
@@ -1778,7 +1752,7 @@ ddb_listview_list_mousemove (DdbListview *ps, GdkEventMotion *ev, int ex, int ey
}
UNREF (it);
if (nchanged >= NUM_CHANGED_ROWS_BEFORE_FULL_REDRAW) {
- ddb_listview_refresh (ps, DDB_REFRESH_LIST | DDB_EXPOSE_LIST);
+ ddb_listview_refresh (ps, DDB_REFRESH_LIST);
ps->binding->selection_changed (it, -1); // that means "selection changed a lot, redraw everything"
}
ps->area_selection_start = start;
@@ -1841,10 +1815,8 @@ ddb_listview_list_set_hscroll (DdbListview *ps, int newscroll) {
{
ps->hscrollpos = newscroll;
GtkWidget *widget = ps->list;
- ddb_listview_header_render (ps);
- ddb_listview_header_expose (ps, 0, 0, ps->header->allocation.width, ps->header->allocation.height);
- ddb_listview_list_render (ps, 0, 0, widget->allocation.width, widget->allocation.height);
- draw_drawable (widget->window, widget->style->black_gc, ps->backbuf, 0, 0, 0, 0, widget->allocation.width, widget->allocation.height);
+ gtk_widget_queue_draw (ps->header);
+ gtk_widget_queue_draw (ps->list);
}
}
@@ -1971,7 +1943,7 @@ ddb_listview_handle_keypress (DdbListview *ps, int keyval, int state) {
}
UNREF (it);
if (nchanged >= NUM_CHANGED_ROWS_BEFORE_FULL_REDRAW) {
- ddb_listview_refresh (ps, DDB_REFRESH_LIST | DDB_EXPOSE_LIST);
+ ddb_listview_refresh (ps, DDB_REFRESH_LIST);
ps->binding->selection_changed (it, -1); // that means "selection changed a lot, redraw everything"
}
}
@@ -2018,7 +1990,7 @@ ddb_listview_list_track_dragdrop (DdbListview *ps, int y) {
GtkWidget *widget = ps->list;
if (ps->drag_motion_y != -1) {
// erase previous track
- draw_drawable (widget->window, widget->style->black_gc, ps->backbuf, 0, ps->drag_motion_y-3-ps->scrollpos, 0, ps->drag_motion_y-ps->scrollpos-3, widget->allocation.width, 7);
+ gtk_widget_queue_draw_area (ps->list, 0, ps->drag_motion_y-ps->scrollpos-3, widget->allocation.width, 7);
}
if (y == -1) {
@@ -2077,7 +2049,7 @@ ddb_listview_list_drag_end (GtkWidget *widget,
gpointer user_data)
{
DdbListview *ps = DDB_LISTVIEW (g_object_get_data (G_OBJECT (widget), "owner"));
- ddb_listview_refresh (ps, DDB_REFRESH_LIST|DDB_EXPOSE_LIST);
+ ddb_listview_refresh (ps, DDB_REFRESH_LIST);
ps->scroll_direction = 0;
ps->scroll_pointer_y = -1;
}
@@ -2094,17 +2066,17 @@ ddb_listview_header_render (DdbListview *ps) {
// fill background and draw bottom line
#if !HEADERS_GTKTHEME
- GdkGC *gc = gdk_gc_new (ps->backbuf_header);
+ GdkGC *gc = gdk_gc_new (ps->header->window);
GdkColor clr;
gdk_gc_set_rgb_fg_color (gc, (gtkui_get_tabstrip_base_color (&clr), &clr));
- gdk_draw_rectangle (ps->backbuf_header, gc, TRUE, 0, 0, widget->allocation.width, widget->allocation.height);
+ gdk_draw_rectangle (ps->header->window, gc, TRUE, 0, 0, widget->allocation.width, widget->allocation.height);
gdk_gc_set_rgb_fg_color (gc, (gtkui_get_tabstrip_dark_color (&clr), &clr));
- gdk_draw_line (ps->backbuf_header, gc, 0, widget->allocation.height-1, widget->allocation.width, widget->allocation.height-1);
+ gdk_draw_line (ps->header->window, gc, 0, widget->allocation.height-1, widget->allocation.width, widget->allocation.height-1);
#else
- gtk_paint_box (theme_button->style, ps->backbuf_header, GTK_STATE_NORMAL, GTK_SHADOW_OUT, NULL, widget, detail, -10, -10, widget->allocation.width+20, widget->allocation.height+20);
- gdk_draw_line (ps->backbuf_header, widget->style->mid_gc[GTK_STATE_NORMAL], 0, widget->allocation.height-1, widget->allocation.width, widget->allocation.height-1);
+ gtk_paint_box (theme_button->style, ps->header->window, GTK_STATE_NORMAL, GTK_SHADOW_OUT, NULL, widget, detail, -10, -10, widget->allocation.width+20, widget->allocation.height+20);
+ gdk_draw_line (ps->header->window, widget->style->mid_gc[GTK_STATE_NORMAL], 0, widget->allocation.height-1, widget->allocation.width, widget->allocation.height-1);
#endif
- draw_begin ((uintptr_t)ps->backbuf_header);
+ draw_begin ((uintptr_t)ps->header->window);
x = -ps->hscrollpos;
DdbListviewColumn *c;
int need_draw_moving = 0;
@@ -2131,11 +2103,11 @@ ddb_listview_header_render (DdbListview *ps) {
if (w > 0) {
#if !HEADERS_GTKTHEME
gdk_gc_set_rgb_fg_color (gc, (gtkui_get_tabstrip_dark_color (&clr), &clr));
- gdk_draw_line (ps->backbuf_header, gc, xx+w - 2, 2, xx+w - 2, h-4);
+ gdk_draw_line (ps->header->window, gc, xx+w - 2, 2, xx+w - 2, h-4);
gdk_gc_set_rgb_fg_color (gc, (gtkui_get_tabstrip_light_color (&clr), &clr));
- gdk_draw_line (ps->backbuf_header, gc, xx+w - 1, 2, xx+w - 1, h-4);
+ gdk_draw_line (ps->header->window, gc, xx+w - 1, 2, xx+w - 1, h-4);
#else
- gtk_paint_vline (widget->style, ps->backbuf_header, GTK_STATE_NORMAL, NULL, widget, NULL, 2, h-4, xx+w - 2);
+ gtk_paint_vline (widget->style, ps->header->window, GTK_STATE_NORMAL, NULL, widget, NULL, 2, h-4, xx+w - 2);
#endif
GdkColor *gdkfg = &theme_button->style->fg[0];
float fg[3] = {(float)gdkfg->red/0xffff, (float)gdkfg->green/0xffff, (float)gdkfg->blue/0xffff};
@@ -2151,7 +2123,7 @@ ddb_listview_header_render (DdbListview *ps) {
}
if (sort) {
int dir = sort == 1 ? GTK_ARROW_DOWN : GTK_ARROW_UP;
- gtk_paint_arrow (widget->style, ps->backbuf_header, GTK_STATE_NORMAL, GTK_SHADOW_NONE, NULL, widget, NULL, dir, TRUE, xx + w-arrow_sz-5, widget->allocation.height/2-arrow_sz/2, arrow_sz, arrow_sz);
+ gtk_paint_arrow (widget->style, ps->header->window, GTK_STATE_NORMAL, GTK_SHADOW_NONE, NULL, widget, NULL, dir, TRUE, xx + w-arrow_sz-5, widget->allocation.height/2-arrow_sz/2, arrow_sz, arrow_sz);
}
}
else {
@@ -2177,14 +2149,14 @@ ddb_listview_header_render (DdbListview *ps) {
#endif
// draw empty slot
if (x < widget->allocation.width) {
- gtk_paint_box (theme_button->style, ps->backbuf_header, GTK_STATE_ACTIVE, GTK_SHADOW_ETCHED_IN, NULL, widget, "button", x, 0, w, h);
+ gtk_paint_box (theme_button->style, ps->header->window, GTK_STATE_ACTIVE, GTK_SHADOW_ETCHED_IN, NULL, widget, "button", x, 0, w, h);
}
x = ps->col_movepos - ps->hscrollpos;
if (x >= widget->allocation.width) {
break;
}
if (w > 0) {
- gtk_paint_box (theme_button->style, ps->backbuf_header, GTK_STATE_SELECTED, GTK_SHADOW_OUT, NULL, widget, "button", x, 0, w, h);
+ gtk_paint_box (theme_button->style, ps->header->window, GTK_STATE_SELECTED, GTK_SHADOW_OUT, NULL, widget, "button", x, 0, w, h);
GdkColor *gdkfg = &theme_button->style->fg[GTK_STATE_SELECTED];
float fg[3] = {(float)gdkfg->red/0xffff, (float)gdkfg->green/0xffff, (float)gdkfg->blue/0xffff};
draw_set_fg_color (fg);
@@ -2224,12 +2196,6 @@ ddb_listview_header_configure_event (GtkWidget *widget,
if (height != widget->allocation.height) {
gtk_widget_set_size_request (widget, -1, height);
}
- if (ps->backbuf_header) {
- g_object_unref (ps->backbuf_header);
- ps->backbuf_header = NULL;
- }
- ps->backbuf_header = gdk_pixmap_new (widget->window, widget->allocation.width, widget->allocation.height, -1);
- ddb_listview_header_render (ps);
return FALSE;
}
@@ -2268,7 +2234,9 @@ ddb_listview_header_motion_notify_event (GtkWidget *widget,
ev_x = event->x;
ev_y = event->y;
ev_state = event->state;
+#if GTK_CHECK_VERSION(2,12,0) && !defined(ULTRA_COMPATIBLE)
gdk_event_request_motions (event);
+#endif
if ((ev_state & GDK_BUTTON1_MASK) && ps->header_prepare) {
if (gtk_drag_check_threshold (widget, ev_x, ps->prev_header_x, 0, 0)) {
@@ -2304,13 +2272,11 @@ ddb_listview_header_motion_notify_event (GtkWidget *widget,
// colhdr_anim_swap (ps, c1, c2, x1, x2);
// force redraw of everything
// ddb_listview_list_setup_hscroll (ps);
- ddb_listview_list_render (ps, 0, 0, ps->list->allocation.width, ps->list->allocation.height);
- ddb_listview_list_expose (ps, 0, 0, ps->list->allocation.width, ps->list->allocation.height);
+ gtk_widget_queue_draw (ps->list);
}
else {
// only redraw that if not animating
- ddb_listview_header_render (ps);
- ddb_listview_header_expose (ps, 0, 0, ps->header->allocation.width, ps->header->allocation.height);
+ gtk_widget_queue_draw (ps->header);
}
}
else if (ps->header_sizing >= 0) {
@@ -2334,10 +2300,8 @@ ddb_listview_header_motion_notify_event (GtkWidget *widget,
ddb_listview_list_setup_vscroll (ps);
ddb_listview_list_setup_hscroll (ps);
ps->block_redraw_on_scroll = 0;
- ddb_listview_header_render (ps);
- ddb_listview_header_expose (ps, 0, 0, ps->header->allocation.width, ps->header->allocation.height);
- ddb_listview_list_render (ps, 0, 0, ps->list->allocation.width, ps->list->allocation.height);
- ddb_listview_list_expose (ps, 0, 0, ps->list->allocation.width, ps->list->allocation.height);
+ gtk_widget_queue_draw (ps->header);
+ gtk_widget_queue_draw (ps->list);
ps->binding->column_size_changed (ps, ps->header_sizing);
}
else {
@@ -2451,7 +2415,7 @@ ddb_listview_header_button_release_event (GtkWidget *widget,
else if (sort_order == 2) {
c->sort_order = 1;
}
- ps->binding->col_sort (i, c->sort_order, c->user_data);
+ ps->binding->col_sort (i, c->sort_order-1, c->user_data);
sorted = 1;
}
else {
@@ -2459,7 +2423,7 @@ ddb_listview_header_button_release_event (GtkWidget *widget,
}
x += w;
}
- ddb_listview_refresh (ps, DDB_REFRESH_LIST | DDB_REFRESH_COLUMNS | DDB_EXPOSE_LIST | DDB_EXPOSE_COLUMNS);
+ ddb_listview_refresh (ps, DDB_REFRESH_LIST | DDB_REFRESH_COLUMNS);
}
else {
ps->header_sizing = -1;
@@ -2478,7 +2442,7 @@ ddb_listview_header_button_release_event (GtkWidget *widget,
}
if (ps->header_dragging >= 0) {
ps->header_dragging = -1;
- ddb_listview_refresh (ps, DDB_REFRESH_LIST | DDB_REFRESH_COLUMNS | DDB_EXPOSE_LIST | DDB_EXPOSE_COLUMNS | DDB_REFRESH_HSCROLL);
+ ddb_listview_refresh (ps, DDB_REFRESH_LIST | DDB_REFRESH_COLUMNS | DDB_REFRESH_HSCROLL);
}
}
ps->binding->columns_changed (ps);
@@ -2630,7 +2594,9 @@ ddb_listview_motion_notify_event (GtkWidget *widget,
{
int x = event->x;
int y = event->y;
+#if GTK_CHECK_VERSION(2,12,0) && !defined(ULTRA_COMPATIBLE)
gdk_event_request_motions (event);
+#endif
DdbListview *ps = DDB_LISTVIEW (g_object_get_data (G_OBJECT (widget), "owner"));
ddb_listview_list_mousemove (ps, event, x, y);
return FALSE;
@@ -2959,6 +2925,5 @@ ddb_listview_clear_sort (DdbListview *listview) {
for (c = listview->columns; c; c = c->next) {
c->sort_order = 0;
}
- ddb_listview_header_render (listview);
- ddb_listview_header_expose (listview, 0, 0, listview->header->allocation.width, listview->header->allocation.height);
+ gtk_widget_queue_draw (listview->header);
}
diff --git a/plugins/gtkui/ddblistview.h b/plugins/gtkui/ddblistview.h
index 55333384..d0a7ceb9 100644
--- a/plugins/gtkui/ddblistview.h
+++ b/plugins/gtkui/ddblistview.h
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -103,8 +103,6 @@ struct _DdbListview {
GtkWidget *hscrollbar;
int totalwidth; // width of listview, including invisible (scrollable) part
- GdkPixmap *backbuf;
- GdkPixmap *backbuf_header;
const char *title; // unique id, used for config writing, etc
int lastpos[2]; // last mouse position (for list widget)
// current state
@@ -205,8 +203,6 @@ enum {
DDB_REFRESH_HSCROLL = 2,
DDB_REFRESH_VSCROLL = 4,
DDB_REFRESH_LIST = 8,
- DDB_EXPOSE_COLUMNS = 16,
- DDB_EXPOSE_LIST = 32,
};
void ddb_listview_refresh (DdbListview *listview, uint32_t flags);
diff --git a/plugins/gtkui/ddbseekbar.c b/plugins/gtkui/ddbseekbar.c
index 407b347c..1ad285a7 100644
--- a/plugins/gtkui/ddbseekbar.c
+++ b/plugins/gtkui/ddbseekbar.c
@@ -1,4 +1,4 @@
-/* ddbseekbar.c generated by valac 0.10.0, the Vala compiler
+/* ddbseekbar.c generated by valac 0.10.2, the Vala compiler
* generated from ddbseekbar.vala, do not modify */
/*
@@ -138,7 +138,7 @@ static gboolean ddb_seekbar_real_configure_event (GtkWidget* base, GdkEventConfi
DdbSeekbar* ddb_seekbar_construct (GType object_type) {
- DdbSeekbar * self;
+ DdbSeekbar * self = NULL;
self = (DdbSeekbar*) gtk_widget_new (object_type, NULL);
return self;
}
diff --git a/plugins/gtkui/ddbseekbar.h b/plugins/gtkui/ddbseekbar.h
index f501a00c..c975654e 100644
--- a/plugins/gtkui/ddbseekbar.h
+++ b/plugins/gtkui/ddbseekbar.h
@@ -1,4 +1,4 @@
-/* ddbseekbar.h generated by valac 0.10.0, the Vala compiler, do not modify */
+/* ddbseekbar.h generated by valac 0.10.2, the Vala compiler, do not modify */
#ifndef __DDBSEEKBAR_H__
diff --git a/plugins/gtkui/ddbtabstrip.c b/plugins/gtkui/ddbtabstrip.c
index ea7905c7..d6920a9f 100644
--- a/plugins/gtkui/ddbtabstrip.c
+++ b/plugins/gtkui/ddbtabstrip.c
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@@ -43,7 +43,14 @@ extern GtkWidget *theme_button;
void
plt_get_title_wrapper (int plt, char *buffer, int len) {
- deadbeef->plt_get_title (plt, buffer, len);
+ if (plt == -1) {
+ strcpy (buffer, "");
+ return;
+ }
+ deadbeef->plt_lock ();
+ void *p = deadbeef->plt_get_handle (plt);
+ deadbeef->plt_get_title (p, buffer, len);
+ deadbeef->plt_unlock ();
char *end;
if (!g_utf8_validate (buffer, -1, (const gchar **)&end)) {
*end = 0;
@@ -135,6 +142,11 @@ ddb_tabstrip_size_allocate (GtkWidget *widget,
}
}
+
+gboolean
+on_tabstrip_scroll_event (GtkWidget *widget,
+ GdkEventScroll *event);
+
gboolean
on_tabstrip_button_press_event (GtkWidget *widget,
GdkEventButton *event);
@@ -213,6 +225,7 @@ ddb_tabstrip_class_init(DdbTabStripClass *class)
widget_class->button_release_event = on_tabstrip_button_release_event;
widget_class->configure_event = on_tabstrip_configure_event;
widget_class->motion_notify_event = on_tabstrip_motion_notify_event;
+ widget_class->scroll_event= on_tabstrip_scroll_event;
widget_class->drag_motion = on_tabstrip_drag_motion_event;
widget_class->drag_drop = on_tabstrip_drag_drop;
widget_class->drag_end = on_tabstrip_drag_end;
@@ -452,6 +465,32 @@ tabstrip_adjust_hscroll (DdbTabStrip *ts) {
}
void
+set_tab_text_color (int idx) {
+ if (idx == -1) {
+ return;
+ }
+ deadbeef->plt_lock ();
+ void *plt = deadbeef->plt_get_handle (idx);
+ const char *clr = deadbeef->plt_find_meta (plt, "gui.color");
+ int fallback = 1;
+ if (clr) {
+ int r, g, b;
+ if (3 == sscanf (clr, "%02x%02x%02x", &r, &g, &b)) {
+ fallback = 0;
+ float fg[3] = {(float)r/0xff, (float)g/0xff, (float)b/0xff};
+ draw_set_fg_color (fg);
+ }
+ }
+ if (fallback) {
+ GdkColor color;
+ gtkui_get_tabstrip_text_color (&color);
+ float fg[3] = {(float)color.red/0xffff, (float)color.green/0xffff, (float)color.blue/0xffff};
+ draw_set_fg_color (fg);
+ }
+ deadbeef->plt_unlock ();
+}
+
+void
tabstrip_render (DdbTabStrip *ts) {
GtkWidget *widget = GTK_WIDGET (ts);
GdkDrawable *backbuf = gtk_widget_get_window (widget);
@@ -514,9 +553,8 @@ tabstrip_render (DdbTabStrip *ts) {
ddb_tabstrip_draw_tab (widget, backbuf, idx == tab_selected, x, y, w, h);
char tab_title[100];
plt_get_title_wrapper (idx, tab_title, sizeof (tab_title));
- GdkColor *color = &widget->style->text[GTK_STATE_NORMAL];
- float fg[3] = {(float)color->red/0xffff, (float)color->green/0xffff, (float)color->blue/0xffff};
- draw_set_fg_color (fg);
+
+ set_tab_text_color (idx);
draw_text (x + text_left_padding, y + h/2 - draw_get_font_size()/2 + text_vert_offset, w, 0, tab_title);
}
x += w - tab_overlap_size;
@@ -541,9 +579,7 @@ tabstrip_render (DdbTabStrip *ts) {
ddb_tabstrip_draw_tab (widget, backbuf, 1, x, y, w, h);
char tab_title[100];
plt_get_title_wrapper (idx, tab_title, sizeof (tab_title));
- GdkColor *color = &widget->style->text[GTK_STATE_NORMAL];
- float fg[3] = {(float)color->red/0xffff, (float)color->green/0xffff, (float)color->blue/0xffff};
- draw_set_fg_color (fg);
+ set_tab_text_color (idx);
draw_text (x + text_left_padding, y + h/2 - draw_get_font_size()/2 + text_vert_offset, w, 0, tab_title);
}
else {
@@ -562,9 +598,7 @@ tabstrip_render (DdbTabStrip *ts) {
ddb_tabstrip_draw_tab (widget, backbuf, 1, x, y, w, h);
char tab_title[100];
plt_get_title_wrapper (idx, tab_title, sizeof (tab_title));
- GdkColor *color = &widget->style->text[GTK_STATE_NORMAL];
- float fg[3] = {(float)color->red/0xffff, (float)color->green/0xffff, (float)color->blue/0xffff};
- draw_set_fg_color (fg);
+ set_tab_text_color (idx);
draw_text (x + text_left_padding, y + h/2 - draw_get_font_size()/2 + text_vert_offset, w, 0, tab_title);
}
break;
@@ -621,17 +655,23 @@ void
on_rename_playlist1_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
- GtkWidget *dlg = create_editplaylistdlg ();
+ GtkWidget *dlg = create_entrydialog ();
gtk_dialog_set_default_response (GTK_DIALOG (dlg), GTK_RESPONSE_OK);
gtk_window_set_title (GTK_WINDOW (dlg), _("Edit playlist"));
- GtkWidget *e = lookup_widget (dlg, "title");
+ GtkWidget *e;
+ e = lookup_widget (dlg, "title_label");
+ gtk_label_set_text (GTK_LABEL(e), _("Title:"));
+ e = lookup_widget (dlg, "title");
char t[100];
plt_get_title_wrapper (tab_clicked, t, sizeof (t));
gtk_entry_set_text (GTK_ENTRY (e), t);
int res = gtk_dialog_run (GTK_DIALOG (dlg));
if (res == GTK_RESPONSE_OK) {
const char *text = gtk_entry_get_text (GTK_ENTRY (e));
- deadbeef->plt_set_title (tab_clicked, text);
+ deadbeef->plt_lock ();
+ void *p = deadbeef->plt_get_handle (tab_clicked);
+ deadbeef->plt_set_title (p, text);
+ deadbeef->plt_unlock ();
}
gtk_widget_destroy (dlg);
}
@@ -643,6 +683,7 @@ on_remove_playlist1_activate (GtkMenuItem *menuitem,
{
if (tab_clicked != -1) {
deadbeef->plt_remove (tab_clicked);
+ playlist_refresh ();
int playlist = deadbeef->plt_get_curr ();
deadbeef->conf_set_int ("playlist.current", playlist);
}
@@ -739,8 +780,26 @@ tabstrip_scroll_cb (gpointer data) {
}
gboolean
-on_tabstrip_button_press_event (GtkWidget *widget,
- GdkEventButton *event)
+on_tabstrip_scroll_event(GtkWidget *widget,
+ GdkEventScroll *event)
+{
+ DdbTabStrip *ts = DDB_TABSTRIP (widget);
+
+ if(event->direction == GDK_SCROLL_UP)
+ {
+ tabstrip_scroll_left(ts);
+ }
+ else if (event->direction == GDK_SCROLL_DOWN)
+ {
+ tabstrip_scroll_right(ts);
+ }
+
+ return TRUE;
+}
+
+gboolean
+on_tabstrip_button_press_event(GtkWidget *widget,
+ GdkEventButton *event)
{
DdbTabStrip *ts = DDB_TABSTRIP (widget);
tab_clicked = get_tab_under_cursor (ts, event->x);
@@ -818,6 +877,7 @@ on_tabstrip_button_press_event (GtkWidget *widget,
else if (deadbeef->conf_get_int ("gtkui.mmb_delete_playlist", 1)) {
if (tab_clicked != -1) {
deadbeef->plt_remove (tab_clicked);
+ playlist_refresh ();
int playlist = deadbeef->plt_get_curr ();
deadbeef->conf_set_int ("playlist.current", playlist);
}
@@ -879,7 +939,9 @@ on_tabstrip_motion_notify_event (GtkWidget *widget,
ev_x = event->x;
ev_y = event->y;
ev_state = event->state;
+#if GTK_CHECK_VERSION(2,12,0) && !defined(ULTRA_COMPATIBLE)
gdk_event_request_motions (event);
+#endif
if ((ev_state & GDK_BUTTON1_MASK) && ts->prepare) {
if (gtk_drag_check_threshold (widget, ev_x, ts->prev_x, 0, 0)) {
ts->prepare = 0;
diff --git a/plugins/gtkui/ddbtabstrip.h b/plugins/gtkui/ddbtabstrip.h
index 7f530e2f..c68b95f1 100644
--- a/plugins/gtkui/ddbtabstrip.h
+++ b/plugins/gtkui/ddbtabstrip.h
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
diff --git a/plugins/gtkui/ddbvolumebar.c b/plugins/gtkui/ddbvolumebar.c
index 83389f7f..b0df2c9a 100644
--- a/plugins/gtkui/ddbvolumebar.c
+++ b/plugins/gtkui/ddbvolumebar.c
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
diff --git a/plugins/gtkui/ddbvolumebar.h b/plugins/gtkui/ddbvolumebar.h
index 530e556e..d2cfbe61 100644
--- a/plugins/gtkui/ddbvolumebar.h
+++ b/plugins/gtkui/ddbvolumebar.h
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
diff --git a/plugins/gtkui/deadbeef.glade b/plugins/gtkui/deadbeef.glade
index 4f38af30..0351668d 100644
--- a/plugins/gtkui/deadbeef.glade
+++ b/plugins/gtkui/deadbeef.glade
@@ -62,7 +62,7 @@
<accelerator key="O" modifiers="GDK_CONTROL_MASK" signal="activate"/>
<child internal-child="image">
- <widget class="GtkImage" id="image452">
+ <widget class="GtkImage" id="image512">
<property name="visible">True</property>
<property name="stock">gtk-open</property>
<property name="icon_size">1</property>
@@ -89,7 +89,7 @@
<signal name="activate" handler="on_add_files_activate" last_modification_time="Sat, 04 Jul 2009 13:04:01 GMT"/>
<child internal-child="image">
- <widget class="GtkImage" id="image453">
+ <widget class="GtkImage" id="image513">
<property name="visible">True</property>
<property name="stock">gtk-add</property>
<property name="icon_size">1</property>
@@ -110,7 +110,7 @@
<signal name="activate" handler="on_add_folders_activate" last_modification_time="Sun, 06 Sep 2009 17:51:40 GMT"/>
<child internal-child="image">
- <widget class="GtkImage" id="image454">
+ <widget class="GtkImage" id="image514">
<property name="visible">True</property>
<property name="stock">gtk-add</property>
<property name="icon_size">1</property>
@@ -190,7 +190,7 @@
<accelerator key="Q" modifiers="GDK_CONTROL_MASK" signal="activate"/>
<child internal-child="image">
- <widget class="GtkImage" id="image455">
+ <widget class="GtkImage" id="image515">
<property name="visible">True</property>
<property name="stock">gtk-quit</property>
<property name="icon_size">1</property>
@@ -224,7 +224,7 @@
<signal name="activate" handler="on_clear1_activate" last_modification_time="Sun, 06 Sep 2009 18:30:03 GMT"/>
<child internal-child="image">
- <widget class="GtkImage" id="image456">
+ <widget class="GtkImage" id="image516">
<property name="visible">True</property>
<property name="stock">gtk-clear</property>
<property name="icon_size">1</property>
@@ -283,7 +283,7 @@
<signal name="activate" handler="on_remove1_activate" last_modification_time="Sun, 06 Sep 2009 18:30:03 GMT"/>
<child internal-child="image">
- <widget class="GtkImage" id="image457">
+ <widget class="GtkImage" id="image517">
<property name="visible">True</property>
<property name="stock">gtk-remove</property>
<property name="icon_size">1</property>
@@ -320,6 +320,55 @@
</child>
<child>
+ <widget class="GtkMenuItem" id="sort_by1">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Sort By</property>
+ <property name="use_underline">True</property>
+
+ <child>
+ <widget class="GtkMenu" id="sort_by1_menu">
+
+ <child>
+ <widget class="GtkMenuItem" id="album1">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Album</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_album1_activate" last_modification_time="Fri, 03 Dec 2010 21:03:21 GMT"/>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkMenuItem" id="artist1">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Artist</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_artist1_activate" last_modification_time="Fri, 03 Dec 2010 21:03:21 GMT"/>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkMenuItem" id="date1">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Date</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_date1_activate" last_modification_time="Fri, 03 Dec 2010 21:03:21 GMT"/>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkMenuItem" id="custom2">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Custom</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_custom2_activate" last_modification_time="Fri, 03 Dec 2010 21:03:21 GMT"/>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+
+ <child>
<widget class="GtkSeparatorMenuItem" id="separator5">
<property name="visible">True</property>
</widget>
@@ -422,7 +471,7 @@
<child>
<widget class="GtkRadioMenuItem" id="order_shuffle">
<property name="visible">True</property>
- <property name="label" translatable="yes">Shuffle</property>
+ <property name="label" translatable="yes">Shuffle tracks</property>
<property name="use_underline">True</property>
<property name="active">True</property>
<property name="group">order_linear</property>
@@ -431,6 +480,17 @@
</child>
<child>
+ <widget class="GtkRadioMenuItem" id="order_shuffle_albums">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Shuffle albums</property>
+ <property name="use_underline">True</property>
+ <property name="active">True</property>
+ <property name="group">order_linear</property>
+ <signal name="activate" handler="on_order_shuffle_albums_activate" last_modification_time="Sun, 12 Dec 2010 18:14:47 GMT"/>
+ </widget>
+ </child>
+
+ <child>
<widget class="GtkRadioMenuItem" id="order_random">
<property name="visible">True</property>
<property name="label" translatable="yes">Random</property>
@@ -558,7 +618,7 @@
<signal name="activate" handler="on_help1_activate" last_modification_time="Tue, 08 Sep 2009 17:32:06 GMT"/>
<child internal-child="image">
- <widget class="GtkImage" id="image458">
+ <widget class="GtkImage" id="image518">
<property name="visible">True</property>
<property name="stock">gtk-help</property>
<property name="icon_size">1</property>
@@ -618,7 +678,7 @@
<signal name="activate" handler="on_about1_activate" last_modification_time="Sat, 04 Jul 2009 12:57:58 GMT"/>
<child internal-child="image">
- <widget class="GtkImage" id="image459">
+ <widget class="GtkImage" id="image519">
<property name="visible">True</property>
<property name="stock">gtk-about</property>
<property name="icon_size">1</property>
@@ -639,7 +699,7 @@
<signal name="activate" handler="on_translators1_activate" last_modification_time="Sun, 19 Sep 2010 13:38:07 GMT"/>
<child internal-child="image">
- <widget class="GtkImage" id="image460">
+ <widget class="GtkImage" id="image520">
<property name="visible">True</property>
<property name="stock">gtk-about</property>
<property name="icon_size">1</property>
@@ -1177,10 +1237,10 @@
</child>
</widget>
-<widget class="GtkWindow" id="addprogress">
+<widget class="GtkWindow" id="progressdlg">
<property name="border_width">12</property>
<property name="visible">True</property>
- <property name="title" translatable="yes">Adding files...</property>
+ <property name="title">progressdlg</property>
<property name="type">GTK_WINDOW_TOPLEVEL</property>
<property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
<property name="modal">True</property>
@@ -1193,7 +1253,6 @@
<property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
<property name="focus_on_map">True</property>
<property name="urgency_hint">False</property>
- <signal name="delete_event" handler="on_addprogress_delete_event" last_modification_time="Sun, 16 Aug 2009 17:20:03 GMT"/>
<child>
<widget class="GtkVBox" id="vbox6">
@@ -1252,14 +1311,13 @@
</child>
<child>
- <widget class="GtkButton" id="button3">
+ <widget class="GtkButton" id="cancelbtn">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label">gtk-cancel</property>
<property name="use_stock">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
- <signal name="clicked" handler="on_progress_abort" last_modification_time="Mon, 25 Oct 2010 20:04:28 GMT"/>
</widget>
<packing>
<property name="padding">0</property>
@@ -1336,7 +1394,7 @@
<property name="visible">True</property>
<property name="title" translatable="yes">Track Properties</property>
<property name="type">GTK_WINDOW_TOPLEVEL</property>
- <property name="window_position">GTK_WIN_POS_NONE</property>
+ <property name="window_position">GTK_WIN_POS_MOUSE</property>
<property name="modal">False</property>
<property name="resizable">True</property>
<property name="destroy_with_parent">False</property>
@@ -1349,6 +1407,8 @@
<property name="urgency_hint">False</property>
<signal name="key_press_event" handler="on_trackproperties_key_press_event" last_modification_time="Thu, 31 Dec 2009 13:46:40 GMT"/>
<signal name="delete_event" handler="on_trackproperties_delete_event" last_modification_time="Sat, 02 Jan 2010 21:38:32 GMT"/>
+ <signal name="configure_event" handler="on_trackproperties_configure_event" last_modification_time="Thu, 10 Mar 2011 11:06:48 GMT"/>
+ <signal name="window_state_event" handler="on_trackproperties_window_state_event" last_modification_time="Thu, 10 Mar 2011 11:08:02 GMT"/>
<child>
<widget class="GtkNotebook" id="notebook3">
@@ -1387,6 +1447,7 @@
<property name="fixed_height_mode">False</property>
<property name="hover_selection">False</property>
<property name="hover_expand">False</property>
+ <signal name="button_press_event" handler="on_metalist_button_press_event" last_modification_time="Sun, 27 Feb 2011 18:14:41 GMT"/>
</widget>
</child>
</widget>
@@ -1398,22 +1459,21 @@
</child>
<child>
- <widget class="GtkHButtonBox" id="hbuttonbox1">
+ <widget class="GtkHBox" id="hbox98">
<property name="visible">True</property>
- <property name="layout_style">GTK_BUTTONBOX_END</property>
+ <property name="homogeneous">False</property>
<property name="spacing">0</property>
<child>
- <widget class="GtkButton" id="write_tags">
+ <widget class="GtkButton" id="settings">
<property name="visible">True</property>
- <property name="can_default">True</property>
<property name="can_focus">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
- <signal name="clicked" handler="on_write_tags_clicked" last_modification_time="Sat, 27 Mar 2010 20:48:33 GMT"/>
+ <signal name="clicked" handler="on_tagwriter_settings_clicked" last_modification_time="Wed, 09 Mar 2011 20:01:45 GMT"/>
<child>
- <widget class="GtkAlignment" id="alignment11">
+ <widget class="GtkAlignment" id="alignment24">
<property name="visible">True</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
@@ -1425,15 +1485,15 @@
<property name="right_padding">0</property>
<child>
- <widget class="GtkHBox" id="hbox52">
+ <widget class="GtkHBox" id="hbox99">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">2</property>
<child>
- <widget class="GtkImage" id="image390">
+ <widget class="GtkImage" id="image522">
<property name="visible">True</property>
- <property name="stock">gtk-apply</property>
+ <property name="stock">gtk-preferences</property>
<property name="icon_size">4</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
@@ -1448,9 +1508,9 @@
</child>
<child>
- <widget class="GtkLabel" id="label88">
+ <widget class="GtkLabel" id="label123">
<property name="visible">True</property>
- <property name="label" translatable="yes">_Apply</property>
+ <property name="label" translatable="yes">Settings</property>
<property name="use_underline">True</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
@@ -1476,81 +1536,174 @@
</widget>
</child>
</widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
</child>
<child>
- <widget class="GtkButton" id="closebtn">
+ <widget class="GtkHButtonBox" id="hbuttonbox1">
<property name="visible">True</property>
- <property name="can_default">True</property>
- <property name="can_focus">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <signal name="clicked" handler="on_closebtn_clicked" last_modification_time="Thu, 01 Apr 2010 12:45:33 GMT"/>
+ <property name="layout_style">GTK_BUTTONBOX_END</property>
+ <property name="spacing">0</property>
<child>
- <widget class="GtkAlignment" id="alignment12">
+ <widget class="GtkButton" id="write_tags">
<property name="visible">True</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xscale">0</property>
- <property name="yscale">0</property>
- <property name="top_padding">0</property>
- <property name="bottom_padding">0</property>
- <property name="left_padding">0</property>
- <property name="right_padding">0</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <signal name="clicked" handler="on_write_tags_clicked" last_modification_time="Sat, 27 Mar 2010 20:48:33 GMT"/>
<child>
- <widget class="GtkHBox" id="hbox53">
+ <widget class="GtkAlignment" id="alignment11">
<property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">2</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xscale">0</property>
+ <property name="yscale">0</property>
+ <property name="top_padding">0</property>
+ <property name="bottom_padding">0</property>
+ <property name="left_padding">0</property>
+ <property name="right_padding">0</property>
<child>
- <widget class="GtkImage" id="image391">
+ <widget class="GtkHBox" id="hbox52">
<property name="visible">True</property>
- <property name="stock">gtk-close</property>
- <property name="icon_size">4</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">2</property>
+
+ <child>
+ <widget class="GtkImage" id="image390">
+ <property name="visible">True</property>
+ <property name="stock">gtk-apply</property>
+ <property name="icon_size">4</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label88">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Apply</property>
+ <property name="use_underline">True</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
</widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
</child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="closebtn">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <signal name="clicked" handler="on_closebtn_clicked" last_modification_time="Thu, 01 Apr 2010 12:45:33 GMT"/>
+
+ <child>
+ <widget class="GtkAlignment" id="alignment12">
+ <property name="visible">True</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xscale">0</property>
+ <property name="yscale">0</property>
+ <property name="top_padding">0</property>
+ <property name="bottom_padding">0</property>
+ <property name="left_padding">0</property>
+ <property name="right_padding">0</property>
<child>
- <widget class="GtkLabel" id="label89">
+ <widget class="GtkHBox" id="hbox53">
<property name="visible">True</property>
- <property name="label" translatable="yes">_Close</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">2</property>
+
+ <child>
+ <widget class="GtkImage" id="image391">
+ <property name="visible">True</property>
+ <property name="stock">gtk-close</property>
+ <property name="icon_size">4</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label89">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Close</property>
+ <property name="use_underline">True</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
</widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
</child>
</widget>
</child>
</widget>
</child>
</widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
</child>
</widget>
<packing>
@@ -1749,7 +1902,7 @@
<widget class="GtkDialog" id="editcolumndlg">
<property name="border_width">12</property>
<property name="visible">True</property>
- <property name="title" translatable="yes">editcolumndlg</property>
+ <property name="title">editcolumndlg</property>
<property name="type">GTK_WINDOW_TOPLEVEL</property>
<property name="window_position">GTK_WIN_POS_NONE</property>
<property name="modal">True</property>
@@ -2037,8 +2190,8 @@ Artist - Album
Artist
Album
Title
-Length
-Track
+Duration
+Track No
Band / Album Artist
Custom</property>
<property name="add_tearoffs">False</property>
@@ -2091,16 +2244,44 @@ Custom</property>
</child>
<child>
- <widget class="GtkEntry" id="format">
+ <widget class="GtkHBox" id="hbox74">
<property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="editable">True</property>
- <property name="visibility">True</property>
- <property name="max_length">0</property>
- <property name="text" translatable="yes"></property>
- <property name="has_frame">True</property>
- <property name="invisible_char">●</property>
- <property name="activates_default">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkEntry" id="format">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="editable">True</property>
+ <property name="visibility">True</property>
+ <property name="max_length">0</property>
+ <property name="text" translatable="yes"></property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char">●</property>
+ <property name="activates_default">True</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="Custom" id="title_formatting_help_link">
+ <property name="visible">True</property>
+ <property name="creation_function">title_formatting_help_link_create</property>
+ <property name="int1">0</property>
+ <property name="int2">0</property>
+ <property name="last_modification_time">Fri, 03 Dec 2010 20:39:24 GMT</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
</widget>
<packing>
<property name="padding">0</property>
@@ -2168,38 +2349,6 @@ Right</property>
<property name="fill">False</property>
</packing>
</child>
-
- <child>
- <widget class="GtkLabel" id="label25">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Format conversions (start with %):
- [a]rtist, [t]itle, al[b]um, [B]and, [C]omposer
- track[n]umber, [N]totaltracks,
- [l]ength, [y]ear, [g]enre, [c]omment,
- copy[r]ight, [f]ilename, [F]ullPathname, [T]ags,
- [d]irectory, [D]irectoryWithPath
-Example: %a - %t [%l]</property>
- <property name="use_underline">False</property>
- <property name="use_markup">True</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">True</property>
- <property name="xalign">0.10000000149</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
</widget>
<packing>
<property name="padding">0</property>
@@ -2213,15 +2362,11 @@ Example: %a - %t [%l]</property>
<widget class="GtkDialog" id="prefwin">
<property name="border_width">12</property>
- <property name="width_request">630</property>
- <property name="height_request">400</property>
<property name="visible">True</property>
<property name="title" translatable="yes">Preferences</property>
<property name="type">GTK_WINDOW_TOPLEVEL</property>
- <property name="window_position">GTK_WIN_POS_NONE</property>
+ <property name="window_position">GTK_WIN_POS_CENTER</property>
<property name="modal">False</property>
- <property name="default_width">630</property>
- <property name="default_height">400</property>
<property name="resizable">True</property>
<property name="destroy_with_parent">False</property>
<property name="decorated">True</property>
@@ -2232,6 +2377,9 @@ Example: %a - %t [%l]</property>
<property name="focus_on_map">True</property>
<property name="urgency_hint">False</property>
<property name="has_separator">True</property>
+ <signal name="configure_event" handler="on_prefwin_configure_event" last_modification_time="Thu, 10 Mar 2011 11:14:37 GMT"/>
+ <signal name="window_state_event" handler="on_prefwin_window_state_event" last_modification_time="Thu, 10 Mar 2011 11:14:42 GMT"/>
+ <signal name="realize" handler="on_prefwin_realize" last_modification_time="Thu, 10 Mar 2011 11:20:24 GMT"/>
<child internal-child="vbox">
<widget class="GtkVBox" id="dialog-vbox2">
@@ -2249,73 +2397,11 @@ Example: %a - %t [%l]</property>
<property name="visible">True</property>
<property name="can_default">True</property>
<property name="can_focus">True</property>
+ <property name="label">gtk-close</property>
+ <property name="use_stock">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<property name="response_id">-7</property>
-
- <child>
- <widget class="GtkAlignment" id="alignment14">
- <property name="visible">True</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xscale">0</property>
- <property name="yscale">0</property>
- <property name="top_padding">0</property>
- <property name="bottom_padding">0</property>
- <property name="left_padding">0</property>
- <property name="right_padding">0</property>
-
- <child>
- <widget class="GtkHBox" id="hbox55">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">2</property>
-
- <child>
- <widget class="GtkImage" id="image393">
- <property name="visible">True</property>
- <property name="stock">gtk-close</property>
- <property name="icon_size">4</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label91">
- <property name="visible">True</property>
- <property name="label" translatable="yes">_Close</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- </child>
- </widget>
- </child>
</widget>
</child>
</widget>
@@ -2483,38 +2569,18 @@ Example: %a - %t [%l]</property>
<property name="spacing">8</property>
<child>
- <widget class="GtkCheckButton" id="pref_dynsamplerate">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Allow dynamic samplerate switching</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- <signal name="clicked" handler="on_pref_dynsamplerate_clicked" last_modification_time="Tue, 26 Jan 2010 19:46:12 GMT"/>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="hbox9">
+ <widget class="GtkHBox" id="hbox10">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">8</property>
<child>
- <widget class="GtkLabel" id="label6">
+ <widget class="GtkLabel" id="label8">
<property name="visible">True</property>
- <property name="label" translatable="yes">Samplerate conversion quality:</property>
+ <property name="label" translatable="yes">Replaygain mode:</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_RIGHT</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0</property>
@@ -2534,16 +2600,15 @@ Example: %a - %t [%l]</property>
</child>
<child>
- <widget class="GtkComboBox" id="pref_src_quality">
+ <widget class="GtkComboBox" id="pref_replaygain_mode">
+ <property name="width_request">337</property>
<property name="visible">True</property>
- <property name="items">sinc_best_quality
-sinc_medium_quality
-sinc_fastest
-zero_order_hold
-linear</property>
+ <property name="items" translatable="yes">Disable
+Track
+Album</property>
<property name="add_tearoffs">False</property>
<property name="focus_on_click">True</property>
- <signal name="changed" handler="on_pref_src_quality_changed" last_modification_time="Sat, 10 Oct 2009 19:02:36 GMT"/>
+ <signal name="changed" handler="on_pref_replaygain_mode_changed" last_modification_time="Sat, 10 Oct 2009 19:22:23 GMT"/>
</widget>
<packing>
<property name="padding">0</property>
@@ -2560,21 +2625,41 @@ linear</property>
</child>
<child>
- <widget class="GtkHBox" id="hbox10">
+ <widget class="GtkCheckButton" id="pref_replaygain_scale">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">Replaygain peak scale</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="active">False</property>
+ <property name="inconsistent">False</property>
+ <property name="draw_indicator">True</property>
+ <signal name="clicked" handler="on_pref_replaygain_scale_clicked" last_modification_time="Sat, 10 Oct 2009 18:52:10 GMT"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHBox" id="hbox100">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">8</property>
<child>
- <widget class="GtkLabel" id="label8">
+ <widget class="GtkLabel" id="label124">
<property name="visible">True</property>
- <property name="label" translatable="yes">Replaygain mode:</property>
+ <property name="label" translatable="yes">Replaygain preamp:</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
- <property name="xalign">0</property>
+ <property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
@@ -2591,15 +2676,41 @@ linear</property>
</child>
<child>
- <widget class="GtkComboBox" id="pref_replaygain_mode">
- <property name="width_request">337</property>
+ <widget class="GtkLabel" id="label125">
<property name="visible">True</property>
- <property name="items" translatable="yes">Disable
-Track
-Album</property>
- <property name="add_tearoffs">False</property>
- <property name="focus_on_click">True</property>
- <signal name="changed" handler="on_pref_replaygain_mode_changed" last_modification_time="Sat, 10 Oct 2009 19:22:23 GMT"/>
+ <property name="label" translatable="yes">-12 dB</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHScale" id="replaygain_preamp">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="draw_value">True</property>
+ <property name="value_pos">GTK_POS_BOTTOM</property>
+ <property name="digits">0</property>
+ <property name="update_policy">GTK_UPDATE_CONTINUOUS</property>
+ <property name="inverted">False</property>
+ <property name="adjustment">0 -12 12 0 0 0</property>
+ <signal name="value_changed" handler="on_replaygain_preamp_value_changed" last_modification_time="Sat, 12 Mar 2011 14:20:29 GMT"/>
</widget>
<packing>
<property name="padding">0</property>
@@ -2607,26 +2718,31 @@ Album</property>
<property name="fill">True</property>
</packing>
</child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- <child>
- <widget class="GtkCheckButton" id="pref_replaygain_scale">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Replaygain peak scale</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- <signal name="clicked" handler="on_pref_replaygain_scale_clicked" last_modification_time="Sat, 10 Oct 2009 18:52:10 GMT"/>
+ <child>
+ <widget class="GtkLabel" id="label126">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">+12 dB</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
</widget>
<packing>
<property name="padding">0</property>
@@ -2707,6 +2823,26 @@ Album</property>
<property name="fill">False</property>
</packing>
</child>
+
+ <child>
+ <widget class="GtkCheckButton" id="ignore_archives">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">Don't add from archives when adding folders</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="active">False</property>
+ <property name="inconsistent">False</property>
+ <property name="draw_indicator">True</property>
+ <signal name="toggled" handler="on_ignore_archives_toggled" last_modification_time="Tue, 05 Apr 2011 20:41:18 GMT"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
</widget>
<packing>
<property name="tab_expand">False</property>
@@ -2738,6 +2874,283 @@ Album</property>
</child>
<child>
+ <widget class="GtkVBox" id="vbox29">
+ <property name="border_width">12</property>
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">8</property>
+
+ <child>
+ <widget class="GtkHBox" id="hbox80">
+ <property name="visible">True</property>
+ <property name="homogeneous">True</property>
+ <property name="spacing">8</property>
+
+ <child>
+ <widget class="GtkButton" id="dsp_add">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-add</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <signal name="clicked" handler="on_dsp_add_clicked" last_modification_time="Wed, 29 Dec 2010 11:54:39 GMT"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="dsp_remove">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-remove</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <signal name="clicked" handler="on_dsp_remove_clicked" last_modification_time="Wed, 29 Dec 2010 11:54:43 GMT"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="dsp_configure">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">Configure</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <signal name="clicked" handler="on_dsp_configure_clicked" last_modification_time="Wed, 29 Dec 2010 11:54:47 GMT"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHBox" id="hbox81">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">8</property>
+
+ <child>
+ <widget class="GtkScrolledWindow" id="scrolledwindow7">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="shadow_type">GTK_SHADOW_IN</property>
+ <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+
+ <child>
+ <widget class="GtkTreeView" id="dsp_listview">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="headers_visible">False</property>
+ <property name="rules_hint">False</property>
+ <property name="reorderable">False</property>
+ <property name="enable_search">True</property>
+ <property name="fixed_height_mode">False</property>
+ <property name="hover_selection">False</property>
+ <property name="hover_expand">False</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkVBox" id="vbox30">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">8</property>
+
+ <child>
+ <widget class="GtkButton" id="dsp_up">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-go-up</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <signal name="clicked" handler="on_dsp_up_clicked" last_modification_time="Wed, 29 Dec 2010 11:54:52 GMT"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="dsp_down">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-go-down</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <signal name="clicked" handler="on_dsp_down_clicked" last_modification_time="Wed, 29 Dec 2010 11:54:55 GMT"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHBox" id="hbox86">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">8</property>
+
+ <child>
+ <widget class="GtkLabel" id="label114">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">DSP Chain Preset</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkComboBoxEntry" id="dsp_preset">
+ <property name="visible">True</property>
+ <property name="add_tearoffs">False</property>
+ <property name="has_frame">True</property>
+ <property name="focus_on_click">True</property>
+ <signal name="changed" handler="on_dsp_preset_changed" last_modification_time="Wed, 05 Jan 2011 19:38:28 GMT"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="dsp_preset_save">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-save</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <signal name="clicked" handler="on_dsp_preset_save_clicked" last_modification_time="Wed, 05 Jan 2011 19:38:10 GMT"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="dsp_preset_load">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">_Load</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <signal name="clicked" handler="on_dsp_preset_load_clicked" last_modification_time="Wed, 05 Jan 2011 19:38:13 GMT"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="tab_expand">False</property>
+ <property name="tab_fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label110">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">DSP</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="type">tab</property>
+ </packing>
+ </child>
+
+ <child>
<widget class="GtkVBox" id="vbox9">
<property name="border_width">12</property>
<property name="visible">True</property>
@@ -2845,6 +3258,83 @@ Album</property>
</child>
<child>
+ <widget class="GtkCheckButton" id="auto_name_playlist_from_folder">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">Auto-name playlists when adding a single folder</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="active">False</property>
+ <property name="inconsistent">False</property>
+ <property name="draw_indicator">True</property>
+ <signal name="toggled" handler="on_auto_name_playlist_from_folder_toggled" last_modification_time="Tue, 04 Jan 2011 20:49:15 GMT"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHBox" id="hbox102">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">8</property>
+
+ <child>
+ <widget class="GtkLabel" id="label129">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Interface refresh rate (times per second):</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHScale" id="gui_fps">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="draw_value">True</property>
+ <property name="value_pos">GTK_POS_RIGHT</property>
+ <property name="digits">0</property>
+ <property name="update_policy">GTK_UPDATE_CONTINUOUS</property>
+ <property name="inverted">False</property>
+ <property name="adjustment">10 1 30 0 0 0</property>
+ <signal name="value_changed" handler="on_gui_fps_value_changed" last_modification_time="Mon, 04 Apr 2011 20:11:49 GMT"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
<widget class="GtkHBox" id="hbox64">
<property name="visible">True</property>
<property name="homogeneous">False</property>
@@ -2961,7 +3451,55 @@ Album</property>
</child>
<child>
- <placeholder/>
+ <widget class="GtkHBox" id="hbox101">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">8</property>
+
+ <child>
+ <widget class="GtkLabel" id="label128">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">GUI Plugin (changing requires restart):</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkComboBox" id="gui_plugin">
+ <property name="visible">True</property>
+ <property name="add_tearoffs">False</property>
+ <property name="focus_on_click">True</property>
+ <signal name="changed" handler="on_gui_plugin_changed" last_modification_time="Wed, 23 Mar 2011 20:30:20 GMT"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
</child>
</widget>
<packing>
@@ -3199,7 +3737,7 @@ Album</property>
<widget class="GtkTable" id="tabstrip_colors_group">
<property name="visible">True</property>
<property name="n_rows">2</property>
- <property name="n_columns">4</property>
+ <property name="n_columns">5</property>
<property name="homogeneous">True</property>
<property name="row_spacing">0</property>
<property name="column_spacing">8</property>
@@ -3387,6 +3925,52 @@ Album</property>
<property name="y_options"></property>
</packing>
</child>
+
+ <child>
+ <widget class="GtkLabel" id="label127">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Text</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="left_attach">4</property>
+ <property name="right_attach">5</property>
+ <property name="top_attach">0</property>
+ <property name="bottom_attach">1</property>
+ <property name="x_options">expand</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkColorButton" id="tabstrip_text">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="use_alpha">False</property>
+ <property name="focus_on_click">True</property>
+ <signal name="color_set" handler="on_tabstrip_text_color_set" last_modification_time="Wed, 23 Mar 2011 20:09:34 GMT"/>
+ </widget>
+ <packing>
+ <property name="left_attach">4</property>
+ <property name="right_attach">5</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">expand</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
</widget>
<packing>
<property name="padding">0</property>
@@ -4148,705 +4732,6 @@ SOCKS5_HOSTNAME</property>
</child>
<child>
- <widget class="GtkVBox" id="vbox18">
- <property name="border_width">12</property>
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <widget class="GtkFrame" id="frame5">
- <property name="visible">True</property>
- <property name="label_xalign">0</property>
- <property name="label_yalign">0.5</property>
- <property name="shadow_type">GTK_SHADOW_NONE</property>
-
- <child>
- <widget class="GtkAlignment" id="alignment3">
- <property name="visible">True</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xscale">1</property>
- <property name="yscale">1</property>
- <property name="top_padding">0</property>
- <property name="bottom_padding">0</property>
- <property name="left_padding">12</property>
- <property name="right_padding">0</property>
-
- <child>
- <widget class="GtkVBox" id="vbox19">
- <property name="border_width">12</property>
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">8</property>
-
- <child>
- <widget class="GtkHBox" id="hbox38">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">8</property>
-
- <child>
- <widget class="GtkCheckButton" id="write_id3v2">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Write ID3v2</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- <signal name="toggled" handler="on_write_id3v2_toggled" last_modification_time="Tue, 30 Mar 2010 20:43:51 GMT"/>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkCheckButton" id="write_id3v1">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Write ID3v1</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- <signal name="toggled" handler="on_write_id3v1_toggled" last_modification_time="Tue, 30 Mar 2010 20:43:55 GMT"/>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkCheckButton" id="write_apev2">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Write APEv2</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- <signal name="toggled" handler="on_write_apev2_toggled" last_modification_time="Tue, 30 Mar 2010 20:43:59 GMT"/>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="hbox40">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">8</property>
-
- <child>
- <widget class="GtkCheckButton" id="strip_id3v2">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Strip ID3v2</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- <signal name="toggled" handler="on_strip_id3v2_toggled" last_modification_time="Tue, 30 Mar 2010 20:44:03 GMT"/>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkCheckButton" id="strip_id3v1">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Strip ID3v1</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- <signal name="toggled" handler="on_strip_id3v1_toggled" last_modification_time="Tue, 30 Mar 2010 20:44:07 GMT"/>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkCheckButton" id="strip_apev2">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Strip APEv2</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- <signal name="toggled" handler="on_strip_apev2_toggled" last_modification_time="Tue, 30 Mar 2010 20:44:12 GMT"/>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="hbox36">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">8</property>
-
- <child>
- <widget class="GtkLabel" id="label69">
- <property name="visible">True</property>
- <property name="label" translatable="yes">ID3v2 version</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkComboBox" id="id3v2_version">
- <property name="visible">True</property>
- <property name="items" translatable="yes">2.3 (Recommended)
-2.4</property>
- <property name="add_tearoffs">False</property>
- <property name="focus_on_click">True</property>
- <signal name="changed" handler="on_id3v2_version_changed" last_modification_time="Tue, 30 Mar 2010 20:44:27 GMT"/>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="hbox39">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">8</property>
-
- <child>
- <widget class="GtkLabel" id="label71">
- <property name="visible">True</property>
- <property name="label" translatable="yes">ID3v1 character encoding (default is iso8859-1)</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkEntry" id="id3v1_encoding">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="editable">True</property>
- <property name="visibility">True</property>
- <property name="max_length">0</property>
- <property name="text" translatable="yes"></property>
- <property name="has_frame">True</property>
- <property name="invisible_char">●</property>
- <property name="activates_default">False</property>
- <signal name="changed" handler="on_id3v1_encoding_changed" last_modification_time="Tue, 30 Mar 2010 20:44:34 GMT"/>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- </child>
- </widget>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label68">
- <property name="visible">True</property>
- <property name="label">&lt;b&gt;MP3&lt;/b&gt;</property>
- <property name="use_underline">False</property>
- <property name="use_markup">True</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="type">label_item</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="hbox41">
- <property name="visible">True</property>
- <property name="homogeneous">True</property>
- <property name="spacing">0</property>
-
- <child>
- <widget class="GtkFrame" id="frame6">
- <property name="visible">True</property>
- <property name="label_xalign">0</property>
- <property name="label_yalign">0.5</property>
- <property name="shadow_type">GTK_SHADOW_NONE</property>
-
- <child>
- <widget class="GtkAlignment" id="alignment4">
- <property name="visible">True</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xscale">1</property>
- <property name="yscale">1</property>
- <property name="top_padding">0</property>
- <property name="bottom_padding">0</property>
- <property name="left_padding">12</property>
- <property name="right_padding">0</property>
-
- <child>
- <widget class="GtkVBox" id="vbox20">
- <property name="border_width">12</property>
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">8</property>
-
- <child>
- <widget class="GtkHBox" id="hbox37">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">8</property>
-
- <child>
- <widget class="GtkCheckButton" id="ape_write_id3v2">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Write ID3v2.4</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- <signal name="toggled" handler="on_ape_write_id3v2_toggled" last_modification_time="Tue, 30 Mar 2010 20:44:42 GMT"/>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkCheckButton" id="ape_write_apev2">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Write APEv2</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- <signal name="toggled" handler="on_ape_write_apev2_toggled" last_modification_time="Tue, 30 Mar 2010 20:44:46 GMT"/>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="hbox45">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">8</property>
-
- <child>
- <widget class="GtkCheckButton" id="ape_strip_id3v2">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Strip ID3v2</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- <signal name="toggled" handler="on_ape_strip_id3v2_toggled" last_modification_time="Tue, 30 Mar 2010 20:44:50 GMT"/>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkCheckButton" id="ape_strip_apev2">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Strip APEv2</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- <signal name="toggled" handler="on_ape_strip_apev2_toggled" last_modification_time="Tue, 30 Mar 2010 20:44:54 GMT"/>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- </child>
- </widget>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label70">
- <property name="visible">True</property>
- <property name="label">&lt;b&gt;APE&lt;/b&gt;</property>
- <property name="use_underline">False</property>
- <property name="use_markup">True</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="type">label_item</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkFrame" id="frame7">
- <property name="visible">True</property>
- <property name="label_xalign">0</property>
- <property name="label_yalign">0.5</property>
- <property name="shadow_type">GTK_SHADOW_NONE</property>
-
- <child>
- <widget class="GtkAlignment" id="alignment5">
- <property name="visible">True</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xscale">1</property>
- <property name="yscale">1</property>
- <property name="top_padding">0</property>
- <property name="bottom_padding">0</property>
- <property name="left_padding">12</property>
- <property name="right_padding">0</property>
-
- <child>
- <widget class="GtkVBox" id="vbox_wv">
- <property name="border_width">12</property>
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">8</property>
-
- <child>
- <widget class="GtkHBox" id="hbox44">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">8</property>
-
- <child>
- <widget class="GtkCheckButton" id="wv_write_apev2">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Write APEv2</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- <signal name="toggled" handler="on_wv_write_apev2_toggled" last_modification_time="Tue, 06 Apr 2010 19:36:17 GMT"/>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkCheckButton" id="wv_write_id3v1">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Write ID3v1</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- <signal name="toggled" handler="on_wv_write_id3v1_toggled" last_modification_time="Tue, 06 Apr 2010 19:36:13 GMT"/>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="hbox43">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">8</property>
-
- <child>
- <widget class="GtkCheckButton" id="wv_strip_apev2">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Strip APEv2</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- <signal name="toggled" handler="on_wv_strip_apev2_toggled" last_modification_time="Tue, 06 Apr 2010 19:40:53 GMT"/>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkCheckButton" id="wv_strip_id3v1">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Strip ID3v1</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- <signal name="toggled" handler="on_wv_strip_id3v1_toggled" last_modification_time="Tue, 06 Apr 2010 19:40:57 GMT"/>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- </child>
- </widget>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label79">
- <property name="visible">True</property>
- <property name="label">&lt;b&gt;WavPack&lt;/b&gt;</property>
- <property name="use_underline">False</property>
- <property name="use_markup">True</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="type">label_item</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="tab_expand">False</property>
- <property name="tab_fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label67">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Tag writer</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="type">tab</property>
- </packing>
- </child>
-
- <child>
<widget class="GtkHPaned" id="hpaned1">
<property name="border_width">12</property>
<property name="visible">True</property>
@@ -4892,249 +4777,138 @@ SOCKS5_HOSTNAME</property>
<property name="spacing">8</property>
<child>
- <widget class="GtkHBox" id="hbox16">
+ <widget class="GtkScrolledWindow" id="scrolledwindow8">
<property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">8</property>
-
- <child>
- <widget class="GtkLabel" id="label11">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Description:</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="shadow_type">GTK_SHADOW_IN</property>
+ <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
<child>
- <widget class="GtkEntry" id="pref_plugin_descr">
+ <widget class="GtkTextView" id="plug_description">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="editable">False</property>
- <property name="visibility">True</property>
- <property name="max_length">0</property>
+ <property name="overwrite">False</property>
+ <property name="accepts_tab">True</property>
+ <property name="justification">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap_mode">GTK_WRAP_NONE</property>
+ <property name="cursor_visible">False</property>
+ <property name="pixels_above_lines">0</property>
+ <property name="pixels_below_lines">0</property>
+ <property name="pixels_inside_wrap">0</property>
+ <property name="left_margin">0</property>
+ <property name="right_margin">0</property>
+ <property name="indent">0</property>
<property name="text" translatable="yes"></property>
- <property name="has_frame">True</property>
- <property name="invisible_char">●</property>
- <property name="activates_default">False</property>
</widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
</packing>
</child>
<child>
- <widget class="GtkHBox" id="hbox17">
+ <widget class="GtkHBox" id="hbox20">
<property name="visible">True</property>
<property name="homogeneous">False</property>
- <property name="spacing">8</property>
-
- <child>
- <widget class="GtkLabel" id="label12">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Author(s):</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
+ <property name="spacing">0</property>
<child>
- <widget class="GtkEntry" id="pref_plugin_author">
+ <widget class="GtkButton" id="configure_plugin">
<property name="visible">True</property>
+ <property name="sensitive">False</property>
<property name="can_focus">True</property>
- <property name="editable">False</property>
- <property name="visibility">True</property>
- <property name="max_length">0</property>
- <property name="text" translatable="yes"></property>
- <property name="has_frame">True</property>
- <property name="invisible_char">●</property>
- <property name="activates_default">False</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="hbox18">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">8</property>
-
- <child>
- <widget class="GtkLabel" id="label13">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Email:</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <signal name="clicked" handler="on_configure_plugin_clicked" last_modification_time="Tue, 01 Dec 2009 16:54:36 GMT"/>
- <child>
- <widget class="GtkEntry" id="pref_plugin_email">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="editable">False</property>
- <property name="visibility">True</property>
- <property name="max_length">0</property>
- <property name="text" translatable="yes"></property>
- <property name="has_frame">True</property>
- <property name="invisible_char">●</property>
- <property name="activates_default">False</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
+ <child>
+ <widget class="GtkAlignment" id="alignment15">
+ <property name="visible">True</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xscale">0</property>
+ <property name="yscale">0</property>
+ <property name="top_padding">0</property>
+ <property name="bottom_padding">0</property>
+ <property name="left_padding">0</property>
+ <property name="right_padding">0</property>
- <child>
- <widget class="GtkHBox" id="hbox19">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">8</property>
+ <child>
+ <widget class="GtkHBox" id="hbox56">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">2</property>
- <child>
- <widget class="GtkLabel" id="label14">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Website:</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
+ <child>
+ <widget class="GtkImage" id="image394">
+ <property name="visible">True</property>
+ <property name="stock">gtk-preferences</property>
+ <property name="icon_size">4</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
- <child>
- <widget class="GtkEntry" id="pref_plugin_website">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="editable">False</property>
- <property name="visibility">True</property>
- <property name="max_length">0</property>
- <property name="text" translatable="yes"></property>
- <property name="has_frame">True</property>
- <property name="invisible_char">●</property>
- <property name="activates_default">False</property>
+ <child>
+ <widget class="GtkLabel" id="label92">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Configure</property>
+ <property name="use_underline">True</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
- <property name="fill">True</property>
+ <property name="fill">False</property>
</packing>
</child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="hbox20">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
<child>
- <widget class="GtkButton" id="configure_plugin">
+ <widget class="GtkButton" id="plug_copyright">
<property name="visible">True</property>
+ <property name="sensitive">False</property>
<property name="can_focus">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
- <signal name="clicked" handler="on_configure_plugin_clicked" last_modification_time="Tue, 01 Dec 2009 16:54:36 GMT"/>
+ <signal name="clicked" handler="on_plug_copyright_clicked" last_modification_time="Sun, 27 Feb 2011 10:24:22 GMT"/>
<child>
- <widget class="GtkAlignment" id="alignment15">
+ <widget class="GtkAlignment" id="alignment20">
<property name="visible">True</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
@@ -5146,15 +4920,15 @@ SOCKS5_HOSTNAME</property>
<property name="right_padding">0</property>
<child>
- <widget class="GtkHBox" id="hbox56">
+ <widget class="GtkHBox" id="hbox88">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">2</property>
<child>
- <widget class="GtkImage" id="image394">
+ <widget class="GtkImage" id="image521">
<property name="visible">True</property>
- <property name="stock">gtk-preferences</property>
+ <property name="stock">gtk-about</property>
<property name="icon_size">4</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
@@ -5169,9 +4943,9 @@ SOCKS5_HOSTNAME</property>
</child>
<child>
- <widget class="GtkLabel" id="label92">
+ <widget class="GtkLabel" id="label117">
<property name="visible">True</property>
- <property name="label" translatable="yes">Configure</property>
+ <property name="label" translatable="yes">Copyright</property>
<property name="use_underline">True</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
@@ -5203,6 +4977,21 @@ SOCKS5_HOSTNAME</property>
<property name="fill">False</property>
</packing>
</child>
+
+ <child>
+ <widget class="Custom" id="weblink">
+ <property name="visible">True</property>
+ <property name="creation_function">create_plugin_weblink</property>
+ <property name="int1">0</property>
+ <property name="int2">0</property>
+ <property name="last_modification_time">Sun, 27 Feb 2011 11:39:00 GMT</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
</widget>
<packing>
<property name="padding">0</property>
@@ -5256,10 +5045,10 @@ SOCKS5_HOSTNAME</property>
</child>
</widget>
-<widget class="GtkDialog" id="editplaylistdlg">
+<widget class="GtkDialog" id="entrydialog">
<property name="border_width">8</property>
<property name="visible">True</property>
- <property name="title" translatable="yes">editplaylistdlg</property>
+ <property name="title">EntryDialog</property>
<property name="type">GTK_WINDOW_TOPLEVEL</property>
<property name="window_position">GTK_WIN_POS_NONE</property>
<property name="modal">False</property>
@@ -5457,7 +5246,7 @@ SOCKS5_HOSTNAME</property>
<property name="spacing">8</property>
<child>
- <widget class="GtkLabel" id="label40">
+ <widget class="GtkLabel" id="title_label">
<property name="visible">True</property>
<property name="label" translatable="yes">Title:</property>
<property name="use_underline">False</property>
@@ -5991,16 +5780,44 @@ SOCKS5_HOSTNAME</property>
</child>
<child>
- <widget class="GtkEntry" id="format">
+ <widget class="GtkHBox" id="hbox75">
<property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="editable">True</property>
- <property name="visibility">True</property>
- <property name="max_length">0</property>
- <property name="text" translatable="yes"></property>
- <property name="has_frame">True</property>
- <property name="invisible_char">●</property>
- <property name="activates_default">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkEntry" id="format">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="editable">True</property>
+ <property name="visibility">True</property>
+ <property name="max_length">0</property>
+ <property name="text" translatable="yes"></property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char">●</property>
+ <property name="activates_default">True</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="Custom" id="custom1">
+ <property name="visible">True</property>
+ <property name="creation_function">title_formatting_help_link_create</property>
+ <property name="int1">0</property>
+ <property name="int2">0</property>
+ <property name="last_modification_time">Fri, 03 Dec 2010 20:39:24 GMT</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
</widget>
<packing>
<property name="padding">0</property>
@@ -6015,30 +5832,347 @@ SOCKS5_HOSTNAME</property>
<property name="fill">False</property>
</packing>
</child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+</widget>
+
+<widget class="GtkDialog" id="sortbydlg">
+ <property name="visible">True</property>
+ <property name="title" translatable="yes">Sort by...</property>
+ <property name="type">GTK_WINDOW_TOPLEVEL</property>
+ <property name="window_position">GTK_WIN_POS_NONE</property>
+ <property name="modal">True</property>
+ <property name="resizable">True</property>
+ <property name="destroy_with_parent">False</property>
+ <property name="decorated">True</property>
+ <property name="skip_taskbar_hint">False</property>
+ <property name="skip_pager_hint">False</property>
+ <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+ <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+ <property name="focus_on_map">True</property>
+ <property name="urgency_hint">False</property>
+ <property name="has_separator">True</property>
+
+ <child internal-child="vbox">
+ <widget class="GtkVBox" id="dialog-vbox8">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child internal-child="action_area">
+ <widget class="GtkHButtonBox" id="dialog-action_area7">
+ <property name="visible">True</property>
+ <property name="layout_style">GTK_BUTTONBOX_END</property>
<child>
- <widget class="GtkLabel" id="label82">
+ <widget class="GtkButton" id="cancelbutton5">
<property name="visible">True</property>
+ <property name="can_default">True</property>
<property name="can_focus">True</property>
- <property name="label" translatable="yes">Format conversions (start with %):
- [a]rtist, [t]itle, al[b]um, [B]and, [C]omposer
- track[n]umber, [N]totaltracks,
- [l]ength, [y]ear, [g]enre, [c]omment,
- copy[r]ight, [f]ilename, [T]ags
-Example: %a - %t [%l]</property>
- <property name="use_underline">False</property>
- <property name="use_markup">True</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">True</property>
- <property name="xalign">0.10000000149</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
+ <property name="label">gtk-cancel</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="response_id">-6</property>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="okbutton5">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-ok</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="response_id">-5</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">GTK_PACK_END</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkVBox" id="vbox28">
+ <property name="border_width">12</property>
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">8</property>
+
+ <child>
+ <widget class="GtkHBox" id="hbox76">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">8</property>
+
+ <child>
+ <widget class="GtkLabel" id="label108">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Format</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHBox" id="hbox77">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkEntry" id="sortfmt">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="editable">True</property>
+ <property name="visibility">True</property>
+ <property name="max_length">0</property>
+ <property name="text" translatable="yes"></property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char">●</property>
+ <property name="activates_default">False</property>
+ <signal name="activate" handler="on_sortfmt_activate" last_modification_time="Fri, 03 Dec 2010 22:08:09 GMT"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="Custom" id="custom3">
+ <property name="visible">True</property>
+ <property name="creation_function">title_formatting_help_link_create</property>
+ <property name="int1">0</property>
+ <property name="int2">0</property>
+ <property name="last_modification_time">Fri, 03 Dec 2010 20:39:24 GMT</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHBox" id="hbox78">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">8</property>
+
+ <child>
+ <widget class="GtkLabel" id="label109">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Order</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkComboBox" id="sortorder">
+ <property name="visible">True</property>
+ <property name="items" translatable="yes">Ascending
+Descending</property>
+ <property name="add_tearoffs">False</property>
+ <property name="focus_on_click">True</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+</widget>
+
+<widget class="GtkDialog" id="select_dsp_plugin">
+ <property name="visible">True</property>
+ <property name="title" translatable="yes">Select DSP Plugin</property>
+ <property name="type">GTK_WINDOW_TOPLEVEL</property>
+ <property name="window_position">GTK_WIN_POS_NONE</property>
+ <property name="modal">True</property>
+ <property name="resizable">True</property>
+ <property name="destroy_with_parent">False</property>
+ <property name="decorated">True</property>
+ <property name="skip_taskbar_hint">False</property>
+ <property name="skip_pager_hint">False</property>
+ <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+ <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+ <property name="focus_on_map">True</property>
+ <property name="urgency_hint">False</property>
+ <property name="has_separator">True</property>
+
+ <child internal-child="vbox">
+ <widget class="GtkVBox" id="dialog-vbox10">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child internal-child="action_area">
+ <widget class="GtkHButtonBox" id="dialog-action_area9">
+ <property name="visible">True</property>
+ <property name="layout_style">GTK_BUTTONBOX_END</property>
+
+ <child>
+ <widget class="GtkButton" id="cancelbutton7">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-cancel</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="response_id">-6</property>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="okbutton7">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-ok</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="response_id">-5</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">GTK_PACK_END</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkVBox" id="vbox31">
+ <property name="border_width">12</property>
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">8</property>
+
+ <child>
+ <widget class="GtkHBox" id="hbox85">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">8</property>
+
+ <child>
+ <widget class="GtkLabel" id="label113">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Plugin</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkComboBox" id="plugin">
+ <property name="visible">True</property>
+ <property name="add_tearoffs">False</property>
+ <property name="focus_on_click">True</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
</widget>
<packing>
<property name="padding">0</property>
@@ -6057,4 +6191,733 @@ Example: %a - %t [%l]</property>
</child>
</widget>
+<widget class="GtkDialog" id="tagwritersettings">
+ <property name="border_width">12</property>
+ <property name="visible">True</property>
+ <property name="title" translatable="yes">Tag Writer Settings</property>
+ <property name="type">GTK_WINDOW_TOPLEVEL</property>
+ <property name="window_position">GTK_WIN_POS_NONE</property>
+ <property name="modal">True</property>
+ <property name="resizable">True</property>
+ <property name="destroy_with_parent">False</property>
+ <property name="decorated">True</property>
+ <property name="skip_taskbar_hint">False</property>
+ <property name="skip_pager_hint">False</property>
+ <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+ <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+ <property name="focus_on_map">True</property>
+ <property name="urgency_hint">False</property>
+ <property name="has_separator">False</property>
+
+ <child internal-child="vbox">
+ <widget class="GtkVBox" id="dialog-vbox11">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child internal-child="action_area">
+ <widget class="GtkHButtonBox" id="dialog-action_area10">
+ <property name="visible">True</property>
+ <property name="layout_style">GTK_BUTTONBOX_END</property>
+
+ <child>
+ <widget class="GtkButton" id="closebutton2">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-close</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="response_id">-7</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">GTK_PACK_END</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkVBox" id="vbox32">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkFrame" id="frame8">
+ <property name="visible">True</property>
+ <property name="label_xalign">0</property>
+ <property name="label_yalign">0.5</property>
+ <property name="shadow_type">GTK_SHADOW_NONE</property>
+
+ <child>
+ <widget class="GtkAlignment" id="alignment21">
+ <property name="visible">True</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xscale">1</property>
+ <property name="yscale">1</property>
+ <property name="top_padding">0</property>
+ <property name="bottom_padding">0</property>
+ <property name="left_padding">12</property>
+ <property name="right_padding">0</property>
+
+ <child>
+ <widget class="GtkVBox" id="vbox33">
+ <property name="border_width">12</property>
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">8</property>
+
+ <child>
+ <widget class="GtkHBox" id="hbox89">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">8</property>
+
+ <child>
+ <widget class="GtkCheckButton" id="write_id3v2">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">Write ID3v2</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="active">False</property>
+ <property name="inconsistent">False</property>
+ <property name="draw_indicator">True</property>
+ <signal name="toggled" handler="on_write_id3v2_toggled" last_modification_time="Tue, 30 Mar 2010 20:43:51 GMT"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkCheckButton" id="write_id3v1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">Write ID3v1</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="active">False</property>
+ <property name="inconsistent">False</property>
+ <property name="draw_indicator">True</property>
+ <signal name="toggled" handler="on_write_id3v1_toggled" last_modification_time="Tue, 30 Mar 2010 20:43:55 GMT"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkCheckButton" id="write_apev2">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">Write APEv2</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="active">False</property>
+ <property name="inconsistent">False</property>
+ <property name="draw_indicator">True</property>
+ <signal name="toggled" handler="on_write_apev2_toggled" last_modification_time="Tue, 30 Mar 2010 20:43:59 GMT"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHBox" id="hbox90">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">8</property>
+
+ <child>
+ <widget class="GtkCheckButton" id="strip_id3v2">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">Strip ID3v2</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="active">False</property>
+ <property name="inconsistent">False</property>
+ <property name="draw_indicator">True</property>
+ <signal name="toggled" handler="on_strip_id3v2_toggled" last_modification_time="Tue, 30 Mar 2010 20:44:03 GMT"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkCheckButton" id="strip_id3v1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">Strip ID3v1</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="active">False</property>
+ <property name="inconsistent">False</property>
+ <property name="draw_indicator">True</property>
+ <signal name="toggled" handler="on_strip_id3v1_toggled" last_modification_time="Tue, 30 Mar 2010 20:44:07 GMT"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkCheckButton" id="strip_apev2">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">Strip APEv2</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="active">False</property>
+ <property name="inconsistent">False</property>
+ <property name="draw_indicator">True</property>
+ <signal name="toggled" handler="on_strip_apev2_toggled" last_modification_time="Tue, 30 Mar 2010 20:44:12 GMT"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHBox" id="hbox91">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">8</property>
+
+ <child>
+ <widget class="GtkLabel" id="label118">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">ID3v2 version</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkComboBox" id="id3v2_version">
+ <property name="visible">True</property>
+ <property name="items" translatable="yes">2.3 (Recommended)
+2.4</property>
+ <property name="add_tearoffs">False</property>
+ <property name="focus_on_click">True</property>
+ <signal name="changed" handler="on_id3v2_version_changed" last_modification_time="Tue, 30 Mar 2010 20:44:27 GMT"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHBox" id="hbox92">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">8</property>
+
+ <child>
+ <widget class="GtkLabel" id="label119">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">ID3v1 character encoding (default is iso8859-1)</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkEntry" id="id3v1_encoding">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="editable">True</property>
+ <property name="visibility">True</property>
+ <property name="max_length">0</property>
+ <property name="text" translatable="yes"></property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char">●</property>
+ <property name="activates_default">False</property>
+ <signal name="changed" handler="on_id3v1_encoding_changed" last_modification_time="Tue, 30 Mar 2010 20:44:34 GMT"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label120">
+ <property name="visible">True</property>
+ <property name="label">&lt;b&gt;MP3&lt;/b&gt;</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">True</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="type">label_item</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHBox" id="hbox93">
+ <property name="visible">True</property>
+ <property name="homogeneous">True</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkFrame" id="frame9">
+ <property name="visible">True</property>
+ <property name="label_xalign">0</property>
+ <property name="label_yalign">0.5</property>
+ <property name="shadow_type">GTK_SHADOW_NONE</property>
+
+ <child>
+ <widget class="GtkAlignment" id="alignment22">
+ <property name="visible">True</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xscale">1</property>
+ <property name="yscale">1</property>
+ <property name="top_padding">0</property>
+ <property name="bottom_padding">0</property>
+ <property name="left_padding">12</property>
+ <property name="right_padding">0</property>
+
+ <child>
+ <widget class="GtkVBox" id="vbox34">
+ <property name="border_width">12</property>
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">8</property>
+
+ <child>
+ <widget class="GtkHBox" id="hbox94">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">8</property>
+
+ <child>
+ <widget class="GtkCheckButton" id="ape_write_id3v2">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">Write ID3v2.4</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="active">False</property>
+ <property name="inconsistent">False</property>
+ <property name="draw_indicator">True</property>
+ <signal name="toggled" handler="on_ape_write_id3v2_toggled" last_modification_time="Tue, 30 Mar 2010 20:44:42 GMT"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkCheckButton" id="ape_write_apev2">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">Write APEv2</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="active">False</property>
+ <property name="inconsistent">False</property>
+ <property name="draw_indicator">True</property>
+ <signal name="toggled" handler="on_ape_write_apev2_toggled" last_modification_time="Tue, 30 Mar 2010 20:44:46 GMT"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHBox" id="hbox95">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">8</property>
+
+ <child>
+ <widget class="GtkCheckButton" id="ape_strip_id3v2">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">Strip ID3v2</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="active">False</property>
+ <property name="inconsistent">False</property>
+ <property name="draw_indicator">True</property>
+ <signal name="toggled" handler="on_ape_strip_id3v2_toggled" last_modification_time="Tue, 30 Mar 2010 20:44:50 GMT"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkCheckButton" id="ape_strip_apev2">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">Strip APEv2</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="active">False</property>
+ <property name="inconsistent">False</property>
+ <property name="draw_indicator">True</property>
+ <signal name="toggled" handler="on_ape_strip_apev2_toggled" last_modification_time="Tue, 30 Mar 2010 20:44:54 GMT"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label121">
+ <property name="visible">True</property>
+ <property name="label">&lt;b&gt;APE&lt;/b&gt;</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">True</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="type">label_item</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkFrame" id="frame10">
+ <property name="visible">True</property>
+ <property name="label_xalign">0</property>
+ <property name="label_yalign">0.5</property>
+ <property name="shadow_type">GTK_SHADOW_NONE</property>
+
+ <child>
+ <widget class="GtkAlignment" id="alignment23">
+ <property name="visible">True</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xscale">1</property>
+ <property name="yscale">1</property>
+ <property name="top_padding">0</property>
+ <property name="bottom_padding">0</property>
+ <property name="left_padding">12</property>
+ <property name="right_padding">0</property>
+
+ <child>
+ <widget class="GtkVBox" id="vbox35">
+ <property name="border_width">12</property>
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">8</property>
+
+ <child>
+ <widget class="GtkHBox" id="hbox96">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">8</property>
+
+ <child>
+ <widget class="GtkCheckButton" id="wv_write_apev2">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">Write APEv2</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="active">False</property>
+ <property name="inconsistent">False</property>
+ <property name="draw_indicator">True</property>
+ <signal name="toggled" handler="on_wv_write_apev2_toggled" last_modification_time="Tue, 06 Apr 2010 19:36:17 GMT"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkCheckButton" id="wv_write_id3v1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">Write ID3v1</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="active">False</property>
+ <property name="inconsistent">False</property>
+ <property name="draw_indicator">True</property>
+ <signal name="toggled" handler="on_wv_write_id3v1_toggled" last_modification_time="Tue, 06 Apr 2010 19:36:13 GMT"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHBox" id="hbox97">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">8</property>
+
+ <child>
+ <widget class="GtkCheckButton" id="wv_strip_apev2">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">Strip APEv2</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="active">False</property>
+ <property name="inconsistent">False</property>
+ <property name="draw_indicator">True</property>
+ <signal name="toggled" handler="on_wv_strip_apev2_toggled" last_modification_time="Tue, 06 Apr 2010 19:40:53 GMT"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkCheckButton" id="wv_strip_id3v1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">Strip ID3v1</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="active">False</property>
+ <property name="inconsistent">False</property>
+ <property name="draw_indicator">True</property>
+ <signal name="toggled" handler="on_wv_strip_id3v1_toggled" last_modification_time="Tue, 06 Apr 2010 19:40:57 GMT"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label122">
+ <property name="visible">True</property>
+ <property name="label">&lt;b&gt;WavPack&lt;/b&gt;</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">True</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="type">label_item</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+</widget>
+
</glade-interface>
diff --git a/plugins/gtkui/deadbeef.gladep b/plugins/gtkui/deadbeef.gladep
index 88874320..d0428a88 100644
--- a/plugins/gtkui/deadbeef.gladep
+++ b/plugins/gtkui/deadbeef.gladep
@@ -7,5 +7,6 @@
<source_directory></source_directory>
<gnome_support>FALSE</gnome_support>
<output_main_file>FALSE</output_main_file>
+ <output_support_files>FALSE</output_support_files>
<output_build_files>FALSE</output_build_files>
</glade-project>
diff --git a/plugins/gtkui/drawing.h b/plugins/gtkui/drawing.h
index e8c7e99d..b73c9f97 100644
--- a/plugins/gtkui/drawing.h
+++ b/plugins/gtkui/drawing.h
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@@ -97,6 +97,9 @@ void
gtkui_get_tabstrip_base_color (GdkColor *clr);
void
+gtkui_get_tabstrip_text_color (GdkColor *clr);
+
+void
gtkui_get_listview_even_row_color (GdkColor *clr);
void
@@ -126,4 +129,7 @@ gtkui_override_bar_colors (void);
int
gtkui_override_tabstrip_colors (void);
+int
+draw_get_listview_rowheight (void);
+
#endif // __DRAWING_H
diff --git a/plugins/gtkui/dspconfig.c b/plugins/gtkui/dspconfig.c
new file mode 100644
index 00000000..268f1b16
--- /dev/null
+++ b/plugins/gtkui/dspconfig.c
@@ -0,0 +1,482 @@
+/*
+ DeaDBeeF - ultimate music player for GNU/Linux systems with X11
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gtk/gtk.h>
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <assert.h>
+#include <dirent.h>
+#include <sys/stat.h>
+#include "callbacks.h"
+#include "interface.h"
+#include "support.h"
+#include "deadbeef.h"
+#include "gtkui.h"
+#include "pluginconf.h"
+
+static ddb_dsp_context_t *chain;
+static GtkWidget *prefwin;
+
+static ddb_dsp_context_t *
+dsp_clone (ddb_dsp_context_t *from) {
+ ddb_dsp_context_t *dsp = from->plugin->open ();
+ char param[2000];
+ if (from->plugin->num_params) {
+ int n = from->plugin->num_params ();
+ for (int i = 0; i < n; i++) {
+ from->plugin->get_param (from, i, param, sizeof (param));
+ dsp->plugin->set_param (dsp, i, param);
+ }
+ }
+ dsp->enabled = from->enabled;
+ return dsp;
+}
+
+static void
+fill_dsp_chain (GtkListStore *mdl) {
+ ddb_dsp_context_t *dsp = chain;
+ while (dsp) {
+ GtkTreeIter iter;
+ gtk_list_store_append (mdl, &iter);
+ gtk_list_store_set (mdl, &iter, 0, dsp->plugin->plugin.name, -1);
+ dsp = dsp->next;
+ }
+}
+
+static int dirent_alphasort (const struct dirent **a, const struct dirent **b) {
+ return strcmp ((*a)->d_name, (*b)->d_name);
+}
+
+static int
+scandir_preset_filter (const struct dirent *ent) {
+ char *ext = strrchr (ent->d_name, '.');
+ if (ext && !strcasecmp (ext, ".txt")) {
+ return 1;
+ }
+ return 0;
+}
+
+void
+dsp_setup_init (GtkWidget *_prefwin) {
+ prefwin = _prefwin;
+ // copy current dsp chain
+ ddb_dsp_context_t *streamer_chain = deadbeef->streamer_get_dsp_chain ();
+
+ ddb_dsp_context_t *tail = NULL;
+ while (streamer_chain) {
+ ddb_dsp_context_t *new = dsp_clone (streamer_chain);
+ if (tail) {
+ tail->next = new;
+ tail = new;
+ }
+ else {
+ chain = tail = new;
+ }
+ streamer_chain = streamer_chain->next;
+ }
+
+ // fill dsp_listview
+ GtkWidget *listview = lookup_widget (prefwin, "dsp_listview");
+
+
+ GtkCellRenderer *title_cell = gtk_cell_renderer_text_new ();
+ GtkTreeViewColumn *col = gtk_tree_view_column_new_with_attributes (_("Plugin"), title_cell, "text", 0, NULL);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (listview), GTK_TREE_VIEW_COLUMN (col));
+ GtkListStore *mdl = gtk_list_store_new (1, G_TYPE_STRING);
+ gtk_tree_view_set_model (GTK_TREE_VIEW (listview), GTK_TREE_MODEL (mdl));
+
+ fill_dsp_chain (mdl);
+
+ // set last preset name
+ GtkWidget *combobox = lookup_widget (prefwin, "dsp_preset");
+ GtkWidget *entry = gtk_bin_get_child (GTK_BIN (combobox));
+ if (entry) {
+ deadbeef->conf_lock ();
+ gtk_entry_set_text (GTK_ENTRY (entry), deadbeef->conf_get_str_fast ("gtkui.conf_dsp_preset", ""));
+ deadbeef->conf_unlock ();
+ }
+
+ // fill list of presets
+ mdl = GTK_LIST_STORE (gtk_combo_box_get_model (GTK_COMBO_BOX (combobox)));
+ struct dirent **namelist = NULL;
+ char path[1024];
+ if (snprintf (path, sizeof (path), "%s/presets/dsp", deadbeef->get_config_dir ()) > 0) {
+ int n = scandir (path, &namelist, scandir_preset_filter, dirent_alphasort);
+ int i;
+ for (i = 0; i < n; i++) {
+ char title[100];
+ strcpy (title, namelist[i]->d_name);
+ char *e = strrchr (title, '.');
+ if (e) {
+ *e = 0;
+ }
+ GtkTreeIter iter;
+ gtk_list_store_append (mdl, &iter);
+ gtk_list_store_set (mdl, &iter, 0, title, -1);
+ free (namelist[i]);
+ }
+ free (namelist);
+ }
+}
+
+void
+dsp_setup_free (void) {
+ while (chain) {
+ ddb_dsp_context_t *next = chain->next;
+ chain->plugin->close (chain);
+ chain = next;
+ }
+ prefwin = NULL;
+}
+
+static void
+fill_dsp_plugin_list (GtkListStore *mdl) {
+ struct DB_dsp_s **dsp = deadbeef->plug_get_dsp_list ();
+ int i;
+ for (i = 0; dsp[i]; i++) {
+ GtkTreeIter iter;
+ gtk_list_store_append (mdl, &iter);
+ gtk_list_store_set (mdl, &iter, 0, dsp[i]->plugin.name, -1);
+ }
+}
+
+static void
+update_streamer (void) {
+ deadbeef->streamer_set_dsp_chain (chain);
+}
+
+void
+on_dsp_add_clicked (GtkButton *button,
+ gpointer user_data)
+{
+ GtkWidget *dlg = create_select_dsp_plugin ();
+ gtk_dialog_set_default_response (GTK_DIALOG (dlg), GTK_RESPONSE_OK);
+ gtk_window_set_transient_for (GTK_WINDOW (dlg), GTK_WINDOW (prefwin));
+ gtk_window_set_title (GTK_WINDOW (dlg), _("Add plugin to DSP chain"));
+
+ GtkComboBox *combo;
+ // fill encoder presets
+ combo = GTK_COMBO_BOX (lookup_widget (dlg, "plugin"));
+ GtkListStore *mdl = GTK_LIST_STORE (gtk_combo_box_get_model (combo));
+ fill_dsp_plugin_list (mdl);
+ gtk_combo_box_set_active (combo, deadbeef->conf_get_int ("converter.last_selected_dsp", 0));
+
+ int r = gtk_dialog_run (GTK_DIALOG (dlg));
+ if (r == GTK_RESPONSE_OK) {
+ // create new instance of the selected plugin
+ int idx = gtk_combo_box_get_active (combo);
+ struct DB_dsp_s **dsp = deadbeef->plug_get_dsp_list ();
+ int i;
+ ddb_dsp_context_t *inst = NULL;
+ for (i = 0; dsp[i]; i++) {
+ if (i == idx) {
+ inst = dsp[i]->open ();
+ break;
+ }
+ }
+ if (inst) {
+ // append to DSP chain
+ ddb_dsp_context_t *tail = chain;
+ while (tail && tail->next) {
+ tail = tail->next;
+ }
+ if (tail) {
+ tail->next = inst;
+ }
+ else {
+ chain = inst;
+ }
+
+ // reinit list of instances
+ GtkWidget *list = lookup_widget (prefwin, "dsp_listview");
+ GtkListStore *mdl = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW(list)));
+ gtk_list_store_clear (mdl);
+ fill_dsp_chain (mdl);
+ update_streamer ();
+ }
+ else {
+ fprintf (stderr, "prefwin: failed to add DSP plugin to chain\n");
+ }
+ }
+ gtk_widget_destroy (dlg);
+}
+
+static int
+listview_get_index (GtkWidget *list) {
+ GtkTreePath *path;
+ GtkTreeViewColumn *col;
+ gtk_tree_view_get_cursor (GTK_TREE_VIEW (list), &path, &col);
+ if (!path || !col) {
+ // nothing selected
+ return - 1;
+ }
+ int *indices = gtk_tree_path_get_indices (path);
+ int idx = *indices;
+ g_free (indices);
+ return idx;
+}
+
+void
+on_dsp_remove_clicked (GtkButton *button,
+ gpointer user_data)
+{
+ GtkWidget *list = lookup_widget (prefwin, "dsp_listview");
+ int idx = listview_get_index (list);
+ if (idx == -1) {
+ return;
+ }
+
+ ddb_dsp_context_t *p = chain;
+ ddb_dsp_context_t *prev = NULL;
+ int i = idx;
+ while (p && i--) {
+ prev = p;
+ p = p->next;
+ }
+ if (p) {
+ if (prev) {
+ prev->next = p->next;
+ }
+ else {
+ chain = p->next;
+ }
+ p->plugin->close (p);
+ GtkListStore *mdl = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW(list)));
+ gtk_list_store_clear (mdl);
+ fill_dsp_chain (mdl);
+ GtkTreePath *path = gtk_tree_path_new_from_indices (idx, -1);
+ GtkTreeViewColumn *col;
+ gtk_tree_view_set_cursor (GTK_TREE_VIEW (list), path, col, FALSE);
+ gtk_tree_path_free (path);
+ update_streamer ();
+ }
+}
+
+static ddb_dsp_context_t *current_dsp_context = NULL;
+
+void
+dsp_ctx_set_param (const char *key, const char *value) {
+ current_dsp_context->plugin->set_param (current_dsp_context, atoi (key), value);
+}
+
+void
+dsp_ctx_get_param (const char *key, char *value, int len, const char *def) {
+ strncpy (value, def, len);
+ current_dsp_context->plugin->get_param (current_dsp_context, atoi (key), value, len);
+}
+
+int
+button_cb (int btn, void *ctx) {
+ if (btn == ddb_button_apply) {
+ update_streamer ();
+ }
+ return 1;
+}
+
+void
+on_dsp_configure_clicked (GtkButton *button,
+ gpointer user_data)
+{
+ GtkWidget *list = lookup_widget (prefwin, "dsp_listview");
+ GtkTreePath *path;
+ GtkTreeViewColumn *col;
+ gtk_tree_view_get_cursor (GTK_TREE_VIEW (list), &path, &col);
+ if (!path || !col) {
+ // nothing selected
+ return;
+ }
+ int *indices = gtk_tree_path_get_indices (path);
+ int idx = *indices;
+ g_free (indices);
+ if (idx == -1) {
+ return;
+ }
+ ddb_dsp_context_t *p = chain;
+ int i = idx;
+ while (p && i--) {
+ p = p->next;
+ }
+ if (!p || !p->plugin->configdialog) {
+ return;
+ }
+ current_dsp_context = p;
+ ddb_dialog_t conf = {
+ .title = p->plugin->plugin.name,
+ .layout = p->plugin->configdialog,
+ .set_param = dsp_ctx_set_param,
+ .get_param = dsp_ctx_get_param,
+ };
+ int response = gtkui_run_dialog (prefwin, &conf, 0, button_cb, NULL);
+ if (response == ddb_button_ok) {
+ update_streamer ();
+ }
+ current_dsp_context = NULL;
+}
+
+static int
+swap_items (GtkWidget *list, int idx) {
+ ddb_dsp_context_t *prev = NULL;
+ ddb_dsp_context_t *p = chain;
+
+ int n = idx;
+ while (n > 0 && p) {
+ prev = p;
+ p = p->next;
+ n--;
+ }
+
+ if (!p || !p->next) {
+ return -1;
+ }
+
+ ddb_dsp_context_t *moved = p->next;
+
+ if (!moved) {
+ return -1;
+ }
+
+ ddb_dsp_context_t *last = moved ? moved->next : NULL;
+
+ if (prev) {
+ p->next = last;
+ prev->next = moved;
+ moved->next = p;
+ }
+ else {
+ p->next = last;
+ chain = moved;
+ moved->next = p;
+ }
+ GtkListStore *mdl = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW(list)));
+ gtk_list_store_clear (mdl);
+ fill_dsp_chain (mdl);
+ return 0;
+}
+
+
+void
+on_dsp_up_clicked (GtkButton *button,
+ gpointer user_data)
+{
+ GtkWidget *list = lookup_widget (prefwin, "dsp_listview");
+ int idx = listview_get_index (list);
+ if (idx <= 0) {
+ return;
+ }
+
+ if (-1 == swap_items (list, idx-1)) {
+ return;
+ }
+ GtkTreePath *path = gtk_tree_path_new_from_indices (idx-1, -1);
+ GtkTreeViewColumn *col;
+ gtk_tree_view_set_cursor (GTK_TREE_VIEW (list), path, col, FALSE);
+ gtk_tree_path_free (path);
+ update_streamer ();
+}
+
+
+void
+on_dsp_down_clicked (GtkButton *button,
+ gpointer user_data)
+{
+ GtkWidget *list = lookup_widget (prefwin, "dsp_listview");
+ int idx = listview_get_index (list);
+ if (idx == -1) {
+ return;
+ }
+
+ if (-1 == swap_items (list, idx)) {
+ return;
+ }
+ GtkTreePath *path = gtk_tree_path_new_from_indices (idx+1, -1);
+ GtkTreeViewColumn *col;
+ gtk_tree_view_set_cursor (GTK_TREE_VIEW (list), path, col, FALSE);
+ gtk_tree_path_free (path);
+ update_streamer ();
+}
+
+void
+on_dsp_preset_changed (GtkComboBox *combobox,
+ gpointer user_data)
+{
+ GtkWidget *entry = gtk_bin_get_child (GTK_BIN (combobox));
+ if (entry) {
+ deadbeef->conf_set_str ("gtkui.conf_dsp_preset", gtk_entry_get_text (GTK_ENTRY (entry)));
+ }
+}
+
+
+void
+on_dsp_preset_save_clicked (GtkButton *button,
+ gpointer user_data)
+{
+ const char *confdir = deadbeef->get_config_dir ();
+ char path[1024];
+ if (snprintf (path, sizeof (path), "%s/presets", confdir) < 0) {
+ return;
+ }
+ mkdir (path, 0755);
+ if (snprintf (path, sizeof (path), "%s/presets/dsp", confdir) < 0) {
+ return;
+ }
+ GtkWidget *combobox = lookup_widget (prefwin, "dsp_preset");
+ GtkWidget *entry = gtk_bin_get_child (GTK_BIN (combobox));
+ if (!entry) {
+ return;
+ }
+
+ const char *text = gtk_entry_get_text (GTK_ENTRY (entry));
+ mkdir (path, 0755);
+ if (snprintf (path, sizeof (path), "%s/presets/dsp/%s.txt", confdir, text) < 0) {
+ return;
+ }
+ deadbeef->dsp_preset_save (path, chain);
+}
+
+
+void
+on_dsp_preset_load_clicked (GtkButton *button,
+ gpointer user_data)
+{
+ GtkWidget *combobox = lookup_widget (prefwin, "dsp_preset");
+ GtkWidget *entry = gtk_bin_get_child (GTK_BIN (combobox));
+ if (entry) {
+ const char *text = gtk_entry_get_text (GTK_ENTRY (entry));
+ char path[PATH_MAX];
+ if (snprintf (path, sizeof (path), "%s/presets/dsp/%s.txt", deadbeef->get_config_dir (), text) > 0) {
+ ddb_dsp_context_t *new_chain = NULL;
+ int res = deadbeef->dsp_preset_load (path, &new_chain);
+ if (!res) {
+ deadbeef->dsp_preset_free (chain);
+ chain = new_chain;
+ GtkWidget *list = lookup_widget (prefwin, "dsp_listview");
+ GtkListStore *mdl = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW(list)));
+ gtk_list_store_clear (mdl);
+ fill_dsp_chain (mdl);
+ update_streamer ();
+ }
+ }
+ }
+}
+
diff --git a/plugins/gtkui/dspconfig.h b/plugins/gtkui/dspconfig.h
new file mode 100644
index 00000000..6b7f5310
--- /dev/null
+++ b/plugins/gtkui/dspconfig.h
@@ -0,0 +1,29 @@
+/*
+ DeaDBeeF - ultimate music player for GNU/Linux systems with X11
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+#ifndef __DSPCONFIG_H
+#define __DSPCONFIG_H
+
+void
+dsp_setup_init (GtkWidget *prefwin);
+
+void
+dsp_setup_free (void);
+
+#endif
+
diff --git a/plugins/gtkui/eq.c b/plugins/gtkui/eq.c
index 93f92af5..bfb77703 100644
--- a/plugins/gtkui/eq.c
+++ b/plugins/gtkui/eq.c
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@@ -22,7 +22,6 @@
#include <stdlib.h>
#include "gtkui.h"
#include "support.h"
-#include "../supereq/supereq.h"
#include "ddbequalizer.h"
static GtkWidget *eqcont;
@@ -40,46 +39,66 @@ amp_to_db (float amp) {
return 20*log10 (amp);
}
-DB_supereq_dsp_t *
-get_supereq_plugin (void) {
- DB_dsp_t **plugs = deadbeef->plug_get_dsp_list ();
- for (int i = 0; plugs[i]; i++) {
- if (plugs[i]->plugin.id && !strcmp (plugs[i]->plugin.id, "supereq")) {
- return (DB_supereq_dsp_t *)plugs[i];
+ddb_dsp_context_t *
+get_supereq (void) {
+ ddb_dsp_context_t *dsp = deadbeef->streamer_get_dsp_chain ();
+ while (dsp) {
+ if (!strcmp (dsp->plugin->plugin.id, "supereq")) {
+ return dsp;
}
+ dsp = dsp->next;
}
+
return NULL;
}
+static void
+set_param (ddb_dsp_context_t *eq, int i, float v) {
+ char fv[100];
+ snprintf (fv, sizeof (fv), "%f", v);
+ eq->plugin->set_param (eq, i, fv);
+}
+
void
eq_value_changed (DdbEqualizer *widget)
{
- DB_supereq_dsp_t *eq = get_supereq_plugin ();
- for (int i = 0; i < 18; i++) {
- eq->set_band (i, db_to_amp (ddb_equalizer_get_band (widget, i)));
+ ddb_dsp_context_t *eq = get_supereq ();
+ if (eq) {
+ for (int i = 0; i < 18; i++) {
+ set_param (eq, i+1, ddb_equalizer_get_band (widget, i));
+ }
+ set_param (eq, 0, ddb_equalizer_get_preamp (widget));
}
- eq->set_preamp (db_to_amp (ddb_equalizer_get_preamp (widget)));
}
void
on_enable_toggled (GtkToggleButton *togglebutton,
gpointer user_data) {
- DB_supereq_dsp_t *eq = get_supereq_plugin ();
- eq->dsp.enable (gtk_toggle_button_get_active (togglebutton));
+ ddb_dsp_context_t *eq = get_supereq ();
+ if (eq) {
+ int enabled = gtk_toggle_button_get_active (togglebutton) ? 1 : 0;
+ eq->enabled = enabled;
+ deadbeef->streamer_dsp_refresh ();
+ }
}
void
on_zero_all_clicked (GtkButton *button,
gpointer user_data) {
if (eqwin) {
- DB_supereq_dsp_t *eq = get_supereq_plugin ();
- eq->set_preamp (1);
- ddb_equalizer_set_preamp (DDB_EQUALIZER (eqwin), 0);
- for (int i = 0; i < 18; i++) {
- ddb_equalizer_set_band (DDB_EQUALIZER (eqwin), i, 0);
- eq->set_band (i, 1);
+ ddb_dsp_context_t *eq = get_supereq ();
+ if (eq) {
+ ddb_equalizer_set_preamp (DDB_EQUALIZER (eqwin), 0);
+ set_param (eq, 0, 0);
+ for (int i = 0; i < 18; i++) {
+ // set gui
+ ddb_equalizer_set_band (DDB_EQUALIZER (eqwin), i, 0);
+
+ // set dsp
+ set_param (eq, i+1, 0);
+ }
+ gdk_window_invalidate_rect (eqwin->window, NULL, FALSE);
}
- gdk_window_invalidate_rect (eqwin->window, NULL, FALSE);
}
}
@@ -87,10 +106,12 @@ void
on_zero_preamp_clicked (GtkButton *button,
gpointer user_data) {
if (eqwin) {
- DB_supereq_dsp_t *eq = get_supereq_plugin ();
- eq->set_preamp (1);
- ddb_equalizer_set_preamp (DDB_EQUALIZER (eqwin), 0);
- gdk_window_invalidate_rect (eqwin->window, NULL, FALSE);
+ ddb_dsp_context_t *eq = get_supereq ();
+ if (eq) {
+ set_param (eq, 0, 0);
+ ddb_equalizer_set_preamp (DDB_EQUALIZER (eqwin), 0);
+ gdk_window_invalidate_rect (eqwin->window, NULL, FALSE);
+ }
}
}
@@ -98,17 +119,19 @@ void
on_zero_bands_clicked (GtkButton *button,
gpointer user_data) {
if (eqwin) {
- DB_supereq_dsp_t *eq = get_supereq_plugin ();
- for (int i = 0; i < 18; i++) {
- ddb_equalizer_set_band (DDB_EQUALIZER (eqwin), i, 0);
- eq->set_band (i, 1);
+ ddb_dsp_context_t *eq = get_supereq ();
+ if (eq) {
+ for (int i = 0; i < 18; i++) {
+ ddb_equalizer_set_band (DDB_EQUALIZER (eqwin), i, 0);
+ set_param (eq, i+1, 0);
+ }
+ gdk_window_invalidate_rect (eqwin->window, NULL, FALSE);
}
- gdk_window_invalidate_rect (eqwin->window, NULL, FALSE);
}
}
void
-on_save_preset_clicked (GtkButton *button,
+on_save_preset_clicked (GtkMenuItem *menuitem,
gpointer user_data) {
GtkWidget *dlg = gtk_file_chooser_dialog_new (_("Save DeaDBeeF EQ Preset"), GTK_WINDOW (mainwin), GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, GTK_RESPONSE_OK, NULL);
@@ -130,11 +153,19 @@ on_save_preset_clicked (GtkButton *button,
if (fname) {
FILE *fp = fopen (fname, "w+b");
if (fp) {
- DB_supereq_dsp_t *eq = get_supereq_plugin ();
- for (int i = 0; i < 18; i++) {
- fprintf (fp, "%f\n", amp_to_db (eq->get_band (i)));
+ ddb_dsp_context_t *eq = get_supereq ();
+ if (eq) {
+ char fv[100];
+ float v;
+ for (int i = 0; i < 18; i++) {
+ eq->plugin->get_param (eq, i+1, fv, sizeof (fv));
+ v = atof (fv);
+ fprintf (fp, "%f\n", v);
+ }
+ eq->plugin->get_param (eq, 0, fv, sizeof (fv));
+ v = atof (fv);
+ fprintf (fp, "%f\n", v);
}
- fprintf (fp, "%f\n", amp_to_db (eq->get_preamp ()));
fclose (fp);
}
g_free (fname);
@@ -146,7 +177,7 @@ on_save_preset_clicked (GtkButton *button,
}
void
-on_load_preset_clicked (GtkButton *button,
+on_load_preset_clicked (GtkMenuItem *menuitem,
gpointer user_data) {
GtkWidget *dlg = gtk_file_chooser_dialog_new (_("Load DeaDBeeF EQ Preset..."), GTK_WINDOW (mainwin), GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_OK, NULL);
@@ -158,7 +189,9 @@ on_load_preset_clicked (GtkButton *button,
gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dlg), FALSE);
// restore folder
- gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER (dlg), deadbeef->conf_get_str ("filechooser.lastdir", ""));
+ deadbeef->conf_lock ();
+ gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER (dlg), deadbeef->conf_get_str_fast ("filechooser.lastdir", ""));
+ deadbeef->conf_unlock ();
int response = gtk_dialog_run (GTK_DIALOG (dlg));
// store folder
gchar *folder = gtk_file_chooser_get_current_folder_uri (GTK_FILE_CHOOSER (dlg));
@@ -186,13 +219,13 @@ on_load_preset_clicked (GtkButton *button,
fclose (fp);
if (i == 19) {
// apply and save config
- DB_supereq_dsp_t *eq = get_supereq_plugin ();
+ ddb_dsp_context_t *eq = get_supereq ();
if (eq) {
- eq->set_preamp (db_to_amp (vals[18]));
+ set_param (eq, 0, vals[18]);
ddb_equalizer_set_preamp (DDB_EQUALIZER (eqwin), vals[18]);
for (int i = 0; i < 18; i++) {
ddb_equalizer_set_band (DDB_EQUALIZER (eqwin), i, vals[i]);
- eq->set_band (i, db_to_amp (vals[i]));
+ set_param (eq, i+1, vals[i]);
}
gdk_window_invalidate_rect (eqwin->window, NULL, FALSE);
deadbeef->conf_save ();
@@ -221,7 +254,10 @@ on_import_fb2k_preset_clicked (GtkButton *button,
gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dlg), FALSE);
// restore folder
- gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER (dlg), deadbeef->conf_get_str ("filechooser.lastdir", ""));
+ deadbeef->conf_lock ();
+ gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER (dlg), deadbeef->conf_get_str_fast ("filechooser.lastdir", ""));
+ deadbeef->conf_unlock ();
+
int response = gtk_dialog_run (GTK_DIALOG (dlg));
// store folder
gchar *folder = gtk_file_chooser_get_current_folder_uri (GTK_FILE_CHOOSER (dlg));
@@ -249,13 +285,13 @@ on_import_fb2k_preset_clicked (GtkButton *button,
fclose (fp);
if (i == 18) {
// apply and save config
- DB_supereq_dsp_t *eq = get_supereq_plugin ();
+ ddb_dsp_context_t *eq = get_supereq ();
if (eq) {
- eq->set_preamp (1);
+ set_param (eq, 0, 0);
ddb_equalizer_set_preamp (DDB_EQUALIZER (eqwin), 0);
for (int i = 0; i < 18; i++) {
- ddb_equalizer_set_band (DDB_EQUALIZER (eqwin), i, vals[i]);
- eq->set_band (i, db_to_amp (vals[i]));
+ ddb_equalizer_set_band (DDB_EQUALIZER (eqwin), i, amp_to_db (vals[i]));
+ set_param (eq, i+1, amp_to_db (vals[i]));
}
gdk_window_invalidate_rect (eqwin->window, NULL, FALSE);
deadbeef->conf_save ();
@@ -272,11 +308,40 @@ on_import_fb2k_preset_clicked (GtkButton *button,
}
void
+on_presets_clicked (GtkButton *button,
+ gpointer user_data) {
+ GtkWidget *menu = gtk_menu_new ();
+ GtkWidget *menuitem;
+
+ menuitem = gtk_menu_item_new_with_mnemonic (_("Save Preset"));
+ gtk_widget_show (menuitem);
+ gtk_container_add (GTK_CONTAINER (menu), menuitem);
+
+ g_signal_connect ((gpointer) menuitem, "activate",
+ G_CALLBACK (on_save_preset_clicked),
+ NULL);
+
+ menuitem = gtk_menu_item_new_with_mnemonic (_("Load Preset"));
+ gtk_widget_show (menuitem);
+ gtk_container_add (GTK_CONTAINER (menu), menuitem);
+
+ g_signal_connect ((gpointer) menuitem, "activate",
+ G_CALLBACK (on_load_preset_clicked),
+ NULL);
+
+ menuitem = gtk_menu_item_new_with_mnemonic (_("Import Foobar2000 Preset"));
+ gtk_widget_show (menuitem);
+ gtk_container_add (GTK_CONTAINER (menu), menuitem);
+
+ g_signal_connect ((gpointer) menuitem, "activate",
+ G_CALLBACK (on_import_fb2k_preset_clicked),
+ NULL);
+
+ gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, 0, gtk_get_current_event_time());
+}
+
+void
eq_window_show (void) {
- DB_supereq_dsp_t *eq = get_supereq_plugin ();
- if (!eq) {
- return;
- }
if (!eqcont) {
eqcont = gtk_vbox_new (FALSE, 8);
GtkWidget *parent= lookup_widget (mainwin, "plugins_bottom_vbox");
@@ -292,7 +357,8 @@ eq_window_show (void) {
eqenablebtn = button = gtk_check_button_new_with_label (_("Enable"));
gtk_widget_show (button);
gtk_box_pack_start (GTK_BOX (buttons), button, FALSE, FALSE, 0);
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (eqenablebtn), deadbeef->conf_get_int ("supereq.enable", 0));
+ ddb_dsp_context_t *eq = get_supereq ();
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (eqenablebtn), eq ? eq->enabled : 0);
g_signal_connect ((gpointer) button, "toggled",
G_CALLBACK (on_enable_toggled),
NULL);
@@ -318,37 +384,29 @@ eq_window_show (void) {
G_CALLBACK (on_zero_bands_clicked),
NULL);
- button = gtk_button_new_with_label (_("Save Preset"));
+ button = gtk_button_new_with_label (_("Presets"));
gtk_widget_show (button);
gtk_box_pack_start (GTK_BOX (buttons), button, FALSE, FALSE, 0);
g_signal_connect ((gpointer) button, "clicked",
- G_CALLBACK (on_save_preset_clicked),
- NULL);
-
- button = gtk_button_new_with_label (_("Load Preset"));
- gtk_widget_show (button);
- gtk_box_pack_start (GTK_BOX (buttons), button, FALSE, FALSE, 0);
- g_signal_connect ((gpointer) button, "clicked",
- G_CALLBACK (on_load_preset_clicked),
- NULL);
-
- button = gtk_button_new_with_label (_("Import Foobar2000 Preset"));
- gtk_widget_show (button);
- gtk_box_pack_start (GTK_BOX (buttons), button, FALSE, FALSE, 0);
- g_signal_connect ((gpointer) button, "clicked",
- G_CALLBACK (on_import_fb2k_preset_clicked),
+ G_CALLBACK (on_presets_clicked),
NULL);
eqwin = GTK_WIDGET (ddb_equalizer_new());
g_signal_connect (eqwin, "on_changed", G_CALLBACK (eq_value_changed), 0);
gtk_widget_set_size_request (eqwin, -1, 200);
-
- ddb_equalizer_set_preamp (DDB_EQUALIZER (eqwin), amp_to_db (eq->get_preamp ()));
- for (int i = 0; i < 18; i++) {
- if (eq) {
- float val = eq->get_band (i);
- ddb_equalizer_set_band (DDB_EQUALIZER (eqwin), i, amp_to_db (val));
+ if (eq) {
+ char fv[100];
+ float v;
+ eq->plugin->get_param (eq, 0, fv, sizeof (fv));
+ v = atof (fv);
+ ddb_equalizer_set_preamp (DDB_EQUALIZER (eqwin), v);
+ for (int i = 0; i < 18; i++) {
+ if (eq) {
+ eq->plugin->get_param (eq, i+1, fv, sizeof (fv));
+ v = atof (fv);
+ ddb_equalizer_set_band (DDB_EQUALIZER (eqwin), i, v);
+ }
}
}
diff --git a/plugins/gtkui/eq.h b/plugins/gtkui/eq.h
index 9e54916e..570cd935 100644
--- a/plugins/gtkui/eq.h
+++ b/plugins/gtkui/eq.h
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@@ -29,8 +29,8 @@ eq_window_hide (void);
void
eq_window_destroy (void);
-struct DB_supereq_dsp_s *
-get_supereq_plugin (void);
+ddb_dsp_context_t *
+get_supereq (void);
void
eq_redraw (void);
diff --git a/plugins/gtkui/fileman.c b/plugins/gtkui/fileman.c
index 3f58bb09..d33764c0 100644
--- a/plugins/gtkui/fileman.c
+++ b/plugins/gtkui/fileman.c
@@ -2,6 +2,7 @@
#include <gtk/gtk.h>
#include <stdlib.h>
#include <ctype.h>
+#include <string.h>
#include "gtkui.h"
#include "ddblistview.h"
#include "progress.h"
@@ -9,10 +10,8 @@
void
gtkpl_add_dir (DdbListview *ps, char *folder) {
- g_idle_add (gtkui_progress_show_idle, NULL);
gtkui_original_pl_add_dir (folder, gtkui_add_file_info_cb, NULL);
g_free (folder);
- g_idle_add (gtkui_progress_hide_idle, NULL);
}
static void
@@ -23,10 +22,30 @@ gtkpl_adddir_cb (gpointer data, gpointer userdata) {
void
gtkpl_add_dirs (GSList *lst) {
- g_idle_add (gtkui_progress_show_idle, NULL);
+ deadbeef->plt_lock ();
+ deadbeef->pl_add_files_begin (deadbeef->plt_get_curr ());
+ if (g_slist_length (lst) == 1
+ && deadbeef->conf_get_int ("gtkui.name_playlist_from_folder", 0)) {
+ int plt = deadbeef->plt_get_curr ();
+ if (plt != -1) {
+ void *p = deadbeef->plt_get_handle (plt);
+ char t[1000];
+ if (!deadbeef->plt_get_title (p, t, sizeof (t))) {
+ char *def = _("New Playlist");
+ if (!strncmp (t, def, strlen (def))) {
+ const char *folder = strrchr ((char*)lst->data, '/');
+ if (!folder) {
+ folder = lst->data;
+ }
+ deadbeef->plt_set_title (p, folder+1);
+ }
+ }
+ }
+ }
+ deadbeef->plt_unlock ();
g_slist_foreach(lst, gtkpl_adddir_cb, NULL);
g_slist_free (lst);
- g_idle_add (gtkui_progress_hide_idle, NULL);
+ deadbeef->pl_add_files_end ();
}
static void
@@ -37,10 +56,10 @@ gtkpl_addfile_cb (gpointer data, gpointer userdata) {
void
gtkpl_add_files (GSList *lst) {
- g_idle_add (gtkui_progress_show_idle, NULL);
+ deadbeef->pl_add_files_begin (deadbeef->plt_get_curr ());
g_slist_foreach(lst, gtkpl_addfile_cb, NULL);
g_slist_free (lst);
- g_idle_add (gtkui_progress_hide_idle, NULL);
+ deadbeef->pl_add_files_end ();
}
static void
@@ -51,7 +70,8 @@ add_dirs_worker (void *data) {
void
gtkui_add_dirs (GSList *lst) {
- deadbeef->thread_start (add_dirs_worker, lst);
+ intptr_t tid = deadbeef->thread_start (add_dirs_worker, lst);
+ deadbeef->thread_detach (tid);
}
static void
@@ -62,7 +82,9 @@ add_files_worker (void *data) {
void
gtkui_add_files (struct _GSList *lst) {
- deadbeef->thread_start (add_files_worker, lst);
+ deadbeef->pl_add_files_begin (deadbeef->plt_get_curr ());
+ intptr_t tid = deadbeef->thread_start (add_files_worker, lst);
+ deadbeef->thread_detach (tid);
}
static void
@@ -73,14 +95,16 @@ open_files_worker (void *data) {
extern GtkWidget *mainwin;
DdbListview *pl = DDB_LISTVIEW (lookup_widget (mainwin, "playlist"));
ddb_listview_set_cursor (pl, 0);
- deadbeef->sendmessage (M_PLAYSONG, 0, 1, 0);
+ deadbeef->sendmessage (M_PLAY_CURRENT, 0, 1, 0);
}
void
gtkui_open_files (struct _GSList *lst) {
deadbeef->pl_clear ();
playlist_refresh ();
- deadbeef->thread_start (open_files_worker, lst);
+
+ intptr_t tid = deadbeef->thread_start (open_files_worker, lst);
+ deadbeef->thread_detach (tid);
}
void
@@ -140,7 +164,7 @@ set_dnd_cursor_idle (gpointer data) {
void
gtkpl_add_fm_dropped_files (DB_playItem_t *drop_before, char *ptr, int length) {
DdbListview *pl = DDB_LISTVIEW (lookup_widget (mainwin, "playlist"));
- g_idle_add (gtkui_progress_show_idle, NULL);
+ deadbeef->pl_add_files_begin (deadbeef->plt_get_curr ());
DdbListviewIter first = NULL;
DdbListviewIter after = NULL;
@@ -188,7 +212,7 @@ gtkpl_add_fm_dropped_files (DB_playItem_t *drop_before, char *ptr, int length) {
}
free (ptr);
- g_idle_add (gtkui_progress_hide_idle, NULL);
+ deadbeef->pl_add_files_end ();
g_idle_add (set_dnd_cursor_idle, first);
}
@@ -222,5 +246,6 @@ gtkui_receive_fm_drop (DB_playItem_t *before, char *mem, int length) {
}
data->drop_before = before;
// since it happens in separate thread, we need to addref
- deadbeef->thread_start (fmdrop_worker, data);
+ intptr_t tid = deadbeef->thread_start (fmdrop_worker, data);
+ deadbeef->thread_detach (tid);
}
diff --git a/plugins/gtkui/gdkdrawing.c b/plugins/gtkui/gdkdrawing.c
index c7c2339b..cb795ccb 100644
--- a/plugins/gtkui/gdkdrawing.c
+++ b/plugins/gtkui/gdkdrawing.c
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@@ -197,6 +197,7 @@ static GdkColor gtkui_tabstrip_dark_color;
static GdkColor gtkui_tabstrip_mid_color;
static GdkColor gtkui_tabstrip_light_color;
static GdkColor gtkui_tabstrip_base_color;
+static GdkColor gtkui_tabstrip_text_color;
static GdkColor gtkui_listview_even_row_color;
static GdkColor gtkui_listview_odd_row_color;
@@ -226,6 +227,7 @@ gtkui_override_tabstrip_colors (void) {
void
gtkui_init_theme_colors (void) {
+ deadbeef->conf_lock ();
override_listview_colors= deadbeef->conf_get_int ("gtkui.override_listview_colors", 0);
override_bar_colors = deadbeef->conf_get_int ("gtkui.override_bar_colors", 0);
override_tabstrip_colors = deadbeef->conf_get_int ("gtkui.override_tabstrip_colors", 0);
@@ -241,11 +243,11 @@ gtkui_init_theme_colors (void) {
}
else {
snprintf (color_text, sizeof (color_text), "%hd %hd %hd", style->base[GTK_STATE_SELECTED].red, style->base[GTK_STATE_SELECTED].green, style->base[GTK_STATE_SELECTED].blue);
- clr = deadbeef->conf_get_str ("gtkui.color.bar_foreground", color_text);
+ clr = deadbeef->conf_get_str_fast ("gtkui.color.bar_foreground", color_text);
sscanf (clr, "%hd %hd %hd", &gtkui_bar_foreground_color.red, &gtkui_bar_foreground_color.green, &gtkui_bar_foreground_color.blue);
snprintf (color_text, sizeof (color_text), "%hd %hd %hd", style->fg[GTK_STATE_NORMAL].red, style->fg[GTK_STATE_NORMAL].green, style->fg[GTK_STATE_NORMAL].blue);
- clr = deadbeef->conf_get_str ("gtkui.color.bar_background", color_text);
+ clr = deadbeef->conf_get_str_fast ("gtkui.color.bar_background", color_text);
sscanf (clr, "%hd %hd %hd", &gtkui_bar_background_color.red, &gtkui_bar_background_color.green, &gtkui_bar_background_color.blue);
}
@@ -255,23 +257,28 @@ gtkui_init_theme_colors (void) {
memcpy (&gtkui_tabstrip_mid_color, &style->mid[GTK_STATE_NORMAL], sizeof (GdkColor));
memcpy (&gtkui_tabstrip_light_color, &style->light[GTK_STATE_NORMAL], sizeof (GdkColor));
memcpy (&gtkui_tabstrip_base_color, &style->bg[GTK_STATE_NORMAL], sizeof (GdkColor));
+ memcpy (&gtkui_tabstrip_text_color, &style->text[GTK_STATE_NORMAL], sizeof (GdkColor));
}
else {
snprintf (color_text, sizeof (color_text), "%hd %hd %hd", style->dark[GTK_STATE_NORMAL].red, style->dark[GTK_STATE_NORMAL].green, style->dark[GTK_STATE_NORMAL].blue);
- clr = deadbeef->conf_get_str ("gtkui.color.tabstrip_dark", color_text);
+ clr = deadbeef->conf_get_str_fast ("gtkui.color.tabstrip_dark", color_text);
sscanf (clr, "%hd %hd %hd", &gtkui_tabstrip_dark_color.red, &gtkui_tabstrip_dark_color.green, &gtkui_tabstrip_dark_color.blue);
snprintf (color_text, sizeof (color_text), "%hd %hd %hd", style->mid[GTK_STATE_NORMAL].red, style->mid[GTK_STATE_NORMAL].green, style->mid[GTK_STATE_NORMAL].blue);
- clr = deadbeef->conf_get_str ("gtkui.color.tabstrip_mid", color_text);
+ clr = deadbeef->conf_get_str_fast ("gtkui.color.tabstrip_mid", color_text);
sscanf (clr, "%hd %hd %hd", &gtkui_tabstrip_mid_color.red, &gtkui_tabstrip_mid_color.green, &gtkui_tabstrip_mid_color.blue);
snprintf (color_text, sizeof (color_text), "%hd %hd %hd", style->light[GTK_STATE_NORMAL].red, style->light[GTK_STATE_NORMAL].green, style->light[GTK_STATE_NORMAL].blue);
- clr = deadbeef->conf_get_str ("gtkui.color.tabstrip_light", color_text);
+ clr = deadbeef->conf_get_str_fast ("gtkui.color.tabstrip_light", color_text);
sscanf (clr, "%hd %hd %hd", &gtkui_tabstrip_light_color.red, &gtkui_tabstrip_light_color.green, &gtkui_tabstrip_light_color.blue);
snprintf (color_text, sizeof (color_text), "%hd %hd %hd", style->bg[GTK_STATE_NORMAL].red, style->bg[GTK_STATE_NORMAL].green, style->bg[GTK_STATE_NORMAL].blue);
- clr = deadbeef->conf_get_str ("gtkui.color.tabstrip_base", color_text);
+ clr = deadbeef->conf_get_str_fast ("gtkui.color.tabstrip_base", color_text);
sscanf (clr, "%hd %hd %hd", &gtkui_tabstrip_base_color.red, &gtkui_tabstrip_base_color.green, &gtkui_tabstrip_base_color.blue);
+
+ snprintf (color_text, sizeof (color_text), "%hd %hd %hd", style->text[GTK_STATE_NORMAL].red, style->text[GTK_STATE_NORMAL].green, style->text[GTK_STATE_NORMAL].blue);
+ clr = deadbeef->conf_get_str_fast ("gtkui.color.tabstrip_text", color_text);
+ sscanf (clr, "%hd %hd %hd", &gtkui_tabstrip_text_color.red, &gtkui_tabstrip_text_color.green, &gtkui_tabstrip_text_color.blue);
}
if (!override_listview_colors) {
@@ -284,29 +291,30 @@ gtkui_init_theme_colors (void) {
}
else {
snprintf (color_text, sizeof (color_text), "%hd %hd %hd", style->light[GTK_STATE_NORMAL].red, style->light[GTK_STATE_NORMAL].green, style->light[GTK_STATE_NORMAL].blue);
- clr = deadbeef->conf_get_str ("gtkui.color.listview_even_row", color_text);
+ clr = deadbeef->conf_get_str_fast ("gtkui.color.listview_even_row", color_text);
sscanf (clr, "%hd %hd %hd", &gtkui_listview_even_row_color.red, &gtkui_listview_even_row_color.green, &gtkui_listview_even_row_color.blue);
snprintf (color_text, sizeof (color_text), "%hd %hd %hd", style->mid[GTK_STATE_NORMAL].red, style->mid[GTK_STATE_NORMAL].green, style->mid[GTK_STATE_NORMAL].blue);
- clr = deadbeef->conf_get_str ("gtkui.color.listview_odd_row", color_text);
+ clr = deadbeef->conf_get_str_fast ("gtkui.color.listview_odd_row", color_text);
sscanf (clr, "%hd %hd %hd", &gtkui_listview_odd_row_color.red, &gtkui_listview_odd_row_color.green, &gtkui_listview_odd_row_color.blue);
snprintf (color_text, sizeof (color_text), "%hd %hd %hd", style->mid[GTK_STATE_NORMAL].red, style->mid[GTK_STATE_NORMAL].green, style->mid[GTK_STATE_NORMAL].blue);
- clr = deadbeef->conf_get_str ("gtkui.color.listview_selection", color_text);
+ clr = deadbeef->conf_get_str_fast ("gtkui.color.listview_selection", color_text);
sscanf (clr, "%hd %hd %hd", &gtkui_listview_selection_color.red, &gtkui_listview_selection_color.green, &gtkui_listview_selection_color.blue);
snprintf (color_text, sizeof (color_text), "%hd %hd %hd", style->fg[GTK_STATE_NORMAL].red, style->fg[GTK_STATE_NORMAL].green, style->fg[GTK_STATE_NORMAL].blue);
- clr = deadbeef->conf_get_str ("gtkui.color.listview_text", color_text);
+ clr = deadbeef->conf_get_str_fast ("gtkui.color.listview_text", color_text);
sscanf (clr, "%hd %hd %hd", &gtkui_listview_text_color.red, &gtkui_listview_text_color.green, &gtkui_listview_text_color.blue);
snprintf (color_text, sizeof (color_text), "%hd %hd %hd", style->fg[GTK_STATE_SELECTED].red, style->fg[GTK_STATE_SELECTED].green, style->fg[GTK_STATE_SELECTED].blue);
- clr = deadbeef->conf_get_str ("gtkui.color.listview_selected_text", color_text);
+ clr = deadbeef->conf_get_str_fast ("gtkui.color.listview_selected_text", color_text);
sscanf (clr, "%hd %hd %hd", &gtkui_listview_selected_text_color.red, &gtkui_listview_selected_text_color.green, &gtkui_listview_selected_text_color.blue);
snprintf (color_text, sizeof (color_text), "%hd %hd %hd", style->fg[GTK_STATE_SELECTED].red, style->fg[GTK_STATE_SELECTED].green, style->fg[GTK_STATE_SELECTED].blue);
- clr = deadbeef->conf_get_str ("gtkui.color.listview_cursor", color_text);
+ clr = deadbeef->conf_get_str_fast ("gtkui.color.listview_cursor", color_text);
sscanf (clr, "%hd %hd %hd", &gtkui_listview_cursor_color.red, &gtkui_listview_cursor_color.green, &gtkui_listview_cursor_color.blue);
}
+ deadbeef->conf_unlock ();
}
void
@@ -340,6 +348,11 @@ gtkui_get_tabstrip_base_color (GdkColor *clr) {
}
void
+gtkui_get_tabstrip_text_color (GdkColor *clr) {
+ memcpy (clr, &gtkui_tabstrip_text_color, sizeof (GdkColor));
+}
+
+void
gtkui_get_listview_even_row_color (GdkColor *clr) {
memcpy (clr, &gtkui_listview_even_row_color, sizeof (GdkColor));
}
@@ -368,3 +381,16 @@ void
gtkui_get_listview_cursor_color (GdkColor *clr) {
memcpy (clr, &gtkui_listview_cursor_color, sizeof (GdkColor));
}
+
+int
+draw_get_listview_rowheight (void) {
+ PangoFontDescription *font_desc = font_style->font_desc;
+ PangoFontMetrics *metrics = pango_context_get_metrics (pangoctx,
+ font_desc,
+ pango_context_get_language (pangoctx));
+ int row_height = (pango_font_metrics_get_ascent (metrics) +
+ pango_font_metrics_get_descent (metrics));
+ pango_font_metrics_unref (metrics);
+ return PANGO_PIXELS(row_height)+6;
+}
+
diff --git a/plugins/gtkui/gtkui.c b/plugins/gtkui/gtkui.c
index 35da1527..6b34e1e9 100644
--- a/plugins/gtkui/gtkui.c
+++ b/plugins/gtkui/gtkui.c
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@@ -44,11 +44,14 @@
#include "ddbtabstrip.h"
#include "eq.h"
#include "actions.h"
+#include "pluginconf.h"
+#include "gtkui_api.h"
+#include "wingeom.h"
-//#define trace(...) { fprintf(stderr, __VA_ARGS__); }
-#define trace(fmt,...)
+#define trace(...) { fprintf(stderr, __VA_ARGS__); }
+//#define trace(fmt,...)
-static DB_gui_t plugin;
+static ddb_gtkui_t plugin;
DB_functions_t *deadbeef;
static intptr_t gtk_tid;
@@ -116,6 +119,7 @@ update_songinfo (gpointer ctx) {
if (!gtk_widget_get_visible (mainwin) || iconified) {
return FALSE;
}
+ DB_output_t *output = deadbeef->get_output ();
char sbtext_new[512] = "-";
float songpos = last_songpos;
@@ -141,7 +145,7 @@ update_songinfo (gpointer ctx) {
float duration = track ? deadbeef->pl_get_item_duration (track) : -1;
- if (deadbeef->get_output ()->state () == OUTPUT_STATE_STOPPED || !track || !c) {
+ if (!output || (output->state () == OUTPUT_STATE_STOPPED || !track || !c)) {
snprintf (sbtext_new, sizeof (sbtext_new), _("Stopped | %d tracks | %s total playtime"), deadbeef->pl_getcount (PL_MAIN), totaltime_str);
songpos = 0;
}
@@ -154,15 +158,15 @@ update_songinfo (gpointer ctx) {
const char *mode;
char temp[20];
- if (c->channels <= 2) {
- mode = c->channels == 1 ? _("Mono") : _("Stereo");
+ if (c->fmt.channels <= 2) {
+ mode = c->fmt.channels == 1 ? _("Mono") : _("Stereo");
}
else {
- snprintf (temp, sizeof (temp), "%dch Multichannel", c->channels);
+ snprintf (temp, sizeof (temp), "%dch Multichannel", c->fmt.channels);
mode = temp;
}
- int samplerate = c->samplerate;
- int bitspersample = c->bps;
+ int samplerate = c->fmt.samplerate;
+ int bitspersample = c->fmt.bps;
songpos = playpos;
// codec_unlock ();
@@ -187,7 +191,11 @@ update_songinfo (gpointer ctx) {
}
}
const char *spaused = deadbeef->get_output ()->state () == OUTPUT_STATE_PAUSED ? _("Paused | ") : "";
- snprintf (sbtext_new, sizeof (sbtext_new), _("%s%s %s| %dHz | %d bit | %s | %d:%02d / %s | %d tracks | %s total playtime"), spaused, track->filetype ? track->filetype:"-", sbitrate, samplerate, bitspersample, mode, minpos, secpos, t, deadbeef->pl_getcount (PL_MAIN), totaltime_str);
+ const char *filetype = deadbeef->pl_find_meta (track, ":FILETYPE");
+ if (!filetype) {
+ filetype = "-";
+ }
+ snprintf (sbtext_new, sizeof (sbtext_new), _("%s%s %s| %dHz | %d bit | %s | %d:%02d / %s | %d tracks | %s total playtime"), spaused, filetype, sbitrate, samplerate, bitspersample, mode, minpos, secpos, t, deadbeef->pl_getcount (PL_MAIN), totaltime_str);
}
if (strcmp (sbtext_new, sb_text)) {
@@ -223,7 +231,7 @@ update_songinfo (gpointer ctx) {
void
set_tray_tooltip (const char *text) {
if (trayicon) {
-#if (GTK_MINOR_VERSION < 16)
+#if !GTK_CHECK_VERSION(2,16,0) || defined(ULTRA_COMPATIBLE)
gtk_status_icon_set_tooltip (trayicon, text);
#else
gtk_status_icon_set_tooltip_text (trayicon, text);
@@ -274,15 +282,7 @@ mainwin_toggle_visible (void) {
gtk_widget_hide (mainwin);
}
else {
- int x = deadbeef->conf_get_int ("mainwin.geometry.x", 40);
- int y = deadbeef->conf_get_int ("mainwin.geometry.y", 40);
- int w = deadbeef->conf_get_int ("mainwin.geometry.w", 500);
- int h = deadbeef->conf_get_int ("mainwin.geometry.h", 300);
- gtk_window_move (GTK_WINDOW (mainwin), x, y);
- gtk_window_resize (GTK_WINDOW (mainwin), w, h);
- if (deadbeef->conf_get_int ("mainwin.geometry.maximized", 0)) {
- gtk_window_maximize (GTK_WINDOW (mainwin));
- }
+ wingeom_restore (mainwin, "mainwin", 40, 40, 500, 300, 0);
if (iconified) {
gtk_window_deiconify (GTK_WINDOW(mainwin));
}
@@ -292,7 +292,7 @@ mainwin_toggle_visible (void) {
}
}
-#if GTK_MINOR_VERSION<=14
+#if !GTK_CHECK_VERSION(2,14,0) || defined(ULTRA_COMPATIBLE)
gboolean
on_trayicon_activate (GtkWidget *widget,
@@ -314,7 +314,7 @@ on_trayicon_button_press_event (GtkWidget *widget,
mainwin_toggle_visible ();
}
else if (event->button == 2) {
- deadbeef->sendmessage (M_PAUSESONG, 0, 0, 0);
+ deadbeef->sendmessage (M_TOGGLE_PAUSE, 0, 0, 0);
}
return FALSE;
}
@@ -398,13 +398,13 @@ gtkui_set_titlebar (DB_playItem_t *it) {
else {
deadbeef->pl_item_ref (it);
}
+ char fmt[500];
char str[600];
- const char *fmt;
if (it) {
- fmt = deadbeef->conf_get_str ("gtkui.titlebar_playing", "%a - %t - DeaDBeeF-%V");
+ deadbeef->conf_get_str ("gtkui.titlebar_playing", "%a - %t - DeaDBeeF-%V", fmt, sizeof (fmt));
}
else {
- fmt = deadbeef->conf_get_str ("gtkui.titlebar_stopped", "DeaDBeeF-%V");
+ deadbeef->conf_get_str ("gtkui.titlebar_stopped", "DeaDBeeF-%V", fmt, sizeof (fmt));
}
deadbeef->pl_format_title (it, -1, str, sizeof (str), -1, fmt);
gtk_window_set_title (GTK_WINDOW (mainwin), str);
@@ -478,7 +478,7 @@ gtkui_on_paused (DB_event_state_t *ev, uintptr_t data) {
void
playlist_refresh (void) {
DdbListview *ps = DDB_LISTVIEW (lookup_widget (mainwin, "playlist"));
- ddb_listview_refresh (ps, DDB_REFRESH_LIST | DDB_REFRESH_VSCROLL | DDB_EXPOSE_LIST);
+ ddb_listview_refresh (ps, DDB_REFRESH_LIST | DDB_REFRESH_VSCROLL);
search_refresh ();
}
@@ -532,11 +532,11 @@ gtkui_on_playlistswitch (DB_event_t *ev, uintptr_t data) {
return 0;
}
-static int
-gtkui_on_frameupdate (DB_event_t *ev, uintptr_t data) {
- g_idle_add (update_songinfo, NULL);
+static gboolean
+gtkui_on_frameupdate (gpointer data) {
+ update_songinfo (NULL);
- return 0;
+ return TRUE;
}
static gboolean
@@ -571,7 +571,9 @@ gtkui_update_status_icon (gpointer unused) {
// system tray icon
traymenu = create_traymenu ();
- const char *icon_name = deadbeef->conf_get_str ("gtkui.custom_tray_icon", TRAY_ICON);
+ char tmp[1000];
+ const char *icon_name = tmp;
+ deadbeef->conf_get_str ("gtkui.custom_tray_icon", TRAY_ICON, tmp, sizeof (tmp));
GtkIconTheme *theme = gtk_icon_theme_get_default();
if (!gtk_icon_theme_has_icon(theme, icon_name))
@@ -583,12 +585,19 @@ gtkui_update_status_icon (gpointer unused) {
icon_name = icon_is_builtin ? "deadbeef" : icon_name;
}
- trayicon = gtk_status_icon_new_from_icon_name(icon_name);
+ if (!gtk_icon_theme_has_icon(theme, icon_name)) {
+ char iconpath[1024];
+ snprintf (iconpath, sizeof (iconpath), "%s/deadbeef.png", deadbeef->get_prefix ());
+ trayicon = gtk_status_icon_new_from_file(iconpath);
+ }
+ else {
+ trayicon = gtk_status_icon_new_from_icon_name(icon_name);
+ }
if (hide_tray_icon) {
g_object_set (trayicon, "visible", FALSE, NULL);
}
-#if GTK_MINOR_VERSION <= 14
+#if !GTK_CHECK_VERSION(2,14,0) || defined(ULTRA_COMPATIBLE)
g_signal_connect ((gpointer)trayicon, "activate", G_CALLBACK (on_trayicon_activate), NULL);
#else
g_signal_connect ((gpointer)trayicon, "scroll_event", G_CALLBACK (on_trayicon_scroll_event), NULL);
@@ -614,7 +623,7 @@ gtkui_on_configchanged (DB_event_t *ev, uintptr_t data) {
const char *w;
// order
- const char *orderwidgets[3] = { "order_linear", "order_shuffle", "order_random" };
+ const char *orderwidgets[4] = { "order_linear", "order_shuffle", "order_random", "order_shuffle_albums" };
w = orderwidgets[deadbeef->conf_get_int ("playback.order", PLAYBACK_ORDER_LINEAR)];
gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (lookup_widget (mainwin, w)), TRUE);
@@ -663,13 +672,31 @@ save_playlist_as (void) {
gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dlg), TRUE);
gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dlg), "untitled.dbpl");
// restore folder
- gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER (dlg), deadbeef->conf_get_str ("filechooser.playlist.lastdir", ""));
+ deadbeef->conf_lock ();
+ gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER (dlg), deadbeef->conf_get_str_fast ("filechooser.playlist.lastdir", ""));
+ deadbeef->conf_unlock ();
GtkFileFilter* flt;
flt = gtk_file_filter_new ();
gtk_file_filter_set_name (flt, _("DeaDBeeF playlist files (*.dbpl)"));
gtk_file_filter_add_pattern (flt, "*.dbpl");
gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dlg), flt);
+ DB_playlist_t **plug = deadbeef->plug_get_playlist_list ();
+ for (int i = 0; plug[i]; i++) {
+ if (plug[i]->extensions && plug[i]->load) {
+ const char **exts = plug[i]->extensions;
+ if (exts && plug[i]->save) {
+ for (int e = 0; exts[e]; e++) {
+ char s[100];
+ flt = gtk_file_filter_new ();
+ gtk_file_filter_set_name (flt, exts[e]);
+ snprintf (s, sizeof (s), "*.%s", exts[e]);
+ gtk_file_filter_add_pattern (flt, s);
+ gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dlg), flt);
+ }
+ }
+ }
+ }
int res = gtk_dialog_run (GTK_DIALOG (dlg));
// store folder
@@ -716,6 +743,29 @@ on_playlist_save_as_activate (GtkMenuItem *menuitem,
save_playlist_as ();
}
+static gboolean
+playlist_filter_func (const GtkFileFilterInfo *filter_info, gpointer data) {
+ // get ext
+ const char *p = strrchr (filter_info->filename, '.');
+ if (!p) {
+ return FALSE;
+ }
+ p++;
+ DB_playlist_t **plug = deadbeef->plug_get_playlist_list ();
+ for (int i = 0; plug[i]; i++) {
+ if (plug[i]->extensions && plug[i]->load) {
+ const char **exts = plug[i]->extensions;
+ if (exts) {
+ for (int e = 0; exts[e]; e++) {
+ if (!strcasecmp (exts[e], p)) {
+ return TRUE;
+ }
+ }
+ }
+ }
+ }
+ return FALSE;
+}
void
on_playlist_load_activate (GtkMenuItem *menuitem,
@@ -724,13 +774,21 @@ on_playlist_load_activate (GtkMenuItem *menuitem,
GtkWidget *dlg = gtk_file_chooser_dialog_new (_("Load Playlist"), GTK_WINDOW (mainwin), GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_OK, NULL);
// restore folder
- gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER (dlg), deadbeef->conf_get_str ("filechooser.playlist.lastdir", ""));
+ deadbeef->conf_lock ();
+ gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER (dlg), deadbeef->conf_get_str_fast ("filechooser.playlist.lastdir", ""));
+ deadbeef->conf_unlock ();
GtkFileFilter* flt;
flt = gtk_file_filter_new ();
- gtk_file_filter_set_name (flt, _("DeaDBeeF playlist files (*.dbpl)"));
+ gtk_file_filter_set_name (flt, "Supported playlist formats");
+ gtk_file_filter_add_custom (flt, GTK_FILE_FILTER_FILENAME, playlist_filter_func, NULL, NULL);
gtk_file_filter_add_pattern (flt, "*.dbpl");
gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dlg), flt);
+ gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (dlg), flt);
+ flt = gtk_file_filter_new ();
+ gtk_file_filter_set_name (flt, _("Other files (*)"));
+ gtk_file_filter_add_pattern (flt, "*");
+ gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dlg), flt);
int res = gtk_dialog_run (GTK_DIALOG (dlg));
// store folder
@@ -767,7 +825,9 @@ on_add_location_activate (GtkMenuItem *menuitem,
if (entry) {
const char *text = gtk_entry_get_text (entry);
if (text) {
+ deadbeef->pl_add_files_begin (deadbeef->plt_get_curr ());
deadbeef->pl_add_file (text, NULL, NULL);
+ deadbeef->pl_add_files_end ();
playlist_refresh ();
}
}
@@ -867,13 +927,16 @@ gtkui_add_new_playlist (void) {
else {
snprintf (name, sizeof (name), _("New Playlist (%d)"), idx);
}
+ deadbeef->plt_lock ();
for (i = 0; i < cnt; i++) {
char t[100];
- deadbeef->plt_get_title (i, t, sizeof (t));
+ void *plt = deadbeef->plt_get_handle (i);
+ deadbeef->plt_get_title (plt, t, sizeof (t));
if (!strcasecmp (t, name)) {
break;
}
}
+ deadbeef->plt_unlock ();
if (i == cnt) {
return deadbeef->plt_add (cnt, name);
}
@@ -895,12 +958,34 @@ tabstrip_redraw (void) {
}
static int gtk_initialized = 0;
+static gint refresh_timeout = 0;
+
+void
+gtkui_setup_gui_refresh (void) {
+ int fps = deadbeef->conf_get_int ("gtkui.refresh_rate", 10);
+ if (fps < 1) {
+ fps = 1;
+ }
+ else if (fps > 30) {
+ fps = 30;
+ }
+
+ int tm = 1000/fps;
+
+ if (refresh_timeout) {
+ g_source_remove (refresh_timeout);
+ refresh_timeout = 0;
+ }
+
+ refresh_timeout = g_timeout_add (tm, gtkui_on_frameupdate, NULL);
+}
void
gtkui_thread (void *ctx) {
// let's start some gtk
g_thread_init (NULL);
- add_pixmap_directory (PREFIX "/share/deadbeef/pixmaps");
+// add_pixmap_directory (PREFIX "/share/deadbeef/pixmaps");
+ add_pixmap_directory (deadbeef->get_pixmap_dir ());
gdk_threads_init ();
gdk_threads_enter ();
@@ -918,19 +1003,15 @@ gtkui_thread (void *ctx) {
mainwin = create_mainwin ();
gtkpl_init ();
+#if PORTABLE
+ char iconpath[1024];
+ snprintf (iconpath, sizeof (iconpath), "%s/deadbeef.png", deadbeef->get_prefix ());
+ gtk_window_set_icon_from_file (GTK_WINDOW (mainwin), iconpath, NULL);
+#else
gtk_window_set_icon_name (GTK_WINDOW (mainwin), "deadbeef");
+#endif
- {
- int x = deadbeef->conf_get_int ("mainwin.geometry.x", 40);
- int y = deadbeef->conf_get_int ("mainwin.geometry.y", 40);
- int w = deadbeef->conf_get_int ("mainwin.geometry.w", 500);
- int h = deadbeef->conf_get_int ("mainwin.geometry.h", 300);
- gtk_window_move (GTK_WINDOW (mainwin), x, y);
- gtk_window_resize (GTK_WINDOW (mainwin), w, h);
- if (deadbeef->conf_get_int ("mainwin.geometry.maximized", 0)) {
- gtk_window_maximize (GTK_WINDOW (mainwin));
- }
- }
+ wingeom_restore (mainwin, "mainwin", 40, 40, 500, 300, 0);
gtkui_on_configchanged (NULL, 0);
gtkui_init_theme_colors ();
@@ -984,14 +1065,17 @@ gtkui_thread (void *ctx) {
deadbeef->ev_subscribe (DB_PLUGIN (&plugin), DB_EV_TRACKINFOCHANGED, DB_CALLBACK (gtkui_on_trackinfochanged), 0);
deadbeef->ev_subscribe (DB_PLUGIN (&plugin), DB_EV_PAUSED, DB_CALLBACK (gtkui_on_paused), 0);
deadbeef->ev_subscribe (DB_PLUGIN (&plugin), DB_EV_PLAYLISTCHANGED, DB_CALLBACK (gtkui_on_playlistchanged), 0);
- deadbeef->ev_subscribe (DB_PLUGIN (&plugin), DB_EV_FRAMEUPDATE, DB_CALLBACK (gtkui_on_frameupdate), 0);
deadbeef->ev_subscribe (DB_PLUGIN (&plugin), DB_EV_VOLUMECHANGED, DB_CALLBACK (gtkui_on_volumechanged), 0);
deadbeef->ev_subscribe (DB_PLUGIN (&plugin), DB_EV_CONFIGCHANGED, DB_CALLBACK (gtkui_on_configchanged), 0);
deadbeef->ev_subscribe (DB_PLUGIN (&plugin), DB_EV_OUTPUTCHANGED, DB_CALLBACK (gtkui_on_outputchanged), 0);
deadbeef->ev_subscribe (DB_PLUGIN (&plugin), DB_EV_PLAYLISTSWITCH, DB_CALLBACK (gtkui_on_playlistswitch), 0);
+ gtkui_setup_gui_refresh ();
+
+ char fmt[500];
char str[600];
- deadbeef->pl_format_title (NULL, -1, str, sizeof (str), -1, deadbeef->conf_get_str ("gtkui.titlebar_stopped", "DeaDBeeF-%V"));
+ deadbeef->conf_get_str ("gtkui.titlebar_stopped", "DeaDBeeF-%V", fmt, sizeof (fmt));
+ deadbeef->pl_format_title (NULL, -1, str, sizeof (str), -1, fmt);
gtk_window_set_title (GTK_WINDOW (mainwin), str);
gtk_initialized = 1;
@@ -1024,7 +1108,7 @@ gtkui_set_progress_text_idle (gpointer data) {
gboolean
gtkui_progress_hide_idle (gpointer data) {
progress_hide ();
- deadbeef->sendmessage (M_PLAYLISTREFRESH, 0, 0, 0);
+ deadbeef->sendmessage (M_PLAYLIST_REFRESH, 0, 0, 0);
//playlist_refresh ();
return FALSE;
}
@@ -1034,13 +1118,13 @@ gtkui_add_file_info_cb (DB_playItem_t *it, void *data) {
if (progress_is_aborted ()) {
return -1;
}
- g_idle_add (gtkui_set_progress_text_idle, it->fname);
+ g_idle_add (gtkui_set_progress_text_idle, (gpointer)deadbeef->pl_find_meta (it, ":URI"));
return 0;
}
int (*gtkui_original_pl_add_dir) (const char *dirname, int (*cb)(DB_playItem_t *it, void *data), void *user_data);
int (*gtkui_original_pl_add_file) (const char *fname, int (*cb)(DB_playItem_t *it, void *data), void *user_data);
-void (*gtkui_original_pl_add_files_begin) (void);
+void (*gtkui_original_pl_add_files_begin) (int plt);
void (*gtkui_original_pl_add_files_end) (void);
int
@@ -1056,9 +1140,9 @@ gtkui_pl_add_file (const char *filename, int (*cb)(DB_playItem_t *it, void *data
}
void
-gtkui_pl_add_files_begin (void) {
+gtkui_pl_add_files_begin (int plt) {
g_idle_add (gtkui_progress_show_idle, NULL);
- gtkui_original_pl_add_files_begin ();
+ gtkui_original_pl_add_files_begin (plt);
}
void
@@ -1093,6 +1177,8 @@ gtkui_playlist_set_curr (int playlist) {
static int
gtkui_start (void) {
+ fprintf (stderr, "gtkui plugin compiled for gtk version: %d.%d.%d\n", GTK_MAJOR_VERSION, GTK_MINOR_VERSION, GTK_MICRO_VERSION);
+
// gtk must be running in separate thread
gtk_initialized = 0;
gtk_tid = deadbeef->thread_start (gtkui_thread, NULL);
@@ -1117,11 +1203,13 @@ gtkui_start (void) {
return 0;
}
+static DB_plugin_t *supereq_plugin;
+
gboolean
gtkui_connect_cb (void *none) {
// equalizer
GtkWidget *eq_mi = lookup_widget (mainwin, "view_eq");
- if (!get_supereq_plugin ()) {
+ if (!supereq_plugin) {
gtk_widget_hide (GTK_WIDGET (eq_mi));
}
else {
@@ -1138,17 +1226,19 @@ gtkui_connect_cb (void *none) {
DB_plugin_t **plugins = deadbeef->plug_get_list ();
for (int i = 0; plugins[i]; i++) {
DB_plugin_t *p = plugins[i];
- if (p->id && !strcmp (p->id, "cover_loader")) {
+ if (p->id && !strcmp (p->id, "artwork")) {
trace ("gtkui: found cover-art loader plugin\n");
coverart_plugin = (DB_artwork_plugin_t *)p;
break;
}
}
+ gtkui_playlist_changed ();
return FALSE;
}
static int
gtkui_connect (void) {
+ supereq_plugin = deadbeef->plug_get_for_id ("supereq");
// need to do it in gtk thread
g_idle_add (gtkui_connect_cb, NULL);
@@ -1174,7 +1264,6 @@ gtkui_stop (void) {
deadbeef->ev_unsubscribe (DB_PLUGIN (&plugin), DB_EV_TRACKINFOCHANGED, DB_CALLBACK (gtkui_on_trackinfochanged), 0);
deadbeef->ev_unsubscribe (DB_PLUGIN (&plugin), DB_EV_PAUSED, DB_CALLBACK (gtkui_on_paused), 0);
deadbeef->ev_unsubscribe (DB_PLUGIN (&plugin), DB_EV_PLAYLISTCHANGED, DB_CALLBACK (gtkui_on_playlistchanged), 0);
- deadbeef->ev_unsubscribe (DB_PLUGIN (&plugin), DB_EV_FRAMEUPDATE, DB_CALLBACK (gtkui_on_frameupdate), 0);
deadbeef->ev_unsubscribe (DB_PLUGIN (&plugin), DB_EV_VOLUMECHANGED, DB_CALLBACK (gtkui_on_volumechanged), 0);
deadbeef->ev_unsubscribe (DB_PLUGIN (&plugin), DB_EV_CONFIGCHANGED, DB_CALLBACK (gtkui_on_configchanged), 0);
deadbeef->ev_unsubscribe (DB_PLUGIN (&plugin), DB_EV_OUTPUTCHANGED, DB_CALLBACK (gtkui_on_outputchanged), 0);
@@ -1190,8 +1279,13 @@ gtkui_stop (void) {
return 0;
}
+GtkWidget *
+gtkui_get_mainwin (void) {
+ return mainwin;
+}
+
DB_plugin_t *
-gtkui_load (DB_functions_t *api) {
+ddb_gui_GTK2_load (DB_functions_t *api) {
deadbeef = api;
return DB_PLUGIN (&plugin);
}
@@ -1205,19 +1299,37 @@ static const char settings_dlg[] =
;
// define plugin interface
-static DB_gui_t plugin = {
- DB_PLUGIN_SET_API_VERSION
- .plugin.version_major = 0,
- .plugin.version_minor = 1,
- .plugin.nostop = 1,
- .plugin.type = DB_PLUGIN_MISC,
- .plugin.name = "Standard GTK2 user interface",
- .plugin.descr = "Default DeaDBeeF GUI",
- .plugin.author = "Alexey Yakovenko",
- .plugin.email = "waker@users.sourceforge.net",
- .plugin.website = "http://deadbeef.sf.net",
- .plugin.start = gtkui_start,
- .plugin.stop = gtkui_stop,
- .plugin.connect = gtkui_connect,
- .plugin.configdialog = settings_dlg,
+static ddb_gtkui_t plugin = {
+ .gui.plugin.api_vmajor = DB_API_VERSION_MAJOR,
+ .gui.plugin.api_vminor = DB_API_VERSION_MINOR,
+ .gui.plugin.version_major = 1,
+ .gui.plugin.version_minor = 0,
+ .gui.plugin.type = DB_PLUGIN_MISC,
+ .gui.plugin.id = "gtkui",
+ .gui.plugin.name = "Standard GTK2 user interface",
+ .gui.plugin.descr = "Default DeaDBeeF GUI",
+ .gui.plugin.copyright =
+ "Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>\n"
+ "\n"
+ "This program is free software; you can redistribute it and/or\n"
+ "modify it under the terms of the GNU General Public License\n"
+ "as published by the Free Software Foundation; either version 2\n"
+ "of the License, or (at your option) any later version.\n"
+ "\n"
+ "This program is distributed in the hope that it will be useful,\n"
+ "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+ "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+ "GNU General Public License for more details.\n"
+ "\n"
+ "You should have received a copy of the GNU General Public License\n"
+ "along with this program; if not, write to the Free Software\n"
+ "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n"
+ ,
+ .gui.plugin.website = "http://deadbeef.sf.net",
+ .gui.plugin.start = gtkui_start,
+ .gui.plugin.stop = gtkui_stop,
+ .gui.plugin.connect = gtkui_connect,
+ .gui.plugin.configdialog = settings_dlg,
+ .gui.run_dialog = gtkui_run_dialog_root,
+ .get_mainwin = gtkui_get_mainwin,
};
diff --git a/plugins/gtkui/gtkui.h b/plugins/gtkui/gtkui.h
index 53db09af..4074ddb2 100644
--- a/plugins/gtkui/gtkui.h
+++ b/plugins/gtkui/gtkui.h
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@@ -25,12 +25,20 @@
#include <gtk/gtk.h>
+#ifdef HAVE_CONFIG_H
+#include "../../config.h"
+#endif
+
+#if defined(ULTRA_COMPATIBLE)
+#warning compiling for compatibility with gtk <2.14
+#endif
+
// workaround to make older gtk compatible with vala codegen
-#if !GTK_CHECK_VERSION(2,14,0)
+#if !GTK_CHECK_VERSION(2,14,0) || defined(ULTRA_COMPATIBLE)
#define gtk_widget_get_window(widget) ((widget)->window)
#endif
-#if !GTK_CHECK_VERSION(2,18,0)
+#if !GTK_CHECK_VERSION(2,18,0) || defined(ULTRA_COMPATIBLE)
#define gtk_widget_set_has_window(widget, has_window) \
if (has_window) GTK_WIDGET_UNSET_FLAGS (widget, GTK_NO_WINDOW); \
else GTK_WIDGET_SET_FLAGS (widget, GTK_NO_WINDOW);
@@ -39,7 +47,7 @@
#define gtk_widget_get_has_window(widget) (!GTK_WIDGET_NO_WINDOW(widget))
#endif
-#if !GTK_CHECK_VERSION(2,20,0)
+#if !GTK_CHECK_VERSION(2,20,0) || defined(ULTRA_COMPATIBLE)
#define gtk_widget_get_realized(widget) (GTK_WIDGET_REALIZED(widget))
#endif
@@ -66,11 +74,6 @@ gtkui_open_files (struct _GSList *lst);
void
gtkui_receive_fm_drop (DB_playItem_t *before, char *mem, int length);
-// plugin configuration dialogs
-
-void
-plugin_configure (GtkWidget *parentwin, DB_plugin_t *p);
-
void
preferences_fill_soundcards (void);
@@ -160,4 +163,7 @@ gtkui_focus_on_playing_track (void);
void
gtkui_playlist_set_curr (int playlist);
+void
+gtkui_setup_gui_refresh ();
+
#endif
diff --git a/plugins/gtkui/gtkui_api.h b/plugins/gtkui/gtkui_api.h
new file mode 100644
index 00000000..596aeb17
--- /dev/null
+++ b/plugins/gtkui/gtkui_api.h
@@ -0,0 +1,28 @@
+/*
+ DeaDBeeF - ultimate music player for GNU/Linux systems with X11
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+#ifndef __GTKUI_API_H
+#define __GTKUI_API_H
+
+typedef struct {
+ DB_gui_t gui;
+ GtkWidget * (*get_mainwin) (void);
+} ddb_gtkui_t;
+
+#endif
diff --git a/plugins/gtkui/interface.c b/plugins/gtkui/interface.c
index 1b255c52..5d3dde1a 100644
--- a/plugins/gtkui/interface.c
+++ b/plugins/gtkui/interface.c
@@ -35,12 +35,12 @@ create_mainwin (void)
GtkWidget *File;
GtkWidget *File_menu;
GtkWidget *open;
- GtkWidget *image452;
+ GtkWidget *image512;
GtkWidget *separator2;
GtkWidget *add_files;
- GtkWidget *image453;
+ GtkWidget *image513;
GtkWidget *add_folders;
- GtkWidget *image454;
+ GtkWidget *image514;
GtkWidget *add_location1;
GtkWidget *separatormenuitem1;
GtkWidget *new_playlist1;
@@ -49,20 +49,26 @@ create_mainwin (void)
GtkWidget *playlist_save_as;
GtkWidget *separator8;
GtkWidget *quit;
- GtkWidget *image455;
+ GtkWidget *image515;
GtkWidget *Edit;
GtkWidget *Edit_menu;
GtkWidget *clear1;
- GtkWidget *image456;
+ GtkWidget *image516;
GtkWidget *select_all1;
GtkWidget *deselect_all1;
GtkWidget *invert_selection1;
GtkWidget *Selection;
GtkWidget *Selection_menu;
GtkWidget *remove1;
- GtkWidget *image457;
+ GtkWidget *image517;
GtkWidget *crop1;
GtkWidget *find1;
+ GtkWidget *sort_by1;
+ GtkWidget *sort_by1_menu;
+ GtkWidget *album1;
+ GtkWidget *artist1;
+ GtkWidget *date1;
+ GtkWidget *custom2;
GtkWidget *separator5;
GtkWidget *preferences;
GtkWidget *View;
@@ -78,6 +84,7 @@ create_mainwin (void)
GSList *order_linear_group = NULL;
GtkWidget *order_linear;
GtkWidget *order_shuffle;
+ GtkWidget *order_shuffle_albums;
GtkWidget *order_random;
GtkWidget *Looping;
GtkWidget *Looping_menu;
@@ -93,16 +100,16 @@ create_mainwin (void)
GtkWidget *Help;
GtkWidget *Help_menu;
GtkWidget *help1;
- GtkWidget *image458;
+ GtkWidget *image518;
GtkWidget *changelog1;
GtkWidget *separator10;
GtkWidget *gpl1;
GtkWidget *lgpl1;
GtkWidget *separator9;
GtkWidget *about1;
- GtkWidget *image459;
+ GtkWidget *image519;
GtkWidget *translators1;
- GtkWidget *image460;
+ GtkWidget *image520;
GtkWidget *hbox2;
GtkWidget *hbox3;
GtkWidget *stopbtn;
@@ -153,9 +160,9 @@ create_mainwin (void)
GDK_O, (GdkModifierType) GDK_CONTROL_MASK,
GTK_ACCEL_VISIBLE);
- image452 = gtk_image_new_from_stock ("gtk-open", GTK_ICON_SIZE_MENU);
- gtk_widget_show (image452);
- gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (open), image452);
+ image512 = gtk_image_new_from_stock ("gtk-open", GTK_ICON_SIZE_MENU);
+ gtk_widget_show (image512);
+ gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (open), image512);
separator2 = gtk_separator_menu_item_new ();
gtk_widget_show (separator2);
@@ -166,17 +173,17 @@ create_mainwin (void)
gtk_widget_show (add_files);
gtk_container_add (GTK_CONTAINER (File_menu), add_files);
- image453 = gtk_image_new_from_stock ("gtk-add", GTK_ICON_SIZE_MENU);
- gtk_widget_show (image453);
- gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (add_files), image453);
+ image513 = gtk_image_new_from_stock ("gtk-add", GTK_ICON_SIZE_MENU);
+ gtk_widget_show (image513);
+ gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (add_files), image513);
add_folders = gtk_image_menu_item_new_with_mnemonic (_("Add folder(s)"));
gtk_widget_show (add_folders);
gtk_container_add (GTK_CONTAINER (File_menu), add_folders);
- image454 = gtk_image_new_from_stock ("gtk-add", GTK_ICON_SIZE_MENU);
- gtk_widget_show (image454);
- gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (add_folders), image454);
+ image514 = gtk_image_new_from_stock ("gtk-add", GTK_ICON_SIZE_MENU);
+ gtk_widget_show (image514);
+ gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (add_folders), image514);
add_location1 = gtk_menu_item_new_with_mnemonic (_("Add location"));
gtk_widget_show (add_location1);
@@ -218,9 +225,9 @@ create_mainwin (void)
GDK_Q, (GdkModifierType) GDK_CONTROL_MASK,
GTK_ACCEL_VISIBLE);
- image455 = gtk_image_new_from_stock ("gtk-quit", GTK_ICON_SIZE_MENU);
- gtk_widget_show (image455);
- gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (quit), image455);
+ image515 = gtk_image_new_from_stock ("gtk-quit", GTK_ICON_SIZE_MENU);
+ gtk_widget_show (image515);
+ gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (quit), image515);
Edit = gtk_menu_item_new_with_mnemonic (_("_Edit"));
gtk_widget_show (Edit);
@@ -233,9 +240,9 @@ create_mainwin (void)
gtk_widget_show (clear1);
gtk_container_add (GTK_CONTAINER (Edit_menu), clear1);
- image456 = gtk_image_new_from_stock ("gtk-clear", GTK_ICON_SIZE_MENU);
- gtk_widget_show (image456);
- gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (clear1), image456);
+ image516 = gtk_image_new_from_stock ("gtk-clear", GTK_ICON_SIZE_MENU);
+ gtk_widget_show (image516);
+ gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (clear1), image516);
select_all1 = gtk_menu_item_new_with_mnemonic (_("Select all"));
gtk_widget_show (select_all1);
@@ -266,9 +273,9 @@ create_mainwin (void)
gtk_widget_show (remove1);
gtk_container_add (GTK_CONTAINER (Selection_menu), remove1);
- image457 = gtk_image_new_from_stock ("gtk-remove", GTK_ICON_SIZE_MENU);
- gtk_widget_show (image457);
- gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (remove1), image457);
+ image517 = gtk_image_new_from_stock ("gtk-remove", GTK_ICON_SIZE_MENU);
+ gtk_widget_show (image517);
+ gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (remove1), image517);
crop1 = gtk_menu_item_new_with_mnemonic (_("Crop"));
gtk_widget_show (crop1);
@@ -281,6 +288,29 @@ create_mainwin (void)
GDK_F, (GdkModifierType) GDK_CONTROL_MASK,
GTK_ACCEL_VISIBLE);
+ sort_by1 = gtk_menu_item_new_with_mnemonic (_("Sort By"));
+ gtk_widget_show (sort_by1);
+ gtk_container_add (GTK_CONTAINER (Edit_menu), sort_by1);
+
+ sort_by1_menu = gtk_menu_new ();
+ gtk_menu_item_set_submenu (GTK_MENU_ITEM (sort_by1), sort_by1_menu);
+
+ album1 = gtk_menu_item_new_with_mnemonic (_("Album"));
+ gtk_widget_show (album1);
+ gtk_container_add (GTK_CONTAINER (sort_by1_menu), album1);
+
+ artist1 = gtk_menu_item_new_with_mnemonic (_("Artist"));
+ gtk_widget_show (artist1);
+ gtk_container_add (GTK_CONTAINER (sort_by1_menu), artist1);
+
+ date1 = gtk_menu_item_new_with_mnemonic (_("Date"));
+ gtk_widget_show (date1);
+ gtk_container_add (GTK_CONTAINER (sort_by1_menu), date1);
+
+ custom2 = gtk_menu_item_new_with_mnemonic (_("Custom"));
+ gtk_widget_show (custom2);
+ gtk_container_add (GTK_CONTAINER (sort_by1_menu), custom2);
+
separator5 = gtk_separator_menu_item_new ();
gtk_widget_show (separator5);
gtk_container_add (GTK_CONTAINER (Edit_menu), separator5);
@@ -333,12 +363,18 @@ create_mainwin (void)
gtk_container_add (GTK_CONTAINER (Order_menu), order_linear);
gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (order_linear), TRUE);
- order_shuffle = gtk_radio_menu_item_new_with_mnemonic (order_linear_group, _("Shuffle"));
+ order_shuffle = gtk_radio_menu_item_new_with_mnemonic (order_linear_group, _("Shuffle tracks"));
order_linear_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (order_shuffle));
gtk_widget_show (order_shuffle);
gtk_container_add (GTK_CONTAINER (Order_menu), order_shuffle);
gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (order_shuffle), TRUE);
+ order_shuffle_albums = gtk_radio_menu_item_new_with_mnemonic (order_linear_group, _("Shuffle albums"));
+ order_linear_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (order_shuffle_albums));
+ gtk_widget_show (order_shuffle_albums);
+ gtk_container_add (GTK_CONTAINER (Order_menu), order_shuffle_albums);
+ gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (order_shuffle_albums), TRUE);
+
order_random = gtk_radio_menu_item_new_with_mnemonic (order_linear_group, _("Random"));
order_linear_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (order_random));
gtk_widget_show (order_random);
@@ -409,9 +445,9 @@ create_mainwin (void)
gtk_widget_show (help1);
gtk_container_add (GTK_CONTAINER (Help_menu), help1);
- image458 = gtk_image_new_from_stock ("gtk-help", GTK_ICON_SIZE_MENU);
- gtk_widget_show (image458);
- gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (help1), image458);
+ image518 = gtk_image_new_from_stock ("gtk-help", GTK_ICON_SIZE_MENU);
+ gtk_widget_show (image518);
+ gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (help1), image518);
changelog1 = gtk_menu_item_new_with_mnemonic (_("_ChangeLog"));
gtk_widget_show (changelog1);
@@ -439,17 +475,17 @@ create_mainwin (void)
gtk_widget_show (about1);
gtk_container_add (GTK_CONTAINER (Help_menu), about1);
- image459 = gtk_image_new_from_stock ("gtk-about", GTK_ICON_SIZE_MENU);
- gtk_widget_show (image459);
- gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (about1), image459);
+ image519 = gtk_image_new_from_stock ("gtk-about", GTK_ICON_SIZE_MENU);
+ gtk_widget_show (image519);
+ gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (about1), image519);
translators1 = gtk_image_menu_item_new_with_mnemonic (_("_Translators"));
gtk_widget_show (translators1);
gtk_container_add (GTK_CONTAINER (Help_menu), translators1);
- image460 = gtk_image_new_from_stock ("gtk-about", GTK_ICON_SIZE_MENU);
- gtk_widget_show (image460);
- gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (translators1), image460);
+ image520 = gtk_image_new_from_stock ("gtk-about", GTK_ICON_SIZE_MENU);
+ gtk_widget_show (image520);
+ gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (translators1), image520);
hbox2 = gtk_hbox_new (FALSE, 0);
gtk_widget_show (hbox2);
@@ -645,6 +681,18 @@ create_mainwin (void)
g_signal_connect ((gpointer) find1, "activate",
G_CALLBACK (on_find_activate),
NULL);
+ g_signal_connect ((gpointer) album1, "activate",
+ G_CALLBACK (on_album1_activate),
+ NULL);
+ g_signal_connect ((gpointer) artist1, "activate",
+ G_CALLBACK (on_artist1_activate),
+ NULL);
+ g_signal_connect ((gpointer) date1, "activate",
+ G_CALLBACK (on_date1_activate),
+ NULL);
+ g_signal_connect ((gpointer) custom2, "activate",
+ G_CALLBACK (on_custom2_activate),
+ NULL);
g_signal_connect ((gpointer) preferences, "activate",
G_CALLBACK (on_preferences_activate),
NULL);
@@ -666,6 +714,9 @@ create_mainwin (void)
g_signal_connect ((gpointer) order_shuffle, "activate",
G_CALLBACK (on_order_shuffle_activate),
NULL);
+ g_signal_connect ((gpointer) order_shuffle_albums, "activate",
+ G_CALLBACK (on_order_shuffle_albums_activate),
+ NULL);
g_signal_connect ((gpointer) order_random, "activate",
G_CALLBACK (on_order_random_activate),
NULL);
@@ -731,12 +782,12 @@ create_mainwin (void)
GLADE_HOOKUP_OBJECT (mainwin, File, "File");
GLADE_HOOKUP_OBJECT (mainwin, File_menu, "File_menu");
GLADE_HOOKUP_OBJECT (mainwin, open, "open");
- GLADE_HOOKUP_OBJECT (mainwin, image452, "image452");
+ GLADE_HOOKUP_OBJECT (mainwin, image512, "image512");
GLADE_HOOKUP_OBJECT (mainwin, separator2, "separator2");
GLADE_HOOKUP_OBJECT (mainwin, add_files, "add_files");
- GLADE_HOOKUP_OBJECT (mainwin, image453, "image453");
+ GLADE_HOOKUP_OBJECT (mainwin, image513, "image513");
GLADE_HOOKUP_OBJECT (mainwin, add_folders, "add_folders");
- GLADE_HOOKUP_OBJECT (mainwin, image454, "image454");
+ GLADE_HOOKUP_OBJECT (mainwin, image514, "image514");
GLADE_HOOKUP_OBJECT (mainwin, add_location1, "add_location1");
GLADE_HOOKUP_OBJECT (mainwin, separatormenuitem1, "separatormenuitem1");
GLADE_HOOKUP_OBJECT (mainwin, new_playlist1, "new_playlist1");
@@ -745,20 +796,26 @@ create_mainwin (void)
GLADE_HOOKUP_OBJECT (mainwin, playlist_save_as, "playlist_save_as");
GLADE_HOOKUP_OBJECT (mainwin, separator8, "separator8");
GLADE_HOOKUP_OBJECT (mainwin, quit, "quit");
- GLADE_HOOKUP_OBJECT (mainwin, image455, "image455");
+ GLADE_HOOKUP_OBJECT (mainwin, image515, "image515");
GLADE_HOOKUP_OBJECT (mainwin, Edit, "Edit");
GLADE_HOOKUP_OBJECT (mainwin, Edit_menu, "Edit_menu");
GLADE_HOOKUP_OBJECT (mainwin, clear1, "clear1");
- GLADE_HOOKUP_OBJECT (mainwin, image456, "image456");
+ GLADE_HOOKUP_OBJECT (mainwin, image516, "image516");
GLADE_HOOKUP_OBJECT (mainwin, select_all1, "select_all1");
GLADE_HOOKUP_OBJECT (mainwin, deselect_all1, "deselect_all1");
GLADE_HOOKUP_OBJECT (mainwin, invert_selection1, "invert_selection1");
GLADE_HOOKUP_OBJECT (mainwin, Selection, "Selection");
GLADE_HOOKUP_OBJECT (mainwin, Selection_menu, "Selection_menu");
GLADE_HOOKUP_OBJECT (mainwin, remove1, "remove1");
- GLADE_HOOKUP_OBJECT (mainwin, image457, "image457");
+ GLADE_HOOKUP_OBJECT (mainwin, image517, "image517");
GLADE_HOOKUP_OBJECT (mainwin, crop1, "crop1");
GLADE_HOOKUP_OBJECT (mainwin, find1, "find1");
+ GLADE_HOOKUP_OBJECT (mainwin, sort_by1, "sort_by1");
+ GLADE_HOOKUP_OBJECT (mainwin, sort_by1_menu, "sort_by1_menu");
+ GLADE_HOOKUP_OBJECT (mainwin, album1, "album1");
+ GLADE_HOOKUP_OBJECT (mainwin, artist1, "artist1");
+ GLADE_HOOKUP_OBJECT (mainwin, date1, "date1");
+ GLADE_HOOKUP_OBJECT (mainwin, custom2, "custom2");
GLADE_HOOKUP_OBJECT (mainwin, separator5, "separator5");
GLADE_HOOKUP_OBJECT (mainwin, preferences, "preferences");
GLADE_HOOKUP_OBJECT (mainwin, View, "View");
@@ -773,6 +830,7 @@ create_mainwin (void)
GLADE_HOOKUP_OBJECT (mainwin, Order_menu, "Order_menu");
GLADE_HOOKUP_OBJECT (mainwin, order_linear, "order_linear");
GLADE_HOOKUP_OBJECT (mainwin, order_shuffle, "order_shuffle");
+ GLADE_HOOKUP_OBJECT (mainwin, order_shuffle_albums, "order_shuffle_albums");
GLADE_HOOKUP_OBJECT (mainwin, order_random, "order_random");
GLADE_HOOKUP_OBJECT (mainwin, Looping, "Looping");
GLADE_HOOKUP_OBJECT (mainwin, Looping_menu, "Looping_menu");
@@ -787,16 +845,16 @@ create_mainwin (void)
GLADE_HOOKUP_OBJECT (mainwin, Help, "Help");
GLADE_HOOKUP_OBJECT (mainwin, Help_menu, "Help_menu");
GLADE_HOOKUP_OBJECT (mainwin, help1, "help1");
- GLADE_HOOKUP_OBJECT (mainwin, image458, "image458");
+ GLADE_HOOKUP_OBJECT (mainwin, image518, "image518");
GLADE_HOOKUP_OBJECT (mainwin, changelog1, "changelog1");
GLADE_HOOKUP_OBJECT (mainwin, separator10, "separator10");
GLADE_HOOKUP_OBJECT (mainwin, gpl1, "gpl1");
GLADE_HOOKUP_OBJECT (mainwin, lgpl1, "lgpl1");
GLADE_HOOKUP_OBJECT (mainwin, separator9, "separator9");
GLADE_HOOKUP_OBJECT (mainwin, about1, "about1");
- GLADE_HOOKUP_OBJECT (mainwin, image459, "image459");
+ GLADE_HOOKUP_OBJECT (mainwin, image519, "image519");
GLADE_HOOKUP_OBJECT (mainwin, translators1, "translators1");
- GLADE_HOOKUP_OBJECT (mainwin, image460, "image460");
+ GLADE_HOOKUP_OBJECT (mainwin, image520, "image520");
GLADE_HOOKUP_OBJECT (mainwin, hbox2, "hbox2");
GLADE_HOOKUP_OBJECT (mainwin, hbox3, "hbox3");
GLADE_HOOKUP_OBJECT (mainwin, stopbtn, "stopbtn");
@@ -1027,26 +1085,26 @@ create_traymenu (void)
}
GtkWidget*
-create_addprogress (void)
+create_progressdlg (void)
{
- GtkWidget *addprogress;
+ GtkWidget *progressdlg;
GtkWidget *vbox6;
GtkWidget *progresstitle;
GtkWidget *hbox7;
GtkWidget *label22;
- GtkWidget *button3;
+ GtkWidget *cancelbtn;
- addprogress = gtk_window_new (GTK_WINDOW_TOPLEVEL);
- gtk_container_set_border_width (GTK_CONTAINER (addprogress), 12);
- gtk_window_set_title (GTK_WINDOW (addprogress), _("Adding files..."));
- gtk_window_set_position (GTK_WINDOW (addprogress), GTK_WIN_POS_CENTER_ON_PARENT);
- gtk_window_set_modal (GTK_WINDOW (addprogress), TRUE);
- gtk_window_set_skip_taskbar_hint (GTK_WINDOW (addprogress), TRUE);
- gtk_window_set_skip_pager_hint (GTK_WINDOW (addprogress), TRUE);
+ progressdlg = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ gtk_container_set_border_width (GTK_CONTAINER (progressdlg), 12);
+ gtk_window_set_title (GTK_WINDOW (progressdlg), "progressdlg");
+ gtk_window_set_position (GTK_WINDOW (progressdlg), GTK_WIN_POS_CENTER_ON_PARENT);
+ gtk_window_set_modal (GTK_WINDOW (progressdlg), TRUE);
+ gtk_window_set_skip_taskbar_hint (GTK_WINDOW (progressdlg), TRUE);
+ gtk_window_set_skip_pager_hint (GTK_WINDOW (progressdlg), TRUE);
vbox6 = gtk_vbox_new (FALSE, 8);
gtk_widget_show (vbox6);
- gtk_container_add (GTK_CONTAINER (addprogress), vbox6);
+ gtk_container_add (GTK_CONTAINER (progressdlg), vbox6);
progresstitle = gtk_entry_new ();
gtk_widget_show (progresstitle);
@@ -1064,26 +1122,19 @@ create_addprogress (void)
gtk_widget_show (label22);
gtk_box_pack_start (GTK_BOX (hbox7), label22, TRUE, FALSE, 0);
- button3 = gtk_button_new_from_stock ("gtk-cancel");
- gtk_widget_show (button3);
- gtk_box_pack_start (GTK_BOX (hbox7), button3, FALSE, FALSE, 0);
-
- g_signal_connect ((gpointer) addprogress, "delete_event",
- G_CALLBACK (on_addprogress_delete_event),
- NULL);
- g_signal_connect ((gpointer) button3, "clicked",
- G_CALLBACK (on_progress_abort),
- NULL);
+ cancelbtn = gtk_button_new_from_stock ("gtk-cancel");
+ gtk_widget_show (cancelbtn);
+ gtk_box_pack_start (GTK_BOX (hbox7), cancelbtn, FALSE, FALSE, 0);
/* Store pointers to all widgets, for use by lookup_widget(). */
- GLADE_HOOKUP_OBJECT_NO_REF (addprogress, addprogress, "addprogress");
- GLADE_HOOKUP_OBJECT (addprogress, vbox6, "vbox6");
- GLADE_HOOKUP_OBJECT (addprogress, progresstitle, "progresstitle");
- GLADE_HOOKUP_OBJECT (addprogress, hbox7, "hbox7");
- GLADE_HOOKUP_OBJECT (addprogress, label22, "label22");
- GLADE_HOOKUP_OBJECT (addprogress, button3, "button3");
-
- return addprogress;
+ GLADE_HOOKUP_OBJECT_NO_REF (progressdlg, progressdlg, "progressdlg");
+ GLADE_HOOKUP_OBJECT (progressdlg, vbox6, "vbox6");
+ GLADE_HOOKUP_OBJECT (progressdlg, progresstitle, "progresstitle");
+ GLADE_HOOKUP_OBJECT (progressdlg, hbox7, "hbox7");
+ GLADE_HOOKUP_OBJECT (progressdlg, label22, "label22");
+ GLADE_HOOKUP_OBJECT (progressdlg, cancelbtn, "cancelbtn");
+
+ return progressdlg;
}
GtkWidget*
@@ -1135,6 +1186,12 @@ create_trackproperties (void)
GtkWidget *vbox16;
GtkWidget *scrolledwindow5;
GtkWidget *metalist;
+ GtkWidget *hbox98;
+ GtkWidget *settings;
+ GtkWidget *alignment24;
+ GtkWidget *hbox99;
+ GtkWidget *image522;
+ GtkWidget *label123;
GtkWidget *hbuttonbox1;
GtkWidget *write_tags;
GtkWidget *alignment11;
@@ -1161,6 +1218,7 @@ create_trackproperties (void)
trackproperties = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_widget_set_size_request (trackproperties, 400, 400);
gtk_window_set_title (GTK_WINDOW (trackproperties), _("Track Properties"));
+ gtk_window_set_position (GTK_WINDOW (trackproperties), GTK_WIN_POS_MOUSE);
gtk_window_set_skip_taskbar_hint (GTK_WINDOW (trackproperties), TRUE);
gtk_window_set_skip_pager_hint (GTK_WINDOW (trackproperties), TRUE);
@@ -1184,9 +1242,33 @@ create_trackproperties (void)
gtk_container_add (GTK_CONTAINER (scrolledwindow5), metalist);
gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (metalist), TRUE);
+ hbox98 = gtk_hbox_new (FALSE, 0);
+ gtk_widget_show (hbox98);
+ gtk_box_pack_start (GTK_BOX (vbox16), hbox98, FALSE, FALSE, 0);
+
+ settings = gtk_button_new ();
+ gtk_widget_show (settings);
+ gtk_box_pack_start (GTK_BOX (hbox98), settings, FALSE, FALSE, 0);
+
+ alignment24 = gtk_alignment_new (0.5, 0.5, 0, 0);
+ gtk_widget_show (alignment24);
+ gtk_container_add (GTK_CONTAINER (settings), alignment24);
+
+ hbox99 = gtk_hbox_new (FALSE, 2);
+ gtk_widget_show (hbox99);
+ gtk_container_add (GTK_CONTAINER (alignment24), hbox99);
+
+ image522 = gtk_image_new_from_stock ("gtk-preferences", GTK_ICON_SIZE_BUTTON);
+ gtk_widget_show (image522);
+ gtk_box_pack_start (GTK_BOX (hbox99), image522, FALSE, FALSE, 0);
+
+ label123 = gtk_label_new_with_mnemonic (_("Settings"));
+ gtk_widget_show (label123);
+ gtk_box_pack_start (GTK_BOX (hbox99), label123, FALSE, FALSE, 0);
+
hbuttonbox1 = gtk_hbutton_box_new ();
gtk_widget_show (hbuttonbox1);
- gtk_box_pack_start (GTK_BOX (vbox16), hbuttonbox1, FALSE, FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (hbox98), hbuttonbox1, TRUE, TRUE, 0);
gtk_button_box_set_layout (GTK_BUTTON_BOX (hbuttonbox1), GTK_BUTTONBOX_END);
write_tags = gtk_button_new ();
@@ -1287,6 +1369,18 @@ create_trackproperties (void)
g_signal_connect ((gpointer) trackproperties, "delete_event",
G_CALLBACK (on_trackproperties_delete_event),
NULL);
+ g_signal_connect ((gpointer) trackproperties, "configure_event",
+ G_CALLBACK (on_trackproperties_configure_event),
+ NULL);
+ g_signal_connect ((gpointer) trackproperties, "window_state_event",
+ G_CALLBACK (on_trackproperties_window_state_event),
+ NULL);
+ g_signal_connect ((gpointer) metalist, "button_press_event",
+ G_CALLBACK (on_metalist_button_press_event),
+ NULL);
+ g_signal_connect ((gpointer) settings, "clicked",
+ G_CALLBACK (on_tagwriter_settings_clicked),
+ NULL);
g_signal_connect ((gpointer) write_tags, "clicked",
G_CALLBACK (on_write_tags_clicked),
NULL);
@@ -1303,6 +1397,12 @@ create_trackproperties (void)
GLADE_HOOKUP_OBJECT (trackproperties, vbox16, "vbox16");
GLADE_HOOKUP_OBJECT (trackproperties, scrolledwindow5, "scrolledwindow5");
GLADE_HOOKUP_OBJECT (trackproperties, metalist, "metalist");
+ GLADE_HOOKUP_OBJECT (trackproperties, hbox98, "hbox98");
+ GLADE_HOOKUP_OBJECT (trackproperties, settings, "settings");
+ GLADE_HOOKUP_OBJECT (trackproperties, alignment24, "alignment24");
+ GLADE_HOOKUP_OBJECT (trackproperties, hbox99, "hbox99");
+ GLADE_HOOKUP_OBJECT (trackproperties, image522, "image522");
+ GLADE_HOOKUP_OBJECT (trackproperties, label123, "label123");
GLADE_HOOKUP_OBJECT (trackproperties, hbuttonbox1, "hbuttonbox1");
GLADE_HOOKUP_OBJECT (trackproperties, write_tags, "write_tags");
GLADE_HOOKUP_OBJECT (trackproperties, alignment11, "alignment11");
@@ -1343,11 +1443,12 @@ create_editcolumndlg (void)
GtkWidget *id;
GtkWidget *hbox31;
GtkWidget *fmtlabel;
+ GtkWidget *hbox74;
GtkWidget *format;
+ GtkWidget *title_formatting_help_link;
GtkWidget *hbox32;
GtkWidget *label38;
GtkWidget *align;
- GtkWidget *label25;
GtkWidget *dialog_action_area1;
GtkWidget *cancelbutton1;
GtkWidget *alignment9;
@@ -1362,7 +1463,7 @@ create_editcolumndlg (void)
editcolumndlg = gtk_dialog_new ();
gtk_container_set_border_width (GTK_CONTAINER (editcolumndlg), 12);
- gtk_window_set_title (GTK_WINDOW (editcolumndlg), _("editcolumndlg"));
+ gtk_window_set_title (GTK_WINDOW (editcolumndlg), "editcolumndlg");
gtk_window_set_modal (GTK_WINDOW (editcolumndlg), TRUE);
gtk_window_set_type_hint (GTK_WINDOW (editcolumndlg), GDK_WINDOW_TYPE_HINT_DIALOG);
@@ -1408,8 +1509,8 @@ create_editcolumndlg (void)
gtk_combo_box_append_text (GTK_COMBO_BOX (id), _("Artist"));
gtk_combo_box_append_text (GTK_COMBO_BOX (id), _("Album"));
gtk_combo_box_append_text (GTK_COMBO_BOX (id), _("Title"));
- gtk_combo_box_append_text (GTK_COMBO_BOX (id), _("Length"));
- gtk_combo_box_append_text (GTK_COMBO_BOX (id), _("Track"));
+ gtk_combo_box_append_text (GTK_COMBO_BOX (id), _("Duration"));
+ gtk_combo_box_append_text (GTK_COMBO_BOX (id), _("Track No"));
gtk_combo_box_append_text (GTK_COMBO_BOX (id), _("Band / Album Artist"));
gtk_combo_box_append_text (GTK_COMBO_BOX (id), _("Custom"));
@@ -1422,12 +1523,22 @@ create_editcolumndlg (void)
gtk_box_pack_start (GTK_BOX (hbox31), fmtlabel, FALSE, FALSE, 0);
gtk_misc_set_alignment (GTK_MISC (fmtlabel), 0, 0.5);
+ hbox74 = gtk_hbox_new (FALSE, 0);
+ gtk_widget_show (hbox74);
+ gtk_box_pack_start (GTK_BOX (hbox31), hbox74, TRUE, TRUE, 0);
+
format = gtk_entry_new ();
gtk_widget_show (format);
- gtk_box_pack_start (GTK_BOX (hbox31), format, TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (hbox74), format, TRUE, TRUE, 0);
gtk_entry_set_invisible_char (GTK_ENTRY (format), 9679);
gtk_entry_set_activates_default (GTK_ENTRY (format), TRUE);
+ title_formatting_help_link = title_formatting_help_link_create ("title_formatting_help_link", "", "", 0, 0);
+ gtk_widget_show (title_formatting_help_link);
+ gtk_box_pack_start (GTK_BOX (hbox74), title_formatting_help_link, TRUE, TRUE, 0);
+ GTK_WIDGET_UNSET_FLAGS (title_formatting_help_link, GTK_CAN_FOCUS);
+ GTK_WIDGET_UNSET_FLAGS (title_formatting_help_link, GTK_CAN_DEFAULT);
+
hbox32 = gtk_hbox_new (FALSE, 8);
gtk_widget_show (hbox32);
gtk_box_pack_start (GTK_BOX (vbox14), hbox32, FALSE, FALSE, 0);
@@ -1443,14 +1554,6 @@ create_editcolumndlg (void)
gtk_combo_box_append_text (GTK_COMBO_BOX (align), _("Left"));
gtk_combo_box_append_text (GTK_COMBO_BOX (align), _("Right"));
- label25 = gtk_label_new (_("Format conversions (start with %):\n [a]rtist, [t]itle, al[b]um, [B]and, [C]omposer\n track[n]umber, [N]totaltracks,\n [l]ength, [y]ear, [g]enre, [c]omment,\n copy[r]ight, [f]ilename, [F]ullPathname, [T]ags,\n [d]irectory, [D]irectoryWithPath\nExample: %a - %t [%l]"));
- gtk_widget_show (label25);
- gtk_box_pack_start (GTK_BOX (vbox14), label25, TRUE, TRUE, 0);
- GTK_WIDGET_SET_FLAGS (label25, GTK_CAN_FOCUS);
- gtk_label_set_use_markup (GTK_LABEL (label25), TRUE);
- gtk_label_set_selectable (GTK_LABEL (label25), TRUE);
- gtk_misc_set_alignment (GTK_MISC (label25), 0.1, 0.5);
-
dialog_action_area1 = GTK_DIALOG (editcolumndlg)->action_area;
gtk_widget_show (dialog_action_area1);
gtk_button_box_set_layout (GTK_BUTTON_BOX (dialog_action_area1), GTK_BUTTONBOX_END);
@@ -1513,11 +1616,12 @@ create_editcolumndlg (void)
GLADE_HOOKUP_OBJECT (editcolumndlg, id, "id");
GLADE_HOOKUP_OBJECT (editcolumndlg, hbox31, "hbox31");
GLADE_HOOKUP_OBJECT (editcolumndlg, fmtlabel, "fmtlabel");
+ GLADE_HOOKUP_OBJECT (editcolumndlg, hbox74, "hbox74");
GLADE_HOOKUP_OBJECT (editcolumndlg, format, "format");
+ GLADE_HOOKUP_OBJECT (editcolumndlg, title_formatting_help_link, "title_formatting_help_link");
GLADE_HOOKUP_OBJECT (editcolumndlg, hbox32, "hbox32");
GLADE_HOOKUP_OBJECT (editcolumndlg, label38, "label38");
GLADE_HOOKUP_OBJECT (editcolumndlg, align, "align");
- GLADE_HOOKUP_OBJECT (editcolumndlg, label25, "label25");
GLADE_HOOKUP_OBJECT_NO_REF (editcolumndlg, dialog_action_area1, "dialog_action_area1");
GLADE_HOOKUP_OBJECT (editcolumndlg, cancelbutton1, "cancelbutton1");
GLADE_HOOKUP_OBJECT (editcolumndlg, alignment9, "alignment9");
@@ -1548,31 +1652,57 @@ create_prefwin (void)
GtkWidget *pref_soundcard;
GtkWidget *Sound;
GtkWidget *vbox8;
- GtkWidget *pref_dynsamplerate;
- GtkWidget *hbox9;
- GtkWidget *label6;
- GtkWidget *pref_src_quality;
GtkWidget *hbox10;
GtkWidget *label8;
GtkWidget *pref_replaygain_mode;
GtkWidget *pref_replaygain_scale;
+ GtkWidget *hbox100;
+ GtkWidget *label124;
+ GtkWidget *label125;
+ GtkWidget *replaygain_preamp;
+ GtkWidget *label126;
GtkWidget *hbox66;
GtkWidget *cli_add_to_playlist;
GtkWidget *cli_playlist_name;
GtkWidget *resume_last_session;
+ GtkWidget *ignore_archives;
GtkWidget *label39;
+ GtkWidget *vbox29;
+ GtkWidget *hbox80;
+ GtkWidget *dsp_add;
+ GtkWidget *dsp_remove;
+ GtkWidget *dsp_configure;
+ GtkWidget *hbox81;
+ GtkWidget *scrolledwindow7;
+ GtkWidget *dsp_listview;
+ GtkWidget *vbox30;
+ GtkWidget *dsp_up;
+ GtkWidget *dsp_down;
+ GtkWidget *hbox86;
+ GtkWidget *label114;
+ GtkWidget *dsp_preset;
+ GtkWidget *dsp_preset_save;
+ GtkWidget *dsp_preset_load;
+ GtkWidget *label110;
GtkWidget *vbox9;
GtkWidget *pref_close_send_to_tray;
GtkWidget *mmb_delete_playlist;
GtkWidget *hide_tray_icon;
GtkWidget *embolden_current;
GtkWidget *hide_delete_from_disk;
+ GtkWidget *auto_name_playlist_from_folder;
+ GtkWidget *hbox102;
+ GtkWidget *label129;
+ GtkWidget *gui_fps;
GtkWidget *hbox64;
GtkWidget *label101;
GtkWidget *titlebar_format_playing;
GtkWidget *hbox65;
GtkWidget *label102;
GtkWidget *titlebar_format_stopped;
+ GtkWidget *hbox101;
+ GtkWidget *label128;
+ GtkWidget *gui_plugin;
GtkWidget *label2;
GtkWidget *notebook4;
GtkWidget *vbox21;
@@ -1594,6 +1724,8 @@ create_prefwin (void)
GtkWidget *tabstrip_dark;
GtkWidget *tabstrip_base;
GtkWidget *label76;
+ GtkWidget *label127;
+ GtkWidget *tabstrip_text;
GtkWidget *label74;
GtkWidget *vbox23;
GtkWidget *override_listview_colors;
@@ -1630,82 +1762,32 @@ create_prefwin (void)
GtkWidget *label98;
GtkWidget *proxypassword;
GtkWidget *label16;
- GtkWidget *vbox18;
- GtkWidget *frame5;
- GtkWidget *alignment3;
- GtkWidget *vbox19;
- GtkWidget *hbox38;
- GtkWidget *write_id3v2;
- GtkWidget *write_id3v1;
- GtkWidget *write_apev2;
- GtkWidget *hbox40;
- GtkWidget *strip_id3v2;
- GtkWidget *strip_id3v1;
- GtkWidget *strip_apev2;
- GtkWidget *hbox36;
- GtkWidget *label69;
- GtkWidget *id3v2_version;
- GtkWidget *hbox39;
- GtkWidget *label71;
- GtkWidget *id3v1_encoding;
- GtkWidget *label68;
- GtkWidget *hbox41;
- GtkWidget *frame6;
- GtkWidget *alignment4;
- GtkWidget *vbox20;
- GtkWidget *hbox37;
- GtkWidget *ape_write_id3v2;
- GtkWidget *ape_write_apev2;
- GtkWidget *hbox45;
- GtkWidget *ape_strip_id3v2;
- GtkWidget *ape_strip_apev2;
- GtkWidget *label70;
- GtkWidget *frame7;
- GtkWidget *alignment5;
- GtkWidget *vbox_wv;
- GtkWidget *hbox44;
- GtkWidget *wv_write_apev2;
- GtkWidget *wv_write_id3v1;
- GtkWidget *hbox43;
- GtkWidget *wv_strip_apev2;
- GtkWidget *wv_strip_id3v1;
- GtkWidget *label79;
- GtkWidget *label67;
GtkWidget *hpaned1;
GtkWidget *scrolledwindow2;
GtkWidget *pref_pluginlist;
GtkWidget *vbox12;
- GtkWidget *hbox16;
- GtkWidget *label11;
- GtkWidget *pref_plugin_descr;
- GtkWidget *hbox17;
- GtkWidget *label12;
- GtkWidget *pref_plugin_author;
- GtkWidget *hbox18;
- GtkWidget *label13;
- GtkWidget *pref_plugin_email;
- GtkWidget *hbox19;
- GtkWidget *label14;
- GtkWidget *pref_plugin_website;
+ GtkWidget *scrolledwindow8;
+ GtkWidget *plug_description;
GtkWidget *hbox20;
GtkWidget *configure_plugin;
GtkWidget *alignment15;
GtkWidget *hbox56;
GtkWidget *image394;
GtkWidget *label92;
+ GtkWidget *plug_copyright;
+ GtkWidget *alignment20;
+ GtkWidget *hbox88;
+ GtkWidget *image521;
+ GtkWidget *label117;
+ GtkWidget *weblink;
GtkWidget *label3;
GtkWidget *dialog_action_area2;
GtkWidget *closebutton1;
- GtkWidget *alignment14;
- GtkWidget *hbox55;
- GtkWidget *image393;
- GtkWidget *label91;
prefwin = gtk_dialog_new ();
- gtk_widget_set_size_request (prefwin, 630, 400);
gtk_container_set_border_width (GTK_CONTAINER (prefwin), 12);
gtk_window_set_title (GTK_WINDOW (prefwin), _("Preferences"));
- gtk_window_set_default_size (GTK_WINDOW (prefwin), 630, 400);
+ gtk_window_set_position (GTK_WINDOW (prefwin), GTK_WIN_POS_CENTER);
gtk_window_set_type_hint (GTK_WINDOW (prefwin), GDK_WINDOW_TYPE_HINT_DIALOG);
dialog_vbox2 = GTK_DIALOG (prefwin)->vbox;
@@ -1756,29 +1838,6 @@ create_prefwin (void)
gtk_container_add (GTK_CONTAINER (notebook), vbox8);
gtk_container_set_border_width (GTK_CONTAINER (vbox8), 12);
- pref_dynsamplerate = gtk_check_button_new_with_mnemonic (_("Allow dynamic samplerate switching"));
- gtk_widget_show (pref_dynsamplerate);
- gtk_box_pack_start (GTK_BOX (vbox8), pref_dynsamplerate, FALSE, FALSE, 0);
-
- hbox9 = gtk_hbox_new (FALSE, 8);
- gtk_widget_show (hbox9);
- gtk_box_pack_start (GTK_BOX (vbox8), hbox9, FALSE, FALSE, 0);
-
- label6 = gtk_label_new (_("Samplerate conversion quality:"));
- gtk_widget_show (label6);
- gtk_box_pack_start (GTK_BOX (hbox9), label6, FALSE, FALSE, 0);
- gtk_label_set_justify (GTK_LABEL (label6), GTK_JUSTIFY_RIGHT);
- gtk_misc_set_alignment (GTK_MISC (label6), 0, 0.5);
-
- pref_src_quality = gtk_combo_box_new_text ();
- gtk_widget_show (pref_src_quality);
- gtk_box_pack_start (GTK_BOX (hbox9), pref_src_quality, TRUE, TRUE, 0);
- gtk_combo_box_append_text (GTK_COMBO_BOX (pref_src_quality), "sinc_best_quality");
- gtk_combo_box_append_text (GTK_COMBO_BOX (pref_src_quality), "sinc_medium_quality");
- gtk_combo_box_append_text (GTK_COMBO_BOX (pref_src_quality), "sinc_fastest");
- gtk_combo_box_append_text (GTK_COMBO_BOX (pref_src_quality), "zero_order_hold");
- gtk_combo_box_append_text (GTK_COMBO_BOX (pref_src_quality), "linear");
-
hbox10 = gtk_hbox_new (FALSE, 8);
gtk_widget_show (hbox10);
gtk_box_pack_start (GTK_BOX (vbox8), hbox10, FALSE, FALSE, 0);
@@ -1800,6 +1859,28 @@ create_prefwin (void)
gtk_widget_show (pref_replaygain_scale);
gtk_box_pack_start (GTK_BOX (vbox8), pref_replaygain_scale, FALSE, FALSE, 0);
+ hbox100 = gtk_hbox_new (FALSE, 8);
+ gtk_widget_show (hbox100);
+ gtk_box_pack_start (GTK_BOX (vbox8), hbox100, FALSE, FALSE, 0);
+
+ label124 = gtk_label_new (_("Replaygain preamp:"));
+ gtk_widget_show (label124);
+ gtk_box_pack_start (GTK_BOX (hbox100), label124, FALSE, FALSE, 0);
+
+ label125 = gtk_label_new (_("-12 dB"));
+ gtk_widget_show (label125);
+ gtk_box_pack_start (GTK_BOX (hbox100), label125, FALSE, FALSE, 0);
+
+ replaygain_preamp = gtk_hscale_new (GTK_ADJUSTMENT (gtk_adjustment_new (0, -12, 12, 0, 0, 0)));
+ gtk_widget_show (replaygain_preamp);
+ gtk_box_pack_start (GTK_BOX (hbox100), replaygain_preamp, TRUE, TRUE, 0);
+ gtk_scale_set_value_pos (GTK_SCALE (replaygain_preamp), GTK_POS_BOTTOM);
+ gtk_scale_set_digits (GTK_SCALE (replaygain_preamp), 0);
+
+ label126 = gtk_label_new (_("+12 dB"));
+ gtk_widget_show (label126);
+ gtk_box_pack_start (GTK_BOX (hbox100), label126, FALSE, FALSE, 0);
+
hbox66 = gtk_hbox_new (FALSE, 8);
gtk_widget_show (hbox66);
gtk_box_pack_start (GTK_BOX (vbox8), hbox66, FALSE, FALSE, 0);
@@ -1817,10 +1898,86 @@ create_prefwin (void)
gtk_widget_show (resume_last_session);
gtk_box_pack_start (GTK_BOX (vbox8), resume_last_session, FALSE, FALSE, 0);
+ ignore_archives = gtk_check_button_new_with_mnemonic (_("Don't add from archives when adding folders"));
+ gtk_widget_show (ignore_archives);
+ gtk_box_pack_start (GTK_BOX (vbox8), ignore_archives, FALSE, FALSE, 0);
+
label39 = gtk_label_new (_("Playback"));
gtk_widget_show (label39);
gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook), gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook), 1), label39);
+ vbox29 = gtk_vbox_new (FALSE, 8);
+ gtk_widget_show (vbox29);
+ gtk_container_add (GTK_CONTAINER (notebook), vbox29);
+ gtk_container_set_border_width (GTK_CONTAINER (vbox29), 12);
+
+ hbox80 = gtk_hbox_new (TRUE, 8);
+ gtk_widget_show (hbox80);
+ gtk_box_pack_start (GTK_BOX (vbox29), hbox80, FALSE, TRUE, 0);
+
+ dsp_add = gtk_button_new_from_stock ("gtk-add");
+ gtk_widget_show (dsp_add);
+ gtk_box_pack_start (GTK_BOX (hbox80), dsp_add, FALSE, TRUE, 0);
+
+ dsp_remove = gtk_button_new_from_stock ("gtk-remove");
+ gtk_widget_show (dsp_remove);
+ gtk_box_pack_start (GTK_BOX (hbox80), dsp_remove, FALSE, TRUE, 0);
+
+ dsp_configure = gtk_button_new_with_mnemonic (_("Configure"));
+ gtk_widget_show (dsp_configure);
+ gtk_box_pack_start (GTK_BOX (hbox80), dsp_configure, FALSE, TRUE, 0);
+
+ hbox81 = gtk_hbox_new (FALSE, 8);
+ gtk_widget_show (hbox81);
+ gtk_box_pack_start (GTK_BOX (vbox29), hbox81, TRUE, TRUE, 0);
+
+ scrolledwindow7 = gtk_scrolled_window_new (NULL, NULL);
+ gtk_widget_show (scrolledwindow7);
+ gtk_box_pack_start (GTK_BOX (hbox81), scrolledwindow7, TRUE, TRUE, 0);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow7), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow7), GTK_SHADOW_IN);
+
+ dsp_listview = gtk_tree_view_new ();
+ gtk_widget_show (dsp_listview);
+ gtk_container_add (GTK_CONTAINER (scrolledwindow7), dsp_listview);
+ gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (dsp_listview), FALSE);
+
+ vbox30 = gtk_vbox_new (FALSE, 8);
+ gtk_widget_show (vbox30);
+ gtk_box_pack_start (GTK_BOX (hbox81), vbox30, FALSE, TRUE, 0);
+
+ dsp_up = gtk_button_new_from_stock ("gtk-go-up");
+ gtk_widget_show (dsp_up);
+ gtk_box_pack_start (GTK_BOX (vbox30), dsp_up, FALSE, FALSE, 0);
+
+ dsp_down = gtk_button_new_from_stock ("gtk-go-down");
+ gtk_widget_show (dsp_down);
+ gtk_box_pack_start (GTK_BOX (vbox30), dsp_down, FALSE, FALSE, 0);
+
+ hbox86 = gtk_hbox_new (FALSE, 8);
+ gtk_widget_show (hbox86);
+ gtk_box_pack_start (GTK_BOX (vbox29), hbox86, FALSE, TRUE, 0);
+
+ label114 = gtk_label_new (_("DSP Chain Preset"));
+ gtk_widget_show (label114);
+ gtk_box_pack_start (GTK_BOX (hbox86), label114, FALSE, FALSE, 0);
+
+ dsp_preset = gtk_combo_box_entry_new_text ();
+ gtk_widget_show (dsp_preset);
+ gtk_box_pack_start (GTK_BOX (hbox86), dsp_preset, FALSE, TRUE, 0);
+
+ dsp_preset_save = gtk_button_new_from_stock ("gtk-save");
+ gtk_widget_show (dsp_preset_save);
+ gtk_box_pack_start (GTK_BOX (hbox86), dsp_preset_save, FALSE, FALSE, 0);
+
+ dsp_preset_load = gtk_button_new_with_mnemonic (_("_Load"));
+ gtk_widget_show (dsp_preset_load);
+ gtk_box_pack_start (GTK_BOX (hbox86), dsp_preset_load, FALSE, FALSE, 0);
+
+ label110 = gtk_label_new (_("DSP"));
+ gtk_widget_show (label110);
+ gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook), gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook), 2), label110);
+
vbox9 = gtk_vbox_new (FALSE, 8);
gtk_widget_show (vbox9);
gtk_container_add (GTK_CONTAINER (notebook), vbox9);
@@ -1846,6 +2003,24 @@ create_prefwin (void)
gtk_widget_show (hide_delete_from_disk);
gtk_box_pack_start (GTK_BOX (vbox9), hide_delete_from_disk, FALSE, FALSE, 0);
+ auto_name_playlist_from_folder = gtk_check_button_new_with_mnemonic (_("Auto-name playlists when adding a single folder"));
+ gtk_widget_show (auto_name_playlist_from_folder);
+ gtk_box_pack_start (GTK_BOX (vbox9), auto_name_playlist_from_folder, FALSE, FALSE, 0);
+
+ hbox102 = gtk_hbox_new (FALSE, 8);
+ gtk_widget_show (hbox102);
+ gtk_box_pack_start (GTK_BOX (vbox9), hbox102, FALSE, FALSE, 0);
+
+ label129 = gtk_label_new (_("Interface refresh rate (times per second):"));
+ gtk_widget_show (label129);
+ gtk_box_pack_start (GTK_BOX (hbox102), label129, FALSE, FALSE, 0);
+
+ gui_fps = gtk_hscale_new (GTK_ADJUSTMENT (gtk_adjustment_new (10, 1, 30, 0, 0, 0)));
+ gtk_widget_show (gui_fps);
+ gtk_box_pack_start (GTK_BOX (hbox102), gui_fps, TRUE, TRUE, 0);
+ gtk_scale_set_value_pos (GTK_SCALE (gui_fps), GTK_POS_RIGHT);
+ gtk_scale_set_digits (GTK_SCALE (gui_fps), 0);
+
hbox64 = gtk_hbox_new (FALSE, 8);
gtk_widget_show (hbox64);
gtk_box_pack_start (GTK_BOX (vbox9), hbox64, FALSE, FALSE, 0);
@@ -1874,9 +2049,21 @@ create_prefwin (void)
gtk_box_pack_start (GTK_BOX (hbox65), titlebar_format_stopped, TRUE, TRUE, 0);
gtk_entry_set_invisible_char (GTK_ENTRY (titlebar_format_stopped), 8226);
+ hbox101 = gtk_hbox_new (FALSE, 8);
+ gtk_widget_show (hbox101);
+ gtk_box_pack_start (GTK_BOX (vbox9), hbox101, FALSE, FALSE, 0);
+
+ label128 = gtk_label_new (_("GUI Plugin (changing requires restart):"));
+ gtk_widget_show (label128);
+ gtk_box_pack_start (GTK_BOX (hbox101), label128, FALSE, FALSE, 0);
+
+ gui_plugin = gtk_combo_box_new_text ();
+ gtk_widget_show (gui_plugin);
+ gtk_box_pack_start (GTK_BOX (hbox101), gui_plugin, TRUE, TRUE, 0);
+
label2 = gtk_label_new (_("GUI"));
gtk_widget_show (label2);
- gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook), gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook), 2), label2);
+ gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook), gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook), 3), label2);
notebook4 = gtk_notebook_new ();
gtk_widget_show (notebook4);
@@ -1937,7 +2124,7 @@ create_prefwin (void)
gtk_widget_show (override_tabstrip_colors);
gtk_box_pack_start (GTK_BOX (vbox22), override_tabstrip_colors, FALSE, FALSE, 0);
- tabstrip_colors_group = gtk_table_new (2, 4, TRUE);
+ tabstrip_colors_group = gtk_table_new (2, 5, TRUE);
gtk_widget_show (tabstrip_colors_group);
gtk_box_pack_start (GTK_BOX (vbox22), tabstrip_colors_group, TRUE, TRUE, 0);
gtk_table_set_col_spacings (GTK_TABLE (tabstrip_colors_group), 8);
@@ -1994,6 +2181,19 @@ create_prefwin (void)
(GtkAttachOptions) (0), 0, 0);
gtk_misc_set_alignment (GTK_MISC (label76), 0, 0.5);
+ label127 = gtk_label_new (_("Text"));
+ gtk_widget_show (label127);
+ gtk_table_attach (GTK_TABLE (tabstrip_colors_group), label127, 4, 5, 0, 1,
+ (GtkAttachOptions) (GTK_EXPAND),
+ (GtkAttachOptions) (0), 0, 0);
+ gtk_misc_set_alignment (GTK_MISC (label127), 0, 0.5);
+
+ tabstrip_text = gtk_color_button_new ();
+ gtk_widget_show (tabstrip_text);
+ gtk_table_attach (GTK_TABLE (tabstrip_colors_group), tabstrip_text, 4, 5, 1, 2,
+ (GtkAttachOptions) (GTK_EXPAND),
+ (GtkAttachOptions) (0), 0, 0);
+
label74 = gtk_label_new (_("Tab strip colors"));
gtk_widget_show (label74);
gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook4), gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook4), 1), label74);
@@ -2096,7 +2296,7 @@ create_prefwin (void)
label100 = gtk_label_new (_("Colors"));
gtk_widget_show (label100);
- gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook), gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook), 3), label100);
+ gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook), gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook), 4), label100);
vbox11 = gtk_vbox_new (FALSE, 8);
gtk_widget_show (vbox11);
@@ -2183,187 +2383,7 @@ create_prefwin (void)
label16 = gtk_label_new (_("Network"));
gtk_widget_show (label16);
- gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook), gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook), 4), label16);
-
- vbox18 = gtk_vbox_new (FALSE, 0);
- gtk_widget_show (vbox18);
- gtk_container_add (GTK_CONTAINER (notebook), vbox18);
- gtk_container_set_border_width (GTK_CONTAINER (vbox18), 12);
-
- frame5 = gtk_frame_new (NULL);
- gtk_widget_show (frame5);
- gtk_box_pack_start (GTK_BOX (vbox18), frame5, FALSE, TRUE, 0);
- gtk_frame_set_shadow_type (GTK_FRAME (frame5), GTK_SHADOW_NONE);
-
- alignment3 = gtk_alignment_new (0.5, 0.5, 1, 1);
- gtk_widget_show (alignment3);
- gtk_container_add (GTK_CONTAINER (frame5), alignment3);
- gtk_alignment_set_padding (GTK_ALIGNMENT (alignment3), 0, 0, 12, 0);
-
- vbox19 = gtk_vbox_new (FALSE, 8);
- gtk_widget_show (vbox19);
- gtk_container_add (GTK_CONTAINER (alignment3), vbox19);
- gtk_container_set_border_width (GTK_CONTAINER (vbox19), 12);
-
- hbox38 = gtk_hbox_new (FALSE, 8);
- gtk_widget_show (hbox38);
- gtk_box_pack_start (GTK_BOX (vbox19), hbox38, FALSE, FALSE, 0);
-
- write_id3v2 = gtk_check_button_new_with_mnemonic (_("Write ID3v2"));
- gtk_widget_show (write_id3v2);
- gtk_box_pack_start (GTK_BOX (hbox38), write_id3v2, FALSE, FALSE, 0);
-
- write_id3v1 = gtk_check_button_new_with_mnemonic (_("Write ID3v1"));
- gtk_widget_show (write_id3v1);
- gtk_box_pack_start (GTK_BOX (hbox38), write_id3v1, FALSE, FALSE, 0);
-
- write_apev2 = gtk_check_button_new_with_mnemonic (_("Write APEv2"));
- gtk_widget_show (write_apev2);
- gtk_box_pack_start (GTK_BOX (hbox38), write_apev2, FALSE, FALSE, 0);
-
- hbox40 = gtk_hbox_new (FALSE, 8);
- gtk_widget_show (hbox40);
- gtk_box_pack_start (GTK_BOX (vbox19), hbox40, FALSE, FALSE, 0);
-
- strip_id3v2 = gtk_check_button_new_with_mnemonic (_("Strip ID3v2"));
- gtk_widget_show (strip_id3v2);
- gtk_box_pack_start (GTK_BOX (hbox40), strip_id3v2, FALSE, FALSE, 0);
-
- strip_id3v1 = gtk_check_button_new_with_mnemonic (_("Strip ID3v1"));
- gtk_widget_show (strip_id3v1);
- gtk_box_pack_start (GTK_BOX (hbox40), strip_id3v1, FALSE, FALSE, 0);
-
- strip_apev2 = gtk_check_button_new_with_mnemonic (_("Strip APEv2"));
- gtk_widget_show (strip_apev2);
- gtk_box_pack_start (GTK_BOX (hbox40), strip_apev2, FALSE, FALSE, 0);
-
- hbox36 = gtk_hbox_new (FALSE, 8);
- gtk_widget_show (hbox36);
- gtk_box_pack_start (GTK_BOX (vbox19), hbox36, TRUE, TRUE, 0);
-
- label69 = gtk_label_new (_("ID3v2 version"));
- gtk_widget_show (label69);
- gtk_box_pack_start (GTK_BOX (hbox36), label69, FALSE, FALSE, 0);
-
- id3v2_version = gtk_combo_box_new_text ();
- gtk_widget_show (id3v2_version);
- gtk_box_pack_start (GTK_BOX (hbox36), id3v2_version, TRUE, TRUE, 0);
- gtk_combo_box_append_text (GTK_COMBO_BOX (id3v2_version), _("2.3 (Recommended)"));
- gtk_combo_box_append_text (GTK_COMBO_BOX (id3v2_version), _("2.4"));
-
- hbox39 = gtk_hbox_new (FALSE, 8);
- gtk_widget_show (hbox39);
- gtk_box_pack_start (GTK_BOX (vbox19), hbox39, TRUE, TRUE, 0);
-
- label71 = gtk_label_new (_("ID3v1 character encoding (default is iso8859-1)"));
- gtk_widget_show (label71);
- gtk_box_pack_start (GTK_BOX (hbox39), label71, FALSE, FALSE, 0);
-
- id3v1_encoding = gtk_entry_new ();
- gtk_widget_show (id3v1_encoding);
- gtk_box_pack_start (GTK_BOX (hbox39), id3v1_encoding, TRUE, TRUE, 0);
- gtk_entry_set_invisible_char (GTK_ENTRY (id3v1_encoding), 9679);
-
- label68 = gtk_label_new ("<b>MP3</b>");
- gtk_widget_show (label68);
- gtk_frame_set_label_widget (GTK_FRAME (frame5), label68);
- gtk_label_set_use_markup (GTK_LABEL (label68), TRUE);
-
- hbox41 = gtk_hbox_new (TRUE, 0);
- gtk_widget_show (hbox41);
- gtk_box_pack_start (GTK_BOX (vbox18), hbox41, FALSE, TRUE, 0);
-
- frame6 = gtk_frame_new (NULL);
- gtk_widget_show (frame6);
- gtk_box_pack_start (GTK_BOX (hbox41), frame6, TRUE, TRUE, 0);
- gtk_frame_set_shadow_type (GTK_FRAME (frame6), GTK_SHADOW_NONE);
-
- alignment4 = gtk_alignment_new (0.5, 0.5, 1, 1);
- gtk_widget_show (alignment4);
- gtk_container_add (GTK_CONTAINER (frame6), alignment4);
- gtk_alignment_set_padding (GTK_ALIGNMENT (alignment4), 0, 0, 12, 0);
-
- vbox20 = gtk_vbox_new (FALSE, 8);
- gtk_widget_show (vbox20);
- gtk_container_add (GTK_CONTAINER (alignment4), vbox20);
- gtk_container_set_border_width (GTK_CONTAINER (vbox20), 12);
-
- hbox37 = gtk_hbox_new (FALSE, 8);
- gtk_widget_show (hbox37);
- gtk_box_pack_start (GTK_BOX (vbox20), hbox37, TRUE, TRUE, 0);
-
- ape_write_id3v2 = gtk_check_button_new_with_mnemonic (_("Write ID3v2.4"));
- gtk_widget_show (ape_write_id3v2);
- gtk_box_pack_start (GTK_BOX (hbox37), ape_write_id3v2, FALSE, FALSE, 0);
-
- ape_write_apev2 = gtk_check_button_new_with_mnemonic (_("Write APEv2"));
- gtk_widget_show (ape_write_apev2);
- gtk_box_pack_start (GTK_BOX (hbox37), ape_write_apev2, FALSE, FALSE, 0);
-
- hbox45 = gtk_hbox_new (FALSE, 8);
- gtk_widget_show (hbox45);
- gtk_box_pack_start (GTK_BOX (vbox20), hbox45, TRUE, TRUE, 0);
-
- ape_strip_id3v2 = gtk_check_button_new_with_mnemonic (_("Strip ID3v2"));
- gtk_widget_show (ape_strip_id3v2);
- gtk_box_pack_start (GTK_BOX (hbox45), ape_strip_id3v2, FALSE, FALSE, 0);
-
- ape_strip_apev2 = gtk_check_button_new_with_mnemonic (_("Strip APEv2"));
- gtk_widget_show (ape_strip_apev2);
- gtk_box_pack_start (GTK_BOX (hbox45), ape_strip_apev2, FALSE, FALSE, 0);
-
- label70 = gtk_label_new ("<b>APE</b>");
- gtk_widget_show (label70);
- gtk_frame_set_label_widget (GTK_FRAME (frame6), label70);
- gtk_label_set_use_markup (GTK_LABEL (label70), TRUE);
-
- frame7 = gtk_frame_new (NULL);
- gtk_widget_show (frame7);
- gtk_box_pack_start (GTK_BOX (hbox41), frame7, TRUE, TRUE, 0);
- gtk_frame_set_shadow_type (GTK_FRAME (frame7), GTK_SHADOW_NONE);
-
- alignment5 = gtk_alignment_new (0.5, 0.5, 1, 1);
- gtk_widget_show (alignment5);
- gtk_container_add (GTK_CONTAINER (frame7), alignment5);
- gtk_alignment_set_padding (GTK_ALIGNMENT (alignment5), 0, 0, 12, 0);
-
- vbox_wv = gtk_vbox_new (FALSE, 8);
- gtk_widget_show (vbox_wv);
- gtk_container_add (GTK_CONTAINER (alignment5), vbox_wv);
- gtk_container_set_border_width (GTK_CONTAINER (vbox_wv), 12);
-
- hbox44 = gtk_hbox_new (FALSE, 8);
- gtk_widget_show (hbox44);
- gtk_box_pack_start (GTK_BOX (vbox_wv), hbox44, FALSE, FALSE, 0);
-
- wv_write_apev2 = gtk_check_button_new_with_mnemonic (_("Write APEv2"));
- gtk_widget_show (wv_write_apev2);
- gtk_box_pack_start (GTK_BOX (hbox44), wv_write_apev2, FALSE, FALSE, 0);
-
- wv_write_id3v1 = gtk_check_button_new_with_mnemonic (_("Write ID3v1"));
- gtk_widget_show (wv_write_id3v1);
- gtk_box_pack_start (GTK_BOX (hbox44), wv_write_id3v1, FALSE, FALSE, 0);
-
- hbox43 = gtk_hbox_new (FALSE, 8);
- gtk_widget_show (hbox43);
- gtk_box_pack_start (GTK_BOX (vbox_wv), hbox43, FALSE, FALSE, 0);
-
- wv_strip_apev2 = gtk_check_button_new_with_mnemonic (_("Strip APEv2"));
- gtk_widget_show (wv_strip_apev2);
- gtk_box_pack_start (GTK_BOX (hbox43), wv_strip_apev2, FALSE, FALSE, 0);
-
- wv_strip_id3v1 = gtk_check_button_new_with_mnemonic (_("Strip ID3v1"));
- gtk_widget_show (wv_strip_id3v1);
- gtk_box_pack_start (GTK_BOX (hbox43), wv_strip_id3v1, FALSE, FALSE, 0);
-
- label79 = gtk_label_new ("<b>WavPack</b>");
- gtk_widget_show (label79);
- gtk_frame_set_label_widget (GTK_FRAME (frame7), label79);
- gtk_label_set_use_markup (GTK_LABEL (label79), TRUE);
-
- label67 = gtk_label_new (_("Tag writer"));
- gtk_widget_show (label67);
- gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook), gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook), 5), label67);
+ gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook), gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook), 5), label16);
hpaned1 = gtk_hpaned_new ();
gtk_widget_show (hpaned1);
@@ -2388,65 +2408,17 @@ create_prefwin (void)
gtk_paned_pack2 (GTK_PANED (hpaned1), vbox12, TRUE, TRUE);
gtk_container_set_border_width (GTK_CONTAINER (vbox12), 12);
- hbox16 = gtk_hbox_new (FALSE, 8);
- gtk_widget_show (hbox16);
- gtk_box_pack_start (GTK_BOX (vbox12), hbox16, FALSE, FALSE, 0);
-
- label11 = gtk_label_new (_("Description:"));
- gtk_widget_show (label11);
- gtk_box_pack_start (GTK_BOX (hbox16), label11, FALSE, FALSE, 0);
- gtk_misc_set_alignment (GTK_MISC (label11), 0, 0.5);
-
- pref_plugin_descr = gtk_entry_new ();
- gtk_widget_show (pref_plugin_descr);
- gtk_box_pack_start (GTK_BOX (hbox16), pref_plugin_descr, TRUE, TRUE, 0);
- gtk_editable_set_editable (GTK_EDITABLE (pref_plugin_descr), FALSE);
- gtk_entry_set_invisible_char (GTK_ENTRY (pref_plugin_descr), 9679);
-
- hbox17 = gtk_hbox_new (FALSE, 8);
- gtk_widget_show (hbox17);
- gtk_box_pack_start (GTK_BOX (vbox12), hbox17, FALSE, FALSE, 0);
-
- label12 = gtk_label_new (_("Author(s):"));
- gtk_widget_show (label12);
- gtk_box_pack_start (GTK_BOX (hbox17), label12, FALSE, FALSE, 0);
- gtk_misc_set_alignment (GTK_MISC (label12), 0, 0.5);
-
- pref_plugin_author = gtk_entry_new ();
- gtk_widget_show (pref_plugin_author);
- gtk_box_pack_start (GTK_BOX (hbox17), pref_plugin_author, TRUE, TRUE, 0);
- gtk_editable_set_editable (GTK_EDITABLE (pref_plugin_author), FALSE);
- gtk_entry_set_invisible_char (GTK_ENTRY (pref_plugin_author), 9679);
-
- hbox18 = gtk_hbox_new (FALSE, 8);
- gtk_widget_show (hbox18);
- gtk_box_pack_start (GTK_BOX (vbox12), hbox18, FALSE, FALSE, 0);
-
- label13 = gtk_label_new (_("Email:"));
- gtk_widget_show (label13);
- gtk_box_pack_start (GTK_BOX (hbox18), label13, FALSE, FALSE, 0);
- gtk_misc_set_alignment (GTK_MISC (label13), 0, 0.5);
-
- pref_plugin_email = gtk_entry_new ();
- gtk_widget_show (pref_plugin_email);
- gtk_box_pack_start (GTK_BOX (hbox18), pref_plugin_email, TRUE, TRUE, 0);
- gtk_editable_set_editable (GTK_EDITABLE (pref_plugin_email), FALSE);
- gtk_entry_set_invisible_char (GTK_ENTRY (pref_plugin_email), 9679);
-
- hbox19 = gtk_hbox_new (FALSE, 8);
- gtk_widget_show (hbox19);
- gtk_box_pack_start (GTK_BOX (vbox12), hbox19, FALSE, FALSE, 0);
-
- label14 = gtk_label_new (_("Website:"));
- gtk_widget_show (label14);
- gtk_box_pack_start (GTK_BOX (hbox19), label14, FALSE, FALSE, 0);
- gtk_misc_set_alignment (GTK_MISC (label14), 0, 0.5);
-
- pref_plugin_website = gtk_entry_new ();
- gtk_widget_show (pref_plugin_website);
- gtk_box_pack_start (GTK_BOX (hbox19), pref_plugin_website, TRUE, TRUE, 0);
- gtk_editable_set_editable (GTK_EDITABLE (pref_plugin_website), FALSE);
- gtk_entry_set_invisible_char (GTK_ENTRY (pref_plugin_website), 9679);
+ scrolledwindow8 = gtk_scrolled_window_new (NULL, NULL);
+ gtk_widget_show (scrolledwindow8);
+ gtk_box_pack_start (GTK_BOX (vbox12), scrolledwindow8, TRUE, TRUE, 0);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow8), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow8), GTK_SHADOW_IN);
+
+ plug_description = gtk_text_view_new ();
+ gtk_widget_show (plug_description);
+ gtk_container_add (GTK_CONTAINER (scrolledwindow8), plug_description);
+ gtk_text_view_set_editable (GTK_TEXT_VIEW (plug_description), FALSE);
+ gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (plug_description), FALSE);
hbox20 = gtk_hbox_new (FALSE, 0);
gtk_widget_show (hbox20);
@@ -2455,6 +2427,7 @@ create_prefwin (void)
configure_plugin = gtk_button_new ();
gtk_widget_show (configure_plugin);
gtk_box_pack_start (GTK_BOX (hbox20), configure_plugin, TRUE, FALSE, 0);
+ gtk_widget_set_sensitive (configure_plugin, FALSE);
alignment15 = gtk_alignment_new (0.5, 0.5, 0, 0);
gtk_widget_show (alignment15);
@@ -2472,6 +2445,33 @@ create_prefwin (void)
gtk_widget_show (label92);
gtk_box_pack_start (GTK_BOX (hbox56), label92, FALSE, FALSE, 0);
+ plug_copyright = gtk_button_new ();
+ gtk_widget_show (plug_copyright);
+ gtk_box_pack_start (GTK_BOX (hbox20), plug_copyright, TRUE, FALSE, 0);
+ gtk_widget_set_sensitive (plug_copyright, FALSE);
+
+ alignment20 = gtk_alignment_new (0.5, 0.5, 0, 0);
+ gtk_widget_show (alignment20);
+ gtk_container_add (GTK_CONTAINER (plug_copyright), alignment20);
+
+ hbox88 = gtk_hbox_new (FALSE, 2);
+ gtk_widget_show (hbox88);
+ gtk_container_add (GTK_CONTAINER (alignment20), hbox88);
+
+ image521 = gtk_image_new_from_stock ("gtk-about", GTK_ICON_SIZE_BUTTON);
+ gtk_widget_show (image521);
+ gtk_box_pack_start (GTK_BOX (hbox88), image521, FALSE, FALSE, 0);
+
+ label117 = gtk_label_new_with_mnemonic (_("Copyright"));
+ gtk_widget_show (label117);
+ gtk_box_pack_start (GTK_BOX (hbox88), label117, FALSE, FALSE, 0);
+
+ weblink = create_plugin_weblink ("weblink", "", "", 0, 0);
+ gtk_widget_show (weblink);
+ gtk_box_pack_start (GTK_BOX (hbox20), weblink, TRUE, FALSE, 0);
+ GTK_WIDGET_UNSET_FLAGS (weblink, GTK_CAN_FOCUS);
+ GTK_WIDGET_UNSET_FLAGS (weblink, GTK_CAN_DEFAULT);
+
label3 = gtk_label_new (_("Plugins"));
gtk_widget_show (label3);
gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook), gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook), 6), label3);
@@ -2481,32 +2481,19 @@ create_prefwin (void)
gtk_widget_show (dialog_action_area2);
gtk_button_box_set_layout (GTK_BUTTON_BOX (dialog_action_area2), GTK_BUTTONBOX_END);
- closebutton1 = gtk_button_new ();
+ closebutton1 = gtk_button_new_from_stock ("gtk-close");
gtk_widget_show (closebutton1);
gtk_dialog_add_action_widget (GTK_DIALOG (prefwin), closebutton1, GTK_RESPONSE_CLOSE);
GTK_WIDGET_SET_FLAGS (closebutton1, GTK_CAN_DEFAULT);
- alignment14 = gtk_alignment_new (0.5, 0.5, 0, 0);
- gtk_widget_show (alignment14);
- gtk_container_add (GTK_CONTAINER (closebutton1), alignment14);
-
- hbox55 = gtk_hbox_new (FALSE, 2);
- gtk_widget_show (hbox55);
- gtk_container_add (GTK_CONTAINER (alignment14), hbox55);
-
- image393 = gtk_image_new_from_stock ("gtk-close", GTK_ICON_SIZE_BUTTON);
- gtk_widget_show (image393);
- gtk_box_pack_start (GTK_BOX (hbox55), image393, FALSE, FALSE, 0);
-
- label91 = gtk_label_new_with_mnemonic (_("_Close"));
- gtk_widget_show (label91);
- gtk_box_pack_start (GTK_BOX (hbox55), label91, FALSE, FALSE, 0);
-
- g_signal_connect ((gpointer) pref_dynsamplerate, "clicked",
- G_CALLBACK (on_pref_dynsamplerate_clicked),
+ g_signal_connect ((gpointer) prefwin, "configure_event",
+ G_CALLBACK (on_prefwin_configure_event),
NULL);
- g_signal_connect ((gpointer) pref_src_quality, "changed",
- G_CALLBACK (on_pref_src_quality_changed),
+ g_signal_connect ((gpointer) prefwin, "window_state_event",
+ G_CALLBACK (on_prefwin_window_state_event),
+ NULL);
+ g_signal_connect ((gpointer) prefwin, "realize",
+ G_CALLBACK (on_prefwin_realize),
NULL);
g_signal_connect ((gpointer) pref_replaygain_mode, "changed",
G_CALLBACK (on_pref_replaygain_mode_changed),
@@ -2514,6 +2501,9 @@ create_prefwin (void)
g_signal_connect ((gpointer) pref_replaygain_scale, "clicked",
G_CALLBACK (on_pref_replaygain_scale_clicked),
NULL);
+ g_signal_connect ((gpointer) replaygain_preamp, "value_changed",
+ G_CALLBACK (on_replaygain_preamp_value_changed),
+ NULL);
g_signal_connect ((gpointer) cli_add_to_playlist, "toggled",
G_CALLBACK (on_cli_add_to_playlist_toggled),
NULL);
@@ -2523,6 +2513,33 @@ create_prefwin (void)
g_signal_connect ((gpointer) resume_last_session, "toggled",
G_CALLBACK (on_resume_last_session_toggled),
NULL);
+ g_signal_connect ((gpointer) ignore_archives, "toggled",
+ G_CALLBACK (on_ignore_archives_toggled),
+ NULL);
+ g_signal_connect ((gpointer) dsp_add, "clicked",
+ G_CALLBACK (on_dsp_add_clicked),
+ NULL);
+ g_signal_connect ((gpointer) dsp_remove, "clicked",
+ G_CALLBACK (on_dsp_remove_clicked),
+ NULL);
+ g_signal_connect ((gpointer) dsp_configure, "clicked",
+ G_CALLBACK (on_dsp_configure_clicked),
+ NULL);
+ g_signal_connect ((gpointer) dsp_up, "clicked",
+ G_CALLBACK (on_dsp_up_clicked),
+ NULL);
+ g_signal_connect ((gpointer) dsp_down, "clicked",
+ G_CALLBACK (on_dsp_down_clicked),
+ NULL);
+ g_signal_connect ((gpointer) dsp_preset, "changed",
+ G_CALLBACK (on_dsp_preset_changed),
+ NULL);
+ g_signal_connect ((gpointer) dsp_preset_save, "clicked",
+ G_CALLBACK (on_dsp_preset_save_clicked),
+ NULL);
+ g_signal_connect ((gpointer) dsp_preset_load, "clicked",
+ G_CALLBACK (on_dsp_preset_load_clicked),
+ NULL);
g_signal_connect ((gpointer) pref_close_send_to_tray, "clicked",
G_CALLBACK (on_pref_close_send_to_tray_clicked),
NULL);
@@ -2538,12 +2555,21 @@ create_prefwin (void)
g_signal_connect ((gpointer) hide_delete_from_disk, "toggled",
G_CALLBACK (on_hide_delete_from_disk_toggled),
NULL);
+ g_signal_connect ((gpointer) auto_name_playlist_from_folder, "toggled",
+ G_CALLBACK (on_auto_name_playlist_from_folder_toggled),
+ NULL);
+ g_signal_connect ((gpointer) gui_fps, "value_changed",
+ G_CALLBACK (on_gui_fps_value_changed),
+ NULL);
g_signal_connect ((gpointer) titlebar_format_playing, "changed",
G_CALLBACK (on_titlebar_format_playing_changed),
NULL);
g_signal_connect ((gpointer) titlebar_format_stopped, "changed",
G_CALLBACK (on_titlebar_format_stopped_changed),
NULL);
+ g_signal_connect ((gpointer) gui_plugin, "changed",
+ G_CALLBACK (on_gui_plugin_changed),
+ NULL);
g_signal_connect ((gpointer) override_bar_colors, "toggled",
G_CALLBACK (on_override_bar_colors_toggled),
NULL);
@@ -2568,6 +2594,9 @@ create_prefwin (void)
g_signal_connect ((gpointer) tabstrip_base, "color_set",
G_CALLBACK (on_tabstrip_base_color_set),
NULL);
+ g_signal_connect ((gpointer) tabstrip_text, "color_set",
+ G_CALLBACK (on_tabstrip_text_color_set),
+ NULL);
g_signal_connect ((gpointer) override_listview_colors, "toggled",
G_CALLBACK (on_override_listview_colors_toggled),
NULL);
@@ -2607,60 +2636,15 @@ create_prefwin (void)
g_signal_connect ((gpointer) proxypassword, "changed",
G_CALLBACK (on_proxypassword_changed),
NULL);
- g_signal_connect ((gpointer) write_id3v2, "toggled",
- G_CALLBACK (on_write_id3v2_toggled),
- NULL);
- g_signal_connect ((gpointer) write_id3v1, "toggled",
- G_CALLBACK (on_write_id3v1_toggled),
- NULL);
- g_signal_connect ((gpointer) write_apev2, "toggled",
- G_CALLBACK (on_write_apev2_toggled),
- NULL);
- g_signal_connect ((gpointer) strip_id3v2, "toggled",
- G_CALLBACK (on_strip_id3v2_toggled),
- NULL);
- g_signal_connect ((gpointer) strip_id3v1, "toggled",
- G_CALLBACK (on_strip_id3v1_toggled),
- NULL);
- g_signal_connect ((gpointer) strip_apev2, "toggled",
- G_CALLBACK (on_strip_apev2_toggled),
- NULL);
- g_signal_connect ((gpointer) id3v2_version, "changed",
- G_CALLBACK (on_id3v2_version_changed),
- NULL);
- g_signal_connect ((gpointer) id3v1_encoding, "changed",
- G_CALLBACK (on_id3v1_encoding_changed),
- NULL);
- g_signal_connect ((gpointer) ape_write_id3v2, "toggled",
- G_CALLBACK (on_ape_write_id3v2_toggled),
- NULL);
- g_signal_connect ((gpointer) ape_write_apev2, "toggled",
- G_CALLBACK (on_ape_write_apev2_toggled),
- NULL);
- g_signal_connect ((gpointer) ape_strip_id3v2, "toggled",
- G_CALLBACK (on_ape_strip_id3v2_toggled),
- NULL);
- g_signal_connect ((gpointer) ape_strip_apev2, "toggled",
- G_CALLBACK (on_ape_strip_apev2_toggled),
- NULL);
- g_signal_connect ((gpointer) wv_write_apev2, "toggled",
- G_CALLBACK (on_wv_write_apev2_toggled),
- NULL);
- g_signal_connect ((gpointer) wv_write_id3v1, "toggled",
- G_CALLBACK (on_wv_write_id3v1_toggled),
- NULL);
- g_signal_connect ((gpointer) wv_strip_apev2, "toggled",
- G_CALLBACK (on_wv_strip_apev2_toggled),
- NULL);
- g_signal_connect ((gpointer) wv_strip_id3v1, "toggled",
- G_CALLBACK (on_wv_strip_id3v1_toggled),
- NULL);
g_signal_connect ((gpointer) pref_pluginlist, "cursor_changed",
G_CALLBACK (on_pref_pluginlist_cursor_changed),
NULL);
g_signal_connect ((gpointer) configure_plugin, "clicked",
G_CALLBACK (on_configure_plugin_clicked),
NULL);
+ g_signal_connect ((gpointer) plug_copyright, "clicked",
+ G_CALLBACK (on_plug_copyright_clicked),
+ NULL);
/* Store pointers to all widgets, for use by lookup_widget(). */
GLADE_HOOKUP_OBJECT_NO_REF (prefwin, prefwin, "prefwin");
@@ -2675,31 +2659,57 @@ create_prefwin (void)
GLADE_HOOKUP_OBJECT (prefwin, pref_soundcard, "pref_soundcard");
GLADE_HOOKUP_OBJECT (prefwin, Sound, "Sound");
GLADE_HOOKUP_OBJECT (prefwin, vbox8, "vbox8");
- GLADE_HOOKUP_OBJECT (prefwin, pref_dynsamplerate, "pref_dynsamplerate");
- GLADE_HOOKUP_OBJECT (prefwin, hbox9, "hbox9");
- GLADE_HOOKUP_OBJECT (prefwin, label6, "label6");
- GLADE_HOOKUP_OBJECT (prefwin, pref_src_quality, "pref_src_quality");
GLADE_HOOKUP_OBJECT (prefwin, hbox10, "hbox10");
GLADE_HOOKUP_OBJECT (prefwin, label8, "label8");
GLADE_HOOKUP_OBJECT (prefwin, pref_replaygain_mode, "pref_replaygain_mode");
GLADE_HOOKUP_OBJECT (prefwin, pref_replaygain_scale, "pref_replaygain_scale");
+ GLADE_HOOKUP_OBJECT (prefwin, hbox100, "hbox100");
+ GLADE_HOOKUP_OBJECT (prefwin, label124, "label124");
+ GLADE_HOOKUP_OBJECT (prefwin, label125, "label125");
+ GLADE_HOOKUP_OBJECT (prefwin, replaygain_preamp, "replaygain_preamp");
+ GLADE_HOOKUP_OBJECT (prefwin, label126, "label126");
GLADE_HOOKUP_OBJECT (prefwin, hbox66, "hbox66");
GLADE_HOOKUP_OBJECT (prefwin, cli_add_to_playlist, "cli_add_to_playlist");
GLADE_HOOKUP_OBJECT (prefwin, cli_playlist_name, "cli_playlist_name");
GLADE_HOOKUP_OBJECT (prefwin, resume_last_session, "resume_last_session");
+ GLADE_HOOKUP_OBJECT (prefwin, ignore_archives, "ignore_archives");
GLADE_HOOKUP_OBJECT (prefwin, label39, "label39");
+ GLADE_HOOKUP_OBJECT (prefwin, vbox29, "vbox29");
+ GLADE_HOOKUP_OBJECT (prefwin, hbox80, "hbox80");
+ GLADE_HOOKUP_OBJECT (prefwin, dsp_add, "dsp_add");
+ GLADE_HOOKUP_OBJECT (prefwin, dsp_remove, "dsp_remove");
+ GLADE_HOOKUP_OBJECT (prefwin, dsp_configure, "dsp_configure");
+ GLADE_HOOKUP_OBJECT (prefwin, hbox81, "hbox81");
+ GLADE_HOOKUP_OBJECT (prefwin, scrolledwindow7, "scrolledwindow7");
+ GLADE_HOOKUP_OBJECT (prefwin, dsp_listview, "dsp_listview");
+ GLADE_HOOKUP_OBJECT (prefwin, vbox30, "vbox30");
+ GLADE_HOOKUP_OBJECT (prefwin, dsp_up, "dsp_up");
+ GLADE_HOOKUP_OBJECT (prefwin, dsp_down, "dsp_down");
+ GLADE_HOOKUP_OBJECT (prefwin, hbox86, "hbox86");
+ GLADE_HOOKUP_OBJECT (prefwin, label114, "label114");
+ GLADE_HOOKUP_OBJECT (prefwin, dsp_preset, "dsp_preset");
+ GLADE_HOOKUP_OBJECT (prefwin, dsp_preset_save, "dsp_preset_save");
+ GLADE_HOOKUP_OBJECT (prefwin, dsp_preset_load, "dsp_preset_load");
+ GLADE_HOOKUP_OBJECT (prefwin, label110, "label110");
GLADE_HOOKUP_OBJECT (prefwin, vbox9, "vbox9");
GLADE_HOOKUP_OBJECT (prefwin, pref_close_send_to_tray, "pref_close_send_to_tray");
GLADE_HOOKUP_OBJECT (prefwin, mmb_delete_playlist, "mmb_delete_playlist");
GLADE_HOOKUP_OBJECT (prefwin, hide_tray_icon, "hide_tray_icon");
GLADE_HOOKUP_OBJECT (prefwin, embolden_current, "embolden_current");
GLADE_HOOKUP_OBJECT (prefwin, hide_delete_from_disk, "hide_delete_from_disk");
+ GLADE_HOOKUP_OBJECT (prefwin, auto_name_playlist_from_folder, "auto_name_playlist_from_folder");
+ GLADE_HOOKUP_OBJECT (prefwin, hbox102, "hbox102");
+ GLADE_HOOKUP_OBJECT (prefwin, label129, "label129");
+ GLADE_HOOKUP_OBJECT (prefwin, gui_fps, "gui_fps");
GLADE_HOOKUP_OBJECT (prefwin, hbox64, "hbox64");
GLADE_HOOKUP_OBJECT (prefwin, label101, "label101");
GLADE_HOOKUP_OBJECT (prefwin, titlebar_format_playing, "titlebar_format_playing");
GLADE_HOOKUP_OBJECT (prefwin, hbox65, "hbox65");
GLADE_HOOKUP_OBJECT (prefwin, label102, "label102");
GLADE_HOOKUP_OBJECT (prefwin, titlebar_format_stopped, "titlebar_format_stopped");
+ GLADE_HOOKUP_OBJECT (prefwin, hbox101, "hbox101");
+ GLADE_HOOKUP_OBJECT (prefwin, label128, "label128");
+ GLADE_HOOKUP_OBJECT (prefwin, gui_plugin, "gui_plugin");
GLADE_HOOKUP_OBJECT (prefwin, label2, "label2");
GLADE_HOOKUP_OBJECT (prefwin, notebook4, "notebook4");
GLADE_HOOKUP_OBJECT (prefwin, vbox21, "vbox21");
@@ -2721,6 +2731,8 @@ create_prefwin (void)
GLADE_HOOKUP_OBJECT (prefwin, tabstrip_dark, "tabstrip_dark");
GLADE_HOOKUP_OBJECT (prefwin, tabstrip_base, "tabstrip_base");
GLADE_HOOKUP_OBJECT (prefwin, label76, "label76");
+ GLADE_HOOKUP_OBJECT (prefwin, label127, "label127");
+ GLADE_HOOKUP_OBJECT (prefwin, tabstrip_text, "tabstrip_text");
GLADE_HOOKUP_OBJECT (prefwin, label74, "label74");
GLADE_HOOKUP_OBJECT (prefwin, vbox23, "vbox23");
GLADE_HOOKUP_OBJECT (prefwin, override_listview_colors, "override_listview_colors");
@@ -2757,88 +2769,39 @@ create_prefwin (void)
GLADE_HOOKUP_OBJECT (prefwin, label98, "label98");
GLADE_HOOKUP_OBJECT (prefwin, proxypassword, "proxypassword");
GLADE_HOOKUP_OBJECT (prefwin, label16, "label16");
- GLADE_HOOKUP_OBJECT (prefwin, vbox18, "vbox18");
- GLADE_HOOKUP_OBJECT (prefwin, frame5, "frame5");
- GLADE_HOOKUP_OBJECT (prefwin, alignment3, "alignment3");
- GLADE_HOOKUP_OBJECT (prefwin, vbox19, "vbox19");
- GLADE_HOOKUP_OBJECT (prefwin, hbox38, "hbox38");
- GLADE_HOOKUP_OBJECT (prefwin, write_id3v2, "write_id3v2");
- GLADE_HOOKUP_OBJECT (prefwin, write_id3v1, "write_id3v1");
- GLADE_HOOKUP_OBJECT (prefwin, write_apev2, "write_apev2");
- GLADE_HOOKUP_OBJECT (prefwin, hbox40, "hbox40");
- GLADE_HOOKUP_OBJECT (prefwin, strip_id3v2, "strip_id3v2");
- GLADE_HOOKUP_OBJECT (prefwin, strip_id3v1, "strip_id3v1");
- GLADE_HOOKUP_OBJECT (prefwin, strip_apev2, "strip_apev2");
- GLADE_HOOKUP_OBJECT (prefwin, hbox36, "hbox36");
- GLADE_HOOKUP_OBJECT (prefwin, label69, "label69");
- GLADE_HOOKUP_OBJECT (prefwin, id3v2_version, "id3v2_version");
- GLADE_HOOKUP_OBJECT (prefwin, hbox39, "hbox39");
- GLADE_HOOKUP_OBJECT (prefwin, label71, "label71");
- GLADE_HOOKUP_OBJECT (prefwin, id3v1_encoding, "id3v1_encoding");
- GLADE_HOOKUP_OBJECT (prefwin, label68, "label68");
- GLADE_HOOKUP_OBJECT (prefwin, hbox41, "hbox41");
- GLADE_HOOKUP_OBJECT (prefwin, frame6, "frame6");
- GLADE_HOOKUP_OBJECT (prefwin, alignment4, "alignment4");
- GLADE_HOOKUP_OBJECT (prefwin, vbox20, "vbox20");
- GLADE_HOOKUP_OBJECT (prefwin, hbox37, "hbox37");
- GLADE_HOOKUP_OBJECT (prefwin, ape_write_id3v2, "ape_write_id3v2");
- GLADE_HOOKUP_OBJECT (prefwin, ape_write_apev2, "ape_write_apev2");
- GLADE_HOOKUP_OBJECT (prefwin, hbox45, "hbox45");
- GLADE_HOOKUP_OBJECT (prefwin, ape_strip_id3v2, "ape_strip_id3v2");
- GLADE_HOOKUP_OBJECT (prefwin, ape_strip_apev2, "ape_strip_apev2");
- GLADE_HOOKUP_OBJECT (prefwin, label70, "label70");
- GLADE_HOOKUP_OBJECT (prefwin, frame7, "frame7");
- GLADE_HOOKUP_OBJECT (prefwin, alignment5, "alignment5");
- GLADE_HOOKUP_OBJECT (prefwin, vbox_wv, "vbox_wv");
- GLADE_HOOKUP_OBJECT (prefwin, hbox44, "hbox44");
- GLADE_HOOKUP_OBJECT (prefwin, wv_write_apev2, "wv_write_apev2");
- GLADE_HOOKUP_OBJECT (prefwin, wv_write_id3v1, "wv_write_id3v1");
- GLADE_HOOKUP_OBJECT (prefwin, hbox43, "hbox43");
- GLADE_HOOKUP_OBJECT (prefwin, wv_strip_apev2, "wv_strip_apev2");
- GLADE_HOOKUP_OBJECT (prefwin, wv_strip_id3v1, "wv_strip_id3v1");
- GLADE_HOOKUP_OBJECT (prefwin, label79, "label79");
- GLADE_HOOKUP_OBJECT (prefwin, label67, "label67");
GLADE_HOOKUP_OBJECT (prefwin, hpaned1, "hpaned1");
GLADE_HOOKUP_OBJECT (prefwin, scrolledwindow2, "scrolledwindow2");
GLADE_HOOKUP_OBJECT (prefwin, pref_pluginlist, "pref_pluginlist");
GLADE_HOOKUP_OBJECT (prefwin, vbox12, "vbox12");
- GLADE_HOOKUP_OBJECT (prefwin, hbox16, "hbox16");
- GLADE_HOOKUP_OBJECT (prefwin, label11, "label11");
- GLADE_HOOKUP_OBJECT (prefwin, pref_plugin_descr, "pref_plugin_descr");
- GLADE_HOOKUP_OBJECT (prefwin, hbox17, "hbox17");
- GLADE_HOOKUP_OBJECT (prefwin, label12, "label12");
- GLADE_HOOKUP_OBJECT (prefwin, pref_plugin_author, "pref_plugin_author");
- GLADE_HOOKUP_OBJECT (prefwin, hbox18, "hbox18");
- GLADE_HOOKUP_OBJECT (prefwin, label13, "label13");
- GLADE_HOOKUP_OBJECT (prefwin, pref_plugin_email, "pref_plugin_email");
- GLADE_HOOKUP_OBJECT (prefwin, hbox19, "hbox19");
- GLADE_HOOKUP_OBJECT (prefwin, label14, "label14");
- GLADE_HOOKUP_OBJECT (prefwin, pref_plugin_website, "pref_plugin_website");
+ GLADE_HOOKUP_OBJECT (prefwin, scrolledwindow8, "scrolledwindow8");
+ GLADE_HOOKUP_OBJECT (prefwin, plug_description, "plug_description");
GLADE_HOOKUP_OBJECT (prefwin, hbox20, "hbox20");
GLADE_HOOKUP_OBJECT (prefwin, configure_plugin, "configure_plugin");
GLADE_HOOKUP_OBJECT (prefwin, alignment15, "alignment15");
GLADE_HOOKUP_OBJECT (prefwin, hbox56, "hbox56");
GLADE_HOOKUP_OBJECT (prefwin, image394, "image394");
GLADE_HOOKUP_OBJECT (prefwin, label92, "label92");
+ GLADE_HOOKUP_OBJECT (prefwin, plug_copyright, "plug_copyright");
+ GLADE_HOOKUP_OBJECT (prefwin, alignment20, "alignment20");
+ GLADE_HOOKUP_OBJECT (prefwin, hbox88, "hbox88");
+ GLADE_HOOKUP_OBJECT (prefwin, image521, "image521");
+ GLADE_HOOKUP_OBJECT (prefwin, label117, "label117");
+ GLADE_HOOKUP_OBJECT (prefwin, weblink, "weblink");
GLADE_HOOKUP_OBJECT (prefwin, label3, "label3");
GLADE_HOOKUP_OBJECT_NO_REF (prefwin, dialog_action_area2, "dialog_action_area2");
GLADE_HOOKUP_OBJECT (prefwin, closebutton1, "closebutton1");
- GLADE_HOOKUP_OBJECT (prefwin, alignment14, "alignment14");
- GLADE_HOOKUP_OBJECT (prefwin, hbox55, "hbox55");
- GLADE_HOOKUP_OBJECT (prefwin, image393, "image393");
- GLADE_HOOKUP_OBJECT (prefwin, label91, "label91");
return prefwin;
}
GtkWidget*
-create_editplaylistdlg (void)
+create_entrydialog (void)
{
- GtkWidget *editplaylistdlg;
+ GtkWidget *entrydialog;
GtkWidget *dialog_vbox3;
GtkWidget *vbox15;
GtkWidget *hbox33;
- GtkWidget *label40;
+ GtkWidget *title_label;
GtkWidget *title;
GtkWidget *dialog_action_area3;
GtkWidget *cancelbutton2;
@@ -2852,13 +2815,13 @@ create_editplaylistdlg (void)
GtkWidget *image395;
GtkWidget *label93;
- editplaylistdlg = gtk_dialog_new ();
- gtk_container_set_border_width (GTK_CONTAINER (editplaylistdlg), 8);
- gtk_window_set_title (GTK_WINDOW (editplaylistdlg), _("editplaylistdlg"));
- gtk_window_set_destroy_with_parent (GTK_WINDOW (editplaylistdlg), TRUE);
- gtk_window_set_type_hint (GTK_WINDOW (editplaylistdlg), GDK_WINDOW_TYPE_HINT_DIALOG);
+ entrydialog = gtk_dialog_new ();
+ gtk_container_set_border_width (GTK_CONTAINER (entrydialog), 8);
+ gtk_window_set_title (GTK_WINDOW (entrydialog), "EntryDialog");
+ gtk_window_set_destroy_with_parent (GTK_WINDOW (entrydialog), TRUE);
+ gtk_window_set_type_hint (GTK_WINDOW (entrydialog), GDK_WINDOW_TYPE_HINT_DIALOG);
- dialog_vbox3 = GTK_DIALOG (editplaylistdlg)->vbox;
+ dialog_vbox3 = GTK_DIALOG (entrydialog)->vbox;
gtk_widget_show (dialog_vbox3);
vbox15 = gtk_vbox_new (FALSE, 0);
@@ -2870,9 +2833,9 @@ create_editplaylistdlg (void)
gtk_widget_show (hbox33);
gtk_box_pack_start (GTK_BOX (vbox15), hbox33, TRUE, TRUE, 0);
- label40 = gtk_label_new (_("Title:"));
- gtk_widget_show (label40);
- gtk_box_pack_start (GTK_BOX (hbox33), label40, FALSE, FALSE, 0);
+ title_label = gtk_label_new (_("Title:"));
+ gtk_widget_show (title_label);
+ gtk_box_pack_start (GTK_BOX (hbox33), title_label, FALSE, FALSE, 0);
title = gtk_entry_new ();
gtk_widget_show (title);
@@ -2880,13 +2843,13 @@ create_editplaylistdlg (void)
gtk_entry_set_invisible_char (GTK_ENTRY (title), 8226);
gtk_entry_set_activates_default (GTK_ENTRY (title), TRUE);
- dialog_action_area3 = GTK_DIALOG (editplaylistdlg)->action_area;
+ dialog_action_area3 = GTK_DIALOG (entrydialog)->action_area;
gtk_widget_show (dialog_action_area3);
gtk_button_box_set_layout (GTK_BUTTON_BOX (dialog_action_area3), GTK_BUTTONBOX_END);
cancelbutton2 = gtk_button_new ();
gtk_widget_show (cancelbutton2);
- gtk_dialog_add_action_widget (GTK_DIALOG (editplaylistdlg), cancelbutton2, GTK_RESPONSE_CANCEL);
+ gtk_dialog_add_action_widget (GTK_DIALOG (entrydialog), cancelbutton2, GTK_RESPONSE_CANCEL);
GTK_WIDGET_SET_FLAGS (cancelbutton2, GTK_CAN_DEFAULT);
alignment17 = gtk_alignment_new (0.5, 0.5, 0, 0);
@@ -2907,7 +2870,7 @@ create_editplaylistdlg (void)
okbutton2 = gtk_button_new ();
gtk_widget_show (okbutton2);
- gtk_dialog_add_action_widget (GTK_DIALOG (editplaylistdlg), okbutton2, GTK_RESPONSE_OK);
+ gtk_dialog_add_action_widget (GTK_DIALOG (entrydialog), okbutton2, GTK_RESPONSE_OK);
GTK_WIDGET_SET_FLAGS (okbutton2, GTK_CAN_DEFAULT);
alignment16 = gtk_alignment_new (0.5, 0.5, 0, 0);
@@ -2927,25 +2890,25 @@ create_editplaylistdlg (void)
gtk_box_pack_start (GTK_BOX (hbox57), label93, FALSE, FALSE, 0);
/* Store pointers to all widgets, for use by lookup_widget(). */
- GLADE_HOOKUP_OBJECT_NO_REF (editplaylistdlg, editplaylistdlg, "editplaylistdlg");
- GLADE_HOOKUP_OBJECT_NO_REF (editplaylistdlg, dialog_vbox3, "dialog_vbox3");
- GLADE_HOOKUP_OBJECT (editplaylistdlg, vbox15, "vbox15");
- GLADE_HOOKUP_OBJECT (editplaylistdlg, hbox33, "hbox33");
- GLADE_HOOKUP_OBJECT (editplaylistdlg, label40, "label40");
- GLADE_HOOKUP_OBJECT (editplaylistdlg, title, "title");
- GLADE_HOOKUP_OBJECT_NO_REF (editplaylistdlg, dialog_action_area3, "dialog_action_area3");
- GLADE_HOOKUP_OBJECT (editplaylistdlg, cancelbutton2, "cancelbutton2");
- GLADE_HOOKUP_OBJECT (editplaylistdlg, alignment17, "alignment17");
- GLADE_HOOKUP_OBJECT (editplaylistdlg, hbox58, "hbox58");
- GLADE_HOOKUP_OBJECT (editplaylistdlg, image396, "image396");
- GLADE_HOOKUP_OBJECT (editplaylistdlg, label94, "label94");
- GLADE_HOOKUP_OBJECT (editplaylistdlg, okbutton2, "okbutton2");
- GLADE_HOOKUP_OBJECT (editplaylistdlg, alignment16, "alignment16");
- GLADE_HOOKUP_OBJECT (editplaylistdlg, hbox57, "hbox57");
- GLADE_HOOKUP_OBJECT (editplaylistdlg, image395, "image395");
- GLADE_HOOKUP_OBJECT (editplaylistdlg, label93, "label93");
-
- return editplaylistdlg;
+ GLADE_HOOKUP_OBJECT_NO_REF (entrydialog, entrydialog, "entrydialog");
+ GLADE_HOOKUP_OBJECT_NO_REF (entrydialog, dialog_vbox3, "dialog_vbox3");
+ GLADE_HOOKUP_OBJECT (entrydialog, vbox15, "vbox15");
+ GLADE_HOOKUP_OBJECT (entrydialog, hbox33, "hbox33");
+ GLADE_HOOKUP_OBJECT (entrydialog, title_label, "title_label");
+ GLADE_HOOKUP_OBJECT (entrydialog, title, "title");
+ GLADE_HOOKUP_OBJECT_NO_REF (entrydialog, dialog_action_area3, "dialog_action_area3");
+ GLADE_HOOKUP_OBJECT (entrydialog, cancelbutton2, "cancelbutton2");
+ GLADE_HOOKUP_OBJECT (entrydialog, alignment17, "alignment17");
+ GLADE_HOOKUP_OBJECT (entrydialog, hbox58, "hbox58");
+ GLADE_HOOKUP_OBJECT (entrydialog, image396, "image396");
+ GLADE_HOOKUP_OBJECT (entrydialog, label94, "label94");
+ GLADE_HOOKUP_OBJECT (entrydialog, okbutton2, "okbutton2");
+ GLADE_HOOKUP_OBJECT (entrydialog, alignment16, "alignment16");
+ GLADE_HOOKUP_OBJECT (entrydialog, hbox57, "hbox57");
+ GLADE_HOOKUP_OBJECT (entrydialog, image395, "image395");
+ GLADE_HOOKUP_OBJECT (entrydialog, label93, "label93");
+
+ return entrydialog;
}
GtkWidget*
@@ -3067,8 +3030,9 @@ create_groupbydlg (void)
GtkWidget *vbox25;
GtkWidget *hbox46;
GtkWidget *label81;
+ GtkWidget *hbox75;
GtkWidget *format;
- GtkWidget *label82;
+ GtkWidget *custom1;
GtkWidget *dialog_action_area4;
GtkWidget *cancelbutton4;
GtkWidget *alignment7;
@@ -3101,19 +3065,21 @@ create_groupbydlg (void)
gtk_widget_show (label81);
gtk_box_pack_start (GTK_BOX (hbox46), label81, FALSE, FALSE, 0);
+ hbox75 = gtk_hbox_new (FALSE, 0);
+ gtk_widget_show (hbox75);
+ gtk_box_pack_start (GTK_BOX (hbox46), hbox75, TRUE, TRUE, 0);
+
format = gtk_entry_new ();
gtk_widget_show (format);
- gtk_box_pack_start (GTK_BOX (hbox46), format, TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (hbox75), format, TRUE, TRUE, 0);
gtk_entry_set_invisible_char (GTK_ENTRY (format), 9679);
gtk_entry_set_activates_default (GTK_ENTRY (format), TRUE);
- label82 = gtk_label_new (_("Format conversions (start with %):\n [a]rtist, [t]itle, al[b]um, [B]and, [C]omposer\n track[n]umber, [N]totaltracks,\n [l]ength, [y]ear, [g]enre, [c]omment,\n copy[r]ight, [f]ilename, [T]ags\nExample: %a - %t [%l]"));
- gtk_widget_show (label82);
- gtk_box_pack_start (GTK_BOX (vbox25), label82, FALSE, FALSE, 0);
- GTK_WIDGET_SET_FLAGS (label82, GTK_CAN_FOCUS);
- gtk_label_set_use_markup (GTK_LABEL (label82), TRUE);
- gtk_label_set_selectable (GTK_LABEL (label82), TRUE);
- gtk_misc_set_alignment (GTK_MISC (label82), 0.1, 0.5);
+ custom1 = title_formatting_help_link_create ("custom1", "", "", 0, 0);
+ gtk_widget_show (custom1);
+ gtk_box_pack_start (GTK_BOX (hbox75), custom1, TRUE, TRUE, 0);
+ GTK_WIDGET_UNSET_FLAGS (custom1, GTK_CAN_FOCUS);
+ GTK_WIDGET_UNSET_FLAGS (custom1, GTK_CAN_DEFAULT);
dialog_action_area4 = GTK_DIALOG (groupbydlg)->action_area;
gtk_widget_show (dialog_action_area4);
@@ -3167,8 +3133,9 @@ create_groupbydlg (void)
GLADE_HOOKUP_OBJECT (groupbydlg, vbox25, "vbox25");
GLADE_HOOKUP_OBJECT (groupbydlg, hbox46, "hbox46");
GLADE_HOOKUP_OBJECT (groupbydlg, label81, "label81");
+ GLADE_HOOKUP_OBJECT (groupbydlg, hbox75, "hbox75");
GLADE_HOOKUP_OBJECT (groupbydlg, format, "format");
- GLADE_HOOKUP_OBJECT (groupbydlg, label82, "label82");
+ GLADE_HOOKUP_OBJECT (groupbydlg, custom1, "custom1");
GLADE_HOOKUP_OBJECT_NO_REF (groupbydlg, dialog_action_area4, "dialog_action_area4");
GLADE_HOOKUP_OBJECT (groupbydlg, cancelbutton4, "cancelbutton4");
GLADE_HOOKUP_OBJECT (groupbydlg, alignment7, "alignment7");
@@ -3184,3 +3151,514 @@ create_groupbydlg (void)
return groupbydlg;
}
+GtkWidget*
+create_sortbydlg (void)
+{
+ GtkWidget *sortbydlg;
+ GtkWidget *dialog_vbox8;
+ GtkWidget *vbox28;
+ GtkWidget *hbox76;
+ GtkWidget *label108;
+ GtkWidget *hbox77;
+ GtkWidget *sortfmt;
+ GtkWidget *custom3;
+ GtkWidget *hbox78;
+ GtkWidget *label109;
+ GtkWidget *sortorder;
+ GtkWidget *dialog_action_area7;
+ GtkWidget *cancelbutton5;
+ GtkWidget *okbutton5;
+
+ sortbydlg = gtk_dialog_new ();
+ gtk_window_set_title (GTK_WINDOW (sortbydlg), _("Sort by..."));
+ gtk_window_set_modal (GTK_WINDOW (sortbydlg), TRUE);
+ gtk_window_set_type_hint (GTK_WINDOW (sortbydlg), GDK_WINDOW_TYPE_HINT_DIALOG);
+
+ dialog_vbox8 = GTK_DIALOG (sortbydlg)->vbox;
+ gtk_widget_show (dialog_vbox8);
+
+ vbox28 = gtk_vbox_new (FALSE, 8);
+ gtk_widget_show (vbox28);
+ gtk_box_pack_start (GTK_BOX (dialog_vbox8), vbox28, FALSE, FALSE, 0);
+ gtk_container_set_border_width (GTK_CONTAINER (vbox28), 12);
+
+ hbox76 = gtk_hbox_new (FALSE, 8);
+ gtk_widget_show (hbox76);
+ gtk_box_pack_start (GTK_BOX (vbox28), hbox76, FALSE, TRUE, 0);
+
+ label108 = gtk_label_new (_("Format"));
+ gtk_widget_show (label108);
+ gtk_box_pack_start (GTK_BOX (hbox76), label108, FALSE, FALSE, 0);
+
+ hbox77 = gtk_hbox_new (FALSE, 0);
+ gtk_widget_show (hbox77);
+ gtk_box_pack_start (GTK_BOX (hbox76), hbox77, TRUE, TRUE, 0);
+
+ sortfmt = gtk_entry_new ();
+ gtk_widget_show (sortfmt);
+ gtk_box_pack_start (GTK_BOX (hbox77), sortfmt, TRUE, TRUE, 0);
+ gtk_entry_set_invisible_char (GTK_ENTRY (sortfmt), 9679);
+
+ custom3 = title_formatting_help_link_create ("custom3", "", "", 0, 0);
+ gtk_widget_show (custom3);
+ gtk_box_pack_start (GTK_BOX (hbox77), custom3, TRUE, TRUE, 0);
+ GTK_WIDGET_UNSET_FLAGS (custom3, GTK_CAN_FOCUS);
+ GTK_WIDGET_UNSET_FLAGS (custom3, GTK_CAN_DEFAULT);
+
+ hbox78 = gtk_hbox_new (FALSE, 8);
+ gtk_widget_show (hbox78);
+ gtk_box_pack_start (GTK_BOX (vbox28), hbox78, TRUE, TRUE, 0);
+
+ label109 = gtk_label_new (_("Order"));
+ gtk_widget_show (label109);
+ gtk_box_pack_start (GTK_BOX (hbox78), label109, FALSE, FALSE, 0);
+
+ sortorder = gtk_combo_box_new_text ();
+ gtk_widget_show (sortorder);
+ gtk_box_pack_start (GTK_BOX (hbox78), sortorder, TRUE, TRUE, 0);
+ gtk_combo_box_append_text (GTK_COMBO_BOX (sortorder), _("Ascending"));
+ gtk_combo_box_append_text (GTK_COMBO_BOX (sortorder), _("Descending"));
+
+ dialog_action_area7 = GTK_DIALOG (sortbydlg)->action_area;
+ gtk_widget_show (dialog_action_area7);
+ gtk_button_box_set_layout (GTK_BUTTON_BOX (dialog_action_area7), GTK_BUTTONBOX_END);
+
+ cancelbutton5 = gtk_button_new_from_stock ("gtk-cancel");
+ gtk_widget_show (cancelbutton5);
+ gtk_dialog_add_action_widget (GTK_DIALOG (sortbydlg), cancelbutton5, GTK_RESPONSE_CANCEL);
+ GTK_WIDGET_SET_FLAGS (cancelbutton5, GTK_CAN_DEFAULT);
+
+ okbutton5 = gtk_button_new_from_stock ("gtk-ok");
+ gtk_widget_show (okbutton5);
+ gtk_dialog_add_action_widget (GTK_DIALOG (sortbydlg), okbutton5, GTK_RESPONSE_OK);
+ GTK_WIDGET_SET_FLAGS (okbutton5, GTK_CAN_DEFAULT);
+
+ g_signal_connect ((gpointer) sortfmt, "activate",
+ G_CALLBACK (on_sortfmt_activate),
+ NULL);
+
+ /* Store pointers to all widgets, for use by lookup_widget(). */
+ GLADE_HOOKUP_OBJECT_NO_REF (sortbydlg, sortbydlg, "sortbydlg");
+ GLADE_HOOKUP_OBJECT_NO_REF (sortbydlg, dialog_vbox8, "dialog_vbox8");
+ GLADE_HOOKUP_OBJECT (sortbydlg, vbox28, "vbox28");
+ GLADE_HOOKUP_OBJECT (sortbydlg, hbox76, "hbox76");
+ GLADE_HOOKUP_OBJECT (sortbydlg, label108, "label108");
+ GLADE_HOOKUP_OBJECT (sortbydlg, hbox77, "hbox77");
+ GLADE_HOOKUP_OBJECT (sortbydlg, sortfmt, "sortfmt");
+ GLADE_HOOKUP_OBJECT (sortbydlg, custom3, "custom3");
+ GLADE_HOOKUP_OBJECT (sortbydlg, hbox78, "hbox78");
+ GLADE_HOOKUP_OBJECT (sortbydlg, label109, "label109");
+ GLADE_HOOKUP_OBJECT (sortbydlg, sortorder, "sortorder");
+ GLADE_HOOKUP_OBJECT_NO_REF (sortbydlg, dialog_action_area7, "dialog_action_area7");
+ GLADE_HOOKUP_OBJECT (sortbydlg, cancelbutton5, "cancelbutton5");
+ GLADE_HOOKUP_OBJECT (sortbydlg, okbutton5, "okbutton5");
+
+ return sortbydlg;
+}
+
+GtkWidget*
+create_select_dsp_plugin (void)
+{
+ GtkWidget *select_dsp_plugin;
+ GtkWidget *dialog_vbox10;
+ GtkWidget *vbox31;
+ GtkWidget *hbox85;
+ GtkWidget *label113;
+ GtkWidget *plugin;
+ GtkWidget *dialog_action_area9;
+ GtkWidget *cancelbutton7;
+ GtkWidget *okbutton7;
+
+ select_dsp_plugin = gtk_dialog_new ();
+ gtk_window_set_title (GTK_WINDOW (select_dsp_plugin), _("Select DSP Plugin"));
+ gtk_window_set_modal (GTK_WINDOW (select_dsp_plugin), TRUE);
+ gtk_window_set_type_hint (GTK_WINDOW (select_dsp_plugin), GDK_WINDOW_TYPE_HINT_DIALOG);
+
+ dialog_vbox10 = GTK_DIALOG (select_dsp_plugin)->vbox;
+ gtk_widget_show (dialog_vbox10);
+
+ vbox31 = gtk_vbox_new (FALSE, 8);
+ gtk_widget_show (vbox31);
+ gtk_box_pack_start (GTK_BOX (dialog_vbox10), vbox31, TRUE, TRUE, 0);
+ gtk_container_set_border_width (GTK_CONTAINER (vbox31), 12);
+
+ hbox85 = gtk_hbox_new (FALSE, 8);
+ gtk_widget_show (hbox85);
+ gtk_box_pack_start (GTK_BOX (vbox31), hbox85, FALSE, FALSE, 0);
+
+ label113 = gtk_label_new (_("Plugin"));
+ gtk_widget_show (label113);
+ gtk_box_pack_start (GTK_BOX (hbox85), label113, FALSE, FALSE, 0);
+
+ plugin = gtk_combo_box_new_text ();
+ gtk_widget_show (plugin);
+ gtk_box_pack_start (GTK_BOX (hbox85), plugin, TRUE, TRUE, 0);
+
+ dialog_action_area9 = GTK_DIALOG (select_dsp_plugin)->action_area;
+ gtk_widget_show (dialog_action_area9);
+ gtk_button_box_set_layout (GTK_BUTTON_BOX (dialog_action_area9), GTK_BUTTONBOX_END);
+
+ cancelbutton7 = gtk_button_new_from_stock ("gtk-cancel");
+ gtk_widget_show (cancelbutton7);
+ gtk_dialog_add_action_widget (GTK_DIALOG (select_dsp_plugin), cancelbutton7, GTK_RESPONSE_CANCEL);
+ GTK_WIDGET_SET_FLAGS (cancelbutton7, GTK_CAN_DEFAULT);
+
+ okbutton7 = gtk_button_new_from_stock ("gtk-ok");
+ gtk_widget_show (okbutton7);
+ gtk_dialog_add_action_widget (GTK_DIALOG (select_dsp_plugin), okbutton7, GTK_RESPONSE_OK);
+ GTK_WIDGET_SET_FLAGS (okbutton7, GTK_CAN_DEFAULT);
+
+ /* Store pointers to all widgets, for use by lookup_widget(). */
+ GLADE_HOOKUP_OBJECT_NO_REF (select_dsp_plugin, select_dsp_plugin, "select_dsp_plugin");
+ GLADE_HOOKUP_OBJECT_NO_REF (select_dsp_plugin, dialog_vbox10, "dialog_vbox10");
+ GLADE_HOOKUP_OBJECT (select_dsp_plugin, vbox31, "vbox31");
+ GLADE_HOOKUP_OBJECT (select_dsp_plugin, hbox85, "hbox85");
+ GLADE_HOOKUP_OBJECT (select_dsp_plugin, label113, "label113");
+ GLADE_HOOKUP_OBJECT (select_dsp_plugin, plugin, "plugin");
+ GLADE_HOOKUP_OBJECT_NO_REF (select_dsp_plugin, dialog_action_area9, "dialog_action_area9");
+ GLADE_HOOKUP_OBJECT (select_dsp_plugin, cancelbutton7, "cancelbutton7");
+ GLADE_HOOKUP_OBJECT (select_dsp_plugin, okbutton7, "okbutton7");
+
+ return select_dsp_plugin;
+}
+
+GtkWidget*
+create_tagwritersettings (void)
+{
+ GtkWidget *tagwritersettings;
+ GtkWidget *dialog_vbox11;
+ GtkWidget *vbox32;
+ GtkWidget *frame8;
+ GtkWidget *alignment21;
+ GtkWidget *vbox33;
+ GtkWidget *hbox89;
+ GtkWidget *write_id3v2;
+ GtkWidget *write_id3v1;
+ GtkWidget *write_apev2;
+ GtkWidget *hbox90;
+ GtkWidget *strip_id3v2;
+ GtkWidget *strip_id3v1;
+ GtkWidget *strip_apev2;
+ GtkWidget *hbox91;
+ GtkWidget *label118;
+ GtkWidget *id3v2_version;
+ GtkWidget *hbox92;
+ GtkWidget *label119;
+ GtkWidget *id3v1_encoding;
+ GtkWidget *label120;
+ GtkWidget *hbox93;
+ GtkWidget *frame9;
+ GtkWidget *alignment22;
+ GtkWidget *vbox34;
+ GtkWidget *hbox94;
+ GtkWidget *ape_write_id3v2;
+ GtkWidget *ape_write_apev2;
+ GtkWidget *hbox95;
+ GtkWidget *ape_strip_id3v2;
+ GtkWidget *ape_strip_apev2;
+ GtkWidget *label121;
+ GtkWidget *frame10;
+ GtkWidget *alignment23;
+ GtkWidget *vbox35;
+ GtkWidget *hbox96;
+ GtkWidget *wv_write_apev2;
+ GtkWidget *wv_write_id3v1;
+ GtkWidget *hbox97;
+ GtkWidget *wv_strip_apev2;
+ GtkWidget *wv_strip_id3v1;
+ GtkWidget *label122;
+ GtkWidget *dialog_action_area10;
+ GtkWidget *closebutton2;
+
+ tagwritersettings = gtk_dialog_new ();
+ gtk_container_set_border_width (GTK_CONTAINER (tagwritersettings), 12);
+ gtk_window_set_title (GTK_WINDOW (tagwritersettings), _("Tag Writer Settings"));
+ gtk_window_set_modal (GTK_WINDOW (tagwritersettings), TRUE);
+ gtk_window_set_type_hint (GTK_WINDOW (tagwritersettings), GDK_WINDOW_TYPE_HINT_DIALOG);
+ gtk_dialog_set_has_separator (GTK_DIALOG (tagwritersettings), FALSE);
+
+ dialog_vbox11 = GTK_DIALOG (tagwritersettings)->vbox;
+ gtk_widget_show (dialog_vbox11);
+
+ vbox32 = gtk_vbox_new (FALSE, 0);
+ gtk_widget_show (vbox32);
+ gtk_box_pack_start (GTK_BOX (dialog_vbox11), vbox32, TRUE, TRUE, 0);
+
+ frame8 = gtk_frame_new (NULL);
+ gtk_widget_show (frame8);
+ gtk_box_pack_start (GTK_BOX (vbox32), frame8, FALSE, TRUE, 0);
+ gtk_frame_set_shadow_type (GTK_FRAME (frame8), GTK_SHADOW_NONE);
+
+ alignment21 = gtk_alignment_new (0.5, 0.5, 1, 1);
+ gtk_widget_show (alignment21);
+ gtk_container_add (GTK_CONTAINER (frame8), alignment21);
+ gtk_alignment_set_padding (GTK_ALIGNMENT (alignment21), 0, 0, 12, 0);
+
+ vbox33 = gtk_vbox_new (FALSE, 8);
+ gtk_widget_show (vbox33);
+ gtk_container_add (GTK_CONTAINER (alignment21), vbox33);
+ gtk_container_set_border_width (GTK_CONTAINER (vbox33), 12);
+
+ hbox89 = gtk_hbox_new (FALSE, 8);
+ gtk_widget_show (hbox89);
+ gtk_box_pack_start (GTK_BOX (vbox33), hbox89, FALSE, FALSE, 0);
+
+ write_id3v2 = gtk_check_button_new_with_mnemonic (_("Write ID3v2"));
+ gtk_widget_show (write_id3v2);
+ gtk_box_pack_start (GTK_BOX (hbox89), write_id3v2, FALSE, FALSE, 0);
+
+ write_id3v1 = gtk_check_button_new_with_mnemonic (_("Write ID3v1"));
+ gtk_widget_show (write_id3v1);
+ gtk_box_pack_start (GTK_BOX (hbox89), write_id3v1, FALSE, FALSE, 0);
+
+ write_apev2 = gtk_check_button_new_with_mnemonic (_("Write APEv2"));
+ gtk_widget_show (write_apev2);
+ gtk_box_pack_start (GTK_BOX (hbox89), write_apev2, FALSE, FALSE, 0);
+
+ hbox90 = gtk_hbox_new (FALSE, 8);
+ gtk_widget_show (hbox90);
+ gtk_box_pack_start (GTK_BOX (vbox33), hbox90, FALSE, FALSE, 0);
+
+ strip_id3v2 = gtk_check_button_new_with_mnemonic (_("Strip ID3v2"));
+ gtk_widget_show (strip_id3v2);
+ gtk_box_pack_start (GTK_BOX (hbox90), strip_id3v2, FALSE, FALSE, 0);
+
+ strip_id3v1 = gtk_check_button_new_with_mnemonic (_("Strip ID3v1"));
+ gtk_widget_show (strip_id3v1);
+ gtk_box_pack_start (GTK_BOX (hbox90), strip_id3v1, FALSE, FALSE, 0);
+
+ strip_apev2 = gtk_check_button_new_with_mnemonic (_("Strip APEv2"));
+ gtk_widget_show (strip_apev2);
+ gtk_box_pack_start (GTK_BOX (hbox90), strip_apev2, FALSE, FALSE, 0);
+
+ hbox91 = gtk_hbox_new (FALSE, 8);
+ gtk_widget_show (hbox91);
+ gtk_box_pack_start (GTK_BOX (vbox33), hbox91, TRUE, TRUE, 0);
+
+ label118 = gtk_label_new (_("ID3v2 version"));
+ gtk_widget_show (label118);
+ gtk_box_pack_start (GTK_BOX (hbox91), label118, FALSE, FALSE, 0);
+
+ id3v2_version = gtk_combo_box_new_text ();
+ gtk_widget_show (id3v2_version);
+ gtk_box_pack_start (GTK_BOX (hbox91), id3v2_version, TRUE, TRUE, 0);
+ gtk_combo_box_append_text (GTK_COMBO_BOX (id3v2_version), _("2.3 (Recommended)"));
+ gtk_combo_box_append_text (GTK_COMBO_BOX (id3v2_version), _("2.4"));
+
+ hbox92 = gtk_hbox_new (FALSE, 8);
+ gtk_widget_show (hbox92);
+ gtk_box_pack_start (GTK_BOX (vbox33), hbox92, TRUE, TRUE, 0);
+
+ label119 = gtk_label_new (_("ID3v1 character encoding (default is iso8859-1)"));
+ gtk_widget_show (label119);
+ gtk_box_pack_start (GTK_BOX (hbox92), label119, FALSE, FALSE, 0);
+
+ id3v1_encoding = gtk_entry_new ();
+ gtk_widget_show (id3v1_encoding);
+ gtk_box_pack_start (GTK_BOX (hbox92), id3v1_encoding, TRUE, TRUE, 0);
+ gtk_entry_set_invisible_char (GTK_ENTRY (id3v1_encoding), 9679);
+
+ label120 = gtk_label_new ("<b>MP3</b>");
+ gtk_widget_show (label120);
+ gtk_frame_set_label_widget (GTK_FRAME (frame8), label120);
+ gtk_label_set_use_markup (GTK_LABEL (label120), TRUE);
+
+ hbox93 = gtk_hbox_new (TRUE, 0);
+ gtk_widget_show (hbox93);
+ gtk_box_pack_start (GTK_BOX (vbox32), hbox93, FALSE, TRUE, 0);
+
+ frame9 = gtk_frame_new (NULL);
+ gtk_widget_show (frame9);
+ gtk_box_pack_start (GTK_BOX (hbox93), frame9, TRUE, TRUE, 0);
+ gtk_frame_set_shadow_type (GTK_FRAME (frame9), GTK_SHADOW_NONE);
+
+ alignment22 = gtk_alignment_new (0.5, 0.5, 1, 1);
+ gtk_widget_show (alignment22);
+ gtk_container_add (GTK_CONTAINER (frame9), alignment22);
+ gtk_alignment_set_padding (GTK_ALIGNMENT (alignment22), 0, 0, 12, 0);
+
+ vbox34 = gtk_vbox_new (FALSE, 8);
+ gtk_widget_show (vbox34);
+ gtk_container_add (GTK_CONTAINER (alignment22), vbox34);
+ gtk_container_set_border_width (GTK_CONTAINER (vbox34), 12);
+
+ hbox94 = gtk_hbox_new (FALSE, 8);
+ gtk_widget_show (hbox94);
+ gtk_box_pack_start (GTK_BOX (vbox34), hbox94, TRUE, TRUE, 0);
+
+ ape_write_id3v2 = gtk_check_button_new_with_mnemonic (_("Write ID3v2.4"));
+ gtk_widget_show (ape_write_id3v2);
+ gtk_box_pack_start (GTK_BOX (hbox94), ape_write_id3v2, FALSE, FALSE, 0);
+
+ ape_write_apev2 = gtk_check_button_new_with_mnemonic (_("Write APEv2"));
+ gtk_widget_show (ape_write_apev2);
+ gtk_box_pack_start (GTK_BOX (hbox94), ape_write_apev2, FALSE, FALSE, 0);
+
+ hbox95 = gtk_hbox_new (FALSE, 8);
+ gtk_widget_show (hbox95);
+ gtk_box_pack_start (GTK_BOX (vbox34), hbox95, TRUE, TRUE, 0);
+
+ ape_strip_id3v2 = gtk_check_button_new_with_mnemonic (_("Strip ID3v2"));
+ gtk_widget_show (ape_strip_id3v2);
+ gtk_box_pack_start (GTK_BOX (hbox95), ape_strip_id3v2, FALSE, FALSE, 0);
+
+ ape_strip_apev2 = gtk_check_button_new_with_mnemonic (_("Strip APEv2"));
+ gtk_widget_show (ape_strip_apev2);
+ gtk_box_pack_start (GTK_BOX (hbox95), ape_strip_apev2, FALSE, FALSE, 0);
+
+ label121 = gtk_label_new ("<b>APE</b>");
+ gtk_widget_show (label121);
+ gtk_frame_set_label_widget (GTK_FRAME (frame9), label121);
+ gtk_label_set_use_markup (GTK_LABEL (label121), TRUE);
+
+ frame10 = gtk_frame_new (NULL);
+ gtk_widget_show (frame10);
+ gtk_box_pack_start (GTK_BOX (hbox93), frame10, TRUE, TRUE, 0);
+ gtk_frame_set_shadow_type (GTK_FRAME (frame10), GTK_SHADOW_NONE);
+
+ alignment23 = gtk_alignment_new (0.5, 0.5, 1, 1);
+ gtk_widget_show (alignment23);
+ gtk_container_add (GTK_CONTAINER (frame10), alignment23);
+ gtk_alignment_set_padding (GTK_ALIGNMENT (alignment23), 0, 0, 12, 0);
+
+ vbox35 = gtk_vbox_new (FALSE, 8);
+ gtk_widget_show (vbox35);
+ gtk_container_add (GTK_CONTAINER (alignment23), vbox35);
+ gtk_container_set_border_width (GTK_CONTAINER (vbox35), 12);
+
+ hbox96 = gtk_hbox_new (FALSE, 8);
+ gtk_widget_show (hbox96);
+ gtk_box_pack_start (GTK_BOX (vbox35), hbox96, FALSE, FALSE, 0);
+
+ wv_write_apev2 = gtk_check_button_new_with_mnemonic (_("Write APEv2"));
+ gtk_widget_show (wv_write_apev2);
+ gtk_box_pack_start (GTK_BOX (hbox96), wv_write_apev2, FALSE, FALSE, 0);
+
+ wv_write_id3v1 = gtk_check_button_new_with_mnemonic (_("Write ID3v1"));
+ gtk_widget_show (wv_write_id3v1);
+ gtk_box_pack_start (GTK_BOX (hbox96), wv_write_id3v1, FALSE, FALSE, 0);
+
+ hbox97 = gtk_hbox_new (FALSE, 8);
+ gtk_widget_show (hbox97);
+ gtk_box_pack_start (GTK_BOX (vbox35), hbox97, FALSE, FALSE, 0);
+
+ wv_strip_apev2 = gtk_check_button_new_with_mnemonic (_("Strip APEv2"));
+ gtk_widget_show (wv_strip_apev2);
+ gtk_box_pack_start (GTK_BOX (hbox97), wv_strip_apev2, FALSE, FALSE, 0);
+
+ wv_strip_id3v1 = gtk_check_button_new_with_mnemonic (_("Strip ID3v1"));
+ gtk_widget_show (wv_strip_id3v1);
+ gtk_box_pack_start (GTK_BOX (hbox97), wv_strip_id3v1, FALSE, FALSE, 0);
+
+ label122 = gtk_label_new ("<b>WavPack</b>");
+ gtk_widget_show (label122);
+ gtk_frame_set_label_widget (GTK_FRAME (frame10), label122);
+ gtk_label_set_use_markup (GTK_LABEL (label122), TRUE);
+
+ dialog_action_area10 = GTK_DIALOG (tagwritersettings)->action_area;
+ gtk_widget_show (dialog_action_area10);
+ gtk_button_box_set_layout (GTK_BUTTON_BOX (dialog_action_area10), GTK_BUTTONBOX_END);
+
+ closebutton2 = gtk_button_new_from_stock ("gtk-close");
+ gtk_widget_show (closebutton2);
+ gtk_dialog_add_action_widget (GTK_DIALOG (tagwritersettings), closebutton2, GTK_RESPONSE_CLOSE);
+ GTK_WIDGET_SET_FLAGS (closebutton2, GTK_CAN_DEFAULT);
+
+ g_signal_connect ((gpointer) write_id3v2, "toggled",
+ G_CALLBACK (on_write_id3v2_toggled),
+ NULL);
+ g_signal_connect ((gpointer) write_id3v1, "toggled",
+ G_CALLBACK (on_write_id3v1_toggled),
+ NULL);
+ g_signal_connect ((gpointer) write_apev2, "toggled",
+ G_CALLBACK (on_write_apev2_toggled),
+ NULL);
+ g_signal_connect ((gpointer) strip_id3v2, "toggled",
+ G_CALLBACK (on_strip_id3v2_toggled),
+ NULL);
+ g_signal_connect ((gpointer) strip_id3v1, "toggled",
+ G_CALLBACK (on_strip_id3v1_toggled),
+ NULL);
+ g_signal_connect ((gpointer) strip_apev2, "toggled",
+ G_CALLBACK (on_strip_apev2_toggled),
+ NULL);
+ g_signal_connect ((gpointer) id3v2_version, "changed",
+ G_CALLBACK (on_id3v2_version_changed),
+ NULL);
+ g_signal_connect ((gpointer) id3v1_encoding, "changed",
+ G_CALLBACK (on_id3v1_encoding_changed),
+ NULL);
+ g_signal_connect ((gpointer) ape_write_id3v2, "toggled",
+ G_CALLBACK (on_ape_write_id3v2_toggled),
+ NULL);
+ g_signal_connect ((gpointer) ape_write_apev2, "toggled",
+ G_CALLBACK (on_ape_write_apev2_toggled),
+ NULL);
+ g_signal_connect ((gpointer) ape_strip_id3v2, "toggled",
+ G_CALLBACK (on_ape_strip_id3v2_toggled),
+ NULL);
+ g_signal_connect ((gpointer) ape_strip_apev2, "toggled",
+ G_CALLBACK (on_ape_strip_apev2_toggled),
+ NULL);
+ g_signal_connect ((gpointer) wv_write_apev2, "toggled",
+ G_CALLBACK (on_wv_write_apev2_toggled),
+ NULL);
+ g_signal_connect ((gpointer) wv_write_id3v1, "toggled",
+ G_CALLBACK (on_wv_write_id3v1_toggled),
+ NULL);
+ g_signal_connect ((gpointer) wv_strip_apev2, "toggled",
+ G_CALLBACK (on_wv_strip_apev2_toggled),
+ NULL);
+ g_signal_connect ((gpointer) wv_strip_id3v1, "toggled",
+ G_CALLBACK (on_wv_strip_id3v1_toggled),
+ NULL);
+
+ /* Store pointers to all widgets, for use by lookup_widget(). */
+ GLADE_HOOKUP_OBJECT_NO_REF (tagwritersettings, tagwritersettings, "tagwritersettings");
+ GLADE_HOOKUP_OBJECT_NO_REF (tagwritersettings, dialog_vbox11, "dialog_vbox11");
+ GLADE_HOOKUP_OBJECT (tagwritersettings, vbox32, "vbox32");
+ GLADE_HOOKUP_OBJECT (tagwritersettings, frame8, "frame8");
+ GLADE_HOOKUP_OBJECT (tagwritersettings, alignment21, "alignment21");
+ GLADE_HOOKUP_OBJECT (tagwritersettings, vbox33, "vbox33");
+ GLADE_HOOKUP_OBJECT (tagwritersettings, hbox89, "hbox89");
+ GLADE_HOOKUP_OBJECT (tagwritersettings, write_id3v2, "write_id3v2");
+ GLADE_HOOKUP_OBJECT (tagwritersettings, write_id3v1, "write_id3v1");
+ GLADE_HOOKUP_OBJECT (tagwritersettings, write_apev2, "write_apev2");
+ GLADE_HOOKUP_OBJECT (tagwritersettings, hbox90, "hbox90");
+ GLADE_HOOKUP_OBJECT (tagwritersettings, strip_id3v2, "strip_id3v2");
+ GLADE_HOOKUP_OBJECT (tagwritersettings, strip_id3v1, "strip_id3v1");
+ GLADE_HOOKUP_OBJECT (tagwritersettings, strip_apev2, "strip_apev2");
+ GLADE_HOOKUP_OBJECT (tagwritersettings, hbox91, "hbox91");
+ GLADE_HOOKUP_OBJECT (tagwritersettings, label118, "label118");
+ GLADE_HOOKUP_OBJECT (tagwritersettings, id3v2_version, "id3v2_version");
+ GLADE_HOOKUP_OBJECT (tagwritersettings, hbox92, "hbox92");
+ GLADE_HOOKUP_OBJECT (tagwritersettings, label119, "label119");
+ GLADE_HOOKUP_OBJECT (tagwritersettings, id3v1_encoding, "id3v1_encoding");
+ GLADE_HOOKUP_OBJECT (tagwritersettings, label120, "label120");
+ GLADE_HOOKUP_OBJECT (tagwritersettings, hbox93, "hbox93");
+ GLADE_HOOKUP_OBJECT (tagwritersettings, frame9, "frame9");
+ GLADE_HOOKUP_OBJECT (tagwritersettings, alignment22, "alignment22");
+ GLADE_HOOKUP_OBJECT (tagwritersettings, vbox34, "vbox34");
+ GLADE_HOOKUP_OBJECT (tagwritersettings, hbox94, "hbox94");
+ GLADE_HOOKUP_OBJECT (tagwritersettings, ape_write_id3v2, "ape_write_id3v2");
+ GLADE_HOOKUP_OBJECT (tagwritersettings, ape_write_apev2, "ape_write_apev2");
+ GLADE_HOOKUP_OBJECT (tagwritersettings, hbox95, "hbox95");
+ GLADE_HOOKUP_OBJECT (tagwritersettings, ape_strip_id3v2, "ape_strip_id3v2");
+ GLADE_HOOKUP_OBJECT (tagwritersettings, ape_strip_apev2, "ape_strip_apev2");
+ GLADE_HOOKUP_OBJECT (tagwritersettings, label121, "label121");
+ GLADE_HOOKUP_OBJECT (tagwritersettings, frame10, "frame10");
+ GLADE_HOOKUP_OBJECT (tagwritersettings, alignment23, "alignment23");
+ GLADE_HOOKUP_OBJECT (tagwritersettings, vbox35, "vbox35");
+ GLADE_HOOKUP_OBJECT (tagwritersettings, hbox96, "hbox96");
+ GLADE_HOOKUP_OBJECT (tagwritersettings, wv_write_apev2, "wv_write_apev2");
+ GLADE_HOOKUP_OBJECT (tagwritersettings, wv_write_id3v1, "wv_write_id3v1");
+ GLADE_HOOKUP_OBJECT (tagwritersettings, hbox97, "hbox97");
+ GLADE_HOOKUP_OBJECT (tagwritersettings, wv_strip_apev2, "wv_strip_apev2");
+ GLADE_HOOKUP_OBJECT (tagwritersettings, wv_strip_id3v1, "wv_strip_id3v1");
+ GLADE_HOOKUP_OBJECT (tagwritersettings, label122, "label122");
+ GLADE_HOOKUP_OBJECT_NO_REF (tagwritersettings, dialog_action_area10, "dialog_action_area10");
+ GLADE_HOOKUP_OBJECT (tagwritersettings, closebutton2, "closebutton2");
+
+ return tagwritersettings;
+}
+
diff --git a/plugins/gtkui/interface.h b/plugins/gtkui/interface.h
index 5c4b5923..d27c75e6 100644
--- a/plugins/gtkui/interface.h
+++ b/plugins/gtkui/interface.h
@@ -5,11 +5,14 @@
GtkWidget* create_mainwin (void);
GtkWidget* create_searchwin (void);
GtkWidget* create_traymenu (void);
-GtkWidget* create_addprogress (void);
+GtkWidget* create_progressdlg (void);
GtkWidget* create_helpwindow (void);
GtkWidget* create_trackproperties (void);
GtkWidget* create_editcolumndlg (void);
GtkWidget* create_prefwin (void);
-GtkWidget* create_editplaylistdlg (void);
+GtkWidget* create_entrydialog (void);
GtkWidget* create_addlocationdlg (void);
GtkWidget* create_groupbydlg (void);
+GtkWidget* create_sortbydlg (void);
+GtkWidget* create_select_dsp_plugin (void);
+GtkWidget* create_tagwritersettings (void);
diff --git a/plugins/gtkui/mainplaylist.c b/plugins/gtkui/mainplaylist.c
index 2df3bd0e..340cbfb3 100644
--- a/plugins/gtkui/mainplaylist.c
+++ b/plugins/gtkui/mainplaylist.c
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@@ -127,9 +127,9 @@ gboolean
playlist_tooltip_handler (GtkWidget *widget, gint x, gint y, gboolean keyboard_mode, GtkTooltip *tooltip, gpointer unused)
{
GtkWidget *pl = lookup_widget (mainwin, "playlist");
- DB_playItem_t *item = (DB_playItem_t *)ddb_listview_get_iter_from_coord (DDB_LISTVIEW (pl), 0, y);
- if (item && item->fname) {
- gtk_tooltip_set_text (tooltip, item->fname);
+ DB_playItem_t *it = (DB_playItem_t *)ddb_listview_get_iter_from_coord (DDB_LISTVIEW (pl), 0, y);
+ if (it) {
+ gtk_tooltip_set_text (tooltip, deadbeef->pl_find_meta (it, ":URI"));
return TRUE;
}
return FALSE;
@@ -143,13 +143,13 @@ main_col_sort (int col, int sort_order, void *user_data) {
deadbeef->pl_sort (PL_MAIN, c->id, c->format, sort_order-1);
}
void main_handle_doubleclick (DdbListview *listview, DdbListviewIter iter, int idx) {
- deadbeef->sendmessage (M_PLAYSONGNUM, 0, idx, 0);
+ deadbeef->sendmessage (M_PLAY_NUM, 0, idx, 0);
}
void main_selection_changed (DdbListviewIter it, int idx) {
DdbListview *search = DDB_LISTVIEW (lookup_widget (searchwin, "searchlist"));
if (idx == -1) {
- ddb_listview_refresh (search, DDB_REFRESH_LIST | DDB_EXPOSE_LIST);
+ ddb_listview_refresh (search, DDB_REFRESH_LIST);
}
else {
ddb_listview_draw_row (search, search_get_idx ((DB_playItem_t *)it), it);
@@ -173,8 +173,8 @@ void main_draw_group_title (DdbListview *listview, GdkDrawable *drawable, DdbLis
draw_set_fg_color (rgb);
}
int ew, eh;
- draw_text (x + 5, y + height/2 - draw_get_font_size ()/2 - 2, width-10, 0, str);
draw_get_text_extents (str, -1, &ew, &eh);
+ draw_text (x + 5, y + height/2 - draw_get_font_size ()/2 - 2, ew+5, 0, str);
draw_line (x + 5 + ew + 3, y+height/2, x + width, y+height/2);
}
}
@@ -305,7 +305,7 @@ main_playlist_init (GtkWidget *widget) {
add_column_helper (listview, _("Playing"), 50, DB_COLUMN_PLAYING, NULL, 0);
add_column_helper (listview, _("Artist / Album"), 150, -1, "%a - %b", 0);
add_column_helper (listview, _("Track No"), 50, -1, "%n", 1);
- add_column_helper (listview, _("Title / Track Artist"), 150, -1, "%t", 0);
+ add_column_helper (listview, _("Title"), 150, -1, "%t", 0);
add_column_helper (listview, _("Duration"), 50, -1, "%l", 0);
}
else {
@@ -325,7 +325,9 @@ main_playlist_init (GtkWidget *widget) {
g_object_set_property (G_OBJECT (widget), "has-tooltip", &value);
g_signal_connect (G_OBJECT (widget), "query-tooltip", G_CALLBACK (playlist_tooltip_handler), NULL);
}
- strncpy (group_by_str, deadbeef->conf_get_str ("playlist.group_by", ""), sizeof (group_by_str));
+ deadbeef->conf_lock ();
+ strncpy (group_by_str, deadbeef->conf_get_str_fast ("playlist.group_by", ""), sizeof (group_by_str));
+ deadbeef->conf_unlock ();
group_by_str[sizeof (group_by_str)-1] = 0;
}
@@ -337,7 +339,7 @@ void
main_refresh (void) {
if (mainwin && gtk_widget_get_visible (mainwin)) {
DdbListview *pl = DDB_LISTVIEW (lookup_widget (mainwin, "playlist"));
- ddb_listview_refresh (pl, DDB_REFRESH_VSCROLL | DDB_REFRESH_LIST | DDB_EXPOSE_LIST);
+ ddb_listview_refresh (pl, DDB_REFRESH_VSCROLL | DDB_REFRESH_LIST);
}
}
diff --git a/plugins/gtkui/mainplaylist.h b/plugins/gtkui/mainplaylist.h
index af266c4a..b17ef63d 100644
--- a/plugins/gtkui/mainplaylist.h
+++ b/plugins/gtkui/mainplaylist.h
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
diff --git a/plugins/gtkui/parser.c b/plugins/gtkui/parser.c
index 96558c9e..6ee81f9a 100644
--- a/plugins/gtkui/parser.c
+++ b/plugins/gtkui/parser.c
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/plugins/gtkui/parser.h b/plugins/gtkui/parser.h
index b5d48a04..ac411577 100644
--- a/plugins/gtkui/parser.h
+++ b/plugins/gtkui/parser.h
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/plugins/gtkui/plcommon.c b/plugins/gtkui/plcommon.c
index beff39bb..216b7122 100644
--- a/plugins/gtkui/plcommon.c
+++ b/plugins/gtkui/plcommon.c
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@@ -120,7 +120,7 @@ void draw_column_data (DdbListview *listview, GdkDrawable *drawable, DdbListview
if (!album || !*album) {
album = deadbeef->pl_find_meta (group_it, "title");
}
- GdkPixbuf *pixbuf = get_cover_art (((DB_playItem_t *)group_it)->fname, artist, album, art_width);
+ GdkPixbuf *pixbuf = get_cover_art (deadbeef->pl_find_meta (((DB_playItem_t *)group_it), ":URI"), artist, album, art_width);
if (pixbuf) {
int pw = gdk_pixbuf_get_width (pixbuf);
int ph = gdk_pixbuf_get_height (pixbuf);
@@ -181,10 +181,10 @@ void draw_column_data (DdbListview *listview, GdkDrawable *drawable, DdbListview
draw_init_font_bold ();
}
if (calign_right) {
- draw_text (x+5, y + height/2 - draw_get_font_size ()/2 - 2, cwidth-10, 1, text);
+ draw_text (x+5, y + (height-1)/2 - draw_get_font_size ()/2, cwidth-10, 1, text);
}
else {
- draw_text (x + 5, y + height/2 - draw_get_font_size ()/2 - 2, cwidth-10, 0, text);
+ draw_text (x + 5, y + (height-1)/2 - draw_get_font_size ()/2, cwidth-10, 0, text);
}
if (gtkui_embolden_current_track && it && it == playing_track) {
draw_init_font_normal ();
@@ -238,14 +238,15 @@ main_reload_metadata_activate
DdbListview *ps = DDB_LISTVIEW (g_object_get_data (G_OBJECT (menuitem), "ps"));
DB_playItem_t *it = deadbeef->pl_get_first (PL_MAIN);
while (it) {
- if (deadbeef->pl_is_selected (it) && deadbeef->is_local_file (it->fname) && it->decoder_id) {
+ const char *decoder_id = deadbeef->pl_find_meta (it, ":DECODER");
+ if (deadbeef->pl_is_selected (it) && deadbeef->is_local_file (deadbeef->pl_find_meta (it, ":URI")) && decoder_id) {
uint32_t f = deadbeef->pl_get_item_flags (it);
if (!(f & DDB_IS_SUBTRACK)) {
f &= ~DDB_TAG_MASK;
deadbeef->pl_set_item_flags (it, f);
DB_decoder_t **decoders = deadbeef->plug_get_decoder_list ();
for (int i = 0; decoders[i]; i++) {
- if (!strcmp (decoders[i]->plugin.id, it->decoder_id)) {
+ if (!strcmp (decoders[i]->plugin.id, decoder_id)) {
if (decoders[i]->read_metadata) {
decoders[i]->read_metadata (it);
}
@@ -266,13 +267,7 @@ void
main_properties_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
- DB_playItem_t *it = deadbeef->pl_get_for_idx_and_iter (clicked_idx, PL_MAIN);
- if (!it) {
- fprintf (stderr, "attempt to view properties of non-existing item\n");
- return;
- }
- show_track_properties_dlg (it);
- deadbeef->pl_item_unref (it);
+ show_track_properties_dlg ();
}
void
@@ -337,8 +332,8 @@ on_remove_from_disk_activate (GtkMenuItem *menuitem,
DB_playItem_t *it = deadbeef->pl_get_first (PL_MAIN);
while (it) {
- if (deadbeef->pl_is_selected (it) && deadbeef->is_local_file (it->fname)) {
- unlink (it->fname);
+ if (deadbeef->pl_is_selected (it) && deadbeef->is_local_file (deadbeef->pl_find_meta (it, ":URI"))) {
+ unlink (deadbeef->pl_find_meta (it, ":URI"));
}
DB_playItem_t *next = deadbeef->pl_get_next (it, PL_MAIN);
deadbeef->pl_item_unref (it);
@@ -460,6 +455,7 @@ list_context_menu (DdbListview *listview, DdbListviewIter it, int idx) {
DB_plugin_t **plugins = deadbeef->plug_get_list();
int i;
+ int added_entries = 0;
for (i = 0; plugins[i]; i++)
{
if (!plugins[i]->get_actions)
@@ -474,6 +470,7 @@ list_context_menu (DdbListview *listview, DdbListviewIter it, int idx) {
if (action->flags & DB_ACTION_COMMON)
continue;
count++;
+ added_entries++;
GtkWidget *actionitem;
actionitem = gtk_menu_item_new_with_mnemonic (_(action->title));
gtk_widget_show (actionitem);
@@ -492,13 +489,14 @@ list_context_menu (DdbListview *listview, DdbListviewIter it, int idx) {
gtk_widget_set_sensitive (GTK_WIDGET (actionitem), FALSE);
}
}
- if (count > 0)
- {
- separator8 = gtk_separator_menu_item_new ();
- gtk_widget_show (separator8);
- gtk_container_add (GTK_CONTAINER (playlist_menu), separator8);
- gtk_widget_set_sensitive (separator8, FALSE);
- }
+ }
+
+ if (added_entries > 0)
+ {
+ separator8 = gtk_separator_menu_item_new ();
+ gtk_widget_show (separator8);
+ gtk_container_add (GTK_CONTAINER (playlist_menu), separator8);
+ gtk_widget_set_sensitive (separator8, FALSE);
}
properties1 = gtk_menu_item_new_with_mnemonic (_("Properties"));
@@ -733,7 +731,7 @@ on_add_column_activate (GtkMenuItem *menuitem,
int align = gtk_combo_box_get_active (GTK_COMBO_BOX (lookup_widget (dlg, "align")));
ddb_listview_column_insert (last_playlist, active_column, title, 100, align, inf->id == DB_COLUMN_ALBUM_ART ? 100 : 0, inf);
- ddb_listview_refresh (last_playlist, DDB_REFRESH_COLUMNS | DDB_REFRESH_LIST | DDB_REFRESH_HSCROLL | DDB_EXPOSE_LIST | DDB_EXPOSE_COLUMNS);
+ ddb_listview_refresh (last_playlist, DDB_REFRESH_COLUMNS | DDB_REFRESH_LIST | DDB_REFRESH_HSCROLL);
}
gtk_widget_destroy (dlg);
}
@@ -808,7 +806,7 @@ on_edit_column_activate (GtkMenuItem *menuitem,
init_column (inf, id, format);
ddb_listview_column_set_info (last_playlist, active_column, title, width, align, inf->id == DB_COLUMN_ALBUM_ART ? width : 0, inf);
- ddb_listview_refresh (last_playlist, DDB_REFRESH_COLUMNS | DDB_REFRESH_LIST | DDB_EXPOSE_LIST | DDB_EXPOSE_COLUMNS);
+ ddb_listview_refresh (last_playlist, DDB_REFRESH_COLUMNS | DDB_REFRESH_LIST);
}
gtk_widget_destroy (dlg);
}
@@ -822,7 +820,7 @@ on_remove_column_activate (GtkMenuItem *menuitem,
return;
ddb_listview_column_remove (last_playlist, active_column);
- ddb_listview_refresh (last_playlist, DDB_REFRESH_COLUMNS | DDB_REFRESH_LIST | DDB_REFRESH_HSCROLL | DDB_EXPOSE_LIST | DDB_EXPOSE_COLUMNS);
+ ddb_listview_refresh (last_playlist, DDB_REFRESH_COLUMNS | DDB_REFRESH_LIST | DDB_REFRESH_HSCROLL);
}
GtkWidget*
diff --git a/plugins/gtkui/plcommon.h b/plugins/gtkui/plcommon.h
index 8332cfcb..6a3114c1 100644
--- a/plugins/gtkui/plcommon.h
+++ b/plugins/gtkui/plcommon.h
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
diff --git a/plugins/gtkui/pluginconf.c b/plugins/gtkui/pluginconf.c
index 601f72e8..c7c73ae8 100644
--- a/plugins/gtkui/pluginconf.c
+++ b/plugins/gtkui/pluginconf.c
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@@ -30,6 +30,7 @@
#include "gtkui.h"
#include "parser.h"
#include "support.h"
+#include "pluginconf.h"
//#define trace(...) { fprintf (stderr, __VA_ARGS__); }
#define trace(fmt,...)
@@ -42,14 +43,16 @@ on_prop_browse_file (GtkButton *button, gpointer user_data) {
gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dlg), FALSE);
// restore folder
- gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER (dlg), deadbeef->conf_get_str ("filechooser.lastdir", ""));
+ deadbeef->conf_lock ();
+ gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER (dlg), deadbeef->conf_get_str_fast ("filechooser.lastdir", ""));
+ deadbeef->conf_unlock ();
int response = gtk_dialog_run (GTK_DIALOG (dlg));
// store folder
gchar *folder = gtk_file_chooser_get_current_folder_uri (GTK_FILE_CHOOSER (dlg));
if (folder) {
deadbeef->conf_set_str ("filechooser.lastdir", folder);
g_free (folder);
- deadbeef->sendmessage (M_CONFIGCHANGED, 0, 0, 0);
+ deadbeef->sendmessage (M_CONFIG_CHANGED, 0, 0, 0);
}
if (response == GTK_RESPONSE_OK) {
gchar *file = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dlg));
@@ -65,14 +68,14 @@ on_prop_browse_file (GtkButton *button, gpointer user_data) {
}
}
-static void apply_conf (GtkWidget *w, DB_plugin_t *p) {
+static void apply_conf (GtkWidget *w, ddb_dialog_t *conf) {
// parse script
char token[MAX_TOKEN];
- const char *script = p->configdialog;
+ const char *script = conf->layout;
parser_line = 1;
while (script = gettoken (script, token)) {
if (strcmp (token, "property")) {
- fprintf (stderr, "invalid token while loading plugin %s config dialog: %s at line %d\n", p->name, token, parser_line);
+ fprintf (stderr, "invalid token while loading plugin %s config dialog: %s at line %d\n", conf->title, token, parser_line);
break;
}
char labeltext[MAX_TOKEN];
@@ -85,8 +88,34 @@ static void apply_conf (GtkWidget *w, DB_plugin_t *p) {
if (!script) {
break;
}
+
+ // skip containers
+ if (!strncmp (type, "hbox[", 5) || !strncmp (type, "vbox[", 5)) {
+ // skip to ;
+ char semicolon[MAX_TOKEN];
+ while (script = gettoken_warn_eof (script, semicolon)) {
+ if (!strcmp (semicolon, ";")) {
+ break;
+ }
+ }
+ continue;
+ }
+
+ // ignore layout options
char key[MAX_TOKEN];
- script = gettoken_warn_eof (script, key);
+ const char *skiptokens[] = { "vert", NULL };
+ for (;;) {
+ script = gettoken_warn_eof (script, key);
+ int i = 0;
+ for (i = 0; skiptokens[i]; i++) {
+ if (!strcmp (key, skiptokens[i])) {
+ break;
+ }
+ }
+ if (!skiptokens[i]) {
+ break;
+ }
+ }
if (!script) {
break;
}
@@ -95,39 +124,66 @@ static void apply_conf (GtkWidget *w, DB_plugin_t *p) {
if (!script) {
break;
}
- script = gettoken_warn_eof (script, token);
- if (!script) {
- break;
- }
- if (strcmp (token, ";")) {
- fprintf (stderr, "expected `;' while loading plugin %s config dialog: %s at line %d\n", p->name, token, parser_line);
- break;
- }
// fetch data
GtkWidget *widget = lookup_widget (w, key);
if (widget) {
if (!strcmp (type, "entry") || !strcmp (type, "password")) {
- deadbeef->conf_set_str (key, gtk_entry_get_text (GTK_ENTRY (widget)));
+ conf->set_param (key, gtk_entry_get_text (GTK_ENTRY (widget)));
}
else if (!strcmp (type, "file")) {
if (deadbeef->conf_get_int ("gtkui.pluginconf.use_filechooser_button", 0)) {
// filechooser
- deadbeef->conf_set_str (key, gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget)));
+ conf->set_param (key, gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget)));
}
else {
- deadbeef->conf_set_str (key, gtk_entry_get_text (GTK_ENTRY (widget)));
+ conf->set_param (key, gtk_entry_get_text (GTK_ENTRY (widget)));
}
}
else if (!strcmp (type, "checkbox")) {
- deadbeef->conf_set_int (key, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)));
+ conf->set_param (key, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)) ? "1" : "0");
+ }
+ else if (!strncmp (type, "hscale[", 7) || !strncmp (type, "vscale[", 7)) {
+ char s[20];
+ snprintf (s, sizeof (s), "%f", gtk_range_get_value (GTK_RANGE (widget)));
+ conf->set_param (key, s);
}
- else if (!strncmp (type, "hscale[", 7)) {
- deadbeef->conf_set_float (key, gtk_range_get_value (GTK_RANGE (widget)));
+ else if (!strncmp (type, "spinbtn[", 8)) {
+ char s[20];
+ snprintf (s, sizeof (s), "%f", (float)gtk_spin_button_get_value (GTK_SPIN_BUTTON (widget)));
+ conf->set_param (key, s);
+ }
+ else if (!strncmp (type, "select[", 7)) {
+ int n;
+ if (1 != sscanf (type+6, "[%d]", &n)) {
+ break;
+ }
+ for (int i = 0; i < n; i++) {
+ char value[MAX_TOKEN];
+ script = gettoken_warn_eof (script, value);
+ if (!script) {
+ break;
+ }
+ }
+ if (!script) {
+ break;
+ }
+ char s[20];
+ snprintf (s, sizeof (s), "%d", gtk_combo_box_get_active (GTK_COMBO_BOX (widget)));
+ conf->set_param (key, s);
}
}
+
+ script = gettoken_warn_eof (script, token);
+ if (!script) {
+ break;
+ }
+ if (strcmp (token, ";")) {
+ fprintf (stderr, "expected `;' while loading plugin %s config dialog: %s at line %d\n", conf->title, token, parser_line);
+ break;
+ }
}
- deadbeef->sendmessage (M_CONFIGCHANGED, 0, 0, 0);
+ deadbeef->sendmessage (M_CONFIG_CHANGED, 0, 0, 0);
}
static void
@@ -135,22 +191,69 @@ prop_changed (GtkWidget *editable, gpointer user_data) {
gtk_dialog_set_response_sensitive (GTK_DIALOG (user_data), GTK_RESPONSE_APPLY, TRUE);
}
-void
-plugin_configure (GtkWidget *parentwin, DB_plugin_t *p) {
+int
+ddb_button_from_gtk_response (int response) {
+ switch (response) {
+ case GTK_RESPONSE_OK:
+ return ddb_button_ok;
+ case GTK_RESPONSE_CANCEL:
+ return ddb_button_cancel;
+ case GTK_RESPONSE_CLOSE:
+ return ddb_button_close;
+ case GTK_RESPONSE_APPLY:
+ return ddb_button_apply;
+ case GTK_RESPONSE_YES:
+ return ddb_button_yes;
+ case GTK_RESPONSE_NO:
+ return ddb_button_no;
+ }
+ return -1;
+}
+
+int
+gtkui_run_dialog (GtkWidget *parentwin, ddb_dialog_t *conf, uint32_t buttons, int (*callback)(int button, void *ctx), void *ctx) {
// create window
char title[200];
- snprintf (title, sizeof (title), _("Setup %s"), p->name);
- GtkWidget *win = gtk_dialog_new_with_buttons (title, GTK_WINDOW (parentwin), GTK_DIALOG_MODAL, GTK_STOCK_APPLY, GTK_RESPONSE_APPLY, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_OK, NULL);
- gtk_dialog_set_default_response (GTK_DIALOG (win), GTK_RESPONSE_OK);
+ snprintf (title, sizeof (title), _("Configure %s"), conf->title);
+ GtkWidget *win;
+ if (!buttons) {
+ win = gtk_dialog_new_with_buttons (title, GTK_WINDOW (parentwin), GTK_DIALOG_MODAL, GTK_STOCK_APPLY, GTK_RESPONSE_APPLY, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_OK, NULL);
+ gtk_dialog_set_default_response (GTK_DIALOG (win), GTK_RESPONSE_OK);
+ }
+ else {
+ win = gtk_dialog_new_with_buttons (title, GTK_WINDOW (parentwin), GTK_DIALOG_MODAL, NULL);
+ if (buttons & (1<<ddb_button_ok)) {
+ gtk_dialog_add_button (GTK_DIALOG (win), GTK_STOCK_OK, GTK_RESPONSE_OK);
+ }
+ if (buttons & (1<<ddb_button_cancel)) {
+ gtk_dialog_add_button (GTK_DIALOG (win), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
+ }
+ if (buttons & (1<<ddb_button_close)) {
+ gtk_dialog_add_button (GTK_DIALOG (win), GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE);
+ }
+ if (buttons & (1<<ddb_button_apply)) {
+ gtk_dialog_add_button (GTK_DIALOG (win), GTK_STOCK_APPLY, GTK_RESPONSE_APPLY);
+ }
+ if (buttons & (1<<ddb_button_yes)) {
+ gtk_dialog_add_button (GTK_DIALOG (win), GTK_STOCK_YES, GTK_RESPONSE_YES);
+ }
+ if (buttons & (1<<ddb_button_no)) {
+ gtk_dialog_add_button (GTK_DIALOG (win), GTK_STOCK_NO, GTK_RESPONSE_NO);
+ }
+ }
gtk_window_set_type_hint (GTK_WINDOW (win), GDK_WINDOW_TYPE_HINT_DIALOG);
gtk_container_set_border_width (GTK_CONTAINER(win), 12);
gtk_window_set_title (GTK_WINDOW (win), title);
gtk_window_set_modal (GTK_WINDOW (win), TRUE);
gtk_window_set_transient_for (GTK_WINDOW (win), GTK_WINDOW (parentwin));
- GtkWidget *vbox;
- vbox = GTK_DIALOG (win)->vbox;
- gtk_box_set_spacing (GTK_BOX (vbox), 8);
+
+ GtkWidget *widgets[100] = {NULL};
+ int pack[100] = {0};
+ int ncurr = 0;
+
+ widgets[ncurr] = GTK_DIALOG (win)->vbox;
+ gtk_box_set_spacing (GTK_BOX (widgets[ncurr]), 8);
GtkWidget *action_area = GTK_DIALOG (win)->action_area;
gtk_widget_show (action_area);
gtk_button_box_set_layout (GTK_BUTTON_BOX (action_area), GTK_BUTTONBOX_END);
@@ -158,11 +261,11 @@ plugin_configure (GtkWidget *parentwin, DB_plugin_t *p) {
// parse script
char token[MAX_TOKEN];
- const char *script = p->configdialog;
+ const char *script = conf->layout;
parser_line = 1;
while (script = gettoken (script, token)) {
if (strcmp (token, "property")) {
- fprintf (stderr, "invalid token while loading plugin %s config dialog: %s at line %d\n", p->name, token, parser_line);
+ fprintf (stderr, "invalid token while loading plugin %s config dialog: %s at line %d\n", conf->title, token, parser_line);
break;
}
char labeltext[MAX_TOKEN];
@@ -170,34 +273,100 @@ plugin_configure (GtkWidget *parentwin, DB_plugin_t *p) {
if (!script) {
break;
}
+
+ if (ncurr > 0) {
+ pack[ncurr]--;
+ if (pack[ncurr] < 0) {
+ ncurr--;
+ }
+ }
+
char type[MAX_TOKEN];
script = gettoken_warn_eof (script, type);
if (!script) {
break;
}
+
+ if (!strncmp (type, "hbox[", 5) || !strncmp (type, "vbox[", 5)) {
+ ncurr++;
+ int n = 0;
+ if (1 != sscanf (type+4, "[%d]", &n)) {
+ break;
+ }
+ pack[ncurr] = n;
+
+ int vert = 0;
+ int hmg = FALSE;
+ int fill = FALSE;
+ int expand = FALSE;
+ int border = 0;
+ int spacing = 8;
+ int height = 100;
+
+ char param[MAX_TOKEN];
+ for (;;) {
+ script = gettoken_warn_eof (script, param);
+ if (!script) {
+ break;
+ }
+ if (!strcmp (param, ";")) {
+ break;
+ }
+ else if (!strcmp (param, "hmg")) {
+ hmg = TRUE;
+ }
+ else if (!strcmp (param, "fill")) {
+ fill = TRUE;
+ }
+ else if (!strcmp (param, "expand")) {
+ expand = TRUE;
+ }
+ else if (!strncmp (param, "border=", 7)) {
+ border = atoi (param+7);
+ }
+ else if (!strncmp (param, "spacing=", 8)) {
+ spacing = atoi (param+8);
+ }
+ else if (!strncmp (param, "height=", 7)) {
+ height = atoi (param+7);
+ }
+ }
+
+ widgets[ncurr] = vert ? gtk_vbox_new (TRUE, spacing) : gtk_hbox_new (TRUE, spacing);
+ gtk_widget_set_size_request (widgets[ncurr], -1, height);
+ gtk_widget_show (widgets[ncurr]);
+ gtk_box_pack_start (GTK_BOX(widgets[ncurr-1]), widgets[ncurr], fill, expand, border);
+ continue;
+ }
+
+ int vertical = 0;
+
char key[MAX_TOKEN];
- script = gettoken_warn_eof (script, key);
- if (!script) {
- break;
+ for (;;) {
+ script = gettoken_warn_eof (script, key);
+ if (!script) {
+ break;
+ }
+ if (!strcmp (key, "vert")) {
+ vertical = 1;
+ }
+ else {
+ break;
+ }
}
+
char def[MAX_TOKEN];
script = gettoken_warn_eof (script, def);
if (!script) {
break;
}
- script = gettoken_warn_eof (script, token);
- if (!script) {
- break;
- }
- if (strcmp (token, ";")) {
- fprintf (stderr, "expected `;' while loading plugin %s config dialog: %s at line %d\n", p->name, token, parser_line);
- break;
- }
// add to dialog
GtkWidget *label = NULL;
GtkWidget *prop = NULL;
GtkWidget *cont = NULL;
+ char value[1000];
+ conf->get_param (key, value, sizeof (value), def);
if (!strcmp (type, "entry") || !strcmp (type, "password")) {
label = gtk_label_new (_(labeltext));
gtk_widget_show (label);
@@ -205,13 +374,17 @@ plugin_configure (GtkWidget *parentwin, DB_plugin_t *p) {
gtk_entry_set_activates_default (GTK_ENTRY (prop), TRUE);
g_signal_connect (G_OBJECT (prop), "changed", G_CALLBACK (prop_changed), win);
gtk_widget_show (prop);
- gtk_entry_set_text (GTK_ENTRY (prop), deadbeef->conf_get_str (key, def));
+ gtk_entry_set_text (GTK_ENTRY (prop), value);
+
+ if (!strcmp (type, "password")) {
+ gtk_entry_set_visibility (GTK_ENTRY (prop), FALSE);
+ }
}
else if (!strcmp (type, "checkbox")) {
prop = gtk_check_button_new_with_label (_(labeltext));
g_signal_connect (G_OBJECT (prop), "toggled", G_CALLBACK (prop_changed), win);
gtk_widget_show (prop);
- int val = deadbeef->conf_get_int (key, atoi (def));
+ int val = atoi (value);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (prop), val);
}
else if (!strcmp (type, "file")) {
@@ -220,7 +393,7 @@ plugin_configure (GtkWidget *parentwin, DB_plugin_t *p) {
if (deadbeef->conf_get_int ("gtkui.pluginconf.use_filechooser_button", 0)) {
prop = gtk_file_chooser_button_new (_(labeltext), GTK_FILE_CHOOSER_ACTION_OPEN);
gtk_widget_show (prop);
- gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (prop), deadbeef->conf_get_str (key, def));
+ gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (prop), value);
g_signal_connect (G_OBJECT (prop), "file-set", G_CALLBACK (prop_changed), win);
}
else {
@@ -231,7 +404,7 @@ plugin_configure (GtkWidget *parentwin, DB_plugin_t *p) {
g_signal_connect (G_OBJECT (prop), "changed", G_CALLBACK (prop_changed), win);
gtk_widget_show (prop);
gtk_editable_set_editable (GTK_EDITABLE (prop), FALSE);
- gtk_entry_set_text (GTK_ENTRY (prop), deadbeef->conf_get_str (key, def));
+ gtk_entry_set_text (GTK_ENTRY (prop), value);
gtk_box_pack_start (GTK_BOX (cont), prop, TRUE, TRUE, 0);
GtkWidget *btn = gtk_button_new_with_label ("…");
gtk_widget_show (btn);
@@ -239,36 +412,88 @@ plugin_configure (GtkWidget *parentwin, DB_plugin_t *p) {
g_signal_connect (G_OBJECT (btn), "clicked", G_CALLBACK (on_prop_browse_file), prop);
}
}
- else if (!strncmp (type, "hscale[", 7)) {
+ else if (!strncmp (type, "select[", 7)) {
+ int n;
+ if (1 != sscanf (type+6, "[%d]", &n)) {
+ break;
+ }
+
+ label = gtk_label_new (_(labeltext));
+ gtk_widget_show (label);
+
+ prop = gtk_combo_box_new_text ();
+ gtk_widget_show (prop);
+
+ for (int i = 0; i < n; i++) {
+ char entry[MAX_TOKEN];
+ script = gettoken_warn_eof (script, entry);
+ if (!script) {
+ break;
+ }
+
+ gtk_combo_box_append_text (GTK_COMBO_BOX (prop), entry);
+ }
+ if (!script) {
+ break;
+ }
+ gtk_combo_box_set_active (GTK_COMBO_BOX (prop), atoi (value));
+ g_signal_connect ((gpointer) prop, "changed",
+ G_CALLBACK (prop_changed),
+ win);
+ }
+ else if (!strncmp (type, "hscale[", 7) || !strncmp (type, "vscale[", 7) || !strncmp (type, "spinbtn[", 8)) {
float min, max, step;
- if (3 != sscanf (type+6, "[%f,%f,%f]", &min, &max, &step)) {
- min = 0;
- max = 100;
- step = 1;
+ const char *args;
+ if (type[0] == 's') {
+ args = type + 7;
}
+ else {
+ args = type + 6;
+ }
+ if (3 != sscanf (args, "[%f,%f,%f]", &min, &max, &step)) {
+ break;
+ }
+ int invert = 0;
if (min >= max) {
float tmp = min;
min = max;
max = tmp;
- break;
+ invert = 1;
}
if (step <= 0) {
step = 1;
}
- prop = gtk_hscale_new_with_range (min, max, step);
+ if (type[0] == 's') {
+ prop = gtk_spin_button_new_with_range (min, max, step);
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON (prop), atof (value));
+ }
+ else {
+ prop = type[0] == 'h' ? gtk_hscale_new_with_range (min, max, step) : gtk_vscale_new_with_range (min, max, step);
+ if (invert) {
+ gtk_range_set_inverted (GTK_RANGE (prop), TRUE);
+ }
+ gtk_range_set_value (GTK_RANGE (prop), (gdouble)atof (value));
+ gtk_scale_set_value_pos (GTK_SCALE (prop), GTK_POS_RIGHT);
+ }
label = gtk_label_new (_(labeltext));
gtk_widget_show (label);
g_signal_connect (G_OBJECT (prop), "value-changed", G_CALLBACK (prop_changed), win);
gtk_widget_show (prop);
- gtk_range_set_value (GTK_RANGE (prop), (gdouble)deadbeef->conf_get_float (key, (float)*def));
- gtk_scale_set_value_pos (GTK_SCALE (prop), GTK_POS_RIGHT);
}
- if (!strcmp (type, "password")) {
- gtk_entry_set_visibility (GTK_ENTRY (prop), FALSE);
+
+ script = gettoken_warn_eof (script, token);
+ if (!script) {
+ break;
+ }
+ if (strcmp (token, ";")) {
+ fprintf (stderr, "expected `;' while loading plugin %s config dialog: %s at line %d\n", conf->title, token, parser_line);
+ break;
}
+
+
if (label && prop) {
GtkWidget *hbox = NULL;
- hbox = gtk_hbox_new (FALSE, 8);
+ hbox = vertical ? gtk_vbox_new (FALSE, 8) : gtk_hbox_new (FALSE, 8);
gtk_widget_show (hbox);
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (hbox), cont ? cont : prop, TRUE, TRUE, 0);
@@ -281,7 +506,7 @@ plugin_configure (GtkWidget *parentwin, DB_plugin_t *p) {
g_object_set_data (G_OBJECT (win), key, prop);
}
if (cont) {
- gtk_box_pack_start (GTK_BOX (vbox), cont, FALSE, FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (widgets[ncurr]), cont, FALSE, FALSE, 0);
}
}
@@ -290,10 +515,21 @@ plugin_configure (GtkWidget *parentwin, DB_plugin_t *p) {
gtk_dialog_set_response_sensitive (GTK_DIALOG (win), GTK_RESPONSE_APPLY, FALSE);
response = gtk_dialog_run (GTK_DIALOG (win));
if (response == GTK_RESPONSE_APPLY || response == GTK_RESPONSE_OK) {
- apply_conf (win, p);
+ apply_conf (win, conf);
+ }
+ if (callback) {
+ int btn = ddb_button_from_gtk_response (response);
+ if (!callback (btn, ctx)) {
+ break;
+ }
}
} while (response == GTK_RESPONSE_APPLY);
gtk_widget_destroy (win);
+ int btn = ddb_button_from_gtk_response (response);
+ return btn;
}
-
+int
+gtkui_run_dialog_root (ddb_dialog_t *conf, uint32_t buttons, int (*callback)(int button, void *ctx), void *ctx) {
+ return gtkui_run_dialog (mainwin, conf, buttons, callback, ctx);
+}
diff --git a/plugins/gtkui/pluginconf.h b/plugins/gtkui/pluginconf.h
new file mode 100644
index 00000000..102691aa
--- /dev/null
+++ b/plugins/gtkui/pluginconf.h
@@ -0,0 +1,28 @@
+/*
+ DeaDBeeF - ultimate music player for GNU/Linux systems with X11
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+#ifndef __PLUGINCONF_H
+#define __PLUGINCONF_H
+
+int
+gtkui_run_dialog (GtkWidget *parentwin, ddb_dialog_t *conf, uint32_t buttons, int (*callback)(int button, void *ctx), void *ctx);
+
+int
+gtkui_run_dialog_root (ddb_dialog_t *conf, uint32_t buttons, int (*callback)(int button, void *ctx), void *ctx);
+
+#endif
diff --git a/plugins/gtkui/prefwin.c b/plugins/gtkui/prefwin.c
index 4e1c42b0..9883fc96 100644
--- a/plugins/gtkui/prefwin.c
+++ b/plugins/gtkui/prefwin.c
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@@ -34,6 +34,9 @@
#include "support.h"
#include "eq.h"
#include "ddblistview.h"
+#include "pluginconf.h"
+#include "dspconfig.h"
+#include "wingeom.h"
#define GLADE_HOOKUP_OBJECT(component,widget,name) \
g_object_set_data_full (G_OBJECT (component), name, \
@@ -56,9 +59,11 @@ gtk_enum_sound_callback (const char *name, const char *desc, void *userdata) {
GtkComboBox *combobox = GTK_COMBO_BOX (userdata);
gtk_combo_box_append_text (combobox, desc);
- if (!strcmp (deadbeef->conf_get_str ("alsa_soundcard", "default"), name)) {
+ deadbeef->conf_lock ();
+ if (!strcmp (deadbeef->conf_get_str_fast ("alsa_soundcard", "default"), name)) {
gtk_combo_box_set_active (combobox, num_alsa_devices);
}
+ deadbeef->conf_unlock ();
strncpy (alsa_device_names[num_alsa_devices], name, 63);
alsa_device_names[num_alsa_devices][63] = 0;
@@ -66,40 +71,23 @@ gtk_enum_sound_callback (const char *name, const char *desc, void *userdata) {
}
void
-on_plugin_active_toggled (GtkCellRendererToggle *cell_renderer, gchar *path, GtkTreeModel *model) {
- GtkTreePath *p = gtk_tree_path_new_from_string (path);
- if (p) {
- int *indices = gtk_tree_path_get_indices (p);
- //gtk_tree_path_free (p); // wtf?? gtk crashes on this
- if (indices) {
- DB_plugin_t **plugins = deadbeef->plug_get_list ();
- DB_plugin_t *plug = plugins[*indices];
- gboolean state;
- GtkTreeIter iter;
- gtk_tree_model_get_iter (model, &iter, p);
- gtk_tree_model_get (model, &iter, 0, &state, -1);
- if (!deadbeef->plug_activate (plug, !state)) {
- gtk_list_store_set (GTK_LIST_STORE (model), &iter, 0, !state, -1);
- }
- }
- g_free (indices);
- }
-}
-
-void
preferences_fill_soundcards (void) {
if (!prefwin) {
return;
}
- const char *s = deadbeef->conf_get_str ("alsa_soundcard", "default");
GtkComboBox *combobox = GTK_COMBO_BOX (lookup_widget (prefwin, "pref_soundcard"));
GtkTreeModel *mdl = gtk_combo_box_get_model (combobox);
gtk_list_store_clear (GTK_LIST_STORE (mdl));
gtk_combo_box_append_text (combobox, _("Default Audio Device"));
+
+ deadbeef->conf_lock ();
+ const char *s = deadbeef->conf_get_str_fast ("alsa_soundcard", "default");
if (!strcmp (s, "default")) {
gtk_combo_box_set_active (combobox, 0);
}
+ deadbeef->conf_unlock ();
+
num_alsa_devices = 1;
strcpy (alsa_device_names[0], "default");
if (deadbeef->get_output ()->enum_soundcards) {
@@ -269,6 +257,7 @@ prefwin_init_theme_colors (void) {
gtk_color_button_set_color (GTK_COLOR_BUTTON (lookup_widget (prefwin, "tabstrip_mid")), (gtkui_get_tabstrip_mid_color (&clr), &clr));
gtk_color_button_set_color (GTK_COLOR_BUTTON (lookup_widget (prefwin, "tabstrip_light")), (gtkui_get_tabstrip_light_color (&clr), &clr));
gtk_color_button_set_color (GTK_COLOR_BUTTON (lookup_widget (prefwin, "tabstrip_base")), (gtkui_get_tabstrip_base_color (&clr), &clr));
+ gtk_color_button_set_color (GTK_COLOR_BUTTON (lookup_widget (prefwin, "tabstrip_text")), (gtkui_get_tabstrip_text_color (&clr), &clr));
gtk_color_button_set_color (GTK_COLOR_BUTTON (lookup_widget (prefwin, "listview_even_row")), (gtkui_get_listview_even_row_color (&clr), &clr));
gtk_color_button_set_color (GTK_COLOR_BUTTON (lookup_widget (prefwin, "listview_odd_row")), (gtkui_get_listview_odd_row_color (&clr), &clr));
gtk_color_button_set_color (GTK_COLOR_BUTTON (lookup_widget (prefwin, "listview_selected_row")), (gtkui_get_listview_selection_color (&clr), &clr));
@@ -472,15 +461,16 @@ on_preferences_activate (GtkMenuItem *menuitem,
if (prefwin) {
return;
}
+ deadbeef->conf_lock ();
GtkWidget *w = prefwin = create_prefwin ();
gtk_window_set_transient_for (GTK_WINDOW (w), GTK_WINDOW (mainwin));
GtkComboBox *combobox = NULL;
// output plugin selection
- const char *outplugname = deadbeef->conf_get_str ("output_plugin", _("ALSA output plugin"));
combobox = GTK_COMBO_BOX (lookup_widget (w, "pref_output_plugin"));
+ const char *outplugname = deadbeef->conf_get_str_fast ("output_plugin", "ALSA output plugin");
DB_output_t **out_plugs = deadbeef->plug_get_output_list ();
for (int i = 0; out_plugs[i]; i++) {
gtk_combo_box_append_text (combobox, out_plugs[i]->plugin.name);
@@ -500,13 +490,6 @@ on_preferences_activate (GtkMenuItem *menuitem,
G_CALLBACK (on_pref_soundcard_changed),
NULL);
- // alsa resampling
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (lookup_widget (w, "pref_dynsamplerate")), deadbeef->conf_get_int ("playback.dynsamplerate", 0));
-
- // src_quality
- combobox = GTK_COMBO_BOX (lookup_widget (w, "pref_src_quality"));
- gtk_combo_box_set_active (combobox, deadbeef->conf_get_int ("src_quality", 2));
-
// replaygain_mode
combobox = GTK_COMBO_BOX (lookup_widget (w, "pref_replaygain_mode"));
gtk_combo_box_set_active (combobox, deadbeef->conf_get_int ("replaygain_mode", 0));
@@ -514,6 +497,12 @@ on_preferences_activate (GtkMenuItem *menuitem,
// replaygain_scale
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (lookup_widget (w, "pref_replaygain_scale")), deadbeef->conf_get_int ("replaygain_scale", 1));
+ // replaygain_preamp
+ gtk_range_set_value (GTK_RANGE (lookup_widget (w, "replaygain_preamp")), deadbeef->conf_get_int ("replaygain_preamp", 0));
+
+ // dsp
+ dsp_setup_init (prefwin);
+
// close_send_to_tray
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (lookup_widget (w, "pref_close_send_to_tray")), deadbeef->conf_get_int ("close_send_to_tray", 0));
@@ -529,19 +518,38 @@ on_preferences_activate (GtkMenuItem *menuitem,
// hide_delete_from_disk
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (lookup_widget (w, "hide_delete_from_disk")), deadbeef->conf_get_int ("gtkui.hide_remove_from_disk", 0));
+ // auto-rename playlist from folder name
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (lookup_widget (w, "auto_name_playlist_from_folder")), deadbeef->conf_get_int ("gtkui.name_playlist_from_folder", 0));
+
+ // refresh rate
+ int val = deadbeef->conf_get_int ("gtkui.refresh_rate", 10);
+ gtk_range_set_value (GTK_RANGE (lookup_widget (w, "gui_fps")), val);
+
+ // add from archives
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (lookup_widget (w, "ignore_archives")), deadbeef->conf_get_int ("ignore_archives", 1));
// titlebar text
- gtk_entry_set_text (GTK_ENTRY (lookup_widget (w, "titlebar_format_playing")), deadbeef->conf_get_str ("gtkui.titlebar_playing", "%a - %t - DeaDBeeF-%V"));
- gtk_entry_set_text (GTK_ENTRY (lookup_widget (w, "titlebar_format_stopped")), deadbeef->conf_get_str ("gtkui.titlebar_stopped", "DeaDBeeF-%V"));
+ gtk_entry_set_text (GTK_ENTRY (lookup_widget (w, "titlebar_format_playing")), deadbeef->conf_get_str_fast ("gtkui.titlebar_playing", "%a - %t - DeaDBeeF-%V"));
+ gtk_entry_set_text (GTK_ENTRY (lookup_widget (w, "titlebar_format_stopped")), deadbeef->conf_get_str_fast ("gtkui.titlebar_stopped", "DeaDBeeF-%V"));
// cli playlist
int active = deadbeef->conf_get_int ("cli_add_to_specific_playlist", 1);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (lookup_widget (prefwin, "cli_add_to_playlist")), active);
gtk_widget_set_sensitive (lookup_widget (prefwin, "cli_playlist_name"), active);
- gtk_entry_set_text (GTK_ENTRY (lookup_widget (prefwin, "cli_playlist_name")), deadbeef->conf_get_str ("cli_add_playlist_name", "Default"));
+ gtk_entry_set_text (GTK_ENTRY (lookup_widget (prefwin, "cli_playlist_name")), deadbeef->conf_get_str_fast ("cli_add_playlist_name", "Default"));
// resume last session
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (lookup_widget (w, "resume_last_session")), deadbeef->conf_get_int ("resume_last_session", 0));
+ // fill gui plugin list
+ combobox = GTK_COMBO_BOX (lookup_widget (w, "gui_plugin"));
+ const char **names = deadbeef->plug_get_gui_names ();
+ for (int i = 0; names[i]; i++) {
+ gtk_combo_box_append_text (combobox, names[i]);
+ if (!strcmp (names[i], deadbeef->conf_get_str_fast ("gui_plugin", "GTK2"))) {
+ gtk_combo_box_set_active (combobox, i);
+ }
+ }
+
// override bar colors
int override = deadbeef->conf_get_int ("gtkui.override_bar_colors", 0);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (lookup_widget (prefwin, "override_bar_colors")), override);
@@ -562,10 +570,10 @@ on_preferences_activate (GtkMenuItem *menuitem,
// network
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (lookup_widget (w, "pref_network_enableproxy")), deadbeef->conf_get_int ("network.proxy", 0));
- gtk_entry_set_text (GTK_ENTRY (lookup_widget (w, "pref_network_proxyaddress")), deadbeef->conf_get_str ("network.proxy.address", ""));
- gtk_entry_set_text (GTK_ENTRY (lookup_widget (w, "pref_network_proxyport")), deadbeef->conf_get_str ("network.proxy.port", "8080"));
+ gtk_entry_set_text (GTK_ENTRY (lookup_widget (w, "pref_network_proxyaddress")), deadbeef->conf_get_str_fast ("network.proxy.address", ""));
+ gtk_entry_set_text (GTK_ENTRY (lookup_widget (w, "pref_network_proxyport")), deadbeef->conf_get_str_fast ("network.proxy.port", "8080"));
combobox = GTK_COMBO_BOX (lookup_widget (w, "pref_network_proxytype"));
- const char *type = deadbeef->conf_get_str ("network.proxy.type", "HTTP");
+ const char *type = deadbeef->conf_get_str_fast ("network.proxy.type", "HTTP");
if (!strcasecmp (type, "HTTP")) {
gtk_combo_box_set_active (combobox, 0);
}
@@ -584,8 +592,8 @@ on_preferences_activate (GtkMenuItem *menuitem,
else if (!strcasecmp (type, "SOCKS5_HOSTNAME")) {
gtk_combo_box_set_active (combobox, 5);
}
- gtk_entry_set_text (GTK_ENTRY (lookup_widget (w, "proxyuser")), deadbeef->conf_get_str ("network.proxy.username", ""));
- gtk_entry_set_text (GTK_ENTRY (lookup_widget (w, "proxypassword")), deadbeef->conf_get_str ("network.proxy.password", ""));
+ gtk_entry_set_text (GTK_ENTRY (lookup_widget (w, "proxyuser")), deadbeef->conf_get_str_fast ("network.proxy.username", ""));
+ gtk_entry_set_text (GTK_ENTRY (lookup_widget (w, "proxypassword")), deadbeef->conf_get_str_fast ("network.proxy.password", ""));
// list of plugins
GtkTreeView *tree = GTK_TREE_VIEW (lookup_widget (w, "pref_pluginlist"));
@@ -622,7 +630,6 @@ on_preferences_activate (GtkMenuItem *menuitem,
gtk_tree_view_set_model (tree, GTK_TREE_MODEL (store));
gtk_widget_set_sensitive (lookup_widget (prefwin, "configure_plugin"), FALSE);
-// gtk_widget_show (w);
// hotkeys
DB_plugin_t *hotkeys = deadbeef->plug_get_for_id ("hotkeys");
@@ -630,42 +637,9 @@ on_preferences_activate (GtkMenuItem *menuitem,
prefwin_add_hotkeys_tab (prefwin);
}
- // tag writer
- int strip_id3v2 = deadbeef->conf_get_int ("mp3.strip_id3v2", 0);
- int strip_id3v1 = deadbeef->conf_get_int ("mp3.strip_id3v1", 0);
- int strip_apev2 = deadbeef->conf_get_int ("mp3.strip_apev2", 0);
- int write_id3v2 = deadbeef->conf_get_int ("mp3.write_id3v2", 1);
- int write_id3v1 = deadbeef->conf_get_int ("mp3.write_id3v1", 1);
- int write_apev2 = deadbeef->conf_get_int ("mp3.write_apev2", 0);
- int id3v2_version = deadbeef->conf_get_int ("mp3.id3v2_version", 3);
- const char *id3v1_encoding = deadbeef->conf_get_str ("mp3.id3v1_encoding", "iso8859-1");
- int ape_strip_id3v2 = deadbeef->conf_get_int ("ape.strip_id3v2", 0);
- int ape_strip_apev2 = deadbeef->conf_get_int ("ape.strip_apev2", 0);
- int ape_write_id3v2 = deadbeef->conf_get_int ("ape.write_id3v2", 0);
- int ape_write_apev2 = deadbeef->conf_get_int ("ape.write_apev2", 1);
- int wv_strip_apev2 = deadbeef->conf_get_int ("wv.strip_apev2", 0);
- int wv_strip_id3v1 = deadbeef->conf_get_int ("wv.strip_id3v1", 0);
- int wv_write_apev2 = deadbeef->conf_get_int ("wv.write_apev2", 1);
- int wv_write_id3v1 = deadbeef->conf_get_int ("wv.write_id3v1", 0);
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (lookup_widget (prefwin, "strip_id3v2")), strip_id3v2);
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (lookup_widget (prefwin, "strip_id3v1")), strip_id3v1);
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (lookup_widget (prefwin, "strip_apev2")), strip_apev2);
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (lookup_widget (prefwin, "write_id3v2")), write_id3v2);
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (lookup_widget (prefwin, "write_id3v1")), write_id3v1);
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (lookup_widget (prefwin, "write_apev2")), write_apev2);
- gtk_combo_box_set_active (GTK_COMBO_BOX (lookup_widget (prefwin, "id3v2_version")), id3v2_version != 4 ? 0 : 1);
- gtk_entry_set_text (GTK_ENTRY (lookup_widget (prefwin, "id3v1_encoding")), id3v1_encoding);
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (lookup_widget (prefwin, "ape_strip_id3v2")), ape_strip_id3v2);
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (lookup_widget (prefwin, "ape_strip_apev2")), ape_strip_apev2);
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (lookup_widget (prefwin, "ape_write_apev2")), ape_write_apev2);
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (lookup_widget (prefwin, "ape_write_id3v2")), ape_write_id3v2);
-
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (lookup_widget (prefwin, "wv_strip_id3v1")), wv_strip_id3v1);
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (lookup_widget (prefwin, "wv_strip_apev2")), wv_strip_apev2);
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (lookup_widget (prefwin, "wv_write_apev2")), wv_write_apev2);
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (lookup_widget (prefwin, "wv_write_id3v1")), wv_write_id3v1);
-
+ deadbeef->conf_unlock ();
gtk_dialog_run (GTK_DIALOG (prefwin));
+ dsp_setup_free ();
gtk_widget_destroy (prefwin);
deadbeef->conf_save ();
prefwin = NULL;
@@ -678,11 +652,13 @@ on_pref_soundcard_changed (GtkComboBox *combobox,
{
int active = gtk_combo_box_get_active (combobox);
if (active >= 0 && active < num_alsa_devices) {
- const char *soundcard = deadbeef->conf_get_str ("alsa_soundcard", "default");
+ deadbeef->conf_lock ();
+ const char *soundcard = deadbeef->conf_get_str_fast ("alsa_soundcard", "default");
if (strcmp (soundcard, alsa_device_names[active])) {
deadbeef->conf_set_str ("alsa_soundcard", alsa_device_names[active]);
- deadbeef->sendmessage (M_CONFIGCHANGED, 0, 0, 0);
+ deadbeef->sendmessage (M_CONFIG_CHANGED, 0, 0, 0);
}
+ deadbeef->conf_unlock ();
}
}
@@ -690,13 +666,14 @@ void
on_pref_output_plugin_changed (GtkComboBox *combobox,
gpointer user_data)
{
- const char *outplugname = deadbeef->conf_get_str ("output_plugin", _("ALSA output plugin"));
int active = gtk_combo_box_get_active (combobox);
DB_output_t **out_plugs = deadbeef->plug_get_output_list ();
DB_output_t *prev = NULL;
DB_output_t *new = NULL;
+ deadbeef->conf_lock ();
+ const char *outplugname = deadbeef->conf_get_str_fast ("output_plugin", "ALSA output plugin");
for (int i = 0; out_plugs[i]; i++) {
if (!strcmp (out_plugs[i]->plugin.name, outplugname)) {
prev = out_plugs[i];
@@ -705,6 +682,7 @@ on_pref_output_plugin_changed (GtkComboBox *combobox,
new = out_plugs[i];
}
}
+ deadbeef->conf_unlock ();
if (!new) {
fprintf (stderr, "failed to find output plugin selected in preferences window\n");
@@ -718,32 +696,12 @@ on_pref_output_plugin_changed (GtkComboBox *combobox,
}
void
-on_pref_dynsamplerate_clicked (GtkButton *button,
- gpointer user_data)
-{
- int active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button));
- deadbeef->conf_set_int ("playback.dynsamplerate", active);
- deadbeef->sendmessage (M_CONFIGCHANGED, 0, 0, 0);
-}
-
-
-void
-on_pref_src_quality_changed (GtkComboBox *combobox,
- gpointer user_data)
-{
- int active = gtk_combo_box_get_active (combobox);
- deadbeef->conf_set_int ("src_quality", active == -1 ? 2 : active);
- deadbeef->sendmessage (M_CONFIGCHANGED, 0, 0, 0);
-}
-
-
-void
on_pref_replaygain_mode_changed (GtkComboBox *combobox,
gpointer user_data)
{
int active = gtk_combo_box_get_active (combobox);
deadbeef->conf_set_int ("replaygain_mode", active == -1 ? 0 : active);
- deadbeef->sendmessage (M_CONFIGCHANGED, 0, 0, 0);
+ deadbeef->sendmessage (M_CONFIG_CHANGED, 0, 0, 0);
}
void
@@ -752,7 +710,16 @@ on_pref_replaygain_scale_clicked (GtkButton *button,
{
int active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button));
deadbeef->conf_set_int ("replaygain_scale", active);
- deadbeef->sendmessage (M_CONFIGCHANGED, 0, 0, 0);
+ deadbeef->sendmessage (M_CONFIG_CHANGED, 0, 0, 0);
+}
+
+void
+on_replaygain_preamp_value_changed (GtkRange *range,
+ gpointer user_data)
+{
+ float val = gtk_range_get_value (range);
+ deadbeef->conf_set_float ("replaygain_preamp", val);
+ deadbeef->sendmessage (M_CONFIG_CHANGED, 0, 0, 0);
}
@@ -762,7 +729,7 @@ on_pref_close_send_to_tray_clicked (GtkButton *button,
{
int active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button));
deadbeef->conf_set_int ("close_send_to_tray", active);
- deadbeef->sendmessage (M_CONFIGCHANGED, 0, 0, 0);
+ deadbeef->sendmessage (M_CONFIG_CHANGED, 0, 0, 0);
}
void
@@ -771,7 +738,7 @@ on_hide_tray_icon_toggled (GtkToggleButton *togglebutton,
{
int active = gtk_toggle_button_get_active (togglebutton);
deadbeef->conf_set_int ("gtkui.hide_tray_icon", active);
- deadbeef->sendmessage (M_CONFIGCHANGED, 0, 0, 0);
+ deadbeef->sendmessage (M_CONFIG_CHANGED, 0, 0, 0);
}
void
@@ -797,21 +764,45 @@ on_pref_pluginlist_cursor_changed (GtkTreeView *treeview,
DB_plugin_t *p = plugins[*indices];
g_free (indices);
assert (p);
- GtkWidget *w = prefwin;//GTK_WIDGET (gtk_widget_get_parent_window (GTK_WIDGET (treeview)));
+ GtkWidget *w = prefwin;
assert (w);
- GtkEntry *e = GTK_ENTRY (lookup_widget (w, "pref_plugin_descr"));
- gtk_entry_set_text (e, p->descr ? p->descr : "");
- e = GTK_ENTRY (lookup_widget (w, "pref_plugin_author"));
- gtk_entry_set_text (e, p->author ? p->author : "");
- e = GTK_ENTRY (lookup_widget (w, "pref_plugin_email"));
- gtk_entry_set_text (e, p->email ? p->email : "");
- e = GTK_ENTRY (lookup_widget (w, "pref_plugin_website"));
- gtk_entry_set_text (e, p->website ? p->website : "");
+ if (p->descr) {
+ GtkTextView *tv = GTK_TEXT_VIEW (lookup_widget (w, "plug_description"));
+
+ GtkTextBuffer *buffer = gtk_text_buffer_new (NULL);
+
+ gtk_text_buffer_set_text (buffer, p->descr, strlen(p->descr));
+ gtk_text_view_set_buffer (GTK_TEXT_VIEW (tv), buffer);
+ g_object_unref (buffer);
+ }
+
+ GtkWidget *link = lookup_widget (w, "weblink");
+ if (p->website) {
+ gtk_link_button_set_uri (GTK_LINK_BUTTON(link), p->website);
+ gtk_widget_set_sensitive (link, TRUE);
+ }
+ else {
+ gtk_link_button_set_uri (GTK_LINK_BUTTON(link), "");
+ gtk_widget_set_sensitive (link, FALSE);
+ }
+
+ GtkWidget *cpr = lookup_widget (w, "plug_copyright");
+ if (p->copyright) {
+ gtk_widget_set_sensitive (cpr, TRUE);
+ }
+ else {
+ gtk_widget_set_sensitive (cpr, FALSE);
+ }
gtk_widget_set_sensitive (lookup_widget (prefwin, "configure_plugin"), p->configdialog ? TRUE : FALSE);
}
void
+gtkui_conf_get_str (const char *key, char *value, int len, const char *def) {
+ deadbeef->conf_get_str (key, def, value, len);
+}
+
+void
on_configure_plugin_clicked (GtkButton *button,
gpointer user_data)
{
@@ -828,7 +819,13 @@ on_configure_plugin_clicked (GtkButton *button,
DB_plugin_t **plugins = deadbeef->plug_get_list ();
DB_plugin_t *p = plugins[*indices];
if (p->configdialog) {
- plugin_configure (prefwin, p);
+ ddb_dialog_t conf = {
+ .title = p->name,
+ .layout = p->configdialog,
+ .set_param = deadbeef->conf_set_str,
+ .get_param = gtkui_conf_get_str,
+ };
+ gtkui_run_dialog (prefwin, &conf, 0, NULL, NULL);
}
}
@@ -837,10 +834,10 @@ redraw_headers (void) {
DdbListview *playlist = DDB_LISTVIEW (lookup_widget (mainwin, "playlist"));
DdbListview *search = DDB_LISTVIEW (lookup_widget (searchwin, "searchlist"));
if (playlist) {
- ddb_listview_refresh (playlist, DDB_REFRESH_COLUMNS | DDB_EXPOSE_COLUMNS);
+ ddb_listview_refresh (playlist, DDB_REFRESH_COLUMNS);
}
if (search) {
- ddb_listview_refresh (search, DDB_REFRESH_COLUMNS | DDB_EXPOSE_COLUMNS);
+ ddb_listview_refresh (search, DDB_REFRESH_COLUMNS);
}
}
@@ -853,7 +850,7 @@ on_tabstrip_light_color_set (GtkColorButton *colorbutton,
char str[100];
snprintf (str, sizeof (str), "%d %d %d", clr.red, clr.green, clr.blue);
deadbeef->conf_set_str ("gtkui.color.tabstrip_light", str);
- deadbeef->sendmessage (M_CONFIGCHANGED, 0, 0, 0);
+ deadbeef->sendmessage (M_CONFIG_CHANGED, 0, 0, 0);
gtkui_init_theme_colors ();
redraw_headers ();
tabstrip_redraw ();
@@ -869,7 +866,7 @@ on_tabstrip_mid_color_set (GtkColorButton *colorbutton,
char str[100];
snprintf (str, sizeof (str), "%d %d %d", clr.red, clr.green, clr.blue);
deadbeef->conf_set_str ("gtkui.color.tabstrip_mid", str);
- deadbeef->sendmessage (M_CONFIGCHANGED, 0, 0, 0);
+ deadbeef->sendmessage (M_CONFIG_CHANGED, 0, 0, 0);
gtkui_init_theme_colors ();
redraw_headers ();
tabstrip_redraw ();
@@ -885,7 +882,7 @@ on_tabstrip_dark_color_set (GtkColorButton *colorbutton,
char str[100];
snprintf (str, sizeof (str), "%d %d %d", clr.red, clr.green, clr.blue);
deadbeef->conf_set_str ("gtkui.color.tabstrip_dark", str);
- deadbeef->sendmessage (M_CONFIGCHANGED, 0, 0, 0);
+ deadbeef->sendmessage (M_CONFIG_CHANGED, 0, 0, 0);
gtkui_init_theme_colors ();
redraw_headers ();
tabstrip_redraw ();
@@ -900,12 +897,26 @@ on_tabstrip_base_color_set (GtkColorButton *colorbutton,
char str[100];
snprintf (str, sizeof (str), "%d %d %d", clr.red, clr.green, clr.blue);
deadbeef->conf_set_str ("gtkui.color.tabstrip_base", str);
- deadbeef->sendmessage (M_CONFIGCHANGED, 0, 0, 0);
+ deadbeef->sendmessage (M_CONFIG_CHANGED, 0, 0, 0);
gtkui_init_theme_colors ();
redraw_headers ();
tabstrip_redraw ();
}
+void
+on_tabstrip_text_color_set (GtkColorButton *colorbutton,
+ gpointer user_data)
+{
+ GdkColor clr;
+ gtk_color_button_get_color (colorbutton, &clr);
+ char str[100];
+ snprintf (str, sizeof (str), "%d %d %d", clr.red, clr.green, clr.blue);
+ deadbeef->conf_set_str ("gtkui.color.tabstrip_text", str);
+ deadbeef->sendmessage (M_CONFIG_CHANGED, 0, 0, 0);
+ gtkui_init_theme_colors ();
+ redraw_headers ();
+ tabstrip_redraw ();
+}
void
on_bar_foreground_color_set (GtkColorButton *colorbutton,
@@ -916,7 +927,7 @@ on_bar_foreground_color_set (GtkColorButton *colorbutton,
char str[100];
snprintf (str, sizeof (str), "%d %d %d", clr.red, clr.green, clr.blue);
deadbeef->conf_set_str ("gtkui.color.bar_foreground", str);
- deadbeef->sendmessage (M_CONFIGCHANGED, 0, 0, 0);
+ deadbeef->sendmessage (M_CONFIG_CHANGED, 0, 0, 0);
gtkui_init_theme_colors ();
seekbar_redraw ();
volumebar_redraw ();
@@ -933,7 +944,7 @@ on_bar_background_color_set (GtkColorButton *colorbutton,
char str[100];
snprintf (str, sizeof (str), "%d %d %d", clr.red, clr.green, clr.blue);
deadbeef->conf_set_str ("gtkui.color.bar_background", str);
- deadbeef->sendmessage (M_CONFIGCHANGED, 0, 0, 0);
+ deadbeef->sendmessage (M_CONFIG_CHANGED, 0, 0, 0);
gtkui_init_theme_colors ();
seekbar_redraw ();
volumebar_redraw ();
@@ -947,7 +958,7 @@ on_override_listview_colors_toggled (GtkToggleButton *togglebutton,
int active = gtk_toggle_button_get_active (togglebutton);
deadbeef->conf_set_int ("gtkui.override_listview_colors", active);
gtk_widget_set_sensitive (lookup_widget (prefwin, "listview_colors_group"), active);
- deadbeef->sendmessage (M_CONFIGCHANGED, 0, 0, 0);
+ deadbeef->sendmessage (M_CONFIG_CHANGED, 0, 0, 0);
gtkui_init_theme_colors ();
prefwin_init_theme_colors ();
playlist_refresh ();
@@ -963,7 +974,7 @@ on_listview_even_row_color_set (GtkColorButton *colorbutton,
char str[100];
snprintf (str, sizeof (str), "%d %d %d", clr.red, clr.green, clr.blue);
deadbeef->conf_set_str ("gtkui.color.listview_even_row", str);
- deadbeef->sendmessage (M_CONFIGCHANGED, 0, 0, 0);
+ deadbeef->sendmessage (M_CONFIG_CHANGED, 0, 0, 0);
gtkui_init_theme_colors ();
playlist_refresh ();
}
@@ -977,7 +988,7 @@ on_listview_odd_row_color_set (GtkColorButton *colorbutton,
char str[100];
snprintf (str, sizeof (str), "%d %d %d", clr.red, clr.green, clr.blue);
deadbeef->conf_set_str ("gtkui.color.listview_odd_row", str);
- deadbeef->sendmessage (M_CONFIGCHANGED, 0, 0, 0);
+ deadbeef->sendmessage (M_CONFIG_CHANGED, 0, 0, 0);
gtkui_init_theme_colors ();
playlist_refresh ();
}
@@ -991,7 +1002,7 @@ on_listview_selected_row_color_set (GtkColorButton *colorbutton,
char str[100];
snprintf (str, sizeof (str), "%d %d %d", clr.red, clr.green, clr.blue);
deadbeef->conf_set_str ("gtkui.color.listview_selection", str);
- deadbeef->sendmessage (M_CONFIGCHANGED, 0, 0, 0);
+ deadbeef->sendmessage (M_CONFIG_CHANGED, 0, 0, 0);
gtkui_init_theme_colors ();
playlist_refresh ();
}
@@ -1005,7 +1016,7 @@ on_listview_text_color_set (GtkColorButton *colorbutton,
char str[100];
snprintf (str, sizeof (str), "%d %d %d", clr.red, clr.green, clr.blue);
deadbeef->conf_set_str ("gtkui.color.listview_text", str);
- deadbeef->sendmessage (M_CONFIGCHANGED, 0, 0, 0);
+ deadbeef->sendmessage (M_CONFIG_CHANGED, 0, 0, 0);
gtkui_init_theme_colors ();
playlist_refresh ();
}
@@ -1020,7 +1031,7 @@ on_listview_selected_text_color_set (GtkColorButton *colorbutton,
char str[100];
snprintf (str, sizeof (str), "%d %d %d", clr.red, clr.green, clr.blue);
deadbeef->conf_set_str ("gtkui.color.listview_selected_text", str);
- deadbeef->sendmessage (M_CONFIGCHANGED, 0, 0, 0);
+ deadbeef->sendmessage (M_CONFIG_CHANGED, 0, 0, 0);
gtkui_init_theme_colors ();
playlist_refresh ();
}
@@ -1034,7 +1045,7 @@ on_listview_cursor_color_set (GtkColorButton *colorbutton,
char str[100];
snprintf (str, sizeof (str), "%d %d %d", clr.red, clr.green, clr.blue);
deadbeef->conf_set_str ("gtkui.color.listview_cursor", str);
- deadbeef->sendmessage (M_CONFIGCHANGED, 0, 0, 0);
+ deadbeef->sendmessage (M_CONFIG_CHANGED, 0, 0, 0);
gtkui_init_theme_colors ();
playlist_refresh ();
}
@@ -1047,7 +1058,7 @@ on_override_bar_colors_toggled (GtkToggleButton *togglebutton,
int active = gtk_toggle_button_get_active (togglebutton);
deadbeef->conf_set_int ("gtkui.override_bar_colors", active);
gtk_widget_set_sensitive (lookup_widget (prefwin, "bar_colors_group"), active);
- deadbeef->sendmessage (M_CONFIGCHANGED, 0, 0, 0);
+ deadbeef->sendmessage (M_CONFIG_CHANGED, 0, 0, 0);
gtkui_init_theme_colors ();
prefwin_init_theme_colors ();
seekbar_redraw ();
@@ -1062,7 +1073,7 @@ on_override_tabstrip_colors_toggled (GtkToggleButton *togglebutton,
int active = gtk_toggle_button_get_active (togglebutton);
deadbeef->conf_set_int ("gtkui.override_tabstrip_colors", active);
gtk_widget_set_sensitive (lookup_widget (prefwin, "tabstrip_colors_group"), active);
- deadbeef->sendmessage (M_CONFIGCHANGED, 0, 0, 0);
+ deadbeef->sendmessage (M_CONFIG_CHANGED, 0, 0, 0);
gtkui_init_theme_colors ();
prefwin_init_theme_colors ();
redraw_headers ();
@@ -1070,137 +1081,6 @@ on_override_tabstrip_colors_toggled (GtkToggleButton *togglebutton,
}
void
-on_write_id3v2_toggled (GtkToggleButton *togglebutton,
- gpointer user_data)
-{
- deadbeef->conf_set_int ("mp3.write_id3v2", gtk_toggle_button_get_active (togglebutton));
-}
-
-
-void
-on_write_id3v1_toggled (GtkToggleButton *togglebutton,
- gpointer user_data)
-{
- deadbeef->conf_set_int ("mp3.write_id3v1", gtk_toggle_button_get_active (togglebutton));
-}
-
-
-void
-on_write_apev2_toggled (GtkToggleButton *togglebutton,
- gpointer user_data)
-{
- deadbeef->conf_set_int ("mp3.write_apev2", gtk_toggle_button_get_active (togglebutton));
-}
-
-
-void
-on_strip_id3v2_toggled (GtkToggleButton *togglebutton,
- gpointer user_data)
-{
- deadbeef->conf_set_int ("mp3.strip_id3v2", gtk_toggle_button_get_active (togglebutton));
-}
-
-
-void
-on_strip_id3v1_toggled (GtkToggleButton *togglebutton,
- gpointer user_data)
-{
- deadbeef->conf_set_int ("mp3.strip_id3v1", gtk_toggle_button_get_active (togglebutton));
-}
-
-
-void
-on_strip_apev2_toggled (GtkToggleButton *togglebutton,
- gpointer user_data)
-{
- deadbeef->conf_set_int ("mp3.strip_apev2", gtk_toggle_button_get_active (togglebutton));
-}
-
-
-void
-on_id3v2_version_changed (GtkComboBox *combobox,
- gpointer user_data)
-{
- int version = 3;
- int active = gtk_combo_box_get_active (combobox);
- if (active == 1) {
- version = 4;
- }
- deadbeef->conf_set_int ("mp3.id3v2_version", version);
-}
-
-
-void
-on_id3v1_encoding_changed (GtkEditable *editable,
- gpointer user_data)
-{
- deadbeef->conf_set_str ("mp3.id3v1_encoding", gtk_entry_get_text (GTK_ENTRY (editable)));
-}
-
-
-void
-on_ape_write_id3v2_toggled (GtkToggleButton *togglebutton,
- gpointer user_data)
-{
- deadbeef->conf_set_int ("ape.write_id3v2", gtk_toggle_button_get_active (togglebutton));
-}
-
-
-void
-on_ape_write_apev2_toggled (GtkToggleButton *togglebutton,
- gpointer user_data)
-{
- deadbeef->conf_set_int ("ape.write_apev2", gtk_toggle_button_get_active (togglebutton));
-}
-
-
-void
-on_ape_strip_id3v2_toggled (GtkToggleButton *togglebutton,
- gpointer user_data)
-{
- deadbeef->conf_set_int ("ape.strip_id3v2", gtk_toggle_button_get_active (togglebutton));
-}
-
-
-void
-on_ape_strip_apev2_toggled (GtkToggleButton *togglebutton,
- gpointer user_data)
-{
- deadbeef->conf_set_int ("ape.strip_apev2", gtk_toggle_button_get_active (togglebutton));
-}
-
-
-void
-on_wv_write_apev2_toggled (GtkToggleButton *togglebutton,
- gpointer user_data)
-{
- deadbeef->conf_set_int ("wv.write_apev2", gtk_toggle_button_get_active (togglebutton));
-}
-
-
-void
-on_wv_write_id3v1_toggled (GtkToggleButton *togglebutton,
- gpointer user_data)
-{
- deadbeef->conf_set_int ("wv.write_id3v1", gtk_toggle_button_get_active (togglebutton));
-}
-
-void
-on_wv_strip_apev2_toggled (GtkToggleButton *togglebutton,
- gpointer user_data)
-{
- deadbeef->conf_set_int ("wv.strip_apev2", gtk_toggle_button_get_active (togglebutton));
-}
-
-
-void
-on_wv_strip_id3v1_toggled (GtkToggleButton *togglebutton,
- gpointer user_data)
-{
- deadbeef->conf_set_int ("wv.strip_id3v1", gtk_toggle_button_get_active (togglebutton));
-}
-
-void
on_pref_network_proxyaddress_changed (GtkEditable *editable,
gpointer user_data)
{
@@ -1344,3 +1224,115 @@ on_resume_last_session_toggled (GtkToggleButton *togglebutton,
deadbeef->conf_set_int ("resume_last_session", active);
}
+
+void
+on_auto_name_playlist_from_folder_toggled
+ (GtkToggleButton *togglebutton,
+ gpointer user_data)
+{
+ int active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (togglebutton));
+ deadbeef->conf_set_int ("gtkui.name_playlist_from_folder", active);
+}
+
+void
+on_info_window_delete (GtkWidget *widget, GtkTextDirection previous_direction, GtkWidget **pwindow);
+
+static void
+show_copyright_window (const char *text, const char *title, GtkWidget **pwindow) {
+ if (*pwindow) {
+ return;
+ }
+ GtkWidget *widget = *pwindow = create_helpwindow ();
+ g_object_set_data (G_OBJECT (widget), "pointer", pwindow);
+ g_signal_connect (widget, "delete_event", G_CALLBACK (on_info_window_delete), pwindow);
+ gtk_window_set_title (GTK_WINDOW (widget), title);
+ gtk_window_set_transient_for (GTK_WINDOW (widget), GTK_WINDOW (prefwin));
+ GtkWidget *txt = lookup_widget (widget, "helptext");
+ GtkTextBuffer *buffer = gtk_text_buffer_new (NULL);
+
+ gtk_text_buffer_set_text (buffer, text, strlen(text));
+ gtk_text_view_set_buffer (GTK_TEXT_VIEW (txt), buffer);
+ g_object_unref (buffer);
+ gtk_widget_show (widget);
+}
+
+static GtkWidget *copyright_window;
+
+void
+on_plug_copyright_clicked (GtkButton *button,
+ gpointer user_data)
+{
+ GtkTreeView *treeview = GTK_TREE_VIEW(lookup_widget (prefwin, "pref_pluginlist"));
+ GtkTreePath *path;
+ GtkTreeViewColumn *col;
+ gtk_tree_view_get_cursor (treeview, &path, &col);
+ if (!path || !col) {
+ // reset
+ return;
+ }
+ int *indices = gtk_tree_path_get_indices (path);
+ DB_plugin_t **plugins = deadbeef->plug_get_list ();
+ DB_plugin_t *p = plugins[*indices];
+ g_free (indices);
+ assert (p);
+
+ if (p->copyright) {
+ show_copyright_window (p->copyright, "Copyright", &copyright_window);
+ }
+}
+
+gboolean
+on_prefwin_configure_event (GtkWidget *widget,
+ GdkEventConfigure *event,
+ gpointer user_data)
+{
+ wingeom_save (widget, "prefwin");
+ return FALSE;
+}
+
+
+gboolean
+on_prefwin_window_state_event (GtkWidget *widget,
+ GdkEventWindowState *event,
+ gpointer user_data)
+{
+ wingeom_save_max (event, widget, "prefwin");
+ return FALSE;
+}
+
+
+void
+on_prefwin_realize (GtkWidget *widget,
+ gpointer user_data)
+{
+ wingeom_restore (widget, "prefwin", -1, -1, -1, -1, 0);
+}
+
+void
+on_gui_plugin_changed (GtkComboBox *combobox,
+ gpointer user_data)
+{
+ gchar *txt = gtk_combo_box_get_active_text (combobox);
+ if (txt) {
+ deadbeef->conf_set_str ("gui_plugin", txt);
+ g_free (txt);
+ }
+}
+
+void
+on_gui_fps_value_changed (GtkRange *range,
+ gpointer user_data)
+{
+ int val = gtk_range_get_value (range);
+ deadbeef->conf_set_int ("gtkui.refresh_rate", val);
+ gtkui_setup_gui_refresh ();
+}
+
+void
+on_ignore_archives_toggled (GtkToggleButton *togglebutton,
+ gpointer user_data)
+{
+
+ deadbeef->conf_set_int ("ignore_archives", gtk_toggle_button_get_active (togglebutton));
+}
+
diff --git a/plugins/gtkui/progress.c b/plugins/gtkui/progress.c
index d986a162..1941c40e 100644
--- a/plugins/gtkui/progress.c
+++ b/plugins/gtkui/progress.c
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -34,9 +34,36 @@ static GtkWidget *progressdlg;
static GtkWidget *progressitem;
static int progress_aborted;
+static void
+on_progress_abort (GtkButton *button,
+ gpointer user_data)
+{
+ progress_aborted = 1;
+}
+
+static gboolean
+on_addprogress_delete_event (GtkWidget *widget,
+ GdkEvent *event,
+ gpointer user_data)
+{
+ progress_aborted = 1;
+ return gtk_widget_hide_on_delete (widget);
+}
void
progress_init (void) {
- progressdlg = create_addprogress ();
+ progressdlg = create_progressdlg ();
+
+ gtk_window_set_title (GTK_WINDOW (progressdlg), _("Adding files..."));
+
+ g_signal_connect ((gpointer) progressdlg, "delete_event",
+ G_CALLBACK (on_addprogress_delete_event),
+ NULL);
+
+ GtkWidget *cancelbtn = lookup_widget (progressdlg, "cancelbtn");
+ g_signal_connect ((gpointer) cancelbtn, "clicked",
+ G_CALLBACK (on_progress_abort),
+ NULL);
+
gtk_window_set_transient_for (GTK_WINDOW (progressdlg), GTK_WINDOW (mainwin));
progressitem = lookup_widget (progressdlg, "progresstitle");
}
@@ -81,24 +108,9 @@ progress_abort (void) {
progress_aborted = 1;
}
-void
-on_progress_abort (GtkButton *button,
- gpointer user_data)
-{
- progress_aborted = 1;
-}
-
int
progress_is_aborted (void) {
return progress_aborted;
}
-gboolean
-on_addprogress_delete_event (GtkWidget *widget,
- GdkEvent *event,
- gpointer user_data)
-{
- progress_aborted = 1;
- return gtk_widget_hide_on_delete (widget);
-}
diff --git a/plugins/gtkui/progress.h b/plugins/gtkui/progress.h
index 49b20248..86558106 100644
--- a/plugins/gtkui/progress.h
+++ b/plugins/gtkui/progress.h
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/plugins/gtkui/search.c b/plugins/gtkui/search.c
index ee096930..4509d3d5 100644
--- a/plugins/gtkui/search.c
+++ b/plugins/gtkui/search.c
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -38,6 +38,8 @@
#include "gtkui.h"
+#include "wingeom.h"
+
#define min(x,y) ((x)<(y)?(x):(y))
#define max(x,y) ((x)>(y)?(x):(y))
@@ -49,27 +51,8 @@ extern GtkWidget *searchwin;
extern GtkWidget *mainwin;
void
-search_restore_attrs (void) {
- int x = deadbeef->conf_get_int ("searchwin.geometry.x", -1);
- int y = deadbeef->conf_get_int ("searchwin.geometry.y", -1);
- int w = deadbeef->conf_get_int ("searchwin.geometry.w", 450);
- int h = deadbeef->conf_get_int ("searchwin.geometry.h", 150);
- gtk_widget_show (searchwin);
- if (x != -1 && y != -1) {
- gtk_window_move (GTK_WINDOW (searchwin), x, y);
- gtk_window_resize (GTK_WINDOW (searchwin), w, h);
- if (deadbeef->conf_get_int ("searchwin.geometry.maximized", 0)) {
- gtk_window_maximize (GTK_WINDOW (searchwin));
- }
- gtk_window_present (GTK_WINDOW (searchwin));
- }
- else {
- gtk_window_resize (GTK_WINDOW (searchwin), w, h);
- }
-}
-
-void
search_start (void) {
+ wingeom_restore (searchwin, "searchwin", -1, -1, 450, 150, 0);
gtk_entry_set_text (GTK_ENTRY (lookup_widget (searchwin, "searchentry")), "");
gtk_widget_show (searchwin);
gtk_window_present (GTK_WINDOW (searchwin));
@@ -98,14 +81,14 @@ on_searchentry_changed (GtkEditable *editable,
search_refresh ();
// redraw main playlist to be in sync selection-wise
- ddb_listview_refresh (DDB_LISTVIEW (lookup_widget (mainwin, "playlist")), DDB_REFRESH_LIST | DDB_EXPOSE_LIST);
+ ddb_listview_refresh (DDB_LISTVIEW (lookup_widget (mainwin, "playlist")), DDB_REFRESH_LIST);
}
void
search_refresh (void) {
if (searchwin && gtk_widget_get_visible (searchwin)) {
GtkWidget *pl = lookup_widget (searchwin, "searchlist");
- ddb_listview_refresh (DDB_LISTVIEW (pl), DDB_REFRESH_VSCROLL | DDB_REFRESH_LIST | DDB_EXPOSE_LIST);
+ ddb_listview_refresh (DDB_LISTVIEW (pl), DDB_REFRESH_VSCROLL | DDB_REFRESH_LIST);
}
}
@@ -176,7 +159,7 @@ on_searchwin_key_press_event (GtkWidget *widget,
int row = deadbeef->pl_get_cursor (PL_SEARCH);
DB_playItem_t *it = deadbeef->pl_get_for_idx_and_iter (max (row, 0), PL_SEARCH);
if (it) {
- deadbeef->sendmessage (M_PLAYSONGNUM, 0, deadbeef->pl_get_idx_of (it), 0);
+ deadbeef->sendmessage (M_PLAY_NUM, 0, deadbeef->pl_get_idx_of (it), 0);
deadbeef->pl_item_unref (it);
}
}
@@ -198,21 +181,7 @@ on_searchwin_configure_event (GtkWidget *widget,
GdkEventConfigure *event,
gpointer user_data)
{
-#if GTK_CHECK_VERSION(2,2,0)
- GdkWindowState window_state = gdk_window_get_state (GDK_WINDOW (widget->window));
-#else
- GdkWindowState window_state = gdk_window_get_state (G_OBJECT (widget));
-#endif
- if (!(window_state & GDK_WINDOW_STATE_MAXIMIZED) && gtk_widget_get_visible (widget)) {
- int x, y;
- int w, h;
- gtk_window_get_position (GTK_WINDOW (widget), &x, &y);
- gtk_window_get_size (GTK_WINDOW (widget), &w, &h);
- deadbeef->conf_set_int ("searchwin.geometry.x", x);
- deadbeef->conf_set_int ("searchwin.geometry.y", y);
- deadbeef->conf_set_int ("searchwin.geometry.w", w);
- deadbeef->conf_set_int ("searchwin.geometry.h", h);
- }
+ wingeom_save (widget, "searchwin");
return FALSE;
}
@@ -221,30 +190,7 @@ on_searchwin_window_state_event (GtkWidget *widget,
GdkEventWindowState *event,
gpointer user_data)
{
- if (!gtk_widget_get_visible (widget)) {
- return FALSE;
- }
- // based on pidgin maximization handler
-#if GTK_CHECK_VERSION(2,2,0)
- if (event->changed_mask & GDK_WINDOW_STATE_MAXIMIZED) {
- if (event->new_window_state & GDK_WINDOW_STATE_MAXIMIZED) {
- deadbeef->conf_set_int ("searchwin.geometry.maximized", 1);
- }
- else {
- deadbeef->conf_set_int ("searchwin.geometry.maximized", 0);
- }
- }
-#else
- GdkWindowState new_window_state = gdk_window_get_state(G_OBJECT(widget));
-
- if ()
- if (new_window_state & GDK_WINDOW_STATE_MAXIMIZED) {
- deadbeef->conf_set_int ("searchwin.geometry.maximized", 1);
- }
- else {
- deadbeef->conf_set_int ("searchwin.geometry.maximized", 0);
- }
-#endif
+ wingeom_save_max (event, widget, "searchwin");
return FALSE;
}
@@ -364,13 +310,13 @@ void search_col_free_user_data (void *data) {
}
void search_handle_doubleclick (DdbListview *listview, DdbListviewIter iter, int idx) {
- deadbeef->sendmessage (M_PLAYSONGNUM, 0, deadbeef->pl_get_idx_of ((DB_playItem_t *)iter), 0);
+ deadbeef->sendmessage (M_PLAY_NUM, 0, deadbeef->pl_get_idx_of ((DB_playItem_t *)iter), 0);
}
void search_selection_changed (DdbListviewIter it, int idx) {
DdbListview *main = DDB_LISTVIEW (lookup_widget (mainwin, "playlist"));
if (idx == -1) {
- ddb_listview_refresh (main, DDB_REFRESH_LIST | DDB_EXPOSE_LIST);
+ ddb_listview_refresh (main, DDB_REFRESH_LIST);
}
else {
ddb_listview_draw_row (main, main_get_idx ((DB_playItem_t *)it), it);
@@ -438,7 +384,7 @@ search_playlist_init (GtkWidget *widget) {
if (!col) {
add_column_helper (listview, _("Artist / Album"), 150, -1, "%a - %b", 0);
add_column_helper (listview, _("Track No"), 50, -1, "%n", 1);
- add_column_helper (listview, _("Title / Track Artist"), 150, -1, "%t", 0);
+ add_column_helper (listview, _("Title"), 150, -1, "%t", 0);
add_column_helper (listview, _("Duration"), 50, -1, "%l", 0);
}
else {
diff --git a/plugins/gtkui/search.h b/plugins/gtkui/search.h
index 7e34d4db..98216d5c 100644
--- a/plugins/gtkui/search.h
+++ b/plugins/gtkui/search.h
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -30,9 +30,6 @@ search_start (void);
void
search_refresh (void);
-void
-search_restore_attrs (void);
-
int
search_get_idx (DdbListviewIter it);
diff --git a/plugins/gtkui/support.h b/plugins/gtkui/support.h
index a32649e5..b4b0ace3 100644
--- a/plugins/gtkui/support.h
+++ b/plugins/gtkui/support.h
@@ -27,7 +27,9 @@
# define dgettext(Domain,Message) (Message)
# define dcgettext(Domain,Message,Type) (Message)
# define bindtextdomain(Domain,Directory) (Domain)
+#ifndef _
# define _(String) (String)
+#endif
# define Q_(String) g_strip_context ((String), (String))
# define N_(String) (String)
#endif
diff --git a/plugins/gtkui/tagwritersettings.c b/plugins/gtkui/tagwritersettings.c
new file mode 100644
index 00000000..ede3d447
--- /dev/null
+++ b/plugins/gtkui/tagwritersettings.c
@@ -0,0 +1,204 @@
+/*
+ DeaDBeeF - ultimate music player for GNU/Linux systems with X11
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include <gtk/gtk.h>
+#include "../../gettext.h"
+#include "interface.h"
+#include "support.h"
+#include "../../deadbeef.h"
+#include "gtkui.h"
+
+void
+run_tagwriter_settings (GtkWidget *parentwindow) {
+ GtkWidget *dlg = create_tagwritersettings ();
+ gtk_window_set_transient_for (GTK_WINDOW (dlg), GTK_WINDOW (parentwindow));
+
+ // tag writer
+ int strip_id3v2 = deadbeef->conf_get_int ("mp3.strip_id3v2", 0);
+ int strip_id3v1 = deadbeef->conf_get_int ("mp3.strip_id3v1", 0);
+ int strip_apev2 = deadbeef->conf_get_int ("mp3.strip_apev2", 0);
+ int write_id3v2 = deadbeef->conf_get_int ("mp3.write_id3v2", 1);
+ int write_id3v1 = deadbeef->conf_get_int ("mp3.write_id3v1", 1);
+ int write_apev2 = deadbeef->conf_get_int ("mp3.write_apev2", 0);
+ int id3v2_version = deadbeef->conf_get_int ("mp3.id3v2_version", 3);
+ char id3v1_encoding[50];
+ deadbeef->conf_get_str ("mp3.id3v1_encoding", "iso8859-1", id3v1_encoding, sizeof (id3v1_encoding));
+ int ape_strip_id3v2 = deadbeef->conf_get_int ("ape.strip_id3v2", 0);
+ int ape_strip_apev2 = deadbeef->conf_get_int ("ape.strip_apev2", 0);
+ int ape_write_id3v2 = deadbeef->conf_get_int ("ape.write_id3v2", 0);
+ int ape_write_apev2 = deadbeef->conf_get_int ("ape.write_apev2", 1);
+ int wv_strip_apev2 = deadbeef->conf_get_int ("wv.strip_apev2", 0);
+ int wv_strip_id3v1 = deadbeef->conf_get_int ("wv.strip_id3v1", 0);
+ int wv_write_apev2 = deadbeef->conf_get_int ("wv.write_apev2", 1);
+ int wv_write_id3v1 = deadbeef->conf_get_int ("wv.write_id3v1", 0);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (lookup_widget (dlg, "strip_id3v2")), strip_id3v2);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (lookup_widget (dlg, "strip_id3v1")), strip_id3v1);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (lookup_widget (dlg, "strip_apev2")), strip_apev2);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (lookup_widget (dlg, "write_id3v2")), write_id3v2);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (lookup_widget (dlg, "write_id3v1")), write_id3v1);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (lookup_widget (dlg, "write_apev2")), write_apev2);
+ gtk_combo_box_set_active (GTK_COMBO_BOX (lookup_widget (dlg, "id3v2_version")), id3v2_version != 4 ? 0 : 1);
+ gtk_entry_set_text (GTK_ENTRY (lookup_widget (dlg, "id3v1_encoding")), id3v1_encoding);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (lookup_widget (dlg, "ape_strip_id3v2")), ape_strip_id3v2);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (lookup_widget (dlg, "ape_strip_apev2")), ape_strip_apev2);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (lookup_widget (dlg, "ape_write_apev2")), ape_write_apev2);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (lookup_widget (dlg, "ape_write_id3v2")), ape_write_id3v2);
+
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (lookup_widget (dlg, "wv_strip_id3v1")), wv_strip_id3v1);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (lookup_widget (dlg, "wv_strip_apev2")), wv_strip_apev2);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (lookup_widget (dlg, "wv_write_apev2")), wv_write_apev2);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (lookup_widget (dlg, "wv_write_id3v1")), wv_write_id3v1);
+
+
+ int response = gtk_dialog_run (GTK_DIALOG (dlg));
+ gtk_widget_destroy (dlg);
+}
+
+void
+on_write_id3v2_toggled (GtkToggleButton *togglebutton,
+ gpointer user_data)
+{
+ deadbeef->conf_set_int ("mp3.write_id3v2", gtk_toggle_button_get_active (togglebutton));
+}
+
+
+void
+on_write_id3v1_toggled (GtkToggleButton *togglebutton,
+ gpointer user_data)
+{
+ deadbeef->conf_set_int ("mp3.write_id3v1", gtk_toggle_button_get_active (togglebutton));
+}
+
+
+void
+on_write_apev2_toggled (GtkToggleButton *togglebutton,
+ gpointer user_data)
+{
+ deadbeef->conf_set_int ("mp3.write_apev2", gtk_toggle_button_get_active (togglebutton));
+}
+
+
+void
+on_strip_id3v2_toggled (GtkToggleButton *togglebutton,
+ gpointer user_data)
+{
+ deadbeef->conf_set_int ("mp3.strip_id3v2", gtk_toggle_button_get_active (togglebutton));
+}
+
+
+void
+on_strip_id3v1_toggled (GtkToggleButton *togglebutton,
+ gpointer user_data)
+{
+ deadbeef->conf_set_int ("mp3.strip_id3v1", gtk_toggle_button_get_active (togglebutton));
+}
+
+
+void
+on_strip_apev2_toggled (GtkToggleButton *togglebutton,
+ gpointer user_data)
+{
+ deadbeef->conf_set_int ("mp3.strip_apev2", gtk_toggle_button_get_active (togglebutton));
+}
+
+
+void
+on_id3v2_version_changed (GtkComboBox *combobox,
+ gpointer user_data)
+{
+ int version = 3;
+ int active = gtk_combo_box_get_active (combobox);
+ if (active == 1) {
+ version = 4;
+ }
+ deadbeef->conf_set_int ("mp3.id3v2_version", version);
+}
+
+
+void
+on_id3v1_encoding_changed (GtkEditable *editable,
+ gpointer user_data)
+{
+ deadbeef->conf_set_str ("mp3.id3v1_encoding", gtk_entry_get_text (GTK_ENTRY (editable)));
+}
+
+
+void
+on_ape_write_id3v2_toggled (GtkToggleButton *togglebutton,
+ gpointer user_data)
+{
+ deadbeef->conf_set_int ("ape.write_id3v2", gtk_toggle_button_get_active (togglebutton));
+}
+
+
+void
+on_ape_write_apev2_toggled (GtkToggleButton *togglebutton,
+ gpointer user_data)
+{
+ deadbeef->conf_set_int ("ape.write_apev2", gtk_toggle_button_get_active (togglebutton));
+}
+
+
+void
+on_ape_strip_id3v2_toggled (GtkToggleButton *togglebutton,
+ gpointer user_data)
+{
+ deadbeef->conf_set_int ("ape.strip_id3v2", gtk_toggle_button_get_active (togglebutton));
+}
+
+
+void
+on_ape_strip_apev2_toggled (GtkToggleButton *togglebutton,
+ gpointer user_data)
+{
+ deadbeef->conf_set_int ("ape.strip_apev2", gtk_toggle_button_get_active (togglebutton));
+}
+
+
+void
+on_wv_write_apev2_toggled (GtkToggleButton *togglebutton,
+ gpointer user_data)
+{
+ deadbeef->conf_set_int ("wv.write_apev2", gtk_toggle_button_get_active (togglebutton));
+}
+
+
+void
+on_wv_write_id3v1_toggled (GtkToggleButton *togglebutton,
+ gpointer user_data)
+{
+ deadbeef->conf_set_int ("wv.write_id3v1", gtk_toggle_button_get_active (togglebutton));
+}
+
+void
+on_wv_strip_apev2_toggled (GtkToggleButton *togglebutton,
+ gpointer user_data)
+{
+ deadbeef->conf_set_int ("wv.strip_apev2", gtk_toggle_button_get_active (togglebutton));
+}
+
+
+void
+on_wv_strip_id3v1_toggled (GtkToggleButton *togglebutton,
+ gpointer user_data)
+{
+ deadbeef->conf_set_int ("wv.strip_id3v1", gtk_toggle_button_get_active (togglebutton));
+}
diff --git a/plugins/gtkui/tagwritersettings.h b/plugins/gtkui/tagwritersettings.h
new file mode 100644
index 00000000..a48aaacb
--- /dev/null
+++ b/plugins/gtkui/tagwritersettings.h
@@ -0,0 +1,25 @@
+/*
+ DeaDBeeF - ultimate music player for GNU/Linux systems with X11
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+#ifndef __TAGWRITERSETTINGS_H
+#define __TAGWRITERSETTINGS_H
+
+void
+run_tagwriter_settings (GtkWidget *parentwindow);
+
+#endif
diff --git a/plugins/gtkui/timeline.c b/plugins/gtkui/timeline.c
index 4543f6c6..83fc7f0f 100644
--- a/plugins/gtkui/timeline.c
+++ b/plugins/gtkui/timeline.c
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
diff --git a/plugins/gtkui/timeline.h b/plugins/gtkui/timeline.h
index 5325288e..4223a84b 100644
--- a/plugins/gtkui/timeline.h
+++ b/plugins/gtkui/timeline.h
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
diff --git a/plugins/gtkui/trkproperties.c b/plugins/gtkui/trkproperties.c
index f60a7b0b..cc419d59 100644
--- a/plugins/gtkui/trkproperties.c
+++ b/plugins/gtkui/trkproperties.c
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@@ -23,6 +23,7 @@
#include <gdk/gdkkeysyms.h>
#include <string.h>
#include <math.h>
+#include <assert.h>
#include "../../gettext.h"
#include "ddblistview.h"
#include "trkproperties.h"
@@ -33,16 +34,121 @@
#include "mainplaylist.h"
#include "search.h"
#include "ddbcellrenderertextmultiline.h"
+#include "tagwritersettings.h"
+#include "wingeom.h"
//#define trace(...) { fprintf(stderr, __VA_ARGS__); }
#define trace(fmt,...)
+#define min(x,y) ((x)<(y)?(x):(y))
+
static GtkWidget *trackproperties;
-static DB_playItem_t *track;
static GtkCellRenderer *rend_text2;
static GtkListStore *store;
static GtkListStore *propstore;
static int trkproperties_modified;
+static DB_playItem_t **tracks;
+static int numtracks;
+static GtkWidget *progressdlg;
+static int progress_aborted;
+
+static int
+build_key_list (const char ***pkeys, int props) {
+ int sz = 20;
+ const char **keys = malloc (sizeof (const char *) * sz);
+ if (!keys) {
+ fprintf (stderr, "fatal: out of memory allocating key list\n");
+ assert (0);
+ return 0;
+ }
+
+ int n = 0;
+
+ for (int i = 0; i < numtracks; i++) {
+ DB_metaInfo_t *meta = deadbeef->pl_get_metadata_head (tracks[i]);
+ while (meta) {
+ if ((props && meta->key[0] == ':') || (!props && meta->key[0] != ':')) {
+ int k = 0;
+ for (; k < n; k++) {
+ if (meta->key == keys[k]) {
+ break;
+ }
+ }
+ if (k == n) {
+ if (n >= sz) {
+ sz *= 2;
+ keys = realloc (keys, sizeof (const char *) * sz);
+ if (!keys) {
+ fprintf (stderr, "fatal: out of memory reallocating key list (%d keys)\n", sz);
+ assert (0);
+ }
+ }
+ keys[n++] = meta->key;
+ }
+ }
+ meta = meta->next;
+ }
+ }
+
+ *pkeys = keys;
+ return n;
+}
+
+static int
+equals_ptr (const char *a, const char *b) {
+ return a == b;
+}
+
+static int
+get_field_value (char *out, int size, const char *key, const char *(*getter)(DB_playItem_t *it, const char *key), int (*equals)(const char *a, const char *b)) {
+ int multiple = 0;
+ *out = 0;
+ if (numtracks == 0) {
+ return 0;
+ }
+ char *p = out;
+ const char **prev = malloc (sizeof (const char *) * numtracks);
+ memset (prev, 0, sizeof (const char *) * numtracks);
+ for (int i = 0; i < numtracks; i++) {
+ const char *val = getter (tracks[i], key);
+ if (val && val[0] == 0) {
+ val = NULL;
+ }
+ if (i > 0) {
+ int n = 0;
+ for (; n < i; n++) {
+ if (equals (prev[n], val)) {
+ break;
+ }
+ }
+ if (n == i) {
+ multiple = 1;
+ if (val) {
+ size_t l = snprintf (out, size, out == p ? "%s" : "; %s", val ? val : "");
+ l = min (l, size);
+ out += l;
+ size -= l;
+ }
+ }
+ }
+ else if (val) {
+ size_t l = snprintf (out, size, "%s", val ? val : "");
+ l = min (l, size);
+ out += l;
+ size -= l;
+ }
+ prev[i] = val;
+ if (size <= 1) {
+ break;
+ }
+ }
+ if (size <= 1) {
+ gchar *prev = g_utf8_prev_char (out-4);
+ strcpy (prev, "...");
+ }
+ free (prev);
+ return multiple;
+}
gboolean
on_trackproperties_delete_event (GtkWidget *widget,
@@ -50,7 +156,7 @@ on_trackproperties_delete_event (GtkWidget *widget,
gpointer user_data)
{
if (trkproperties_modified) {
- GtkWidget *dlg = gtk_message_dialog_new (GTK_WINDOW (mainwin), GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING, GTK_BUTTONS_YES_NO, _("You've modified data for this track."));
+ GtkWidget *dlg = gtk_message_dialog_new (GTK_WINDOW (trackproperties), GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING, GTK_BUTTONS_YES_NO, _("You've modified data for this track."));
gtk_window_set_transient_for (GTK_WINDOW (dlg), GTK_WINDOW (trackproperties));
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dlg), _("Really close the window?"));
gtk_window_set_title (GTK_WINDOW (dlg), _("Warning"));
@@ -64,9 +170,13 @@ on_trackproperties_delete_event (GtkWidget *widget,
gtk_widget_destroy (widget);
rend_text2 = NULL;
trackproperties = NULL;
- if (track) {
- deadbeef->pl_item_unref (track);
- track = NULL;
+ if (tracks) {
+ for (int i = 0; i < numtracks; i++) {
+ deadbeef->pl_item_unref (tracks[i]);
+ }
+ free (tracks);
+ tracks = NULL;
+ numtracks = 0;
}
return TRUE;
}
@@ -108,7 +218,7 @@ on_metadata_edited (GtkCellRendererText *renderer, gchar *path, gchar *new_text,
gtk_tree_model_get_value (GTK_TREE_MODEL (store), &iter, 1, &value);
const char *svalue = g_value_get_string (&value);
if (strcmp (svalue, new_text)) {
- gtk_list_store_set (store, &iter, 1, new_text, -1);
+ gtk_list_store_set (store, &iter, 1, new_text, 3, 0, -1);
trkproperties_modified = 1;
}
}
@@ -117,8 +227,6 @@ on_metadata_edited (GtkCellRendererText *renderer, gchar *path, gchar *new_text,
static const char *types[] = {
"artist", "Artist",
"title", "Track Title",
- "performer", "Performer",
- "band", "Band / Album Artist",
"album", "Album",
"year", "Date",
"track", "Track Number",
@@ -127,17 +235,36 @@ static const char *types[] = {
"composer", "Composer",
"disc", "Disc Number",
"comment", "Comment",
- "vendor", "Encoder / Vendor",
- "copyright", "Copyright",
- // nonstandard frames, let's hide them for now
-// "<performer>", "<PERFORMER>",
-// "<albumartist>", "<ALBUM ARTIST>",
NULL
};
-static inline float
-amp_to_db (float amp) {
- return 20*log10 (amp);
+static const char *hc_props[] = {
+ ":URI", "Location",
+ ":TRACKNUM", "Subtrack Index",
+ ":DURATION", "Duration",
+ ":TAGS", "Tag Type(s)",
+ ":HAS_EMBEDDED_CUESHEET", "Embedded Cuesheet",
+ ":DECODER", "Codec",
+ NULL
+};
+
+void
+add_field (GtkListStore *store, const char *key, const char *title, int is_prop) {
+ // get value to edit
+ const char *mult = is_prop ? "" : _("[Multiple values] ");
+ char val[1000];
+ size_t ml = strlen (mult);
+ memcpy (val, mult, ml+1);
+ int n = get_field_value (val + ml, sizeof (val) - ml, key, deadbeef->pl_find_meta, equals_ptr);
+
+ GtkTreeIter iter;
+ gtk_list_store_append (store, &iter);
+ if (!is_prop) {
+ gtk_list_store_set (store, &iter, 0, title, 1, n ? val : val + ml, 2, key, 3, n ? 1 : 0, -1);
+ }
+ else {
+ gtk_list_store_set (store, &iter, 0, title, 1, n ? val : val + ml, -1);
+ }
}
void
@@ -148,105 +275,126 @@ trkproperties_fill_metadata (void) {
trkproperties_modified = 0;
gtk_list_store_clear (store);
deadbeef->pl_lock ();
- int i = 0;
- while (types[i]) {
- GtkTreeIter iter;
- gtk_list_store_append (store, &iter);
- const char *value = deadbeef->pl_find_meta (track, types[i]);
- if (!value) {
- value = "";
+
+ const char **keys = NULL;
+ int nkeys = build_key_list (&keys, 0);
+
+ int k;
+
+ // add "standard" fields
+ for (int i = 0; types[i]; i += 2) {
+ add_field (store, types[i], _(types[i+1]), 0);
+ }
+
+ // add all other fields
+ for (int k = 0; k < nkeys; k++) {
+ int i;
+ for (i = 0; types[i]; i += 2) {
+ if (!strcasecmp (keys[k], types[i])) {
+ break;
+ }
}
- gtk_list_store_set (store, &iter, 0, _(types[i+1]), 1, value, 2, types[i], -1);
- i += 2;
+ if (types[i]) {
+ continue;
+ }
+
+ char title[1000];
+ if (!types[i]) {
+ snprintf (title, sizeof (title), "<%s>", keys[k]);
+ }
+ add_field (store, keys[k], title, 0);
+ }
+ if (keys) {
+ free (keys);
}
- deadbeef->pl_unlock ();
+ // hardcoded properties
+ for (int i = 0; hc_props[i]; i += 2) {
+ add_field (propstore, hc_props[i], _(hc_props[i+1]), 1);
+ }
// properties
- char temp[200];
- GtkTreeIter iter;
- gtk_list_store_clear (propstore);
- gtk_list_store_append (propstore, &iter);
- gtk_list_store_set (propstore, &iter, 0, _("Location"), 1, track->fname, -1);
- gtk_list_store_append (propstore, &iter);
- snprintf (temp, sizeof (temp), "%d", track->tracknum);
- gtk_list_store_set (propstore, &iter, 0, _("Subtrack Index"), 1, temp, -1);
- gtk_list_store_append (propstore, &iter);
- deadbeef->pl_format_time (deadbeef->pl_get_item_duration (track), temp, sizeof (temp));
- gtk_list_store_set (propstore, &iter, 0, _("Duration"), 1, temp, -1);
- gtk_list_store_append (propstore, &iter);
- deadbeef->pl_format_title (track, -1, temp, sizeof (temp), -1, "%T");
- gtk_list_store_set (propstore, &iter, 0, _("Tag Type(s)"), 1, temp, -1);
- gtk_list_store_append (propstore, &iter);
- gtk_list_store_set (propstore, &iter, 0, _("Embedded Cuesheet"), 1, (deadbeef->pl_get_item_flags (track) & DDB_HAS_EMBEDDED_CUESHEET) ? _("Yes") : _("No"), -1);
- gtk_list_store_append (propstore, &iter);
- gtk_list_store_set (propstore, &iter, 0, _("Codec"), 1, track->decoder_id, -1);
-
- gtk_list_store_append (propstore, &iter);
- snprintf (temp, sizeof (temp), "%0.2f dB", track->replaygain_album_gain);
- gtk_list_store_set (propstore, &iter, 0, "REPLAYGAIN_ALBUM_GAIN", 1, temp, -1);
- gtk_list_store_append (propstore, &iter);
- snprintf (temp, sizeof (temp), "%0.6f", track->replaygain_album_peak);
- gtk_list_store_set (propstore, &iter, 0, "REPLAYGAIN_ALBUM_PEAK", 1, temp, -1);
-
- gtk_list_store_append (propstore, &iter);
- snprintf (temp, sizeof (temp), "%0.2f dB", track->replaygain_track_gain);
- gtk_list_store_set (propstore, &iter, 0, "REPLAYGAIN_TRACK_GAIN", 1, temp, -1);
- gtk_list_store_append (propstore, &iter);
- snprintf (temp, sizeof (temp), "%0.6f", track->replaygain_track_peak);
- gtk_list_store_set (propstore, &iter, 0, "REPLAYGAIN_TRACK_PEAK", 1, temp, -1);
-}
-
-void
-show_track_properties_dlg (DB_playItem_t *it) {
- if (track) {
- deadbeef->pl_item_unref (track);
- track = NULL;
+ keys = NULL;
+ nkeys = build_key_list (&keys, 1);
+ for (int k = 0; k < nkeys; k++) {
+ int i;
+ for (i = 0; hc_props[i]; i += 2) {
+ if (!strcasecmp (keys[k], hc_props[i])) {
+ break;
+ }
+ }
+ if (hc_props[i]) {
+ continue;
+ }
+ char title[1000];
+ snprintf (title, sizeof (title), "<%s>", keys[k]+1);
+ add_field (propstore, keys[k], title, 1);
}
- if (it) {
- deadbeef->pl_item_ref (it);
+ if (keys) {
+ free (keys);
}
- track = it;
+ deadbeef->pl_unlock ();
+}
- int allow_editing = 0;
+void
+show_track_properties_dlg (void) {
- int is_subtrack = deadbeef->pl_get_item_flags (it) & DDB_IS_SUBTRACK;
+ deadbeef->plt_lock ();
+ deadbeef->pl_lock ();
- if (!is_subtrack && deadbeef->is_local_file (it->fname)) {
- // get decoder plugin by id
- DB_decoder_t *dec = NULL;
- if (it->decoder_id) {
- DB_decoder_t **decoders = deadbeef->plug_get_decoder_list ();
- for (int i = 0; decoders[i]; i++) {
- if (!strcmp (decoders[i]->plugin.id, it->decoder_id)) {
- dec = decoders[i];
- break;
+ if (tracks) {
+ for (int i = 0; i < numtracks; i++) {
+ deadbeef->pl_item_unref (tracks[i]);
+ }
+ free (tracks);
+ tracks = NULL;
+ numtracks = 0;
+ }
+
+ int nsel = deadbeef->pl_getselcount ();
+ if (0 < nsel) {
+ tracks = malloc (sizeof (DB_playItem_t *) * nsel);
+ if (tracks) {
+ int n = 0;
+ DB_playItem_t *it = deadbeef->pl_get_first (PL_MAIN);
+ while (it) {
+ if (deadbeef->pl_is_selected (it)) {
+ assert (n < nsel);
+ deadbeef->pl_item_ref (it);
+ tracks[n++] = it;
}
+ DB_playItem_t *next = deadbeef->pl_get_next (it, PL_MAIN);
+ deadbeef->pl_item_unref (it);
+ it = next;
}
+ numtracks = nsel;
}
-
- if (dec && dec->write_metadata) {
- allow_editing = 1;
+ else {
+ deadbeef->pl_unlock ();
+ deadbeef->plt_unlock ();
+ return;
}
}
+ deadbeef->pl_unlock ();
+ deadbeef->plt_unlock ();
+
GtkTreeView *tree;
GtkTreeView *proptree;
if (!trackproperties) {
trackproperties = create_trackproperties ();
gtk_window_set_transient_for (GTK_WINDOW (trackproperties), GTK_WINDOW (mainwin));
+ wingeom_restore (trackproperties, "trkproperties", -1, -1, 300, 400, 0);
// metadata tree
tree = GTK_TREE_VIEW (lookup_widget (trackproperties, "metalist"));
- store = gtk_list_store_new (3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
+ store = gtk_list_store_new (4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT);
gtk_tree_view_set_model (tree, GTK_TREE_MODEL (store));
GtkCellRenderer *rend_text = gtk_cell_renderer_text_new ();
- rend_text2 = GTK_CELL_RENDERER (ddb_cell_renderer_text_multiline_new ());//gtk_cell_renderer_text_new ();
- if (allow_editing) {
- g_signal_connect ((gpointer)rend_text2, "edited",
- G_CALLBACK (on_metadata_edited),
- store);
- }
+ rend_text2 = GTK_CELL_RENDERER (ddb_cell_renderer_text_multiline_new ());
+ g_signal_connect ((gpointer)rend_text2, "edited",
+ G_CALLBACK (on_metadata_edited),
+ store);
GtkTreeViewColumn *col1 = gtk_tree_view_column_new_with_attributes (_("Key"), rend_text, "text", 0, NULL);
GtkTreeViewColumn *col2 = gtk_tree_view_column_new_with_attributes (_("Value"), rend_text2, "text", 1, NULL);
gtk_tree_view_append_column (tree, col1);
@@ -273,12 +421,7 @@ show_track_properties_dlg (DB_playItem_t *it) {
gtk_list_store_clear (propstore);
}
-// if (allow_editing) {
- g_object_set (G_OBJECT (rend_text2), "editable", TRUE, NULL);
-// }
-// else {
-// g_object_set (G_OBJECT (rend_text2), "editable", FALSE, NULL);
-// }
+ g_object_set (G_OBJECT (rend_text2), "editable", TRUE, NULL);
GtkWidget *widget = trackproperties;
GtkWidget *w;
@@ -286,12 +429,7 @@ show_track_properties_dlg (DB_playItem_t *it) {
trkproperties_fill_metadata ();
- if (allow_editing) {
- gtk_widget_set_sensitive (lookup_widget (widget, "write_tags"), TRUE);
- }
- else {
- gtk_widget_set_sensitive (lookup_widget (widget, "write_tags"), FALSE);
- }
+ gtk_widget_set_sensitive (lookup_widget (widget, "write_tags"), TRUE);
gtk_widget_show (widget);
gtk_window_present (GTK_WINDOW (widget));
@@ -299,46 +437,322 @@ show_track_properties_dlg (DB_playItem_t *it) {
static gboolean
set_metadata_cb (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data) {
- GValue key = {0,}, value = {0,};
- gtk_tree_model_get_value (model, iter, 2, &key);
- gtk_tree_model_get_value (model, iter, 1, &value);
- const char *skey = g_value_get_string (&key);
- const char *svalue = g_value_get_string (&value);
+ GValue mult = {0,};
+ gtk_tree_model_get_value (model, iter, 3, &mult);
+ int smult = g_value_get_int (&mult);
+ if (!smult) {
+ GValue key = {0,}, value = {0,};
+ gtk_tree_model_get_value (model, iter, 2, &key);
+ gtk_tree_model_get_value (model, iter, 1, &value);
+ const char *skey = g_value_get_string (&key);
+ const char *svalue = g_value_get_string (&value);
+ if (*svalue) {
+ for (int i = 0; i < numtracks; i++) {
+ deadbeef->pl_replace_meta (tracks[i], skey, svalue);
+ }
+ }
+ else {
+ for (int i = 0; i < numtracks; i++) {
+ deadbeef->pl_delete_meta (tracks[i], skey);
+ }
+ }
+ }
+ return FALSE;
+}
- for (int i = 0; types[i]; i += 2) {
- if (!strcmp (skey, types[i])) {
- deadbeef->pl_replace_meta (DB_PLAYITEM (data), types[i], svalue);
+static gboolean
+write_finished_cb (void *ctx) {
+ gtk_widget_destroy (progressdlg);
+ progressdlg = NULL;
+ main_refresh ();
+ search_refresh ();
+ trkproperties_modified = 0;
+ return FALSE;
+}
+
+static gboolean
+set_progress_cb (void *ctx) {
+ DB_playItem_t *track = ctx;
+ GtkWidget *progressitem = lookup_widget (progressdlg, "progresstitle");
+ const char *fname = deadbeef->pl_find_meta (track, ":URI");
+ gtk_entry_set_text (GTK_ENTRY (progressitem), fname);
+ deadbeef->pl_item_unref (track);
+}
+
+static void
+write_meta_worker (void *ctx) {
+ for (int t = 0; t < numtracks; t++) {
+ if (progress_aborted) {
+ break;
+ }
+ DB_playItem_t *track = tracks[t];
+ const char *decoder_id = deadbeef->pl_find_meta (track, ":DECODER");
+ if (track && decoder_id) {
+ int is_subtrack = deadbeef->pl_get_item_flags (track) & DDB_IS_SUBTRACK;
+ if (is_subtrack) {
+ continue;
+ }
+ deadbeef->pl_item_ref (track);
+ g_idle_add (set_progress_cb, track);
+ // find decoder
+ DB_decoder_t *dec = NULL;
+ DB_decoder_t **decoders = deadbeef->plug_get_decoder_list ();
+ for (int i = 0; decoders[i]; i++) {
+ if (!strcmp (decoders[i]->plugin.id, decoder_id)) {
+ dec = decoders[i];
+ if (dec->write_metadata) {
+ dec->write_metadata (track);
+ }
+ break;
+ }
+ }
}
}
+ g_idle_add (write_finished_cb, ctx);
+}
- return FALSE;
+static gboolean
+on_progress_delete_event (GtkWidget *widget,
+ GdkEvent *event,
+ gpointer user_data)
+{
+ progress_aborted = 1;
+ return gtk_widget_hide_on_delete (widget);
+}
+
+static void
+on_progress_abort (GtkButton *button,
+ gpointer user_data)
+{
+ progress_aborted = 1;
}
void
on_write_tags_clicked (GtkButton *button,
gpointer user_data)
{
- if (!track || !track->decoder_id) {
- return;
+ deadbeef->pl_lock ();
+ GtkTreeView *tree = GTK_TREE_VIEW (lookup_widget (trackproperties, "metalist"));
+ GtkTreeModel *model = GTK_TREE_MODEL (gtk_tree_view_get_model (tree));
+
+ // delete all metadata properties that are not in the listview
+ for (int i = 0; i < numtracks; i++) {
+ DB_metaInfo_t *meta = deadbeef->pl_get_metadata_head (tracks[i]);
+ while (meta) {
+ DB_metaInfo_t *next = meta->next;
+ if (meta->key[0] != ':') {
+ GtkTreeIter iter;
+ gboolean res = gtk_tree_model_get_iter_first (model, &iter);
+ int mult = 0;
+ while (res) {
+ GValue key = {0,};
+ gtk_tree_model_get_value (model, &iter, 2, &key);
+ const char *skey = g_value_get_string (&key);
+
+ if (!strcasecmp (skey, meta->key)) {
+ // field found, don't delete
+ break;
+ }
+ res = gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter);
+ }
+ if (!res) {
+ // field not found, delete
+ deadbeef->pl_delete_metadata (tracks[i], meta);
+ }
+ }
+ meta = next;
+ }
}
- // find decoder
- DB_decoder_t *dec = NULL;
- DB_decoder_t **decoders = deadbeef->plug_get_decoder_list ();
- for (int i = 0; decoders[i]; i++) {
- if (!strcmp (decoders[i]->plugin.id, track->decoder_id)) {
- dec = decoders[i];
- if (dec->write_metadata) {
- // put all metainfo into track
- GtkTreeView *tree = GTK_TREE_VIEW (lookup_widget (trackproperties, "metalist"));
- GtkTreeModel *model = GTK_TREE_MODEL (gtk_tree_view_get_model (tree));
- gtk_tree_model_foreach (model, set_metadata_cb, track);
- dec->write_metadata (track);
- main_refresh ();
- search_refresh ();
+ // put all metainfo into track
+ gtk_tree_model_foreach (model, set_metadata_cb, NULL);
+ deadbeef->pl_unlock ();
+
+ progress_aborted = 0;
+ progressdlg = create_progressdlg ();
+ gtk_window_set_title (GTK_WINDOW (progressdlg), _("Writing tags..."));
+
+ g_signal_connect ((gpointer) progressdlg, "delete_event",
+ G_CALLBACK (on_progress_delete_event),
+ NULL);
+ GtkWidget *cancelbtn = lookup_widget (progressdlg, "cancelbtn");
+ g_signal_connect ((gpointer) cancelbtn, "clicked",
+ G_CALLBACK (on_progress_abort),
+ NULL);
+
+ gtk_widget_show_all (progressdlg);
+ gtk_window_present (GTK_WINDOW (progressdlg));
+ gtk_window_set_transient_for (GTK_WINDOW (progressdlg), GTK_WINDOW (trackproperties));
+
+ // start new thread for writing metadata
+ intptr_t tid = deadbeef->thread_start (write_meta_worker, NULL);
+ deadbeef->thread_detach (tid);
+}
+
+void
+on_add_field_activate (GtkMenuItem *menuitem,
+ gpointer user_data) {
+ GtkWidget *dlg = create_entrydialog ();
+ gtk_dialog_set_default_response (GTK_DIALOG (dlg), GTK_RESPONSE_OK);
+ gtk_window_set_title (GTK_WINDOW (dlg), _("Edit playlist"));
+ GtkWidget *e;
+ e = lookup_widget (dlg, "title_label");
+ gtk_label_set_text (GTK_LABEL(e), _("Name:"));
+ for (;;) {
+ int res = gtk_dialog_run (GTK_DIALOG (dlg));
+ if (res == GTK_RESPONSE_OK) {
+ e = lookup_widget (dlg, "title");
+
+ const char *text = gtk_entry_get_text (GTK_ENTRY(e));
+
+ GtkTreeIter iter;
+
+ // check for _ and :
+ if (text[0] == '_' || text[0] == ':') {
+ GtkWidget *d = gtk_message_dialog_new (GTK_WINDOW (dlg), GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("Field names must not start with : or _"));
+ gtk_window_set_title (GTK_WINDOW (d), _("Cannot add field"));
+
+ gtk_dialog_run (GTK_DIALOG (d));
+ gtk_widget_destroy (d);
+ continue;
}
+
+ // check if a field with the same name already exists
+ int dup = 0;
+ gboolean res = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter);
+ while (res) {
+ GValue value = {0,};
+ gtk_tree_model_get_value (GTK_TREE_MODEL (store), &iter, 2, &value);
+ const char *svalue = g_value_get_string (&value);
+ if (!strcasecmp (svalue, text)) {
+ dup = 1;
+ break;
+ }
+ res = gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter);
+ }
+
+ if (!dup) {
+ int l = strlen (text);
+ char title[l+3];
+ snprintf (title, sizeof (title), "<%s>", text);
+ const char *value = "";
+ const char *key = text;
+
+ gtk_list_store_append (store, &iter);
+ gtk_list_store_set (store, &iter, 0, title, 1, value, 2, key, -1);
+ trkproperties_modified = 1;
+ }
+ else {
+ GtkWidget *d = gtk_message_dialog_new (GTK_WINDOW (dlg), GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("Field with such name already exists, please try different name."));
+ gtk_window_set_title (GTK_WINDOW (d), _("Cannot add field"));
+
+ gtk_dialog_run (GTK_DIALOG (d));
+ gtk_widget_destroy (d);
+ continue;
+ }
+ }
+ break;
+ }
+ gtk_widget_destroy (dlg);
+}
+
+void
+on_remove_field_activate (GtkMenuItem *menuitem,
+ gpointer user_data) {
+
+ GtkTreePath *path;
+ GtkTreeViewColumn *col;
+ GtkTreeView *treeview = GTK_TREE_VIEW (lookup_widget (trackproperties, "metalist"));
+ gtk_tree_view_get_cursor (treeview, &path, &col);
+ if (!path || !col) {
+ return;
+ }
+
+ GtkWidget *dlg = gtk_message_dialog_new (GTK_WINDOW (trackproperties), GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING, GTK_BUTTONS_YES_NO, _("Really remove selected field?"));
+ gtk_window_set_title (GTK_WINDOW (dlg), _("Warning"));
+
+ int response = gtk_dialog_run (GTK_DIALOG (dlg));
+ gtk_widget_destroy (dlg);
+ if (response != GTK_RESPONSE_YES) {
+ return;
+ }
+
+ GtkTreeIter iter;
+ gtk_tree_model_get_iter (GTK_TREE_MODEL (store), &iter, path);
+ GValue value = {0,};
+ gtk_tree_model_get_value (GTK_TREE_MODEL (store), &iter, 2, &value);
+ const char *svalue = g_value_get_string (&value);
+
+ // delete unknown fields completely; otherwise just clear
+ int i = 0;
+ for (; types[i]; i += 2) {
+ if (!strcasecmp (svalue, types[i])) {
break;
}
}
- trkproperties_modified = 0;
+ if (types[i]) { // known val, clear
+ gtk_list_store_set (store, &iter, 1, "", 3, 0, -1);
+ }
+ else {
+ gtk_list_store_remove (store, &iter);
+ }
+ gtk_tree_path_free (path);
+ trkproperties_modified = 1;
+}
+
+gboolean
+on_metalist_button_press_event (GtkWidget *widget,
+ GdkEventButton *event,
+ gpointer user_data)
+{
+ if (event->button == 3) {
+ GtkWidget *menu;
+ GtkWidget *add;
+ GtkWidget *remove;
+ menu = gtk_menu_new ();
+ add = gtk_menu_item_new_with_mnemonic (_("Add field"));
+ gtk_widget_show (add);
+ gtk_container_add (GTK_CONTAINER (menu), add);
+ remove = gtk_menu_item_new_with_mnemonic (_("Remove field"));
+ gtk_widget_show (remove);
+ gtk_container_add (GTK_CONTAINER (menu), remove);
+
+ g_signal_connect ((gpointer) add, "activate",
+ G_CALLBACK (on_add_field_activate),
+ NULL);
+
+ g_signal_connect ((gpointer) remove, "activate",
+ G_CALLBACK (on_remove_field_activate),
+ NULL);
+
+ gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, widget, event->button, gtk_get_current_event_time());
+ }
+ return FALSE;
+}
+
+void
+on_tagwriter_settings_clicked (GtkButton *button,
+ gpointer user_data)
+{
+ run_tagwriter_settings (trackproperties);
+}
+
+gboolean
+on_trackproperties_configure_event (GtkWidget *widget,
+ GdkEventConfigure *event,
+ gpointer user_data)
+{
+ wingeom_save (widget, "trkproperties");
+ return FALSE;
}
+
+
+gboolean
+on_trackproperties_window_state_event (GtkWidget *widget,
+ GdkEventWindowState *event,
+ gpointer user_data)
+{
+ wingeom_save_max (event, widget, "trkproperties");
+ return FALSE;
+}
+
diff --git a/plugins/gtkui/trkproperties.h b/plugins/gtkui/trkproperties.h
index 8bd1a903..ccdaa69f 100644
--- a/plugins/gtkui/trkproperties.h
+++ b/plugins/gtkui/trkproperties.h
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@@ -22,7 +22,7 @@
struct DB_playItem_s;
void
-show_track_properties_dlg (struct DB_playItem_s *it);
+show_track_properties_dlg (void);
void
trkproperties_destroy (void);
diff --git a/plugins/gtkui/wingeom.c b/plugins/gtkui/wingeom.c
new file mode 100644
index 00000000..8591a5c6
--- /dev/null
+++ b/plugins/gtkui/wingeom.c
@@ -0,0 +1,101 @@
+/*
+ DeaDBeeF - ultimate music player for GNU/Linux systems with X11
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include <gtk/gtk.h>
+#include "wingeom.h"
+#include "../../deadbeef.h"
+#include "gtkui.h"
+
+void
+wingeom_save (GtkWidget *widget, const char *name) {
+#if GTK_CHECK_VERSION(2,2,0)
+ GdkWindowState window_state = gdk_window_get_state (GDK_WINDOW (widget->window));
+#else
+ GdkWindowState window_state = gdk_window_get_state (G_OBJECT (widget));
+#endif
+ if (!(window_state & GDK_WINDOW_STATE_MAXIMIZED) && gtk_widget_get_visible (widget)) {
+ int x, y;
+ int w, h;
+ char key[100];
+ gtk_window_get_position (GTK_WINDOW (widget), &x, &y);
+ gtk_window_get_size (GTK_WINDOW (widget), &w, &h);
+ snprintf (key, sizeof (key), "%s.geometry.x", name);
+ deadbeef->conf_set_int (key, x);
+ snprintf (key, sizeof (key), "%s.geometry.y", name);
+ deadbeef->conf_set_int (key, y);
+ snprintf (key, sizeof (key), "%s.geometry.w", name);
+ deadbeef->conf_set_int (key, w);
+ snprintf (key, sizeof (key), "%s.geometry.h", name);
+ deadbeef->conf_set_int (key, h);
+ }
+}
+
+void
+wingeom_save_max (GdkEventWindowState *event, GtkWidget *widget, const char *name) {
+ if (!gtk_widget_get_visible (widget)) {
+ return;
+ }
+ char key[100];
+ snprintf (key, sizeof (key), "%s.geometry.maximized", name);
+ // based on pidgin maximization handler
+#if GTK_CHECK_VERSION(2,2,0)
+ if (event->changed_mask & GDK_WINDOW_STATE_MAXIMIZED) {
+ if (event->new_window_state & GDK_WINDOW_STATE_MAXIMIZED) {
+ deadbeef->conf_set_int (key, 1);
+ }
+ else {
+ deadbeef->conf_set_int (key, 0);
+ }
+ }
+#else
+ GdkWindowState new_window_state = gdk_window_get_state(G_OBJECT(widget));
+
+ if (new_window_state & GDK_WINDOW_STATE_MAXIMIZED) {
+ deadbeef->conf_set_int (key, 1);
+ }
+ else {
+ deadbeef->conf_set_int (key, 0);
+ }
+#endif
+}
+
+void
+wingeom_restore (GtkWidget *win, const char *name, int dx, int dy, int dw, int dh, int dmax) {
+ char key[100];
+ snprintf (key, sizeof (key), "%s.geometry.x", name);
+ int x = deadbeef->conf_get_int (key, dx);
+ snprintf (key, sizeof (key), "%s.geometry.y", name);
+ int y = deadbeef->conf_get_int (key, dy);
+ snprintf (key, sizeof (key), "%s.geometry.w", name);
+ int w = deadbeef->conf_get_int (key, dw);
+ snprintf (key, sizeof (key), "%s.geometry.h", name);
+ int h = deadbeef->conf_get_int (key, dh);
+ if (x != -1 && y != -1) {
+ gtk_window_move (GTK_WINDOW (win), x, y);
+ }
+ if (w != -1 && h != -1) {
+ gtk_window_resize (GTK_WINDOW (win), w, h);
+ }
+ snprintf (key, sizeof (key), "%s.geometry.maximized", name);
+ if (deadbeef->conf_get_int (key, dmax)) {
+ gtk_window_maximize (GTK_WINDOW (win));
+ }
+}
diff --git a/plugins/gtkui/wingeom.h b/plugins/gtkui/wingeom.h
new file mode 100644
index 00000000..9b468846
--- /dev/null
+++ b/plugins/gtkui/wingeom.h
@@ -0,0 +1,31 @@
+/*
+ DeaDBeeF - ultimate music player for GNU/Linux systems with X11
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+#ifndef __WINGEOM_H
+#define __WINGEOM_H
+
+void
+wingeom_save (GtkWidget *widget, const char *name);
+
+void
+wingeom_save_max (GdkEventWindowState *event, GtkWidget *widget, const char *name);
+
+void
+wingeom_restore (GtkWidget *win, const char *name, int dx, int dy, int dw, int dh, int dmax);
+
+#endif
diff --git a/plugins/hotkeys/hotkeys.c b/plugins/hotkeys/hotkeys.c
index 2be24387..ec8f2e96 100644
--- a/plugins/hotkeys/hotkeys.c
+++ b/plugins/hotkeys/hotkeys.c
@@ -111,7 +111,7 @@ cmd_stop_after_current (void *unused) {
int var = deadbeef->conf_get_int ("playlist.stop_after_current", 0);
var = 1 - var;
deadbeef->conf_set_int ("playlist.stop_after_current", var);
- deadbeef->sendmessage (M_CONFIGCHANGED, 0, 0, 0);
+ deadbeef->sendmessage (M_CONFIG_CHANGED, 0, 0, 0);
}
/*
@@ -461,7 +461,7 @@ hotkeys_event_loop (void *unused) {
}
static int
-hotkeys_start (void) {
+hotkeys_connect (void) {
finished = 0;
loop_tid = 0;
disp = XOpenDisplay (NULL);
@@ -475,12 +475,11 @@ hotkeys_start (void) {
read_config (disp);
XSync (disp, 0);
loop_tid = deadbeef->thread_start (hotkeys_event_loop, 0);
-
return 0;
}
static int
-hotkeys_stop (void) {
+hotkeys_disconnect (void) {
if (loop_tid) {
finished = 1;
deadbeef->thread_join (loop_tid);
@@ -508,31 +507,31 @@ hotkeys_reset (void) {
int
action_play_cb (struct DB_plugin_action_s *action, DB_playItem_t *it) {
- deadbeef->playback_play ();
+ deadbeef->sendmessage (M_PLAY_CURRENT, 0, 0, 0);
return 0;
}
int
action_prev_cb (struct DB_plugin_action_s *action, DB_playItem_t *it) {
- deadbeef->playback_prev ();
+ deadbeef->sendmessage (M_PREV, 0, 0, 0);
return 0;
}
int
action_next_cb (struct DB_plugin_action_s *action, DB_playItem_t *it) {
- deadbeef->playback_next ();
+ deadbeef->sendmessage (M_NEXT, 0, 0, 0);
return 0;
}
int
action_stop_cb (struct DB_plugin_action_s *action, DB_playItem_t *it) {
- deadbeef->playback_stop ();
+ deadbeef->sendmessage (M_STOP, 0, 0, 0);
return 0;
}
int
action_toggle_pause_cb (struct DB_plugin_action_s *action, DB_playItem_t *it) {
- deadbeef->playback_pause ();
+ deadbeef->sendmessage (M_TOGGLE_PAUSE, 0, 0, 0);
return 0;
}
@@ -540,17 +539,17 @@ int
action_play_pause_cb (struct DB_plugin_action_s *action, DB_playItem_t *it) {
int state = deadbeef->get_output ()->state ();
if (state == OUTPUT_STATE_PLAYING) {
- deadbeef->playback_pause ();
+ deadbeef->sendmessage (M_PAUSE, 0, 0, 0);
}
else {
- deadbeef->playback_play ();
+ deadbeef->sendmessage (M_PLAY_CURRENT, 0, 0, 0);
}
return 0;
}
int
action_play_random_cb (struct DB_plugin_action_s *action, DB_playItem_t *it) {
- deadbeef->playback_random ();
+ deadbeef->sendmessage (M_PLAY_RANDOM, 0, 0, 0);
return 0;
}
@@ -583,7 +582,7 @@ action_toggle_stop_after_current_cb (struct DB_plugin_action_s *action, DB_playI
int var = deadbeef->conf_get_int ("playlist.stop_after_current", 0);
var = 1 - var;
deadbeef->conf_set_int ("playlist.stop_after_current", var);
- deadbeef->sendmessage (M_CONFIGCHANGED, 0, 0, 0);
+ deadbeef->sendmessage (M_CONFIG_CHANGED, 0, 0, 0);
return 0;
}
@@ -693,16 +692,34 @@ hotkeys_get_actions (DB_playItem_t *it)
static DB_hotkeys_plugin_t plugin = {
.misc.plugin.api_vmajor = DB_API_VERSION_MAJOR,
.misc.plugin.api_vminor = DB_API_VERSION_MINOR,
+ .misc.plugin.version_major = 1,
+ .misc.plugin.version_minor = 0,
.misc.plugin.type = DB_PLUGIN_MISC,
.misc.plugin.id = "hotkeys",
.misc.plugin.name = "Global hotkeys support",
.misc.plugin.descr = "Allows to control player with global hotkeys",
- .misc.plugin.author = "Viktor Semykin",
- .misc.plugin.email = "thesame.ml@gmail.com",
+ .misc.plugin.copyright =
+ "Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>\n"
+ "Copyright (C) 2009-2011 Viktor Semykin <thesame.ml@gmail.com>\n"
+ "\n"
+ "This program is free software; you can redistribute it and/or\n"
+ "modify it under the terms of the GNU General Public License\n"
+ "as published by the Free Software Foundation; either version 2\n"
+ "of the License, or (at your option) any later version.\n"
+ "\n"
+ "This program is distributed in the hope that it will be useful,\n"
+ "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+ "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+ "GNU General Public License for more details.\n"
+ "\n"
+ "You should have received a copy of the GNU General Public License\n"
+ "along with this program; if not, write to the Free Software\n"
+ "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n"
+ ,
.misc.plugin.website = "http://deadbeef.sf.net",
- .misc.plugin.start = hotkeys_start,
- .misc.plugin.stop = hotkeys_stop,
.misc.plugin.get_actions = hotkeys_get_actions,
+ .misc.plugin.connect = hotkeys_connect,
+ .misc.plugin.disconnect = hotkeys_disconnect,
.get_name_for_keycode = hotkeys_get_name_for_keycode,
.reset = hotkeys_reset,
};
diff --git a/plugins/hotkeys/hotkeys.h b/plugins/hotkeys/hotkeys.h
index f520aa41..010f0919 100644
--- a/plugins/hotkeys/hotkeys.h
+++ b/plugins/hotkeys/hotkeys.h
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
diff --git a/plugins/lastfm/lastfm.c b/plugins/lastfm/lastfm.c
index 4a234e8f..b29355b1 100644
--- a/plugins/lastfm/lastfm.c
+++ b/plugins/lastfm/lastfm.c
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@@ -67,13 +67,15 @@ static DB_playItem_t *lfm_subm_queue[LFM_SUBMISSION_QUEUE_SIZE];
static void
lfm_update_auth (void) {
- const char *user = deadbeef->conf_get_str ("lastfm.login", "");
- const char *pass = deadbeef->conf_get_str ("lastfm.password", "");
+ deadbeef->conf_lock ();
+ const char *user = deadbeef->conf_get_str_fast ("lastfm.login", "");
+ const char *pass = deadbeef->conf_get_str_fast ("lastfm.password", "");
if (strcmp (user, lfm_user) || strcmp (pass, lfm_pass)) {
strcpy (lfm_user, user);
strcpy (lfm_pass, pass);
lfm_sess[0] = 0;
}
+ deadbeef->conf_unlock ();
}
static size_t
@@ -128,9 +130,10 @@ curl_req_send (const char *req, const char *post) {
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, strlen(post));
}
if (deadbeef->conf_get_int ("network.proxy", 0)) {
- curl_easy_setopt (curl, CURLOPT_PROXY, deadbeef->conf_get_str ("network.proxy.address", ""));
+ deadbeef->conf_lock ();
+ curl_easy_setopt (curl, CURLOPT_PROXY, deadbeef->conf_get_str_fast ("network.proxy.address", ""));
curl_easy_setopt (curl, CURLOPT_PROXYPORT, deadbeef->conf_get_int ("network.proxy.port", 8080));
- const char *type = deadbeef->conf_get_str ("network.proxy.type", "HTTP");
+ const char *type = deadbeef->conf_get_str_fast ("network.proxy.type", "HTTP");
int curlproxytype = CURLPROXY_HTTP;
if (!strcasecmp (type, "HTTP")) {
curlproxytype = CURLPROXY_HTTP;
@@ -158,8 +161,8 @@ curl_req_send (const char *req, const char *post) {
#endif
curl_easy_setopt (curl, CURLOPT_PROXYTYPE, curlproxytype);
- const char *proxyuser = deadbeef->conf_get_str ("network.proxy.username", "");
- const char *proxypass = deadbeef->conf_get_str ("network.proxy.password", "");
+ const char *proxyuser = deadbeef->conf_get_str_fast ("network.proxy.username", "");
+ const char *proxypass = deadbeef->conf_get_str_fast ("network.proxy.password", "");
if (*proxyuser || *proxypass) {
#if LIBCURL_VERSION_MINOR >= 19 && LIBCURL_VERSION_PATCH >= 1
curl_easy_setopt (curl, CURLOPT_PROXYUSERNAME, proxyuser);
@@ -170,6 +173,7 @@ curl_req_send (const char *req, const char *post) {
curl_easy_setopt (curl, CURLOPT_PROXYUSERPWD, pwd);
#endif
}
+ deadbeef->conf_unlock ();
}
int status = curl_easy_perform(curl);
curl_easy_cleanup (curl);
@@ -207,12 +211,14 @@ auth (void) {
deadbeef->md5 (sig, token, strlen (token));
deadbeef->md5_to_str (token, sig);
- const char *scrobbler_url = deadbeef->conf_get_str ("lastfm.scrobbler_url", SCROBBLER_URL_LFM);
+ deadbeef->conf_lock ();
+ const char *scrobbler_url = deadbeef->conf_get_str_fast ("lastfm.scrobbler_url", SCROBBLER_URL_LFM);
#if LFM_TESTMODE
snprintf (req, sizeof (req), "%s/?hs=true&p=1.2.1&c=tst&v=1.0&u=%s&t=%d&a=%s", scrobbler_url, lfm_user, (int)timestamp, token);
#else
snprintf (req, sizeof (req), "%s/?hs=true&p=1.2.1&c=%s&v=%d.%d&u=%s&t=%d&a=%s", scrobbler_url, LFM_CLIENTID, plugin.plugin.version_major, plugin.plugin.version_minor, lfm_user, (int)timestamp, token);
#endif
+ deadbeef->conf_unlock ();
// handshake
int status = curl_req_send (req, NULL);
if (!status) {
@@ -846,7 +852,6 @@ lfm_action_lookup (DB_plugin_action_t *action, DB_playItem_t *it)
char *command = NULL;
if (-1 == asprintf (&command, "xdg-open 'http://www.last.fm/music/%s/_/%s' &", eartist, etitle))
return 0;
- printf ("executing %s\n", command);
system (command);
free (command);
}
@@ -902,13 +907,28 @@ static const char settings_dlg[] =
// define plugin interface
static DB_misc_t plugin = {
DB_PLUGIN_SET_API_VERSION
- .plugin.version_major = 0,
- .plugin.version_minor = 1,
+ .plugin.version_major = 1,
+ .plugin.version_minor = 0,
.plugin.type = DB_PLUGIN_MISC,
.plugin.name = "last.fm scrobbler",
- .plugin.descr = "sends played songs information to your last.fm account",
- .plugin.author = "Alexey Yakovenko",
- .plugin.email = "waker@users.sourceforge.net",
+ .plugin.descr = "Sends played songs information to your last.fm account, or other service that use AudioScrobbler protocol",
+ .plugin.copyright =
+ "Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>\n"
+ "\n"
+ "This program is free software; you can redistribute it and/or\n"
+ "modify it under the terms of the GNU General Public License\n"
+ "as published by the Free Software Foundation; either version 2\n"
+ "of the License, or (at your option) any later version.\n"
+ "\n"
+ "This program is distributed in the hope that it will be useful,\n"
+ "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+ "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+ "GNU General Public License for more details.\n"
+ "\n"
+ "You should have received a copy of the GNU General Public License\n"
+ "along with this program; if not, write to the Free Software\n"
+ "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n"
+ ,
.plugin.website = "http://deadbeef.sf.net",
.plugin.start = lastfm_start,
.plugin.stop = lastfm_stop,
diff --git a/plugins/m3u/Makefile.am b/plugins/m3u/Makefile.am
new file mode 100644
index 00000000..e77663c6
--- /dev/null
+++ b/plugins/m3u/Makefile.am
@@ -0,0 +1,11 @@
+if HAVE_M3U
+pkglib_LTLIBRARIES = m3u.la
+
+m3u_la_SOURCES = m3u.c
+
+m3u_la_LDFLAGS = -module
+
+m3u_la_LIBADD = $(LIBADD)
+
+m3u_la_CFLAGS = $(CFLAGS) -std=c99
+endif
diff --git a/plugins/m3u/m3u.c b/plugins/m3u/m3u.c
new file mode 100644
index 00000000..4e5afe83
--- /dev/null
+++ b/plugins/m3u/m3u.c
@@ -0,0 +1,469 @@
+/*
+ DeaDBeeF - ultimate music player for GNU/Linux systems with X11
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+#include <string.h>
+#include <stdlib.h>
+#include <math.h>
+#include "../../deadbeef.h"
+
+//#define trace(...) { fprintf(stderr, __VA_ARGS__); }
+#define trace(fmt,...)
+
+#define min(x,y) ((x)<(y)?(x):(y))
+#define max(x,y) ((x)>(y)?(x):(y))
+
+static DB_functions_t *deadbeef;
+
+static const uint8_t *
+skipspaces (const uint8_t *p, const uint8_t *end) {
+ while (p < end && *p <= ' ') {
+ p++;
+ }
+ return p;
+}
+
+static DB_playItem_t *
+load_m3u (DB_playItem_t *after, const char *fname, int *pabort, int (*cb)(DB_playItem_t *it, void *data), void *user_data) {
+ const char *slash = strrchr (fname, '/');
+ trace ("enter pl_insert_m3u\n");
+ // skip all empty lines and comments
+ DB_FILE *fp = deadbeef->fopen (fname);
+ if (!fp) {
+ trace ("failed to open file %s\n", fname);
+ return NULL;
+ }
+ int sz = deadbeef->fgetlength (fp);
+ trace ("loading m3u...\n");
+ uint8_t *buffer = malloc (sz);
+ if (!buffer) {
+ deadbeef->fclose (fp);
+ trace ("failed to allocate %d bytes to read the file %s\n", sz, fname);
+ return NULL;
+ }
+ deadbeef->fread (buffer, 1, sz, fp);
+ deadbeef->fclose (fp);
+ const uint8_t *p = buffer;
+ const uint8_t *end = buffer+sz;
+ deadbeef->pl_lock ();
+ while (p < end) {
+ p = skipspaces (p, end);
+ if (p >= end) {
+ break;
+ }
+ if (*p == '#') {
+ while (p < end && *p >= 0x20) {
+ p++;
+ }
+ if (p >= end) {
+ break;
+ }
+ continue;
+ }
+ const uint8_t *e = p;
+ while (e < end && *e >= 0x20) {
+ e++;
+ }
+ int n = e-p;
+ uint8_t nm[n+1];
+ memcpy (nm, p, n);
+ nm[n] = 0;
+
+ DB_playItem_t *it = NULL;
+ if (strrchr (nm, '/')) {
+ trace ("pl_insert_m3u: adding file %s\n", nm);
+ it = deadbeef->pl_insert_file (after, nm, pabort, cb, user_data);
+ }
+ else {
+ int l = strlen (nm);
+ char fullpath[slash - fname + l + 2];
+ memcpy (fullpath, fname, slash - fname + 1);
+ strcpy (fullpath + (slash - fname + 1), nm);
+ trace ("pl_insert_m3u: adding file %s\n", fullpath);
+ it = deadbeef->pl_insert_file (after, fullpath, pabort, cb, user_data);
+ }
+ if (it) {
+ after = it;
+ }
+ if (pabort && *pabort) {
+ deadbeef->pl_unlock ();
+ free (buffer);
+ return after;
+ }
+ p = e;
+ if (p >= end) {
+ break;
+ }
+ }
+ deadbeef->pl_unlock ();
+ trace ("leave pl_insert_m3u\n");
+ free (buffer);
+ return after;
+}
+
+static DB_playItem_t *
+pls_insert_file (DB_playItem_t *after, const char *fname, const char *uri, int *pabort, int (*cb)(DB_playItem_t *it, void *data), void *user_data, const char *title, const char *length) {
+ trace ("pls_insert_file uri: %s\n", uri);
+ DB_playItem_t *it = NULL;
+ const char *slash = NULL;
+
+ if (strrchr (uri, '/')) {
+ it = deadbeef->pl_insert_file (after, uri, pabort, cb, user_data);
+ }
+ else if (slash = strrchr (fname, '/')) {
+ int l = strlen (uri);
+ char fullpath[slash - fname + l + 2];
+ memcpy (fullpath, fname, slash - fname + 1);
+ strcpy (fullpath + (slash - fname + 1), uri);
+ trace ("pls_insert_file: adding file %s\n", fullpath);
+ it = deadbeef->pl_insert_file (after, fullpath, pabort, cb, user_data);
+ }
+ if (length[0]) {
+ deadbeef->pl_set_item_duration (it, atoi (length));
+ }
+ if (title[0]) {
+ deadbeef->pl_replace_meta (it, "title", title);
+ }
+ return it;
+}
+
+static DB_playItem_t *
+load_pls (DB_playItem_t *after, const char *fname, int *pabort, int (*cb)(DB_playItem_t *it, void *data), void *user_data) {
+ const char *slash = strrchr (fname, '/');
+ DB_FILE *fp = deadbeef->fopen (fname);
+ if (!fp) {
+ trace ("failed to open file %s\n", fname);
+ return NULL;
+ }
+ int sz = deadbeef->fgetlength (fp);
+ deadbeef->rewind (fp);
+ uint8_t *buffer = malloc (sz);
+ if (!buffer) {
+ deadbeef->fclose (fp);
+ trace ("failed to allocate %d bytes to read the file %s\n", sz, fname);
+ return NULL;
+ }
+ deadbeef->fread (buffer, 1, sz, fp);
+ deadbeef->fclose (fp);
+ // 1st line must be "[playlist]"
+ const uint8_t *p = buffer;
+ const uint8_t *end = buffer+sz;
+ if (strncasecmp (p, "[playlist]", 10)) {
+ trace ("file %s doesn't begin with [playlist]\n", fname);
+ free (buffer);
+ return NULL;
+ }
+ p += 10;
+ p = skipspaces (p, end);
+ if (p >= end) {
+ trace ("file %s finished before numberofentries had been read\n", fname);
+ free (buffer);
+ return NULL;
+ }
+ // fetch all tracks
+ char uri[1024] = "";
+ char title[1024] = "";
+ char length[20] = "";
+ int lastidx = -1;
+ deadbeef->pl_lock ();
+ while (p < end) {
+ p = skipspaces (p, end);
+ if (p >= end) {
+ break;
+ }
+ if (end-p < 6) {
+ break;
+ }
+ const uint8_t *e;
+ int n;
+ if (!strncasecmp (p, "numberofentries=", 16) || !strncasecmp (p, "version=", 8)) {
+ while (p < end && *p >= 0x20) {
+ p++;
+ }
+ continue;
+ }
+ else if (!strncasecmp (p, "file", 4)) {
+ int idx = atoi (p + 4);
+ if (uri[0] && idx != lastidx && lastidx != -1) {
+ trace ("uri%d\n", idx);
+ DB_playItem_t *it = pls_insert_file (after, fname, uri, pabort, cb, user_data, title, length);
+ if (it) {
+ after = it;
+ }
+ if (pabort && *pabort) {
+ deadbeef->pl_unlock ();
+ free (buffer);
+ return after;
+ }
+ uri[0] = 0;
+ title[0] = 0;
+ length[0] = 0;
+ }
+ lastidx = idx;
+ p += 4;
+ while (p < end && *p != '=') {
+ p++;
+ }
+ p++;
+ if (p >= end) {
+ break;
+ }
+ e = p;
+ while (e < end && *e >= 0x20) {
+ e++;
+ }
+ n = e-p;
+ n = min (n, sizeof (uri)-1);
+ memcpy (uri, p, n);
+ uri[n] = 0;
+ trace ("uri: %s\n", uri);
+ trace ("uri%d=%s\n", idx, uri);
+ p = ++e;
+ }
+ else if (!strncasecmp (p, "title", 5)) {
+ int idx = atoi (p + 5);
+ if (uri[0] && idx != lastidx && lastidx != -1) {
+ trace ("title%d\n", idx);
+ DB_playItem_t *it = pls_insert_file (after, fname, uri, pabort, cb, user_data, title, length);
+ if (it) {
+ after = it;
+ }
+ if (pabort && *pabort) {
+ deadbeef->pl_unlock ();
+ free (buffer);
+ return after;
+ }
+ uri[0] = 0;
+ title[0] = 0;
+ length[0] = 0;
+ }
+ lastidx = idx;
+ p += 5;
+ while (p < end && *p != '=') {
+ p++;
+ }
+ p++;
+ if (p >= end) {
+ break;
+ }
+ e = p;
+ while (e < end && *e >= 0x20) {
+ e++;
+ }
+ n = e-p;
+ n = min (n, sizeof (title)-1);
+ memcpy (title, p, n);
+ title[n] = 0;
+ trace ("title%d=%s\n", idx, title);
+ p = ++e;
+ }
+ else if (!strncasecmp (p, "length", 6)) {
+ int idx = atoi (p + 6);
+ if (uri[0] && idx != lastidx && lastidx != -1) {
+ trace ("length%d\n", idx);
+ DB_playItem_t *it = pls_insert_file (after, fname, uri, pabort, cb, user_data, title, length);
+ if (it) {
+ after = it;
+ }
+ if (pabort && *pabort) {
+ deadbeef->pl_unlock ();
+ free (buffer);
+ return after;
+ }
+ uri[0] = 0;
+ title[0] = 0;
+ length[0] = 0;
+ }
+ lastidx = idx;
+ p += 6;
+ // skip =
+ while (p < end && *p != '=') {
+ p++;
+ }
+ p++;
+ if (p >= end) {
+ break;
+ }
+ e = p;
+ while (e < end && *e >= 0x20) {
+ e++;
+ }
+ n = e-p;
+ n = min (n, sizeof (length)-1);
+ memcpy (length, p, n);
+ trace ("length%d=%s\n", idx, length);
+ }
+ else {
+ trace ("invalid entry in pls file: %s\n", p);
+ break;
+ }
+ while (e < end && *e < 0x20) {
+ e++;
+ }
+ p = e;
+ }
+ if (uri[0]) {
+ DB_playItem_t *it = pls_insert_file (after, fname, uri, pabort, cb, user_data, title, length);
+ if (it) {
+ after = it;
+ }
+ }
+ deadbeef->pl_unlock ();
+ free (buffer);
+ return after;
+}
+
+static DB_playItem_t *
+m3uplug_load (DB_playItem_t *after, const char *fname, int *pabort, int (*cb)(DB_playItem_t *it, void *data), void *user_data) {
+ const char *ext = strrchr (fname, '.');
+ if (!ext) {
+ return NULL;
+ }
+ ext++;
+
+ if (!strcasecmp (ext, "m3u") || !strcasecmp (ext, "m3u8")) {
+ return load_m3u (after, fname, pabort, cb, user_data);
+ }
+ else if (!strcasecmp (ext, "pls")) {
+ return load_pls (after, fname, pabort, cb, user_data);
+ }
+
+ return NULL;
+}
+
+int
+m3uplug_save_m3u (const char *fname, DB_playItem_t *first, DB_playItem_t *last) {
+ FILE *fp = fopen (fname, "w+t");
+ if (!fp) {
+ return -1;
+ }
+ DB_playItem_t *it = first;
+ deadbeef->pl_item_ref (it);
+ while (it) {
+ int dur = (int)ceil(deadbeef->pl_get_item_duration (it));
+ char s[1000];
+ deadbeef->pl_format_title (it, -1, s, sizeof (s), -1, "%a - %t");
+ const char *fname = deadbeef->pl_find_meta (it, ":URI");
+ fprintf (fp, "#EXTINF:%d,%s\n", dur, s);
+ fprintf (fp, "%s\n", fname);
+
+ if (it == last) {
+ break;
+ }
+ DB_playItem_t *next = deadbeef->pl_get_next (it, PL_MAIN);
+ deadbeef->pl_item_unref (it);
+ it = next;
+ }
+ fclose (fp);
+ return 0;
+}
+
+int
+m3uplug_save_pls (const char *fname, DB_playItem_t *first, DB_playItem_t *last) {
+ FILE *fp = fopen (fname, "w+t");
+ if (!fp) {
+ return -1;
+ }
+
+ int n = 0;
+ DB_playItem_t *it = first;
+ deadbeef->pl_item_ref (it);
+ while (it) {
+ n++;
+ if (it == last) {
+ break;
+ }
+ DB_playItem_t *next = deadbeef->pl_get_next (it, PL_MAIN);
+ deadbeef->pl_item_unref (it);
+ it = next;
+ }
+
+ fprintf (fp, "[playlist]\n");
+ fprintf (fp, "NumberOfEntries=%d\n", n);
+
+ it = first;
+ deadbeef->pl_item_ref (it);
+ int i = 1;
+ while (it) {
+ const char *fname = deadbeef->pl_find_meta (it, ":URI");
+ fprintf (fp, "File%d=%s\n", i, fname);
+
+ if (it == last) {
+ break;
+ }
+ DB_playItem_t *next = deadbeef->pl_get_next (it, PL_MAIN);
+ deadbeef->pl_item_unref (it);
+ it = next;
+ i++;
+ }
+ fclose (fp);
+ return 0;
+}
+
+int
+m3uplug_save (const char *fname, DB_playItem_t *first, DB_playItem_t *last) {
+ const char *e = strrchr (fname, '.');
+ if (!e) {
+ return -1;
+ }
+ if (!strcasecmp (e, ".m3u") || !strcasecmp (e, ".m3u8")) {
+ return m3uplug_save_m3u (fname, first, last);
+ }
+ else if (!strcasecmp (e, ".pls")) {
+ return m3uplug_save_pls (fname, first, last);
+ }
+ return -1;
+}
+
+static const char * exts[] = { "m3u", "m3u8", "pls", NULL };
+DB_playlist_t plugin = {
+ DB_PLUGIN_SET_API_VERSION
+ .plugin.version_major = 1,
+ .plugin.version_minor = 0,
+ .plugin.type = DB_PLUGIN_PLAYLIST,
+ .plugin.id = "m3u",
+ .plugin.name = "M3U and PLS support",
+ .plugin.descr = "Importing and exporting M3U and PLS formats\nRecognizes .pls, .m3u and .m3u8 file types\n\nNOTE: only utf8 file names are currently supported",
+ .plugin.copyright =
+ "Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>\n"
+ "\n"
+ "This program is free software; you can redistribute it and/or\n"
+ "modify it under the terms of the GNU General Public License\n"
+ "as published by the Free Software Foundation; either version 2\n"
+ "of the License, or (at your option) any later version.\n"
+ "\n"
+ "This program is distributed in the hope that it will be useful,\n"
+ "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+ "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+ "GNU General Public License for more details.\n"
+ "\n"
+ "You should have received a copy of the GNU General Public License\n"
+ "along with this program; if not, write to the Free Software\n"
+ "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n"
+ ,
+ .plugin.website = "http://deadbeef.sf.net",
+ .load = m3uplug_load,
+ .save = m3uplug_save,
+ .extensions = exts,
+};
+
+DB_plugin_t *
+m3u_load (DB_functions_t *api) {
+ deadbeef = api;
+ return &plugin.plugin;
+}
diff --git a/plugins/mms/mmsplug.c b/plugins/mms/mmsplug.c
index 4ad57832..787af70d 100644
--- a/plugins/mms/mmsplug.c
+++ b/plugins/mms/mmsplug.c
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@@ -108,15 +108,42 @@ mms_get_content_type (DB_FILE *stream) {
static const char *scheme_names[] = { "mms://", "mmsh://", NULL };
+const char **
+mms_get_schemes (void) {
+ return scheme_names;
+}
+
+int
+mms_is_streaming (void) {
+ return 1;
+}
+
static DB_vfs_t plugin = {
DB_PLUGIN_SET_API_VERSION
- .plugin.version_major = 0,
- .plugin.version_minor = 1,
+ .plugin.version_major = 1,
+ .plugin.version_minor = 0,
.plugin.type = DB_PLUGIN_VFS,
.plugin.name = "mms vfs",
.plugin.descr = "MMS streaming plugin based on libmms",
- .plugin.author = "Alexey Yakovenko",
- .plugin.email = "waker@users.sourceforge.net",
+ .plugin.copyright =
+ "Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>\n"
+ "\n"
+ "Uses modified libmms-0.6.0, http://sourceforge.net/projects/libmms/\n"
+ "\n"
+ "This program is free software; you can redistribute it and/or\n"
+ "modify it under the terms of the GNU General Public License\n"
+ "as published by the Free Software Foundation; either version 2\n"
+ "of the License, or (at your option) any later version.\n"
+ "\n"
+ "This program is distributed in the hope that it will be useful,\n"
+ "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+ "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+ "GNU General Public License for more details.\n"
+ "\n"
+ "You should have received a copy of the GNU General Public License\n"
+ "along with this program; if not, write to the Free Software\n"
+ "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n"
+ ,
.plugin.website = "http://deadbeef.sf.net",
.open = mms_open,
.close = mms_close,
@@ -126,8 +153,8 @@ static DB_vfs_t plugin = {
.rewind = mms_rewind,
.getlength = mms_getlength,
.get_content_type = mms_get_content_type,
- .scheme_names = scheme_names,
- .streaming = 1
+ .get_schemes = mms_get_schemes,
+ .is_streaming = mms_is_streaming,
};
DB_plugin_t *
diff --git a/plugins/mpgmad/mpgmad.c b/plugins/mpgmad/mpgmad.c
index 13544238..3f8c4260 100644
--- a/plugins/mpgmad/mpgmad.c
+++ b/plugins/mpgmad/mpgmad.c
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -22,6 +22,7 @@
#include <stdlib.h>
#include <limits.h>
#include <unistd.h>
+#include <sys/time.h>
#include "../../deadbeef.h"
//#define trace(...) { fprintf(stderr, __VA_ARGS__); }
@@ -45,13 +46,15 @@ static DB_functions_t *deadbeef;
#define READBUFFER 0x2800 // 10k is enough for single frame
// vbrmethod constants
-#define LAME_CBR 1
-#define LAME_CBR2 8
-#define LAME_ABR 2
-#define LAME_VBR1 3
-#define LAME_VBR2 4
-#define LAME_VBR3 5
-#define LAME_VBR4 6
+#define XING_CBR 1
+#define XING_ABR 2
+#define XING_VBR1 3
+#define XING_VBR2 4
+#define XING_VBR3 5
+#define XING_VBR4 6
+#define XING_CBR2 8
+#define XING_ABR2 9
+#define DETECTED_VBR 100
// xing header flags
#define FRAMES_FLAG 0x0001
@@ -78,24 +81,34 @@ typedef struct {
int bitrate;
int samplerate;
int packetlength;
- float frameduration;
int bitspersample;
int channels;
float duration;
+
+ // currentsample and totalsamples are in the entire file scope (delay/padding inclusive)
int currentsample;
int totalsamples;
+
int skipsamples;
- int startoffset;
- int endoffset;
+
+ int startoffset; // in bytes (id3v2, xing/lame)
+ int endoffset; // in bytes (apev2, id3v1)
+
+ // startsample and endsample exclude delay/padding
int startsample;
int endsample;
- int startdelay;
- int enddelay;
- int avg_packetlength;
+
+ // number of samples to skip at the start/end of file
+ int delay;
+ int padding;
+
+ float avg_packetlength;
int avg_samplerate;
int avg_samples_per_frame;
int nframes;
int last_comment_update;
+ int vbr;
+ int have_xing_header;
} buffer_t;
typedef struct {
@@ -175,25 +188,29 @@ extract_f32 (unsigned char *buf) {
static int
cmp3_scan_stream (buffer_t *buffer, int sample) {
trace ("cmp3_scan_stream %d\n", sample);
+
int initpos = deadbeef->ftell (buffer->file);
trace ("initpos: %d\n", initpos);
-// if (sample == 0) {
-// sample = -1;
-// }
int packetlength = 0;
int nframe = 0;
- int got_xing_header = 0;
- buffer->duration = 0;
int scansamples = 0;
buffer->currentsample = 0;
buffer->skipsamples = 0;
- int fsize = 0;
- int avg_bitrate = 0;
+// int avg_bitrate = 0;
int valid_frames = 0;
+ int prev_bitrate = -1;
+ buffer->samplerate = 0;
+ int64_t fsize = deadbeef->fgetlength (buffer->file);
if (sample <= 0) {
buffer->totalsamples = 0;
- fsize = deadbeef->fgetlength (buffer->file) - initpos;
+ if (fsize > 0) {
+ fsize -= initpos;
+ if (fsize < 0) {
+ trace ("cmp3_scan_stream: invalid file: bad header\n");
+ return -1;
+ }
+ }
}
if (sample <= 0 && buffer->avg_packetlength == 0) {
buffer->avg_packetlength = 0;
@@ -204,37 +221,40 @@ cmp3_scan_stream (buffer_t *buffer, int sample) {
buffer->startoffset = initpos;
}
+ int lastframe_valid = 0;
+ int64_t offs = -1;
+
for (;;) {
- uint32_t hdr;
- uint8_t sync;
- //size_t pos = deadbeef->ftell (buffer->file);
- if (deadbeef->fread (&sync, 1, 1, buffer->file) != 1) {
+ if (!lastframe_valid && offs >= 0) {
+ deadbeef->fseek (buffer->file, offs+1, SEEK_SET);
+ }
+ offs = deadbeef->ftell (buffer->file);
+ uint8_t fb[4];
+ if (deadbeef->fread (fb, 1, 4, buffer->file) != 4) {
break; // eof
}
+
+ uint32_t hdr;
+ uint8_t sync = fb[0];
if (sync != 0xff) {
// trace ("[1]frame %d didn't seek to frame end\n", nframe);
+ lastframe_valid = 0;
continue; // not an mpeg frame
}
else {
// 2nd sync byte
- if (deadbeef->fread (&sync, 1, 1, buffer->file) != 1) {
- break; // eof
- }
+ sync = fb[1];
if ((sync >> 5) != 7) {
// trace ("[2]frame %d didn't seek to frame end\n", nframe);
+ lastframe_valid = 0;
continue;
}
}
// found frame
hdr = (0xff<<24) | (sync << 16);
- // read 2 bytes more
- if (deadbeef->fread (&sync, 1, 1, buffer->file) != 1) {
- break; // eof
- }
+ sync = fb[2];
hdr |= sync << 8;
- if (deadbeef->fread (&sync, 1, 1, buffer->file) != 1) {
- break; // eof
- }
+ sync = fb[3];
hdr |= sync;
// parse header
@@ -246,20 +266,22 @@ cmp3_scan_stream (buffer_t *buffer, int sample) {
}
// mpeg version
- static int vertbl[] = {3, -1, 2, 1}; // 3 is 2.5
+ static const int vertbl[] = {3, -1, 2, 1}; // 3 is 2.5
int ver = (hdr & (3<<19)) >> 19;
ver = vertbl[ver];
if (ver < 0) {
trace ("frame %d bad mpeg version %d\n", nframe, (hdr & (3<<19)) >> 19);
+ lastframe_valid = 0;
continue; // invalid frame
}
// layer info
- static int ltbl[] = { -1, 3, 2, 1 };
+ static const int ltbl[] = { -1, 3, 2, 1 };
int layer = (hdr & (3<<17)) >> 17;
layer = ltbl[layer];
if (layer < 0) {
trace ("frame %d bad layer %d\n", nframe, (hdr & (3<<17)) >> 17);
+ lastframe_valid = 0;
continue; // invalid frame
}
@@ -282,6 +304,7 @@ cmp3_scan_stream (buffer_t *buffer, int sample) {
bitrate = brtable[idx][bitrate];
if (bitrate <= 0) {
trace ("frame %d bad bitrate %d\n", nframe, (hdr & (0x0f<<12)) >> 12);
+ lastframe_valid = 0;
continue; // invalid frame
}
@@ -295,13 +318,14 @@ cmp3_scan_stream (buffer_t *buffer, int sample) {
samplerate = srtable[ver-1][samplerate];
if (samplerate < 0) {
trace ("frame %d bad samplerate %d\n", nframe, (hdr & (0x03<<10))>>10);
+ lastframe_valid = 0;
continue; // invalid frame
}
// padding
int padding = (hdr & (0x1 << 9)) >> 9;
- static int chantbl[4] = { 2, 2, 2, 1 };
+ static const int chantbl[4] = { 2, 2, 2, 1 };
int nchannels = (hdr & (0x3 << 6)) >> 6;
nchannels = chantbl[nchannels];
@@ -309,10 +333,12 @@ cmp3_scan_stream (buffer_t *buffer, int sample) {
if (layer == 2) {
if ((bitrate <= 56 || bitrate == 80) && nchannels != 1) {
trace ("mpgmad: bad frame %d: layer %d, channels %d, bitrate %d\n", nframe, layer, nchannels, bitrate);
+ lastframe_valid = 0;
continue; // bad frame
}
if (bitrate >= 224 && nchannels == 1) {
trace ("mpgmad: bad frame %d: layer %d, channels %d, bitrate %d\n", nframe, layer, nchannels, bitrate);
+ lastframe_valid = 0;
continue; // bad frame
}
}
@@ -320,34 +346,35 @@ cmp3_scan_stream (buffer_t *buffer, int sample) {
// packetlength
packetlength = 0;
bitrate *= 1000;
- float dur = 0;
int samples_per_frame = 0;
if (samplerate > 0 && bitrate > 0) {
if (layer == 1) {
samples_per_frame = 384;
- dur = (float)384 / samplerate;
}
else if (layer == 2) {
samples_per_frame = 1152;
- dur = (float)1152 / samplerate;
}
else if (layer == 3) {
if (ver == 1) {
samples_per_frame = 1152;
- dur = (float)1152 / samplerate;
}
else {
samples_per_frame = 576;
- dur = (float)576 / samplerate;
}
}
packetlength = samples_per_frame / 8 * bitrate / samplerate + padding;
}
else {
trace ("frame %d samplerate or bitrate is invalid\n", nframe);
+ lastframe_valid = 0;
continue;
}
+ if (!buffer->have_xing_header && prev_bitrate != -1 && prev_bitrate != bitrate) {
+ buffer->vbr = DETECTED_VBR;
+ }
+ prev_bitrate = bitrate;
+
valid_frames++;
#if 0
if (nframe < 1000) {
@@ -356,23 +383,26 @@ cmp3_scan_stream (buffer_t *buffer, int sample) {
#endif
if (sample != 0 || nframe == 0)
{
+ if (sample == 0 && lastframe_valid) {
+ return 0;
+ }
buffer->version = ver;
buffer->layer = layer;
buffer->bitrate = bitrate;
buffer->samplerate = samplerate;
buffer->packetlength = packetlength;
- buffer->frameduration = dur;
if (nchannels > buffer->channels) {
buffer->channels = nchannels;
}
buffer->bitspersample = 16;
- //trace ("frame %d mpeg v%d layer %d bitrate %d samplerate %d packetlength %d framedur %f channels %d\n", nframe, ver, layer, bitrate, samplerate, packetlength, dur, nchannels);
+ trace ("frame %d mpeg v%d layer %d bitrate %d samplerate %d packetlength %d channels %d\n", nframe, ver, layer, bitrate, samplerate, packetlength, nchannels);
}
+ lastframe_valid = 1;
// try to read xing/info tag (only on initial scans)
- if (sample <= 0 && !got_xing_header)
+ if (sample <= 0 && !buffer->have_xing_header)
{
size_t framepos = deadbeef->ftell (buffer->file);
- if (!buffer->file->vfs->streaming) {
+ if (!buffer->file->vfs->is_streaming ()) {
// trace ("trying to read xing header at pos %d\n", framepos);
if (ver == 1) {
deadbeef->fseek (buffer->file, 32, SEEK_CUR);
@@ -408,7 +438,9 @@ cmp3_scan_stream (buffer_t *buffer, int sample) {
return -1; // EOF
}
uint32_t nframes = extract_i32 (buf);
- buffer->duration = (float)nframes * (float)samples_per_frame / (float)samplerate;
+ if (sample == 0) {
+ buffer->duration = (((uint64_t)nframes * (uint64_t)samples_per_frame) - buffer->delay - buffer->padding)/ (uint64_t)samplerate;
+ }
trace ("xing totalsamples: %d, nframes: %d, samples_per_frame: %d\n", nframes*samples_per_frame, nframes, samples_per_frame);
if (nframes <= 0 || samples_per_frame <= 0) {
trace ("bad xing header\n");
@@ -432,9 +464,23 @@ cmp3_scan_stream (buffer_t *buffer, int sample) {
return -1; // EOF
}
// trace ("tell=%x, %c%c%c%c\n", deadbeef->ftell(buffer->file), buf[0], buf[1], buf[2], buf[3]);
+
+ deadbeef->fseek (buffer->file, 5, SEEK_CUR);
+ uint8_t rev = 0;
+ if (deadbeef->fread (&rev, 1, 1, buffer->file) != 1) {
+ trace ("cmp3_scan_stream: EOF while reading info tag revision / vbr method\n");
+ }
+ switch (rev & 0x0f) {
+ case XING_ABR ... XING_VBR4:
+ case XING_ABR2:
+ buffer->vbr = rev & 0x0f;
+ break;
+ default:
+ buffer->vbr = DETECTED_VBR;
+ break;
+ }
if (!memcmp (buf, "LAME", 4)) {
trace ("lame header found\n");
- deadbeef->fseek (buffer->file, 6, SEEK_CUR);
// FIXME: that can be optimized by single read
uint8_t lpf;
@@ -451,8 +497,8 @@ cmp3_scan_stream (buffer_t *buffer, int sample) {
// skip
deadbeef->fseek (buffer->file, 2, SEEK_CUR);
deadbeef->fread (buf, 1, 3, buffer->file);
- uint32_t startdelay = (((uint32_t)buf[0]) << 4) | ((((uint32_t)buf[1]) & 0xf0)>>4);
- uint32_t enddelay = ((((uint32_t)buf[1])&0x0f)<<8) | ((uint32_t)buf[2]);
+// buffer->delay = (((uint32_t)buf[0]) << 4) | ((((uint32_t)buf[1]) & 0xf0)>>4);
+// buffer->padding = ((((uint32_t)buf[1])&0x0f)<<8) | ((uint32_t)buf[2]);
// skip
deadbeef->fseek (buffer->file, 1, SEEK_CUR);
// mp3gain
@@ -464,43 +510,54 @@ cmp3_scan_stream (buffer_t *buffer, int sample) {
deadbeef->fread (buf, 1, 4, buffer->file);
// uint32_t musiclen = extract_i32 (buf);
- //trace ("lpf: %d, peaksignalamp: %f, radiogain: %d, audiophile: %d, startdelay: %d, enddelay: %d, mp3gain: %d, musiclen: %d\n", lpf, rg_peaksignalamp, rg_radio, rg_audiophile, startdelay, enddelay, mp3gain, musiclen);
+ //trace ("lpf: %d, peaksignalamp: %f, radiogain: %d, audiophile: %d, delay: %d, padding: %d, mp3gain: %d, musiclen: %d\n", lpf, rg_peaksignalamp, rg_radio, rg_audiophile, delay, padding, mp3gain, musiclen);
// skip crc
//deadbeef->fseek (buffer->file, 4, SEEK_CUR);
- buffer->startdelay = startdelay;
- buffer->enddelay = enddelay;
trace ("lame totalsamples: %d\n", buffer->totalsamples);
}
if (sample <= 0 && (flags&FRAMES_FLAG)) {
- buffer->totalsamples -= buffer->enddelay;
+ buffer->have_xing_header = 1;
deadbeef->fseek (buffer->file, framepos+packetlength-4, SEEK_SET);
- return 0;
+ if (fsize >= 0) {
+ buffer->bitrate = (fsize - deadbeef->ftell (buffer->file))/ buffer->samplerate * 1000;
+ }
+ buffer->startoffset = deadbeef->ftell (buffer->file);
}
}
}
if (sample == 0) {
- // xing header failed, calculate based on file size
-// trace ("xing header failed\n");
+ trace ("cmp3_scan_stream: trying to figure out duration from file size\n");
buffer->samplerate = samplerate;
- if (buffer->file->vfs->streaming) {
+ if (buffer->file->vfs->is_streaming ()) {
// only suitable for cbr files, used if streaming
- int sz = deadbeef->fgetlength (buffer->file) - buffer->startoffset - buffer->endoffset;
+ int sz = deadbeef->fgetlength (buffer->file);
+ if (sz > 0) {
+ sz -= buffer->startoffset + buffer->endoffset;
+ if (sz < 0) {
+ trace ("cmp3_scan_stream: bad file headers\n");
+ return -1;
+ }
+ }
if (sz < 0) {
// unable to determine duration
buffer->duration = -1;
buffer->totalsamples = -1;
if (sample == 0) {
- deadbeef->fseek (buffer->file, framepos/*+packetlength-4*/, SEEK_SET);
+ trace ("check validity of the next frame...\n");
+ deadbeef->fseek (buffer->file, framepos+packetlength-4, SEEK_SET);
+ continue;
}
+ trace ("cmp3_scan_stream: unable to determine duration");
return 0;
}
buffer->nframes = sz / packetlength;
buffer->avg_packetlength = packetlength;
buffer->avg_samplerate = samplerate;
buffer->avg_samples_per_frame = samples_per_frame;
- buffer->duration = buffer->nframes * samples_per_frame / samplerate;
+ buffer->duration = (buffer->nframes * samples_per_frame - buffer->delay - buffer->padding) / samplerate;
buffer->totalsamples = buffer->nframes * samples_per_frame;
-// trace ("bitrate=%d, layer=%d, packetlength=%d, fsize=%d, nframes=%d, samples_per_frame=%d, samplerate=%d, duration=%f, totalsamples=%d\n", bitrate, layer, packetlength, sz, nframes, samples_per_frame, samplerate, buffer->duration, buffer->totalsamples);
+ trace ("totalsamples: %d, samplesperframe: %d, fsize=%lld\n", buffer->totalsamples, samples_per_frame, fsize);
+// trace ("bitrate=%d, layer=%d, packetlength=%d, fsize=%d, nframes=%d, samples_per_frame=%d, samplerate=%d, duration=%f, totalsamples=%d\n", bitrate, layer, packetlength, sz, nframe, samples_per_frame, samplerate, buffer->duration, buffer->totalsamples);
if (sample == 0) {
deadbeef->fseek (buffer->file, framepos/*+packetlength-4*/, SEEK_SET);
@@ -513,7 +570,7 @@ cmp3_scan_stream (buffer_t *buffer, int sample) {
}
else {
deadbeef->fseek (buffer->file, framepos+packetlength-4, SEEK_SET);
- got_xing_header = 1;
+ buffer->have_xing_header = 1;
}
}
@@ -526,18 +583,9 @@ cmp3_scan_stream (buffer_t *buffer, int sample) {
buffer->avg_packetlength += packetlength;
buffer->avg_samplerate += samplerate;
buffer->avg_samples_per_frame += samples_per_frame;
- avg_bitrate += bitrate;
+ //avg_bitrate += bitrate;
if (nframe >= 100) {
- buffer->avg_packetlength /= valid_frames;
- buffer->avg_samplerate /= valid_frames;
- buffer->avg_samples_per_frame /= valid_frames;
- avg_bitrate /= valid_frames;
- trace ("valid_frames=%d, avg_bitrate=%d, avg_packetlength=%d, avg_samplerate=%d, avg_samples_per_frame=%d\n", valid_frames, avg_bitrate, buffer->avg_packetlength, buffer->avg_samplerate, buffer->avg_samples_per_frame);
-
- buffer->nframes = fsize / buffer->avg_packetlength;
- buffer->duration = buffer->nframes * buffer->avg_samples_per_frame / buffer->avg_samplerate;
- buffer->totalsamples = buffer->nframes * buffer->avg_samples_per_frame;
- return 0;
+ goto end_scan;
}
}
else {
@@ -549,37 +597,133 @@ cmp3_scan_stream (buffer_t *buffer, int sample) {
}
}
scansamples += samples_per_frame;
- buffer->duration += dur;
nframe++;
if (packetlength > 0) {
deadbeef->fseek (buffer->file, packetlength-4, SEEK_CUR);
}
}
+end_scan:
if (nframe == 0) {
trace ("cmp3_scan_stream: couldn't find mpeg frames in file\n");
return -1;
}
+ if (sample == 0) {
+ buffer->avg_packetlength /= (float)valid_frames;
+ buffer->avg_samplerate /= valid_frames;
+ buffer->avg_samples_per_frame /= valid_frames;
+// avg_bitrate /= valid_frames;
+ //trace ("valid_frames=%d, avg_bitrate=%d, avg_packetlength=%f, avg_samplerate=%d, avg_samples_per_frame=%d\n", valid_frames, avg_bitrate, buffer->avg_packetlength, buffer->avg_samplerate, buffer->avg_samples_per_frame);
+ trace ("startoffs: %d, endoffs: %d\n", buffer->startoffset, buffer->endoffset);
+
+ buffer->nframes = (fsize - buffer->startoffset - buffer->endoffset) / buffer->avg_packetlength;
+ if (!buffer->have_xing_header) {
+ buffer->totalsamples = buffer->nframes * buffer->avg_samples_per_frame;
+ buffer->duration = (buffer->totalsamples - buffer->delay - buffer->padding) / buffer->avg_samplerate;
+ }
+ buffer->bitrate = (fsize-buffer->startoffset-buffer->endoffset) / buffer->duration * 8;
+ trace ("nframes: %d, fsize: %lld, spf: %d, smp: %d, totalsamples: %d\n", buffer->nframes, fsize, buffer->avg_samples_per_frame, buffer->avg_samplerate, buffer->totalsamples);
+ return 0;
+ }
+
buffer->totalsamples = scansamples;
-// buffer->duration = buffer->totalsamples / buffer->samplerate;
+ buffer->duration = (buffer->totalsamples - buffer->delay - buffer->padding) / buffer->samplerate;
trace ("nframes=%d, totalsamples=%d, samplerate=%d, dur=%f\n", nframe, scansamples, buffer->samplerate, buffer->duration);
return 0;
}
+int
+cmp3_seek_stream (DB_fileinfo_t *_info, int sample) {
+ mpgmad_info_t *info = (mpgmad_info_t *)_info;
+ sample += info->buffer.delay;
+ if (sample == 0) {
+ _info->readpos = 0;
+ info->buffer.currentsample = 0;
+ return 0;
+
+ }
+ return cmp3_scan_stream (&info->buffer, sample);
+}
+
static DB_fileinfo_t *
-cmp3_open (void) {
+cmp3_open (uint32_t hints) {
DB_fileinfo_t *_info = malloc (sizeof (mpgmad_info_t));
mpgmad_info_t *info = (mpgmad_info_t *)_info;
memset (info, 0, sizeof (mpgmad_info_t));
return _info;
}
+void
+cmp3_set_extra_properties (buffer_t *buffer) {
+ char s[100];
+ int64_t size = deadbeef->fgetlength (buffer->file);
+ if (size >= 0) {
+ snprintf (s, sizeof (s), "%lld", size);
+ deadbeef->pl_replace_meta (buffer->it, ":FILE_SIZE", s);
+ }
+ else {
+ deadbeef->pl_replace_meta (buffer->it, ":FILE_SIZE", "∞");
+ }
+ if (buffer->bitrate > 0) {
+ snprintf (s, sizeof (s), "%d", buffer->bitrate/1000);
+ deadbeef->pl_replace_meta (buffer->it, ":BITRATE", s);
+ }
+ deadbeef->pl_replace_meta (buffer->it, ":BPS", "16");
+ snprintf (s, sizeof (s), "%d", buffer->channels);
+ deadbeef->pl_replace_meta (buffer->it, ":CHANNELS", s);
+ snprintf (s, sizeof (s), "%d", buffer->samplerate);
+ deadbeef->pl_replace_meta (buffer->it, ":SAMPLERATE", s);
+
+ // set codec profile (cbr or vbr) and mp3 vbr method (guessed, or from Xing/Info header)
+
+ switch (buffer->vbr) {
+ case XING_ABR:
+ deadbeef->pl_replace_meta (buffer->it, ":CODEC_PROFILE", "VBR");
+ deadbeef->pl_replace_meta (buffer->it, ":MP3_VBR_METHOD", "ABR");
+ break;
+ case XING_VBR1:
+ deadbeef->pl_replace_meta (buffer->it, ":CODEC_PROFILE", "VBR");
+ deadbeef->pl_replace_meta (buffer->it, ":MP3_VBR_METHOD", "full VBR method 1");
+ break;
+ case XING_VBR2:
+ deadbeef->pl_replace_meta (buffer->it, ":CODEC_PROFILE", "VBR");
+ deadbeef->pl_replace_meta (buffer->it, ":MP3_VBR_METHOD", "full VBR method 2");
+ break;
+ case XING_VBR3:
+ deadbeef->pl_replace_meta (buffer->it, ":CODEC_PROFILE", "VBR");
+ deadbeef->pl_replace_meta (buffer->it, ":MP3_VBR_METHOD", "full VBR method 3");
+ break;
+ case XING_VBR4:
+ deadbeef->pl_replace_meta (buffer->it, ":CODEC_PROFILE", "VBR");
+ deadbeef->pl_replace_meta (buffer->it, ":MP3_VBR_METHOD", "full VBR method 4");
+ break;
+ case XING_CBR2:
+ deadbeef->pl_replace_meta (buffer->it, ":CODEC_PROFILE", "CBR");
+ break;
+ case XING_ABR2:
+ deadbeef->pl_replace_meta (buffer->it, ":CODEC_PROFILE", "VBR");
+ deadbeef->pl_replace_meta (buffer->it, ":MP3_VBR_METHOD", "ABR 2 pass");
+ break;
+ case DETECTED_VBR:
+ deadbeef->pl_replace_meta (buffer->it, ":CODEC_PROFILE", "VBR");
+ deadbeef->pl_replace_meta (buffer->it, ":MP3_VBR_METHOD", "unspecified");
+ break;
+ default:
+ deadbeef->pl_replace_meta (buffer->it, ":CODEC_PROFILE", "CBR");
+ break;
+ }
+ const char *versions[] = {"1", "2", "2.5"};
+ snprintf (s, sizeof (s), "MPEG%s layer%d", versions[buffer->version-1], buffer->layer);
+ deadbeef->pl_replace_meta (buffer->it, ":MPEG_VERSION", s);
+ deadbeef->pl_replace_meta (buffer->it, ":XING_HEADER", buffer->have_xing_header ? "Yes" : "No");
+}
+
static int
cmp3_init (DB_fileinfo_t *_info, DB_playItem_t *it) {
mpgmad_info_t *info = (mpgmad_info_t *)_info;
_info->plugin = &plugin;
memset (&info->buffer, 0, sizeof (info->buffer));
- info->buffer.file = deadbeef->fopen (it->fname);
+ info->buffer.file = deadbeef->fopen (deadbeef->pl_find_meta (it, ":URI"));
if (!info->buffer.file) {
return -1;
}
@@ -587,33 +731,35 @@ cmp3_init (DB_fileinfo_t *_info, DB_playItem_t *it) {
deadbeef->pl_item_ref (it);
info->buffer.it = it;
info->info.readpos = 0;
- if (!info->buffer.file->vfs->streaming) {
+ if (!info->buffer.file->vfs->is_streaming ()) {
int skip = deadbeef->junk_get_leading_size (info->buffer.file);
if (skip > 0) {
trace ("mpgmad: skipping %d(%xH) bytes of junk\n", skip, skip);
deadbeef->fseek (info->buffer.file, skip, SEEK_SET);
}
- cmp3_scan_stream (&info->buffer, -1); // scan entire stream, calc duration
+ int res = cmp3_scan_stream (&info->buffer, -1);
+ if (res < 0) {
+ trace ("mpgmad: cmp3_init: initial cmp3_scan_stream failed\n");
+ return -1;
+ }
if (it->endsample > 0) {
info->buffer.startsample = it->startsample;
info->buffer.endsample = it->endsample;
// that comes from cue, don't calc duration, just seek and play
- plugin.seek_sample (_info, 0);
}
else {
deadbeef->pl_set_item_duration (it, info->buffer.duration);
info->buffer.startsample = 0;
- info->buffer.endsample = info->buffer.totalsamples-1;
- info->buffer.skipsamples = info->buffer.startdelay;
- info->buffer.currentsample = info->buffer.startdelay;
+ info->buffer.endsample = info->buffer.totalsamples-info->buffer.delay-info->buffer.padding;
trace ("mpgmad: seeking to %d(%xH) start offset\n", info->buffer.startoffset, info->buffer.startoffset);
deadbeef->fseek (info->buffer.file, info->buffer.startoffset, SEEK_SET);
}
+ plugin.seek_sample (_info, 0);
}
else {
deadbeef->fset_track (info->buffer.file, it);
- info->buffer.it->filetype = NULL;
- int len = deadbeef->fgetlength (info->buffer.file);
+ deadbeef->pl_delete_meta (info->buffer.it, ":FILETYPE");
+ int64_t len = deadbeef->fgetlength (info->buffer.file);
if (len > 0) {
deadbeef->pl_delete_all_meta (it);
int v2err = deadbeef->junk_id3v2_read (it, info->buffer.file);
@@ -627,6 +773,10 @@ cmp3_init (DB_fileinfo_t *_info, DB_playItem_t *it) {
trace ("mpgmad: cmp3_init: initial cmp3_scan_stream failed\n");
return -1;
}
+ deadbeef->fseek (info->buffer.file, 0, SEEK_SET);
+
+ cmp3_set_extra_properties (&info->buffer);
+
deadbeef->pl_set_item_duration (it, info->buffer.duration);
if (info->buffer.duration >= 0) {
info->buffer.endsample = info->buffer.totalsamples - 1;
@@ -648,12 +798,14 @@ cmp3_init (DB_fileinfo_t *_info, DB_playItem_t *it) {
trace ("duration=%f, endsample=%d, totalsamples=%d\n", info->buffer.duration, info->buffer.endsample, info->buffer.totalsamples);
}
if (info->buffer.samplerate == 0) {
- trace ("bad mpeg file: %f\n", it->fname);
+ trace ("bad mpeg file: %f\n", deadbeef->pl_find_meta (it, ":URI"));
return -1;
}
- _info->bps = info->buffer.bitspersample;
- _info->samplerate = info->buffer.samplerate;
- _info->channels = info->buffer.channels;
+ _info->fmt.bps = info->buffer.bitspersample;
+ _info->fmt.samplerate = info->buffer.samplerate;
+ _info->fmt.channels = info->buffer.channels;
+ _info->fmt.channelmask = _info->fmt.channels == 1 ? DDB_SPEAKER_FRONT_LEFT : (DDB_SPEAKER_FRONT_LEFT | DDB_SPEAKER_FRONT_RIGHT);
+ trace ("mp3 format: bps:%d sr:%d channels:%d\n", _info->fmt.bps, _info->fmt.samplerate, _info->fmt.channels);
mad_stream_init(&info->stream);
mad_stream_options (&info->stream, MAD_OPTION_IGNORECRC);
@@ -716,14 +868,6 @@ cmp3_decode_cut (mpgmad_info_t *info, int framesize) {
trace ("mpgmad: got frame with invalid number of channels (%d)\n", info->buffer.channels);
return 1;
}
- if (info->buffer.currentsample + info->buffer.readsize / (framesize * info->buffer.channels) > info->buffer.endsample) {
- int sz = (info->buffer.endsample - info->buffer.currentsample + 1) * framesize * info->buffer.channels;
- trace ("size truncated to %d bytes, cursample=%d, endsample=%d, totalsamples=%d\n", info->buffer.readsize, info->buffer.currentsample, info->buffer.endsample, info->buffer.totalsamples);
- if (sz <= 0) {
- return 1;
- }
- info->buffer.readsize = sz;
- }
}
return 0;
}
@@ -732,6 +876,7 @@ static inline void
cmp3_skip (mpgmad_info_t *info) {
if (info->buffer.skipsamples > 0) {
int skip = min (info->buffer.skipsamples, info->buffer.decode_remaining);
+// printf ("skip %d / %d\n", skip, info->buffer.skipsamples);
info->buffer.skipsamples -= skip;
info->buffer.decode_remaining -= skip;
}
@@ -743,23 +888,43 @@ cmp3_decode_requested_int16 (mpgmad_info_t *info) {
cmp3_skip (info);
// copy synthesized samples into readbuffer
int idx = info->synth.pcm.length-info->buffer.decode_remaining;
- while (info->buffer.decode_remaining > 0 && info->buffer.readsize > 0) {
- int16_t sample = MadFixedToSshort (info->synth.pcm.samples[0][idx]);
- *((int16_t*)info->buffer.out) = sample;
- info->buffer.readsize -= 2;
- info->buffer.out += 2;
- if (MAD_NCHANNELS(&info->frame.header) == 2 && info->info.channels == 2) {
+
+ // stereo
+ if (MAD_NCHANNELS(&info->frame.header) == 2 && info->info.fmt.channels == 2) {
+ while (info->buffer.decode_remaining > 0 && info->buffer.readsize > 0) {
+ *((int16_t*)info->buffer.out) = MadFixedToSshort (info->synth.pcm.samples[0][idx]);
+ info->buffer.readsize -= 2;
+ info->buffer.out += 2;
*((int16_t*)info->buffer.out) = MadFixedToSshort (info->synth.pcm.samples[1][idx]);
info->buffer.readsize -= 2;
info->buffer.out += 2;
+ info->buffer.decode_remaining--;
+ idx++;
}
- else if (MAD_NCHANNELS(&info->frame.header) == 1 && info->info.channels == 2) {
+ }
+ // mono
+ else if (MAD_NCHANNELS(&info->frame.header) == 1 && info->info.fmt.channels == 1){
+ while (info->buffer.decode_remaining > 0 && info->buffer.readsize > 0) {
+ *((int16_t*)info->buffer.out) = MadFixedToSshort (info->synth.pcm.samples[0][idx]);
+ info->buffer.readsize -= 2;
+ info->buffer.out += 2;
+ info->buffer.decode_remaining--;
+ idx++;
+ }
+ }
+ // workaround for bad mp3s that have both mono and stereo frames
+ else if (MAD_NCHANNELS(&info->frame.header) == 1 && info->info.fmt.channels == 2) {
+ while (info->buffer.decode_remaining > 0 && info->buffer.readsize > 0) {
+ int16_t sample = MadFixedToSshort (info->synth.pcm.samples[0][idx]);
*((int16_t*)info->buffer.out) = sample;
info->buffer.readsize -= 2;
info->buffer.out += 2;
+ *((int16_t*)info->buffer.out) = sample;
+ info->buffer.readsize -= 2;
+ info->buffer.out += 2;
+ info->buffer.decode_remaining--;
+ idx++;
}
- info->buffer.decode_remaining--;
- idx++;
}
assert (info->buffer.readsize >= 0);
}
@@ -775,12 +940,12 @@ cmp3_decode_requested_float32 (mpgmad_info_t *info) {
*((float*)info->buffer.out) = sample;
info->buffer.readsize -= 4;
info->buffer.out += 4;
- if (MAD_NCHANNELS(&info->frame.header) == 2 && info->info.channels == 2) {
+ if (MAD_NCHANNELS(&info->frame.header) == 2 && info->info.fmt.channels == 2) {
*((float*)info->buffer.out) = MadFixedToFloat (info->synth.pcm.samples[1][idx]);
info->buffer.readsize -= 4;
info->buffer.out += 4;
}
- else if (MAD_NCHANNELS(&info->frame.header) == 1 && info->info.channels == 2) {
+ else if (MAD_NCHANNELS(&info->frame.header) == 1 && info->info.fmt.channels == 2) {
*((float*)info->buffer.out) = sample;
info->buffer.readsize -= 4;
info->buffer.out += 4;
@@ -834,41 +999,43 @@ cmp3_stream_frame (mpgmad_info_t *info) {
}
}
info->stream.error=0;
+
// decode next frame
if(mad_frame_decode(&info->frame,&info->stream))
{
if(MAD_RECOVERABLE(info->stream.error))
{
if(info->stream.error!=MAD_ERROR_LOSTSYNC) {
- trace ("mpgmad: recoverable frame level error (%s)\n", MadErrorString(&info->stream));
+ //trace ("mpgmad: recoverable frame level error (%s)\n", MadErrorString(&info->stream));
}
continue;
}
else {
if(info->stream.error==MAD_ERROR_BUFLEN) {
- trace ("mpgmad: recoverable frame level error (%s)\n", MadErrorString(&info->stream));
+ //trace ("mpgmad: recoverable frame level error (%s)\n", MadErrorString(&info->stream));
continue;
}
else
{
- trace ("mpgmad: unrecoverable frame level error (%s).\n", MadErrorString(&info->stream));
+ //trace ("mpgmad: unrecoverable frame level error (%s).\n", MadErrorString(&info->stream));
return -1; // fatal error
}
}
}
- if (!info->buffer.it->filetype) {
- int layer = info->frame.header.layer;
- if (layer >= 1 && layer <= 3) {
- info->buffer.it->filetype = plugin.filetypes[layer-1];
- }
- }
+// const char *filetype = deadbeef->pl_find_meta (info->buffer.it, ":FILETYPE");
+// if (!filetype) {
+// int layer = info->frame.header.layer;
+// if (layer >= 1 && layer <= 3) {
+// deadbeef->pl_replace_meta (info->buffer.it, ":FILETYPE", plugin.filetypes[layer-1]);
+// }
+// }
- info->info.samplerate = info->frame.header.samplerate;
+ info->info.fmt.samplerate = info->frame.header.samplerate;
#if 0
// don't switch number of channels on the fly
- if (info->info.channels == 0) {
- info->info.channels = MAD_NCHANNELS(&info->frame.header);
+ if (info->info.fmt.channels == 0) {
+ info->info.fmt.channels = MAD_NCHANNELS(&info->frame.header);
}
#endif
@@ -937,36 +1104,36 @@ cmp3_free (DB_fileinfo_t *_info) {
}
static int
-cmp3_read_int16 (DB_fileinfo_t *_info, char *bytes, int size) {
+cmp3_read (DB_fileinfo_t *_info, char *bytes, int size) {
#if WRITE_DUMP
if (!out) {
out = fopen ("out.raw", "w+b");
}
#endif
mpgmad_info_t *info = (mpgmad_info_t *)_info;
+ if (info->buffer.duration >= 0) {
+ int samplesize = _info->fmt.channels * _info->fmt.bps / 8;
+ int curr = info->buffer.currentsample - info->buffer.delay;
+ if (size / samplesize + curr > info->buffer.endsample) {
+ size = (info->buffer.endsample - curr + 1) * samplesize;
+ trace ("mp3: size truncated to %d bytes (%d samples), cursample=%d, endsample=%d\n", size, info->buffer.endsample - curr + 1, curr, info->buffer.endsample);
+ if (size <= 0) {
+ return 0;
+ }
+ }
+ }
+ int initsize = size;
info->buffer.readsize = size;
info->buffer.out = bytes;
cmp3_decode_int16 (info);
info->buffer.currentsample += (size - info->buffer.readsize) / 4;
- _info->readpos = (float)(info->buffer.currentsample - info->buffer.startsample) / info->buffer.samplerate;
+ _info->readpos = (float)(info->buffer.currentsample - info->buffer.delay - info->buffer.startsample) / info->buffer.samplerate;
#if WRITE_DUMP
if (size - info->buffer.readsize > 0) {
fwrite (bytes, 1, size - info->buffer.readsize, out);
}
#endif
- return size - info->buffer.readsize;
-}
-
-static int
-cmp3_read_float32 (DB_fileinfo_t *_info, char *bytes, int size) {
- mpgmad_info_t *info = (mpgmad_info_t *)_info;
-// trace ("cmp3_read_float32 readsize=%d, nchannels=%d\n", size, _info->channels);
- info->buffer.readsize = size;
- info->buffer.out = bytes;
- cmp3_decode_float32 (info);
- info->buffer.currentsample += (size - info->buffer.readsize) / 8;
- _info->readpos = (float)(info->buffer.currentsample - info->buffer.startsample) / info->buffer.samplerate;
- return size - info->buffer.readsize;
+ return initsize - info->buffer.readsize;
}
static int
@@ -976,23 +1143,22 @@ cmp3_seek_sample (DB_fileinfo_t *_info, int sample) {
return -1;
}
- if (info->buffer.file->vfs->streaming) {
- if (info->buffer.totalsamples > 0 && info->buffer.avg_samples_per_frame && info->buffer.avg_packetlength) { // that means seekable remote stream, like podcast
+ if (info->buffer.file->vfs->is_streaming ()) {
+ if (info->buffer.totalsamples > 0 && info->buffer.avg_samples_per_frame > 0 && info->buffer.avg_packetlength > 0) { // that means seekable remote stream, like podcast
trace ("seeking is possible!\n");
// get length excluding id3v2
- int64_t l = deadbeef->fgetlength (info->buffer.file) - info->buffer.startoffset;
+ int64_t l = deadbeef->fgetlength (info->buffer.file) - info->buffer.startoffset - info->buffer.endoffset;
int r;
// seek to beginning of the frame
- int frm = sample / info->buffer.avg_samples_per_frame;
- r = deadbeef->fseek (info->buffer.file, frm * info->buffer.avg_packetlength, SEEK_SET);
+ int64_t frm = sample / info->buffer.avg_samples_per_frame;
+ r = deadbeef->fseek (info->buffer.file, frm * info->buffer.avg_packetlength + info->buffer.startoffset, SEEK_SET);
// l = l * sample / buffer.totalsamples;
// r = deadbeef->fseek (buffer.file, l, SEEK_SET);
if (!r) {
- trace ("seek successful!\n");
info->buffer.skipsamples = sample - frm * info->buffer.avg_samples_per_frame;
info->buffer.currentsample = sample;
@@ -1018,17 +1184,14 @@ cmp3_seek_sample (DB_fileinfo_t *_info, int sample) {
return 0;
}
- sample += info->buffer.startsample + info->buffer.startdelay;
+ sample += info->buffer.startsample;
+// sample += info->buffer.delay;
if (sample > info->buffer.endsample) {
trace ("seek sample %d is beyond end of track (%d)\n", sample, info->buffer.endsample);
return -1; // eof
}
// restart file, and load until we hit required pos
- deadbeef->fseek (info->buffer.file, 0, SEEK_SET);
- int skip = deadbeef->junk_get_leading_size (info->buffer.file);
- if (skip > 0) {
- deadbeef->fseek (info->buffer.file, skip, SEEK_SET);
- }
+ deadbeef->fseek (info->buffer.file, info->buffer.startoffset, SEEK_SET);
mad_synth_finish (&info->synth);
mad_frame_finish (&info->frame);
mad_stream_finish (&info->stream);
@@ -1036,23 +1199,23 @@ cmp3_seek_sample (DB_fileinfo_t *_info, int sample) {
info->buffer.readsize = 0;
info->buffer.decode_remaining = 0;
- if (sample == 0) {
- _info->readpos = 0;
- info->buffer.currentsample = 0;
- info->buffer.skipsamples = info->buffer.startdelay;
- return 0;
- }
-
- if (cmp3_scan_stream (&info->buffer, sample) == -1) {
+// struct timeval tm1;
+// gettimeofday (&tm1, NULL);
+ if (cmp3_seek_stream (_info, sample) == -1) {
trace ("failed to seek to sample %d\n", sample);
_info->readpos = 0;
return -1;
}
+// struct timeval tm2;
+// gettimeofday (&tm2, NULL);
+// int ms = (tm2.tv_sec*1000+tm2.tv_usec/1000) - (tm1.tv_sec*1000+tm1.tv_usec/1000);
+// printf ("cmp3_scan_stream took %d ms\n", ms);
mad_stream_init(&info->stream);
mad_stream_options (&info->stream, MAD_OPTION_IGNORECRC);
mad_frame_init(&info->frame);
mad_synth_init(&info->synth);
- _info->readpos = (float)(info->buffer.currentsample - info->buffer.startsample) / info->buffer.samplerate;
+ trace ("seeked to %d\n", info->buffer.currentsample-info->buffer.delay);
+ _info->readpos = (float)(info->buffer.currentsample - info->buffer.delay - info->buffer.startsample) / info->buffer.samplerate;
return 0;
}
@@ -1075,14 +1238,11 @@ cmp3_insert (DB_playItem_t *after, const char *fname) {
trace ("failed to open file %s\n", fname);
return NULL;
}
- if (fp->vfs->streaming) {
- DB_playItem_t *it = deadbeef->pl_item_alloc ();
- it->decoder_id = deadbeef->plug_get_decoder_id (plugin.plugin.id);
- it->fname = strdup (fname);
+ if (fp->vfs->is_streaming ()) {
+ DB_playItem_t *it = deadbeef->pl_item_alloc_init (fname, plugin.plugin.id);
deadbeef->fclose (fp);
deadbeef->pl_add_meta (it, "title", NULL);
deadbeef->pl_set_item_duration (it, -1);
- it->filetype = NULL;//filetypes[0];
after = deadbeef->pl_insert_item (after, it);
deadbeef->pl_item_unref (it);
return after;
@@ -1143,9 +1303,7 @@ cmp3_insert (DB_playItem_t *after, const char *fname) {
break;
}
}
- DB_playItem_t *it = deadbeef->pl_item_alloc ();
- it->decoder_id = deadbeef->plug_get_decoder_id (plugin.plugin.id);
- it->fname = strdup (fname);
+ DB_playItem_t *it = deadbeef->pl_item_alloc_init (fname, plugin.plugin.id);
deadbeef->rewind (fp);
// reset tags
@@ -1155,13 +1313,18 @@ cmp3_insert (DB_playItem_t *after, const char *fname) {
/*int apeerr = */deadbeef->junk_apev2_read (it, fp);
/*int v2err = */deadbeef->junk_id3v2_read (it, fp);
/*int v1err = */deadbeef->junk_id3v1_read (it, fp);
- deadbeef->pl_add_meta (it, "title", NULL);
+ deadbeef->pl_set_meta_int (it, ":MP3_DELAY", buffer.delay);
+ deadbeef->pl_set_meta_int (it, ":MP3_PADDING", buffer.padding);
+
+ buffer.it = it;
+ cmp3_set_extra_properties (&buffer);
+
deadbeef->pl_set_item_duration (it, buffer.duration);
- it->filetype = ftype;
+ deadbeef->pl_replace_meta (it, ":FILETYPE", ftype);
deadbeef->fclose (fp);
// FIXME! bad numsamples passed to cue
- DB_playItem_t *cue_after = deadbeef->pl_insert_cue (after, it, buffer.duration*buffer.samplerate, buffer.samplerate);
+ DB_playItem_t *cue_after = deadbeef->pl_insert_cue (after, it, buffer.totalsamples-buffer.delay-buffer.padding, buffer.samplerate);
if (cue_after) {
deadbeef->pl_item_unref (it);
deadbeef->pl_item_unref (cue_after);
@@ -1175,7 +1338,7 @@ cmp3_insert (DB_playItem_t *after, const char *fname) {
int
cmp3_read_metadata (DB_playItem_t *it) {
- DB_FILE *fp = deadbeef->fopen (it->fname);
+ DB_FILE *fp = deadbeef->fopen (deadbeef->pl_find_meta (it, ":URI"));
if (!fp) {
return -1;
}
@@ -1223,7 +1386,8 @@ cmp3_write_metadata (DB_playItem_t *it) {
if (id3v2_version != 3 && id3v2_version != 4) {
id3v2_version = 3;
}
- const char *id3v1_encoding = deadbeef->conf_get_str ("mp3.id3v1_encoding", "iso8859-1");
+ char id3v1_encoding[50];
+ deadbeef->conf_get_str ("mp3.id3v1_encoding", "iso8859-1", id3v1_encoding, sizeof (id3v1_encoding));
return deadbeef->junk_rewrite_tags (it, junk_flags, id3v2_version, id3v1_encoding);
}
@@ -1234,20 +1398,34 @@ static const char *exts[] = {
// define plugin interface
static DB_decoder_t plugin = {
DB_PLUGIN_SET_API_VERSION
- .plugin.version_major = 0,
- .plugin.version_minor = 1,
+ .plugin.version_major = 1,
+ .plugin.version_minor = 0,
.plugin.type = DB_PLUGIN_DECODER,
.plugin.id = "stdmpg",
.plugin.name = "MPEG decoder",
.plugin.descr = "MPEG v1/2 layer1/2/3 decoder based on libmad",
- .plugin.author = "Alexey Yakovenko",
- .plugin.email = "waker@users.sourceforge.net",
+ .plugin.copyright =
+ "Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>\n"
+ "\n"
+ "This program is free software; you can redistribute it and/or\n"
+ "modify it under the terms of the GNU General Public License\n"
+ "as published by the Free Software Foundation; either version 2\n"
+ "of the License, or (at your option) any later version.\n"
+ "\n"
+ "This program is distributed in the hope that it will be useful,\n"
+ "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+ "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+ "GNU General Public License for more details.\n"
+ "\n"
+ "You should have received a copy of the GNU General Public License\n"
+ "along with this program; if not, write to the Free Software\n"
+ "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n"
+ ,
.plugin.website = "http://deadbeef.sf.net",
.open = cmp3_open,
.init = cmp3_init,
.free = cmp3_free,
- .read_int16 = cmp3_read_int16,
- .read_float32 = cmp3_read_float32,
+ .read = cmp3_read,
.seek = cmp3_seek,
.seek_sample = cmp3_seek_sample,
.insert = cmp3_insert,
diff --git a/plugins/musepack/Makefile.am b/plugins/musepack/Makefile.am
index 213fee32..c82490aa 100644
--- a/plugins/musepack/Makefile.am
+++ b/plugins/musepack/Makefile.am
@@ -27,6 +27,6 @@ mpc/minimax.h
musepack_la_LDFLAGS = -module
musepack_la_LIBADD = $(LDADD) -lm
-AM_CFLAGS = $(CFLAGS) -fPIC
+AM_CFLAGS = $(CFLAGS) -fPIC -std=c99
endif
diff --git a/plugins/musepack/mpc_decoder.c b/plugins/musepack/mpc_decoder.c
index a7732bf2..952789fd 100644
--- a/plugins/musepack/mpc_decoder.c
+++ b/plugins/musepack/mpc_decoder.c
@@ -650,11 +650,11 @@ void mpc_decoder_read_bitstream_sv8(mpc_decoder * d, mpc_bits_reader * r, mpc_bo
for ( ; k < 36; k += 2 ) {
union {
mpc_int8_t sym;
- struct { mpc_int8_t s1:4, s2:4; };
+ struct { mpc_int8_t s1:4, s2:4; } symf;
} tmp;
tmp.sym = mpc_bits_can_dec(r, Table);
- q[k] = tmp.s1;
- q[k + 1] = tmp.s2;
+ q[k] = tmp.symf.s1;
+ q[k + 1] = tmp.symf.s2;
}
} else if (Res <= 8) {
Tables[0] = & mpc_can_Q [Res - 3][0];
diff --git a/plugins/musepack/musepack.c b/plugins/musepack/musepack.c
index 69d18027..7f34c624 100644
--- a/plugins/musepack/musepack.c
+++ b/plugins/musepack/musepack.c
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -80,7 +80,7 @@ mpc_bool_t musepack_vfs_canseek (mpc_reader *r) {
}
static DB_fileinfo_t *
-musepack_open (void) {
+musepack_open (uint32_t hints) {
DB_fileinfo_t *_info = malloc (sizeof (musepack_info_t));
musepack_info_t *info = (musepack_info_t *)_info;
memset (info, 0, sizeof (musepack_info_t));
@@ -97,7 +97,7 @@ musepack_init (DB_fileinfo_t *_info, DB_playItem_t *it) {
info->reader.get_size = musepack_vfs_get_size;
info->reader.canseek = musepack_vfs_canseek;
- DB_FILE *fp = deadbeef->fopen (it->fname);
+ DB_FILE *fp = deadbeef->fopen (deadbeef->pl_find_meta (it, ":URI"));
if (!fp) {
return -1;
}
@@ -112,19 +112,17 @@ musepack_init (DB_fileinfo_t *_info, DB_playItem_t *it) {
}
mpc_demux_get_info (info->demux, &info->si);
-// info->mpcdec = mpc_decoder_init (&info->si);
-// if (!info->mpcdec) {
-// deadbeef->fclose ((DB_FILE *)info->reader.data);
-// info->reader.data = NULL;
-// return -1;
-// }
info->vbr_update_acc = 0;
info->vbr_update_bits = 0;
info->remaining = 0;
- _info->bps = 16;
- _info->channels = info->si.channels;
- _info->samplerate = info->si.sample_freq;
+ _info->fmt.is_float = 1;
+ _info->fmt.bps = 32;
+ _info->fmt.channels = info->si.channels;
+ _info->fmt.samplerate = info->si.sample_freq;
+ for (int i = 0; i < _info->fmt.channels; i++) {
+ _info->fmt.channelmask |= 1 << i;
+ }
_info->readpos = 0;
_info->plugin = &plugin;
@@ -145,10 +143,6 @@ static void
musepack_free (DB_fileinfo_t *_info) {
musepack_info_t *info = (musepack_info_t *)_info;
if (info) {
-// if (info->mpcdec) {
-// mpc_decoder_exit (info->mpcdec);
-// info->decoder = NULL;
-// }
if (info->demux) {
mpc_demux_exit (info->demux);
info->demux = NULL;
@@ -161,27 +155,24 @@ musepack_free (DB_fileinfo_t *_info) {
}
}
+#if 0
static int
-musepack_read_int16 (DB_fileinfo_t *_info, char *bytes, int size) {
+musepack_read (DB_fileinfo_t *_info, char *bytes, int size) {
musepack_info_t *info = (musepack_info_t *)_info;
- if (info->currentsample + size / (2 * _info->channels) > info->endsample) {
- size = (info->endsample - info->currentsample + 1) * 2 * _info->channels;
+ int samplesize = _info->fmt.bps / 8 * _info->fmt.channels;
+ if (info->currentsample + size / samplesize > info->endsample) {
+ size = (info->endsample - info->currentsample + 1) * samplesize;
if (size <= 0) {
return 0;
}
}
int initsize = size;
- int out_channels = _info->channels;
- if (out_channels > 2) {
- out_channels = 2;
- }
- int sample_size = ((_info->bps >> 3) * out_channels);
while (size > 0) {
if (info->remaining > 0) {
- int n = size / sample_size;
+ int n = size / samplesize;
n = min (n, info->remaining);
int nn = n;
float *p = info->buffer;
@@ -195,7 +186,7 @@ musepack_read_int16 (DB_fileinfo_t *_info, char *bytes, int size) {
}
*((int16_t *)bytes) = (int16_t)sample;
bytes += 2;
- if (_info->channels == 2) {
+ if (_info->fmt.channels == 2) {
sample = (int)(*(p+1) * 32767.0f);
if (sample > 32767) {
sample = 32767;
@@ -207,11 +198,11 @@ musepack_read_int16 (DB_fileinfo_t *_info, char *bytes, int size) {
bytes += 2;
}
n--;
- size -= sample_size;
+ size -= samplesize;
p += info->si.channels;
}
if (info->remaining > nn) {
- memmove (info->buffer, p, (info->remaining - nn) * sizeof (float) * _info->channels);
+ memmove (info->buffer, p, (info->remaining - nn) * sizeof (float) * _info->fmt.channels);
}
info->remaining -= nn;
}
@@ -227,48 +218,39 @@ musepack_read_int16 (DB_fileinfo_t *_info, char *bytes, int size) {
info->remaining = frame.samples;
}
}
- info->currentsample += (initsize-size) / sample_size;
+ info->currentsample += (initsize-size) / samplesize;
return initsize-size;
}
+#endif
static int
-musepack_read_float32 (DB_fileinfo_t *_info, char *bytes, int size) {
+musepack_read (DB_fileinfo_t *_info, char *bytes, int size) {
musepack_info_t *info = (musepack_info_t *)_info;
+ int samplesize = _info->fmt.bps / 8 * _info->fmt.channels;
- if (info->currentsample + size / (4 * _info->channels) > info->endsample) {
- size = (info->endsample - info->currentsample + 1) * 4 * _info->channels;
+ if (info->currentsample + size / samplesize > info->endsample) {
+ size = (info->endsample - info->currentsample + 1) * samplesize;
if (size <= 0) {
return 0;
}
}
int initsize = size;
- int out_channels = _info->channels;
- if (out_channels > 2) {
- out_channels = 2;
- }
while (size > 0) {
if (info->remaining > 0) {
- int n = size / (out_channels * 4);
+ int n = size / samplesize;
n = min (n, info->remaining);
- int nn = n;
- float *p = info->buffer;
- while (n > 0) {
- *((float *)bytes) = *p;
- bytes += 4;
- if (out_channels == 2) {
- *((float *)bytes) = *(p+1);
- bytes += 4;
- }
- n--;
- size -= out_channels * 4;
- p += info->si.channels;
- }
- if (info->remaining > nn) {
- memmove (info->buffer, p, (info->remaining - nn) * 4 * _info->channels);
+
+ memcpy (bytes, info->buffer, n * samplesize);
+
+ size -= n * samplesize;
+ bytes += n * samplesize;
+
+ if (info->remaining > n) {
+ memmove (info->buffer, ((char *)info->buffer) + n * samplesize, (info->remaining - n) * samplesize);
}
- info->remaining -= nn;
+ info->remaining -= n;
}
if (size > 0 && !info->remaining) {
@@ -282,9 +264,10 @@ musepack_read_float32 (DB_fileinfo_t *_info, char *bytes, int size) {
info->remaining = frame.samples;
}
}
- info->currentsample += (initsize-size) / (4 * _info->channels);
+ info->currentsample += (initsize-size) / samplesize;
return initsize-size;
}
+
static int
musepack_seek_sample (DB_fileinfo_t *_info, int sample) {
musepack_info_t *info = (musepack_info_t *)_info;
@@ -294,7 +277,7 @@ musepack_seek_sample (DB_fileinfo_t *_info, int sample) {
return -1;
}
info->currentsample = sample + info->startsample;
- _info->readpos = (float)sample / _info->samplerate;
+ _info->readpos = (float)sample / _info->fmt.samplerate;
info->remaining = 0;
return 0;
}
@@ -302,7 +285,37 @@ musepack_seek_sample (DB_fileinfo_t *_info, int sample) {
static int
musepack_seek (DB_fileinfo_t *_info, float time) {
musepack_info_t *info = (musepack_info_t *)_info;
- return musepack_seek_sample (_info, time * _info->samplerate);
+ return musepack_seek_sample (_info, time * _info->fmt.samplerate);
+}
+
+void
+mpc_set_trk_properties (DB_playItem_t *it, mpc_streaminfo *si, int64_t fsize) {
+ char s[100];
+ snprintf (s, sizeof (s), "%lld", fsize);
+ deadbeef->pl_add_meta (it, ":FILE_SIZE", s);
+ deadbeef->pl_add_meta (it, ":BPS", "32");
+ snprintf (s, sizeof (s), "%d", si->channels);
+ deadbeef->pl_add_meta (it, ":CHANNELS", s);
+ snprintf (s, sizeof (s), "%d", si->sample_freq);
+ deadbeef->pl_add_meta (it, ":SAMPLERATE", s);
+ snprintf (s, sizeof (s), "%d", (int)(si->average_bitrate/1000));
+ deadbeef->pl_add_meta (it, ":BITRATE", s);
+ snprintf (s, sizeof (s), "%f", si->profile);
+ deadbeef->pl_add_meta (it, ":MPC_QUALITY_PROFILE", s);
+ deadbeef->pl_add_meta (it, ":MPC_PROFILE_NAME", si->profile_name);
+ deadbeef->pl_add_meta (it, ":MPC_ENCODER", si->encoder);
+ snprintf (s, sizeof (s), "%d.%d", (si->encoder_version&0xff000000)>>24, (si->encoder_version&0x00ff0000)>>16);
+ deadbeef->pl_add_meta (it, ":MPC_ENCODER_VERSION", s);
+ deadbeef->pl_add_meta (it, ":MPC_PNS_USED", si->pns ? "1" : "0");
+ deadbeef->pl_add_meta (it, ":MPC_TRUE_GAPLESS", si->is_true_gapless ? "1" : "0");
+ snprintf (s, sizeof (s), "%d", si->beg_silence);
+ deadbeef->pl_add_meta (it, ":MPC_BEG_SILENCE", s);
+ snprintf (s, sizeof (s), "%d", si->stream_version);
+ deadbeef->pl_add_meta (it, ":MPC_STREAM_VERSION", s);
+ snprintf (s, sizeof (s), "%d", si->max_band);
+ deadbeef->pl_add_meta (it, ":MPC_MAX_BAND", s);
+ deadbeef->pl_add_meta (it, ":MPC_MS", si->ms ? "1" : "0");
+ deadbeef->pl_add_meta (it, ":MPC_FAST_SEEK", si->fast_seek ? "1" : "0");
}
static DB_playItem_t *
@@ -321,6 +334,7 @@ musepack_insert (DB_playItem_t *after, const char *fname) {
trace ("mpc: insert failed to open %s\n", fname);
return NULL;
}
+ int64_t fsize = deadbeef->fgetlength (fp);
reader.data = fp;
mpc_demux *demux = mpc_demux_init (&reader);
@@ -363,11 +377,9 @@ musepack_insert (DB_playItem_t *after, const char *fname) {
int i;
for (i = 0; i < nchapters; i++) {
const mpc_chap_info *ch = mpc_demux_chap (demux, i);
- DB_playItem_t *it = deadbeef->pl_item_alloc ();
- it->decoder_id = deadbeef->plug_get_decoder_id (plugin.plugin.id);
- it->fname = strdup (fname);
- it->filetype = "MusePack";
- it->tracknum = i;
+ DB_playItem_t *it = deadbeef->pl_item_alloc_init (fname, plugin.plugin.id);
+ deadbeef->pl_add_meta (it, ":FILETYPE", "MusePack");
+ deadbeef->pl_set_meta_int (it, ":TRACKNUM", i);
it->startsample = ch->sample;
it->endsample = totalsamples-1;
float gain = gain_title, peak = peak_title;
@@ -377,10 +389,10 @@ musepack_insert (DB_playItem_t *after, const char *fname) {
if (ch->peak != 0) {
peak = pow (10, ch->peak / (20.0 * 256.0)) / (1<<15);
}
- it->replaygain_album_gain = gain_album;
- it->replaygain_album_peak = peak_album;
- it->replaygain_track_gain = gain_title;
- it->replaygain_track_peak = peak_title;
+ deadbeef->pl_set_item_replaygain (it, DDB_REPLAYGAIN_ALBUMGAIN, gain_album);
+ deadbeef->pl_set_item_replaygain (it, DDB_REPLAYGAIN_ALBUMPEAK, peak_album);
+ deadbeef->pl_set_item_replaygain (it, DDB_REPLAYGAIN_TRACKGAIN, gain_title);
+ deadbeef->pl_set_item_replaygain (it, DDB_REPLAYGAIN_TRACKPEAK, peak_title);
deadbeef->pl_set_item_flags (it, DDB_IS_SUBTRACK);
if (!prev) {
meta = deadbeef->pl_item_alloc ();
@@ -402,6 +414,9 @@ musepack_insert (DB_playItem_t *after, const char *fname) {
deadbeef->pl_items_copy_junk (meta, it, it);
}
}
+
+ mpc_set_trk_properties (it, &si, fsize);
+
after = deadbeef->pl_insert_item (after, it);
prev = it;
deadbeef->pl_item_unref (it);
@@ -415,17 +430,15 @@ musepack_insert (DB_playItem_t *after, const char *fname) {
return after;
}
- DB_playItem_t *it = deadbeef->pl_item_alloc ();
- it->decoder_id = deadbeef->plug_get_decoder_id (plugin.plugin.id);
- it->fname = strdup (fname);
- it->filetype = "MusePack";
+ DB_playItem_t *it = deadbeef->pl_item_alloc_init (fname, plugin.plugin.id);
+ deadbeef->pl_add_meta (it, ":FILETYPE", "MusePack");
deadbeef->pl_set_item_duration (it, dur);
/*int apeerr = */deadbeef->junk_apev2_read (it, fp);
- it->replaygain_album_gain = gain_album;
- it->replaygain_album_peak = peak_album;
- it->replaygain_track_gain = gain_title;
- it->replaygain_track_peak = peak_title;
+ deadbeef->pl_set_item_replaygain (it, DDB_REPLAYGAIN_ALBUMGAIN, gain_album);
+ deadbeef->pl_set_item_replaygain (it, DDB_REPLAYGAIN_ALBUMPEAK, peak_album);
+ deadbeef->pl_set_item_replaygain (it, DDB_REPLAYGAIN_TRACKGAIN, gain_title);
+ deadbeef->pl_set_item_replaygain (it, DDB_REPLAYGAIN_TRACKPEAK, peak_title);
deadbeef->fclose (fp);
@@ -447,6 +460,7 @@ musepack_insert (DB_playItem_t *after, const char *fname) {
}
deadbeef->pl_unlock ();
+ mpc_set_trk_properties (it, &si, fsize);
cue = deadbeef->pl_insert_cue (after, it, totalsamples, si.sample_freq);
if (cue) {
deadbeef->pl_item_unref (it);
@@ -468,7 +482,7 @@ musepack_insert (DB_playItem_t *after, const char *fname) {
}
static int musepack_read_metadata (DB_playItem_t *it) {
- DB_FILE *fp = deadbeef->fopen (it->fname);
+ DB_FILE *fp = deadbeef->fopen (deadbeef->pl_find_meta (it, ":URI"));
if (!fp) {
return -1;
}
@@ -512,22 +526,38 @@ static const char *filetypes[] = { "MusePack", NULL };
// define plugin interface
static DB_decoder_t plugin = {
DB_PLUGIN_SET_API_VERSION
- .plugin.version_major = 0,
- .plugin.version_minor = 1,
+ .plugin.version_major = 1,
+ .plugin.version_minor = 0,
.plugin.type = DB_PLUGIN_DECODER,
.plugin.id = "musepack",
.plugin.name = "MusePack decoder",
.plugin.descr = "Musepack decoder using libmppdec",
- .plugin.author = "Alexey Yakovenko",
- .plugin.email = "waker@users.sourceforge.net",
+ .plugin.copyright =
+ "Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>\n"
+ "\n"
+ "Uses Musepack SV8 libs (r435), (C) 2005-2009, The Musepack Development Team\n"
+ "\n"
+ "This program is free software; you can redistribute it and/or\n"
+ "modify it under the terms of the GNU General Public License\n"
+ "as published by the Free Software Foundation; either version 2\n"
+ "of the License, or (at your option) any later version.\n"
+ "\n"
+ "This program is distributed in the hope that it will be useful,\n"
+ "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+ "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+ "GNU General Public License for more details.\n"
+ "\n"
+ "You should have received a copy of the GNU General Public License\n"
+ "along with this program; if not, write to the Free Software\n"
+ "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n"
+ ,
.plugin.website = "http://deadbeef.sf.net",
.plugin.start = musepack_start,
.plugin.stop = musepack_stop,
.open = musepack_open,
.init = musepack_init,
.free = musepack_free,
- .read_int16 = musepack_read_int16,
- .read_float32 = musepack_read_float32,
+ .read = musepack_read,
.seek = musepack_seek,
.seek_sample = musepack_seek_sample,
.insert = musepack_insert,
diff --git a/plugins/notify/notify.c b/plugins/notify/notify.c
index ba7daa92..c572b131 100644
--- a/plugins/notify/notify.c
+++ b/plugins/notify/notify.c
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@@ -22,6 +22,7 @@
#include <stdlib.h>
#include <string.h>
#include "../../gettext.h"
+#include "../artwork/artwork.h"
#define E_NOTIFICATION_BUS_NAME "org.freedesktop.Notifications"
#define E_NOTIFICATION_INTERFACE "org.freedesktop.Notifications"
@@ -29,8 +30,62 @@
DB_functions_t *deadbeef;
DB_misc_t plugin;
+DB_artwork_plugin_t *artwork_plugin;
-#define NOTIFY_DEFAULT_FORMAT "%a - %t"
+static dbus_uint32_t replaces_id = 0;
+
+#define NOTIFY_DEFAULT_TITLE "%t"
+#define NOTIFY_DEFAULT_CONTENT "%a - %b"
+
+static void
+notify_thread (void *ctx) {
+
+ DBusMessage *msg = (DBusMessage*) ctx;
+ DBusMessage *reply = NULL;
+
+ DBusError error;
+ dbus_error_init (&error);
+ DBusConnection *conn = dbus_bus_get (DBUS_BUS_SESSION, &error);
+ if(dbus_error_is_set (&error)) {
+ fprintf(stderr, "connection failed: %s",error.message);
+ dbus_error_free(&error);
+ dbus_message_unref (msg);
+ deadbeef->thread_exit(NULL);
+ }
+
+ reply = dbus_connection_send_with_reply_and_block (conn, msg, -1, &error);
+ if (dbus_error_is_set (&error)) {
+ fprintf(stderr, "send_with_reply_and_block error: (%s)\n", error.message);
+ dbus_error_free(&error);
+ dbus_message_unref (msg);
+ deadbeef->thread_exit(NULL);
+ }
+
+ if (reply != NULL) {
+ // Process the reply message
+ DBusMessageIter args;
+
+ dbus_uint32_t id = 0;
+ if (dbus_message_iter_init(reply, &args)) {
+ if (DBUS_TYPE_UINT32 == dbus_message_iter_get_arg_type(&args)) {
+ dbus_message_iter_get_basic(&args, &id);
+ if (id != replaces_id) {
+ replaces_id = id;
+ }
+ dbus_message_unref (reply);
+ } else {
+ fprintf(stderr, "Argument is not uint32\n");
+ }
+ } else {
+ fprintf(stderr, "Reply has no arguments\n");
+ }
+ }
+
+ dbus_message_unref (msg);
+ dbus_connection_unref (conn);
+ deadbeef->thread_exit(NULL);
+
+}
#if 0
static void
@@ -62,107 +117,137 @@ notify_marshal_dict_string(DBusMessageIter *iter, const char *key, const char *v
}
#endif
+static void
+esc_xml (const char *cmd, char *esc, int size) {
+ const char *src = cmd;
+ char *dst = esc;
+ char *end = dst + size - 1;
+ while (*src && dst < end) {
+ if (*src == '&') {
+ if (end - dst < 5) {
+ break;
+ }
+ strcpy (dst, "&amp;");
+ dst += 5;
+ src++;
+ }
+ else if (*src == '<') {
+ if (end - dst < 4) {
+ break;
+ }
+ strcpy (dst, "&lt;");
+ dst += 4;
+ src++;
+ }
+ else if (*src == '>') {
+ if (end - dst < 4) {
+ break;
+ }
+ strcpy (dst, "&gt;");
+ dst += 4;
+ src++;
+ }
+ else if (*src == '\'') {
+ if (end - dst < 6) {
+ break;
+ }
+ strcpy (dst, "&apos;");
+ dst += 6;
+ src++;
+ }
+ else if (*src == '"') {
+ if (end - dst < 6) {
+ break;
+ }
+ strcpy (dst, "&quot;");
+ dst += 6;
+ src++;
+ }
+ else if (*src == '\\' && *(src+1) == 'n') {
+ strcpy (dst, "\n");
+ dst++;
+ src+=2;
+ }
+ else {
+ *dst++ = *src++;
+ }
+ }
+ *dst = 0;
+}
+
+
+static void
+cover_avail_callback (const char *fname, const char *artist, const char *album, void *user_data) {
+// show_notification (track);
+}
+
+static void show_notification (DB_playItem_t *track) {
+ char title[1024];
+ char content[1024];
+ deadbeef->conf_lock ();
+ deadbeef->pl_format_title (track, -1, title, sizeof (title), -1, deadbeef->conf_get_str_fast ("notify.format", NOTIFY_DEFAULT_TITLE));
+ deadbeef->pl_format_title (track, -1, content, sizeof (content), -1, deadbeef->conf_get_str_fast ("notify.format_content", NOTIFY_DEFAULT_CONTENT));
+ deadbeef->conf_unlock ();
+
+ // escape &
+// char esc_title[1024];
+ char esc_content[1024];
+// esc_xml (title, esc_title, sizeof (esc_title));
+ esc_xml (content, esc_content, sizeof (esc_content));
+ DBusMessage *msg = dbus_message_new_method_call (E_NOTIFICATION_BUS_NAME, E_NOTIFICATION_PATH, E_NOTIFICATION_INTERFACE, "Notify");
+
+ const char *v_appname = "DeaDBeeF";
+ dbus_uint32_t v_id = 0;
+ char *v_iconname = NULL;
+ if (deadbeef->conf_get_int("notify.albumart", 0) && artwork_plugin) {
+ const char *album = deadbeef->pl_find_meta (track, "album");
+ const char *artist = deadbeef->pl_find_meta (track, "artist");
+ v_iconname = artwork_plugin->get_album_art (deadbeef->pl_find_meta (track, ":URI"), artist, album, deadbeef->conf_get_int ("notify.albumart_size", 64), cover_avail_callback, NULL);
+ }
+ if (!v_iconname) {
+ v_iconname = strdup ("deadbeef");
+ }
+ const char *v_summary = title;
+ const char *v_body = esc_content;
+ dbus_int32_t v_timeout = -1;
+
+ dbus_message_append_args (msg
+ , DBUS_TYPE_STRING, &v_appname
+ , DBUS_TYPE_UINT32, &replaces_id
+ , DBUS_TYPE_STRING, &v_iconname
+ , DBUS_TYPE_STRING, &v_summary
+ , DBUS_TYPE_STRING, &v_body
+ , DBUS_TYPE_INVALID
+ );
+
+ DBusMessageIter iter, sub;
+ // actions
+ dbus_message_iter_init_append(msg, &iter);
+ dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "s", &sub);
+ dbus_message_iter_close_container(&iter, &sub);
+ // hints
+ dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "{sv}", &sub);
+ dbus_message_iter_close_container(&iter, &sub);
+
+ dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &v_timeout);
+
+ intptr_t tid = 0;
+ if ((tid=deadbeef->thread_start(notify_thread, msg)) != 0) {
+ dbus_message_ref (msg);
+ deadbeef->thread_detach (tid);
+ }
+ dbus_message_unref (msg);
+ if (v_iconname) {
+ free (v_iconname);
+ }
+}
+
static int
on_songchanged (DB_event_trackchange_t *ev, uintptr_t data) {
if (ev->to && deadbeef->conf_get_int ("notify.enable", 0)) {
DB_playItem_t *track = ev->to;
if (track) {
- char cmd[1024];
- deadbeef->pl_format_title (track, -1, cmd, sizeof (cmd), -1, deadbeef->conf_get_str ("notify.format", NOTIFY_DEFAULT_FORMAT));
-
- // escape &
- char esc[1024];
-
- char *src = cmd;
- char *dst = esc;
- char *end = dst + sizeof (esc) - 1;
- while (*src && dst < end) {
- if (*src == '&') {
- if (end - dst < 5) {
- break;
- }
- strcpy (dst, "&amp;");
- dst += 5;
- src++;
- }
- else if (*src == '<') {
- if (end - dst < 4) {
- break;
- }
- strcpy (dst, "&lt;");
- dst += 4;
- src++;
- }
- else if (*src == '>') {
- if (end - dst < 4) {
- break;
- }
- strcpy (dst, "&gt;");
- dst += 4;
- src++;
- }
- else if (*src == '\'') {
- if (end - dst < 6) {
- break;
- }
- strcpy (dst, "&apos;");
- dst += 6;
- src++;
- }
- else if (*src == '"') {
- if (end - dst < 6) {
- break;
- }
- strcpy (dst, "&quot;");
- dst += 6;
- src++;
- }
- else {
- *dst++ = *src++;
- }
- }
- *dst = 0;
-
- DBusError error;
- dbus_error_init (&error);
- DBusConnection *conn = dbus_bus_get (DBUS_BUS_SESSION, &error);
- if(conn == NULL) {
- printf("connection failed: %s",error.message);
- exit(1);
- }
- DBusMessage *msg = dbus_message_new_method_call (E_NOTIFICATION_BUS_NAME, E_NOTIFICATION_PATH, E_NOTIFICATION_INTERFACE, "Notify");
-
- const char *v_appname = "DeaDBeeF";
- dbus_uint32_t v_id = 0;
- const char *v_iconname = "deadbeef";
- const char *v_summary = _("DeaDBeeF now playing");
- const char *v_body = esc;
- dbus_int32_t v_timeout = -1;
-
- dbus_message_append_args (msg
- , DBUS_TYPE_STRING, &v_appname
- , DBUS_TYPE_UINT32, &v_id
- , DBUS_TYPE_STRING, &v_iconname
- , DBUS_TYPE_STRING, &v_summary
- , DBUS_TYPE_STRING, &v_body
- , DBUS_TYPE_INVALID
- );
-
- DBusMessageIter iter, sub;
- // actions
- dbus_message_iter_init_append(msg, &iter);
- dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "s", &sub);
- dbus_message_iter_close_container(&iter, &sub);
- // hints
- dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "{sv}", &sub);
- dbus_message_iter_close_container(&iter, &sub);
-
- dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &v_timeout);
-
- int serial;
- dbus_bool_t retval = dbus_connection_send(conn,msg,&serial);
- dbus_connection_flush (conn);
- dbus_message_unref (msg);
+ show_notification (track);
}
}
return 0;
@@ -180,9 +265,24 @@ notify_stop (void) {
return 0;
}
+static int
+notify_connect (void) {
+ artwork_plugin = (DB_artwork_plugin_t *)deadbeef->plug_get_for_id ("artwork");
+ return 0;
+}
+
+static int
+notify_disconnect (void) {
+ artwork_plugin = NULL;
+ return 0;
+}
+
static const char settings_dlg[] =
"property \"Enable\" checkbox notify.enable 0;\n"
- "property \"Notification format\" entry notify.format \"" NOTIFY_DEFAULT_FORMAT "\";\n"
+ "property \"Notification title format\" entry notify.format \"" NOTIFY_DEFAULT_TITLE "\";\n"
+ "property \"Notification content format\" entry notify.format_content \"" NOTIFY_DEFAULT_CONTENT "\";\n"
+ "property \"Show album art\" checkbox notify.albumart 1;\n"
+ "property \"Album art size (px)\" entry notify.albumart_size 64;\n"
;
DB_misc_t plugin = {
@@ -192,12 +292,29 @@ DB_misc_t plugin = {
.plugin.version_minor = 0,
.plugin.id = "notify",
.plugin.name = "OSD Notify",
- .plugin.descr = "notification daemon OSD",
- .plugin.author = "Alexey Yakovenko",
- .plugin.email = "waker@users.sourceforge.net",
+ .plugin.descr = "Displays notifications when new track starts.\nRequires dbus and notification daemon to be running.\nNotification daemon should be provided by your desktop environment.\n",
+ .plugin.copyright =
+ "Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>\n"
+ "\n"
+ "This program is free software; you can redistribute it and/or\n"
+ "modify it under the terms of the GNU General Public License\n"
+ "as published by the Free Software Foundation; either version 2\n"
+ "of the License, or (at your option) any later version.\n"
+ "\n"
+ "This program is distributed in the hope that it will be useful,\n"
+ "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+ "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+ "GNU General Public License for more details.\n"
+ "\n"
+ "You should have received a copy of the GNU General Public License\n"
+ "along with this program; if not, write to the Free Software\n"
+ "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n"
+ ,
.plugin.website = "http://deadbeef.sourceforge.net",
.plugin.start = notify_start,
.plugin.stop = notify_stop,
+ .plugin.connect = notify_connect,
+ .plugin.disconnect = notify_disconnect,
.plugin.configdialog = settings_dlg,
};
diff --git a/plugins/nullout/nullout.c b/plugins/nullout/nullout.c
index 8720de6d..c568f5d2 100644
--- a/plugins/nullout/nullout.c
+++ b/plugins/nullout/nullout.c
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -32,7 +32,6 @@ DB_functions_t *deadbeef;
static intptr_t null_tid;
static int null_terminate;
-static int null_rate;
static int state;
static void
@@ -47,8 +46,8 @@ pnull_init (void);
static int
pnull_free (void);
-static int
-pnull_change_rate (int rate);
+int
+pnull_setformat (ddb_waveformat_t *fmt);
static int
pnull_play (void);
@@ -62,32 +61,19 @@ pnull_pause (void);
static int
pnull_unpause (void);
-static int
-pnull_get_rate (void);
-
-static int
-pnull_get_bps (void);
-
-static int
-pnull_get_channels (void);
-
-static int
-pnull_get_endianness (void);
-
int
pnull_init (void) {
trace ("pnull_init\n");
state = OUTPUT_STATE_STOPPED;
- null_rate = 44100;
null_terminate = 0;
null_tid = deadbeef->thread_start (pnull_thread, NULL);
return 0;
}
int
-pnull_change_rate (int rate) {
- null_rate = rate;
- return null_rate;
+pnull_setformat (ddb_waveformat_t *fmt) {
+ memcpy (&plugin.fmt, fmt, sizeof (ddb_waveformat_t));
+ return 0;
}
int
@@ -140,21 +126,6 @@ pnull_unpause (void) {
return 0;
}
-int
-pnull_get_rate (void) {
- return null_rate;
-}
-
-int
-pnull_get_bps (void) {
- return 16;
-}
-
-int
-pnull_get_channels (void) {
- return 2;
-}
-
static int
pnull_get_endianness (void) {
#if WORDS_BIGENDIAN
@@ -220,27 +191,39 @@ nullout_load (DB_functions_t *api) {
// define plugin interface
static DB_output_t plugin = {
DB_PLUGIN_SET_API_VERSION
- .plugin.version_major = 0,
- .plugin.version_minor = 1,
- .plugin.nostop = 1,
+ .plugin.version_major = 1,
+ .plugin.version_minor = 0,
.plugin.type = DB_PLUGIN_OUTPUT,
+ .plugin.id = "nullout",
.plugin.name = "null output plugin",
.plugin.descr = "doesn't play anything",
- .plugin.author = "Alexey Yakovenko",
- .plugin.email = "waker@users.sourceforge.net",
+ .plugin.copyright =
+ "Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>\n"
+ "\n"
+ "This program is free software; you can redistribute it and/or\n"
+ "modify it under the terms of the GNU General Public License\n"
+ "as published by the Free Software Foundation; either version 2\n"
+ "of the License, or (at your option) any later version.\n"
+ "\n"
+ "This program is distributed in the hope that it will be useful,\n"
+ "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+ "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+ "GNU General Public License for more details.\n"
+ "\n"
+ "You should have received a copy of the GNU General Public License\n"
+ "along with this program; if not, write to the Free Software\n"
+ "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n"
+ ,
.plugin.website = "http://deadbeef.sf.net",
.plugin.start = null_start,
.plugin.stop = null_stop,
.init = pnull_init,
.free = pnull_free,
- .change_rate = pnull_change_rate,
+ .setformat = pnull_setformat,
.play = pnull_play,
.stop = pnull_stop,
.pause = pnull_pause,
.unpause = pnull_unpause,
.state = pnull_get_state,
- .samplerate = pnull_get_rate,
- .bitspersample = pnull_get_bps,
- .channels = pnull_get_channels,
- .endianness = pnull_get_endianness,
+ .fmt = {.samplerate = 44100, .channels = 2, .bps = 16, .channelmask = DDB_SPEAKER_FRONT_LEFT | DDB_SPEAKER_FRONT_RIGHT}
};
diff --git a/plugins/oss/oss.c b/plugins/oss/oss.c
index 52c417fa..953398af 100644
--- a/plugins/oss/oss.c
+++ b/plugins/oss/oss.c
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -48,6 +48,8 @@ static int state;
static int fd;
static uintptr_t mutex;
+static char oss_device[100];
+
#define BLOCKSIZE 8192
static void
@@ -56,70 +58,90 @@ oss_thread (void *context);
static int
oss_callback (char *stream, int len);
-static int
-oss_init (void) {
- trace ("oss_init\n");
- state = OUTPUT_STATE_STOPPED;
- oss_terminate = 0;
- mutex = 0;
-
- // prepare oss for playback
- const char *name = deadbeef->conf_get_str ("oss.device", "/dev/dsp");
- fd = open (name, O_WRONLY);
- if (fd == -1) {
- fprintf (stderr, "oss: failed to open file %s\n", name);
- perror (name);
- plugin.free ();
- return -1;
+int
+oss_set_hwparams (ddb_waveformat_t *fmt) {
+ int samplefmt;
+ switch (fmt->bps) {
+ case 8:
+ samplefmt = AFMT_S8;
+ break;
+ case 16:
+ samplefmt = AFMT_S16_NE;
+ break;
+ default:
+ samplefmt = AFMT_S16_NE;
+ break;
}
-
-#if OSS_VERSION>=0x040000
-/*
- int cooked = 1;
- ioctl (fd, SNDCTL_DSP_COOKEDMODE, &cooked);
- trace ("oss: cooked_mode=%d\n", cooked);
-
- int policy = 3;
- ioctl (fd, SNDCTL_DSP_POLICY, &policy);
- trace ("oss: policy=%d\n", policy);
-*/
-#endif
-
- int fmt = AFMT_S16_NE;
- if (ioctl (fd, SNDCTL_DSP_SETFMT, &fmt) == -1) {
+ if (ioctl (fd, SNDCTL_DSP_SETFMT, &samplefmt) == -1) {
fprintf (stderr, "oss: failed to set format\n");
perror ("SNDCTL_DSP_SETFMT");
- plugin.free ();
- return -1;
- }
-
- if (fmt != AFMT_S16_NE) {
- fprintf (stderr, "oss: device doesn't support 16 bit sample format\n");
- plugin.free ();
return -1;
}
- int channels = 2;
+ int channels = fmt->channels;
if (ioctl (fd, SNDCTL_DSP_CHANNELS, &channels) == -1) {
- fprintf (stderr, "oss: failed to set channels\n");
+ if (channels != 2) {
+ fprintf (stderr, "oss: failed to set %d channels, trying fallback to stereo\n", fmt->channels);
+ channels = 2;
+ if (ioctl (fd, SNDCTL_DSP_CHANNELS, &channels) == -1) {
+ fprintf (stderr, "oss: stereo fallback failed\n");
+ perror ("SNDCTL_DSP_CHANNELS");
+ return -1;
+ }
+ }
+ else {
+ fprintf (stderr, "oss: failed to set %d channels\n", fmt->channels);
+ perror ("SNDCTL_DSP_CHANNELS");
+ return -1;
+ }
+ }
+ int rate = fmt->samplerate;
+ if (ioctl (fd, SNDCTL_DSP_SPEED, &rate) == -1) {
+ fprintf (stderr, "oss: can't switch to %d samplerate\n", rate);
perror ("SNDCTL_DSP_CHANNELS");
- plugin.free ();
return -1;
}
- if (channels != 2) {
- fprintf (stderr, "oss: device doesn't support stereo output\n");
- plugin.free ();
+
+ plugin.fmt.samplerate = rate;
+ plugin.fmt.channels = channels;
+ switch (samplefmt) {
+ case AFMT_S8:
+ plugin.fmt.bps = 8;
+ break;
+ case AFMT_S16_LE:
+ case AFMT_S16_BE:
+ plugin.fmt.bps = 16;
+ break;
+ default:
+ fprintf (stderr, "oss: unsupported output format: 0x%X\n", samplefmt);
return -1;
}
+ plugin.fmt.channelmask = 0;
+ for (int i = 0; i < plugin.fmt.channels; i++) {
+ plugin.fmt.channelmask |= 1 << i;
+ }
- if (ioctl (fd, SNDCTL_DSP_SPEED, &oss_rate) == -1) {
- fprintf (stderr, "oss: failed to set samplerate\n");
- perror ("SNDCTL_DSP_CHANNELS");
+ return 0;
+}
+
+static int
+oss_init (void) {
+ trace ("oss_init\n");
+ state = OUTPUT_STATE_STOPPED;
+ oss_terminate = 0;
+ mutex = 0;
+
+ // prepare oss for playback
+ const char *name = oss_device;
+ fd = open (name, O_WRONLY);
+ if (fd == -1) {
+ fprintf (stderr, "oss: failed to open file %s\n", name);
+ perror (name);
plugin.free ();
return -1;
}
- trace ("oss: samplerate: %d\n", oss_rate);
+ oss_set_hwparams (&plugin.fmt);
mutex = deadbeef->mutex_create ();
@@ -128,28 +150,6 @@ oss_init (void) {
}
static int
-oss_change_rate (int rate) {
- if (!fd) {
- oss_rate = rate;
- return oss_rate;
- }
- if (rate == oss_rate) {
- trace ("oss_change_rate %d: ignored\n", rate);
- return rate;
- }
- deadbeef->mutex_lock (mutex);
- if (ioctl (fd, SNDCTL_DSP_SPEED, &rate) == -1) {
- fprintf (stderr, "oss: can't switch to %d samplerate\n", rate);
- perror ("SNDCTL_DSP_CHANNELS");
- plugin.free ();
- return -1;
- }
- oss_rate = rate;
- deadbeef->mutex_unlock (mutex);
- return oss_rate;
-}
-
-static int
oss_free (void) {
trace ("oss_free\n");
if (!oss_terminate) {
@@ -201,6 +201,41 @@ oss_pause (void) {
return 0;
}
+
+static int
+oss_setformat (ddb_waveformat_t *fmt) {
+ trace ("oss_setformat\n");
+ if (!fd) {
+ memcpy (&plugin.fmt, fmt, sizeof (ddb_waveformat_t));
+ }
+ if (!memcmp (fmt, &plugin.fmt, sizeof (ddb_waveformat_t))) {
+ return 0;
+ }
+ deadbeef->mutex_lock (mutex);
+
+ if (0 != oss_set_hwparams (fmt)) {
+ return -1;
+ }
+
+ deadbeef->mutex_unlock (mutex);
+
+ switch (state) {
+ case OUTPUT_STATE_STOPPED:
+ return oss_stop ();
+ case OUTPUT_STATE_PLAYING:
+ return oss_play ();
+ case OUTPUT_STATE_PAUSED:
+ if (0 != oss_play ()) {
+ return -1;
+ }
+ if (0 != oss_pause ()) {
+ return -1;
+ }
+ break;
+ }
+ return 0;
+}
+
static int
oss_unpause (void) {
oss_play ();
@@ -247,7 +282,14 @@ oss_thread (void *context) {
int res = 0;
- char buf[BLOCKSIZE];
+ int sample_size = plugin.fmt.channels * (plugin.fmt.bps / 8);
+ int bs = BLOCKSIZE;
+ int mod = bs % sample_size;
+ if (mod > 0) {
+ bs -= mod;
+ }
+ char buf[bs];
+
int write_size = oss_callback (buf, sizeof (buf));
deadbeef->mutex_lock (mutex);
if ( write_size > 0 )
@@ -264,13 +306,7 @@ oss_thread (void *context) {
static int
oss_callback (char *stream, int len) {
- int bytesread = deadbeef->streamer_read (stream, len);
- int16_t ivolume = deadbeef->volume_get_amp () * 1000;
- for (int i = 0; i < bytesread/2; i++) {
- ((int16_t*)stream)[i] = (int16_t)(((int32_t)(((int16_t*)stream)[i])) * ivolume / 1000);
- }
-
- return bytesread;
+ return deadbeef->streamer_read (stream, len);
}
static int
@@ -279,12 +315,28 @@ oss_get_state (void) {
}
static int
+oss_configchanged (DB_event_t *ev, uintptr_t data) {
+ deadbeef->conf_lock ();
+ const char *dev = deadbeef->conf_get_str_fast ("oss.device", "/dev/dsp");
+ if (strcmp (dev, oss_device)) {
+ strncpy (oss_device, dev, sizeof (oss_device)-1);
+ trace ("oss: config option changed, restarting\n");
+ deadbeef->sendmessage (M_REINIT_SOUND, 0, 0, 0);
+ }
+ deadbeef->conf_unlock ();
+ return 0;
+}
+
+static int
oss_plugin_start (void) {
+ deadbeef->conf_get_str ("oss.device", "/dev/dsp", oss_device, sizeof (oss_device));
+ deadbeef->ev_subscribe (DB_PLUGIN (&plugin), DB_EV_CONFIGCHANGED, DB_CALLBACK (oss_configchanged), 0);
return 0;
}
static int
oss_plugin_stop (void) {
+ deadbeef->ev_unsubscribe (DB_PLUGIN (&plugin), DB_EV_CONFIGCHANGED, DB_CALLBACK (oss_configchanged), 0);
return 0;
}
@@ -294,31 +346,46 @@ oss_load (DB_functions_t *api) {
return DB_PLUGIN (&plugin);
}
+static const char settings_dlg[] =
+ "property \"Device file\" entry oss.device /dev/dsp;\n";
+
// define plugin interface
static DB_output_t plugin = {
DB_PLUGIN_SET_API_VERSION
- .plugin.version_major = 0,
- .plugin.version_minor = 1,
- .plugin.nostop = 0,
+ .plugin.version_major = 1,
+ .plugin.version_minor = 0,
.plugin.type = DB_PLUGIN_OUTPUT,
.plugin.id = "oss",
.plugin.name = "OSS output plugin",
.plugin.descr = "plays sound via OSS API",
- .plugin.author = "Alexey Yakovenko",
- .plugin.email = "waker@users.sourceforge.net",
+ .plugin.copyright =
+ "Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>\n"
+ "\n"
+ "This program is free software; you can redistribute it and/or\n"
+ "modify it under the terms of the GNU General Public License\n"
+ "as published by the Free Software Foundation; either version 2\n"
+ "of the License, or (at your option) any later version.\n"
+ "\n"
+ "This program is distributed in the hope that it will be useful,\n"
+ "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+ "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+ "GNU General Public License for more details.\n"
+ "\n"
+ "You should have received a copy of the GNU General Public License\n"
+ "along with this program; if not, write to the Free Software\n"
+ "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n"
+ ,
.plugin.website = "http://deadbeef.sf.net",
.plugin.start = oss_plugin_start,
.plugin.stop = oss_plugin_stop,
+ .plugin.configdialog = settings_dlg,
.init = oss_init,
.free = oss_free,
- .change_rate = oss_change_rate,
+ .setformat = oss_setformat,
.play = oss_play,
.stop = oss_stop,
.pause = oss_pause,
.unpause = oss_unpause,
.state = oss_get_state,
- .samplerate = oss_get_rate,
- .bitspersample = oss_get_bps,
- .channels = oss_get_channels,
- .endianness = oss_get_endianness,
+ .fmt = {-1},
};
diff --git a/plugins/pulse/pulse.c b/plugins/pulse/pulse.c
index 266ea107..9a08ff08 100644
--- a/plugins/pulse/pulse.c
+++ b/plugins/pulse/pulse.c
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -42,7 +42,6 @@
static DB_output_t plugin;
DB_functions_t * deadbeef;
-#define CONFSTR_PULSE_SAMPLERATE "pulse.samplerate"
#define CONFSTR_PULSE_SERVERADDR "pulse.serveraddr"
#define CONFSTR_PULSE_BUFFERSIZE "pulse.buffersize"
@@ -51,6 +50,8 @@ static int pulse_terminate;
static pa_simple *s;
static pa_sample_spec ss;
+static pa_channel_map channel_map;
+static ddb_waveformat_t requested_fmt;
static int state;
static uintptr_t mutex;
@@ -60,29 +61,70 @@ static void pulse_thread(void *context);
static void pulse_callback(char *stream, int len);
-static int pulse_init(void)
+static int pulse_init();
+
+static int pulse_free();
+
+static int pulse_setformat(ddb_waveformat_t *fmt);
+
+static int pulse_play();
+
+static int pulse_stop();
+
+static int pulse_pause();
+
+static int pulse_unpause();
+
+static int pulse_set_spec(ddb_waveformat_t *fmt)
{
- trace ("pulse_init\n");
- state = OUTPUT_STATE_STOPPED;
- pulse_terminate = 0;
+ memcpy (&plugin.fmt, fmt, sizeof (ddb_waveformat_t));
+ if (!plugin.fmt.channels) {
+ // generic format
+ plugin.fmt.bps = 16;
+ plugin.fmt.is_float = 0;
+ plugin.fmt.channels = 2;
+ plugin.fmt.samplerate = 44100;
+ plugin.fmt.channelmask = 3;
+ }
- // Read serveraddr from config
- const char * server = deadbeef->conf_get_str(CONFSTR_PULSE_SERVERADDR, NULL);
+ trace ("format %dbit %s %dch %dHz channelmask=%X\n", plugin.fmt.bps, plugin.fmt.is_float ? "float" : "int", plugin.fmt.channels, plugin.fmt.samplerate, plugin.fmt.channelmask);
- if (server)
- server = strcmp(server, "default") ? server : NULL;
+ ss.channels = plugin.fmt.channels;
+ // Try to auto-configure the channel map, see <pulse/channelmap.h> for details
+ pa_channel_map_init_extend(&channel_map, ss.channels, PA_CHANNEL_MAP_DEFAULT);
+ //pa_channel_map_init(&channel_map);
+ trace ("pulse: channels: %d\n", ss.channels);
// Read samplerate from config
- ss.rate = deadbeef->conf_get_int(CONFSTR_PULSE_SAMPLERATE, 44100);
+ //ss.rate = deadbeef->conf_get_int(CONFSTR_PULSE_SAMPLERATE, 44100);
+ ss.rate = plugin.fmt.samplerate;
trace ("pulse: samplerate: %d\n", ss.rate);
- // TODO: add config for this
- pa_channel_map * map = NULL;//pa_channel_map_init_stereo(NULL);
- ss.channels = 2;
- ss.format = PA_SAMPLE_S16NE;
+ switch (plugin.fmt.bps) {
+ case 8:
+ ss.format = PA_SAMPLE_U8;
+ break;
+ case 16:
+ ss.format = PA_SAMPLE_S16LE;
+ break;
+ case 24:
+ ss.format = PA_SAMPLE_S24LE;
+ break;
+ case 32:
+ if (plugin.fmt.is_float) {
+ ss.format = PA_SAMPLE_FLOAT32LE;
+ }
+ else {
+ ss.format = PA_SAMPLE_S32LE;
+ }
+ break;
+ default:
+ return -1;
+ };
- // TODO: where list of all available devices? add this option to config too..
- char * dev = NULL;
+ if (s) {
+ pa_simple_free(s);
+ }
pa_buffer_attr * attr = NULL;
//attr->maxlength = Maximum length of the buffer.
@@ -93,11 +135,42 @@ static int pulse_init(void)
buffer_size = deadbeef->conf_get_int(CONFSTR_PULSE_BUFFERSIZE, 4096);
+ // TODO: where list of all available devices? add this option to config too..
+ char * dev = NULL;
+
int error;
- s = pa_simple_new(server, "Deadbeef", PA_STREAM_PLAYBACK, dev, "Music", &ss, map, attr, &error);
+
+ // Read serveraddr from config
+ deadbeef->conf_lock ();
+ const char * server = deadbeef->conf_get_str_fast (CONFSTR_PULSE_SERVERADDR, NULL);
+
+ if (server) {
+ server = strcmp(server, "default") ? server : NULL;
+ }
+
+ s = pa_simple_new(server, "Deadbeef", PA_STREAM_PLAYBACK, dev, "Music", &ss, &channel_map, attr, &error);
+ deadbeef->conf_unlock ();
if (!s)
{
+ trace ("pulse_init failed (%d)\n", error);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int pulse_init(void)
+{
+ trace ("pulse_init\n");
+ state = OUTPUT_STATE_STOPPED;
+ pulse_terminate = 0;
+
+ if (requested_fmt.samplerate != 0) {
+ memcpy (&plugin.fmt, &requested_fmt, sizeof (ddb_waveformat_t));
+ }
+
+ if (0 != pulse_set_spec(&plugin.fmt)) {
return -1;
}
@@ -106,6 +179,42 @@ static int pulse_init(void)
return 0;
}
+static int pulse_setformat (ddb_waveformat_t *fmt)
+{
+ memcpy (&requested_fmt, fmt, sizeof (ddb_waveformat_t));
+ if (!s) {
+ return -1;
+ }
+ if (!memcmp (fmt, &plugin.fmt, sizeof (ddb_waveformat_t))) {
+ trace ("pulse_setformat ignored\n");
+ return 0;
+ }
+ trace ("pulse_setformat %dbit %s %dch %dHz channelmask=%X\n", fmt->bps, fmt->is_float ? "float" : "int", fmt->channels, fmt->samplerate, fmt->channelmask);
+
+ int prev_state = state;
+ pulse_stop ();
+ deadbeef->mutex_lock(mutex);
+ pulse_set_spec(fmt);
+ deadbeef->mutex_unlock(mutex);
+ trace ("new format %dbit %s %dch %dHz channelmask=%X\n", plugin.fmt.bps, plugin.fmt.is_float ? "float" : "int", plugin.fmt.channels, plugin.fmt.samplerate, plugin.fmt.channelmask);
+
+ switch (prev_state) {
+ case OUTPUT_STATE_STOPPED:
+ return pulse_stop ();
+ case OUTPUT_STATE_PLAYING:
+ return pulse_play ();
+ case OUTPUT_STATE_PAUSED:
+ if (0 != pulse_play ()) {
+ return -1;
+ }
+ if (0 != pulse_pause ()) {
+ return -1;
+ }
+ break;
+ }
+ return 0;
+}
+
static int pulse_free(void)
{
trace("pulse_free\n");
@@ -118,7 +227,7 @@ static int pulse_free(void)
pulse_tid = 0;
state = OUTPUT_STATE_STOPPED;
- if (s != NULL)
+ if (s)
{
pa_simple_free(s);
s = NULL;
@@ -170,41 +279,6 @@ static int pulse_unpause(void)
return 0;
}
-static int pulse_change_rate(int rate)
-{
- pulse_free();
- ss.rate = rate;
-
- if (!pulse_init())
- return -1;
-
- return ss.rate;
-}
-
-static int pulse_get_rate(void)
-{
- return ss.rate;
-}
-
-static int pulse_get_bps(void)
-{
- return 16;
-}
-
-static int pulse_get_channels(void)
-{
- return ss.channels;
-}
-
-static int pulse_get_endianness(void)
-{
-#if WORDS_BIGENDIAN
- return 1;
-#else
- return 0;
-#endif
-}
-
static void pulse_thread(void *context)
{
#ifdef __linux__
@@ -219,7 +293,14 @@ static void pulse_thread(void *context)
continue;
}
- char buf[buffer_size];
+ int sample_size = plugin.fmt.channels * (plugin.fmt.bps / 8);
+ int bs = buffer_size;
+ int mod = bs % sample_size;
+ if (mod > 0) {
+ bs -= mod;
+ }
+
+ char buf[bs];
pulse_callback (buf, sizeof (buf));
int error;
@@ -240,13 +321,6 @@ static void pulse_thread(void *context)
static void pulse_callback(char *stream, int len)
{
int bytesread = deadbeef->streamer_read(stream, len);
- int16_t ivolume = deadbeef->volume_get_amp() * 1000;
-
- for (int i = 0; i < bytesread/2; i++)
- {
- ((int16_t*)stream)[i] = (int16_t)(((int32_t)(((int16_t*)stream)[i])) * ivolume / 1000);
- }
-
if (bytesread < len)
{
memset (stream + bytesread, 0, len-bytesread);
@@ -280,34 +354,45 @@ DB_plugin_t * pulse_load(DB_functions_t *api)
static const char settings_dlg[] =
"property \"PulseAudio server\" entry " CONFSTR_PULSE_SERVERADDR " default;\n"
- "property \"Preferred buffer size\" entry " CONFSTR_PULSE_BUFFERSIZE " 4096;\n"
- "property \"Samplerate\" entry " CONFSTR_PULSE_SAMPLERATE " 44100;\n";
+ "property \"Preferred buffer size\" entry " CONFSTR_PULSE_BUFFERSIZE " 4096;\n";
static DB_output_t plugin =
{
DB_PLUGIN_SET_API_VERSION
.plugin.version_major = 0,
.plugin.version_minor = 1,
- .plugin.nostop = 0,
.plugin.type = DB_PLUGIN_OUTPUT,
+ .plugin.id = "pulseaudio",
.plugin.name = "PulseAudio output plugin",
- .plugin.descr = "plays sound via pulse API",
- .plugin.author = "Anton Novikov",
- .plugin.email = "tonn.post@gmail.com",
+ .plugin.descr = "At the moment of this writing, PulseAudio seems to be very unstable in many (or most) GNU/Linux distributions.\nIf you experience problems - please try switching to ALSA or OSS output.\nIf that doesn't help - please uninstall PulseAudio from your system, and try ALSA or OSS again.\nThanks for understanding",
+ .plugin.copyright =
+ "Copyright (C) 2011 Jan D. Behrens <zykure@web.de>\n"
+ "Copyright (C) 2010-2011 Alexey Yakovenko <waker@users.sourceforge.net>\n"
+ "Copyright (C) 2010 Anton Novikov <tonn.post@gmail.com>\n"
+ "\n"
+ "This program is free software; you can redistribute it and/or\n"
+ "modify it under the terms of the GNU General Public License\n"
+ "as published by the Free Software Foundation; either version 2\n"
+ "of the License, or (at your option) any later version.\n"
+ "\n"
+ "This program is distributed in the hope that it will be useful,\n"
+ "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+ "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+ "GNU General Public License for more details.\n"
+ "\n"
+ "You should have received a copy of the GNU General Public License\n"
+ "along with this program; if not, write to the Free Software\n"
+ "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n",
.plugin.website = "http://deadbeef.sf.net",
.plugin.start = pulse_plugin_start,
.plugin.stop = pulse_plugin_stop,
.plugin.configdialog = settings_dlg,
.init = pulse_init,
.free = pulse_free,
- .change_rate = pulse_change_rate,
+ .setformat = pulse_setformat,
.play = pulse_play,
.stop = pulse_stop,
.pause = pulse_pause,
.unpause = pulse_unpause,
.state = pulse_get_state,
- .samplerate = pulse_get_rate,
- .bitspersample = pulse_get_bps,
- .channels = pulse_get_channels,
- .endianness = pulse_get_endianness,
};
diff --git a/plugins/shellexec/Makefile.am b/plugins/shellexec/Makefile.am
index 65d6a5b8..212f6a0b 100644
--- a/plugins/shellexec/Makefile.am
+++ b/plugins/shellexec/Makefile.am
@@ -4,6 +4,6 @@ pkglib_LTLIBRARIES = shellexec.la
shellexec_la_SOURCES = shellexec.c
shellexec_la_LDFLAGS = -module
-shellexec_la_LIBADD = $(LDADD) $(HOTKEYS_LIBS)
+shellexec_la_LIBADD = $(LDADD)
AM_CFLAGS = $(CFLAGS) -std=c99
endif
diff --git a/plugins/shellexec/shellexec.c b/plugins/shellexec/shellexec.c
index e8298cab..a2c60af4 100644
--- a/plugins/shellexec/shellexec.c
+++ b/plugins/shellexec/shellexec.c
@@ -1,5 +1,6 @@
/*
Shellexec plugin for DeaDBeeF
+ Copyright (C) 2010-2011 Alexey Yakovenko <waker@users.sf.net>
Copyright (C) 2010 Viktor Semykin <thesame.ml@gmail.com>
This program is free software: you can redistribute it and/or modify
@@ -101,7 +102,7 @@ shx_callback (Shx_action_t *action, DB_playItem_t *it)
static DB_plugin_action_t *
shx_get_actions (DB_playItem_t *it)
{
- int is_local = it ? deadbeef->is_local_file (it->fname) : 1;
+ int is_local = it ? deadbeef->is_local_file (deadbeef->pl_find_meta (it, ":URI")) : 1;
Shx_action_t *action;
for (action = actions; action; action = (Shx_action_t *)action->parent.next)
@@ -200,12 +201,30 @@ shx_start ()
static DB_misc_t plugin = {
.plugin.api_vmajor = DB_API_VERSION_MAJOR,
.plugin.api_vminor = DB_API_VERSION_MINOR,
+ .plugin.version_major = 1,
+ .plugin.version_minor = 0,
.plugin.type = DB_PLUGIN_MISC,
.plugin.id = "shellexec",
.plugin.name = "Shell commands",
.plugin.descr = "Executes configurable shell commands for tracks",
- .plugin.author = "Viktor Semykin",
- .plugin.email = "thesame.ml@gmail.com",
+ .plugin.copyright =
+ "Copyright (C) 2010-2011 Alexey Yakovenko <waker@users.sf.net>\n"
+ "Copyright (C) 2010 Viktor Semykin <thesame.ml@gmail.com>\n"
+ "\n"
+ "This program is free software; you can redistribute it and/or\n"
+ "modify it under the terms of the GNU General Public License\n"
+ "as published by the Free Software Foundation; either version 2\n"
+ "of the License, or (at your option) any later version.\n"
+ "\n"
+ "This program is distributed in the hope that it will be useful,\n"
+ "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+ "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+ "GNU General Public License for more details.\n"
+ "\n"
+ "You should have received a copy of the GNU General Public License\n"
+ "along with this program; if not, write to the Free Software\n"
+ "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n"
+ ,
.plugin.website = "http://deadbeef.sf.net",
.plugin.start = shx_start,
.plugin.get_actions = shx_get_actions
diff --git a/plugins/shn/Makefile b/plugins/shn/Makefile
new file mode 100644
index 00000000..7ce0e430
--- /dev/null
+++ b/plugins/shn/Makefile
@@ -0,0 +1,22 @@
+OUT=shn.so
+
+CC=gcc
+
+CFLAGS+=-Wall -fPIC -std=c99 -D_GNU_SOURCE -DHAVE_CONFIG_H -I. -I../..
+
+LDFLAGS+=-module -shared -lm
+
+SOURCES=array.c convert.c misc.c output.c seek.c shn.c shorten.c sulawalaw.c vario.c wave.c
+
+OBJECTS=$(SOURCES:.c=.o)
+
+all: $(SOURCES) $(OUT)
+
+$(OUT): $(OBJECTS)
+ $(CC) $(LDFLAGS) $(OBJECTS) -o $@
+
+.c.o:
+ $(CC) $(CFLAGS) $< -c -o $@
+
+clean:
+ rm $(OBJECTS) $(OUT)
diff --git a/plugins/shn/Makefile.am b/plugins/shn/Makefile.am
deleted file mode 100644
index 335dacff..00000000
--- a/plugins/shn/Makefile.am
+++ /dev/null
@@ -1,10 +0,0 @@
-if HAVE_SHN
-shndir = $(libdir)/$(PACKAGE)
-pkglib_LTLIBRARIES = shn.la
-shn_la_SOURCES = array.c convert.c misc.c output.c seek.c shn.c shn.h shorten.c shorten.h sulawalaw.c vario.c wave.c bitshift.h
-
-shn_la_LDFLAGS = -module
-
-shn_la_LIBADD = $(LDADD) -lm
-AM_CFLAGS = $(CFLAGS) -std=c99
-endif
diff --git a/plugins/shn/shn.c b/plugins/shn/shn.c
index 1d44f6e8..4a90583c 100644
--- a/plugins/shn/shn.c
+++ b/plugins/shn/shn.c
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@@ -33,11 +33,6 @@ static DB_decoder_t plugin;
DB_functions_t *deadbeef;
shn_file *load_shn(const char *filename);
-static void shn_play(char *);
-static void shn_stop(void);
-static int shn_get_time(void);
-static void shn_get_file_info(char *,char **,int *);
-static void shn_display_file_info(char *);
typedef struct {
DB_fileinfo_t info;
@@ -67,7 +62,7 @@ typedef struct {
shn_config shn_cfg;
DB_fileinfo_t *
-shn_open (void) {
+shn_open (uint32_t hints) {
DB_fileinfo_t *_info = malloc (sizeof (shn_fileinfo_t));
shn_fileinfo_t *info = (shn_fileinfo_t *)_info;
memset (info, 0, sizeof (shn_fileinfo_t));
@@ -311,8 +306,9 @@ shn_init_decoder (shn_fileinfo_t *info) {
static void
shn_init_config (void) {
shn_cfg.error_output_method = ERROR_OUTPUT_DEVNULL;
- strncpy (shn_cfg.seek_tables_path, deadbeef->conf_get_str ("shn.seektable_path", ""), sizeof (shn_cfg.seek_tables_path));
- strncpy (shn_cfg.relative_seek_tables_path, deadbeef->conf_get_str ("shn.relative_seektable_path", "seektables"), sizeof (shn_cfg.relative_seek_tables_path));
+
+ deadbeef->conf_get_str ("shn.seektable_path", "", shn_cfg.seek_tables_path, sizeof (shn_cfg.seek_tables_path));
+ deadbeef->conf_get_str ("shn.relative_seektable_path", "seektables", shn_cfg.relative_seek_tables_path, sizeof (shn_cfg.relative_seek_tables_path));
shn_cfg.verbose = 0;
shn_cfg.swap_bytes = deadbeef->conf_get_int ("shn.swap_bytes", 0);
}
@@ -326,9 +322,9 @@ shn_init(DB_fileinfo_t *_info, DB_playItem_t *it) {
char data[4];
DB_FILE *f;
- f = deadbeef->fopen (it->fname);
+ f = deadbeef->fopen (deadbeef->pl_find_meta (it, ":URI"));
if (!f) {
- trace ("shn: failed to open %s\n", it->fname);
+ trace ("shn: failed to open %s\n", deadbeef->pl_find_meta (it, ":URI"));
return -1;
}
@@ -340,7 +336,7 @@ shn_init(DB_fileinfo_t *_info, DB_playItem_t *it) {
if (deadbeef->fread((void *)data,1,4,f) != 4)
{
deadbeef->fclose(f);
- trace ("shn: failed to read magic from %s\n", it->fname);
+ trace ("shn: failed to read magic from %s\n", deadbeef->pl_find_meta (it, ":URI"));
return -1;
}
deadbeef->fclose(f);
@@ -350,14 +346,17 @@ shn_init(DB_fileinfo_t *_info, DB_playItem_t *it) {
return -1;
}
- if (!(info->shnfile = load_shn(it->fname))) {
+ if (!(info->shnfile = load_shn(deadbeef->pl_find_meta (it, ":URI")))) {
trace ("shn: load_shn failed\n");
return -1;
}
- _info->bps = info->shnfile->wave_header.bits_per_sample;
- _info->channels = info->shnfile->wave_header.channels;
- _info->samplerate = info->shnfile->wave_header.samples_per_sec;
+ _info->fmt.bps = info->shnfile->wave_header.bits_per_sample;
+ _info->fmt.channels = info->shnfile->wave_header.channels;
+ _info->fmt.samplerate = info->shnfile->wave_header.samples_per_sec;
+ for (int i = 0; i < _info->fmt.channels; i++) {
+ _info->fmt.channelmask |= 1 << i;
+ }
_info->plugin = &plugin;
int totalsamples = info->shnfile->wave_header.length * info->shnfile->wave_header.samples_per_sec;
@@ -732,22 +731,21 @@ shn_decode (shn_fileinfo_t *info) {
}
int
-shn_read_int16 (DB_fileinfo_t *_info, char *bytes, int size) {
+shn_read (DB_fileinfo_t *_info, char *bytes, int size) {
shn_fileinfo_t *info = (shn_fileinfo_t *)_info;
- if (info->currentsample + size / (2 * _info->channels) > info->endsample) {
- size = (info->endsample - info->currentsample + 1) * 2 * _info->channels;
+ int samplesize = _info->fmt.channels * _info->fmt.bps / 8;
+ if (info->currentsample + size / samplesize > info->endsample) {
+ size = (info->endsample - info->currentsample + 1) * samplesize;
if (size <= 0) {
return 0;
}
}
int initsize = size;
- int ch = min (_info->channels, 2);
- int sample_size = ch * (_info->bps >> 3);
while (size > 0) {
if (info->shnfile->vars.bytes_in_buf > 0) {
- int n = size / sample_size;
- int nsamples = info->shnfile->vars.bytes_in_buf / (_info->channels * 2);
+ int n = size / samplesize;
+ int nsamples = info->shnfile->vars.bytes_in_buf / samplesize;
if (info->skipsamples > 0) {
int nskip = min(nsamples, info->skipsamples);
info->skipsamples -= nskip;
@@ -756,26 +754,23 @@ shn_read_int16 (DB_fileinfo_t *_info, char *bytes, int size) {
continue;
}
else {
- memmove (info->shnfile->vars.buffer, info->shnfile->vars.buffer + nskip * (_info->channels * 2), info->shnfile->vars.bytes_in_buf - nskip * (_info->channels * 2));
+ memmove (info->shnfile->vars.buffer, info->shnfile->vars.buffer + nskip * samplesize, info->shnfile->vars.bytes_in_buf - nskip * samplesize);
nsamples -= nskip;
continue;
}
}
n = min (nsamples, n);
- char *src = info->shnfile->vars.buffer;
- for (int i = 0; i < n; i++) {
- memcpy (bytes, src, sample_size);
- bytes += sample_size;
- src += _info->channels * 2;
- }
-
- size -= n * sample_size;
- if (n == info->shnfile->vars.bytes_in_buf / (_info->channels * 2)) {
+ char *src = (char *)info->shnfile->vars.buffer;
+ memcpy (bytes, src, samplesize * n);
+ src += samplesize * n;
+ bytes += samplesize * n;
+ size -= n * samplesize;
+ if (n == info->shnfile->vars.bytes_in_buf / samplesize) {
info->shnfile->vars.bytes_in_buf = 0;
}
else {
- memmove (info->shnfile->vars.buffer, src, info->shnfile->vars.bytes_in_buf - n * (_info->channels * 2));
- info->shnfile->vars.bytes_in_buf -= n * (_info->channels * 2);
+ memmove (info->shnfile->vars.buffer, src, info->shnfile->vars.bytes_in_buf - n * samplesize);
+ info->shnfile->vars.bytes_in_buf -= n * samplesize;
}
continue;
}
@@ -785,7 +780,7 @@ shn_read_int16 (DB_fileinfo_t *_info, char *bytes, int size) {
}
}
- info->currentsample += (initsize-size) / sample_size;
+ info->currentsample += (initsize-size) / samplesize;
if (size != 0) {
trace ("shn_read_int16 eof\n");
}
@@ -798,7 +793,7 @@ shn_seek_sample (DB_fileinfo_t *_info, int sample) {
sample += info->startsample;
- info->shnfile->vars.seek_to = sample / _info->samplerate;
+ info->shnfile->vars.seek_to = sample / _info->fmt.samplerate;
if (info->shnfile->vars.seek_table_entries == NO_SEEK_TABLE) {
// seek by skipping samples from the start
@@ -814,7 +809,7 @@ shn_seek_sample (DB_fileinfo_t *_info, int sample) {
}
info->skipsamples = sample;
}
- info->currentsample = info->shnfile->vars.seek_to * _info->samplerate;
+ info->currentsample = info->shnfile->vars.seek_to * _info->fmt.samplerate;
_info->readpos = info->shnfile->vars.seek_to;
return 0;
}
@@ -853,14 +848,14 @@ shn_seek_sample (DB_fileinfo_t *_info, int sample) {
info->shnfile->vars.bytes_in_buf = 0;
- info->currentsample = info->shnfile->vars.seek_to * _info->samplerate;
+ info->currentsample = info->shnfile->vars.seek_to * _info->fmt.samplerate;
_info->readpos = info->shnfile->vars.seek_to;
return 0;
}
int
shn_seek (DB_fileinfo_t *_info, float time) {
- return shn_seek_sample (_info, time * _info->samplerate);
+ return shn_seek_sample (_info, time * _info->fmt.samplerate);
return 0;
}
@@ -874,6 +869,7 @@ shn_insert (DB_playItem_t *after, const char *fname) {
if (!f) {
return NULL;
}
+ int64_t fsize = deadbeef->fgetlength (f);
int id3v2_tag_size = deadbeef->junk_get_leading_size (f);
if (id3v2_tag_size > 0) {
@@ -898,10 +894,8 @@ shn_insert (DB_playItem_t *after, const char *fname) {
return NULL;
}
- DB_playItem_t *it = deadbeef->pl_item_alloc ();
- it->decoder_id = deadbeef->plug_get_decoder_id (plugin.plugin.id);
- it->fname = strdup (fname);
- it->filetype = "Shorten";
+ DB_playItem_t *it = deadbeef->pl_item_alloc_init (fname, plugin.plugin.id);
+ deadbeef->pl_add_meta (it, ":FILETYPE", "Shorten");
deadbeef->pl_set_item_duration (it, tmp_file->wave_header.length);
int apeerr = deadbeef->junk_apev2_read (it, tmp_file->vars.fd);
@@ -910,6 +904,18 @@ shn_insert (DB_playItem_t *after, const char *fname) {
shn_unload(tmp_file);
+ char s[100];
+ snprintf (s, sizeof (s), "%lld", fsize);
+ deadbeef->pl_add_meta (it, ":FILE_SIZE", s);
+ snprintf (s, sizeof (s), "%d", tmp_file->wave_header.bits_per_sample);
+ deadbeef->pl_add_meta (it, ":BPS", s);
+ snprintf (s, sizeof (s), "%d", tmp_file->wave_header.channels);
+ deadbeef->pl_add_meta (it, ":CHANNELS", s);
+ snprintf (s, sizeof (s), "%d", tmp_file->wave_header.samples_per_sec);
+ deadbeef->pl_add_meta (it, ":SAMPLERATE", s);
+ int br = (int)roundf(fsize / (float)tmp_file->wave_header.length * 8 / 1000);
+ snprintf (s, sizeof (s), "%d", br);
+ deadbeef->pl_add_meta (it, ":BITRATE", s);
deadbeef->pl_add_meta (it, "title", NULL);
after = deadbeef->pl_insert_item (after, it);
@@ -1792,20 +1798,38 @@ static const char settings_dlg[] =
// define plugin interface
static DB_decoder_t plugin = {
DB_PLUGIN_SET_API_VERSION
- .plugin.version_major = 0,
- .plugin.version_minor = 1,
+ .plugin.version_major = 1,
+ .plugin.version_minor = 0,
.plugin.type = DB_PLUGIN_DECODER,
.plugin.id = "shn",
- .plugin.name = "SHN player",
- .plugin.descr = "SHN player based on xmms-shn",
- .plugin.author = "Alexey Yakovenko",
- .plugin.email = "waker@users.sourceforge.net",
+ .plugin.name = "Shorten player",
+ .plugin.descr = "decodes shn files",
+ .plugin.copyright =
+ "Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>\n"
+ "\n"
+ "Based on xmms-shn, http://www.etree.org/shnutils/xmms-shn/\n"
+ "Copyright (C) 2000-2007 Jason Jordan <shnutils@freeshell.org>\n"
+ "\n"
+ "This program is free software; you can redistribute it and/or\n"
+ "modify it under the terms of the GNU General Public License\n"
+ "as published by the Free Software Foundation; either version 2\n"
+ "of the License, or (at your option) any later version.\n"
+ "\n"
+ "This program is distributed in the hope that it will be useful,\n"
+ "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+ "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+ "GNU General Public License for more details.\n"
+ "\n"
+ "You should have received a copy of the GNU General Public License\n"
+ "along with this program; if not, write to the Free Software\n"
+ "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n"
+ ,
.plugin.website = "http://deadbeef.sf.net",
.plugin.configdialog = settings_dlg,
.open = shn_open,
.init = shn_init,
.free = shn_free,
- .read_int16 = shn_read_int16,
+ .read = shn_read,
.seek = shn_seek,
.seek_sample = shn_seek_sample,
.insert = shn_insert,
diff --git a/plugins/sid/Makefile.am b/plugins/sid/Makefile.am
index 38caa014..f5408088 100644
--- a/plugins/sid/Makefile.am
+++ b/plugins/sid/Makefile.am
@@ -103,9 +103,9 @@ sidplay-libs/libsidplay/src/kernal.bin\
sidplay-libs/libsidplay/src/psiddrv.bin\
sidplay-libs/libsidplay/src/poweron.bin
-sid_la_LIBADD = -lstdc++
-sid_la_LDFLAGS = -module
+sid_la_LDFLAGS = -module -nostdlib -lsupc++
AM_CFLAGS = $(CFLAGS) -std=c99 -I$(sidpath)/libsidplay/include -I$(sidpath)/builders/resid-builder/include -fPIC
-AM_CPPFLAGS = $(CXXFLAGS) -DHAVE_UNIX -I$(sidpath) -I$(sidpath)/unix -I$(sidpath)/libsidplay -I$(sidpath)/libsidplay/include -I$(sidpath)/libsidplay/include/sidplay -I$(sidpath)/libsidutils/include/sidplay/utils -I$(sidpath)/builders/resid-builder/include/sidplay/builders -I$(sidpath)/builders/resid-builder/include -DHAVE_STRCASECMP -DHAVE_STRNCASECMP
+AM_CPPFLAGS = $(CXXFLAGS) -DHAVE_UNIX -I$(sidpath) -I$(sidpath)/unix -I$(sidpath)/libsidplay -I$(sidpath)/libsidplay/include -I$(sidpath)/libsidplay/include/sidplay -I$(sidpath)/libsidutils/include/sidplay/utils -I$(sidpath)/builders/resid-builder/include/sidplay/builders -I$(sidpath)/builders/resid-builder/include -DHAVE_STRCASECMP -DHAVE_STRNCASECMP -fno-exceptions -fno-rtti -fno-unwind-tables
+
endif
diff --git a/plugins/sid/csid.cpp b/plugins/sid/csid.cpp
index ccb2ecb3..ffdd4548 100644
--- a/plugins/sid/csid.cpp
+++ b/plugins/sid/csid.cpp
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -34,12 +34,26 @@
#include "../../deadbeef.h"
#include "csid.h"
+#ifndef ANDROID
+int _Unwind_Resume_or_Rethrow;
+int _Unwind_RaiseException;
+int _Unwind_GetLanguageSpecificData;
+int _Unwind_Resume;
+int _Unwind_DeleteException;
+int _Unwind_GetTextRelBase;
+int _Unwind_SetIP;
+int _Unwind_GetDataRelBase;
+int _Unwind_GetRegionStart;
+int _Unwind_SetGR;
+int _Unwind_GetIPInfo;
+#endif
+
extern DB_decoder_t sid_plugin;
//#define trace(...) { fprintf(stderr, __VA_ARGS__); }
#define trace(fmt,...)
-static DB_functions_t *deadbeef;
+DB_functions_t *deadbeef;
#define min(x,y) ((x)<(y)?(x):(y))
#define max(x,y) ((x)>(y)?(x):(y))
@@ -94,8 +108,9 @@ sldb_load()
sldb_disable = 1;
return;
}
- const char *conf_hvsc_path = deadbeef->conf_get_str ("hvsc_path", NULL);
- if (!conf_hvsc_path) {
+ char conf_hvsc_path[1000];
+ deadbeef->conf_get_str ("hvsc_path", "", conf_hvsc_path, sizeof (conf_hvsc_path));
+ if (!conf_hvsc_path[0]) {
sldb_disable = 1;
return;
}
@@ -276,7 +291,7 @@ sldb_find (const uint8_t *digest) {
}
DB_fileinfo_t *
-csid_open (void) {
+csid_open (uint32_t hints) {
DB_fileinfo_t *_info = (DB_fileinfo_t *)malloc (sizeof (sid_info_t));
memset (_info, 0, sizeof (sid_info_t));
return _info;
@@ -288,26 +303,28 @@ csid_init (DB_fileinfo_t *_info, DB_playItem_t *it) {
// libsidplay crashes if file doesn't exist
// so i have to check it here
- FILE *fp = fopen (it->fname, "rb");
+ DB_FILE *fp = deadbeef->fopen (deadbeef->pl_find_meta (it, ":URI"));
if (!fp ){
return -1;
}
- fclose (fp);
+ deadbeef->fclose (fp);
info->sidplay = new sidplay2;
info->resid = new ReSIDBuilder ("wtf");
info->resid->create (info->sidplay->info ().maxsids);
-// resid->create (1);
info->resid->filter (true);
int samplerate = deadbeef->conf_get_int ("sid.samplerate", 44100);
- int bps = deadbeef->get_output ()->bitspersample ();
+ int bps = deadbeef->conf_get_int ("sid.bps", 16);
+ if (bps != 16 && bps != 8) {
+ bps = 16;
+ }
info->resid->sampling (samplerate);
info->duration = deadbeef->pl_get_item_duration (it);
- info->tune = new SidTune (it->fname);
+ info->tune = new SidTune (deadbeef->pl_find_meta (it, ":URI"));
- info->tune->selectSong (it->tracknum+1);
+ info->tune->selectSong (deadbeef->pl_find_meta_int (it, ":TRACKNUM", 0)+1);
sid2_config_t conf;
conf = info->sidplay->config ();
conf.frequency = samplerate;
@@ -319,9 +336,10 @@ csid_init (DB_fileinfo_t *_info, DB_playItem_t *it) {
info->sidplay->load (info->tune);
_info->plugin = &sid_plugin;
- _info->channels = info->tune->isStereo () ? 2 : 1;
- _info->bps = bps;
- _info->samplerate = conf.frequency;
+ _info->fmt.channels = conf.playback == sid2_stereo ? 2 : 1;
+ _info->fmt.bps = bps;
+ _info->fmt.samplerate = conf.frequency;
+ _info->fmt.channelmask = _info->fmt.channels == 1 ? DDB_SPEAKER_FRONT_LEFT : (DDB_SPEAKER_FRONT_LEFT | DDB_SPEAKER_FRONT_RIGHT);
_info->readpos = 0;
int maxsids = info->sidplay->info ().maxsids;
@@ -354,24 +372,15 @@ csid_read (DB_fileinfo_t *_info, char *bytes, int size) {
if (_info->readpos > info->duration) {
return 0;
}
- int rd = info->sidplay->play (bytes, size/_info->channels);
- _info->readpos += size/_info->channels/2 / (float)_info->samplerate;
-#if 0
-#if WORDS_BIGENDIAN
- // convert samples from le to be
- int n = rd * _info->channels/2;
- int16_t *ptr = (int16_t *)bytes;
- while (n > 0) {
- int16_t out;
- le_int16 (*ptr, (unsigned char *)&out);
- *ptr = out;
- ptr++;
- n--;
- }
-#endif
-#endif
- return rd * _info->channels;
+ int rd = info->sidplay->play (bytes, size);
+
+ int samplesize = (_info->fmt.bps>>3) * _info->fmt.channels;
+
+ _info->readpos += rd / samplesize / (float)_info->fmt.samplerate;
+
+ return size;
+
}
int
@@ -386,11 +395,11 @@ csid_seek (DB_fileinfo_t *_info, float time) {
t -= _info->readpos;
}
info->resid->filter (false);
- int samples = t * _info->samplerate;
- samples *= 2 * _info->channels;
- uint16_t buffer[2048 * _info->channels];
+ int samples = t * _info->fmt.samplerate;
+ samples *= (_info->fmt.bps>>3) * _info->fmt.channels;
+ uint16_t buffer[2048 * _info->fmt.channels];
while (samples > 0) {
- int n = min (samples, 2048) * _info->channels;
+ int n = min (samples, 2048) * _info->fmt.channels;
int done = info->sidplay->play (buffer, n);
if (done < n) {
trace ("sid seek failure\n");
@@ -478,15 +487,13 @@ csid_insert (DB_playItem_t *after, const char *fname) {
// Include number of songs.
endian_little16 (tmp,tune->getInfo ().songs);
myMD5.append (tmp,sizeof(tmp));
- { // Include song speed for each song.
- //uint_least16_t currentSong = tune->getInfo ().currentSong;
+ {
+ // Include song speed for each song.
for (uint_least16_t s = 1; s <= tune->getInfo ().songs; s++)
{
tune->selectSong (s);
myMD5.append (&tune->getInfo ().songSpeed,1);
}
- // Restore old song
- //tune->selectSong (currentSong);
}
// Deal with PSID v2NG clock speed flags: Let only NTSC
// clock speed change the MD5 fingerprint. That way the
@@ -499,7 +506,6 @@ csid_insert (DB_playItem_t *after, const char *fname) {
memcpy (sig, myMD5.getDigest (), 16);
#endif
-// sldb_load ();
int song = -1;
if (sldb_loaded) {
song = sldb_find (sig);
@@ -509,10 +515,8 @@ csid_insert (DB_playItem_t *after, const char *fname) {
for (int s = 0; s < tunes; s++) {
trace ("select %d...\n", s);
if (tune->selectSong (s+1)) {
- DB_playItem_t *it = deadbeef->pl_item_alloc ();
- it->decoder_id = deadbeef->plug_get_decoder_id (sid_plugin.plugin.id);
- it->fname = strdup (fname);
- it->tracknum = s;
+ DB_playItem_t *it = deadbeef->pl_item_alloc_init (fname, sid_plugin.plugin.id);
+ deadbeef->pl_set_meta_int (it, ":TRACKNUM", s);
SidTuneInfo sidinfo;
tune->getInfo (sidinfo);
int i = sidinfo.numberOfInfoStrings;
@@ -549,7 +553,7 @@ csid_insert (DB_playItem_t *after, const char *fname) {
deadbeef->pl_add_meta (it, "title", NULL);
}
- float length = 120;
+ float length = deadbeef->conf_get_float ("sid.defaultlength", 180);
if (sldb_loaded) {
if (song >= 0 && sldb->sldb_lengths[song][s] >= 0) {
length = sldb->sldb_lengths[song][s];
@@ -563,7 +567,7 @@ csid_insert (DB_playItem_t *after, const char *fname) {
// }
}
deadbeef->pl_set_item_duration (it, length);
- it->filetype = "SID";
+ deadbeef->pl_add_meta (it, ":FILETYPE", "SID");
after = deadbeef->pl_insert_item (after, it);
deadbeef->pl_item_unref (it);
diff --git a/plugins/sid/csid.h b/plugins/sid/csid.h
index 273daa2c..c35be3d7 100644
--- a/plugins/sid/csid.h
+++ b/plugins/sid/csid.h
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -23,7 +23,7 @@
extern "C" {
#endif
-DB_fileinfo_t *csid_open (void);
+DB_fileinfo_t *csid_open (uint32_t hints);
int csid_init (DB_fileinfo_t *_info, DB_playItem_t *it);
void csid_free (DB_fileinfo_t *);
int csid_read (DB_fileinfo_t *, char *bytes, int size);
diff --git a/plugins/sid/plugin.c b/plugins/sid/plugin.c
index 9a2e9a27..c8f1f7b0 100644
--- a/plugins/sid/plugin.c
+++ b/plugins/sid/plugin.c
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -22,21 +22,42 @@ static const char *exts[] = { "sid",NULL };
const char *filetypes[] = { "SID", NULL };
static const char settings_dlg[] =
- "property \"Enable HVSC\" checkbox hvsc_enable 0;\n"
- "property \"HVSC path\" file hvsc_path \"\";\n"
- "property \"Samplerate\" entry sid.samplerate 48000;\n"
+ "property \"Enable HVSC Songlength DB\" checkbox hvsc_enable 0;\n"
+ "property \"Songlengths.txt (from HVSC)\" file hvsc_path \"\";\n"
+ "property \"Samplerate\" entry sid.samplerate 44100;\n"
+ "property \"Bits per sample (8 or 16)\" entry sid.bps 16;\n"
+ "property \"Default song length (sec)\" entry sid.defaultlength 180;\n"
;
// define plugin interface
DB_decoder_t sid_plugin = {
DB_PLUGIN_SET_API_VERSION
.plugin.type = DB_PLUGIN_DECODER,
- .plugin.version_major = 0,
- .plugin.version_minor = 1,
+ .plugin.version_major = 1,
+ .plugin.version_minor = 0,
.plugin.name = "SID decoder",
.plugin.descr = "SID player based on libsidplay2",
- .plugin.author = "Alexey Yakovenko",
- .plugin.email = "waker@users.sourceforge.net",
+ .plugin.copyright =
+ "Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>\n"
+ "\n"
+ "Uses modified libsidplay2-2.1.0\n"
+ "Commodore 64 SID emulation library\n"
+ "Copyright (C) Simon White and other authors\n"
+ "\n"
+ "This program is free software; you can redistribute it and/or\n"
+ "modify it under the terms of the GNU General Public License\n"
+ "as published by the Free Software Foundation; either version 2\n"
+ "of the License, or (at your option) any later version.\n"
+ "\n"
+ "This program is distributed in the hope that it will be useful,\n"
+ "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+ "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+ "GNU General Public License for more details.\n"
+ "\n"
+ "You should have received a copy of the GNU General Public License\n"
+ "along with this program; if not, write to the Free Software\n"
+ "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n"
+ ,
.plugin.website = "http://deadbeef.sf.net",
.plugin.start = csid_start,
.plugin.stop = csid_stop,
@@ -45,7 +66,7 @@ DB_decoder_t sid_plugin = {
.open = csid_open,
.init = csid_init,
.free = csid_free,
- .read_int16 = csid_read,
+ .read = csid_read,
.seek = csid_seek,
.seek_sample = NULL,
.insert = csid_insert,
diff --git a/plugins/sid/sidplay-libs/libsidplay/src/sidtune/SidTune.cpp b/plugins/sid/sidplay-libs/libsidplay/src/sidtune/SidTune.cpp
index 4dfba1d7..fdbd64e1 100644
--- a/plugins/sid/sidplay-libs/libsidplay/src/sidtune/SidTune.cpp
+++ b/plugins/sid/sidplay-libs/libsidplay/src/sidtune/SidTune.cpp
@@ -25,6 +25,7 @@
#include "sidendian.h"
#include "PP20.h"
#include <stdio.h>
+#include "../../../../../../../deadbeef.h"
#ifdef HAVE_EXCEPTIONS
# include <new>
@@ -32,6 +33,8 @@
#include <string.h>
#include <limits.h>
+extern DB_functions_t *deadbeef;
+
#if defined(HAVE_IOS_OPENMODE)
typedef std::ios::openmode openmode;
#else
@@ -252,7 +255,7 @@ bool SidTune::loadFile(const char* fileName, Buffer_sidtt<const uint_least8_t>&
Buffer_sidtt<uint_least8_t> fileBuf;
uint_least32_t fileLen = 0;
- FILE *fp = fopen (fileName, "rb");
+ DB_FILE *fp = deadbeef->fopen (fileName);
if (!fp)
{
@@ -261,9 +264,7 @@ bool SidTune::loadFile(const char* fileName, Buffer_sidtt<const uint_least8_t>&
}
else
{
- fseek (fp, 0, SEEK_END);
- fileLen = ftell (fp);
- rewind (fp);
+ fileLen = deadbeef->fgetlength(fp);
#ifdef HAVE_EXCEPTIONS
if ( !fileBuf.assign(new(std::nothrow) uint_least8_t[fileLen],fileLen) )
#else
@@ -274,7 +275,7 @@ bool SidTune::loadFile(const char* fileName, Buffer_sidtt<const uint_least8_t>&
return false;
}
uint_least32_t restFileLen = fileLen;
- int res = fread((char*)fileBuf.get()+(fileLen-restFileLen),1,restFileLen,fp);
+ int res = deadbeef->fread((char*)fileBuf.get()+(fileLen-restFileLen),1,restFileLen,fp);
if ( res != restFileLen )
{
info.statusString = SidTune::txt_cantLoadFile;
@@ -285,7 +286,7 @@ bool SidTune::loadFile(const char* fileName, Buffer_sidtt<const uint_least8_t>&
info.statusString = SidTune::txt_noErrors;
}
}
- fclose(fp);
+ deadbeef->fclose(fp);
if ( fileLen==0 )
{
info.statusString = SidTune::txt_empty;
diff --git a/plugins/sndfile/sndfile.c b/plugins/sndfile/sndfile.c
index ab1d1ee9..3af4616f 100644
--- a/plugins/sndfile/sndfile.c
+++ b/plugins/sndfile/sndfile.c
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@@ -21,6 +21,8 @@
#endif
#include <string.h>
#include <sndfile.h>
+#include <math.h>
+#include <stdlib.h>
#include "../../deadbeef.h"
#define min(x,y) ((x)<(y)?(x):(y))
@@ -85,20 +87,78 @@ static SF_VIRTUAL_IO vfs = {
};
static DB_fileinfo_t *
-sndfile_open (void) {
+sndfile_open (uint32_t hints) {
DB_fileinfo_t *_info = malloc (sizeof (sndfile_info_t));
memset (_info, 0, sizeof (sndfile_info_t));
return _info;
}
+
+// taken from libsndfile
+#define ARRAY_LEN(x) ((int) (sizeof (x) / sizeof ((x) [0])))
+/* This stores which bit in dwChannelMask maps to which channel */
+static const struct chanmap_s
+{ int id ;
+ const char * name ;
+} channel_mask_bits [] =
+{ /* WAVEFORMATEXTENSIBLE doesn't distuingish FRONT_LEFT from LEFT */
+ { SF_CHANNEL_MAP_LEFT, "L" },
+ { SF_CHANNEL_MAP_RIGHT, "R" },
+ { SF_CHANNEL_MAP_CENTER, "C" },
+ { SF_CHANNEL_MAP_LFE, "LFE" },
+ { SF_CHANNEL_MAP_REAR_LEFT, "Ls" },
+ { SF_CHANNEL_MAP_REAR_RIGHT, "Rs" },
+ { SF_CHANNEL_MAP_FRONT_LEFT_OF_CENTER, "Lc" },
+ { SF_CHANNEL_MAP_FRONT_RIGHT_OF_CENTER, "Rc" },
+ { SF_CHANNEL_MAP_REAR_CENTER, "Cs" },
+ { SF_CHANNEL_MAP_SIDE_LEFT, "Sl" },
+ { SF_CHANNEL_MAP_SIDE_RIGHT, "Sr" },
+ { SF_CHANNEL_MAP_TOP_CENTER, "Tc" },
+ { SF_CHANNEL_MAP_TOP_FRONT_LEFT, "Tfl" },
+ { SF_CHANNEL_MAP_TOP_FRONT_CENTER, "Tfc" },
+ { SF_CHANNEL_MAP_TOP_FRONT_RIGHT, "Tfr" },
+ { SF_CHANNEL_MAP_TOP_REAR_LEFT, "Trl" },
+ { SF_CHANNEL_MAP_TOP_REAR_CENTER, "Trc" },
+ { SF_CHANNEL_MAP_TOP_REAR_RIGHT, "Trr" },
+} ;
+
+
+static int
+wavex_gen_channel_mask (const int *chan_map, int channels)
+{ int chan, mask = 0, bit = -1, last_bit = -1 ;
+
+ if (chan_map == NULL)
+ return 0 ;
+
+ for (chan = 0 ; chan < channels ; chan ++)
+ { int k ;
+
+ for (k = bit + 1 ; k < ARRAY_LEN (channel_mask_bits) ; k++)
+ if (chan_map [chan] == channel_mask_bits [k].id)
+ { bit = k ;
+ break ;
+ } ;
+
+ /* Check for bad sequence. */
+ if (bit <= last_bit)
+ return 0 ;
+
+ mask += 1 << bit ;
+ last_bit = bit ;
+ } ;
+
+ return mask ;
+} /* wavex_gen_channel_mask */
+
+
static int
sndfile_init (DB_fileinfo_t *_info, DB_playItem_t *it) {
sndfile_info_t *info = (sndfile_info_t*)_info;
SF_INFO inf;
- DB_FILE *fp = deadbeef->fopen (it->fname);
+ DB_FILE *fp = deadbeef->fopen (deadbeef->pl_find_meta (it, ":URI"));
if (!fp) {
- trace ("sndfile: failed to open %s\n", it->fname);
+ trace ("sndfile: failed to open %s\n", deadbeef->pl_find_meta (it, ":URI"));
return -1;
}
int fsize = deadbeef->fgetlength (fp);
@@ -114,27 +174,45 @@ sndfile_init (DB_fileinfo_t *_info, DB_playItem_t *it) {
switch (inf.format&0x000f) {
case SF_FORMAT_PCM_S8:
case SF_FORMAT_PCM_U8:
- _info->bps = 8;
+ _info->fmt.bps = 8;
break;
case SF_FORMAT_PCM_16:
- _info->bps = 16;
+ _info->fmt.bps = 16;
break;
case SF_FORMAT_PCM_24:
- _info->bps = 24;
+ _info->fmt.bps = 24;
break;
- case SF_FORMAT_PCM_32:
case SF_FORMAT_FLOAT:
- _info->bps = 24;
+ _info->fmt.is_float = 1;
+ case SF_FORMAT_PCM_32:
+ _info->fmt.bps = 32;
break;
case SF_FORMAT_DOUBLE:
- _info->bps = 64;
+ fprintf (stderr, "[sndfile] 64 bit float input format is not supported (yet)\n");
+ return -1;
+// _info->fmt.bps = 64;
break;
default:
- _info->bps = 16;
+ fprintf (stderr, "[sndfile] unidentified input format: 0x%X\n", inf.format&0x000f);
+ return -1;
+ }
+
+ _info->fmt.channels = inf.channels;
+ _info->fmt.samplerate = inf.samplerate;
+
+ int channel_map [inf.channels];
+ int cmdres = sf_command (info->ctx, SFC_GET_CHANNEL_MAP_INFO, channel_map, sizeof (channel_map)) ;
+ if (cmdres != SF_FALSE) {
+ // channel map found, convert to channel mask
+ _info->fmt.channelmask = wavex_gen_channel_mask (channel_map, inf.channels);
+ }
+ else {
+ // channel map not found, generate from channel number
+ for (int i = 0; i < inf.channels; i++) {
+ _info->fmt.channelmask |= 1 << i;
+ }
}
- _info->channels = inf.channels;
- _info->samplerate = inf.samplerate;
_info->readpos = 0;
if (it->endsample > 0) {
info->startsample = it->startsample;
@@ -148,7 +226,9 @@ sndfile_init (DB_fileinfo_t *_info, DB_playItem_t *it) {
info->endsample = inf.frames-1;
}
// hack bitrate
- float sec = (float)(info->endsample-info->startsample) / inf.samplerate;
+
+ int totalsamples = inf.frames;
+ float sec = (float)totalsamples / inf.samplerate;
if (sec > 0) {
info->bitrate = fsize / sec * 8 / 1000;
}
@@ -172,11 +252,11 @@ sndfile_free (DB_fileinfo_t *_info) {
}
static int
-sndfile_read_int16 (DB_fileinfo_t *_info, char *bytes, int size) {
+sndfile_read (DB_fileinfo_t *_info, char *bytes, int size) {
sndfile_info_t *info = (sndfile_info_t*)_info;
- int out_ch = min (_info->channels, 2);
- if (size / (2 * out_ch) + info->currentsample > info->endsample) {
- size = (info->endsample - info->currentsample + 1) * 2 * out_ch;
+ int samplesize = _info->fmt.channels * _info->fmt.bps / 8;
+ if (size / samplesize + info->currentsample > info->endsample) {
+ size = (info->endsample - info->currentsample + 1) * samplesize;
trace ("sndfile: size truncated to %d bytes, cursample=%d, endsample=%d\n", size, info->currentsample, info->endsample);
if (size <= 0) {
return 0;
@@ -184,61 +264,12 @@ sndfile_read_int16 (DB_fileinfo_t *_info, char *bytes, int size) {
}
int n = 0;
- if (out_ch != _info->channels) {
- // read into temp buffer, and downmix
- int nframes = size / out_ch / 2;
- int16_t buf[nframes * _info->channels];
- n = sf_readf_short (info->ctx, buf, nframes);
- for (int i = 0; i < n; i++) {
- for (int j = 0; j < out_ch; j++) {
- ((int16_t *)bytes)[i * out_ch + j] = buf[i * _info->channels + j];
- }
- }
- }
- else {
- n = sf_readf_short (info->ctx, (short *)bytes, size/(2*_info->channels));
- }
+ n = sf_read_raw (info->ctx, (short *)bytes, size);
+ n /= samplesize;
info->currentsample += n;
-
- size = n * 2 * out_ch;
- _info->readpos = (float)(info->currentsample-info->startsample)/_info->samplerate;
- if (info->bitrate > 0) {
- deadbeef->streamer_set_bitrate (info->bitrate);
- }
- return size;
-}
-
-static int
-sndfile_read_float32 (DB_fileinfo_t *_info, char *bytes, int size) {
- sndfile_info_t *info = (sndfile_info_t*)_info;
- int out_ch = min (_info->channels, 2);
- if (size / (4 * out_ch) + info->currentsample > info->endsample) {
- size = (info->endsample - info->currentsample + 1) * 4 * out_ch;
- trace ("sndfile: size truncated to %d bytes, cursample=%d, endsample=%d\n", size, info->currentsample, info->endsample);
- if (size <= 0) {
- return 0;
- }
- }
- int n = 0;
- if (out_ch != _info->channels) {
- // read into temp buffer, and downmix
- int nframes = size / out_ch / 4;
- float buf[nframes * _info->channels];
- n = sf_readf_float (info->ctx, buf, nframes);
- for (int i = 0; i < n; i++) {
- for (int j = 0; j < out_ch; j++) {
- ((float *)bytes)[i * out_ch + j] = buf[i * _info->channels + j];
- }
- }
- }
- else {
- n = sf_readf_float (info->ctx, (float *)bytes, size/(4*_info->channels));
- }
-
- info->currentsample += n;
- size = n * 4 * out_ch;
- _info->readpos = (float)(info->currentsample-info->startsample)/_info->samplerate;
+ size = n * samplesize;
+ _info->readpos = (float)(info->currentsample-info->startsample)/_info->fmt.samplerate;
if (info->bitrate > 0) {
deadbeef->streamer_set_bitrate (info->bitrate);
}
@@ -253,13 +284,13 @@ sndfile_seek_sample (DB_fileinfo_t *_info, int sample) {
return -1;
}
info->currentsample = ret;
- _info->readpos = (float)(info->currentsample - info->startsample) / _info->samplerate;
+ _info->readpos = (float)(info->currentsample - info->startsample) / _info->fmt.samplerate;
return 0;
}
static int
sndfile_seek (DB_fileinfo_t *_info, float sec) {
- return sndfile_seek_sample (_info, sec * _info->samplerate);
+ return sndfile_seek_sample (_info, sec * _info->fmt.samplerate);
}
static DB_playItem_t *
@@ -272,6 +303,7 @@ sndfile_insert (DB_playItem_t *after, const char *fname) {
trace ("sndfile: failed to open %s\n", fname);
return NULL;
}
+ int64_t fsize = deadbeef->fgetlength (info.file);
info.ctx = sf_open_virtual (&vfs, SFM_READ, &inf, &info);
if (!info.ctx) {
trace ("sndfile: sf_open failed");
@@ -284,14 +316,45 @@ sndfile_insert (DB_playItem_t *after, const char *fname) {
deadbeef->fclose (info.file);
float duration = (float)totalsamples / samplerate;
- DB_playItem_t *it = deadbeef->pl_item_alloc ();
- it->decoder_id = deadbeef->plug_get_decoder_id (plugin.plugin.id);
- it->fname = strdup (fname);
- it->filetype = "wav";
+ DB_playItem_t *it = deadbeef->pl_item_alloc_init (fname, plugin.plugin.id);
+ deadbeef->pl_add_meta (it, ":FILETYPE", "wav");
deadbeef->pl_set_item_duration (it, duration);
trace ("sndfile: totalsamples=%d, samplerate=%d, duration=%f\n", totalsamples, samplerate, duration);
+ char s[100];
+ snprintf (s, sizeof (s), "%lld", fsize);
+ deadbeef->pl_add_meta (it, ":FILE_SIZE", s);
+
+ int bps = -1;
+ switch (inf.format&0x000f) {
+ case SF_FORMAT_PCM_S8:
+ case SF_FORMAT_PCM_U8:
+ bps = 8;
+ break;
+ case SF_FORMAT_PCM_16:
+ bps = 16;
+ break;
+ case SF_FORMAT_PCM_24:
+ bps = 24;
+ break;
+ case SF_FORMAT_FLOAT:
+ case SF_FORMAT_PCM_32:
+ bps = 32;
+ break;
+ }
+
+ snprintf (s, sizeof (s), "%d", bps);
+ deadbeef->pl_add_meta (it, ":BPS", s);
+ snprintf (s, sizeof (s), "%d", inf.channels);
+ deadbeef->pl_add_meta (it, ":CHANNELS", s);
+ snprintf (s, sizeof (s), "%d", samplerate);
+ deadbeef->pl_add_meta (it, ":SAMPLERATE", s);
+ int br = (int)roundf(fsize / duration * 8 / 1000);
+ snprintf (s, sizeof (s), "%d", br);
+ deadbeef->pl_add_meta (it, ":BITRATE", s);
+
+
DB_playItem_t *cue_after = deadbeef->pl_insert_cue (after, it, totalsamples, samplerate);
if (cue_after) {
deadbeef->pl_item_unref (it);
@@ -306,31 +369,116 @@ sndfile_insert (DB_playItem_t *after, const char *fname) {
return after;
}
-static const char * exts[] = { "wav", "aif", "aiff", "snd", "au", "paf", "svx", "nist", "voc", "ircam", "w64", "mat4", "mat5", "pvf", "xi", "htk", "sds", "avr", "wavex", "sd2", "caf", "wve", NULL };
+#define DEFAULT_EXTS "wav;aif;aiff;snd;au;paf;svx;nist;voc;ircam;w64;mat4;mat5;pvf;xi;htk;sds;avr;wavex;sd2;caf;wve"
+
+#define EXT_MAX 100
+
+static char *exts[EXT_MAX] = {NULL};
static const char *filetypes[] = { "WAV", NULL };
+
+static void
+sndfile_init_exts (void) {
+ for (int i = 0; exts[i]; i++) {
+ free (exts[i]);
+ }
+ exts[0] = NULL;
+
+ int n = 0;
+ deadbeef->conf_lock ();
+ const char *new_exts = deadbeef->conf_get_str_fast ("sndfile.extensions", DEFAULT_EXTS);
+ while (*new_exts) {
+ if (n >= EXT_MAX) {
+ fprintf (stderr, "sndfile: too many extensions, max is %d\n", EXT_MAX);
+ break;
+ }
+ const char *e = new_exts;
+ while (*e && *e != ';') {
+ e++;
+ }
+ if (e != new_exts) {
+ char *ext = malloc (e-new_exts+1);
+ memcpy (ext, new_exts, e-new_exts);
+ ext[e-new_exts] = 0;
+ exts[n++] = ext;
+ }
+ if (*e == 0) {
+ break;
+ }
+ new_exts = e+1;
+ }
+ deadbeef->conf_unlock ();
+ exts[n] = NULL;
+}
+
+
+static int
+sndfile_on_configchanged (DB_event_t *ev, uintptr_t data) {
+ sndfile_init_exts ();
+ return 0;
+}
+
+static int
+sndfile_start (void) {
+ sndfile_init_exts ();
+ deadbeef->ev_subscribe (DB_PLUGIN (&plugin), DB_EV_CONFIGCHANGED, DB_CALLBACK (sndfile_on_configchanged), 0);
+ return 0;
+}
+
+static int
+sndfile_stop (void) {
+ deadbeef->ev_unsubscribe (DB_PLUGIN (&plugin), DB_EV_CONFIGCHANGED, DB_CALLBACK (sndfile_on_configchanged), 0);
+ for (int i = 0; exts[i]; i++) {
+ free (exts[i]);
+ }
+ exts[0] = NULL;
+ return 0;
+}
+
+static const char settings_dlg[] =
+ "property \"File Extensions (separate with ';')\" entry sndfile.extensions \"" DEFAULT_EXTS "\";\n"
+;
+
+
// define plugin interface
static DB_decoder_t plugin = {
DB_PLUGIN_SET_API_VERSION
- .plugin.version_major = 0,
- .plugin.version_minor = 1,
+ .plugin.version_major = 1,
+ .plugin.version_minor = 0,
.plugin.type = DB_PLUGIN_DECODER,
.plugin.id = "sndfile",
- .plugin.name = "pcm player",
+ .plugin.name = "WAV/PCM player",
.plugin.descr = "wav/aiff player using libsndfile",
- .plugin.author = "Alexey Yakovenko",
- .plugin.email = "waker@users.sourceforge.net",
+ .plugin.copyright =
+ "Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>\n"
+ "\n"
+ "This program is free software; you can redistribute it and/or\n"
+ "modify it under the terms of the GNU General Public License\n"
+ "as published by the Free Software Foundation; either version 2\n"
+ "of the License, or (at your option) any later version.\n"
+ "\n"
+ "This program is distributed in the hope that it will be useful,\n"
+ "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+ "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+ "GNU General Public License for more details.\n"
+ "\n"
+ "You should have received a copy of the GNU General Public License\n"
+ "along with this program; if not, write to the Free Software\n"
+ "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n"
+ ,
.plugin.website = "http://deadbeef.sf.net",
.open = sndfile_open,
.init = sndfile_init,
.free = sndfile_free,
- .read_int16 = sndfile_read_int16,
- .read_float32 = sndfile_read_float32,
+ .read = sndfile_read,
.seek = sndfile_seek,
.seek_sample = sndfile_seek_sample,
.insert = sndfile_insert,
- .exts = exts,
- .filetypes = filetypes
+ .exts = (const char **)exts,
+ .filetypes = filetypes,
+ .plugin.start = sndfile_start,
+ .plugin.stop = sndfile_stop,
+ .plugin.configdialog = settings_dlg,
};
DB_plugin_t *
diff --git a/plugins/soundtouch/Makefile b/plugins/soundtouch/Makefile
new file mode 100644
index 00000000..ce4a0ad0
--- /dev/null
+++ b/plugins/soundtouch/Makefile
@@ -0,0 +1,52 @@
+CC=gcc
+CXX=g++
+
+OUT=ddb_soundtouch.so
+
+soundtouch_path=soundtouch
+
+CFLAGS+=-Wall -g -D_GNU_SOURCE -I$(soundtouch_path)/include -I../../include -std=c99 -fPIC -msse2
+CXXFLAGS+=-Wall -g -D_GNU_SOURCE -I$(soundtouch_path)/include -I../../include -fPIC -msse2
+
+LDFLAGS+=-shared -lm
+
+SOURCES=plugin.c
+
+CXX_SOURCES=st.cpp\
+$(soundtouch_path)/source/SoundTouch/AAFilter.cpp\
+$(soundtouch_path)/source/SoundTouch/BPMDetect.cpp\
+$(soundtouch_path)/source/SoundTouch/cpu_detect_x86_gcc.cpp\
+$(soundtouch_path)/source/SoundTouch/FIFOSampleBuffer.cpp\
+$(soundtouch_path)/source/SoundTouch/FIRFilter.cpp\
+$(soundtouch_path)/source/SoundTouch/mmx_optimized.cpp\
+$(soundtouch_path)/source/SoundTouch/PeakFinder.cpp\
+$(soundtouch_path)/source/SoundTouch/RateTransposer.cpp\
+$(soundtouch_path)/source/SoundTouch/SoundTouch.cpp\
+$(soundtouch_path)/source/SoundTouch/sse_optimized.cpp\
+$(soundtouch_path)/source/SoundTouch/TDStretch.cpp
+
+HEADERS=st.h\
+$(soundtouch_path)/include/BPMDetect.h\
+$(soundtouch_path)/include/FIFOSampleBuffer.h\
+$(soundtouch_path)/include/FIFOSamplePipe.h\
+$(soundtouch_path)/include/soundtouch_config.h\
+$(soundtouch_path)/include/SoundTouch.h\
+$(soundtouch_path)/include/STTypes.h
+
+CXX_OBJECTS=$(CXX_SOURCES:.cpp=.o)
+OBJECTS=$(SOURCES:.c=.o)
+
+all: $(SOURCES) $(OUT)
+
+$(OUT): $(OBJECTS) $(CXX_OBJECTS)
+ $(CXX) $(LDFLAGS) $(OBJECTS) $(CXX_OBJECTS) -o $@
+
+.c.o: $(HEADERS)
+ $(CC) $(CFLAGS) $< -c -o $@
+
+.cpp.o: $(HEADERS)
+ $(CXX) $(CXXFLAGS) $< -c -o $@
+
+clean:
+ rm $(OBJECTS) $(CXX_OBJECTS) $(OUT)
+
diff --git a/plugins/soundtouch/plugin.c b/plugins/soundtouch/plugin.c
new file mode 100644
index 00000000..42b633ac
--- /dev/null
+++ b/plugins/soundtouch/plugin.c
@@ -0,0 +1,308 @@
+/*
+ DeaDBeeF - ultimate music player for GNU/Linux systems with X11
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include "../../deadbeef.h"
+#include "st.h"
+
+enum {
+ ST_PARAM_TEMPO,
+ ST_PARAM_PITCH,
+ ST_PARAM_RATE,
+ ST_PARAM_USE_AA_FILTER,
+ ST_PARAM_AA_FILTER_LENGTH,
+ ST_PARAM_USE_QUICKSEEK,
+ ST_PARAM_SEQUENCE_MS,
+ ST_PARAM_SEEKWINDOW_MS,
+ ST_PARAM_SET_OUTPUT_SAMPLERATE,
+ ST_PARAM_COUNT
+};
+
+static DB_functions_t *deadbeef;
+static DB_dsp_t plugin;
+
+typedef struct {
+ ddb_dsp_context_t ctx;
+ void *st;
+ float tempo;
+ float pitch;
+ float rate;
+ int use_aa_filter;
+ int aa_filter_length;
+ int use_quickseek;
+ int sequence_ms;
+ int seekwindow_ms;
+ int set_output_samplerate;
+ int changed;
+} ddb_soundtouch_t;
+
+ddb_dsp_context_t*
+st_open (void) {
+ ddb_soundtouch_t *st = malloc (sizeof (ddb_soundtouch_t));
+ DDB_INIT_DSP_CONTEXT (st,ddb_soundtouch_t,&plugin);
+ st->st = st_alloc ();
+ st->changed = 1;
+ st->tempo = 0;
+ st->rate = 0;
+ st->pitch = 0;
+ st->use_aa_filter = 0;
+ st->aa_filter_length = 32;
+ st->use_quickseek = 0;
+ st->sequence_ms = 82;
+ st->seekwindow_ms = 28;
+ return (ddb_dsp_context_t *)st;
+}
+
+void
+st_close (ddb_dsp_context_t *_src) {
+ ddb_soundtouch_t *st = (ddb_soundtouch_t *)_src;
+ if (st->st) {
+ st_free (st->st);
+ }
+ free (st);
+}
+
+void
+st_reset (ddb_dsp_context_t *_src) {
+ ddb_soundtouch_t *st = (ddb_soundtouch_t *)_src;
+ st_clear (st->st);
+}
+
+int
+st_process (ddb_dsp_context_t *_src, float *samples, int nframes, int maxframes, ddb_waveformat_t *fmt, float *ratio) {
+ ddb_soundtouch_t *st = (ddb_soundtouch_t *)_src;
+ if (st->changed) {
+ if (st->set_output_samplerate > 0) {
+ st_set_rate_change (st->st, 0);
+ st_set_rate (st->st, fmt->samplerate / (float)st->set_output_samplerate);
+ }
+ else {
+ st_set_rate (st->st, 1);
+ st_set_rate_change (st->st, st->rate);
+ }
+ st_set_pitch_semi_tones (st->st, st->pitch);
+ st_set_tempo_change (st->st, st->tempo);
+ st_set_setting (st->st, SETTING_USE_AA_FILTER, st->use_aa_filter);
+ st_set_setting (st->st, SETTING_AA_FILTER_LENGTH, st->aa_filter_length);
+ st_set_setting (st->st, SETTING_USE_QUICKSEEK, st->use_quickseek);
+ st_set_setting (st->st, SETTING_SEQUENCE_MS, st->sequence_ms);
+ st_set_setting (st->st, SETTING_SEEKWINDOW_MS, st->seekwindow_ms);
+ st->changed = 0;
+ }
+ *ratio = (1.f + 0.01f * st->tempo);
+
+ if (st->set_output_samplerate > 0) {
+ fmt->samplerate = st->set_output_samplerate;
+ }
+ else {
+ *ratio *= (1.f + 0.01f * st->rate);
+ }
+
+ st_set_sample_rate (st->st, fmt->samplerate);
+ st_set_channels (st->st, fmt->channels);
+
+ st_put_samples (st->st, samples, nframes);
+ int nout = 0;
+ int n = 0;
+ do {
+ n = st_receive_samples (st->st, samples, maxframes);
+ maxframes -= n;
+ samples += n * fmt->channels;
+ nout += n;
+ } while (n != 0);
+
+ return nout;
+}
+
+const char *
+st_get_param_name (int p) {
+ switch (p) {
+ case ST_PARAM_TEMPO:
+ return "Tempo";
+ case ST_PARAM_PITCH:
+ return "Pitch";
+ case ST_PARAM_RATE:
+ return "Playback Rate";
+ case ST_PARAM_USE_AA_FILTER:
+ return "Use AA Filter";
+ case ST_PARAM_AA_FILTER_LENGTH:
+ return "AA Filter Length";
+ case ST_PARAM_USE_QUICKSEEK:
+ return "Use Quickseek";
+ case ST_PARAM_SEQUENCE_MS:
+ return "Time Stretch Sequence Length (ms)";
+ case ST_PARAM_SEEKWINDOW_MS:
+ return "Time Stretch Seek Window Length (ms)";
+ case ST_PARAM_SET_OUTPUT_SAMPLERATE:
+ return "Set Output Samplerate";
+ default:
+ fprintf (stderr, "st_param_name: invalid param index (%d)\n", p);
+ }
+ return NULL;
+}
+
+int
+st_num_params (void) {
+ return ST_PARAM_COUNT;
+}
+
+void
+st_set_param (ddb_dsp_context_t *ctx, int p, const char *val) {
+ ddb_soundtouch_t *st = (ddb_soundtouch_t *)ctx;
+ switch (p) {
+ case ST_PARAM_TEMPO:
+ st->tempo = atof (val);
+ st->changed = 1;
+ break;
+ case ST_PARAM_PITCH:
+ st->pitch = atof (val);
+ st->changed = 1;
+ break;
+ case ST_PARAM_RATE:
+ st->rate = atof (val);
+ st->changed = 1;
+ break;
+ case ST_PARAM_USE_AA_FILTER:
+ st->use_aa_filter = atoi (val);
+ st->changed = 1;
+ break;
+ case ST_PARAM_AA_FILTER_LENGTH:
+ st->aa_filter_length = atoi (val);
+ st->changed = 1;
+ break;
+ case ST_PARAM_USE_QUICKSEEK:
+ st->use_quickseek = atoi (val);
+ st->changed = 1;
+ break;
+ case ST_PARAM_SEQUENCE_MS:
+ st->sequence_ms = atoi (val);
+ st->changed = 1;
+ break;
+ case ST_PARAM_SEEKWINDOW_MS:
+ st->seekwindow_ms = atoi (val);
+ st->changed = 1;
+ break;
+ case ST_PARAM_SET_OUTPUT_SAMPLERATE:
+ st->set_output_samplerate = atoi (val);
+ if (st->set_output_samplerate < 8000) {
+ st->set_output_samplerate = 0;
+ }
+ else if (st->set_output_samplerate > 192000) {
+ st->set_output_samplerate = 192000;
+ }
+ break;
+ default:
+ fprintf (stderr, "st_param: invalid param index (%d)\n", p);
+ }
+}
+
+void
+st_get_param (ddb_dsp_context_t *ctx, int p, char *val, int sz) {
+ ddb_soundtouch_t *st = (ddb_soundtouch_t *)ctx;
+ switch (p) {
+ case ST_PARAM_TEMPO:
+ snprintf (val, sz, "%f", st->tempo);
+ break;
+ case ST_PARAM_PITCH:
+ snprintf (val, sz, "%f", st->pitch);
+ break;
+ case ST_PARAM_RATE:
+ snprintf (val, sz, "%f", st->rate);
+ break;
+ case ST_PARAM_USE_AA_FILTER:
+ snprintf (val, sz, "%d", st->use_aa_filter);
+ break;
+ case ST_PARAM_AA_FILTER_LENGTH:
+ snprintf (val, sz, "%d", st->aa_filter_length);
+ break;
+ case ST_PARAM_USE_QUICKSEEK:
+ snprintf (val, sz, "%d", st->use_quickseek);
+ break;
+ case ST_PARAM_SEQUENCE_MS:
+ snprintf (val, sz, "%d", st->sequence_ms);
+ break;
+ case ST_PARAM_SEEKWINDOW_MS:
+ snprintf (val, sz, "%d", st->seekwindow_ms);
+ break;
+ case ST_PARAM_SET_OUTPUT_SAMPLERATE:
+ snprintf (val, sz, "%d", st->set_output_samplerate);
+ break;
+ default:
+ fprintf (stderr, "st_get_param: invalid param index (%d)\n", p);
+ }
+}
+
+static const char settings_dlg[] =
+ "property \"Tempo Change (%)\" spinbtn[-200,200,1] 0 0;\n"
+ "property \"Pitch Change (semi-tones)\" spinbtn[-24,24,1] 1 0;\n"
+ "property \"Playback Rate Change (%)\" spinbtn[-200,200,1] 2 0;\n"
+ "property \"Absolute Samplerate (overrides Rate Change if nonzero)\" spinbtn[0,192000,1] 8 0;\n"
+ "property \"Use AA Filter\" checkbox 3 0;\n"
+ "property \"AA Filter Length\" spinbtn[16,64,1] 4 32;\n"
+ "property \"Use Quickseek\" checkbox 5 0;\n"
+ "property \"Time Stretch Sequence Length (ms)\" spinbtn[10,500,1] 6 82;\n"
+ "property \"Time Stretch Seek Window Length (ms)\" spinbtn[10,500,1] 7 28;\n"
+;
+
+static DB_dsp_t plugin = {
+ .plugin.api_vmajor = DB_API_VERSION_MAJOR,
+ .plugin.api_vminor = DB_API_VERSION_MINOR,
+ .open = st_open,
+ .close = st_close,
+ .process = st_process,
+ .plugin.version_major = 0,
+ .plugin.version_minor = 1,
+ .plugin.type = DB_PLUGIN_DSP,
+ .plugin.id = "soundtouch",
+ .plugin.name = "Soundtouch",
+ .plugin.descr = "Tempo/Pitch/Rate changer using SoundTouch Library (http://www.surina.net/soundtouch)",
+ .plugin.copyright =
+ "Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>\n"
+ "\n"
+ "uses SoundTouch Library, (C) Olli Parviainen"
+ "\n"
+ "This program is free software; you can redistribute it and/or\n"
+ "modify it under the terms of the GNU General Public License\n"
+ "as published by the Free Software Foundation; either version 2\n"
+ "of the License, or (at your option) any later version.\n"
+ "\n"
+ "This program is distributed in the hope that it will be useful,\n"
+ "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+ "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+ "GNU General Public License for more details.\n"
+ "\n"
+ "You should have received a copy of the GNU General Public License\n"
+ "along with this program; if not, write to the Free Software\n"
+ "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n"
+ ,
+ .plugin.website = "http://deadbeef.sf.net",
+ .num_params = st_num_params,
+ .get_param_name = st_get_param_name,
+ .set_param = st_set_param,
+ .get_param = st_get_param,
+ .reset = st_reset,
+ .configdialog = settings_dlg,
+};
+
+DB_plugin_t *
+ddb_soundtouch_load (DB_functions_t *f) {
+ deadbeef = f;
+ return &plugin.plugin;
+}
diff --git a/plugins/soundtouch/soundtouch/COPYING.TXT b/plugins/soundtouch/soundtouch/COPYING.TXT
new file mode 100644
index 00000000..5b2161be
--- /dev/null
+++ b/plugins/soundtouch/soundtouch/COPYING.TXT
@@ -0,0 +1,458 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authoried party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
diff --git a/plugins/soundtouch/soundtouch/README.html b/plugins/soundtouch/soundtouch/README.html
new file mode 100644
index 00000000..15a34c86
--- /dev/null
+++ b/plugins/soundtouch/soundtouch/README.html
@@ -0,0 +1,752 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+ <meta http-equiv="Content-Type"
+ content="text/html; charset=windows-1252">
+ <meta http-equiv="Content-Language" content="en-us">
+ <meta name="author" content="Olli Parviainen">
+ <meta name="description"
+ content="Readme file for SoundTouch audio processing library">
+ <meta name="GENERATOR" content="Microsoft FrontPage 4.0">
+ <meta name="ProgId" content="FrontPage.Editor.Document">
+ <title>SoundTouch library README</title>
+ <style>
+<!--
+.normal { font-family: Arial }
+-->
+ </style>
+</head>
+<body class="normal">
+<hr>
+<h1>SoundTouch audio processing library v1.5.0
+</h1>
+<p class="normal">SoundTouch library Copyright (c) Olli
+Parviainen 2002-2009 </p>
+<hr>
+<h2>1. Introduction </h2>
+<p>SoundTouch is an open-source audio
+processing library that allows changing the sound tempo, pitch
+and playback rate parameters independently from each other, i.e.:</p>
+<ul>
+ <li>Sound tempo can be increased or decreased while
+maintaining the original pitch</li>
+ <li>Sound pitch can be increased or decreased while
+maintaining the original tempo </li>
+ <li>Change playback rate that affects both tempo
+and pitch at the same time </li>
+ <li>Choose any combination of tempo/pitch/rate</li>
+</ul>
+<h3>1.1 Contact information </h3>
+<p>Author email: oparviai 'at' iki.fi </p>
+<p>SoundTouch WWW page: <a href="http://www.surina.net/soundtouch">http://www.surina.net/soundtouch</a></p>
+<hr>
+<h2>2. Compiling SoundTouch</h2>
+<p>Before compiling, notice that you can choose the sample data format
+if it's desirable to use floating point sample
+data instead of 16bit integers. See section "sample data format"
+for more information.</p>
+<h3>2.1. Building in Microsoft Windows</h3>
+<p>Project files for Microsoft Visual C++ 6.0 and Visual C++ .NET are
+supplied with the source code package.&nbsp;</p>
+<p> Please notice that SoundTouch
+library uses processor-specific optimizations for Pentium III and AMD
+processors. Visual Studio .NET and later versions supports the required
+instructions by default, but Visual Studio 6.0 requires a processor pack upgrade
+to be installed in order to support these optimizations. The processor pack upgrade can be downloaded from
+Microsoft site at this URL:</p>
+<p><a href="http://msdn.microsoft.com/en-us/vstudio/aa718349.aspx">http://msdn.microsoft.com/en-us/vstudio/aa718349.aspx</a></p>
+<p>If the above URL is unavailable or removed, go
+to <a href="http://msdn.microsoft.com/">http://msdn.microsoft.com</a>
+and perform a search with keywords &quot;processor pack&quot;. </p>
+<p>To build the binaries with Visual C++
+compiler, either run &quot;make-win.bat&quot; script, or open the
+appropriate project files in source code directories with Visual
+Studio. The final executable will appear under the &quot;SoundTouch\bin&quot;
+directory. If using the Visual Studio IDE instead of the make-win.bat script, directories bin and
+lib may need to be created manually to the SoundTouch
+package root for the final executables. The make-win.bat script
+creates these directories automatically.
+</p>
+<h3>2.2. Building in Gnu platforms</h3>
+<p>The SoundTouch library can be compiled in
+practically any platform supporting GNU compiler (GCC) tools.
+SoundTouch have been tested with gcc version 3.3.4., but it
+shouldn't be very specific about the gcc version. Assembler-level
+performance optimizations for GNU platform are currently available in
+x86 platforms only, they are automatically disabled and replaced with
+standard C routines in other processor platforms.</p>
+<p>To build and install the binaries, run the
+following commands in the SoundTouch/ directory:</p>
+<table border="0" cellpadding="0" cellspacing="4">
+ <tbody>
+ <tr valign="top">
+ <td>
+ <pre>./configure -</pre>
+ </td>
+ <td>
+ <p>Configures the SoundTouch package for the local
+environment.</p>
+ </td>
+ </tr>
+ <tr valign="top">
+ <td>
+ <pre>make -</pre>
+ </td>
+ <td>
+ <p>Builds the SoundTouch library &amp;
+SoundStretch utility.</p>
+ </td>
+ </tr>
+ <tr valign="top">
+ <td>
+ <pre>make install -</pre>
+ </td>
+ <td>
+ <p>Installs the SoundTouch &amp; BPM libraries
+to <b>/usr/local/lib</b> and SoundStretch utility to <b>/usr/local/bin</b>.
+Please notice that 'root' privileges may be required to install the
+binaries to the destination locations.</p>
+ </td>
+ </tr>
+ </tbody>
+</table>
+<h4><b>2.2.1 Required GNU tools</b>&nbsp;</h4>
+<p> Bash shell, GNU C++ compiler, libtool, autoconf and automake tools are required
+for compiling
+the SoundTouch library. These are usually included with the GNU/Linux distribution, but if
+not, install these packages first. For example, in Ubuntu Linux these can be acquired and
+installed with the following command:</p>
+<pre><b>sudo apt-get install <font SIZE="2">automake autoconf libtool build-essential</font></b></pre>
+<h4><b>2.2.2 Problems with GCC compiler compatibility</b></h4>
+<p>At the release time the SoundTouch package has been tested to compile in
+GNU/Linux platform. However, in past it's happened that new gcc versions aren't
+necessarily compatible with the assembler settings used in the optimized
+routines. <b>If you have problems getting the
+SoundTouch library compiled, try the workaround of disabling the optimizations</b>
+by editing the file &quot;include/STTypes.h&quot; and removing the following
+definition there:</p>
+<blockquote>
+ <pre>#define ALLOW_OPTIMIZATIONS 1</pre>
+</blockquote>
+<h4><b>2.2.3 Problems with configure script or build process</b>&nbsp;</h4>
+<p>Incompatibilities between various GNU toolchain versions may cause errors when running the &quot;configure&quot; script or building the source
+codes, if your GNU tool versions are not compatible with the versions used for
+preparing the SoundTouch kit.&nbsp;</p>
+<p>To resolve the issue, regenerate the configure scripts with your local tool
+set by running
+the &quot;<b>./bootstrap</b>&quot; script included in the SoundTouch source code
+kit. After that, run the <b>configure</b> script and <b>make</b> as usually.</p>
+<h4><b>2.2.4 Compiler issues with non-x86 processors</b></h4>
+<p>SoundTouch library works also on non-x86 processors.</p>
+<p>However, in case that you get compiler errors when trying to compile for non-Intel processor, edit the file
+&quot;<b>source\SoundTouch\Makefile.am</b>&quot; and remove the &quot;<b>-msse2</b>&quot;
+flag on the <b>AM_CXXFLAGS </b>line:</p>
+<pre><b>AM_CXXFLAGS=-O3 -fcheck-new -I../../include&nbsp;&nbsp;&nbsp; # Note: -msse2 flag removed!</b></pre>
+<p>After that, run &quot;<b>./bootstrap</b>&quot; script, and then run <b>configure</b>
+and <b>make</b> again.</p>
+<hr>
+<h2>3. About implementation &amp; Usage tips</h2>
+<h3>3.1. Supported sample data formats</h3>
+<p>The sample data format can be chosen
+between 16bit signed integer and 32bit floating point values, the
+default is 32bit floating point. </p>
+
+<p>
+In Windows environment, the sample data format is chosen
+in file &quot;STTypes.h&quot; by choosing one of the following
+defines:</p>
+<ul>
+ <li><span style="font-weight: bold;">#define INTEGER_SAMPLES</span>
+for 16bit signed
+integer</li>
+ <li><span style="font-weight: bold;">#define FLOAT_SAMPLES</span> for
+32bit floating point</li>
+</ul>
+<p>
+In GNU environment, the floating sample format is used by default, but
+integer sample format can be chosen by giving the
+following switch to the configure script:
+<blockquote>
+<pre>./configure --enable-integer-samples</pre>
+</blockquote>
+
+<p>The sample data can have either single (mono)
+or double (stereo) audio channel. Stereo data is interleaved so
+that every other data value is for left channel and every second
+for right channel. Notice that while it'd be possible in theory
+to process stereo sound as two separate mono channels, this isn't
+recommended because processing the channels separately would
+result in losing the phase coherency between the channels, which
+consequently would ruin the stereo effect.</p>
+<p>Sample rates between 8000-48000H are
+supported.</p>
+<h3>3.2. Processing latency</h3>
+<p>The processing and latency constraints of
+the SoundTouch library are:</p>
+<ul>
+ <li>Input/output processing latency for the
+SoundTouch processor is around 100 ms. This is when time-stretching is
+used. If the rate transposing effect alone is used, the latency
+requirement
+is much shorter, see section 'About algorithms'.</li>
+ <li>Processing CD-quality sound (16bit stereo
+sound with 44100H sample rate) in real-time or faster is possible
+starting from processors equivalent to Intel Pentium 133Mh or better,
+if using the "quick" processing algorithm. If not using the "quick"
+mode or
+if floating point sample data are being used, several times more CPU
+power is typically required.</li>
+</ul>
+<h3>3.3. About algorithms</h3>
+<p>SoundTouch provides three seemingly
+independent effects: tempo, pitch and playback rate control.
+These three controls are implemented as combination of two primary
+effects, <em>sample rate transposing</em> and <em>time-stretching</em>.</p>
+<p><em>Sample rate transposing</em> affects
+both the audio stream duration and pitch. It's implemented simply
+by converting the original audio sample stream to the&nbsp; desired
+duration by interpolating from the original audio samples. In SoundTouch, linear interpolation with anti-alias filtering is
+used. Theoretically a higher-order interpolation provide better
+result than 1st order linear interpolation, but in audio
+application linear interpolation together with anti-alias
+filtering performs subjectively about as well as higher-order
+filtering would.</p>
+<p><em>Time-stretching </em>means changing
+the audio stream duration without affecting it's pitch. SoundTouch
+uses WSOLA-like time-stretching routines that operate in the time
+domain. Compared to sample rate transposing, time-stretching is a
+much heavier operation and also requires a longer processing
+"window" of sound samples used by the
+processing algorithm, thus increasing the algorithm input/output
+latency. Typical i/o latency for the SoundTouch
+time-stretch algorithm is around 100 ms.</p>
+<p>Sample rate transposing and time-stretching
+are then used together to produce the tempo, pitch and rate
+controls:</p>
+<ul>
+ <li><strong>'Tempo'</strong> control is
+implemented purely by time-stretching.</li>
+ <li><strong>'Rate</strong>' control is implemented
+purely by sample rate transposing.</li>
+ <li><strong>'Pitch</strong>' control is
+implemented as a combination of time-stretching and sample rate
+transposing. For example, to increase pitch the audio stream is first
+time-stretched to longer duration (without affecting pitch) and then
+transposed back to original duration by sample rate transposing, which
+simultaneously reduces duration and increases pitch. The result is
+original duration but increased pitch.</li>
+</ul>
+<h3>3.4 Tuning the algorithm parameters</h3>
+<p>The time-stretch algorithm has few
+parameters that can be tuned to optimize sound quality for
+certain application. The current default parameters have been
+chosen by iterative if-then analysis (read: "trial and error")
+to obtain best subjective sound quality in pop/rock music
+processing, but in applications processing different kind of
+sound the default parameter set may result into a sub-optimal
+result.</p>
+<p>The time-stretch algorithm default
+parameter values are set by the following #defines in file &quot;TDStretch.h&quot;:</p>
+<blockquote>
+ <pre>#define DEFAULT_SEQUENCE_MS AUTOMATIC
+#define DEFAULT_SEEKWINDOW_MS AUTOMATIC
+#define DEFAULT_OVERLAP_MS 8</pre>
+</blockquote>
+<p>These parameters affect to the time-stretch
+algorithm as follows:</p>
+<ul>
+ <li><strong>DEFAULT_SEQUENCE_MS</strong>: This is
+the default length of a single processing sequence in milliseconds
+which determines the how the original sound is chopped in
+the time-stretch algorithm. Larger values mean fewer sequences
+are used in processing. In principle a larger value sounds better when
+slowing down the tempo, but worse when increasing the tempo and vice
+versa.&nbsp;<br>
+ <br>
+ By default, this setting value is calculated automatically according to
+ tempo value.<br>
+ </li>
+ <li><strong>DEFAULT_SEEKWINDOW_MS</strong>: The seeking window
+default length in milliseconds is for the algorithm that seeks the best
+possible overlapping location. This determines from how
+wide a sample "window" the algorithm can use to find an optimal mixing
+location when the sound sequences are to be linked back together.&nbsp;<br>
+ <br>
+The bigger this window setting is, the higher the possibility to find a
+better mixing position becomes, but at the same time large values may
+cause a "drifting" sound artifact because neighboring sequences can be
+chosen at more uneven intervals. If there's a disturbing artifact that
+sounds as if a constant frequency was drifting around, try reducing
+this setting.<br>
+ <br>
+ By default, this setting value is calculated automatically according to
+ tempo value.<br>
+ </li>
+ <li><strong>DEFAULT_OVERLAP_MS</strong>: Overlap
+length in milliseconds. When the sound sequences are mixed back
+together to form again a continuous sound stream, this parameter
+defines how much the ends of the consecutive sequences will overlap with each other.<br>
+ <br>
+ This shouldn't be that critical parameter. If you reduce the
+DEFAULT_SEQUENCE_MS setting by a large amount, you might wish to try a
+smaller value on this.</li>
+</ul>
+<p>Notice that these parameters can also be
+set during execution time with functions "<strong>TDStretch::setParameters()</strong>"
+and "<strong>SoundTouch::setSetting()</strong>".</p>
+<p>The table below summaries how the
+parameters can be adjusted for different applications:</p>
+<table border="1">
+ <tbody>
+ <tr>
+ <td valign="top"><strong>Parameter name</strong></td>
+ <td valign="top"><strong>Default value
+magnitude</strong></td>
+ <td valign="top"><strong>Larger value
+affects...</strong></td>
+ <td valign="top"><strong>Smaller value
+affects...</strong></td>
+ <td valign="top"><strong>Effect to CPU burden</strong></td>
+ </tr>
+ <tr>
+ <td valign="top">
+ <pre>SEQUENCE_MS</pre>
+ </td>
+ <td valign="top">Default value is relatively
+large, chosen for slowing down music tempo</td>
+ <td valign="top">Larger value is usually
+better for slowing down tempo. Growing the value decelerates the
+"echoing" artifact when slowing down the tempo.</td>
+ <td valign="top">Smaller value might be better
+for speeding up tempo. Reducing the value accelerates the "echoing"
+artifact when slowing down the tempo </td>
+ <td valign="top">Increasing the parameter
+value reduces computation burden</td>
+ </tr>
+ <tr>
+ <td valign="top">
+ <pre>SEEKWINDOW_MS</pre>
+ </td>
+ <td valign="top">Default value is relatively
+large, chosen for slowing down music tempo</td>
+ <td valign="top">Larger value eases finding a
+good mixing position, but may cause a "drifting" artifact</td>
+ <td valign="top">Smaller reduce possibility to
+find a good mixing position, but reduce the "drifting" artifact.</td>
+ <td valign="top">Increasing the parameter
+value increases computation burden</td>
+ </tr>
+ <tr>
+ <td valign="top">
+ <pre>OVERLAP_MS</pre>
+ </td>
+ <td valign="top">Default value is relatively
+large, chosen to suit with above parameters.</td>
+ <td valign="top">&nbsp;</td>
+ <td valign="top">If you reduce the "sequence
+ms" setting, you might wish to try a smaller value.</td>
+ <td valign="top">Increasing the parameter
+value increases computation burden</td>
+ </tr>
+ </tbody>
+</table>
+<h3>3.5 Performance Optimizations </h3>
+<p><strong>General optimizations:</strong></p>
+<p>The time-stretch routine has a 'quick' mode
+that substantially speeds up the algorithm but may degrade the
+sound quality by a small amount. This mode is activated by
+calling SoundTouch::setSetting() function with parameter&nbsp; id
+of SETTING_USE_QUICKSEEK and value "1", i.e. </p>
+<blockquote>
+ <p>setSetting(SETTING_USE_QUICKSEEK, 1);</p>
+</blockquote>
+<p><strong>CPU-specific optimizations:</strong></p>
+<ul>
+ <li>Intel MMX optimized routines are used with
+compatible CPUs when 16bit integer sample type is used. MMX optimizations are available both in Win32 and Gnu/x86 platforms.
+Compatible processors are Intel PentiumMMX and later; AMD K6-2, Athlon
+and later. </li>
+ <li>Intel SSE optimized routines are used with
+compatible CPUs when floating point sample type is used. SSE optimizations are currently implemented for Win32 platform only.
+Processors compatible with SSE extension are Intel processors starting
+from Pentium-III, and AMD processors starting from Athlon XP. </li>
+ <li>AMD 3DNow! optimized routines are used with
+compatible CPUs when floating point sample type is used, but SSE
+extension isn't supported . 3DNow! optimizations are currently
+implemented for Win32 platform only. These optimizations are used in
+AMD K6-2 and Athlon (classic) CPU's; better performing SSE routines are
+used with AMD processor starting from Athlon XP. </li>
+</ul>
+<hr>
+<h2><a name="SoundStretch"></a>4. SoundStretch audio processing utility
+</h2>
+<p>SoundStretch audio processing utility<br>
+Copyright (c) Olli Parviainen 2002-2009</p>
+<p>SoundStretch is a simple command-line
+application that can change tempo, pitch and playback rates of
+WAV sound files. This program is intended primarily to
+demonstrate how the &quot;SoundTouch&quot; library can be used to
+process sound in your own program, but it can as well be used for
+processing sound files.</p>
+<h3>4.1. SoundStretch Usage Instructions</h3>
+<p>SoundStretch Usage syntax:</p>
+<blockquote>
+ <pre>soundstretch infilename outfilename [switches]</pre>
+</blockquote>
+<p>Where: </p>
+<table border="0" cellpadding="2" width="100%">
+ <tbody>
+ <tr>
+ <td valign="top">
+ <pre>&quot;infilename&quot;</pre>
+ </td>
+ <td valign="top">Name of the input sound
+data file (in .WAV audio file format). Give &quot;stdin&quot; as filename to use
+ standard input pipe. </td>
+ </tr>
+ <tr>
+ <td valign="top">
+ <pre>&quot;outfilename&quot;</pre>
+ </td>
+ <td valign="top">Name of the output sound
+file where the resulting sound is saved (in .WAV audio file format).
+This parameter may be omitted if you&nbsp; don't want to save the
+output
+(e.g. when only calculating BPM rate with '-bpm' switch). Give &quot;stdout&quot;
+ as filename to use standard output pipe.</td>
+ </tr>
+ <tr>
+ <td valign="top">
+ <pre>&nbsp;[switches]</pre>
+ </td>
+ <td valign="top">Are one or more control
+switches.</td>
+ </tr>
+ </tbody>
+</table>
+<p>Available control switches are:</p>
+<table border="0" cellpadding="2" width="100%">
+ <tbody>
+ <tr>
+ <td valign="top">
+ <pre>-tempo=n </pre>
+ </td>
+ <td valign="top">Change the sound tempo by n
+percents (n = -95.0 .. +5000.0 %) </td>
+ </tr>
+ <tr>
+ <td valign="top">
+ <pre>-pitch=n</pre>
+ </td>
+ <td valign="top">Change the sound pitch by n
+semitones (n = -60.0 .. + 60.0 semitones) </td>
+ </tr>
+ <tr>
+ <td valign="top">
+ <pre>-rate=n</pre>
+ </td>
+ <td valign="top">Change the sound playback rate by
+n percents (n = -95.0 .. +5000.0 %) </td>
+ </tr>
+ <tr>
+ <td valign="top">
+ <pre>-bpm=n</pre>
+ </td>
+ <td valign="top">Detect the Beats-Per-Minute (BPM) rate of the sound and adjust the tempo to meet 'n'
+ BPMs. When this switch is
+ applied, the &quot;-tempo&quot; switch is ignored. If "=n" is
+omitted, i.e. switch &quot;-bpm&quot; is used alone, then the BPM rate is
+ estimated and displayed, but tempo not adjusted according to the BPM
+value. </td>
+ </tr>
+ <tr>
+ <td valign="top">
+ <pre>-quick</pre>
+ </td>
+ <td valign="top">Use quicker tempo change
+algorithm. Gains speed but loses sound quality. </td>
+ </tr>
+ <tr>
+ <td valign="top">
+ <pre>-naa</pre>
+ </td>
+ <td valign="top">Don't use anti-alias
+filtering in sample rate transposing. Gains speed but loses sound
+quality. </td>
+ </tr>
+ <tr>
+ <td valign="top">
+ <pre>-license</pre>
+ </td>
+ <td valign="top">Displays the program license
+text (LGPL)</td>
+ </tr>
+ </tbody>
+</table>
+<p>Notes:</p>
+<ul>
+ <li>To use standard input/output pipes for processing, give &quot;stdin&quot;
+ and &quot;stdout&quot; as input/output filenames correspondingly. The
+ standard input/output pipes will still carry the audio data in .wav audio
+ file format.</li>
+ <li>The numerical switches allow both integer (e.g. "-tempo=123") and decimal (e.g.
+"-tempo=123.45") numbers.</li>
+ <li>The &quot;-naa&quot; and/or "-quick" switches can be
+used to reduce CPU usage while compromising some sound quality </li>
+ <li>The BPM detection algorithm works by detecting
+repeating bass or drum patterns at low frequencies of &lt;250Hz. A
+ lower-than-expected BPM figure may be reported for music with uneven or
+ complex bass patterns. </li>
+</ul>
+<h3>4.2. SoundStretch usage examples </h3>
+<p><strong>Example 1</strong></p>
+<p>The following command increases tempo of
+the sound file &quot;originalfile.wav&quot; by 12.5% and stores result to file &quot;destinationfile.wav&quot;:</p>
+<blockquote>
+ <pre>soundstretch originalfile.wav destinationfile.wav -tempo=12.5</pre>
+</blockquote>
+<p><strong>Example 2</strong></p>
+<p>The following command decreases the sound
+pitch (key) of the sound file &quot;orig.wav&quot; by two
+semitones and stores the result to file &quot;dest.wav&quot;:</p>
+<blockquote>
+ <pre>soundstretch orig.wav dest.wav -pitch=-2</pre>
+</blockquote>
+<p><strong>Example 3</strong></p>
+<p>The following command processes the file &quot;orig.wav&quot; by decreasing the sound tempo by 25.3% and
+increasing the sound pitch (key) by 1.5 semitones. Resulting .wav audio data is
+directed to standard output pipe:</p>
+<blockquote>
+ <pre>soundstretch orig.wav stdout -tempo=-25.3 -pitch=1.5</pre>
+</blockquote>
+<p><strong>Example 4</strong></p>
+<p>The following command detects the BPM rate
+of the file &quot;orig.wav&quot; and adjusts the tempo to match
+100 beats per minute. Result is stored to file &quot;dest.wav&quot;:</p>
+<blockquote>
+ <pre>soundstretch orig.wav dest.wav -bpm=100</pre>
+</blockquote>
+<p><strong>Example 5</strong></p>
+<p>The following command reads .wav sound data from standard input pipe and
+estimates the BPM rate:</p>
+<blockquote>
+ <pre>soundstretch stdin -bpm</pre>
+</blockquote>
+<hr>
+<h2>5. Change History</h2>
+<h3>5.1. SoundTouch library Change History </h3>
+
+<p><strong>1.5.0:</strong></p>
+<ul>
+<li>Added normalization to correlation calculation and improvement automatic seek/sequence parameter calculation to improve sound quality</li>
+
+<li>Bugfixes:&nbsp;
+ <ul>
+ <li>Fixed negative array indexing in quick seek algorithm</li>
+ <li>FIR autoalias filter running too far in processing buffer</li>
+ <li>Check against zero sample count in rate transposing</li>
+ <li>Fix for x86-64 support: Removed pop/push instructions from the cpu detection algorithm.&nbsp;</li>
+ <li>Check against empty buffers in FIFOSampleBuffer</li>
+ <li>Other minor fixes &amp; code cleanup</li>
+ </ul>
+</li>
+
+<li>Fixes in compilation scripts for non-Intel platforms</li>
+<li>Added Dynamic-Link-Library (DLL) version of SoundTouch library build,
+ provided with Delphi/Pascal wrapper for calling the dll routines</li>
+<li>Added #define PREVENT_CLICK_AT_RATE_CROSSOVER that prevents a click artifact
+ when crossing the nominal pitch from either positive to negative side or vice
+ versa</li>
+
+</ul>
+
+<p><strong>1.4.1:</strong></p>
+<ul>
+<li>Fixed a buffer overflow bug in BPM detect algorithm routines if processing
+ more than 2048 samples at one call&nbsp;</li>
+
+</ul>
+
+<p><strong>1.4.0:</strong></p>
+<ul>
+<li>Improved sound quality by automatic calculation of time stretch algorithm
+ processing parameters according to tempo setting</li>
+<li>Moved BPM detection routines from SoundStretch application into SoundTouch
+ library</li>
+<li>Bugfixes: Usage of uninitialied variables, GNU build scripts, compiler errors
+ due to 'const' keyword mismatch.</li>
+<li>Source code cleanup</li>
+
+</ul>
+
+<p><strong>v1.3.1:
+</strong></p>
+<ul>
+<li>Changed static class declaration to GCC 4.x compiler compatible syntax.</li>
+<li>Enabled MMX/SSE-optimized routines also for GCC compilers. Earlier
+the MMX/SSE-optimized routines were written in compiler-specific inline
+assembler, now these routines are migrated to use compiler intrinsic
+syntax which allows compiling the same MMX/SSE-optimized source code with
+both Visual C++ and GCC compilers. </li>
+<li>Set floating point as the default sample format and added switch to
+the GNU configure script for selecting the other sample format.</li>
+
+</ul>
+
+<p><strong>v1.3.0:
+</strong></p>
+<ul>
+ <li>Fixed tempo routine output duration inaccuracy due to rounding
+error </li>
+ <li>Implemented separate processing routines for integer and
+floating arithmetic to allow improvements to floating point routines
+(earlier used algorithms mostly optimized for integer arithmetic also
+for floating point samples) </li>
+ <li>Fixed a bug that distorts sound if sample rate changes during the
+sound stream </li>
+ <li>Fixed a memory leak that appeared in MMX/SSE/3DNow! optimized
+routines </li>
+ <li>Reduced redundant code pieces in MMX/SSE/3DNow! optimized
+routines vs. the standard C routines.</li>
+ <li>MMX routine incompatibility with new gcc compiler versions </li>
+ <li>Other miscellaneous bug fixes </li>
+</ul>
+<p><strong>v1.2.1: </strong></p>
+<ul>
+ <li>Added automake/autoconf scripts for GNU
+platforms (in courtesy of David Durham)</li>
+ <li>Fixed SCALE overflow bug in rate transposer
+routine.</li>
+ <li>Fixed 64bit address space bugs.</li>
+ <li>Created a 'soundtouch' namespace for
+SAMPLETYPE definitions.</li>
+</ul>
+<p><strong>v1.2.0: </strong></p>
+<ul>
+ <li>Added support for 32bit floating point sample
+data type with SSE/3DNow! optimizations for Win32 platform (SSE/3DNow! optimizations currently not supported in GCC environment)</li>
+ <li>Replaced 'make-gcc' script for GNU environment
+by master Makefile</li>
+ <li>Added time-stretch routine configurability to
+SoundTouch main class</li>
+ <li>Bugfixes</li>
+</ul>
+<p><strong>v1.1.1: </strong></p>
+<ul>
+ <li>Moved SoundTouch under lesser GPL license (LGPL). This allows using SoundTouch library in programs that aren't
+released under GPL license. </li>
+ <li>Changed MMX routine organiation so that MMX optimized routines are now implemented in classes that are derived from
+the basic classes having the standard non-mmx routines. </li>
+ <li>MMX routines to support gcc version 3. </li>
+ <li>Replaced windows makefiles by script using the .dsw files </li>
+</ul>
+<p><strong>v1.01: </strong></p>
+<ul>
+ <li>&quot;mmx_gcc.cpp&quot;: Added "using namespace std" and
+removed "return 0" from a function with void return value to fix
+compiler errors when compiling the library in Solaris environment. </li>
+ <li>Moved file &quot;FIFOSampleBuffer.h&quot; to "include"
+directory to allow accessing the FIFOSampleBuffer class from external
+files. </li>
+</ul>
+<p><strong>v1.0: </strong></p>
+<ul>
+ <li>Initial release </li>
+</ul>
+<p>&nbsp;</p>
+<h3>5.2. SoundStretch application Change
+History </h3>
+
+<p><strong>1.4.0:</strong></p>
+<ul>
+<li>Moved BPM detection routines from SoundStretch application into SoundTouch
+ library</li>
+<li>Allow using standard input/output pipes as audio processing input/output
+ streams</li>
+
+</ul>
+
+<p><strong>v1.3.0:</strong></p>
+<ul>
+ <li>Simplified accessing WAV files with floating
+point sample format.
+ </li>
+</ul>
+<p><strong>v1.2.1: </strong></p>
+<ul>
+ <li>Fixed 64bit address space bugs.</li>
+</ul>
+<p><strong>v1.2.0: </strong></p>
+<ul>
+ <li>Added support for 32bit floating point sample
+data type</li>
+ <li>Restructured the BPM routines into separate
+library</li>
+ <li>Fixed big-endian conversion bugs in WAV file
+routines (hopefully :)</li>
+</ul>
+<p><strong>v1.1.1: </strong></p>
+<ul>
+ <li>Fixed bugs in WAV file reading &amp; added
+byte-order conversion for big-endian processors. </li>
+ <li>Moved SoundStretch source code under 'example'
+directory to highlight difference from SoundTouch stuff. </li>
+ <li>Replaced windows makefiles by script using the .dsw files </li>
+ <li>Output file name isn't required if output
+isn't desired (e.g. if using the switch '-bpm' in plain format only) </li>
+</ul>
+<p><strong>v1.1:</strong></p>
+<ul>
+ <li>Fixed "Release" settings in Microsoft Visual
+C++ project file (.dsp) </li>
+ <li>Added beats-per-minute (BPM) detection routine
+and command-line switch &quot;-bpm&quot; </li>
+</ul>
+<p><strong>v1.01: </strong></p>
+<ul>
+ <li>Initial release </li>
+</ul>
+<hr>
+<h2 >6. Acknowledgements </h2>
+<p >Kudos for these people who have contributed to development or submitted
+bugfixes since
+SoundTouch v1.3.1: </p>
+<ul>
+ <li>Arthur A</li>
+ <li>Richard Ash</li>
+ <li>Stanislav Brabec</li>
+ <li>Christian Budde</li>
+ <li>Brian Cameron</li>
+ <li>Jason Champion</li>
+ <li>Patrick Colis</li>
+ <li>Justin Frankel</li>
+ <li>Jason Garland</li>
+ <li>Takashi Iwai</li>
+ <li>Paulo Pizarro</li>
+ <li>RJ Ryan</li>
+ <li>John Sheehy</li>
+</ul>
+<p >Moral greetings to all other contributors and users also!</p>
+<hr>
+<h2 >7. LICENSE </h2>
+<p>SoundTouch audio processing library<br>
+Copyright (c) Olli Parviainen</p>
+<p>This library is free software; you can
+redistribute it and/or modify it under the terms of the GNU
+Lesser General Public License version 2.1 as published by the Free Software
+Foundation.</p>
+<p>This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even
+the implied warranty of MERCHANTABILITY or FITNESS FOR A
+PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.</p>
+<p>You should have received a copy of the GNU
+Lesser General Public License along with this library; if not,
+write to the Free Software Foundation, Inc., 59 Temple Place,
+Suite 330, Boston, MA 02111-1307 USA</p>
+<hr>
+<!--
+$Id: README.html 81 2009-12-28 20:51:18Z oparviai $
+-->
+</body>
+</html>
diff --git a/plugins/soundtouch/soundtouch/include/BPMDetect.h b/plugins/soundtouch/soundtouch/include/BPMDetect.h
new file mode 100644
index 00000000..4def43f1
--- /dev/null
+++ b/plugins/soundtouch/soundtouch/include/BPMDetect.h
@@ -0,0 +1,161 @@
+////////////////////////////////////////////////////////////////////////////////
+///
+/// Beats-per-minute (BPM) detection routine.
+///
+/// The beat detection algorithm works as follows:
+/// - Use function 'inputSamples' to input a chunks of samples to the class for
+/// analysis. It's a good idea to enter a large sound file or stream in smallish
+/// chunks of around few kilosamples in order not to extinguish too much RAM memory.
+/// - Input sound data is decimated to approx 500 Hz to reduce calculation burden,
+/// which is basically ok as low (bass) frequencies mostly determine the beat rate.
+/// Simple averaging is used for anti-alias filtering because the resulting signal
+/// quality isn't of that high importance.
+/// - Decimated sound data is enveloped, i.e. the amplitude shape is detected by
+/// taking absolute value that's smoothed by sliding average. Signal levels that
+/// are below a couple of times the general RMS amplitude level are cut away to
+/// leave only notable peaks there.
+/// - Repeating sound patterns (e.g. beats) are detected by calculating short-term
+/// autocorrelation function of the enveloped signal.
+/// - After whole sound data file has been analyzed as above, the bpm level is
+/// detected by function 'getBpm' that finds the highest peak of the autocorrelation
+/// function, calculates it's precise location and converts this reading to bpm's.
+///
+/// Author : Copyright (c) Olli Parviainen
+/// Author e-mail : oparviai 'at' iki.fi
+/// SoundTouch WWW: http://www.surina.net/soundtouch
+///
+////////////////////////////////////////////////////////////////////////////////
+//
+// Last changed : $Date: 2009-02-21 18:00:14 +0200 (Sat, 21 Feb 2009) $
+// File revision : $Revision: 4 $
+//
+// $Id: BPMDetect.h 63 2009-02-21 16:00:14Z oparviai $
+//
+////////////////////////////////////////////////////////////////////////////////
+//
+// License :
+//
+// SoundTouch audio processing library
+// Copyright (c) Olli Parviainen
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+////////////////////////////////////////////////////////////////////////////////
+
+#ifndef _BPMDetect_H_
+#define _BPMDetect_H_
+
+#include "STTypes.h"
+#include "FIFOSampleBuffer.h"
+
+namespace soundtouch
+{
+
+/// Minimum allowed BPM rate. Used to restrict accepted result above a reasonable limit.
+#define MIN_BPM 29
+
+/// Maximum allowed BPM rate. Used to restrict accepted result below a reasonable limit.
+#define MAX_BPM 230
+
+
+/// Class for calculating BPM rate for audio data.
+class BPMDetect
+{
+protected:
+ /// Auto-correlation accumulator bins.
+ float *xcorr;
+
+ /// Amplitude envelope sliding average approximation level accumulator
+ float envelopeAccu;
+
+ /// RMS volume sliding average approximation level accumulator
+ float RMSVolumeAccu;
+
+ /// Sample average counter.
+ int decimateCount;
+
+ /// Sample average accumulator for FIFO-like decimation.
+ soundtouch::LONG_SAMPLETYPE decimateSum;
+
+ /// Decimate sound by this coefficient to reach approx. 500 Hz.
+ int decimateBy;
+
+ /// Auto-correlation window length
+ int windowLen;
+
+ /// Number of channels (1 = mono, 2 = stereo)
+ int channels;
+
+ /// sample rate
+ int sampleRate;
+
+ /// Beginning of auto-correlation window: Autocorrelation isn't being updated for
+ /// the first these many correlation bins.
+ int windowStart;
+
+ /// FIFO-buffer for decimated processing samples.
+ soundtouch::FIFOSampleBuffer *buffer;
+
+ /// Updates auto-correlation function for given number of decimated samples that
+ /// are read from the internal 'buffer' pipe (samples aren't removed from the pipe
+ /// though).
+ void updateXCorr(int process_samples /// How many samples are processed.
+ );
+
+ /// Decimates samples to approx. 500 Hz.
+ ///
+ /// \return Number of output samples.
+ int decimate(soundtouch::SAMPLETYPE *dest, ///< Destination buffer
+ const soundtouch::SAMPLETYPE *src, ///< Source sample buffer
+ int numsamples ///< Number of source samples.
+ );
+
+ /// Calculates amplitude envelope for the buffer of samples.
+ /// Result is output to 'samples'.
+ void calcEnvelope(soundtouch::SAMPLETYPE *samples, ///< Pointer to input/output data buffer
+ int numsamples ///< Number of samples in buffer
+ );
+
+public:
+ /// Constructor.
+ BPMDetect(int numChannels, ///< Number of channels in sample data.
+ int sampleRate ///< Sample rate in Hz.
+ );
+
+ /// Destructor.
+ virtual ~BPMDetect();
+
+ /// Inputs a block of samples for analyzing: Envelopes the samples and then
+ /// updates the autocorrelation estimation. When whole song data has been input
+ /// in smaller blocks using this function, read the resulting bpm with 'getBpm'
+ /// function.
+ ///
+ /// Notice that data in 'samples' array can be disrupted in processing.
+ void inputSamples(const soundtouch::SAMPLETYPE *samples, ///< Pointer to input/working data buffer
+ int numSamples ///< Number of samples in buffer
+ );
+
+
+ /// Analyzes the results and returns the BPM rate. Use this function to read result
+ /// after whole song data has been input to the class by consecutive calls of
+ /// 'inputSamples' function.
+ ///
+ /// \return Beats-per-minute rate, or zero if detection failed.
+ float getBpm();
+};
+
+}
+
+#endif // _BPMDetect_H_
diff --git a/plugins/soundtouch/soundtouch/include/FIFOSampleBuffer.h b/plugins/soundtouch/soundtouch/include/FIFOSampleBuffer.h
new file mode 100644
index 00000000..76cbf951
--- /dev/null
+++ b/plugins/soundtouch/soundtouch/include/FIFOSampleBuffer.h
@@ -0,0 +1,174 @@
+////////////////////////////////////////////////////////////////////////////////
+///
+/// A buffer class for temporarily storaging sound samples, operates as a
+/// first-in-first-out pipe.
+///
+/// Samples are added to the end of the sample buffer with the 'putSamples'
+/// function, and are received from the beginning of the buffer by calling
+/// the 'receiveSamples' function. The class automatically removes the
+/// output samples from the buffer as well as grows the storage size
+/// whenever necessary.
+///
+/// Author : Copyright (c) Olli Parviainen
+/// Author e-mail : oparviai 'at' iki.fi
+/// SoundTouch WWW: http://www.surina.net/soundtouch
+///
+////////////////////////////////////////////////////////////////////////////////
+//
+// Last changed : $Date: 2009-02-21 18:00:14 +0200 (Sat, 21 Feb 2009) $
+// File revision : $Revision: 4 $
+//
+// $Id: FIFOSampleBuffer.h 63 2009-02-21 16:00:14Z oparviai $
+//
+////////////////////////////////////////////////////////////////////////////////
+//
+// License :
+//
+// SoundTouch audio processing library
+// Copyright (c) Olli Parviainen
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+////////////////////////////////////////////////////////////////////////////////
+
+#ifndef FIFOSampleBuffer_H
+#define FIFOSampleBuffer_H
+
+#include "FIFOSamplePipe.h"
+
+namespace soundtouch
+{
+
+/// Sample buffer working in FIFO (first-in-first-out) principle. The class takes
+/// care of storage size adjustment and data moving during input/output operations.
+///
+/// Notice that in case of stereo audio, one sample is considered to consist of
+/// both channel data.
+class FIFOSampleBuffer : public FIFOSamplePipe
+{
+private:
+ /// Sample buffer.
+ SAMPLETYPE *buffer;
+
+ // Raw unaligned buffer memory. 'buffer' is made aligned by pointing it to first
+ // 16-byte aligned location of this buffer
+ SAMPLETYPE *bufferUnaligned;
+
+ /// Sample buffer size in bytes
+ uint sizeInBytes;
+
+ /// How many samples are currently in buffer.
+ uint samplesInBuffer;
+
+ /// Channels, 1=mono, 2=stereo.
+ uint channels;
+
+ /// Current position pointer to the buffer. This pointer is increased when samples are
+ /// removed from the pipe so that it's necessary to actually rewind buffer (move data)
+ /// only new data when is put to the pipe.
+ uint bufferPos;
+
+ /// Rewind the buffer by moving data from position pointed by 'bufferPos' to real
+ /// beginning of the buffer.
+ void rewind();
+
+ /// Ensures that the buffer has capacity for at least this many samples.
+ void ensureCapacity(uint capacityRequirement);
+
+ /// Returns current capacity.
+ uint getCapacity() const;
+
+public:
+
+ /// Constructor
+ FIFOSampleBuffer(int numChannels = 2 ///< Number of channels, 1=mono, 2=stereo.
+ ///< Default is stereo.
+ );
+
+ /// destructor
+ ~FIFOSampleBuffer();
+
+ /// Returns a pointer to the beginning of the output samples.
+ /// This function is provided for accessing the output samples directly.
+ /// Please be careful for not to corrupt the book-keeping!
+ ///
+ /// When using this function to output samples, also remember to 'remove' the
+ /// output samples from the buffer by calling the
+ /// 'receiveSamples(numSamples)' function
+ virtual SAMPLETYPE *ptrBegin();
+
+ /// Returns a pointer to the end of the used part of the sample buffer (i.e.
+ /// where the new samples are to be inserted). This function may be used for
+ /// inserting new samples into the sample buffer directly. Please be careful
+ /// not corrupt the book-keeping!
+ ///
+ /// When using this function as means for inserting new samples, also remember
+ /// to increase the sample count afterwards, by calling the
+ /// 'putSamples(numSamples)' function.
+ SAMPLETYPE *ptrEnd(
+ uint slackCapacity ///< How much free capacity (in samples) there _at least_
+ ///< should be so that the caller can succesfully insert the
+ ///< desired samples to the buffer. If necessary, the function
+ ///< grows the buffer size to comply with this requirement.
+ );
+
+ /// Adds 'numSamples' pcs of samples from the 'samples' memory position to
+ /// the sample buffer.
+ virtual void putSamples(const SAMPLETYPE *samples, ///< Pointer to samples.
+ uint numSamples ///< Number of samples to insert.
+ );
+
+ /// Adjusts the book-keeping to increase number of samples in the buffer without
+ /// copying any actual samples.
+ ///
+ /// This function is used to update the number of samples in the sample buffer
+ /// when accessing the buffer directly with 'ptrEnd' function. Please be
+ /// careful though!
+ virtual void putSamples(uint numSamples ///< Number of samples been inserted.
+ );
+
+ /// Output samples from beginning of the sample buffer. Copies requested samples to
+ /// output buffer and removes them from the sample buffer. If there are less than
+ /// 'numsample' samples in the buffer, returns all that available.
+ ///
+ /// \return Number of samples returned.
+ virtual uint receiveSamples(SAMPLETYPE *output, ///< Buffer where to copy output samples.
+ uint maxSamples ///< How many samples to receive at max.
+ );
+
+ /// Adjusts book-keeping so that given number of samples are removed from beginning of the
+ /// sample buffer without copying them anywhere.
+ ///
+ /// Used to reduce the number of samples in the buffer when accessing the sample buffer directly
+ /// with 'ptrBegin' function.
+ virtual uint receiveSamples(uint maxSamples ///< Remove this many samples from the beginning of pipe.
+ );
+
+ /// Returns number of samples currently available.
+ virtual uint numSamples() const;
+
+ /// Sets number of channels, 1 = mono, 2 = stereo.
+ void setChannels(int numChannels);
+
+ /// Returns nonzero if there aren't any samples available for outputting.
+ virtual int isEmpty() const;
+
+ /// Clears all the samples.
+ virtual void clear();
+};
+
+}
+
+#endif
diff --git a/plugins/soundtouch/soundtouch/include/FIFOSamplePipe.h b/plugins/soundtouch/soundtouch/include/FIFOSamplePipe.h
new file mode 100644
index 00000000..b5fc3b77
--- /dev/null
+++ b/plugins/soundtouch/soundtouch/include/FIFOSamplePipe.h
@@ -0,0 +1,221 @@
+////////////////////////////////////////////////////////////////////////////////
+///
+/// 'FIFOSamplePipe' : An abstract base class for classes that manipulate sound
+/// samples by operating like a first-in-first-out pipe: New samples are fed
+/// into one end of the pipe with the 'putSamples' function, and the processed
+/// samples are received from the other end with the 'receiveSamples' function.
+///
+/// 'FIFOProcessor' : A base class for classes the do signal processing with
+/// the samples while operating like a first-in-first-out pipe. When samples
+/// are input with the 'putSamples' function, the class processes them
+/// and moves the processed samples to the given 'output' pipe object, which
+/// may be either another processing stage, or a fifo sample buffer object.
+///
+/// Author : Copyright (c) Olli Parviainen
+/// Author e-mail : oparviai 'at' iki.fi
+/// SoundTouch WWW: http://www.surina.net/soundtouch
+///
+////////////////////////////////////////////////////////////////////////////////
+//
+// Last changed : $Date: 2009-04-13 16:18:48 +0300 (Mon, 13 Apr 2009) $
+// File revision : $Revision: 4 $
+//
+// $Id: FIFOSamplePipe.h 69 2009-04-13 13:18:48Z oparviai $
+//
+////////////////////////////////////////////////////////////////////////////////
+//
+// License :
+//
+// SoundTouch audio processing library
+// Copyright (c) Olli Parviainen
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+////////////////////////////////////////////////////////////////////////////////
+
+#ifndef FIFOSamplePipe_H
+#define FIFOSamplePipe_H
+
+#include <assert.h>
+#include <stdlib.h>
+#include "STTypes.h"
+
+namespace soundtouch
+{
+
+/// Abstract base class for FIFO (first-in-first-out) sample processing classes.
+class FIFOSamplePipe
+{
+public:
+ // virtual default destructor
+ virtual ~FIFOSamplePipe() {}
+
+
+ /// Returns a pointer to the beginning of the output samples.
+ /// This function is provided for accessing the output samples directly.
+ /// Please be careful for not to corrupt the book-keeping!
+ ///
+ /// When using this function to output samples, also remember to 'remove' the
+ /// output samples from the buffer by calling the
+ /// 'receiveSamples(numSamples)' function
+ virtual SAMPLETYPE *ptrBegin() = 0;
+
+ /// Adds 'numSamples' pcs of samples from the 'samples' memory position to
+ /// the sample buffer.
+ virtual void putSamples(const SAMPLETYPE *samples, ///< Pointer to samples.
+ uint numSamples ///< Number of samples to insert.
+ ) = 0;
+
+
+ // Moves samples from the 'other' pipe instance to this instance.
+ void moveSamples(FIFOSamplePipe &other ///< Other pipe instance where from the receive the data.
+ )
+ {
+ int oNumSamples = other.numSamples();
+
+ putSamples(other.ptrBegin(), oNumSamples);
+ other.receiveSamples(oNumSamples);
+ };
+
+ /// Output samples from beginning of the sample buffer. Copies requested samples to
+ /// output buffer and removes them from the sample buffer. If there are less than
+ /// 'numsample' samples in the buffer, returns all that available.
+ ///
+ /// \return Number of samples returned.
+ virtual uint receiveSamples(SAMPLETYPE *output, ///< Buffer where to copy output samples.
+ uint maxSamples ///< How many samples to receive at max.
+ ) = 0;
+
+ /// Adjusts book-keeping so that given number of samples are removed from beginning of the
+ /// sample buffer without copying them anywhere.
+ ///
+ /// Used to reduce the number of samples in the buffer when accessing the sample buffer directly
+ /// with 'ptrBegin' function.
+ virtual uint receiveSamples(uint maxSamples ///< Remove this many samples from the beginning of pipe.
+ ) = 0;
+
+ /// Returns number of samples currently available.
+ virtual uint numSamples() const = 0;
+
+ // Returns nonzero if there aren't any samples available for outputting.
+ virtual int isEmpty() const = 0;
+
+ /// Clears all the samples.
+ virtual void clear() = 0;
+};
+
+
+
+/// Base-class for sound processing routines working in FIFO principle. With this base
+/// class it's easy to implement sound processing stages that can be chained together,
+/// so that samples that are fed into beginning of the pipe automatically go through
+/// all the processing stages.
+///
+/// When samples are input to this class, they're first processed and then put to
+/// the FIFO pipe that's defined as output of this class. This output pipe can be
+/// either other processing stage or a FIFO sample buffer.
+class FIFOProcessor :public FIFOSamplePipe
+{
+protected:
+ /// Internal pipe where processed samples are put.
+ FIFOSamplePipe *output;
+
+ /// Sets output pipe.
+ void setOutPipe(FIFOSamplePipe *pOutput)
+ {
+ assert(output == NULL);
+ assert(pOutput != NULL);
+ output = pOutput;
+ }
+
+
+ /// Constructor. Doesn't define output pipe; it has to be set be
+ /// 'setOutPipe' function.
+ FIFOProcessor()
+ {
+ output = NULL;
+ }
+
+
+ /// Constructor. Configures output pipe.
+ FIFOProcessor(FIFOSamplePipe *pOutput ///< Output pipe.
+ )
+ {
+ output = pOutput;
+ }
+
+
+ /// Destructor.
+ virtual ~FIFOProcessor()
+ {
+ }
+
+
+ /// Returns a pointer to the beginning of the output samples.
+ /// This function is provided for accessing the output samples directly.
+ /// Please be careful for not to corrupt the book-keeping!
+ ///
+ /// When using this function to output samples, also remember to 'remove' the
+ /// output samples from the buffer by calling the
+ /// 'receiveSamples(numSamples)' function
+ virtual SAMPLETYPE *ptrBegin()
+ {
+ return output->ptrBegin();
+ }
+
+public:
+
+ /// Output samples from beginning of the sample buffer. Copies requested samples to
+ /// output buffer and removes them from the sample buffer. If there are less than
+ /// 'numsample' samples in the buffer, returns all that available.
+ ///
+ /// \return Number of samples returned.
+ virtual uint receiveSamples(SAMPLETYPE *outBuffer, ///< Buffer where to copy output samples.
+ uint maxSamples ///< How many samples to receive at max.
+ )
+ {
+ return output->receiveSamples(outBuffer, maxSamples);
+ }
+
+
+ /// Adjusts book-keeping so that given number of samples are removed from beginning of the
+ /// sample buffer without copying them anywhere.
+ ///
+ /// Used to reduce the number of samples in the buffer when accessing the sample buffer directly
+ /// with 'ptrBegin' function.
+ virtual uint receiveSamples(uint maxSamples ///< Remove this many samples from the beginning of pipe.
+ )
+ {
+ return output->receiveSamples(maxSamples);
+ }
+
+
+ /// Returns number of samples currently available.
+ virtual uint numSamples() const
+ {
+ return output->numSamples();
+ }
+
+
+ /// Returns nonzero if there aren't any samples available for outputting.
+ virtual int isEmpty() const
+ {
+ return output->isEmpty();
+ }
+};
+
+}
+
+#endif
diff --git a/plugins/soundtouch/soundtouch/include/STTypes.h b/plugins/soundtouch/soundtouch/include/STTypes.h
new file mode 100644
index 00000000..c09a45f9
--- /dev/null
+++ b/plugins/soundtouch/soundtouch/include/STTypes.h
@@ -0,0 +1,149 @@
+////////////////////////////////////////////////////////////////////////////////
+///
+/// Common type definitions for SoundTouch audio processing library.
+///
+/// Author : Copyright (c) Olli Parviainen
+/// Author e-mail : oparviai 'at' iki.fi
+/// SoundTouch WWW: http://www.surina.net/soundtouch
+///
+////////////////////////////////////////////////////////////////////////////////
+//
+// Last changed : $Date: 2009-05-17 14:30:57 +0300 (Sun, 17 May 2009) $
+// File revision : $Revision: 3 $
+//
+// $Id: STTypes.h 70 2009-05-17 11:30:57Z oparviai $
+//
+////////////////////////////////////////////////////////////////////////////////
+//
+// License :
+//
+// SoundTouch audio processing library
+// Copyright (c) Olli Parviainen
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+////////////////////////////////////////////////////////////////////////////////
+
+#ifndef STTypes_H
+#define STTypes_H
+
+typedef unsigned int uint;
+typedef unsigned long ulong;
+
+#ifdef __GNUC__
+ // In GCC, include soundtouch_config.h made by config scritps
+ #include "soundtouch_config.h"
+#endif
+
+#ifndef _WINDEF_
+ // if these aren't defined already by Windows headers, define now
+
+ typedef int BOOL;
+
+ #define FALSE 0
+ #define TRUE 1
+
+#endif // _WINDEF_
+
+
+namespace soundtouch
+{
+
+/// Activate these undef's to overrule the possible sampletype
+/// setting inherited from some other header file:
+//#undef INTEGER_SAMPLES
+//#undef FLOAT_SAMPLES
+
+#if !(INTEGER_SAMPLES || FLOAT_SAMPLES)
+
+ /// Choose either 32bit floating point or 16bit integer sampletype
+ /// by choosing one of the following defines, unless this selection
+ /// has already been done in some other file.
+ ////
+ /// Notes:
+ /// - In Windows environment, choose the sample format with the
+ /// following defines.
+ /// - In GNU environment, the floating point samples are used by
+ /// default, but integer samples can be chosen by giving the
+ /// following switch to the configure script:
+ /// ./configure --enable-integer-samples
+ /// However, if you still prefer to select the sample format here
+ /// also in GNU environment, then please #undef the INTEGER_SAMPLE
+ /// and FLOAT_SAMPLE defines first as in comments above.
+ //#define INTEGER_SAMPLES 1 //< 16bit integer samples
+ #define FLOAT_SAMPLES 1 //< 32bit float samples
+
+ #endif
+
+ #if (WIN32 || __i386__ || __x86_64__)
+ /// Define this to allow X86-specific assembler/intrinsic optimizations.
+ /// Notice that library contains also usual C++ versions of each of these
+ /// these routines, so if you're having difficulties getting the optimized
+ /// routines compiled for whatever reason, you may disable these optimizations
+ /// to make the library compile.
+
+ #define ALLOW_X86_OPTIMIZATIONS 0
+
+ #endif
+
+ // If defined, allows the SIMD-optimized routines to take minor shortcuts
+ // for improved performance. Undefine to require faithfully similar SIMD
+ // calculations as in normal C implementation.
+ #define ALLOW_NONEXACT_SIMD_OPTIMIZATION 1
+
+
+ #ifdef INTEGER_SAMPLES
+ // 16bit integer sample type
+ typedef short SAMPLETYPE;
+ // data type for sample accumulation: Use 32bit integer to prevent overflows
+ typedef long LONG_SAMPLETYPE;
+
+ #ifdef FLOAT_SAMPLES
+ // check that only one sample type is defined
+ #error "conflicting sample types defined"
+ #endif // FLOAT_SAMPLES
+
+ #ifdef ALLOW_X86_OPTIMIZATIONS
+ // Allow MMX optimizations
+ #define ALLOW_MMX 1
+ #endif
+
+ #else
+
+ // floating point samples
+ typedef float SAMPLETYPE;
+ // data type for sample accumulation: Use double to utilize full precision.
+ typedef double LONG_SAMPLETYPE;
+
+ #ifdef ALLOW_X86_OPTIMIZATIONS
+ // Allow 3DNow! and SSE optimizations
+ #if WIN32
+ #define ALLOW_3DNOW 1
+ #endif
+
+ #define ALLOW_SSE 1
+ #endif
+
+ #endif // INTEGER_SAMPLES
+};
+
+
+// When this #define is active, eliminates a clicking sound when the "rate" or "pitch"
+// parameter setting crosses from value <1 to >=1 or vice versa during processing.
+// Default is off as such crossover is untypical case and involves a slight sound
+// quality compromise.
+//#define PREVENT_CLICK_AT_RATE_CROSSOVER 1
+
+#endif
diff --git a/plugins/soundtouch/soundtouch/include/SoundTouch.h b/plugins/soundtouch/soundtouch/include/SoundTouch.h
new file mode 100644
index 00000000..0e042d3c
--- /dev/null
+++ b/plugins/soundtouch/soundtouch/include/SoundTouch.h
@@ -0,0 +1,252 @@
+//////////////////////////////////////////////////////////////////////////////
+///
+/// SoundTouch - main class for tempo/pitch/rate adjusting routines.
+///
+/// Notes:
+/// - Initialize the SoundTouch object instance by setting up the sound stream
+/// parameters with functions 'setSampleRate' and 'setChannels', then set
+/// desired tempo/pitch/rate settings with the corresponding functions.
+///
+/// - The SoundTouch class behaves like a first-in-first-out pipeline: The
+/// samples that are to be processed are fed into one of the pipe by calling
+/// function 'putSamples', while the ready processed samples can be read
+/// from the other end of the pipeline with function 'receiveSamples'.
+///
+/// - The SoundTouch processing classes require certain sized 'batches' of
+/// samples in order to process the sound. For this reason the classes buffer
+/// incoming samples until there are enough of samples available for
+/// processing, then they carry out the processing step and consequently
+/// make the processed samples available for outputting.
+///
+/// - For the above reason, the processing routines introduce a certain
+/// 'latency' between the input and output, so that the samples input to
+/// SoundTouch may not be immediately available in the output, and neither
+/// the amount of outputtable samples may not immediately be in direct
+/// relationship with the amount of previously input samples.
+///
+/// - The tempo/pitch/rate control parameters can be altered during processing.
+/// Please notice though that they aren't currently protected by semaphores,
+/// so in multi-thread application external semaphore protection may be
+/// required.
+///
+/// - This class utilizes classes 'TDStretch' for tempo change (without modifying
+/// pitch) and 'RateTransposer' for changing the playback rate (that is, both
+/// tempo and pitch in the same ratio) of the sound. The third available control
+/// 'pitch' (change pitch but maintain tempo) is produced by a combination of
+/// combining the two other controls.
+///
+/// Author : Copyright (c) Olli Parviainen
+/// Author e-mail : oparviai 'at' iki.fi
+/// SoundTouch WWW: http://www.surina.net/soundtouch
+///
+////////////////////////////////////////////////////////////////////////////////
+//
+// Last changed : $Date: 2009-12-28 22:10:14 +0200 (Mon, 28 Dec 2009) $
+// File revision : $Revision: 4 $
+//
+// $Id: SoundTouch.h 78 2009-12-28 20:10:14Z oparviai $
+//
+////////////////////////////////////////////////////////////////////////////////
+//
+// License :
+//
+// SoundTouch audio processing library
+// Copyright (c) Olli Parviainen
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+////////////////////////////////////////////////////////////////////////////////
+
+#ifndef SoundTouch_H
+#define SoundTouch_H
+
+#include "FIFOSamplePipe.h"
+#include "STTypes.h"
+
+namespace soundtouch
+{
+
+/// Soundtouch library version string
+#define SOUNDTOUCH_VERSION "1.5.0"
+
+/// SoundTouch library version id
+#define SOUNDTOUCH_VERSION_ID (10500)
+
+//
+// Available setting IDs for the 'setSetting' & 'get_setting' functions:
+
+/// Enable/disable anti-alias filter in pitch transposer (0 = disable)
+#define SETTING_USE_AA_FILTER 0
+
+/// Pitch transposer anti-alias filter length (8 .. 128 taps, default = 32)
+#define SETTING_AA_FILTER_LENGTH 1
+
+/// Enable/disable quick seeking algorithm in tempo changer routine
+/// (enabling quick seeking lowers CPU utilization but causes a minor sound
+/// quality compromising)
+#define SETTING_USE_QUICKSEEK 2
+
+/// Time-stretch algorithm single processing sequence length in milliseconds. This determines
+/// to how long sequences the original sound is chopped in the time-stretch algorithm.
+/// See "STTypes.h" or README for more information.
+#define SETTING_SEQUENCE_MS 3
+
+/// Time-stretch algorithm seeking window length in milliseconds for algorithm that finds the
+/// best possible overlapping location. This determines from how wide window the algorithm
+/// may look for an optimal joining location when mixing the sound sequences back together.
+/// See "STTypes.h" or README for more information.
+#define SETTING_SEEKWINDOW_MS 4
+
+/// Time-stretch algorithm overlap length in milliseconds. When the chopped sound sequences
+/// are mixed back together, to form a continuous sound stream, this parameter defines over
+/// how long period the two consecutive sequences are let to overlap each other.
+/// See "STTypes.h" or README for more information.
+#define SETTING_OVERLAP_MS 5
+
+
+class SoundTouch : public FIFOProcessor
+{
+private:
+ /// Rate transposer class instance
+ class RateTransposer *pRateTransposer;
+
+ /// Time-stretch class instance
+ class TDStretch *pTDStretch;
+
+ /// Virtual pitch parameter. Effective rate & tempo are calculated from these parameters.
+ float virtualRate;
+
+ /// Virtual pitch parameter. Effective rate & tempo are calculated from these parameters.
+ float virtualTempo;
+
+ /// Virtual pitch parameter. Effective rate & tempo are calculated from these parameters.
+ float virtualPitch;
+
+ /// Flag: Has sample rate been set?
+ BOOL bSrateSet;
+
+ /// Calculates effective rate & tempo valuescfrom 'virtualRate', 'virtualTempo' and
+ /// 'virtualPitch' parameters.
+ void calcEffectiveRateAndTempo();
+
+protected :
+ /// Number of channels
+ uint channels;
+
+ /// Effective 'rate' value calculated from 'virtualRate', 'virtualTempo' and 'virtualPitch'
+ float rate;
+
+ /// Effective 'tempo' value calculated from 'virtualRate', 'virtualTempo' and 'virtualPitch'
+ float tempo;
+
+public:
+ SoundTouch();
+ virtual ~SoundTouch();
+
+ /// Get SoundTouch library version string
+ static const char *getVersionString();
+
+ /// Get SoundTouch library version Id
+ static uint getVersionId();
+
+ /// Sets new rate control value. Normal rate = 1.0, smaller values
+ /// represent slower rate, larger faster rates.
+ void setRate(float newRate);
+
+ /// Sets new tempo control value. Normal tempo = 1.0, smaller values
+ /// represent slower tempo, larger faster tempo.
+ void setTempo(float newTempo);
+
+ /// Sets new rate control value as a difference in percents compared
+ /// to the original rate (-50 .. +100 %)
+ void setRateChange(float newRate);
+
+ /// Sets new tempo control value as a difference in percents compared
+ /// to the original tempo (-50 .. +100 %)
+ void setTempoChange(float newTempo);
+
+ /// Sets new pitch control value. Original pitch = 1.0, smaller values
+ /// represent lower pitches, larger values higher pitch.
+ void setPitch(float newPitch);
+
+ /// Sets pitch change in octaves compared to the original pitch
+ /// (-1.00 .. +1.00)
+ void setPitchOctaves(float newPitch);
+
+ /// Sets pitch change in semi-tones compared to the original pitch
+ /// (-12 .. +12)
+ void setPitchSemiTones(int newPitch);
+ void setPitchSemiTones(float newPitch);
+
+ /// Sets the number of channels, 1 = mono, 2 = stereo
+ void setChannels(uint numChannels);
+
+ /// Sets sample rate.
+ void setSampleRate(uint srate);
+
+ /// Flushes the last samples from the processing pipeline to the output.
+ /// Clears also the internal processing buffers.
+ //
+ /// Note: This function is meant for extracting the last samples of a sound
+ /// stream. This function may introduce additional blank samples in the end
+ /// of the sound stream, and thus it's not recommended to call this function
+ /// in the middle of a sound stream.
+ void flush();
+
+ /// Adds 'numSamples' pcs of samples from the 'samples' memory position into
+ /// the input of the object. Notice that sample rate _has_to_ be set before
+ /// calling this function, otherwise throws a runtime_error exception.
+ virtual void putSamples(
+ const SAMPLETYPE *samples, ///< Pointer to sample buffer.
+ uint numSamples ///< Number of samples in buffer. Notice
+ ///< that in case of stereo-sound a single sample
+ ///< contains data for both channels.
+ );
+
+ /// Clears all the samples in the object's output and internal processing
+ /// buffers.
+ virtual void clear();
+
+ /// Changes a setting controlling the processing system behaviour. See the
+ /// 'SETTING_...' defines for available setting ID's.
+ ///
+ /// \return 'TRUE' if the setting was succesfully changed
+ BOOL setSetting(int settingId, ///< Setting ID number. see SETTING_... defines.
+ int value ///< New setting value.
+ );
+
+ /// Reads a setting controlling the processing system behaviour. See the
+ /// 'SETTING_...' defines for available setting ID's.
+ ///
+ /// \return the setting value.
+ int getSetting(int settingId ///< Setting ID number, see SETTING_... defines.
+ ) const;
+
+ /// Returns number of samples currently unprocessed.
+ virtual uint numUnprocessedSamples() const;
+
+
+ /// Other handy functions that are implemented in the ancestor classes (see
+ /// classes 'FIFOProcessor' and 'FIFOSamplePipe')
+ ///
+ /// - receiveSamples() : Use this function to receive 'ready' processed samples from SoundTouch.
+ /// - numSamples() : Get number of 'ready' samples that can be received with
+ /// function 'receiveSamples()'
+ /// - isEmpty() : Returns nonzero if there aren't any 'ready' samples.
+ /// - clear() : Clears all samples from ready/processing buffers.
+};
+
+}
+#endif
diff --git a/plugins/soundtouch/soundtouch/include/soundtouch_config.h b/plugins/soundtouch/soundtouch/include/soundtouch_config.h
new file mode 100644
index 00000000..4097691b
--- /dev/null
+++ b/plugins/soundtouch/soundtouch/include/soundtouch_config.h
@@ -0,0 +1,88 @@
+/* include/soundtouch_config.h. Generated from soundtouch_config.h.in by configure. */
+/* include/soundtouch_config.h.in. Generated from configure.ac by autoheader. */
+
+/* Use Float as Sample type */
+#define FLOAT_SAMPLES 1
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#define HAVE_DLFCN_H 1
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the `m' library (-lm). */
+#define HAVE_LIBM 1
+
+/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
+ to 0 otherwise. */
+#define HAVE_MALLOC 1
+
+/* Define to 1 if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Use Integer as Sample type */
+/* #undef INTEGER_SAMPLES */
+
+/* Define to the sub-directory in which libtool stores uninstalled libraries.
+ */
+#define LT_OBJDIR ".libs/"
+
+/* Name of package */
+#define PACKAGE "soundtouch"
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT "http://www.surina.net/soundtouch"
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "SoundTouch"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "SoundTouch 1.4.0"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "soundtouch"
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "1.4.0"
+
+/* Define as the return type of signal handlers (`int' or `void'). */
+#define RETSIGTYPE void
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Version number of package */
+#define VERSION "1.4.0"
+
+/* Define to empty if `const' does not conform to ANSI C. */
+/* #undef const */
+
+/* Define to `__inline__' or `__inline' if that's what the C compiler
+ calls it, or to nothing if 'inline' is not supported under any name. */
+#ifndef __cplusplus
+/* #undef inline */
+#endif
+
+/* Define to rpl_malloc if the replacement function should be used. */
+/* #undef malloc */
diff --git a/plugins/soundtouch/soundtouch/source/SoundTouch/3dnow_win.cpp b/plugins/soundtouch/soundtouch/source/SoundTouch/3dnow_win.cpp
new file mode 100644
index 00000000..f0a9d7ec
--- /dev/null
+++ b/plugins/soundtouch/soundtouch/source/SoundTouch/3dnow_win.cpp
@@ -0,0 +1,349 @@
+////////////////////////////////////////////////////////////////////////////////
+///
+/// Win32 version of the AMD 3DNow! optimized routines for AMD K6-2/Athlon
+/// processors. All 3DNow! optimized functions have been gathered into this
+/// single source code file, regardless to their class or original source code
+/// file, in order to ease porting the library to other compiler and processor
+/// platforms.
+///
+/// By the way; the performance gain depends heavily on the CPU generation: On
+/// K6-2 these routines provided speed-up of even 2.4 times, while on Athlon the
+/// difference to the original routines stayed at unremarkable 8%! Such a small
+/// improvement on Athlon is due to 3DNow can perform only two operations in
+/// parallel, and obviously also the Athlon FPU is doing a very good job with
+/// the standard C floating point routines! Here these routines are anyway,
+/// although it might not be worth the effort to convert these to GCC platform,
+/// for Athlon CPU at least. The situation is different regarding the SSE
+/// optimizations though, thanks to the four parallel operations of SSE that
+/// already make a difference.
+///
+/// This file is to be compiled in Windows platform with Microsoft Visual C++
+/// Compiler. Please see '3dnow_gcc.cpp' for the gcc compiler version for all
+/// GNU platforms (if file supplied).
+///
+/// NOTICE: If using Visual Studio 6.0, you'll need to install the "Visual C++
+/// 6.0 processor pack" update to support 3DNow! instruction set. The update is
+/// available for download at Microsoft Developers Network, see here:
+/// http://msdn.microsoft.com/en-us/vstudio/aa718349.aspx
+///
+/// If the above URL is expired or removed, go to "http://msdn.microsoft.com" and
+/// perform a search with keywords "processor pack".
+///
+/// Author : Copyright (c) Olli Parviainen
+/// Author e-mail : oparviai 'at' iki.fi
+/// SoundTouch WWW: http://www.surina.net/soundtouch
+///
+////////////////////////////////////////////////////////////////////////////////
+//
+// Last changed : $Date: 2009-02-21 18:00:14 +0200 (Sat, 21 Feb 2009) $
+// File revision : $Revision: 4 $
+//
+// $Id: 3dnow_win.cpp 63 2009-02-21 16:00:14Z oparviai $
+//
+////////////////////////////////////////////////////////////////////////////////
+//
+// License :
+//
+// SoundTouch audio processing library
+// Copyright (c) Olli Parviainen
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+////////////////////////////////////////////////////////////////////////////////
+
+#include "cpu_detect.h"
+#include "STTypes.h"
+
+#ifndef WIN32
+#error "wrong platform - this source code file is exclusively for Win32 platform"
+#endif
+
+using namespace soundtouch;
+
+#ifdef ALLOW_3DNOW
+// 3DNow! routines available only with float sample type
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// implementation of 3DNow! optimized functions of class 'TDStretch3DNow'
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#include "TDStretch.h"
+
+
+// Calculates cross correlation of two buffers
+double TDStretch3DNow::calcCrossCorrStereo(const float *pV1, const float *pV2) const
+{
+ int overlapLengthLocal = overlapLength;
+ float corr = 0;
+
+ // Calculates the cross-correlation value between 'pV1' and 'pV2' vectors
+ /*
+ c-pseudocode:
+
+ corr = 0;
+ for (i = 0; i < overlapLength / 4; i ++)
+ {
+ corr += pV1[0] * pV2[0];
+ pV1[1] * pV2[1];
+ pV1[2] * pV2[2];
+ pV1[3] * pV2[3];
+ pV1[4] * pV2[4];
+ pV1[5] * pV2[5];
+ pV1[6] * pV2[6];
+ pV1[7] * pV2[7];
+
+ pV1 += 8;
+ pV2 += 8;
+ }
+ */
+
+ _asm
+ {
+ // give prefetch hints to CPU of what data are to be needed soonish.
+ // give more aggressive hints on pV1 as that changes more between different calls
+ // while pV2 stays the same.
+ prefetch [pV1]
+ prefetch [pV2]
+ prefetch [pV1 + 32]
+
+ mov eax, dword ptr pV2
+ mov ebx, dword ptr pV1
+
+ pxor mm0, mm0
+
+ mov ecx, overlapLengthLocal
+ shr ecx, 2 // div by four
+
+ loop1:
+ movq mm1, [eax]
+ prefetch [eax + 32] // give a prefetch hint to CPU what data are to be needed soonish
+ pfmul mm1, [ebx]
+ prefetch [ebx + 64] // give a prefetch hint to CPU what data are to be needed soonish
+
+ movq mm2, [eax + 8]
+ pfadd mm0, mm1
+ pfmul mm2, [ebx + 8]
+
+ movq mm3, [eax + 16]
+ pfadd mm0, mm2
+ pfmul mm3, [ebx + 16]
+
+ movq mm4, [eax + 24]
+ pfadd mm0, mm3
+ pfmul mm4, [ebx + 24]
+
+ add eax, 32
+ pfadd mm0, mm4
+ add ebx, 32
+
+ dec ecx
+ jnz loop1
+
+ // add halfs of mm0 together and return the result.
+ // note: mm1 is used as a dummy parameter only, we actually don't care about it's value
+ pfacc mm0, mm1
+ movd corr, mm0
+ femms
+ }
+
+ return corr;
+}
+
+
+
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// implementation of 3DNow! optimized functions of class 'FIRFilter'
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#include "FIRFilter.h"
+
+FIRFilter3DNow::FIRFilter3DNow() : FIRFilter()
+{
+ filterCoeffsUnalign = NULL;
+ filterCoeffsAlign = NULL;
+}
+
+
+FIRFilter3DNow::~FIRFilter3DNow()
+{
+ delete[] filterCoeffsUnalign;
+ filterCoeffsUnalign = NULL;
+ filterCoeffsAlign = NULL;
+}
+
+
+// (overloaded) Calculates filter coefficients for 3DNow! routine
+void FIRFilter3DNow::setCoefficients(const float *coeffs, uint newLength, uint uResultDivFactor)
+{
+ uint i;
+ float fDivider;
+
+ FIRFilter::setCoefficients(coeffs, newLength, uResultDivFactor);
+
+ // Scale the filter coefficients so that it won't be necessary to scale the filtering result
+ // also rearrange coefficients suitably for 3DNow!
+ // Ensure that filter coeffs array is aligned to 16-byte boundary
+ delete[] filterCoeffsUnalign;
+ filterCoeffsUnalign = new float[2 * newLength + 4];
+ filterCoeffsAlign = (float *)(((uint)filterCoeffsUnalign + 15) & (uint)-16);
+
+ fDivider = (float)resultDivider;
+
+ // rearrange the filter coefficients for mmx routines
+ for (i = 0; i < newLength; i ++)
+ {
+ filterCoeffsAlign[2 * i + 0] =
+ filterCoeffsAlign[2 * i + 1] = coeffs[i + 0] / fDivider;
+ }
+}
+
+
+// 3DNow!-optimized version of the filter routine for stereo sound
+uint FIRFilter3DNow::evaluateFilterStereo(float *dest, const float *src, uint numSamples) const
+{
+ float *filterCoeffsLocal = filterCoeffsAlign;
+ uint count = (numSamples - length) & (uint)-2;
+ uint lengthLocal = length / 4;
+
+ assert(length != 0);
+ assert(count % 2 == 0);
+
+ /* original code:
+
+ double suml1, suml2;
+ double sumr1, sumr2;
+ uint i, j;
+
+ for (j = 0; j < count; j += 2)
+ {
+ const float *ptr;
+
+ suml1 = sumr1 = 0.0;
+ suml2 = sumr2 = 0.0;
+ ptr = src;
+ filterCoeffsLocal = filterCoeffs;
+ for (i = 0; i < lengthLocal; i ++)
+ {
+ // unroll loop for efficiency.
+
+ suml1 += ptr[0] * filterCoeffsLocal[0] +
+ ptr[2] * filterCoeffsLocal[2] +
+ ptr[4] * filterCoeffsLocal[4] +
+ ptr[6] * filterCoeffsLocal[6];
+
+ sumr1 += ptr[1] * filterCoeffsLocal[1] +
+ ptr[3] * filterCoeffsLocal[3] +
+ ptr[5] * filterCoeffsLocal[5] +
+ ptr[7] * filterCoeffsLocal[7];
+
+ suml2 += ptr[8] * filterCoeffsLocal[0] +
+ ptr[10] * filterCoeffsLocal[2] +
+ ptr[12] * filterCoeffsLocal[4] +
+ ptr[14] * filterCoeffsLocal[6];
+
+ sumr2 += ptr[9] * filterCoeffsLocal[1] +
+ ptr[11] * filterCoeffsLocal[3] +
+ ptr[13] * filterCoeffsLocal[5] +
+ ptr[15] * filterCoeffsLocal[7];
+
+ ptr += 16;
+ filterCoeffsLocal += 8;
+ }
+ dest[0] = (float)suml1;
+ dest[1] = (float)sumr1;
+ dest[2] = (float)suml2;
+ dest[3] = (float)sumr2;
+
+ src += 4;
+ dest += 4;
+ }
+
+ */
+ _asm
+ {
+ mov eax, dword ptr dest
+ mov ebx, dword ptr src
+ mov edx, count
+ shr edx, 1
+
+ loop1:
+ // "outer loop" : during each round 2*2 output samples are calculated
+ prefetch [ebx] // give a prefetch hint to CPU what data are to be needed soonish
+ prefetch [filterCoeffsLocal] // give a prefetch hint to CPU what data are to be needed soonish
+
+ mov esi, ebx
+ mov edi, filterCoeffsLocal
+ pxor mm0, mm0
+ pxor mm1, mm1
+ mov ecx, lengthLocal
+
+ loop2:
+ // "inner loop" : during each round four FIR filter taps are evaluated for 2*2 output samples
+ movq mm2, [edi]
+ movq mm3, mm2
+ prefetch [edi + 32] // give a prefetch hint to CPU what data are to be needed soonish
+ pfmul mm2, [esi]
+ prefetch [esi + 32] // give a prefetch hint to CPU what data are to be needed soonish
+ pfmul mm3, [esi + 8]
+
+ movq mm4, [edi + 8]
+ movq mm5, mm4
+ pfadd mm0, mm2
+ pfmul mm4, [esi + 8]
+ pfadd mm1, mm3
+ pfmul mm5, [esi + 16]
+
+ movq mm2, [edi + 16]
+ movq mm6, mm2
+ pfadd mm0, mm4
+ pfmul mm2, [esi + 16]
+ pfadd mm1, mm5
+ pfmul mm6, [esi + 24]
+
+ movq mm3, [edi + 24]
+ movq mm7, mm3
+ pfadd mm0, mm2
+ pfmul mm3, [esi + 24]
+ pfadd mm1, mm6
+ pfmul mm7, [esi + 32]
+ add esi, 32
+ pfadd mm0, mm3
+ add edi, 32
+ pfadd mm1, mm7
+
+ dec ecx
+ jnz loop2
+
+ movq [eax], mm0
+ add ebx, 16
+ movq [eax + 8], mm1
+ add eax, 16
+
+ dec edx
+ jnz loop1
+
+ femms
+ }
+
+ return count;
+}
+
+
+#endif // ALLOW_3DNOW
diff --git a/plugins/soundtouch/soundtouch/source/SoundTouch/AAFilter.cpp b/plugins/soundtouch/soundtouch/source/SoundTouch/AAFilter.cpp
new file mode 100644
index 00000000..96abda49
--- /dev/null
+++ b/plugins/soundtouch/soundtouch/source/SoundTouch/AAFilter.cpp
@@ -0,0 +1,184 @@
+////////////////////////////////////////////////////////////////////////////////
+///
+/// FIR low-pass (anti-alias) filter with filter coefficient design routine and
+/// MMX optimization.
+///
+/// Anti-alias filter is used to prevent folding of high frequencies when
+/// transposing the sample rate with interpolation.
+///
+/// Author : Copyright (c) Olli Parviainen
+/// Author e-mail : oparviai 'at' iki.fi
+/// SoundTouch WWW: http://www.surina.net/soundtouch
+///
+////////////////////////////////////////////////////////////////////////////////
+//
+// Last changed : $Date: 2009-01-11 13:34:24 +0200 (Sun, 11 Jan 2009) $
+// File revision : $Revision: 4 $
+//
+// $Id: AAFilter.cpp 45 2009-01-11 11:34:24Z oparviai $
+//
+////////////////////////////////////////////////////////////////////////////////
+//
+// License :
+//
+// SoundTouch audio processing library
+// Copyright (c) Olli Parviainen
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+////////////////////////////////////////////////////////////////////////////////
+
+#include <memory.h>
+#include <assert.h>
+#include <math.h>
+#include <stdlib.h>
+#include "AAFilter.h"
+#include "FIRFilter.h"
+
+using namespace soundtouch;
+
+#define PI 3.141592655357989
+#define TWOPI (2 * PI)
+
+/*****************************************************************************
+ *
+ * Implementation of the class 'AAFilter'
+ *
+ *****************************************************************************/
+
+AAFilter::AAFilter(uint len)
+{
+ pFIR = FIRFilter::newInstance();
+ cutoffFreq = 0.5;
+ setLength(len);
+}
+
+
+
+AAFilter::~AAFilter()
+{
+ delete pFIR;
+}
+
+
+
+// Sets new anti-alias filter cut-off edge frequency, scaled to
+// sampling frequency (nyquist frequency = 0.5).
+// The filter will cut frequencies higher than the given frequency.
+void AAFilter::setCutoffFreq(double newCutoffFreq)
+{
+ cutoffFreq = newCutoffFreq;
+ calculateCoeffs();
+}
+
+
+
+// Sets number of FIR filter taps
+void AAFilter::setLength(uint newLength)
+{
+ length = newLength;
+ calculateCoeffs();
+}
+
+
+
+// Calculates coefficients for a low-pass FIR filter using Hamming window
+void AAFilter::calculateCoeffs()
+{
+ uint i;
+ double cntTemp, temp, tempCoeff,h, w;
+ double fc2, wc;
+ double scaleCoeff, sum;
+ double *work;
+ SAMPLETYPE *coeffs;
+
+ assert(length >= 2);
+ assert(length % 4 == 0);
+ assert(cutoffFreq >= 0);
+ assert(cutoffFreq <= 0.5);
+
+ work = new double[length];
+ coeffs = new SAMPLETYPE[length];
+
+ fc2 = 2.0 * cutoffFreq;
+ wc = PI * fc2;
+ tempCoeff = TWOPI / (double)length;
+
+ sum = 0;
+ for (i = 0; i < length; i ++)
+ {
+ cntTemp = (double)i - (double)(length / 2);
+
+ temp = cntTemp * wc;
+ if (temp != 0)
+ {
+ h = fc2 * sin(temp) / temp; // sinc function
+ }
+ else
+ {
+ h = 1.0;
+ }
+ w = 0.54 + 0.46 * cos(tempCoeff * cntTemp); // hamming window
+
+ temp = w * h;
+ work[i] = temp;
+
+ // calc net sum of coefficients
+ sum += temp;
+ }
+
+ // ensure the sum of coefficients is larger than zero
+ assert(sum > 0);
+
+ // ensure we've really designed a lowpass filter...
+ assert(work[length/2] > 0);
+ assert(work[length/2 + 1] > -1e-6);
+ assert(work[length/2 - 1] > -1e-6);
+
+ // Calculate a scaling coefficient in such a way that the result can be
+ // divided by 16384
+ scaleCoeff = 16384.0f / sum;
+
+ for (i = 0; i < length; i ++)
+ {
+ // scale & round to nearest integer
+ temp = work[i] * scaleCoeff;
+ temp += (temp >= 0) ? 0.5 : -0.5;
+ // ensure no overfloods
+ assert(temp >= -32768 && temp <= 32767);
+ coeffs[i] = (SAMPLETYPE)temp;
+ }
+
+ // Set coefficients. Use divide factor 14 => divide result by 2^14 = 16384
+ pFIR->setCoefficients(coeffs, length, 14);
+
+ delete[] work;
+ delete[] coeffs;
+}
+
+
+// Applies the filter to the given sequence of samples.
+// Note : The amount of outputted samples is by value of 'filter length'
+// smaller than the amount of input samples.
+uint AAFilter::evaluate(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSamples, uint numChannels) const
+{
+ return pFIR->evaluate(dest, src, numSamples, numChannels);
+}
+
+
+uint AAFilter::getLength() const
+{
+ return pFIR->getLength();
+}
diff --git a/plugins/soundtouch/soundtouch/source/SoundTouch/AAFilter.h b/plugins/soundtouch/soundtouch/source/SoundTouch/AAFilter.h
new file mode 100644
index 00000000..d5c8ce4c
--- /dev/null
+++ b/plugins/soundtouch/soundtouch/source/SoundTouch/AAFilter.h
@@ -0,0 +1,91 @@
+////////////////////////////////////////////////////////////////////////////////
+///
+/// Sampled sound tempo changer/time stretch algorithm. Changes the sound tempo
+/// while maintaining the original pitch by using a time domain WSOLA-like method
+/// with several performance-increasing tweaks.
+///
+/// Anti-alias filter is used to prevent folding of high frequencies when
+/// transposing the sample rate with interpolation.
+///
+/// Author : Copyright (c) Olli Parviainen
+/// Author e-mail : oparviai 'at' iki.fi
+/// SoundTouch WWW: http://www.surina.net/soundtouch
+///
+////////////////////////////////////////////////////////////////////////////////
+//
+// Last changed : $Date: 2008-02-10 18:26:55 +0200 (Sun, 10 Feb 2008) $
+// File revision : $Revision: 4 $
+//
+// $Id: AAFilter.h 11 2008-02-10 16:26:55Z oparviai $
+//
+////////////////////////////////////////////////////////////////////////////////
+//
+// License :
+//
+// SoundTouch audio processing library
+// Copyright (c) Olli Parviainen
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+////////////////////////////////////////////////////////////////////////////////
+
+#ifndef AAFilter_H
+#define AAFilter_H
+
+#include "STTypes.h"
+
+namespace soundtouch
+{
+
+class AAFilter
+{
+protected:
+ class FIRFilter *pFIR;
+
+ /// Low-pass filter cut-off frequency, negative = invalid
+ double cutoffFreq;
+
+ /// num of filter taps
+ uint length;
+
+ /// Calculate the FIR coefficients realizing the given cutoff-frequency
+ void calculateCoeffs();
+public:
+ AAFilter(uint length);
+
+ ~AAFilter();
+
+ /// Sets new anti-alias filter cut-off edge frequency, scaled to sampling
+ /// frequency (nyquist frequency = 0.5). The filter will cut off the
+ /// frequencies than that.
+ void setCutoffFreq(double newCutoffFreq);
+
+ /// Sets number of FIR filter taps, i.e. ~filter complexity
+ void setLength(uint newLength);
+
+ uint getLength() const;
+
+ /// Applies the filter to the given sequence of samples.
+ /// Note : The amount of outputted samples is by value of 'filter length'
+ /// smaller than the amount of input samples.
+ uint evaluate(SAMPLETYPE *dest,
+ const SAMPLETYPE *src,
+ uint numSamples,
+ uint numChannels) const;
+};
+
+}
+
+#endif
diff --git a/plugins/soundtouch/soundtouch/source/SoundTouch/BPMDetect.cpp b/plugins/soundtouch/soundtouch/source/SoundTouch/BPMDetect.cpp
new file mode 100644
index 00000000..405f514b
--- /dev/null
+++ b/plugins/soundtouch/soundtouch/source/SoundTouch/BPMDetect.cpp
@@ -0,0 +1,308 @@
+////////////////////////////////////////////////////////////////////////////////
+///
+/// Beats-per-minute (BPM) detection routine.
+///
+/// The beat detection algorithm works as follows:
+/// - Use function 'inputSamples' to input a chunks of samples to the class for
+/// analysis. It's a good idea to enter a large sound file or stream in smallish
+/// chunks of around few kilosamples in order not to extinguish too much RAM memory.
+/// - Inputted sound data is decimated to approx 500 Hz to reduce calculation burden,
+/// which is basically ok as low (bass) frequencies mostly determine the beat rate.
+/// Simple averaging is used for anti-alias filtering because the resulting signal
+/// quality isn't of that high importance.
+/// - Decimated sound data is enveloped, i.e. the amplitude shape is detected by
+/// taking absolute value that's smoothed by sliding average. Signal levels that
+/// are below a couple of times the general RMS amplitude level are cut away to
+/// leave only notable peaks there.
+/// - Repeating sound patterns (e.g. beats) are detected by calculating short-term
+/// autocorrelation function of the enveloped signal.
+/// - After whole sound data file has been analyzed as above, the bpm level is
+/// detected by function 'getBpm' that finds the highest peak of the autocorrelation
+/// function, calculates it's precise location and converts this reading to bpm's.
+///
+/// Author : Copyright (c) Olli Parviainen
+/// Author e-mail : oparviai 'at' iki.fi
+/// SoundTouch WWW: http://www.surina.net/soundtouch
+///
+////////////////////////////////////////////////////////////////////////////////
+//
+// Last changed : $Date: 2009-02-21 18:00:14 +0200 (Sat, 21 Feb 2009) $
+// File revision : $Revision: 4 $
+//
+// $Id: BPMDetect.cpp 63 2009-02-21 16:00:14Z oparviai $
+//
+////////////////////////////////////////////////////////////////////////////////
+//
+// License :
+//
+// SoundTouch audio processing library
+// Copyright (c) Olli Parviainen
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+////////////////////////////////////////////////////////////////////////////////
+
+#include <math.h>
+#include <assert.h>
+#include <string.h>
+#include "FIFOSampleBuffer.h"
+#include "PeakFinder.h"
+#include "BPMDetect.h"
+
+using namespace soundtouch;
+
+#define INPUT_BLOCK_SAMPLES 2048
+#define DECIMATED_BLOCK_SAMPLES 256
+
+/// decay constant for calculating RMS volume sliding average approximation
+/// (time constant is about 10 sec)
+const float avgdecay = 0.99986f;
+
+/// Normalization coefficient for calculating RMS sliding average approximation.
+const float avgnorm = (1 - avgdecay);
+
+
+
+BPMDetect::BPMDetect(int numChannels, int aSampleRate)
+{
+ this->sampleRate = aSampleRate;
+ this->channels = numChannels;
+
+ decimateSum = 0;
+ decimateCount = 0;
+
+ envelopeAccu = 0;
+
+ // Initialize RMS volume accumulator to RMS level of 3000 (out of 32768) that's
+ // a typical RMS signal level value for song data. This value is then adapted
+ // to the actual level during processing.
+#ifdef INTEGER_SAMPLES
+ // integer samples
+ RMSVolumeAccu = (3000 * 3000) / avgnorm;
+#else
+ // float samples, scaled to range [-1..+1[
+ RMSVolumeAccu = (0.092f * 0.092f) / avgnorm;
+#endif
+
+ // choose decimation factor so that result is approx. 500 Hz
+ decimateBy = sampleRate / 500;
+ assert(decimateBy > 0);
+ assert(INPUT_BLOCK_SAMPLES < decimateBy * DECIMATED_BLOCK_SAMPLES);
+
+ // Calculate window length & starting item according to desired min & max bpms
+ windowLen = (60 * sampleRate) / (decimateBy * MIN_BPM);
+ windowStart = (60 * sampleRate) / (decimateBy * MAX_BPM);
+
+ assert(windowLen > windowStart);
+
+ // allocate new working objects
+ xcorr = new float[windowLen];
+ memset(xcorr, 0, windowLen * sizeof(float));
+
+ // allocate processing buffer
+ buffer = new FIFOSampleBuffer();
+ // we do processing in mono mode
+ buffer->setChannels(1);
+ buffer->clear();
+}
+
+
+
+BPMDetect::~BPMDetect()
+{
+ delete[] xcorr;
+ delete buffer;
+}
+
+
+
+/// convert to mono, low-pass filter & decimate to about 500 Hz.
+/// return number of outputted samples.
+///
+/// Decimation is used to remove the unnecessary frequencies and thus to reduce
+/// the amount of data needed to be processed as calculating autocorrelation
+/// function is a very-very heavy operation.
+///
+/// Anti-alias filtering is done simply by averaging the samples. This is really a
+/// poor-man's anti-alias filtering, but it's not so critical in this kind of application
+/// (it'd also be difficult to design a high-quality filter with steep cut-off at very
+/// narrow band)
+int BPMDetect::decimate(SAMPLETYPE *dest, const SAMPLETYPE *src, int numsamples)
+{
+ int count, outcount;
+ LONG_SAMPLETYPE out;
+
+ assert(channels > 0);
+ assert(decimateBy > 0);
+ outcount = 0;
+ for (count = 0; count < numsamples; count ++)
+ {
+ int j;
+
+ // convert to mono and accumulate
+ for (j = 0; j < channels; j ++)
+ {
+ decimateSum += src[j];
+ }
+ src += j;
+
+ decimateCount ++;
+ if (decimateCount >= decimateBy)
+ {
+ // Store every Nth sample only
+ out = (LONG_SAMPLETYPE)(decimateSum / (decimateBy * channels));
+ decimateSum = 0;
+ decimateCount = 0;
+#ifdef INTEGER_SAMPLES
+ // check ranges for sure (shouldn't actually be necessary)
+ if (out > 32767)
+ {
+ out = 32767;
+ }
+ else if (out < -32768)
+ {
+ out = -32768;
+ }
+#endif // INTEGER_SAMPLES
+ dest[outcount] = (SAMPLETYPE)out;
+ outcount ++;
+ }
+ }
+ return outcount;
+}
+
+
+
+// Calculates autocorrelation function of the sample history buffer
+void BPMDetect::updateXCorr(int process_samples)
+{
+ int offs;
+ SAMPLETYPE *pBuffer;
+
+ assert(buffer->numSamples() >= (uint)(process_samples + windowLen));
+
+ pBuffer = buffer->ptrBegin();
+ for (offs = windowStart; offs < windowLen; offs ++)
+ {
+ LONG_SAMPLETYPE sum;
+ int i;
+
+ sum = 0;
+ for (i = 0; i < process_samples; i ++)
+ {
+ sum += pBuffer[i] * pBuffer[i + offs]; // scaling the sub-result shouldn't be necessary
+ }
+// xcorr[offs] *= xcorr_decay; // decay 'xcorr' here with suitable coefficients
+ // if it's desired that the system adapts automatically to
+ // various bpms, e.g. in processing continouos music stream.
+ // The 'xcorr_decay' should be a value that's smaller than but
+ // close to one, and should also depend on 'process_samples' value.
+
+ xcorr[offs] += (float)sum;
+ }
+}
+
+
+
+// Calculates envelope of the sample data
+void BPMDetect::calcEnvelope(SAMPLETYPE *samples, int numsamples)
+{
+ const float decay = 0.7f; // decay constant for smoothing the envelope
+ const float norm = (1 - decay);
+
+ int i;
+ LONG_SAMPLETYPE out;
+ float val;
+
+ for (i = 0; i < numsamples; i ++)
+ {
+ // calc average RMS volume
+ RMSVolumeAccu *= avgdecay;
+ val = (float)fabs((float)samples[i]);
+ RMSVolumeAccu += val * val;
+
+ // cut amplitudes that are below 2 times average RMS volume
+ // (we're interested in peak values, not the silent moments)
+ val -= 2 * (float)sqrt(RMSVolumeAccu * avgnorm);
+ val = (val > 0) ? val : 0;
+
+ // smooth amplitude envelope
+ envelopeAccu *= decay;
+ envelopeAccu += val;
+ out = (LONG_SAMPLETYPE)(envelopeAccu * norm);
+
+#ifdef INTEGER_SAMPLES
+ // cut peaks (shouldn't be necessary though)
+ if (out > 32767) out = 32767;
+#endif // INTEGER_SAMPLES
+ samples[i] = (SAMPLETYPE)out;
+ }
+}
+
+
+
+void BPMDetect::inputSamples(const SAMPLETYPE *samples, int numSamples)
+{
+ SAMPLETYPE decimated[DECIMATED_BLOCK_SAMPLES];
+
+ // iterate so that max INPUT_BLOCK_SAMPLES processed per iteration
+ while (numSamples > 0)
+ {
+ int block;
+ int decSamples;
+
+ block = (numSamples > INPUT_BLOCK_SAMPLES) ? INPUT_BLOCK_SAMPLES : numSamples;
+
+ // decimate. note that converts to mono at the same time
+ decSamples = decimate(decimated, samples, block);
+ samples += block * channels;
+ numSamples -= block;
+
+ // envelope new samples and add them to buffer
+ calcEnvelope(decimated, decSamples);
+ buffer->putSamples(decimated, decSamples);
+ }
+
+ // when the buffer has enought samples for processing...
+ if ((int)buffer->numSamples() > windowLen)
+ {
+ int processLength;
+
+ // how many samples are processed
+ processLength = (int)buffer->numSamples() - windowLen;
+
+ // ... calculate autocorrelations for oldest samples...
+ updateXCorr(processLength);
+ // ... and remove them from the buffer
+ buffer->receiveSamples(processLength);
+ }
+}
+
+
+
+float BPMDetect::getBpm()
+{
+ double peakPos;
+ PeakFinder peakFinder;
+
+ // find peak position
+ peakPos = peakFinder.detectPeak(xcorr, windowStart, windowLen);
+
+ assert(decimateBy != 0);
+ if (peakPos < 1e-6) return 0.0; // detection failed.
+
+ // calculate BPM
+ return (float)(60.0 * (((double)sampleRate / (double)decimateBy) / peakPos));
+}
diff --git a/plugins/soundtouch/soundtouch/source/SoundTouch/FIFOSampleBuffer.cpp b/plugins/soundtouch/soundtouch/source/SoundTouch/FIFOSampleBuffer.cpp
new file mode 100644
index 00000000..01f64b08
--- /dev/null
+++ b/plugins/soundtouch/soundtouch/source/SoundTouch/FIFOSampleBuffer.cpp
@@ -0,0 +1,262 @@
+////////////////////////////////////////////////////////////////////////////////
+///
+/// A buffer class for temporarily storaging sound samples, operates as a
+/// first-in-first-out pipe.
+///
+/// Samples are added to the end of the sample buffer with the 'putSamples'
+/// function, and are received from the beginning of the buffer by calling
+/// the 'receiveSamples' function. The class automatically removes the
+/// outputted samples from the buffer, as well as grows the buffer size
+/// whenever necessary.
+///
+/// Author : Copyright (c) Olli Parviainen
+/// Author e-mail : oparviai 'at' iki.fi
+/// SoundTouch WWW: http://www.surina.net/soundtouch
+///
+////////////////////////////////////////////////////////////////////////////////
+//
+// Last changed : $Date: 2009-02-27 19:24:42 +0200 (Fri, 27 Feb 2009) $
+// File revision : $Revision: 4 $
+//
+// $Id: FIFOSampleBuffer.cpp 68 2009-02-27 17:24:42Z oparviai $
+//
+////////////////////////////////////////////////////////////////////////////////
+//
+// License :
+//
+// SoundTouch audio processing library
+// Copyright (c) Olli Parviainen
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+////////////////////////////////////////////////////////////////////////////////
+
+#include <stdlib.h>
+#include <memory.h>
+#include <string.h>
+#include <assert.h>
+#include <stdexcept>
+
+#include "FIFOSampleBuffer.h"
+
+using namespace soundtouch;
+
+// Constructor
+FIFOSampleBuffer::FIFOSampleBuffer(int numChannels)
+{
+ assert(numChannels > 0);
+ sizeInBytes = 0; // reasonable initial value
+ buffer = NULL;
+ bufferUnaligned = NULL;
+ samplesInBuffer = 0;
+ bufferPos = 0;
+ channels = (uint)numChannels;
+ ensureCapacity(32); // allocate initial capacity
+}
+
+
+// destructor
+FIFOSampleBuffer::~FIFOSampleBuffer()
+{
+ delete[] bufferUnaligned;
+ bufferUnaligned = NULL;
+ buffer = NULL;
+}
+
+
+// Sets number of channels, 1 = mono, 2 = stereo
+void FIFOSampleBuffer::setChannels(int numChannels)
+{
+ uint usedBytes;
+
+ assert(numChannels > 0);
+ usedBytes = channels * samplesInBuffer;
+ channels = (uint)numChannels;
+ samplesInBuffer = usedBytes / channels;
+}
+
+
+// if output location pointer 'bufferPos' isn't zero, 'rewinds' the buffer and
+// zeroes this pointer by copying samples from the 'bufferPos' pointer
+// location on to the beginning of the buffer.
+void FIFOSampleBuffer::rewind()
+{
+ if (buffer && bufferPos)
+ {
+ memmove(buffer, ptrBegin(), sizeof(SAMPLETYPE) * channels * samplesInBuffer);
+ bufferPos = 0;
+ }
+}
+
+
+// Adds 'numSamples' pcs of samples from the 'samples' memory position to
+// the sample buffer.
+void FIFOSampleBuffer::putSamples(const SAMPLETYPE *samples, uint nSamples)
+{
+ memcpy(ptrEnd(nSamples), samples, sizeof(SAMPLETYPE) * nSamples * channels);
+ samplesInBuffer += nSamples;
+}
+
+
+// Increases the number of samples in the buffer without copying any actual
+// samples.
+//
+// This function is used to update the number of samples in the sample buffer
+// when accessing the buffer directly with 'ptrEnd' function. Please be
+// careful though!
+void FIFOSampleBuffer::putSamples(uint nSamples)
+{
+ uint req;
+
+ req = samplesInBuffer + nSamples;
+ ensureCapacity(req);
+ samplesInBuffer += nSamples;
+}
+
+
+// Returns a pointer to the end of the used part of the sample buffer (i.e.
+// where the new samples are to be inserted). This function may be used for
+// inserting new samples into the sample buffer directly. Please be careful!
+//
+// Parameter 'slackCapacity' tells the function how much free capacity (in
+// terms of samples) there _at least_ should be, in order to the caller to
+// succesfully insert all the required samples to the buffer. When necessary,
+// the function grows the buffer size to comply with this requirement.
+//
+// When using this function as means for inserting new samples, also remember
+// to increase the sample count afterwards, by calling the
+// 'putSamples(numSamples)' function.
+SAMPLETYPE *FIFOSampleBuffer::ptrEnd(uint slackCapacity)
+{
+ ensureCapacity(samplesInBuffer + slackCapacity);
+ return buffer + samplesInBuffer * channels;
+}
+
+
+// Returns a pointer to the beginning of the currently non-outputted samples.
+// This function is provided for accessing the output samples directly.
+// Please be careful!
+//
+// When using this function to output samples, also remember to 'remove' the
+// outputted samples from the buffer by calling the
+// 'receiveSamples(numSamples)' function
+SAMPLETYPE *FIFOSampleBuffer::ptrBegin()
+{
+ assert(buffer);
+ return buffer + bufferPos * channels;
+}
+
+
+// Ensures that the buffer has enought capacity, i.e. space for _at least_
+// 'capacityRequirement' number of samples. The buffer is grown in steps of
+// 4 kilobytes to eliminate the need for frequently growing up the buffer,
+// as well as to round the buffer size up to the virtual memory page size.
+void FIFOSampleBuffer::ensureCapacity(uint capacityRequirement)
+{
+ SAMPLETYPE *tempUnaligned, *temp;
+
+ if (capacityRequirement > getCapacity())
+ {
+ // enlarge the buffer in 4kbyte steps (round up to next 4k boundary)
+ sizeInBytes = (capacityRequirement * channels * sizeof(SAMPLETYPE) + 4095) & (uint)-4096;
+ assert(sizeInBytes % 2 == 0);
+ tempUnaligned = new SAMPLETYPE[sizeInBytes / sizeof(SAMPLETYPE) + 16 / sizeof(SAMPLETYPE)];
+ if (tempUnaligned == NULL)
+ {
+ throw std::runtime_error("Couldn't allocate memory!\n");
+ }
+ // Align the buffer to begin at 16byte cache line boundary for optimal performance
+ temp = (SAMPLETYPE *)(((ulong)tempUnaligned + 15) & (ulong)-16);
+ if (samplesInBuffer)
+ {
+ memcpy(temp, ptrBegin(), samplesInBuffer * channels * sizeof(SAMPLETYPE));
+ }
+ delete[] bufferUnaligned;
+ buffer = temp;
+ bufferUnaligned = tempUnaligned;
+ bufferPos = 0;
+ }
+ else
+ {
+ // simply rewind the buffer (if necessary)
+ rewind();
+ }
+}
+
+
+// Returns the current buffer capacity in terms of samples
+uint FIFOSampleBuffer::getCapacity() const
+{
+ return sizeInBytes / (channels * sizeof(SAMPLETYPE));
+}
+
+
+// Returns the number of samples currently in the buffer
+uint FIFOSampleBuffer::numSamples() const
+{
+ return samplesInBuffer;
+}
+
+
+// Output samples from beginning of the sample buffer. Copies demanded number
+// of samples to output and removes them from the sample buffer. If there
+// are less than 'numsample' samples in the buffer, returns all available.
+//
+// Returns number of samples copied.
+uint FIFOSampleBuffer::receiveSamples(SAMPLETYPE *output, uint maxSamples)
+{
+ uint num;
+
+ num = (maxSamples > samplesInBuffer) ? samplesInBuffer : maxSamples;
+
+ memcpy(output, ptrBegin(), channels * sizeof(SAMPLETYPE) * num);
+ return receiveSamples(num);
+}
+
+
+// Removes samples from the beginning of the sample buffer without copying them
+// anywhere. Used to reduce the number of samples in the buffer, when accessing
+// the sample buffer with the 'ptrBegin' function.
+uint FIFOSampleBuffer::receiveSamples(uint maxSamples)
+{
+ if (maxSamples >= samplesInBuffer)
+ {
+ uint temp;
+
+ temp = samplesInBuffer;
+ samplesInBuffer = 0;
+ return temp;
+ }
+
+ samplesInBuffer -= maxSamples;
+ bufferPos += maxSamples;
+
+ return maxSamples;
+}
+
+
+// Returns nonzero if the sample buffer is empty
+int FIFOSampleBuffer::isEmpty() const
+{
+ return (samplesInBuffer == 0) ? 1 : 0;
+}
+
+
+// Clears the sample buffer
+void FIFOSampleBuffer::clear()
+{
+ samplesInBuffer = 0;
+ bufferPos = 0;
+}
diff --git a/plugins/soundtouch/soundtouch/source/SoundTouch/FIRFilter.cpp b/plugins/soundtouch/soundtouch/source/SoundTouch/FIRFilter.cpp
new file mode 100644
index 00000000..231263ad
--- /dev/null
+++ b/plugins/soundtouch/soundtouch/source/SoundTouch/FIRFilter.cpp
@@ -0,0 +1,269 @@
+////////////////////////////////////////////////////////////////////////////////
+///
+/// General FIR digital filter routines with MMX optimization.
+///
+/// Note : MMX optimized functions reside in a separate, platform-specific file,
+/// e.g. 'mmx_win.cpp' or 'mmx_gcc.cpp'
+///
+/// Author : Copyright (c) Olli Parviainen
+/// Author e-mail : oparviai 'at' iki.fi
+/// SoundTouch WWW: http://www.surina.net/soundtouch
+///
+////////////////////////////////////////////////////////////////////////////////
+//
+// Last changed : $Date: 2009-02-25 19:13:51 +0200 (Wed, 25 Feb 2009) $
+// File revision : $Revision: 4 $
+//
+// $Id: FIRFilter.cpp 67 2009-02-25 17:13:51Z oparviai $
+//
+////////////////////////////////////////////////////////////////////////////////
+//
+// License :
+//
+// SoundTouch audio processing library
+// Copyright (c) Olli Parviainen
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+////////////////////////////////////////////////////////////////////////////////
+
+#include <memory.h>
+#include <assert.h>
+#include <math.h>
+#include <stdlib.h>
+#include <stdexcept>
+#include "FIRFilter.h"
+#include "cpu_detect.h"
+
+using namespace soundtouch;
+
+/*****************************************************************************
+ *
+ * Implementation of the class 'FIRFilter'
+ *
+ *****************************************************************************/
+
+FIRFilter::FIRFilter()
+{
+ resultDivFactor = 0;
+ resultDivider = 0;
+ length = 0;
+ lengthDiv8 = 0;
+ filterCoeffs = NULL;
+}
+
+
+FIRFilter::~FIRFilter()
+{
+ delete[] filterCoeffs;
+}
+
+// Usual C-version of the filter routine for stereo sound
+uint FIRFilter::evaluateFilterStereo(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSamples) const
+{
+ uint i, j, end;
+ LONG_SAMPLETYPE suml, sumr;
+#ifdef FLOAT_SAMPLES
+ // when using floating point samples, use a scaler instead of a divider
+ // because division is much slower operation than multiplying.
+ double dScaler = 1.0 / (double)resultDivider;
+#endif
+
+ assert(length != 0);
+ assert(src != NULL);
+ assert(dest != NULL);
+ assert(filterCoeffs != NULL);
+
+ end = 2 * (numSamples - length);
+
+ for (j = 0; j < end; j += 2)
+ {
+ const SAMPLETYPE *ptr;
+
+ suml = sumr = 0;
+ ptr = src + j;
+
+ for (i = 0; i < length; i += 4)
+ {
+ // loop is unrolled by factor of 4 here for efficiency
+ suml += ptr[2 * i + 0] * filterCoeffs[i + 0] +
+ ptr[2 * i + 2] * filterCoeffs[i + 1] +
+ ptr[2 * i + 4] * filterCoeffs[i + 2] +
+ ptr[2 * i + 6] * filterCoeffs[i + 3];
+ sumr += ptr[2 * i + 1] * filterCoeffs[i + 0] +
+ ptr[2 * i + 3] * filterCoeffs[i + 1] +
+ ptr[2 * i + 5] * filterCoeffs[i + 2] +
+ ptr[2 * i + 7] * filterCoeffs[i + 3];
+ }
+
+#ifdef INTEGER_SAMPLES
+ suml >>= resultDivFactor;
+ sumr >>= resultDivFactor;
+ // saturate to 16 bit integer limits
+ suml = (suml < -32768) ? -32768 : (suml > 32767) ? 32767 : suml;
+ // saturate to 16 bit integer limits
+ sumr = (sumr < -32768) ? -32768 : (sumr > 32767) ? 32767 : sumr;
+#else
+ suml *= dScaler;
+ sumr *= dScaler;
+#endif // INTEGER_SAMPLES
+ dest[j] = (SAMPLETYPE)suml;
+ dest[j + 1] = (SAMPLETYPE)sumr;
+ }
+ return numSamples - length;
+}
+
+
+
+
+// Usual C-version of the filter routine for mono sound
+uint FIRFilter::evaluateFilterMono(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSamples) const
+{
+ uint i, j, end;
+ LONG_SAMPLETYPE sum;
+#ifdef FLOAT_SAMPLES
+ // when using floating point samples, use a scaler instead of a divider
+ // because division is much slower operation than multiplying.
+ double dScaler = 1.0 / (double)resultDivider;
+#endif
+
+
+ assert(length != 0);
+
+ end = numSamples - length;
+ for (j = 0; j < end; j ++)
+ {
+ sum = 0;
+ for (i = 0; i < length; i += 4)
+ {
+ // loop is unrolled by factor of 4 here for efficiency
+ sum += src[i + 0] * filterCoeffs[i + 0] +
+ src[i + 1] * filterCoeffs[i + 1] +
+ src[i + 2] * filterCoeffs[i + 2] +
+ src[i + 3] * filterCoeffs[i + 3];
+ }
+#ifdef INTEGER_SAMPLES
+ sum >>= resultDivFactor;
+ // saturate to 16 bit integer limits
+ sum = (sum < -32768) ? -32768 : (sum > 32767) ? 32767 : sum;
+#else
+ sum *= dScaler;
+#endif // INTEGER_SAMPLES
+ dest[j] = (SAMPLETYPE)sum;
+ src ++;
+ }
+ return end;
+}
+
+
+// Set filter coeffiecients and length.
+//
+// Throws an exception if filter length isn't divisible by 8
+void FIRFilter::setCoefficients(const SAMPLETYPE *coeffs, uint newLength, uint uResultDivFactor)
+{
+ assert(newLength > 0);
+ if (newLength % 8) throw std::runtime_error("FIR filter length not divisible by 8");
+
+ lengthDiv8 = newLength / 8;
+ length = lengthDiv8 * 8;
+ assert(length == newLength);
+
+ resultDivFactor = uResultDivFactor;
+ resultDivider = (SAMPLETYPE)::pow(2.0, (int)resultDivFactor);
+
+ delete[] filterCoeffs;
+ filterCoeffs = new SAMPLETYPE[length];
+ memcpy(filterCoeffs, coeffs, length * sizeof(SAMPLETYPE));
+}
+
+
+uint FIRFilter::getLength() const
+{
+ return length;
+}
+
+
+
+// Applies the filter to the given sequence of samples.
+//
+// Note : The amount of outputted samples is by value of 'filter_length'
+// smaller than the amount of input samples.
+uint FIRFilter::evaluate(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSamples, uint numChannels) const
+{
+ assert(numChannels == 1 || numChannels == 2);
+
+ assert(length > 0);
+ assert(lengthDiv8 * 8 == length);
+ if (numSamples < length) return 0;
+ if (numChannels == 2)
+ {
+ return evaluateFilterStereo(dest, src, numSamples);
+ } else {
+ return evaluateFilterMono(dest, src, numSamples);
+ }
+}
+
+
+
+// Operator 'new' is overloaded so that it automatically creates a suitable instance
+// depending on if we've a MMX-capable CPU available or not.
+void * FIRFilter::operator new(size_t s)
+{
+ // Notice! don't use "new FIRFilter" directly, use "newInstance" to create a new instance instead!
+ throw std::runtime_error("Error in FIRFilter::new: Don't use 'new FIRFilter', use 'newInstance' member instead!");
+ return NULL;
+}
+
+
+FIRFilter * FIRFilter::newInstance()
+{
+ uint uExtensions;
+
+ uExtensions = detectCPUextensions();
+
+ // Check if MMX/SSE/3DNow! instruction set extensions supported by CPU
+
+#ifdef ALLOW_MMX
+ // MMX routines available only with integer sample types
+ if (uExtensions & SUPPORT_MMX)
+ {
+ return ::new FIRFilterMMX;
+ }
+ else
+#endif // ALLOW_MMX
+
+#ifdef ALLOW_SSE
+ if (uExtensions & SUPPORT_SSE)
+ {
+ // SSE support
+ return ::new FIRFilterSSE;
+ }
+ else
+#endif // ALLOW_SSE
+
+#ifdef ALLOW_3DNOW
+ if (uExtensions & SUPPORT_3DNOW)
+ {
+ // 3DNow! support
+ return ::new FIRFilter3DNow;
+ }
+ else
+#endif // ALLOW_3DNOW
+
+ {
+ // ISA optimizations not supported, use plain C version
+ return ::new FIRFilter;
+ }
+}
diff --git a/plugins/soundtouch/soundtouch/source/SoundTouch/FIRFilter.h b/plugins/soundtouch/soundtouch/source/SoundTouch/FIRFilter.h
new file mode 100644
index 00000000..5713f7bb
--- /dev/null
+++ b/plugins/soundtouch/soundtouch/source/SoundTouch/FIRFilter.h
@@ -0,0 +1,164 @@
+////////////////////////////////////////////////////////////////////////////////
+///
+/// General FIR digital filter routines with MMX optimization.
+///
+/// Note : MMX optimized functions reside in a separate, platform-specific file,
+/// e.g. 'mmx_win.cpp' or 'mmx_gcc.cpp'
+///
+/// Author : Copyright (c) Olli Parviainen
+/// Author e-mail : oparviai 'at' iki.fi
+/// SoundTouch WWW: http://www.surina.net/soundtouch
+///
+////////////////////////////////////////////////////////////////////////////////
+//
+// Last changed : $Date: 2009-02-21 18:00:14 +0200 (Sat, 21 Feb 2009) $
+// File revision : $Revision: 4 $
+//
+// $Id: FIRFilter.h 63 2009-02-21 16:00:14Z oparviai $
+//
+////////////////////////////////////////////////////////////////////////////////
+//
+// License :
+//
+// SoundTouch audio processing library
+// Copyright (c) Olli Parviainen
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+////////////////////////////////////////////////////////////////////////////////
+
+#ifndef FIRFilter_H
+#define FIRFilter_H
+
+#include <stddef.h>
+#include "STTypes.h"
+
+namespace soundtouch
+{
+
+class FIRFilter
+{
+protected:
+ // Number of FIR filter taps
+ uint length;
+ // Number of FIR filter taps divided by 8
+ uint lengthDiv8;
+
+ // Result divider factor in 2^k format
+ uint resultDivFactor;
+
+ // Result divider value.
+ SAMPLETYPE resultDivider;
+
+ // Memory for filter coefficients
+ SAMPLETYPE *filterCoeffs;
+
+ virtual uint evaluateFilterStereo(SAMPLETYPE *dest,
+ const SAMPLETYPE *src,
+ uint numSamples) const;
+ virtual uint evaluateFilterMono(SAMPLETYPE *dest,
+ const SAMPLETYPE *src,
+ uint numSamples) const;
+
+public:
+ FIRFilter();
+ virtual ~FIRFilter();
+
+ /// Operator 'new' is overloaded so that it automatically creates a suitable instance
+ /// depending on if we've a MMX-capable CPU available or not.
+ static void * operator new(size_t s);
+
+ static FIRFilter *newInstance();
+
+ /// Applies the filter to the given sequence of samples.
+ /// Note : The amount of outputted samples is by value of 'filter_length'
+ /// smaller than the amount of input samples.
+ ///
+ /// \return Number of samples copied to 'dest'.
+ uint evaluate(SAMPLETYPE *dest,
+ const SAMPLETYPE *src,
+ uint numSamples,
+ uint numChannels) const;
+
+ uint getLength() const;
+
+ virtual void setCoefficients(const SAMPLETYPE *coeffs,
+ uint newLength,
+ uint uResultDivFactor);
+};
+
+
+// Optional subclasses that implement CPU-specific optimizations:
+
+#ifdef ALLOW_MMX
+
+/// Class that implements MMX optimized functions exclusive for 16bit integer samples type.
+ class FIRFilterMMX : public FIRFilter
+ {
+ protected:
+ short *filterCoeffsUnalign;
+ short *filterCoeffsAlign;
+
+ virtual uint evaluateFilterStereo(short *dest, const short *src, uint numSamples) const;
+ public:
+ FIRFilterMMX();
+ ~FIRFilterMMX();
+
+ virtual void setCoefficients(const short *coeffs, uint newLength, uint uResultDivFactor);
+ };
+
+#endif // ALLOW_MMX
+
+
+#ifdef ALLOW_3DNOW
+
+ /// Class that implements 3DNow! optimized functions exclusive for floating point samples type.
+ class FIRFilter3DNow : public FIRFilter
+ {
+ protected:
+ float *filterCoeffsUnalign;
+ float *filterCoeffsAlign;
+
+ virtual uint evaluateFilterStereo(float *dest, const float *src, uint numSamples) const;
+ public:
+ FIRFilter3DNow();
+ ~FIRFilter3DNow();
+ virtual void setCoefficients(const float *coeffs, uint newLength, uint uResultDivFactor);
+ };
+
+#endif // ALLOW_3DNOW
+
+
+#ifdef ALLOW_SSE
+ /// Class that implements SSE optimized functions exclusive for floating point samples type.
+ class FIRFilterSSE : public FIRFilter
+ {
+ protected:
+ float *filterCoeffsUnalign;
+ float *filterCoeffsAlign;
+
+ virtual uint evaluateFilterStereo(float *dest, const float *src, uint numSamples) const;
+ public:
+ FIRFilterSSE();
+ ~FIRFilterSSE();
+
+ virtual void setCoefficients(const float *coeffs, uint newLength, uint uResultDivFactor);
+ };
+
+#endif // ALLOW_SSE
+
+}
+
+#endif // FIRFilter_H
diff --git a/plugins/soundtouch/soundtouch/source/SoundTouch/PeakFinder.cpp b/plugins/soundtouch/soundtouch/source/SoundTouch/PeakFinder.cpp
new file mode 100644
index 00000000..03f60bfa
--- /dev/null
+++ b/plugins/soundtouch/soundtouch/source/SoundTouch/PeakFinder.cpp
@@ -0,0 +1,239 @@
+////////////////////////////////////////////////////////////////////////////////
+///
+/// Peak detection routine.
+///
+/// The routine detects highest value on an array of values and calculates the
+/// precise peak location as a mass-center of the 'hump' around the peak value.
+///
+/// Author : Copyright (c) Olli Parviainen
+/// Author e-mail : oparviai 'at' iki.fi
+/// SoundTouch WWW: http://www.surina.net/soundtouch
+///
+////////////////////////////////////////////////////////////////////////////////
+//
+// Last changed : $Date: 2009-02-21 18:00:14 +0200 (Sat, 21 Feb 2009) $
+// File revision : $Revision: 4 $
+//
+// $Id: PeakFinder.cpp 63 2009-02-21 16:00:14Z oparviai $
+//
+////////////////////////////////////////////////////////////////////////////////
+//
+// License :
+//
+// SoundTouch audio processing library
+// Copyright (c) Olli Parviainen
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+////////////////////////////////////////////////////////////////////////////////
+
+#include <math.h>
+#include <assert.h>
+
+#include "PeakFinder.h"
+
+using namespace soundtouch;
+
+#define max(x, y) (((x) > (y)) ? (x) : (y))
+
+
+PeakFinder::PeakFinder()
+{
+ minPos = maxPos = 0;
+}
+
+
+// Finds 'ground level' of a peak hump by starting from 'peakpos' and proceeding
+// to direction defined by 'direction' until next 'hump' after minimum value will
+// begin
+int PeakFinder::findGround(const float *data, int peakpos, int direction) const
+{
+ float refvalue;
+ int lowpos;
+ int pos;
+ int climb_count;
+ float delta;
+
+ climb_count = 0;
+ refvalue = data[peakpos];
+ lowpos = peakpos;
+
+ pos = peakpos;
+
+ while ((pos > minPos) && (pos < maxPos))
+ {
+ int prevpos;
+
+ prevpos = pos;
+ pos += direction;
+
+ // calculate derivate
+ delta = data[pos] - data[prevpos];
+ if (delta <= 0)
+ {
+ // going downhill, ok
+ if (climb_count)
+ {
+ climb_count --; // decrease climb count
+ }
+
+ // check if new minimum found
+ if (data[pos] < refvalue)
+ {
+ // new minimum found
+ lowpos = pos;
+ refvalue = data[pos];
+ }
+ }
+ else
+ {
+ // going uphill, increase climbing counter
+ climb_count ++;
+ if (climb_count > 5) break; // we've been climbing too long => it's next uphill => quit
+ }
+ }
+ return lowpos;
+}
+
+
+// Find offset where the value crosses the given level, when starting from 'peakpos' and
+// proceeds to direction defined in 'direction'
+int PeakFinder::findCrossingLevel(const float *data, float level, int peakpos, int direction) const
+{
+ float peaklevel;
+ int pos;
+
+ peaklevel = data[peakpos];
+ assert(peaklevel >= level);
+ pos = peakpos;
+ while ((pos >= minPos) && (pos < maxPos))
+ {
+ if (data[pos + direction] < level) return pos; // crossing found
+ pos += direction;
+ }
+ return -1; // not found
+}
+
+
+// Calculates the center of mass location of 'data' array items between 'firstPos' and 'lastPos'
+double PeakFinder::calcMassCenter(const float *data, int firstPos, int lastPos) const
+{
+ int i;
+ float sum;
+ float wsum;
+
+ sum = 0;
+ wsum = 0;
+ for (i = firstPos; i <= lastPos; i ++)
+ {
+ sum += (float)i * data[i];
+ wsum += data[i];
+ }
+
+ if (wsum < 1e-6) return 0;
+ return sum / wsum;
+}
+
+
+
+/// get exact center of peak near given position by calculating local mass of center
+double PeakFinder::getPeakCenter(const float *data, int peakpos) const
+{
+ float peakLevel; // peak level
+ int crosspos1, crosspos2; // position where the peak 'hump' crosses cutting level
+ float cutLevel; // cutting value
+ float groundLevel; // ground level of the peak
+ int gp1, gp2; // bottom positions of the peak 'hump'
+
+ // find ground positions.
+ gp1 = findGround(data, peakpos, -1);
+ gp2 = findGround(data, peakpos, 1);
+
+ groundLevel = max(data[gp1], data[gp2]);
+ peakLevel = data[peakpos];
+
+ if (groundLevel < 1e-6) return 0; // ground level too small => detection failed
+ if ((peakLevel / groundLevel) < 1.3) return 0; // peak less than 30% of the ground level => no good peak detected
+
+ // calculate 70%-level of the peak
+ cutLevel = 0.70f * peakLevel + 0.30f * groundLevel;
+ // find mid-level crossings
+ crosspos1 = findCrossingLevel(data, cutLevel, peakpos, -1);
+ crosspos2 = findCrossingLevel(data, cutLevel, peakpos, 1);
+
+ if ((crosspos1 < 0) || (crosspos2 < 0)) return 0; // no crossing, no peak..
+
+ // calculate mass center of the peak surroundings
+ return calcMassCenter(data, crosspos1, crosspos2);
+}
+
+
+
+double PeakFinder::detectPeak(const float *data, int aminPos, int amaxPos)
+{
+
+ int i;
+ int peakpos; // position of peak level
+ double highPeak, peak;
+
+ this->minPos = aminPos;
+ this->maxPos = amaxPos;
+
+ // find absolute peak
+ peakpos = minPos;
+ peak = data[minPos];
+ for (i = minPos + 1; i < maxPos; i ++)
+ {
+ if (data[i] > peak)
+ {
+ peak = data[i];
+ peakpos = i;
+ }
+ }
+
+ // Calculate exact location of the highest peak mass center
+ highPeak = getPeakCenter(data, peakpos);
+ peak = highPeak;
+
+ // Now check if the highest peak were in fact harmonic of the true base beat peak
+ // - sometimes the highest peak can be Nth harmonic of the true base peak yet
+ // just a slightly higher than the true base
+ for (i = 2; i < 10; i ++)
+ {
+ double peaktmp, tmp;
+ int i1,i2;
+
+ peakpos = (int)(highPeak / (double)i + 0.5f);
+ if (peakpos < minPos) break;
+
+ // calculate mass-center of possible base peak
+ peaktmp = getPeakCenter(data, peakpos);
+
+ // now compare to highest detected peak
+ i1 = (int)(highPeak + 0.5);
+ i2 = (int)(peaktmp + 0.5);
+ tmp = 2 * (data[i2] - data[i1]) / (data[i2] + data[i1]);
+ if (fabs(tmp) < 0.1)
+ {
+ // The highest peak is harmonic of almost as high base peak,
+ // thus use the base peak instead
+ peak = peaktmp;
+ }
+ }
+
+ return peak;
+}
+
+
diff --git a/plugins/soundtouch/soundtouch/source/SoundTouch/PeakFinder.h b/plugins/soundtouch/soundtouch/source/SoundTouch/PeakFinder.h
new file mode 100644
index 00000000..e3640cc6
--- /dev/null
+++ b/plugins/soundtouch/soundtouch/source/SoundTouch/PeakFinder.h
@@ -0,0 +1,93 @@
+////////////////////////////////////////////////////////////////////////////////
+///
+/// The routine detects highest value on an array of values and calculates the
+/// precise peak location as a mass-center of the 'hump' around the peak value.
+///
+/// Author : Copyright (c) Olli Parviainen
+/// Author e-mail : oparviai 'at' iki.fi
+/// SoundTouch WWW: http://www.surina.net/soundtouch
+///
+////////////////////////////////////////////////////////////////////////////////
+//
+// Last changed : $Date: 2009-02-21 18:00:14 +0200 (Sat, 21 Feb 2009) $
+// File revision : $Revision: 4 $
+//
+// $Id: PeakFinder.h 63 2009-02-21 16:00:14Z oparviai $
+//
+////////////////////////////////////////////////////////////////////////////////
+//
+// License :
+//
+// SoundTouch audio processing library
+// Copyright (c) Olli Parviainen
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+////////////////////////////////////////////////////////////////////////////////
+
+#ifndef _PeakFinder_H_
+#define _PeakFinder_H_
+
+namespace soundtouch
+{
+
+class PeakFinder
+{
+protected:
+ /// Min, max allowed peak positions within the data vector
+ int minPos, maxPos;
+
+ /// Calculates the mass center between given vector items.
+ double calcMassCenter(const float *data, ///< Data vector.
+ int firstPos, ///< Index of first vector item beloging to the peak.
+ int lastPos ///< Index of last vector item beloging to the peak.
+ ) const;
+
+ /// Finds the data vector index where the monotoniously decreasing signal crosses the
+ /// given level.
+ int findCrossingLevel(const float *data, ///< Data vector.
+ float level, ///< Goal crossing level.
+ int peakpos, ///< Peak position index within the data vector.
+ int direction /// Direction where to proceed from the peak: 1 = right, -1 = left.
+ ) const;
+
+ /// Finds the 'ground' level, i.e. smallest level between two neighbouring peaks, to right-
+ /// or left-hand side of the given peak position.
+ int findGround(const float *data, /// Data vector.
+ int peakpos, /// Peak position index within the data vector.
+ int direction /// Direction where to proceed from the peak: 1 = right, -1 = left.
+ ) const;
+
+ /// get exact center of peak near given position by calculating local mass of center
+ double getPeakCenter(const float *data, int peakpos) const;
+
+public:
+ /// Constructor.
+ PeakFinder();
+
+ /// Detect exact peak position of the data vector by finding the largest peak 'hump'
+ /// and calculating the mass-center location of the peak hump.
+ ///
+ /// \return The location of the largest base harmonic peak hump.
+ double detectPeak(const float *data, /// Data vector to be analyzed. The data vector has
+ /// to be at least 'maxPos' items long.
+ int minPos, ///< Min allowed peak location within the vector data.
+ int maxPos ///< Max allowed peak location within the vector data.
+ );
+};
+
+}
+
+#endif // _PeakFinder_H_
diff --git a/plugins/soundtouch/soundtouch/source/SoundTouch/RateTransposer.cpp b/plugins/soundtouch/soundtouch/source/SoundTouch/RateTransposer.cpp
new file mode 100644
index 00000000..7e0b277d
--- /dev/null
+++ b/plugins/soundtouch/soundtouch/source/SoundTouch/RateTransposer.cpp
@@ -0,0 +1,628 @@
+////////////////////////////////////////////////////////////////////////////////
+///
+/// Sample rate transposer. Changes sample rate by using linear interpolation
+/// together with anti-alias filtering (first order interpolation with anti-
+/// alias filtering should be quite adequate for this application)
+///
+/// Author : Copyright (c) Olli Parviainen
+/// Author e-mail : oparviai 'at' iki.fi
+/// SoundTouch WWW: http://www.surina.net/soundtouch
+///
+////////////////////////////////////////////////////////////////////////////////
+//
+// Last changed : $Date: 2009-10-31 16:37:24 +0200 (Sat, 31 Oct 2009) $
+// File revision : $Revision: 4 $
+//
+// $Id: RateTransposer.cpp 74 2009-10-31 14:37:24Z oparviai $
+//
+////////////////////////////////////////////////////////////////////////////////
+//
+// License :
+//
+// SoundTouch audio processing library
+// Copyright (c) Olli Parviainen
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+////////////////////////////////////////////////////////////////////////////////
+
+#include <memory.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdexcept>
+#include "RateTransposer.h"
+#include "AAFilter.h"
+
+using namespace std;
+using namespace soundtouch;
+
+
+/// A linear samplerate transposer class that uses integer arithmetics.
+/// for the transposing.
+class RateTransposerInteger : public RateTransposer
+{
+protected:
+ int iSlopeCount;
+ int iRate;
+ SAMPLETYPE sPrevSampleL, sPrevSampleR;
+
+ virtual void resetRegisters();
+
+ virtual uint transposeStereo(SAMPLETYPE *dest,
+ const SAMPLETYPE *src,
+ uint numSamples);
+ virtual uint transposeMono(SAMPLETYPE *dest,
+ const SAMPLETYPE *src,
+ uint numSamples);
+
+public:
+ RateTransposerInteger();
+ virtual ~RateTransposerInteger();
+
+ /// Sets new target rate. Normal rate = 1.0, smaller values represent slower
+ /// rate, larger faster rates.
+ virtual void setRate(float newRate);
+
+};
+
+
+/// A linear samplerate transposer class that uses floating point arithmetics
+/// for the transposing.
+class RateTransposerFloat : public RateTransposer
+{
+protected:
+ float fSlopeCount;
+ SAMPLETYPE sPrevSampleL, sPrevSampleR;
+
+ virtual void resetRegisters();
+
+ virtual uint transposeStereo(SAMPLETYPE *dest,
+ const SAMPLETYPE *src,
+ uint numSamples);
+ virtual uint transposeMono(SAMPLETYPE *dest,
+ const SAMPLETYPE *src,
+ uint numSamples);
+
+public:
+ RateTransposerFloat();
+ virtual ~RateTransposerFloat();
+};
+
+
+
+
+// Operator 'new' is overloaded so that it automatically creates a suitable instance
+// depending on if we've a MMX/SSE/etc-capable CPU available or not.
+void * RateTransposer::operator new(size_t s)
+{
+ throw runtime_error("Error in RateTransoser::new: don't use \"new TDStretch\" directly, use \"newInstance\" to create a new instance instead!");
+ return NULL;
+}
+
+
+RateTransposer *RateTransposer::newInstance()
+{
+#ifdef INTEGER_SAMPLES
+ return ::new RateTransposerInteger;
+#else
+ return ::new RateTransposerFloat;
+#endif
+}
+
+
+// Constructor
+RateTransposer::RateTransposer() : FIFOProcessor(&outputBuffer)
+{
+ numChannels = 2;
+ bUseAAFilter = TRUE;
+ fRate = 0;
+
+ // Instantiates the anti-alias filter with default tap length
+ // of 32
+ pAAFilter = new AAFilter(32);
+}
+
+
+
+RateTransposer::~RateTransposer()
+{
+ delete pAAFilter;
+}
+
+
+
+/// Enables/disables the anti-alias filter. Zero to disable, nonzero to enable
+void RateTransposer::enableAAFilter(BOOL newMode)
+{
+ bUseAAFilter = newMode;
+}
+
+
+/// Returns nonzero if anti-alias filter is enabled.
+BOOL RateTransposer::isAAFilterEnabled() const
+{
+ return bUseAAFilter;
+}
+
+
+AAFilter *RateTransposer::getAAFilter()
+{
+ return pAAFilter;
+}
+
+
+
+// Sets new target iRate. Normal iRate = 1.0, smaller values represent slower
+// iRate, larger faster iRates.
+void RateTransposer::setRate(float newRate)
+{
+ double fCutoff;
+
+ fRate = newRate;
+
+ // design a new anti-alias filter
+ if (newRate > 1.0f)
+ {
+ fCutoff = 0.5f / newRate;
+ }
+ else
+ {
+ fCutoff = 0.5f * newRate;
+ }
+ pAAFilter->setCutoffFreq(fCutoff);
+}
+
+
+// Outputs as many samples of the 'outputBuffer' as possible, and if there's
+// any room left, outputs also as many of the incoming samples as possible.
+// The goal is to drive the outputBuffer empty.
+//
+// It's allowed for 'output' and 'input' parameters to point to the same
+// memory position.
+/*
+void RateTransposer::flushStoreBuffer()
+{
+ if (storeBuffer.isEmpty()) return;
+
+ outputBuffer.moveSamples(storeBuffer);
+}
+*/
+
+
+// Adds 'nSamples' pcs of samples from the 'samples' memory position into
+// the input of the object.
+void RateTransposer::putSamples(const SAMPLETYPE *samples, uint nSamples)
+{
+ processSamples(samples, nSamples);
+}
+
+
+
+// Transposes up the sample rate, causing the observed playback 'rate' of the
+// sound to decrease
+void RateTransposer::upsample(const SAMPLETYPE *src, uint nSamples)
+{
+ uint count, sizeTemp, num;
+
+ // If the parameter 'uRate' value is smaller than 'SCALE', first transpose
+ // the samples and then apply the anti-alias filter to remove aliasing.
+
+ // First check that there's enough room in 'storeBuffer'
+ // (+16 is to reserve some slack in the destination buffer)
+ sizeTemp = (uint)((float)nSamples / fRate + 16.0f);
+
+ // Transpose the samples, store the result into the end of "storeBuffer"
+ count = transpose(storeBuffer.ptrEnd(sizeTemp), src, nSamples);
+ storeBuffer.putSamples(count);
+
+ // Apply the anti-alias filter to samples in "store output", output the
+ // result to "dest"
+ num = storeBuffer.numSamples();
+ count = pAAFilter->evaluate(outputBuffer.ptrEnd(num),
+ storeBuffer.ptrBegin(), num, (uint)numChannels);
+ outputBuffer.putSamples(count);
+
+ // Remove the processed samples from "storeBuffer"
+ storeBuffer.receiveSamples(count);
+}
+
+
+// Transposes down the sample rate, causing the observed playback 'rate' of the
+// sound to increase
+void RateTransposer::downsample(const SAMPLETYPE *src, uint nSamples)
+{
+ uint count, sizeTemp;
+
+ // If the parameter 'uRate' value is larger than 'SCALE', first apply the
+ // anti-alias filter to remove high frequencies (prevent them from folding
+ // over the lover frequencies), then transpose.
+
+ // Add the new samples to the end of the storeBuffer
+ storeBuffer.putSamples(src, nSamples);
+
+ // Anti-alias filter the samples to prevent folding and output the filtered
+ // data to tempBuffer. Note : because of the FIR filter length, the
+ // filtering routine takes in 'filter_length' more samples than it outputs.
+ assert(tempBuffer.isEmpty());
+ sizeTemp = storeBuffer.numSamples();
+
+ count = pAAFilter->evaluate(tempBuffer.ptrEnd(sizeTemp),
+ storeBuffer.ptrBegin(), sizeTemp, (uint)numChannels);
+
+ if (count == 0) return;
+
+ // Remove the filtered samples from 'storeBuffer'
+ storeBuffer.receiveSamples(count);
+
+ // Transpose the samples (+16 is to reserve some slack in the destination buffer)
+ sizeTemp = (uint)((float)nSamples / fRate + 16.0f);
+ count = transpose(outputBuffer.ptrEnd(sizeTemp), tempBuffer.ptrBegin(), count);
+ outputBuffer.putSamples(count);
+}
+
+
+// Transposes sample rate by applying anti-alias filter to prevent folding.
+// Returns amount of samples returned in the "dest" buffer.
+// The maximum amount of samples that can be returned at a time is set by
+// the 'set_returnBuffer_size' function.
+void RateTransposer::processSamples(const SAMPLETYPE *src, uint nSamples)
+{
+ uint count;
+ uint sizeReq;
+
+ if (nSamples == 0) return;
+ assert(pAAFilter);
+
+ // If anti-alias filter is turned off, simply transpose without applying
+ // the filter
+ if (bUseAAFilter == FALSE)
+ {
+ sizeReq = (uint)((float)nSamples / fRate + 1.0f);
+ count = transpose(outputBuffer.ptrEnd(sizeReq), src, nSamples);
+ outputBuffer.putSamples(count);
+ return;
+ }
+
+ // Transpose with anti-alias filter
+ if (fRate < 1.0f)
+ {
+ upsample(src, nSamples);
+ }
+ else
+ {
+ downsample(src, nSamples);
+ }
+}
+
+
+// Transposes the sample rate of the given samples using linear interpolation.
+// Returns the number of samples returned in the "dest" buffer
+inline uint RateTransposer::transpose(SAMPLETYPE *dest, const SAMPLETYPE *src, uint nSamples)
+{
+ if (numChannels == 2)
+ {
+ return transposeStereo(dest, src, nSamples);
+ }
+ else
+ {
+ return transposeMono(dest, src, nSamples);
+ }
+}
+
+
+// Sets the number of channels, 1 = mono, 2 = stereo
+void RateTransposer::setChannels(int nChannels)
+{
+ assert(nChannels > 0);
+ if (numChannels == nChannels) return;
+
+ assert(nChannels == 1 || nChannels == 2);
+ numChannels = nChannels;
+
+ storeBuffer.setChannels(numChannels);
+ tempBuffer.setChannels(numChannels);
+ outputBuffer.setChannels(numChannels);
+
+ // Inits the linear interpolation registers
+ resetRegisters();
+}
+
+
+// Clears all the samples in the object
+void RateTransposer::clear()
+{
+ outputBuffer.clear();
+ storeBuffer.clear();
+}
+
+
+// Returns nonzero if there aren't any samples available for outputting.
+int RateTransposer::isEmpty() const
+{
+ int res;
+
+ res = FIFOProcessor::isEmpty();
+ if (res == 0) return 0;
+ return storeBuffer.isEmpty();
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// RateTransposerInteger - integer arithmetic implementation
+//
+
+/// fixed-point interpolation routine precision
+#define SCALE 65536
+
+// Constructor
+RateTransposerInteger::RateTransposerInteger() : RateTransposer()
+{
+ // Notice: use local function calling syntax for sake of clarity,
+ // to indicate the fact that C++ constructor can't call virtual functions.
+ RateTransposerInteger::resetRegisters();
+ RateTransposerInteger::setRate(1.0f);
+}
+
+
+RateTransposerInteger::~RateTransposerInteger()
+{
+}
+
+
+void RateTransposerInteger::resetRegisters()
+{
+ iSlopeCount = 0;
+ sPrevSampleL =
+ sPrevSampleR = 0;
+}
+
+
+
+// Transposes the sample rate of the given samples using linear interpolation.
+// 'Mono' version of the routine. Returns the number of samples returned in
+// the "dest" buffer
+uint RateTransposerInteger::transposeMono(SAMPLETYPE *dest, const SAMPLETYPE *src, uint nSamples)
+{
+ unsigned int i, used;
+ LONG_SAMPLETYPE temp, vol1;
+
+ if (nSamples == 0) return 0; // no samples, no work
+
+ used = 0;
+ i = 0;
+
+ // Process the last sample saved from the previous call first...
+ while (iSlopeCount <= SCALE)
+ {
+ vol1 = (LONG_SAMPLETYPE)(SCALE - iSlopeCount);
+ temp = vol1 * sPrevSampleL + iSlopeCount * src[0];
+ dest[i] = (SAMPLETYPE)(temp / SCALE);
+ i++;
+ iSlopeCount += iRate;
+ }
+ // now always (iSlopeCount > SCALE)
+ iSlopeCount -= SCALE;
+
+ while (1)
+ {
+ while (iSlopeCount > SCALE)
+ {
+ iSlopeCount -= SCALE;
+ used ++;
+ if (used >= nSamples - 1) goto end;
+ }
+ vol1 = (LONG_SAMPLETYPE)(SCALE - iSlopeCount);
+ temp = src[used] * vol1 + iSlopeCount * src[used + 1];
+ dest[i] = (SAMPLETYPE)(temp / SCALE);
+
+ i++;
+ iSlopeCount += iRate;
+ }
+end:
+ // Store the last sample for the next round
+ sPrevSampleL = src[nSamples - 1];
+
+ return i;
+}
+
+
+// Transposes the sample rate of the given samples using linear interpolation.
+// 'Stereo' version of the routine. Returns the number of samples returned in
+// the "dest" buffer
+uint RateTransposerInteger::transposeStereo(SAMPLETYPE *dest, const SAMPLETYPE *src, uint nSamples)
+{
+ unsigned int srcPos, i, used;
+ LONG_SAMPLETYPE temp, vol1;
+
+ if (nSamples == 0) return 0; // no samples, no work
+
+ used = 0;
+ i = 0;
+
+ // Process the last sample saved from the sPrevSampleLious call first...
+ while (iSlopeCount <= SCALE)
+ {
+ vol1 = (LONG_SAMPLETYPE)(SCALE - iSlopeCount);
+ temp = vol1 * sPrevSampleL + iSlopeCount * src[0];
+ dest[2 * i] = (SAMPLETYPE)(temp / SCALE);
+ temp = vol1 * sPrevSampleR + iSlopeCount * src[1];
+ dest[2 * i + 1] = (SAMPLETYPE)(temp / SCALE);
+ i++;
+ iSlopeCount += iRate;
+ }
+ // now always (iSlopeCount > SCALE)
+ iSlopeCount -= SCALE;
+
+ while (1)
+ {
+ while (iSlopeCount > SCALE)
+ {
+ iSlopeCount -= SCALE;
+ used ++;
+ if (used >= nSamples - 1) goto end;
+ }
+ srcPos = 2 * used;
+ vol1 = (LONG_SAMPLETYPE)(SCALE - iSlopeCount);
+ temp = src[srcPos] * vol1 + iSlopeCount * src[srcPos + 2];
+ dest[2 * i] = (SAMPLETYPE)(temp / SCALE);
+ temp = src[srcPos + 1] * vol1 + iSlopeCount * src[srcPos + 3];
+ dest[2 * i + 1] = (SAMPLETYPE)(temp / SCALE);
+
+ i++;
+ iSlopeCount += iRate;
+ }
+end:
+ // Store the last sample for the next round
+ sPrevSampleL = src[2 * nSamples - 2];
+ sPrevSampleR = src[2 * nSamples - 1];
+
+ return i;
+}
+
+
+// Sets new target iRate. Normal iRate = 1.0, smaller values represent slower
+// iRate, larger faster iRates.
+void RateTransposerInteger::setRate(float newRate)
+{
+ iRate = (int)(newRate * SCALE + 0.5f);
+ RateTransposer::setRate(newRate);
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// RateTransposerFloat - floating point arithmetic implementation
+//
+//////////////////////////////////////////////////////////////////////////////
+
+// Constructor
+RateTransposerFloat::RateTransposerFloat() : RateTransposer()
+{
+ // Notice: use local function calling syntax for sake of clarity,
+ // to indicate the fact that C++ constructor can't call virtual functions.
+ RateTransposerFloat::resetRegisters();
+ RateTransposerFloat::setRate(1.0f);
+}
+
+
+RateTransposerFloat::~RateTransposerFloat()
+{
+}
+
+
+void RateTransposerFloat::resetRegisters()
+{
+ fSlopeCount = 0;
+ sPrevSampleL =
+ sPrevSampleR = 0;
+}
+
+
+
+// Transposes the sample rate of the given samples using linear interpolation.
+// 'Mono' version of the routine. Returns the number of samples returned in
+// the "dest" buffer
+uint RateTransposerFloat::transposeMono(SAMPLETYPE *dest, const SAMPLETYPE *src, uint nSamples)
+{
+ unsigned int i, used;
+
+ used = 0;
+ i = 0;
+
+ // Process the last sample saved from the previous call first...
+ while (fSlopeCount <= 1.0f)
+ {
+ dest[i] = (SAMPLETYPE)((1.0f - fSlopeCount) * sPrevSampleL + fSlopeCount * src[0]);
+ i++;
+ fSlopeCount += fRate;
+ }
+ fSlopeCount -= 1.0f;
+
+ if (nSamples > 1)
+ {
+ while (1)
+ {
+ while (fSlopeCount > 1.0f)
+ {
+ fSlopeCount -= 1.0f;
+ used ++;
+ if (used >= nSamples - 1) goto end;
+ }
+ dest[i] = (SAMPLETYPE)((1.0f - fSlopeCount) * src[used] + fSlopeCount * src[used + 1]);
+ i++;
+ fSlopeCount += fRate;
+ }
+ }
+end:
+ // Store the last sample for the next round
+ sPrevSampleL = src[nSamples - 1];
+
+ return i;
+}
+
+
+// Transposes the sample rate of the given samples using linear interpolation.
+// 'Mono' version of the routine. Returns the number of samples returned in
+// the "dest" buffer
+uint RateTransposerFloat::transposeStereo(SAMPLETYPE *dest, const SAMPLETYPE *src, uint nSamples)
+{
+ unsigned int srcPos, i, used;
+
+ if (nSamples == 0) return 0; // no samples, no work
+
+ used = 0;
+ i = 0;
+
+ // Process the last sample saved from the sPrevSampleLious call first...
+ while (fSlopeCount <= 1.0f)
+ {
+ dest[2 * i] = (SAMPLETYPE)((1.0f - fSlopeCount) * sPrevSampleL + fSlopeCount * src[0]);
+ dest[2 * i + 1] = (SAMPLETYPE)((1.0f - fSlopeCount) * sPrevSampleR + fSlopeCount * src[1]);
+ i++;
+ fSlopeCount += fRate;
+ }
+ // now always (iSlopeCount > 1.0f)
+ fSlopeCount -= 1.0f;
+
+ if (nSamples > 1)
+ {
+ while (1)
+ {
+ while (fSlopeCount > 1.0f)
+ {
+ fSlopeCount -= 1.0f;
+ used ++;
+ if (used >= nSamples - 1) goto end;
+ }
+ srcPos = 2 * used;
+
+ dest[2 * i] = (SAMPLETYPE)((1.0f - fSlopeCount) * src[srcPos]
+ + fSlopeCount * src[srcPos + 2]);
+ dest[2 * i + 1] = (SAMPLETYPE)((1.0f - fSlopeCount) * src[srcPos + 1]
+ + fSlopeCount * src[srcPos + 3]);
+
+ i++;
+ fSlopeCount += fRate;
+ }
+ }
+end:
+ // Store the last sample for the next round
+ sPrevSampleL = src[2 * nSamples - 2];
+ sPrevSampleR = src[2 * nSamples - 1];
+
+ return i;
+}
diff --git a/plugins/soundtouch/soundtouch/source/SoundTouch/RateTransposer.h b/plugins/soundtouch/soundtouch/source/SoundTouch/RateTransposer.h
new file mode 100644
index 00000000..f035af2c
--- /dev/null
+++ b/plugins/soundtouch/soundtouch/source/SoundTouch/RateTransposer.h
@@ -0,0 +1,159 @@
+////////////////////////////////////////////////////////////////////////////////
+///
+/// Sample rate transposer. Changes sample rate by using linear interpolation
+/// together with anti-alias filtering (first order interpolation with anti-
+/// alias filtering should be quite adequate for this application).
+///
+/// Use either of the derived classes of 'RateTransposerInteger' or
+/// 'RateTransposerFloat' for corresponding integer/floating point tranposing
+/// algorithm implementation.
+///
+/// Author : Copyright (c) Olli Parviainen
+/// Author e-mail : oparviai 'at' iki.fi
+/// SoundTouch WWW: http://www.surina.net/soundtouch
+///
+////////////////////////////////////////////////////////////////////////////////
+//
+// Last changed : $Date: 2009-02-21 18:00:14 +0200 (Sat, 21 Feb 2009) $
+// File revision : $Revision: 4 $
+//
+// $Id: RateTransposer.h 63 2009-02-21 16:00:14Z oparviai $
+//
+////////////////////////////////////////////////////////////////////////////////
+//
+// License :
+//
+// SoundTouch audio processing library
+// Copyright (c) Olli Parviainen
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+////////////////////////////////////////////////////////////////////////////////
+
+#ifndef RateTransposer_H
+#define RateTransposer_H
+
+#include <stddef.h>
+#include "AAFilter.h"
+#include "FIFOSamplePipe.h"
+#include "FIFOSampleBuffer.h"
+
+#include "STTypes.h"
+
+namespace soundtouch
+{
+
+/// A common linear samplerate transposer class.
+///
+/// Note: Use function "RateTransposer::newInstance()" to create a new class
+/// instance instead of the "new" operator; that function automatically
+/// chooses a correct implementation depending on if integer or floating
+/// arithmetics are to be used.
+class RateTransposer : public FIFOProcessor
+{
+protected:
+ /// Anti-alias filter object
+ AAFilter *pAAFilter;
+
+ float fRate;
+
+ int numChannels;
+
+ /// Buffer for collecting samples to feed the anti-alias filter between
+ /// two batches
+ FIFOSampleBuffer storeBuffer;
+
+ /// Buffer for keeping samples between transposing & anti-alias filter
+ FIFOSampleBuffer tempBuffer;
+
+ /// Output sample buffer
+ FIFOSampleBuffer outputBuffer;
+
+ BOOL bUseAAFilter;
+
+ virtual void resetRegisters() = 0;
+
+ virtual uint transposeStereo(SAMPLETYPE *dest,
+ const SAMPLETYPE *src,
+ uint numSamples) = 0;
+ virtual uint transposeMono(SAMPLETYPE *dest,
+ const SAMPLETYPE *src,
+ uint numSamples) = 0;
+ inline uint transpose(SAMPLETYPE *dest,
+ const SAMPLETYPE *src,
+ uint numSamples);
+
+ void downsample(const SAMPLETYPE *src,
+ uint numSamples);
+ void upsample(const SAMPLETYPE *src,
+ uint numSamples);
+
+ /// Transposes sample rate by applying anti-alias filter to prevent folding.
+ /// Returns amount of samples returned in the "dest" buffer.
+ /// The maximum amount of samples that can be returned at a time is set by
+ /// the 'set_returnBuffer_size' function.
+ void processSamples(const SAMPLETYPE *src,
+ uint numSamples);
+
+
+public:
+ RateTransposer();
+ virtual ~RateTransposer();
+
+ /// Operator 'new' is overloaded so that it automatically creates a suitable instance
+ /// depending on if we're to use integer or floating point arithmetics.
+ static void *operator new(size_t s);
+
+ /// Use this function instead of "new" operator to create a new instance of this class.
+ /// This function automatically chooses a correct implementation, depending on if
+ /// integer ot floating point arithmetics are to be used.
+ static RateTransposer *newInstance();
+
+ /// Returns the output buffer object
+ FIFOSamplePipe *getOutput() { return &outputBuffer; };
+
+ /// Returns the store buffer object
+ FIFOSamplePipe *getStore() { return &storeBuffer; };
+
+ /// Return anti-alias filter object
+ AAFilter *getAAFilter();
+
+ /// Enables/disables the anti-alias filter. Zero to disable, nonzero to enable
+ void enableAAFilter(BOOL newMode);
+
+ /// Returns nonzero if anti-alias filter is enabled.
+ BOOL isAAFilterEnabled() const;
+
+ /// Sets new target rate. Normal rate = 1.0, smaller values represent slower
+ /// rate, larger faster rates.
+ virtual void setRate(float newRate);
+
+ /// Sets the number of channels, 1 = mono, 2 = stereo
+ void setChannels(int channels);
+
+ /// Adds 'numSamples' pcs of samples from the 'samples' memory position into
+ /// the input of the object.
+ void putSamples(const SAMPLETYPE *samples, uint numSamples);
+
+ /// Clears all the samples in the object
+ void clear();
+
+ /// Returns nonzero if there aren't any samples available for outputting.
+ int isEmpty() const;
+};
+
+}
+
+#endif
diff --git a/plugins/soundtouch/soundtouch/source/SoundTouch/SoundTouch.cpp b/plugins/soundtouch/soundtouch/source/SoundTouch/SoundTouch.cpp
new file mode 100644
index 00000000..aa7ac028
--- /dev/null
+++ b/plugins/soundtouch/soundtouch/source/SoundTouch/SoundTouch.cpp
@@ -0,0 +1,480 @@
+//////////////////////////////////////////////////////////////////////////////
+///
+/// SoundTouch - main class for tempo/pitch/rate adjusting routines.
+///
+/// Notes:
+/// - Initialize the SoundTouch object instance by setting up the sound stream
+/// parameters with functions 'setSampleRate' and 'setChannels', then set
+/// desired tempo/pitch/rate settings with the corresponding functions.
+///
+/// - The SoundTouch class behaves like a first-in-first-out pipeline: The
+/// samples that are to be processed are fed into one of the pipe by calling
+/// function 'putSamples', while the ready processed samples can be read
+/// from the other end of the pipeline with function 'receiveSamples'.
+///
+/// - The SoundTouch processing classes require certain sized 'batches' of
+/// samples in order to process the sound. For this reason the classes buffer
+/// incoming samples until there are enough of samples available for
+/// processing, then they carry out the processing step and consequently
+/// make the processed samples available for outputting.
+///
+/// - For the above reason, the processing routines introduce a certain
+/// 'latency' between the input and output, so that the samples input to
+/// SoundTouch may not be immediately available in the output, and neither
+/// the amount of outputtable samples may not immediately be in direct
+/// relationship with the amount of previously input samples.
+///
+/// - The tempo/pitch/rate control parameters can be altered during processing.
+/// Please notice though that they aren't currently protected by semaphores,
+/// so in multi-thread application external semaphore protection may be
+/// required.
+///
+/// - This class utilizes classes 'TDStretch' for tempo change (without modifying
+/// pitch) and 'RateTransposer' for changing the playback rate (that is, both
+/// tempo and pitch in the same ratio) of the sound. The third available control
+/// 'pitch' (change pitch but maintain tempo) is produced by a combination of
+/// combining the two other controls.
+///
+/// Author : Copyright (c) Olli Parviainen
+/// Author e-mail : oparviai 'at' iki.fi
+/// SoundTouch WWW: http://www.surina.net/soundtouch
+///
+////////////////////////////////////////////////////////////////////////////////
+//
+// Last changed : $Date: 2009-05-19 07:57:30 +0300 (Tue, 19 May 2009) $
+// File revision : $Revision: 4 $
+//
+// $Id: SoundTouch.cpp 73 2009-05-19 04:57:30Z oparviai $
+//
+////////////////////////////////////////////////////////////////////////////////
+//
+// License :
+//
+// SoundTouch audio processing library
+// Copyright (c) Olli Parviainen
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+////////////////////////////////////////////////////////////////////////////////
+
+#include <assert.h>
+#include <stdlib.h>
+#include <memory.h>
+#include <math.h>
+#include <stdexcept>
+#include <stdio.h>
+
+#include "SoundTouch.h"
+#include "TDStretch.h"
+#include "RateTransposer.h"
+#include "cpu_detect.h"
+
+using namespace soundtouch;
+
+/// test if two floating point numbers are equal
+#define TEST_FLOAT_EQUAL(a, b) (fabs(a - b) < 1e-10)
+
+
+/// Print library version string for autoconf
+extern "C" void soundtouch_ac_test()
+{
+ printf("SoundTouch Version: %s\n",SOUNDTOUCH_VERSION);
+}
+
+
+SoundTouch::SoundTouch()
+{
+ // Initialize rate transposer and tempo changer instances
+
+ pRateTransposer = RateTransposer::newInstance();
+ pTDStretch = TDStretch::newInstance();
+
+ setOutPipe(pTDStretch);
+
+ rate = tempo = 0;
+
+ virtualPitch =
+ virtualRate =
+ virtualTempo = 1.0;
+
+ calcEffectiveRateAndTempo();
+
+ channels = 0;
+ bSrateSet = FALSE;
+}
+
+
+
+SoundTouch::~SoundTouch()
+{
+ delete pRateTransposer;
+ delete pTDStretch;
+}
+
+
+
+/// Get SoundTouch library version string
+const char *SoundTouch::getVersionString()
+{
+ static const char *_version = SOUNDTOUCH_VERSION;
+
+ return _version;
+}
+
+
+/// Get SoundTouch library version Id
+uint SoundTouch::getVersionId()
+{
+ return SOUNDTOUCH_VERSION_ID;
+}
+
+
+// Sets the number of channels, 1 = mono, 2 = stereo
+void SoundTouch::setChannels(uint numChannels)
+{
+ if (numChannels != 1 && numChannels != 2)
+ {
+ throw std::runtime_error("Illegal number of channels");
+ }
+ channels = numChannels;
+ pRateTransposer->setChannels((int)numChannels);
+ pTDStretch->setChannels((int)numChannels);
+}
+
+
+
+// Sets new rate control value. Normal rate = 1.0, smaller values
+// represent slower rate, larger faster rates.
+void SoundTouch::setRate(float newRate)
+{
+ virtualRate = newRate;
+ calcEffectiveRateAndTempo();
+}
+
+
+
+// Sets new rate control value as a difference in percents compared
+// to the original rate (-50 .. +100 %)
+void SoundTouch::setRateChange(float newRate)
+{
+ virtualRate = 1.0f + 0.01f * newRate;
+ calcEffectiveRateAndTempo();
+}
+
+
+
+// Sets new tempo control value. Normal tempo = 1.0, smaller values
+// represent slower tempo, larger faster tempo.
+void SoundTouch::setTempo(float newTempo)
+{
+ virtualTempo = newTempo;
+ calcEffectiveRateAndTempo();
+}
+
+
+
+// Sets new tempo control value as a difference in percents compared
+// to the original tempo (-50 .. +100 %)
+void SoundTouch::setTempoChange(float newTempo)
+{
+ virtualTempo = 1.0f + 0.01f * newTempo;
+ calcEffectiveRateAndTempo();
+}
+
+
+
+// Sets new pitch control value. Original pitch = 1.0, smaller values
+// represent lower pitches, larger values higher pitch.
+void SoundTouch::setPitch(float newPitch)
+{
+ virtualPitch = newPitch;
+ calcEffectiveRateAndTempo();
+}
+
+
+
+// Sets pitch change in octaves compared to the original pitch
+// (-1.00 .. +1.00)
+void SoundTouch::setPitchOctaves(float newPitch)
+{
+ virtualPitch = (float)exp(0.69314718056f * newPitch);
+ calcEffectiveRateAndTempo();
+}
+
+
+
+// Sets pitch change in semi-tones compared to the original pitch
+// (-12 .. +12)
+void SoundTouch::setPitchSemiTones(int newPitch)
+{
+ setPitchOctaves((float)newPitch / 12.0f);
+}
+
+
+
+void SoundTouch::setPitchSemiTones(float newPitch)
+{
+ setPitchOctaves(newPitch / 12.0f);
+}
+
+
+// Calculates 'effective' rate and tempo values from the
+// nominal control values.
+void SoundTouch::calcEffectiveRateAndTempo()
+{
+ float oldTempo = tempo;
+ float oldRate = rate;
+
+ tempo = virtualTempo / virtualPitch;
+ rate = virtualPitch * virtualRate;
+
+ if (!TEST_FLOAT_EQUAL(rate,oldRate)) pRateTransposer->setRate(rate);
+ if (!TEST_FLOAT_EQUAL(tempo, oldTempo)) pTDStretch->setTempo(tempo);
+
+#ifndef PREVENT_CLICK_AT_RATE_CROSSOVER
+ if (rate <= 1.0f)
+ {
+ if (output != pTDStretch)
+ {
+ FIFOSamplePipe *tempoOut;
+
+ assert(output == pRateTransposer);
+ // move samples in the current output buffer to the output of pTDStretch
+ tempoOut = pTDStretch->getOutput();
+ tempoOut->moveSamples(*output);
+ // move samples in pitch transposer's store buffer to tempo changer's input
+ pTDStretch->moveSamples(*pRateTransposer->getStore());
+
+ output = pTDStretch;
+ }
+ }
+ else
+#endif
+ {
+ if (output != pRateTransposer)
+ {
+ FIFOSamplePipe *transOut;
+
+ assert(output == pTDStretch);
+ // move samples in the current output buffer to the output of pRateTransposer
+ transOut = pRateTransposer->getOutput();
+ transOut->moveSamples(*output);
+ // move samples in tempo changer's input to pitch transposer's input
+ pRateTransposer->moveSamples(*pTDStretch->getInput());
+
+ output = pRateTransposer;
+ }
+ }
+}
+
+
+// Sets sample rate.
+void SoundTouch::setSampleRate(uint srate)
+{
+ bSrateSet = TRUE;
+ // set sample rate, leave other tempo changer parameters as they are.
+ pTDStretch->setParameters((int)srate);
+}
+
+
+// Adds 'numSamples' pcs of samples from the 'samples' memory position into
+// the input of the object.
+void SoundTouch::putSamples(const SAMPLETYPE *samples, uint nSamples)
+{
+ if (bSrateSet == FALSE)
+ {
+ throw std::runtime_error("SoundTouch : Sample rate not defined");
+ }
+ else if (channels == 0)
+ {
+ throw std::runtime_error("SoundTouch : Number of channels not defined");
+ }
+
+ // Transpose the rate of the new samples if necessary
+ /* Bypass the nominal setting - can introduce a click in sound when tempo/pitch control crosses the nominal value...
+ if (rate == 1.0f)
+ {
+ // The rate value is same as the original, simply evaluate the tempo changer.
+ assert(output == pTDStretch);
+ if (pRateTransposer->isEmpty() == 0)
+ {
+ // yet flush the last samples in the pitch transposer buffer
+ // (may happen if 'rate' changes from a non-zero value to zero)
+ pTDStretch->moveSamples(*pRateTransposer);
+ }
+ pTDStretch->putSamples(samples, nSamples);
+ }
+ */
+#ifndef PREVENT_CLICK_AT_RATE_CROSSOVER
+ else if (rate <= 1.0f)
+ {
+ // transpose the rate down, output the transposed sound to tempo changer buffer
+ assert(output == pTDStretch);
+ pRateTransposer->putSamples(samples, nSamples);
+ pTDStretch->moveSamples(*pRateTransposer);
+ }
+ else
+#endif
+ {
+ // evaluate the tempo changer, then transpose the rate up,
+ assert(output == pRateTransposer);
+ pTDStretch->putSamples(samples, nSamples);
+ pRateTransposer->moveSamples(*pTDStretch);
+ }
+}
+
+
+// Flushes the last samples from the processing pipeline to the output.
+// Clears also the internal processing buffers.
+//
+// Note: This function is meant for extracting the last samples of a sound
+// stream. This function may introduce additional blank samples in the end
+// of the sound stream, and thus it's not recommended to call this function
+// in the middle of a sound stream.
+void SoundTouch::flush()
+{
+ int i;
+ uint nOut;
+ SAMPLETYPE buff[128];
+
+ nOut = numSamples();
+
+ memset(buff, 0, 128 * sizeof(SAMPLETYPE));
+ // "Push" the last active samples out from the processing pipeline by
+ // feeding blank samples into the processing pipeline until new,
+ // processed samples appear in the output (not however, more than
+ // 8ksamples in any case)
+ for (i = 0; i < 128; i ++)
+ {
+ putSamples(buff, 64);
+ if (numSamples() != nOut) break; // new samples have appeared in the output!
+ }
+
+ // Clear working buffers
+ pRateTransposer->clear();
+ pTDStretch->clearInput();
+ // yet leave the 'tempoChanger' output intouched as that's where the
+ // flushed samples are!
+}
+
+
+// Changes a setting controlling the processing system behaviour. See the
+// 'SETTING_...' defines for available setting ID's.
+BOOL SoundTouch::setSetting(int settingId, int value)
+{
+ int sampleRate, sequenceMs, seekWindowMs, overlapMs;
+
+ // read current tdstretch routine parameters
+ pTDStretch->getParameters(&sampleRate, &sequenceMs, &seekWindowMs, &overlapMs);
+
+ switch (settingId)
+ {
+ case SETTING_USE_AA_FILTER :
+ // enables / disabless anti-alias filter
+ pRateTransposer->enableAAFilter((value != 0) ? TRUE : FALSE);
+ return TRUE;
+
+ case SETTING_AA_FILTER_LENGTH :
+ // sets anti-alias filter length
+ pRateTransposer->getAAFilter()->setLength(value);
+ return TRUE;
+
+ case SETTING_USE_QUICKSEEK :
+ // enables / disables tempo routine quick seeking algorithm
+ pTDStretch->enableQuickSeek((value != 0) ? TRUE : FALSE);
+ return TRUE;
+
+ case SETTING_SEQUENCE_MS:
+ // change time-stretch sequence duration parameter
+ pTDStretch->setParameters(sampleRate, value, seekWindowMs, overlapMs);
+ return TRUE;
+
+ case SETTING_SEEKWINDOW_MS:
+ // change time-stretch seek window length parameter
+ pTDStretch->setParameters(sampleRate, sequenceMs, value, overlapMs);
+ return TRUE;
+
+ case SETTING_OVERLAP_MS:
+ // change time-stretch overlap length parameter
+ pTDStretch->setParameters(sampleRate, sequenceMs, seekWindowMs, value);
+ return TRUE;
+
+ default :
+ return FALSE;
+ }
+}
+
+
+// Reads a setting controlling the processing system behaviour. See the
+// 'SETTING_...' defines for available setting ID's.
+//
+// Returns the setting value.
+int SoundTouch::getSetting(int settingId) const
+{
+ int temp;
+
+ switch (settingId)
+ {
+ case SETTING_USE_AA_FILTER :
+ return (uint)pRateTransposer->isAAFilterEnabled();
+
+ case SETTING_AA_FILTER_LENGTH :
+ return pRateTransposer->getAAFilter()->getLength();
+
+ case SETTING_USE_QUICKSEEK :
+ return (uint) pTDStretch->isQuickSeekEnabled();
+
+ case SETTING_SEQUENCE_MS:
+ pTDStretch->getParameters(NULL, &temp, NULL, NULL);
+ return temp;
+
+ case SETTING_SEEKWINDOW_MS:
+ pTDStretch->getParameters(NULL, NULL, &temp, NULL);
+ return temp;
+
+ case SETTING_OVERLAP_MS:
+ pTDStretch->getParameters(NULL, NULL, NULL, &temp);
+ return temp;
+
+ default :
+ return 0;
+ }
+}
+
+
+// Clears all the samples in the object's output and internal processing
+// buffers.
+void SoundTouch::clear()
+{
+ pRateTransposer->clear();
+ pTDStretch->clear();
+}
+
+
+
+/// Returns number of samples currently unprocessed.
+uint SoundTouch::numUnprocessedSamples() const
+{
+ FIFOSamplePipe * psp;
+ if (pTDStretch)
+ {
+ psp = pTDStretch->getInput();
+ if (psp)
+ {
+ return psp->numSamples();
+ }
+ }
+ return 0;
+}
diff --git a/plugins/soundtouch/soundtouch/source/SoundTouch/TDStretch.cpp b/plugins/soundtouch/soundtouch/source/SoundTouch/TDStretch.cpp
new file mode 100644
index 00000000..232133b5
--- /dev/null
+++ b/plugins/soundtouch/soundtouch/source/SoundTouch/TDStretch.cpp
@@ -0,0 +1,1045 @@
+////////////////////////////////////////////////////////////////////////////////
+///
+/// Sampled sound tempo changer/time stretch algorithm. Changes the sound tempo
+/// while maintaining the original pitch by using a time domain WSOLA-like
+/// method with several performance-increasing tweaks.
+///
+/// Note : MMX optimized functions reside in a separate, platform-specific
+/// file, e.g. 'mmx_win.cpp' or 'mmx_gcc.cpp'
+///
+/// Author : Copyright (c) Olli Parviainen
+/// Author e-mail : oparviai 'at' iki.fi
+/// SoundTouch WWW: http://www.surina.net/soundtouch
+///
+////////////////////////////////////////////////////////////////////////////////
+//
+// Last changed : $Date: 2009-12-28 21:27:04 +0200 (Mon, 28 Dec 2009) $
+// File revision : $Revision: 1.12 $
+//
+// $Id: TDStretch.cpp 77 2009-12-28 19:27:04Z oparviai $
+//
+////////////////////////////////////////////////////////////////////////////////
+//
+// License :
+//
+// SoundTouch audio processing library
+// Copyright (c) Olli Parviainen
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+////////////////////////////////////////////////////////////////////////////////
+
+#include <string.h>
+#include <limits.h>
+#include <assert.h>
+#include <math.h>
+#include <float.h>
+#include <stdexcept>
+
+#include "STTypes.h"
+#include "cpu_detect.h"
+#include "TDStretch.h"
+
+#include <stdio.h>
+
+using namespace soundtouch;
+
+#define max(x, y) (((x) > (y)) ? (x) : (y))
+
+
+/*****************************************************************************
+ *
+ * Constant definitions
+ *
+ *****************************************************************************/
+
+// Table for the hierarchical mixing position seeking algorithm
+static const short _scanOffsets[5][24]={
+ { 124, 186, 248, 310, 372, 434, 496, 558, 620, 682, 744, 806,
+ 868, 930, 992, 1054, 1116, 1178, 1240, 1302, 1364, 1426, 1488, 0},
+ {-100, -75, -50, -25, 25, 50, 75, 100, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { -20, -15, -10, -5, 5, 10, 15, 20, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { -4, -3, -2, -1, 1, 2, 3, 4, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 121, 114, 97, 114, 98, 105, 108, 32, 104, 99, 117, 111,
+ 116, 100, 110, 117, 111, 115, 0, 0, 0, 0, 0, 0}};
+
+/*****************************************************************************
+ *
+ * Implementation of the class 'TDStretch'
+ *
+ *****************************************************************************/
+
+
+TDStretch::TDStretch() : FIFOProcessor(&outputBuffer)
+{
+ bQuickSeek = FALSE;
+ channels = 2;
+
+ pMidBuffer = NULL;
+ pRefMidBufferUnaligned = NULL;
+ overlapLength = 0;
+
+ bAutoSeqSetting = TRUE;
+ bAutoSeekSetting = TRUE;
+
+// outDebt = 0;
+ skipFract = 0;
+
+ tempo = 1.0f;
+ setParameters(44100, DEFAULT_SEQUENCE_MS, DEFAULT_SEEKWINDOW_MS, DEFAULT_OVERLAP_MS);
+ setTempo(1.0f);
+
+ clear();
+}
+
+
+
+TDStretch::~TDStretch()
+{
+ delete[] pMidBuffer;
+ delete[] pRefMidBufferUnaligned;
+}
+
+
+
+// Sets routine control parameters. These control are certain time constants
+// defining how the sound is stretched to the desired duration.
+//
+// 'sampleRate' = sample rate of the sound
+// 'sequenceMS' = one processing sequence length in milliseconds (default = 82 ms)
+// 'seekwindowMS' = seeking window length for scanning the best overlapping
+// position (default = 28 ms)
+// 'overlapMS' = overlapping length (default = 12 ms)
+
+void TDStretch::setParameters(int aSampleRate, int aSequenceMS,
+ int aSeekWindowMS, int aOverlapMS)
+{
+ // accept only positive parameter values - if zero or negative, use old values instead
+ if (aSampleRate > 0) this->sampleRate = aSampleRate;
+ if (aOverlapMS > 0) this->overlapMs = aOverlapMS;
+
+ if (aSequenceMS > 0)
+ {
+ this->sequenceMs = aSequenceMS;
+ bAutoSeqSetting = FALSE;
+ }
+ else if (aSequenceMS == 0)
+ {
+ // if zero, use automatic setting
+ bAutoSeqSetting = TRUE;
+ }
+
+ if (aSeekWindowMS > 0)
+ {
+ this->seekWindowMs = aSeekWindowMS;
+ bAutoSeekSetting = FALSE;
+ }
+ else if (aSeekWindowMS == 0)
+ {
+ // if zero, use automatic setting
+ bAutoSeekSetting = TRUE;
+ }
+
+ calcSeqParameters();
+
+ calculateOverlapLength(overlapMs);
+
+ // set tempo to recalculate 'sampleReq'
+ setTempo(tempo);
+
+}
+
+
+
+/// Get routine control parameters, see setParameters() function.
+/// Any of the parameters to this function can be NULL, in such case corresponding parameter
+/// value isn't returned.
+void TDStretch::getParameters(int *pSampleRate, int *pSequenceMs, int *pSeekWindowMs, int *pOverlapMs) const
+{
+ if (pSampleRate)
+ {
+ *pSampleRate = sampleRate;
+ }
+
+ if (pSequenceMs)
+ {
+ *pSequenceMs = (bAutoSeqSetting) ? (USE_AUTO_SEQUENCE_LEN) : sequenceMs;
+ }
+
+ if (pSeekWindowMs)
+ {
+ *pSeekWindowMs = (bAutoSeekSetting) ? (USE_AUTO_SEEKWINDOW_LEN) : seekWindowMs;
+ }
+
+ if (pOverlapMs)
+ {
+ *pOverlapMs = overlapMs;
+ }
+}
+
+
+// Overlaps samples in 'midBuffer' with the samples in 'pInput'
+void TDStretch::overlapMono(SAMPLETYPE *pOutput, const SAMPLETYPE *pInput) const
+{
+ int i, itemp;
+
+ for (i = 0; i < overlapLength ; i ++)
+ {
+ itemp = overlapLength - i;
+ pOutput[i] = (pInput[i] * i + pMidBuffer[i] * itemp ) / overlapLength; // >> overlapDividerBits;
+ }
+}
+
+
+
+void TDStretch::clearMidBuffer()
+{
+ memset(pMidBuffer, 0, 2 * sizeof(SAMPLETYPE) * overlapLength);
+}
+
+
+void TDStretch::clearInput()
+{
+ inputBuffer.clear();
+ clearMidBuffer();
+}
+
+
+// Clears the sample buffers
+void TDStretch::clear()
+{
+ outputBuffer.clear();
+ clearInput();
+}
+
+
+
+// Enables/disables the quick position seeking algorithm. Zero to disable, nonzero
+// to enable
+void TDStretch::enableQuickSeek(BOOL enable)
+{
+ bQuickSeek = enable;
+}
+
+
+// Returns nonzero if the quick seeking algorithm is enabled.
+BOOL TDStretch::isQuickSeekEnabled() const
+{
+ return bQuickSeek;
+}
+
+
+// Seeks for the optimal overlap-mixing position.
+int TDStretch::seekBestOverlapPosition(const SAMPLETYPE *refPos)
+{
+ if (channels == 2)
+ {
+ // stereo sound
+ if (bQuickSeek)
+ {
+ return seekBestOverlapPositionStereoQuick(refPos);
+ }
+ else
+ {
+ return seekBestOverlapPositionStereo(refPos);
+ }
+ }
+ else
+ {
+ // mono sound
+ if (bQuickSeek)
+ {
+ return seekBestOverlapPositionMonoQuick(refPos);
+ }
+ else
+ {
+ return seekBestOverlapPositionMono(refPos);
+ }
+ }
+}
+
+
+
+
+// Overlaps samples in 'midBuffer' with the samples in 'pInputBuffer' at position
+// of 'ovlPos'.
+inline void TDStretch::overlap(SAMPLETYPE *pOutput, const SAMPLETYPE *pInput, uint ovlPos) const
+{
+ if (channels == 2)
+ {
+ // stereo sound
+ overlapStereo(pOutput, pInput + 2 * ovlPos);
+ } else {
+ // mono sound.
+ overlapMono(pOutput, pInput + ovlPos);
+ }
+}
+
+
+
+
+// Seeks for the optimal overlap-mixing position. The 'stereo' version of the
+// routine
+//
+// The best position is determined as the position where the two overlapped
+// sample sequences are 'most alike', in terms of the highest cross-correlation
+// value over the overlapping period
+int TDStretch::seekBestOverlapPositionStereo(const SAMPLETYPE *refPos)
+{
+ int bestOffs;
+ double bestCorr, corr;
+ int i;
+
+ // Slopes the amplitudes of the 'midBuffer' samples
+ precalcCorrReferenceStereo();
+
+ bestCorr = FLT_MIN;
+ bestOffs = 0;
+
+ // Scans for the best correlation value by testing each possible position
+ // over the permitted range.
+ for (i = 0; i < seekLength; i ++)
+ {
+ // Calculates correlation value for the mixing position corresponding
+ // to 'i'
+ corr = (double)calcCrossCorrStereo(refPos + 2 * i, pRefMidBuffer);
+ // heuristic rule to slightly favour values close to mid of the range
+ double tmp = (double)(2 * i - seekLength) / (double)seekLength;
+ corr = ((corr + 0.1) * (1.0 - 0.25 * tmp * tmp));
+
+ // Checks for the highest correlation value
+ if (corr > bestCorr)
+ {
+ bestCorr = corr;
+ bestOffs = i;
+ }
+ }
+ // clear cross correlation routine state if necessary (is so e.g. in MMX routines).
+ clearCrossCorrState();
+
+ return bestOffs;
+}
+
+
+// Seeks for the optimal overlap-mixing position. The 'stereo' version of the
+// routine
+//
+// The best position is determined as the position where the two overlapped
+// sample sequences are 'most alike', in terms of the highest cross-correlation
+// value over the overlapping period
+int TDStretch::seekBestOverlapPositionStereoQuick(const SAMPLETYPE *refPos)
+{
+ int j;
+ int bestOffs;
+ double bestCorr, corr;
+ int scanCount, corrOffset, tempOffset;
+
+ // Slopes the amplitude of the 'midBuffer' samples
+ precalcCorrReferenceStereo();
+
+ bestCorr = FLT_MIN;
+ bestOffs = _scanOffsets[0][0];
+ corrOffset = 0;
+ tempOffset = 0;
+
+ // Scans for the best correlation value using four-pass hierarchical search.
+ //
+ // The look-up table 'scans' has hierarchical position adjusting steps.
+ // In first pass the routine searhes for the highest correlation with
+ // relatively coarse steps, then rescans the neighbourhood of the highest
+ // correlation with better resolution and so on.
+ for (scanCount = 0;scanCount < 4; scanCount ++)
+ {
+ j = 0;
+ while (_scanOffsets[scanCount][j])
+ {
+ tempOffset = corrOffset + _scanOffsets[scanCount][j];
+ if (tempOffset >= seekLength) break;
+
+ // Calculates correlation value for the mixing position corresponding
+ // to 'tempOffset'
+ corr = (double)calcCrossCorrStereo(refPos + 2 * tempOffset, pRefMidBuffer);
+ // heuristic rule to slightly favour values close to mid of the range
+ double tmp = (double)(2 * tempOffset - seekLength) / seekLength;
+ corr = ((corr + 0.1) * (1.0 - 0.25 * tmp * tmp));
+
+ // Checks for the highest correlation value
+ if (corr > bestCorr)
+ {
+ bestCorr = corr;
+ bestOffs = tempOffset;
+ }
+ j ++;
+ }
+ corrOffset = bestOffs;
+ }
+ // clear cross correlation routine state if necessary (is so e.g. in MMX routines).
+ clearCrossCorrState();
+
+ return bestOffs;
+}
+
+
+
+// Seeks for the optimal overlap-mixing position. The 'mono' version of the
+// routine
+//
+// The best position is determined as the position where the two overlapped
+// sample sequences are 'most alike', in terms of the highest cross-correlation
+// value over the overlapping period
+int TDStretch::seekBestOverlapPositionMono(const SAMPLETYPE *refPos)
+{
+ int bestOffs;
+ double bestCorr, corr;
+ int tempOffset;
+ const SAMPLETYPE *compare;
+
+ // Slopes the amplitude of the 'midBuffer' samples
+ precalcCorrReferenceMono();
+
+ bestCorr = FLT_MIN;
+ bestOffs = 0;
+
+ // Scans for the best correlation value by testing each possible position
+ // over the permitted range.
+ for (tempOffset = 0; tempOffset < seekLength; tempOffset ++)
+ {
+ compare = refPos + tempOffset;
+
+ // Calculates correlation value for the mixing position corresponding
+ // to 'tempOffset'
+ corr = (double)calcCrossCorrMono(pRefMidBuffer, compare);
+ // heuristic rule to slightly favour values close to mid of the range
+ double tmp = (double)(2 * tempOffset - seekLength) / seekLength;
+ corr = ((corr + 0.1) * (1.0 - 0.25 * tmp * tmp));
+
+ // Checks for the highest correlation value
+ if (corr > bestCorr)
+ {
+ bestCorr = corr;
+ bestOffs = tempOffset;
+ }
+ }
+ // clear cross correlation routine state if necessary (is so e.g. in MMX routines).
+ clearCrossCorrState();
+
+ return bestOffs;
+}
+
+
+// Seeks for the optimal overlap-mixing position. The 'mono' version of the
+// routine
+//
+// The best position is determined as the position where the two overlapped
+// sample sequences are 'most alike', in terms of the highest cross-correlation
+// value over the overlapping period
+int TDStretch::seekBestOverlapPositionMonoQuick(const SAMPLETYPE *refPos)
+{
+ int j;
+ int bestOffs;
+ double bestCorr, corr;
+ int scanCount, corrOffset, tempOffset;
+
+ // Slopes the amplitude of the 'midBuffer' samples
+ precalcCorrReferenceMono();
+
+ bestCorr = FLT_MIN;
+ bestOffs = _scanOffsets[0][0];
+ corrOffset = 0;
+ tempOffset = 0;
+
+ // Scans for the best correlation value using four-pass hierarchical search.
+ //
+ // The look-up table 'scans' has hierarchical position adjusting steps.
+ // In first pass the routine searhes for the highest correlation with
+ // relatively coarse steps, then rescans the neighbourhood of the highest
+ // correlation with better resolution and so on.
+ for (scanCount = 0;scanCount < 4; scanCount ++)
+ {
+ j = 0;
+ while (_scanOffsets[scanCount][j])
+ {
+ tempOffset = corrOffset + _scanOffsets[scanCount][j];
+ if (tempOffset >= seekLength) break;
+
+ // Calculates correlation value for the mixing position corresponding
+ // to 'tempOffset'
+ corr = (double)calcCrossCorrMono(refPos + tempOffset, pRefMidBuffer);
+ // heuristic rule to slightly favour values close to mid of the range
+ double tmp = (double)(2 * tempOffset - seekLength) / seekLength;
+ corr = ((corr + 0.1) * (1.0 - 0.25 * tmp * tmp));
+
+ // Checks for the highest correlation value
+ if (corr > bestCorr)
+ {
+ bestCorr = corr;
+ bestOffs = tempOffset;
+ }
+ j ++;
+ }
+ corrOffset = bestOffs;
+ }
+ // clear cross correlation routine state if necessary (is so e.g. in MMX routines).
+ clearCrossCorrState();
+
+ return bestOffs;
+}
+
+
+/// clear cross correlation routine state if necessary
+void TDStretch::clearCrossCorrState()
+{
+ // default implementation is empty.
+}
+
+
+/// Calculates processing sequence length according to tempo setting
+void TDStretch::calcSeqParameters()
+{
+ // Adjust tempo param according to tempo, so that variating processing sequence length is used
+ // at varius tempo settings, between the given low...top limits
+ #define AUTOSEQ_TEMPO_LOW 0.5 // auto setting low tempo range (-50%)
+ #define AUTOSEQ_TEMPO_TOP 2.0 // auto setting top tempo range (+100%)
+
+ // sequence-ms setting values at above low & top tempo
+ #define AUTOSEQ_AT_MIN 125.0
+ #define AUTOSEQ_AT_MAX 50.0
+ #define AUTOSEQ_K ((AUTOSEQ_AT_MAX - AUTOSEQ_AT_MIN) / (AUTOSEQ_TEMPO_TOP - AUTOSEQ_TEMPO_LOW))
+ #define AUTOSEQ_C (AUTOSEQ_AT_MIN - (AUTOSEQ_K) * (AUTOSEQ_TEMPO_LOW))
+
+ // seek-window-ms setting values at above low & top tempo
+ #define AUTOSEEK_AT_MIN 25.0
+ #define AUTOSEEK_AT_MAX 15.0
+ #define AUTOSEEK_K ((AUTOSEEK_AT_MAX - AUTOSEEK_AT_MIN) / (AUTOSEQ_TEMPO_TOP - AUTOSEQ_TEMPO_LOW))
+ #define AUTOSEEK_C (AUTOSEEK_AT_MIN - (AUTOSEEK_K) * (AUTOSEQ_TEMPO_LOW))
+
+ #define CHECK_LIMITS(x, mi, ma) (((x) < (mi)) ? (mi) : (((x) > (ma)) ? (ma) : (x)))
+
+ double seq, seek;
+
+ if (bAutoSeqSetting)
+ {
+ seq = AUTOSEQ_C + AUTOSEQ_K * tempo;
+ seq = CHECK_LIMITS(seq, AUTOSEQ_AT_MAX, AUTOSEQ_AT_MIN);
+ sequenceMs = (int)(seq + 0.5);
+ }
+
+ if (bAutoSeekSetting)
+ {
+ seek = AUTOSEEK_C + AUTOSEEK_K * tempo;
+ seek = CHECK_LIMITS(seek, AUTOSEEK_AT_MAX, AUTOSEEK_AT_MIN);
+ seekWindowMs = (int)(seek + 0.5);
+ }
+
+ // Update seek window lengths
+ seekWindowLength = (sampleRate * sequenceMs) / 1000;
+ if (seekWindowLength < 2 * overlapLength)
+ {
+ seekWindowLength = 2 * overlapLength;
+ }
+ seekLength = (sampleRate * seekWindowMs) / 1000;
+}
+
+
+
+// Sets new target tempo. Normal tempo = 'SCALE', smaller values represent slower
+// tempo, larger faster tempo.
+void TDStretch::setTempo(float newTempo)
+{
+ int intskip;
+
+ tempo = newTempo;
+
+ // Calculate new sequence duration
+ calcSeqParameters();
+
+ // Calculate ideal skip length (according to tempo value)
+ nominalSkip = tempo * (seekWindowLength - overlapLength);
+ intskip = (int)(nominalSkip + 0.5f);
+
+ // Calculate how many samples are needed in the 'inputBuffer' to
+ // process another batch of samples
+ //sampleReq = max(intskip + overlapLength, seekWindowLength) + seekLength / 2;
+ sampleReq = max(intskip + overlapLength, seekWindowLength) + seekLength;
+}
+
+
+
+// Sets the number of channels, 1 = mono, 2 = stereo
+void TDStretch::setChannels(int numChannels)
+{
+ assert(numChannels > 0);
+ if (channels == numChannels) return;
+ assert(numChannels == 1 || numChannels == 2);
+
+ channels = numChannels;
+ inputBuffer.setChannels(channels);
+ outputBuffer.setChannels(channels);
+}
+
+
+// nominal tempo, no need for processing, just pass the samples through
+// to outputBuffer
+/*
+void TDStretch::processNominalTempo()
+{
+ assert(tempo == 1.0f);
+
+ if (bMidBufferDirty)
+ {
+ // If there are samples in pMidBuffer waiting for overlapping,
+ // do a single sliding overlapping with them in order to prevent a
+ // clicking distortion in the output sound
+ if (inputBuffer.numSamples() < overlapLength)
+ {
+ // wait until we've got overlapLength input samples
+ return;
+ }
+ // Mix the samples in the beginning of 'inputBuffer' with the
+ // samples in 'midBuffer' using sliding overlapping
+ overlap(outputBuffer.ptrEnd(overlapLength), inputBuffer.ptrBegin(), 0);
+ outputBuffer.putSamples(overlapLength);
+ inputBuffer.receiveSamples(overlapLength);
+ clearMidBuffer();
+ // now we've caught the nominal sample flow and may switch to
+ // bypass mode
+ }
+
+ // Simply bypass samples from input to output
+ outputBuffer.moveSamples(inputBuffer);
+}
+*/
+
+#include <stdio.h>
+
+// Processes as many processing frames of the samples 'inputBuffer', store
+// the result into 'outputBuffer'
+void TDStretch::processSamples()
+{
+ int ovlSkip, offset;
+ int temp;
+
+ /* Removed this small optimization - can introduce a click to sound when tempo setting
+ crosses the nominal value
+ if (tempo == 1.0f)
+ {
+ // tempo not changed from the original, so bypass the processing
+ processNominalTempo();
+ return;
+ }
+ */
+
+ // Process samples as long as there are enough samples in 'inputBuffer'
+ // to form a processing frame.
+// while ((int)inputBuffer.numSamples() >= sampleReq - (outDebt / 4))
+ while ((int)inputBuffer.numSamples() >= sampleReq)
+ {
+ // If tempo differs from the normal ('SCALE'), scan for the best overlapping
+ // position
+ offset = seekBestOverlapPosition(inputBuffer.ptrBegin());
+
+ // Mix the samples in the 'inputBuffer' at position of 'offset' with the
+ // samples in 'midBuffer' using sliding overlapping
+ // ... first partially overlap with the end of the previous sequence
+ // (that's in 'midBuffer')
+ overlap(outputBuffer.ptrEnd((uint)overlapLength), inputBuffer.ptrBegin(), (uint)offset);
+ outputBuffer.putSamples((uint)overlapLength);
+
+ // ... then copy sequence samples from 'inputBuffer' to output:
+ temp = (seekLength / 2 - offset);
+
+ // compensate cumulated output length diff vs. ideal output
+// temp -= outDebt / 4;
+
+ // update ideal vs. true output difference
+// outDebt += temp;
+
+ // length of sequence
+// temp += (seekWindowLength - 2 * overlapLength);
+ temp = (seekWindowLength - 2 * overlapLength);
+
+ // crosscheck that we don't have buffer overflow...
+ if ((int)inputBuffer.numSamples() < (offset + temp + overlapLength * 2))
+ {
+ continue; // just in case, shouldn't really happen
+ }
+
+ outputBuffer.putSamples(inputBuffer.ptrBegin() + channels * (offset + overlapLength), (uint)temp);
+
+ // Copies the end of the current sequence from 'inputBuffer' to
+ // 'midBuffer' for being mixed with the beginning of the next
+ // processing sequence and so on
+ assert((offset + temp + overlapLength * 2) <= (int)inputBuffer.numSamples());
+ memcpy(pMidBuffer, inputBuffer.ptrBegin() + channels * (offset + temp + overlapLength),
+ channels * sizeof(SAMPLETYPE) * overlapLength);
+
+ // Remove the processed samples from the input buffer. Update
+ // the difference between integer & nominal skip step to 'skipFract'
+ // in order to prevent the error from accumulating over time.
+ skipFract += nominalSkip; // real skip size
+ ovlSkip = (int)skipFract; // rounded to integer skip
+ skipFract -= ovlSkip; // maintain the fraction part, i.e. real vs. integer skip
+ inputBuffer.receiveSamples((uint)ovlSkip);
+ }
+}
+
+
+// Adds 'numsamples' pcs of samples from the 'samples' memory position into
+// the input of the object.
+void TDStretch::putSamples(const SAMPLETYPE *samples, uint nSamples)
+{
+ // Add the samples into the input buffer
+ inputBuffer.putSamples(samples, nSamples);
+ // Process the samples in input buffer
+ processSamples();
+}
+
+
+
+/// Set new overlap length parameter & reallocate RefMidBuffer if necessary.
+void TDStretch::acceptNewOverlapLength(int newOverlapLength)
+{
+ int prevOvl;
+
+ assert(newOverlapLength >= 0);
+ prevOvl = overlapLength;
+ overlapLength = newOverlapLength;
+
+ if (overlapLength > prevOvl)
+ {
+ delete[] pMidBuffer;
+ delete[] pRefMidBufferUnaligned;
+
+ pMidBuffer = new SAMPLETYPE[overlapLength * 2];
+ clearMidBuffer();
+
+ pRefMidBufferUnaligned = new SAMPLETYPE[2 * overlapLength + 16 / sizeof(SAMPLETYPE)];
+ // ensure that 'pRefMidBuffer' is aligned to 16 byte boundary for efficiency
+ pRefMidBuffer = (SAMPLETYPE *)((((ulong)pRefMidBufferUnaligned) + 15) & (ulong)-16);
+ }
+}
+
+
+// Operator 'new' is overloaded so that it automatically creates a suitable instance
+// depending on if we've a MMX/SSE/etc-capable CPU available or not.
+void * TDStretch::operator new(size_t s)
+{
+ // Notice! don't use "new TDStretch" directly, use "newInstance" to create a new instance instead!
+ throw std::runtime_error("Error in TDStretch::new: Don't use 'new TDStretch' directly, use 'newInstance' member instead!");
+ return NULL;
+}
+
+
+TDStretch * TDStretch::newInstance()
+{
+ uint uExtensions;
+
+ uExtensions = detectCPUextensions();
+
+ // Check if MMX/SSE/3DNow! instruction set extensions supported by CPU
+
+#ifdef ALLOW_MMX
+ // MMX routines available only with integer sample types
+ if (uExtensions & SUPPORT_MMX)
+ {
+ return ::new TDStretchMMX;
+ }
+ else
+#endif // ALLOW_MMX
+
+
+#ifdef ALLOW_SSE
+ if (uExtensions & SUPPORT_SSE)
+ {
+ // SSE support
+ return ::new TDStretchSSE;
+ }
+ else
+#endif // ALLOW_SSE
+
+
+#ifdef ALLOW_3DNOW
+ if (uExtensions & SUPPORT_3DNOW)
+ {
+ // 3DNow! support
+ return ::new TDStretch3DNow;
+ }
+ else
+#endif // ALLOW_3DNOW
+
+ {
+ // ISA optimizations not supported, use plain C version
+ return ::new TDStretch;
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// Integer arithmetics specific algorithm implementations.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifdef INTEGER_SAMPLES
+
+// Slopes the amplitude of the 'midBuffer' samples so that cross correlation
+// is faster to calculate
+void TDStretch::precalcCorrReferenceStereo()
+{
+ int i, cnt2;
+ int temp, temp2;
+
+ for (i=0 ; i < (int)overlapLength ;i ++)
+ {
+ temp = i * (overlapLength - i);
+ cnt2 = i * 2;
+
+ temp2 = (pMidBuffer[cnt2] * temp) / slopingDivider;
+ pRefMidBuffer[cnt2] = (short)(temp2);
+ temp2 = (pMidBuffer[cnt2 + 1] * temp) / slopingDivider;
+ pRefMidBuffer[cnt2 + 1] = (short)(temp2);
+ }
+}
+
+
+// Slopes the amplitude of the 'midBuffer' samples so that cross correlation
+// is faster to calculate
+void TDStretch::precalcCorrReferenceMono()
+{
+ int i;
+ long temp;
+ long temp2;
+
+ for (i=0 ; i < (int)overlapLength ;i ++)
+ {
+ temp = i * (overlapLength - i);
+ temp2 = (pMidBuffer[i] * temp) / slopingDivider;
+ pRefMidBuffer[i] = (short)temp2;
+ }
+}
+
+
+// Overlaps samples in 'midBuffer' with the samples in 'input'. The 'Stereo'
+// version of the routine.
+void TDStretch::overlapStereo(short *poutput, const short *input) const
+{
+ int i;
+ short temp;
+ int cnt2;
+
+ for (i = 0; i < overlapLength ; i ++)
+ {
+ temp = (short)(overlapLength - i);
+ cnt2 = 2 * i;
+ poutput[cnt2] = (input[cnt2] * i + pMidBuffer[cnt2] * temp ) / overlapLength;
+ poutput[cnt2 + 1] = (input[cnt2 + 1] * i + pMidBuffer[cnt2 + 1] * temp ) / overlapLength;
+ }
+}
+
+// Calculates the x having the closest 2^x value for the given value
+static int _getClosest2Power(double value)
+{
+ return (int)(log(value) / log(2.0) + 0.5);
+}
+
+
+/// Calculates overlap period length in samples.
+/// Integer version rounds overlap length to closest power of 2
+/// for a divide scaling operation.
+void TDStretch::calculateOverlapLength(int aoverlapMs)
+{
+ int newOvl;
+
+ assert(aoverlapMs >= 0);
+
+ // calculate overlap length so that it's power of 2 - thus it's easy to do
+ // integer division by right-shifting. Term "-1" at end is to account for
+ // the extra most significatnt bit left unused in result by signed multiplication
+ overlapDividerBits = _getClosest2Power((sampleRate * aoverlapMs) / 1000.0) - 1;
+ if (overlapDividerBits > 9) overlapDividerBits = 9;
+ if (overlapDividerBits < 3) overlapDividerBits = 3;
+ newOvl = (int)pow(2.0, (int)overlapDividerBits + 1); // +1 => account for -1 above
+
+ acceptNewOverlapLength(newOvl);
+
+ // calculate sloping divider so that crosscorrelation operation won't
+ // overflow 32-bit register. Max. sum of the crosscorrelation sum without
+ // divider would be 2^30*(N^3-N)/3, where N = overlap length
+ slopingDivider = (newOvl * newOvl - 1) / 3;
+}
+
+
+long TDStretch::calcCrossCorrMono(const short *mixingPos, const short *compare) const
+{
+ long corr;
+ long norm;
+ int i;
+
+ corr = norm = 0;
+ for (i = 1; i < overlapLength; i ++)
+ {
+ corr += (mixingPos[i] * compare[i]) >> overlapDividerBits;
+ norm += (mixingPos[i] * mixingPos[i]) >> overlapDividerBits;
+ }
+
+ // Normalize result by dividing by sqrt(norm) - this step is easiest
+ // done using floating point operation
+ if (norm == 0) norm = 1; // to avoid div by zero
+ return (long)((double)corr * SHRT_MAX / sqrt((double)norm));
+}
+
+
+long TDStretch::calcCrossCorrStereo(const short *mixingPos, const short *compare) const
+{
+ long corr;
+ long norm;
+ int i;
+
+ corr = norm = 0;
+ for (i = 2; i < 2 * overlapLength; i += 2)
+ {
+ corr += (mixingPos[i] * compare[i] +
+ mixingPos[i + 1] * compare[i + 1]) >> overlapDividerBits;
+ norm += (mixingPos[i] * mixingPos[i] + mixingPos[i + 1] * mixingPos[i + 1]) >> overlapDividerBits;
+ }
+
+ // Normalize result by dividing by sqrt(norm) - this step is easiest
+ // done using floating point operation
+ if (norm == 0) norm = 1; // to avoid div by zero
+ return (long)((double)corr * SHRT_MAX / sqrt((double)norm));
+}
+
+#endif // INTEGER_SAMPLES
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// Floating point arithmetics specific algorithm implementations.
+//
+
+#ifdef FLOAT_SAMPLES
+
+
+// Slopes the amplitude of the 'midBuffer' samples so that cross correlation
+// is faster to calculate
+void TDStretch::precalcCorrReferenceStereo()
+{
+ int i, cnt2;
+ float temp;
+
+ for (i=0 ; i < (int)overlapLength ;i ++)
+ {
+ temp = (float)i * (float)(overlapLength - i);
+ cnt2 = i * 2;
+ pRefMidBuffer[cnt2] = (float)(pMidBuffer[cnt2] * temp);
+ pRefMidBuffer[cnt2 + 1] = (float)(pMidBuffer[cnt2 + 1] * temp);
+ }
+}
+
+
+// Slopes the amplitude of the 'midBuffer' samples so that cross correlation
+// is faster to calculate
+void TDStretch::precalcCorrReferenceMono()
+{
+ int i;
+ float temp;
+
+ for (i=0 ; i < (int)overlapLength ;i ++)
+ {
+ temp = (float)i * (float)(overlapLength - i);
+ pRefMidBuffer[i] = (float)(pMidBuffer[i] * temp);
+ }
+}
+
+
+// Overlaps samples in 'midBuffer' with the samples in 'pInput'
+void TDStretch::overlapStereo(float *pOutput, const float *pInput) const
+{
+ int i;
+ int cnt2;
+ float fTemp;
+ float fScale;
+ float fi;
+
+ fScale = 1.0f / (float)overlapLength;
+
+ for (i = 0; i < (int)overlapLength ; i ++)
+ {
+ fTemp = (float)(overlapLength - i) * fScale;
+ fi = (float)i * fScale;
+ cnt2 = 2 * i;
+ pOutput[cnt2 + 0] = pInput[cnt2 + 0] * fi + pMidBuffer[cnt2 + 0] * fTemp;
+ pOutput[cnt2 + 1] = pInput[cnt2 + 1] * fi + pMidBuffer[cnt2 + 1] * fTemp;
+ }
+}
+
+
+/// Calculates overlapInMsec period length in samples.
+void TDStretch::calculateOverlapLength(int overlapInMsec)
+{
+ int newOvl;
+
+ assert(overlapInMsec >= 0);
+ newOvl = (sampleRate * overlapInMsec) / 1000;
+ if (newOvl < 16) newOvl = 16;
+
+ // must be divisible by 8
+ newOvl -= newOvl % 8;
+
+ acceptNewOverlapLength(newOvl);
+}
+
+
+
+double TDStretch::calcCrossCorrMono(const float *mixingPos, const float *compare) const
+{
+ double corr;
+ double norm;
+ int i;
+
+ corr = norm = 0;
+ for (i = 1; i < overlapLength; i ++)
+ {
+ corr += mixingPos[i] * compare[i];
+ norm += mixingPos[i] * mixingPos[i];
+ }
+
+ if (norm < 1e-9) norm = 1.0; // to avoid div by zero
+ return corr / sqrt(norm);
+}
+
+
+double TDStretch::calcCrossCorrStereo(const float *mixingPos, const float *compare) const
+{
+ double corr;
+ double norm;
+ int i;
+
+ corr = norm = 0;
+ for (i = 2; i < 2 * overlapLength; i += 2)
+ {
+ corr += mixingPos[i] * compare[i] +
+ mixingPos[i + 1] * compare[i + 1];
+ norm += mixingPos[i] * mixingPos[i] +
+ mixingPos[i + 1] * mixingPos[i + 1];
+ }
+
+ if (norm < 1e-9) norm = 1.0; // to avoid div by zero
+ return corr / sqrt(norm);
+}
+
+#endif // FLOAT_SAMPLES
diff --git a/plugins/soundtouch/soundtouch/source/SoundTouch/TDStretch.h b/plugins/soundtouch/soundtouch/source/SoundTouch/TDStretch.h
new file mode 100644
index 00000000..00d1f3e3
--- /dev/null
+++ b/plugins/soundtouch/soundtouch/source/SoundTouch/TDStretch.h
@@ -0,0 +1,275 @@
+////////////////////////////////////////////////////////////////////////////////
+///
+/// Sampled sound tempo changer/time stretch algorithm. Changes the sound tempo
+/// while maintaining the original pitch by using a time domain WSOLA-like method
+/// with several performance-increasing tweaks.
+///
+/// Note : MMX/SSE optimized functions reside in separate, platform-specific files
+/// 'mmx_optimized.cpp' and 'sse_optimized.cpp'
+///
+/// Author : Copyright (c) Olli Parviainen
+/// Author e-mail : oparviai 'at' iki.fi
+/// SoundTouch WWW: http://www.surina.net/soundtouch
+///
+////////////////////////////////////////////////////////////////////////////////
+//
+// Last changed : $Date: 2009-05-17 14:35:13 +0300 (Sun, 17 May 2009) $
+// File revision : $Revision: 4 $
+//
+// $Id: TDStretch.h 71 2009-05-17 11:35:13Z oparviai $
+//
+////////////////////////////////////////////////////////////////////////////////
+//
+// License :
+//
+// SoundTouch audio processing library
+// Copyright (c) Olli Parviainen
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+////////////////////////////////////////////////////////////////////////////////
+
+#ifndef TDStretch_H
+#define TDStretch_H
+
+#include <stddef.h>
+#include "STTypes.h"
+#include "RateTransposer.h"
+#include "FIFOSamplePipe.h"
+
+namespace soundtouch
+{
+
+/// Default values for sound processing parameters:
+/// Notice that the default parameters are tuned for contemporary popular music
+/// processing. For speech processing applications these parameters suit better:
+/// #define DEFAULT_SEQUENCE_MS 40
+/// #define DEFAULT_SEEKWINDOW_MS 15
+/// #define DEFAULT_OVERLAP_MS 8
+///
+
+/// Default length of a single processing sequence, in milliseconds. This determines to how
+/// long sequences the original sound is chopped in the time-stretch algorithm.
+///
+/// The larger this value is, the lesser sequences are used in processing. In principle
+/// a bigger value sounds better when slowing down tempo, but worse when increasing tempo
+/// and vice versa.
+///
+/// Increasing this value reduces computational burden & vice versa.
+//#define DEFAULT_SEQUENCE_MS 40
+#define DEFAULT_SEQUENCE_MS USE_AUTO_SEQUENCE_LEN
+
+/// Giving this value for the sequence length sets automatic parameter value
+/// according to tempo setting (recommended)
+#define USE_AUTO_SEQUENCE_LEN 0
+
+/// Seeking window default length in milliseconds for algorithm that finds the best possible
+/// overlapping location. This determines from how wide window the algorithm may look for an
+/// optimal joining location when mixing the sound sequences back together.
+///
+/// The bigger this window setting is, the higher the possibility to find a better mixing
+/// position will become, but at the same time large values may cause a "drifting" artifact
+/// because consequent sequences will be taken at more uneven intervals.
+///
+/// If there's a disturbing artifact that sounds as if a constant frequency was drifting
+/// around, try reducing this setting.
+///
+/// Increasing this value increases computational burden & vice versa.
+//#define DEFAULT_SEEKWINDOW_MS 15
+#define DEFAULT_SEEKWINDOW_MS USE_AUTO_SEEKWINDOW_LEN
+
+/// Giving this value for the seek window length sets automatic parameter value
+/// according to tempo setting (recommended)
+#define USE_AUTO_SEEKWINDOW_LEN 0
+
+/// Overlap length in milliseconds. When the chopped sound sequences are mixed back together,
+/// to form a continuous sound stream, this parameter defines over how long period the two
+/// consecutive sequences are let to overlap each other.
+///
+/// This shouldn't be that critical parameter. If you reduce the DEFAULT_SEQUENCE_MS setting
+/// by a large amount, you might wish to try a smaller value on this.
+///
+/// Increasing this value increases computational burden & vice versa.
+#define DEFAULT_OVERLAP_MS 8
+
+
+/// Class that does the time-stretch (tempo change) effect for the processed
+/// sound.
+class TDStretch : public FIFOProcessor
+{
+protected:
+ int channels;
+ int sampleReq;
+ float tempo;
+
+ SAMPLETYPE *pMidBuffer;
+ SAMPLETYPE *pRefMidBuffer;
+ SAMPLETYPE *pRefMidBufferUnaligned;
+ int overlapLength;
+ int seekLength;
+ int seekWindowLength;
+ int overlapDividerBits;
+ int slopingDivider;
+ float nominalSkip;
+ float skipFract;
+ FIFOSampleBuffer outputBuffer;
+ FIFOSampleBuffer inputBuffer;
+ BOOL bQuickSeek;
+// int outDebt;
+// BOOL bMidBufferDirty;
+
+ int sampleRate;
+ int sequenceMs;
+ int seekWindowMs;
+ int overlapMs;
+ BOOL bAutoSeqSetting;
+ BOOL bAutoSeekSetting;
+
+ void acceptNewOverlapLength(int newOverlapLength);
+
+ virtual void clearCrossCorrState();
+ void calculateOverlapLength(int overlapMs);
+
+ virtual LONG_SAMPLETYPE calcCrossCorrStereo(const SAMPLETYPE *mixingPos, const SAMPLETYPE *compare) const;
+ virtual LONG_SAMPLETYPE calcCrossCorrMono(const SAMPLETYPE *mixingPos, const SAMPLETYPE *compare) const;
+
+ virtual int seekBestOverlapPositionStereo(const SAMPLETYPE *refPos);
+ virtual int seekBestOverlapPositionStereoQuick(const SAMPLETYPE *refPos);
+ virtual int seekBestOverlapPositionMono(const SAMPLETYPE *refPos);
+ virtual int seekBestOverlapPositionMonoQuick(const SAMPLETYPE *refPos);
+ int seekBestOverlapPosition(const SAMPLETYPE *refPos);
+
+ virtual void overlapStereo(SAMPLETYPE *output, const SAMPLETYPE *input) const;
+ virtual void overlapMono(SAMPLETYPE *output, const SAMPLETYPE *input) const;
+
+ void clearMidBuffer();
+ void overlap(SAMPLETYPE *output, const SAMPLETYPE *input, uint ovlPos) const;
+
+ void precalcCorrReferenceMono();
+ void precalcCorrReferenceStereo();
+
+ void calcSeqParameters();
+
+ /// Changes the tempo of the given sound samples.
+ /// Returns amount of samples returned in the "output" buffer.
+ /// The maximum amount of samples that can be returned at a time is set by
+ /// the 'set_returnBuffer_size' function.
+ void processSamples();
+
+public:
+ TDStretch();
+ virtual ~TDStretch();
+
+ /// Operator 'new' is overloaded so that it automatically creates a suitable instance
+ /// depending on if we've a MMX/SSE/etc-capable CPU available or not.
+ static void *operator new(size_t s);
+
+ /// Use this function instead of "new" operator to create a new instance of this class.
+ /// This function automatically chooses a correct feature set depending on if the CPU
+ /// supports MMX/SSE/etc extensions.
+ static TDStretch *newInstance();
+
+ /// Returns the output buffer object
+ FIFOSamplePipe *getOutput() { return &outputBuffer; };
+
+ /// Returns the input buffer object
+ FIFOSamplePipe *getInput() { return &inputBuffer; };
+
+ /// Sets new target tempo. Normal tempo = 'SCALE', smaller values represent slower
+ /// tempo, larger faster tempo.
+ void setTempo(float newTempo);
+
+ /// Returns nonzero if there aren't any samples available for outputting.
+ virtual void clear();
+
+ /// Clears the input buffer
+ void clearInput();
+
+ /// Sets the number of channels, 1 = mono, 2 = stereo
+ void setChannels(int numChannels);
+
+ /// Enables/disables the quick position seeking algorithm. Zero to disable,
+ /// nonzero to enable
+ void enableQuickSeek(BOOL enable);
+
+ /// Returns nonzero if the quick seeking algorithm is enabled.
+ BOOL isQuickSeekEnabled() const;
+
+ /// Sets routine control parameters. These control are certain time constants
+ /// defining how the sound is stretched to the desired duration.
+ //
+ /// 'sampleRate' = sample rate of the sound
+ /// 'sequenceMS' = one processing sequence length in milliseconds
+ /// 'seekwindowMS' = seeking window length for scanning the best overlapping
+ /// position
+ /// 'overlapMS' = overlapping length
+ void setParameters(int sampleRate, ///< Samplerate of sound being processed (Hz)
+ int sequenceMS = -1, ///< Single processing sequence length (ms)
+ int seekwindowMS = -1, ///< Offset seeking window length (ms)
+ int overlapMS = -1 ///< Sequence overlapping length (ms)
+ );
+
+ /// Get routine control parameters, see setParameters() function.
+ /// Any of the parameters to this function can be NULL, in such case corresponding parameter
+ /// value isn't returned.
+ void getParameters(int *pSampleRate, int *pSequenceMs, int *pSeekWindowMs, int *pOverlapMs) const;
+
+ /// Adds 'numsamples' pcs of samples from the 'samples' memory position into
+ /// the input of the object.
+ virtual void putSamples(
+ const SAMPLETYPE *samples, ///< Input sample data
+ uint numSamples ///< Number of samples in 'samples' so that one sample
+ ///< contains both channels if stereo
+ );
+};
+
+
+
+// Implementation-specific class declarations:
+
+#ifdef ALLOW_MMX
+ /// Class that implements MMX optimized routines for 16bit integer samples type.
+ class TDStretchMMX : public TDStretch
+ {
+ protected:
+ long calcCrossCorrStereo(const short *mixingPos, const short *compare) const;
+ virtual void overlapStereo(short *output, const short *input) const;
+ virtual void clearCrossCorrState();
+ };
+#endif /// ALLOW_MMX
+
+
+#ifdef ALLOW_3DNOW
+ /// Class that implements 3DNow! optimized routines for floating point samples type.
+ class TDStretch3DNow : public TDStretch
+ {
+ protected:
+ double calcCrossCorrStereo(const float *mixingPos, const float *compare) const;
+ };
+#endif /// ALLOW_3DNOW
+
+
+#ifdef ALLOW_SSE
+ /// Class that implements SSE optimized routines for floating point samples type.
+ class TDStretchSSE : public TDStretch
+ {
+ protected:
+ double calcCrossCorrStereo(const float *mixingPos, const float *compare) const;
+ };
+
+#endif /// ALLOW_SSE
+
+}
+#endif /// TDStretch_H
diff --git a/plugins/soundtouch/soundtouch/source/SoundTouch/cpu_detect.h b/plugins/soundtouch/soundtouch/source/SoundTouch/cpu_detect.h
new file mode 100644
index 00000000..025781da
--- /dev/null
+++ b/plugins/soundtouch/soundtouch/source/SoundTouch/cpu_detect.h
@@ -0,0 +1,62 @@
+////////////////////////////////////////////////////////////////////////////////
+///
+/// A header file for detecting the Intel MMX instructions set extension.
+///
+/// Please see 'mmx_win.cpp', 'mmx_cpp.cpp' and 'mmx_non_x86.cpp' for the
+/// routine implementations for x86 Windows, x86 gnu version and non-x86
+/// platforms, respectively.
+///
+/// Author : Copyright (c) Olli Parviainen
+/// Author e-mail : oparviai 'at' iki.fi
+/// SoundTouch WWW: http://www.surina.net/soundtouch
+///
+////////////////////////////////////////////////////////////////////////////////
+//
+// Last changed : $Date: 2008-02-10 18:26:55 +0200 (Sun, 10 Feb 2008) $
+// File revision : $Revision: 4 $
+//
+// $Id: cpu_detect.h 11 2008-02-10 16:26:55Z oparviai $
+//
+////////////////////////////////////////////////////////////////////////////////
+//
+// License :
+//
+// SoundTouch audio processing library
+// Copyright (c) Olli Parviainen
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+////////////////////////////////////////////////////////////////////////////////
+
+#ifndef _CPU_DETECT_H_
+#define _CPU_DETECT_H_
+
+#include "STTypes.h"
+
+#define SUPPORT_MMX 0x0001
+#define SUPPORT_3DNOW 0x0002
+#define SUPPORT_ALTIVEC 0x0004
+#define SUPPORT_SSE 0x0008
+#define SUPPORT_SSE2 0x0010
+
+/// Checks which instruction set extensions are supported by the CPU.
+///
+/// \return A bitmask of supported extensions, see SUPPORT_... defines.
+uint detectCPUextensions(void);
+
+/// Disables given set of instruction extensions. See SUPPORT_... defines.
+void disableExtensions(uint wDisableMask);
+
+#endif // _CPU_DETECT_H_
diff --git a/plugins/soundtouch/soundtouch/source/SoundTouch/cpu_detect_x86_gcc.cpp b/plugins/soundtouch/soundtouch/source/SoundTouch/cpu_detect_x86_gcc.cpp
new file mode 100644
index 00000000..b0d0a693
--- /dev/null
+++ b/plugins/soundtouch/soundtouch/source/SoundTouch/cpu_detect_x86_gcc.cpp
@@ -0,0 +1,135 @@
+////////////////////////////////////////////////////////////////////////////////
+///
+/// Generic version of the x86 CPU extension detection routine.
+///
+/// This file is for GNU & other non-Windows compilers, see 'cpu_detect_x86_win.cpp'
+/// for the Microsoft compiler version.
+///
+/// Author : Copyright (c) Olli Parviainen
+/// Author e-mail : oparviai 'at' iki.fi
+/// SoundTouch WWW: http://www.surina.net/soundtouch
+///
+////////////////////////////////////////////////////////////////////////////////
+//
+// Last changed : $Date: 2009-02-25 19:13:51 +0200 (Wed, 25 Feb 2009) $
+// File revision : $Revision: 4 $
+//
+// $Id: cpu_detect_x86_gcc.cpp 67 2009-02-25 17:13:51Z oparviai $
+//
+////////////////////////////////////////////////////////////////////////////////
+//
+// License :
+//
+// SoundTouch audio processing library
+// Copyright (c) Olli Parviainen
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+////////////////////////////////////////////////////////////////////////////////
+
+#include <stdexcept>
+#include <string>
+#include "cpu_detect.h"
+#include "STTypes.h"
+
+using namespace std;
+
+#include <stdio.h>
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// processor instructions extension detection routines
+//
+//////////////////////////////////////////////////////////////////////////////
+
+// Flag variable indicating whick ISA extensions are disabled (for debugging)
+static uint _dwDisabledISA = 0x00; // 0xffffffff; //<- use this to disable all extensions
+
+// Disables given set of instruction extensions. See SUPPORT_... defines.
+void disableExtensions(uint dwDisableMask)
+{
+ _dwDisabledISA = dwDisableMask;
+}
+
+
+
+/// Checks which instruction set extensions are supported by the CPU.
+uint detectCPUextensions(void)
+{
+#if (!(ALLOW_X86_OPTIMIZATIONS) || !(__GNUC__))
+
+ return 0; // always disable extensions on non-x86 platforms.
+
+#else
+ uint res = 0;
+
+ if (_dwDisabledISA == 0xffffffff) return 0;
+
+ asm volatile(
+ "\n\txor %%esi, %%esi" // clear %%esi = result register
+ // check if 'cpuid' instructions is available by toggling eflags bit 21
+
+ "\n\tpushf" // save eflags to stack
+ "\n\tmovl (%%esp), %%eax" // load eax from stack (with eflags)
+ "\n\tmovl %%eax, %%ecx" // save the original eflags values to ecx
+ "\n\txor $0x00200000, %%eax" // toggle bit 21
+ "\n\tmovl %%eax, (%%esp)" // store toggled eflags to stack
+ "\n\tpopf" // load eflags from stack
+ "\n\tpushf" // save updated eflags to stack
+ "\n\tmovl (%%esp), %%eax" // load eax from stack
+ "\n\tpopf" // pop stack to restore esp
+ "\n\txor %%edx, %%edx" // clear edx for defaulting no mmx
+ "\n\tcmp %%ecx, %%eax" // compare to original eflags values
+ "\n\tjz end" // jumps to 'end' if cpuid not present
+ // cpuid instruction available, test for presence of mmx instructions
+
+ "\n\tmovl $1, %%eax"
+ "\n\tcpuid"
+ "\n\ttest $0x00800000, %%edx"
+ "\n\tjz end" // branch if MMX not available
+
+ "\n\tor $0x01, %%esi" // otherwise add MMX support bit
+
+ "\n\ttest $0x02000000, %%edx"
+ "\n\tjz test3DNow" // branch if SSE not available
+
+ "\n\tor $0x08, %%esi" // otherwise add SSE support bit
+
+ "\n\ttest3DNow:"
+ // test for precense of AMD extensions
+ "\n\tmov $0x80000000, %%eax"
+ "\n\tcpuid"
+ "\n\tcmp $0x80000000, %%eax"
+ "\n\tjbe end" // branch if no AMD extensions detected
+
+ // test for precense of 3DNow! extension
+ "\n\tmov $0x80000001, %%eax"
+ "\n\tcpuid"
+ "\n\ttest $0x80000000, %%edx"
+ "\n\tjz end" // branch if 3DNow! not detected
+
+ "\n\tor $0x02, %%esi" // otherwise add 3DNow support bit
+
+ "\n\tend:"
+
+ "\n\tmov %%esi, %0"
+
+ : "=r" (res)
+ : /* no inputs */
+ : "%edx", "%eax", "%ecx", "%esi" );
+
+ return res & ~_dwDisabledISA;
+#endif
+}
diff --git a/plugins/soundtouch/soundtouch/source/SoundTouch/cpu_detect_x86_win.cpp b/plugins/soundtouch/soundtouch/source/SoundTouch/cpu_detect_x86_win.cpp
new file mode 100644
index 00000000..c6c54246
--- /dev/null
+++ b/plugins/soundtouch/soundtouch/source/SoundTouch/cpu_detect_x86_win.cpp
@@ -0,0 +1,129 @@
+////////////////////////////////////////////////////////////////////////////////
+///
+/// Win32 version of the x86 CPU detect routine.
+///
+/// This file is to be compiled in Windows platform with Microsoft Visual C++
+/// Compiler. Please see 'cpu_detect_x86_gcc.cpp' for the gcc compiler version
+/// for all GNU platforms.
+///
+/// Author : Copyright (c) Olli Parviainen
+/// Author e-mail : oparviai 'at' iki.fi
+/// SoundTouch WWW: http://www.surina.net/soundtouch
+///
+////////////////////////////////////////////////////////////////////////////////
+//
+// Last changed : $Date: 2009-02-13 18:22:48 +0200 (Fri, 13 Feb 2009) $
+// File revision : $Revision: 4 $
+//
+// $Id: cpu_detect_x86_win.cpp 62 2009-02-13 16:22:48Z oparviai $
+//
+////////////////////////////////////////////////////////////////////////////////
+//
+// License :
+//
+// SoundTouch audio processing library
+// Copyright (c) Olli Parviainen
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+////////////////////////////////////////////////////////////////////////////////
+
+#include "cpu_detect.h"
+
+#ifndef WIN32
+#error wrong platform - this source code file is exclusively for Win32 platform
+#endif
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// processor instructions extension detection routines
+//
+//////////////////////////////////////////////////////////////////////////////
+
+// Flag variable indicating whick ISA extensions are disabled (for debugging)
+static uint _dwDisabledISA = 0x00; // 0xffffffff; //<- use this to disable all extensions
+
+
+// Disables given set of instruction extensions. See SUPPORT_... defines.
+void disableExtensions(uint dwDisableMask)
+{
+ _dwDisabledISA = dwDisableMask;
+}
+
+
+
+/// Checks which instruction set extensions are supported by the CPU.
+uint detectCPUextensions(void)
+{
+ uint res = 0;
+
+ if (_dwDisabledISA == 0xffffffff) return 0;
+
+ _asm
+ {
+ ; check if 'cpuid' instructions is available by toggling eflags bit 21
+ ;
+ xor esi, esi ; clear esi = result register
+
+ pushfd ; save eflags to stack
+ mov eax,dword ptr [esp] ; load eax from stack (with eflags)
+ mov ecx, eax ; save the original eflags values to ecx
+ xor eax, 0x00200000 ; toggle bit 21
+ mov dword ptr [esp],eax ; store toggled eflags to stack
+ popfd ; load eflags from stack
+
+ pushfd ; save updated eflags to stack
+ mov eax,dword ptr [esp] ; load eax from stack
+ popfd ; pop stack to restore stack pointer
+
+ xor edx, edx ; clear edx for defaulting no mmx
+ cmp eax, ecx ; compare to original eflags values
+ jz end ; jumps to 'end' if cpuid not present
+
+ ; cpuid instruction available, test for presence of mmx instructions
+ mov eax, 1
+ cpuid
+ test edx, 0x00800000
+ jz end ; branch if MMX not available
+
+ or esi, SUPPORT_MMX ; otherwise add MMX support bit
+
+ test edx, 0x02000000
+ jz test3DNow ; branch if SSE not available
+
+ or esi, SUPPORT_SSE ; otherwise add SSE support bit
+
+ test3DNow:
+ ; test for precense of AMD extensions
+ mov eax, 0x80000000
+ cpuid
+ cmp eax, 0x80000000
+ jbe end ; branch if no AMD extensions detected
+
+ ; test for precense of 3DNow! extension
+ mov eax, 0x80000001
+ cpuid
+ test edx, 0x80000000
+ jz end ; branch if 3DNow! not detected
+
+ or esi, SUPPORT_3DNOW ; otherwise add 3DNow support bit
+
+ end:
+
+ mov res, esi
+ }
+
+ return res & ~_dwDisabledISA;
+}
diff --git a/plugins/soundtouch/soundtouch/source/SoundTouch/mmx_optimized.cpp b/plugins/soundtouch/soundtouch/source/SoundTouch/mmx_optimized.cpp
new file mode 100644
index 00000000..539ee57c
--- /dev/null
+++ b/plugins/soundtouch/soundtouch/source/SoundTouch/mmx_optimized.cpp
@@ -0,0 +1,320 @@
+////////////////////////////////////////////////////////////////////////////////
+///
+/// MMX optimized routines. All MMX optimized functions have been gathered into
+/// this single source code file, regardless to their class or original source
+/// code file, in order to ease porting the library to other compiler and
+/// processor platforms.
+///
+/// The MMX-optimizations are programmed using MMX compiler intrinsics that
+/// are supported both by Microsoft Visual C++ and GCC compilers, so this file
+/// should compile with both toolsets.
+///
+/// NOTICE: If using Visual Studio 6.0, you'll need to install the "Visual C++
+/// 6.0 processor pack" update to support compiler intrinsic syntax. The update
+/// is available for download at Microsoft Developers Network, see here:
+/// http://msdn.microsoft.com/en-us/vstudio/aa718349.aspx
+///
+/// Author : Copyright (c) Olli Parviainen
+/// Author e-mail : oparviai 'at' iki.fi
+/// SoundTouch WWW: http://www.surina.net/soundtouch
+///
+////////////////////////////////////////////////////////////////////////////////
+//
+// Last changed : $Date: 2009-10-31 16:53:23 +0200 (Sat, 31 Oct 2009) $
+// File revision : $Revision: 4 $
+//
+// $Id: mmx_optimized.cpp 75 2009-10-31 14:53:23Z oparviai $
+//
+////////////////////////////////////////////////////////////////////////////////
+//
+// License :
+//
+// SoundTouch audio processing library
+// Copyright (c) Olli Parviainen
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+////////////////////////////////////////////////////////////////////////////////
+
+#include "STTypes.h"
+
+#ifdef ALLOW_MMX
+// MMX routines available only with integer sample type
+
+#if !(WIN32 || __i386__ || __x86_64__)
+#error "wrong platform - this source code file is exclusively for x86 platforms"
+#endif
+
+using namespace soundtouch;
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// implementation of MMX optimized functions of class 'TDStretchMMX'
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#include "TDStretch.h"
+#include <mmintrin.h>
+#include <limits.h>
+#include <math.h>
+
+
+// Calculates cross correlation of two buffers
+long TDStretchMMX::calcCrossCorrStereo(const short *pV1, const short *pV2) const
+{
+ const __m64 *pVec1, *pVec2;
+ __m64 shifter;
+ __m64 accu, normaccu;
+ long corr, norm;
+ int i;
+
+ pVec1 = (__m64*)pV1;
+ pVec2 = (__m64*)pV2;
+
+ shifter = _m_from_int(overlapDividerBits);
+ normaccu = accu = _mm_setzero_si64();
+
+ // Process 4 parallel sets of 2 * stereo samples each during each
+ // round to improve CPU-level parallellization.
+ for (i = 0; i < overlapLength / 8; i ++)
+ {
+ __m64 temp, temp2;
+
+ // dictionary of instructions:
+ // _m_pmaddwd : 4*16bit multiply-add, resulting two 32bits = [a0*b0+a1*b1 ; a2*b2+a3*b3]
+ // _mm_add_pi32 : 2*32bit add
+ // _m_psrad : 32bit right-shift
+
+ temp = _mm_add_pi32(_mm_madd_pi16(pVec1[0], pVec2[0]),
+ _mm_madd_pi16(pVec1[1], pVec2[1]));
+ temp2 = _mm_add_pi32(_mm_madd_pi16(pVec1[0], pVec1[0]),
+ _mm_madd_pi16(pVec1[1], pVec1[1]));
+ accu = _mm_add_pi32(accu, _mm_sra_pi32(temp, shifter));
+ normaccu = _mm_add_pi32(normaccu, _mm_sra_pi32(temp2, shifter));
+
+ temp = _mm_add_pi32(_mm_madd_pi16(pVec1[2], pVec2[2]),
+ _mm_madd_pi16(pVec1[3], pVec2[3]));
+ temp2 = _mm_add_pi32(_mm_madd_pi16(pVec1[2], pVec1[2]),
+ _mm_madd_pi16(pVec1[3], pVec1[3]));
+ accu = _mm_add_pi32(accu, _mm_sra_pi32(temp, shifter));
+ normaccu = _mm_add_pi32(normaccu, _mm_sra_pi32(temp2, shifter));
+
+ pVec1 += 4;
+ pVec2 += 4;
+ }
+
+ // copy hi-dword of mm0 to lo-dword of mm1, then sum mmo+mm1
+ // and finally store the result into the variable "corr"
+
+ accu = _mm_add_pi32(accu, _mm_srli_si64(accu, 32));
+ corr = _m_to_int(accu);
+
+ normaccu = _mm_add_pi32(normaccu, _mm_srli_si64(normaccu, 32));
+ norm = _m_to_int(normaccu);
+
+ // Clear MMS state
+ _m_empty();
+
+ // Normalize result by dividing by sqrt(norm) - this step is easiest
+ // done using floating point operation
+ if (norm == 0) norm = 1; // to avoid div by zero
+ return (long)((double)corr * USHRT_MAX / sqrt((double)norm));
+ // Note: Warning about the missing EMMS instruction is harmless
+ // as it'll be called elsewhere.
+}
+
+
+
+void TDStretchMMX::clearCrossCorrState()
+{
+ // Clear MMS state
+ _m_empty();
+ //_asm EMMS;
+}
+
+
+
+// MMX-optimized version of the function overlapStereo
+void TDStretchMMX::overlapStereo(short *output, const short *input) const
+{
+ const __m64 *pVinput, *pVMidBuf;
+ __m64 *pVdest;
+ __m64 mix1, mix2, adder, shifter;
+ int i;
+
+ pVinput = (const __m64*)input;
+ pVMidBuf = (const __m64*)pMidBuffer;
+ pVdest = (__m64*)output;
+
+ // mix1 = mixer values for 1st stereo sample
+ // mix1 = mixer values for 2nd stereo sample
+ // adder = adder for updating mixer values after each round
+
+ mix1 = _mm_set_pi16(0, overlapLength, 0, overlapLength);
+ adder = _mm_set_pi16(1, -1, 1, -1);
+ mix2 = _mm_add_pi16(mix1, adder);
+ adder = _mm_add_pi16(adder, adder);
+
+ // Overlaplength-division by shifter. "+1" is to account for "-1" deduced in
+ // overlapDividerBits calculation earlier.
+ shifter = _m_from_int(overlapDividerBits + 1);
+
+ for (i = 0; i < overlapLength / 4; i ++)
+ {
+ __m64 temp1, temp2;
+
+ // load & shuffle data so that input & mixbuffer data samples are paired
+ temp1 = _mm_unpacklo_pi16(pVMidBuf[0], pVinput[0]); // = i0l m0l i0r m0r
+ temp2 = _mm_unpackhi_pi16(pVMidBuf[0], pVinput[0]); // = i1l m1l i1r m1r
+
+ // temp = (temp .* mix) >> shifter
+ temp1 = _mm_sra_pi32(_mm_madd_pi16(temp1, mix1), shifter);
+ temp2 = _mm_sra_pi32(_mm_madd_pi16(temp2, mix2), shifter);
+ pVdest[0] = _mm_packs_pi32(temp1, temp2); // pack 2*2*32bit => 4*16bit
+
+ // update mix += adder
+ mix1 = _mm_add_pi16(mix1, adder);
+ mix2 = _mm_add_pi16(mix2, adder);
+
+ // --- second round begins here ---
+
+ // load & shuffle data so that input & mixbuffer data samples are paired
+ temp1 = _mm_unpacklo_pi16(pVMidBuf[1], pVinput[1]); // = i2l m2l i2r m2r
+ temp2 = _mm_unpackhi_pi16(pVMidBuf[1], pVinput[1]); // = i3l m3l i3r m3r
+
+ // temp = (temp .* mix) >> shifter
+ temp1 = _mm_sra_pi32(_mm_madd_pi16(temp1, mix1), shifter);
+ temp2 = _mm_sra_pi32(_mm_madd_pi16(temp2, mix2), shifter);
+ pVdest[1] = _mm_packs_pi32(temp1, temp2); // pack 2*2*32bit => 4*16bit
+
+ // update mix += adder
+ mix1 = _mm_add_pi16(mix1, adder);
+ mix2 = _mm_add_pi16(mix2, adder);
+
+ pVinput += 2;
+ pVMidBuf += 2;
+ pVdest += 2;
+ }
+
+ _m_empty(); // clear MMS state
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// implementation of MMX optimized functions of class 'FIRFilter'
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#include "FIRFilter.h"
+
+
+FIRFilterMMX::FIRFilterMMX() : FIRFilter()
+{
+ filterCoeffsUnalign = NULL;
+}
+
+
+FIRFilterMMX::~FIRFilterMMX()
+{
+ delete[] filterCoeffsUnalign;
+}
+
+
+// (overloaded) Calculates filter coefficients for MMX routine
+void FIRFilterMMX::setCoefficients(const short *coeffs, uint newLength, uint uResultDivFactor)
+{
+ uint i;
+ FIRFilter::setCoefficients(coeffs, newLength, uResultDivFactor);
+
+ // Ensure that filter coeffs array is aligned to 16-byte boundary
+ delete[] filterCoeffsUnalign;
+ filterCoeffsUnalign = new short[2 * newLength + 8];
+ filterCoeffsAlign = (short *)(((ulong)filterCoeffsUnalign + 15) & -16);
+
+ // rearrange the filter coefficients for mmx routines
+ for (i = 0;i < length; i += 4)
+ {
+ filterCoeffsAlign[2 * i + 0] = coeffs[i + 0];
+ filterCoeffsAlign[2 * i + 1] = coeffs[i + 2];
+ filterCoeffsAlign[2 * i + 2] = coeffs[i + 0];
+ filterCoeffsAlign[2 * i + 3] = coeffs[i + 2];
+
+ filterCoeffsAlign[2 * i + 4] = coeffs[i + 1];
+ filterCoeffsAlign[2 * i + 5] = coeffs[i + 3];
+ filterCoeffsAlign[2 * i + 6] = coeffs[i + 1];
+ filterCoeffsAlign[2 * i + 7] = coeffs[i + 3];
+ }
+}
+
+
+
+// mmx-optimized version of the filter routine for stereo sound
+uint FIRFilterMMX::evaluateFilterStereo(short *dest, const short *src, uint numSamples) const
+{
+ // Create stack copies of the needed member variables for asm routines :
+ uint i, j;
+ __m64 *pVdest = (__m64*)dest;
+
+ if (length < 2) return 0;
+
+ for (i = 0; i < (numSamples - length) / 2; i ++)
+ {
+ __m64 accu1;
+ __m64 accu2;
+ const __m64 *pVsrc = (const __m64*)src;
+ const __m64 *pVfilter = (const __m64*)filterCoeffsAlign;
+
+ accu1 = accu2 = _mm_setzero_si64();
+ for (j = 0; j < lengthDiv8 * 2; j ++)
+ {
+ __m64 temp1, temp2;
+
+ temp1 = _mm_unpacklo_pi16(pVsrc[0], pVsrc[1]); // = l2 l0 r2 r0
+ temp2 = _mm_unpackhi_pi16(pVsrc[0], pVsrc[1]); // = l3 l1 r3 r1
+
+ accu1 = _mm_add_pi32(accu1, _mm_madd_pi16(temp1, pVfilter[0])); // += l2*f2+l0*f0 r2*f2+r0*f0
+ accu1 = _mm_add_pi32(accu1, _mm_madd_pi16(temp2, pVfilter[1])); // += l3*f3+l1*f1 r3*f3+r1*f1
+
+ temp1 = _mm_unpacklo_pi16(pVsrc[1], pVsrc[2]); // = l4 l2 r4 r2
+
+ accu2 = _mm_add_pi32(accu2, _mm_madd_pi16(temp2, pVfilter[0])); // += l3*f2+l1*f0 r3*f2+r1*f0
+ accu2 = _mm_add_pi32(accu2, _mm_madd_pi16(temp1, pVfilter[1])); // += l4*f3+l2*f1 r4*f3+r2*f1
+
+ // accu1 += l2*f2+l0*f0 r2*f2+r0*f0
+ // += l3*f3+l1*f1 r3*f3+r1*f1
+
+ // accu2 += l3*f2+l1*f0 r3*f2+r1*f0
+ // l4*f3+l2*f1 r4*f3+r2*f1
+
+ pVfilter += 2;
+ pVsrc += 2;
+ }
+ // accu >>= resultDivFactor
+ accu1 = _mm_srai_pi32(accu1, resultDivFactor);
+ accu2 = _mm_srai_pi32(accu2, resultDivFactor);
+
+ // pack 2*2*32bits => 4*16 bits
+ pVdest[0] = _mm_packs_pi32(accu1, accu2);
+ src += 4;
+ pVdest ++;
+ }
+
+ _m_empty(); // clear emms state
+
+ return (numSamples & 0xfffffffe) - length;
+}
+
+#endif // ALLOW_MMX
diff --git a/plugins/soundtouch/soundtouch/source/SoundTouch/sse_optimized.cpp b/plugins/soundtouch/soundtouch/source/SoundTouch/sse_optimized.cpp
new file mode 100644
index 00000000..7659be68
--- /dev/null
+++ b/plugins/soundtouch/soundtouch/source/SoundTouch/sse_optimized.cpp
@@ -0,0 +1,510 @@
+////////////////////////////////////////////////////////////////////////////////
+///
+/// SSE optimized routines for Pentium-III, Athlon-XP and later CPUs. All SSE
+/// optimized functions have been gathered into this single source
+/// code file, regardless to their class or original source code file, in order
+/// to ease porting the library to other compiler and processor platforms.
+///
+/// The SSE-optimizations are programmed using SSE compiler intrinsics that
+/// are supported both by Microsoft Visual C++ and GCC compilers, so this file
+/// should compile with both toolsets.
+///
+/// NOTICE: If using Visual Studio 6.0, you'll need to install the "Visual C++
+/// 6.0 processor pack" update to support SSE instruction set. The update is
+/// available for download at Microsoft Developers Network, see here:
+/// http://msdn.microsoft.com/en-us/vstudio/aa718349.aspx
+///
+/// If the above URL is expired or removed, go to "http://msdn.microsoft.com" and
+/// perform a search with keywords "processor pack".
+///
+/// Author : Copyright (c) Olli Parviainen
+/// Author e-mail : oparviai 'at' iki.fi
+/// SoundTouch WWW: http://www.surina.net/soundtouch
+///
+////////////////////////////////////////////////////////////////////////////////
+//
+// Last changed : $Date: 2009-12-28 22:32:57 +0200 (Mon, 28 Dec 2009) $
+// File revision : $Revision: 4 $
+//
+// $Id: sse_optimized.cpp 80 2009-12-28 20:32:57Z oparviai $
+//
+////////////////////////////////////////////////////////////////////////////////
+//
+// License :
+//
+// SoundTouch audio processing library
+// Copyright (c) Olli Parviainen
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+////////////////////////////////////////////////////////////////////////////////
+
+#include "cpu_detect.h"
+#include "STTypes.h"
+
+using namespace soundtouch;
+
+#ifdef ALLOW_SSE
+
+// SSE routines available only with float sample type
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// implementation of SSE optimized functions of class 'TDStretchSSE'
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#include "TDStretch.h"
+#include <xmmintrin.h>
+#include <math.h>
+
+// Calculates cross correlation of two buffers
+double TDStretchSSE::calcCrossCorrStereo(const float *pV1, const float *pV2) const
+{
+ int i;
+ const float *pVec1;
+ const __m128 *pVec2;
+ __m128 vSum, vNorm;
+
+ // Note. It means a major slow-down if the routine needs to tolerate
+ // unaligned __m128 memory accesses. It's way faster if we can skip
+ // unaligned slots and use _mm_load_ps instruction instead of _mm_loadu_ps.
+ // This can mean up to ~ 10-fold difference (incl. part of which is
+ // due to skipping every second round for stereo sound though).
+ //
+ // Compile-time define ALLOW_NONEXACT_SIMD_OPTIMIZATION is provided
+ // for choosing if this little cheating is allowed.
+
+#ifdef ALLOW_NONEXACT_SIMD_OPTIMIZATION
+ // Little cheating allowed, return valid correlation only for
+ // aligned locations, meaning every second round for stereo sound.
+
+ #define _MM_LOAD _mm_load_ps
+
+ if (((ulong)pV1) & 15) return -1e50; // skip unaligned locations
+
+#else
+ // No cheating allowed, use unaligned load & take the resulting
+ // performance hit.
+ #define _MM_LOAD _mm_loadu_ps
+#endif
+
+ // ensure overlapLength is divisible by 8
+ assert((overlapLength % 8) == 0);
+
+ // Calculates the cross-correlation value between 'pV1' and 'pV2' vectors
+ // Note: pV2 _must_ be aligned to 16-bit boundary, pV1 need not.
+ pVec1 = (const float*)pV1;
+ pVec2 = (const __m128*)pV2;
+ vSum = vNorm = _mm_setzero_ps();
+
+ // Unroll the loop by factor of 4 * 4 operations
+ for (i = 0; i < overlapLength / 8; i ++)
+ {
+ __m128 vTemp;
+ // vSum += pV1[0..3] * pV2[0..3]
+ vTemp = _MM_LOAD(pVec1);
+ vSum = _mm_add_ps(vSum, _mm_mul_ps(vTemp ,pVec2[0]));
+ vNorm = _mm_add_ps(vNorm, _mm_mul_ps(vTemp ,vTemp));
+
+ // vSum += pV1[4..7] * pV2[4..7]
+ vTemp = _MM_LOAD(pVec1 + 4);
+ vSum = _mm_add_ps(vSum, _mm_mul_ps(vTemp, pVec2[1]));
+ vNorm = _mm_add_ps(vNorm, _mm_mul_ps(vTemp ,vTemp));
+
+ // vSum += pV1[8..11] * pV2[8..11]
+ vTemp = _MM_LOAD(pVec1 + 8);
+ vSum = _mm_add_ps(vSum, _mm_mul_ps(vTemp, pVec2[2]));
+ vNorm = _mm_add_ps(vNorm, _mm_mul_ps(vTemp ,vTemp));
+
+ // vSum += pV1[12..15] * pV2[12..15]
+ vTemp = _MM_LOAD(pVec1 + 12);
+ vSum = _mm_add_ps(vSum, _mm_mul_ps(vTemp, pVec2[3]));
+ vNorm = _mm_add_ps(vNorm, _mm_mul_ps(vTemp ,vTemp));
+
+ pVec1 += 16;
+ pVec2 += 4;
+ }
+
+ // return value = vSum[0] + vSum[1] + vSum[2] + vSum[3]
+ float *pvNorm = (float*)&vNorm;
+ double norm = sqrt(pvNorm[0] + pvNorm[1] + pvNorm[2] + pvNorm[3]);
+ if (norm < 1e-9) norm = 1.0; // to avoid div by zero
+
+ float *pvSum = (float*)&vSum;
+ return (double)(pvSum[0] + pvSum[1] + pvSum[2] + pvSum[3]) / norm;
+
+ /* This is approximately corresponding routine in C-language yet without normalization:
+ double corr, norm;
+ uint i;
+
+ // Calculates the cross-correlation value between 'pV1' and 'pV2' vectors
+ corr = norm = 0.0;
+ for (i = 0; i < overlapLength / 8; i ++)
+ {
+ corr += pV1[0] * pV2[0] +
+ pV1[1] * pV2[1] +
+ pV1[2] * pV2[2] +
+ pV1[3] * pV2[3] +
+ pV1[4] * pV2[4] +
+ pV1[5] * pV2[5] +
+ pV1[6] * pV2[6] +
+ pV1[7] * pV2[7] +
+ pV1[8] * pV2[8] +
+ pV1[9] * pV2[9] +
+ pV1[10] * pV2[10] +
+ pV1[11] * pV2[11] +
+ pV1[12] * pV2[12] +
+ pV1[13] * pV2[13] +
+ pV1[14] * pV2[14] +
+ pV1[15] * pV2[15];
+
+ for (j = 0; j < 15; j ++) norm += pV1[j] * pV1[j];
+
+ pV1 += 16;
+ pV2 += 16;
+ }
+ return corr / sqrt(norm);
+ */
+
+ /* This is a bit outdated, corresponding routine in assembler. This may be teeny-weeny bit
+ faster than intrinsic version, but more difficult to maintain & get compiled on multiple
+ platforms.
+
+ uint overlapLengthLocal = overlapLength;
+ float corr;
+
+ _asm
+ {
+ // Very important note: data in 'pV2' _must_ be aligned to
+ // 16-byte boundary!
+
+ // give prefetch hints to CPU of what data are to be needed soonish
+ // give more aggressive hints on pV1 as that changes while pV2 stays
+ // same between runs
+ prefetcht0 [pV1]
+ prefetcht0 [pV2]
+ prefetcht0 [pV1 + 32]
+
+ mov eax, dword ptr pV1
+ mov ebx, dword ptr pV2
+
+ xorps xmm0, xmm0
+
+ mov ecx, overlapLengthLocal
+ shr ecx, 3 // div by eight
+
+ loop1:
+ prefetcht0 [eax + 64] // give a prefetch hint to CPU what data are to be needed soonish
+ prefetcht0 [ebx + 32] // give a prefetch hint to CPU what data are to be needed soonish
+ movups xmm1, [eax]
+ mulps xmm1, [ebx]
+ addps xmm0, xmm1
+
+ movups xmm2, [eax + 16]
+ mulps xmm2, [ebx + 16]
+ addps xmm0, xmm2
+
+ prefetcht0 [eax + 96] // give a prefetch hint to CPU what data are to be needed soonish
+ prefetcht0 [ebx + 64] // give a prefetch hint to CPU what data are to be needed soonish
+
+ movups xmm3, [eax + 32]
+ mulps xmm3, [ebx + 32]
+ addps xmm0, xmm3
+
+ movups xmm4, [eax + 48]
+ mulps xmm4, [ebx + 48]
+ addps xmm0, xmm4
+
+ add eax, 64
+ add ebx, 64
+
+ dec ecx
+ jnz loop1
+
+ // add the four floats of xmm0 together and return the result.
+
+ movhlps xmm1, xmm0 // move 3 & 4 of xmm0 to 1 & 2 of xmm1
+ addps xmm1, xmm0
+ movaps xmm2, xmm1
+ shufps xmm2, xmm2, 0x01 // move 2 of xmm2 as 1 of xmm2
+ addss xmm2, xmm1
+ movss corr, xmm2
+ }
+
+ return (double)corr;
+ */
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// implementation of SSE optimized functions of class 'FIRFilter'
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#include "FIRFilter.h"
+
+FIRFilterSSE::FIRFilterSSE() : FIRFilter()
+{
+ filterCoeffsAlign = NULL;
+ filterCoeffsUnalign = NULL;
+}
+
+
+FIRFilterSSE::~FIRFilterSSE()
+{
+ delete[] filterCoeffsUnalign;
+ filterCoeffsAlign = NULL;
+ filterCoeffsUnalign = NULL;
+}
+
+
+// (overloaded) Calculates filter coefficients for SSE routine
+void FIRFilterSSE::setCoefficients(const float *coeffs, uint newLength, uint uResultDivFactor)
+{
+ uint i;
+ float fDivider;
+
+ FIRFilter::setCoefficients(coeffs, newLength, uResultDivFactor);
+
+ // Scale the filter coefficients so that it won't be necessary to scale the filtering result
+ // also rearrange coefficients suitably for 3DNow!
+ // Ensure that filter coeffs array is aligned to 16-byte boundary
+ delete[] filterCoeffsUnalign;
+ filterCoeffsUnalign = new float[2 * newLength + 4];
+ filterCoeffsAlign = (float *)(((unsigned long)filterCoeffsUnalign + 15) & (ulong)-16);
+
+ fDivider = (float)resultDivider;
+
+ // rearrange the filter coefficients for mmx routines
+ for (i = 0; i < newLength; i ++)
+ {
+ filterCoeffsAlign[2 * i + 0] =
+ filterCoeffsAlign[2 * i + 1] = coeffs[i + 0] / fDivider;
+ }
+}
+
+
+
+// SSE-optimized version of the filter routine for stereo sound
+uint FIRFilterSSE::evaluateFilterStereo(float *dest, const float *source, uint numSamples) const
+{
+ int count = (int)((numSamples - length) & (uint)-2);
+ int j;
+
+ assert(count % 2 == 0);
+
+ if (count < 2) return 0;
+
+ assert(source != NULL);
+ assert(dest != NULL);
+ assert((length % 8) == 0);
+ assert(filterCoeffsAlign != NULL);
+ assert(((ulong)filterCoeffsAlign) % 16 == 0);
+
+ // filter is evaluated for two stereo samples with each iteration, thus use of 'j += 2'
+ for (j = 0; j < count; j += 2)
+ {
+ const float *pSrc;
+ const __m128 *pFil;
+ __m128 sum1, sum2;
+ uint i;
+
+ pSrc = (const float*)source; // source audio data
+ pFil = (const __m128*)filterCoeffsAlign; // filter coefficients. NOTE: Assumes coefficients
+ // are aligned to 16-byte boundary
+ sum1 = sum2 = _mm_setzero_ps();
+
+ for (i = 0; i < length / 8; i ++)
+ {
+ // Unroll loop for efficiency & calculate filter for 2*2 stereo samples
+ // at each pass
+
+ // sum1 is accu for 2*2 filtered stereo sound data at the primary sound data offset
+ // sum2 is accu for 2*2 filtered stereo sound data for the next sound sample offset.
+
+ sum1 = _mm_add_ps(sum1, _mm_mul_ps(_mm_loadu_ps(pSrc) , pFil[0]));
+ sum2 = _mm_add_ps(sum2, _mm_mul_ps(_mm_loadu_ps(pSrc + 2), pFil[0]));
+
+ sum1 = _mm_add_ps(sum1, _mm_mul_ps(_mm_loadu_ps(pSrc + 4), pFil[1]));
+ sum2 = _mm_add_ps(sum2, _mm_mul_ps(_mm_loadu_ps(pSrc + 6), pFil[1]));
+
+ sum1 = _mm_add_ps(sum1, _mm_mul_ps(_mm_loadu_ps(pSrc + 8) , pFil[2]));
+ sum2 = _mm_add_ps(sum2, _mm_mul_ps(_mm_loadu_ps(pSrc + 10), pFil[2]));
+
+ sum1 = _mm_add_ps(sum1, _mm_mul_ps(_mm_loadu_ps(pSrc + 12), pFil[3]));
+ sum2 = _mm_add_ps(sum2, _mm_mul_ps(_mm_loadu_ps(pSrc + 14), pFil[3]));
+
+ pSrc += 16;
+ pFil += 4;
+ }
+
+ // Now sum1 and sum2 both have a filtered 2-channel sample each, but we still need
+ // to sum the two hi- and lo-floats of these registers together.
+
+ // post-shuffle & add the filtered values and store to dest.
+ _mm_storeu_ps(dest, _mm_add_ps(
+ _mm_shuffle_ps(sum1, sum2, _MM_SHUFFLE(1,0,3,2)), // s2_1 s2_0 s1_3 s1_2
+ _mm_shuffle_ps(sum1, sum2, _MM_SHUFFLE(3,2,1,0)) // s2_3 s2_2 s1_1 s1_0
+ ));
+ source += 4;
+ dest += 4;
+ }
+
+ // Ideas for further improvement:
+ // 1. If it could be guaranteed that 'source' were always aligned to 16-byte
+ // boundary, a faster aligned '_mm_load_ps' instruction could be used.
+ // 2. If it could be guaranteed that 'dest' were always aligned to 16-byte
+ // boundary, a faster '_mm_store_ps' instruction could be used.
+
+ return (uint)count;
+
+ /* original routine in C-language. please notice the C-version has differently
+ organized coefficients though.
+ double suml1, suml2;
+ double sumr1, sumr2;
+ uint i, j;
+
+ for (j = 0; j < count; j += 2)
+ {
+ const float *ptr;
+ const float *pFil;
+
+ suml1 = sumr1 = 0.0;
+ suml2 = sumr2 = 0.0;
+ ptr = src;
+ pFil = filterCoeffs;
+ for (i = 0; i < lengthLocal; i ++)
+ {
+ // unroll loop for efficiency.
+
+ suml1 += ptr[0] * pFil[0] +
+ ptr[2] * pFil[2] +
+ ptr[4] * pFil[4] +
+ ptr[6] * pFil[6];
+
+ sumr1 += ptr[1] * pFil[1] +
+ ptr[3] * pFil[3] +
+ ptr[5] * pFil[5] +
+ ptr[7] * pFil[7];
+
+ suml2 += ptr[8] * pFil[0] +
+ ptr[10] * pFil[2] +
+ ptr[12] * pFil[4] +
+ ptr[14] * pFil[6];
+
+ sumr2 += ptr[9] * pFil[1] +
+ ptr[11] * pFil[3] +
+ ptr[13] * pFil[5] +
+ ptr[15] * pFil[7];
+
+ ptr += 16;
+ pFil += 8;
+ }
+ dest[0] = (float)suml1;
+ dest[1] = (float)sumr1;
+ dest[2] = (float)suml2;
+ dest[3] = (float)sumr2;
+
+ src += 4;
+ dest += 4;
+ }
+ */
+
+
+ /* Similar routine in assembly, again obsoleted due to maintainability
+ _asm
+ {
+ // Very important note: data in 'src' _must_ be aligned to
+ // 16-byte boundary!
+ mov edx, count
+ mov ebx, dword ptr src
+ mov eax, dword ptr dest
+ shr edx, 1
+
+ loop1:
+ // "outer loop" : during each round 2*2 output samples are calculated
+
+ // give prefetch hints to CPU of what data are to be needed soonish
+ prefetcht0 [ebx]
+ prefetcht0 [filterCoeffsLocal]
+
+ mov esi, ebx
+ mov edi, filterCoeffsLocal
+ xorps xmm0, xmm0
+ xorps xmm1, xmm1
+ mov ecx, lengthLocal
+
+ loop2:
+ // "inner loop" : during each round eight FIR filter taps are evaluated for 2*2 samples
+ prefetcht0 [esi + 32] // give a prefetch hint to CPU what data are to be needed soonish
+ prefetcht0 [edi + 32] // give a prefetch hint to CPU what data are to be needed soonish
+
+ movups xmm2, [esi] // possibly unaligned load
+ movups xmm3, [esi + 8] // possibly unaligned load
+ mulps xmm2, [edi]
+ mulps xmm3, [edi]
+ addps xmm0, xmm2
+ addps xmm1, xmm3
+
+ movups xmm4, [esi + 16] // possibly unaligned load
+ movups xmm5, [esi + 24] // possibly unaligned load
+ mulps xmm4, [edi + 16]
+ mulps xmm5, [edi + 16]
+ addps xmm0, xmm4
+ addps xmm1, xmm5
+
+ prefetcht0 [esi + 64] // give a prefetch hint to CPU what data are to be needed soonish
+ prefetcht0 [edi + 64] // give a prefetch hint to CPU what data are to be needed soonish
+
+ movups xmm6, [esi + 32] // possibly unaligned load
+ movups xmm7, [esi + 40] // possibly unaligned load
+ mulps xmm6, [edi + 32]
+ mulps xmm7, [edi + 32]
+ addps xmm0, xmm6
+ addps xmm1, xmm7
+
+ movups xmm4, [esi + 48] // possibly unaligned load
+ movups xmm5, [esi + 56] // possibly unaligned load
+ mulps xmm4, [edi + 48]
+ mulps xmm5, [edi + 48]
+ addps xmm0, xmm4
+ addps xmm1, xmm5
+
+ add esi, 64
+ add edi, 64
+ dec ecx
+ jnz loop2
+
+ // Now xmm0 and xmm1 both have a filtered 2-channel sample each, but we still need
+ // to sum the two hi- and lo-floats of these registers together.
+
+ movhlps xmm2, xmm0 // xmm2 = xmm2_3 xmm2_2 xmm0_3 xmm0_2
+ movlhps xmm2, xmm1 // xmm2 = xmm1_1 xmm1_0 xmm0_3 xmm0_2
+ shufps xmm0, xmm1, 0xe4 // xmm0 = xmm1_3 xmm1_2 xmm0_1 xmm0_0
+ addps xmm0, xmm2
+
+ movaps [eax], xmm0
+ add ebx, 16
+ add eax, 16
+
+ dec edx
+ jnz loop1
+ }
+ */
+}
+
+#endif // ALLOW_SSE
diff --git a/plugins/soundtouch/st.cpp b/plugins/soundtouch/st.cpp
new file mode 100644
index 00000000..458a5b44
--- /dev/null
+++ b/plugins/soundtouch/st.cpp
@@ -0,0 +1,112 @@
+/*
+ DeaDBeeF - ultimate music player for GNU/Linux systems with X11
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+#include <SoundTouch.h>
+#include "st.h"
+
+using namespace soundtouch;
+
+void*
+st_alloc (void) {
+ return new SoundTouch ();
+}
+
+void
+st_free (void *st) {
+ delete (SoundTouch *)st;
+}
+
+void
+st_set_rate (void *st, float r) {
+ ((SoundTouch *)st)->setRate (r);
+}
+
+void
+st_set_tempo (void *st, float t) {
+ ((SoundTouch *)st)->setTempo (t);
+}
+
+void
+st_set_rate_change (void *st, float r) {
+ ((SoundTouch *)st)->setRateChange (r);
+}
+
+void
+st_set_tempo_change (void *st, float t) {
+ ((SoundTouch *)st)->setTempoChange (t);
+}
+
+void
+st_set_pitch (void *st, float p) {
+ ((SoundTouch *)st)->setPitch (p);
+}
+
+void
+st_set_pitch_octaves (void *st, float po) {
+ ((SoundTouch *)st)->setPitchOctaves (po);
+}
+
+void
+st_set_pitch_semi_tones (void *st, float p) {
+ ((SoundTouch *)st)->setPitchSemiTones (p);
+}
+
+void
+st_set_channels (void *st, int c) {
+ ((SoundTouch *)st)->setChannels (c);
+}
+
+void
+st_set_sample_rate (void *st, int r) {
+ ((SoundTouch *)st)->setSampleRate (r);
+}
+
+void
+st_flush (void *st) {
+ ((SoundTouch *)st)->flush ();
+}
+
+void
+st_put_samples (void *st, float *samples, int nsamples) {
+ ((SoundTouch *)st)->putSamples (samples, nsamples);
+}
+
+void
+st_clear (void *st) {
+ ((SoundTouch *)st)->clear ();
+}
+
+void
+st_set_setting (void *st, int id, int value) {
+ ((SoundTouch *)st)->setSetting (id, value);
+}
+
+int
+st_get_setting (void *st, int id) {
+ return ((SoundTouch *)st)->getSetting (id);
+}
+
+unsigned int
+st_num_unprocessed_samples (void *st) {
+ return ((SoundTouch *)st)->numUnprocessedSamples ();
+}
+
+unsigned int
+st_receive_samples (void *st, float *out, unsigned int max_samples) {
+ return ((SoundTouch *)st)->receiveSamples (out, max_samples);
+}
diff --git a/plugins/soundtouch/st.h b/plugins/soundtouch/st.h
new file mode 100644
index 00000000..ae1f4f05
--- /dev/null
+++ b/plugins/soundtouch/st.h
@@ -0,0 +1,115 @@
+/*
+ DeaDBeeF - ultimate music player for GNU/Linux systems with X11
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+#ifndef __ST_H
+#define __ST_H
+
+//////////////////////////////////
+// C-wrapper for soundtouch class
+
+/// Enable/disable anti-alias filter in pitch transposer (0 = disable)
+#define SETTING_USE_AA_FILTER 0
+
+/// Pitch transposer anti-alias filter length (8 .. 128 taps, default = 32)
+#define SETTING_AA_FILTER_LENGTH 1
+
+/// Enable/disable quick seeking algorithm in tempo changer routine
+/// (enabling quick seeking lowers CPU utilization but causes a minor sound
+/// quality compromising)
+#define SETTING_USE_QUICKSEEK 2
+
+/// Time-stretch algorithm single processing sequence length in milliseconds. This determines
+/// to how long sequences the original sound is chopped in the time-stretch algorithm.
+/// See "STTypes.h" or README for more information.
+#define SETTING_SEQUENCE_MS 3
+
+/// Time-stretch algorithm seeking window length in milliseconds for algorithm that finds the
+/// best possible overlapping location. This determines from how wide window the algorithm
+/// may look for an optimal joining location when mixing the sound sequences back together.
+/// See "STTypes.h" or README for more information.
+#define SETTING_SEEKWINDOW_MS 4
+
+/// Time-stretch algorithm overlap length in milliseconds. When the chopped sound sequences
+/// are mixed back together, to form a continuous sound stream, this parameter defines over
+/// how long period the two consecutive sequences are let to overlap each other.
+/// See "STTypes.h" or README for more information.
+#define SETTING_OVERLAP_MS 5
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void*
+st_alloc (void);
+
+void
+st_free (void *st);
+
+void
+st_set_rate (void *st, float r);
+
+void
+st_set_tempo (void *st, float t);
+
+void
+st_set_rate_change (void *st, float r);
+
+void
+st_set_tempo_change (void *st, float t);
+
+void
+st_set_pitch (void *st, float p);
+
+void
+st_set_pitch_octaves (void *st, float po);
+
+void
+st_set_pitch_semi_tones (void *st, float p);
+
+void
+st_set_channels (void *st, int c);
+
+void
+st_set_sample_rate (void *st, int r);
+
+void
+st_flush (void *st);
+
+void
+st_put_samples (void *st, float *samples, int nsamples);
+
+void
+st_clear (void *st);
+
+void
+st_set_setting (void *st, int id, int value);
+
+int
+st_get_setting (void *st, int id);
+
+unsigned int
+st_num_unprocessed_samples (void *st);
+
+unsigned int
+st_receive_samples (void *st, float *out, unsigned int max_samples);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/plugins/supereq/Equ.cpp b/plugins/supereq/Equ.cpp
index f53b99d1..0aff4f8a 100644
--- a/plugins/supereq/Equ.cpp
+++ b/plugins/supereq/Equ.cpp
@@ -1,37 +1,92 @@
+/*
+ DeaDBeeF - ultimate music player for GNU/Linux systems with X11
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
+ Original SuperEQ code (C) Naoki Shibata <shibatch@users.sf.net>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <assert.h>
#include "paramlist.hpp"
+#include "Equ.h"
+
+int _Unwind_Resume_or_Rethrow;
+int _Unwind_RaiseException;
+int _Unwind_GetLanguageSpecificData;
+int _Unwind_Resume;
+int _Unwind_DeleteException;
+int _Unwind_GetTextRelBase;
+int _Unwind_SetIP;
+int _Unwind_GetDataRelBase;
+int _Unwind_GetRegionStart;
+int _Unwind_SetGR;
+int _Unwind_GetIPInfo;
+
+#ifdef USE_OOURA
+extern "C" void rdft(int, int, REAL *, int *, REAL *);
+void rfft(int n,int isign,REAL *x)
+{
+ static int ipsize = 0,wsize=0;
+ static int *ip = NULL;
+ static REAL *w = NULL;
+ int newipsize,newwsize;
+ if (n == 0) {
+ free(ip); ip = NULL; ipsize = 0;
+ free(w); w = NULL; wsize = 0;
+ return;
+ }
-typedef float REAL;
-void rfft(int n,int isign,REAL x[]);
+ n = 1 << n;
-#define M 15
-#define PI 3.1415926535897932384626433832795
+ newipsize = 2+sqrt(n/2);
+ if (newipsize > ipsize) {
+ ipsize = newipsize;
+ ip = (int *)realloc(ip,sizeof(int)*ipsize);
+ ip[0] = 0;
+ }
-#define RINT(x) ((x) >= 0 ? ((int)((x) + 0.5)) : ((int)((x) - 0.5)))
+ newwsize = n/2;
+ if (newwsize > wsize) {
+ wsize = newwsize;
+ w = (REAL *)realloc(w,sizeof(REAL)*wsize);
+ }
-#define DITHERLEN 65536
+ rdft(n,isign,x,ip,w);
+}
+#elif defined(USE_FFMPEG) || defined(USE_SHIBATCH)
+extern "C" void rfft(int n,int isign,REAL *x);
+#endif
-// play -c 2 -r 44100 -fs -sw
+#if defined(USE_SHIBATCH)
+extern "C" {
+#include "SIMDBase.h"
+}
+#endif
+
+
+#define PI 3.1415926535897932384626433832795
+
+#define DITHERLEN 65536
+#define M 15
static REAL fact[M+1];
static REAL aa = 96;
-static REAL iza;
-static REAL *lires,*lires1,*lires2,*rires,*rires1,*rires2,*irest;
-static REAL *fsamples;
-static REAL *ditherbuf;
-static int ditherptr = 0;
-static volatile int chg_ires,cur_ires;
-static int winlen,winlenbit,tabsize,nbufsamples;
-static short *inbuf;
-static REAL *outbuf;
-static int maxamp;
-int enable = 1, dither = 0;
-
-#define NCH 2
+static REAL iza = 0;
#define NBANDS 17
static REAL bands[] = {
@@ -62,49 +117,75 @@ static REAL izero(REAL x)
return ret;
}
-extern "C" void equ_init(int wb)
+void *equ_malloc (int size) {
+#ifdef USE_SHIBATCH
+ return SIMDBase_alignedMalloc (size);
+#else
+ return malloc (size);
+#endif
+}
+
+void equ_free (void *mem) {
+#ifdef USE_SHIBATCH
+ SIMDBase_alignedFree (mem);
+#else
+ free (mem);
+#endif
+}
+
+extern "C" void equ_init(SuperEqState *state, int wb, int channels)
{
int i,j;
- if (lires1 != NULL) free(lires1);
- if (lires2 != NULL) free(lires2);
- if (rires1 != NULL) free(rires1);
- if (rires2 != NULL) free(rires2);
- if (irest != NULL) free(irest);
- if (fsamples != NULL) free(fsamples);
- if (inbuf != NULL) free(inbuf);
- if (outbuf != NULL) free(outbuf);
- if (ditherbuf != NULL) free(ditherbuf);
-
- winlen = (1 << (wb-1))-1;
- winlenbit = wb;
- tabsize = 1 << wb;
-
- lires1 = (REAL *)malloc(sizeof(REAL)*tabsize);
- lires2 = (REAL *)malloc(sizeof(REAL)*tabsize);
- rires1 = (REAL *)malloc(sizeof(REAL)*tabsize);
- rires2 = (REAL *)malloc(sizeof(REAL)*tabsize);
- irest = (REAL *)malloc(sizeof(REAL)*tabsize);
- fsamples = (REAL *)malloc(sizeof(REAL)*tabsize);
- inbuf = (short *)calloc(winlen*NCH,sizeof(int));
- outbuf = (REAL *)calloc(tabsize*NCH,sizeof(REAL));
- ditherbuf = (REAL *)malloc(sizeof(REAL)*DITHERLEN);
-
- lires = lires1;
- rires = rires1;
- cur_ires = 1;
- chg_ires = 1;
+ if (state->lires1 != NULL) free(state->lires1);
+ if (state->lires2 != NULL) free(state->lires2);
+ if (state->irest != NULL) free(state->irest);
+ if (state->fsamples != NULL) free(state->fsamples);
+ if (state->finbuf != NULL) free(state->finbuf);
+ if (state->outbuf != NULL) free(state->outbuf);
+ if (state->ditherbuf != NULL) free(state->ditherbuf);
+
+
+ memset (state, 0, sizeof (SuperEqState));
+ state->channels = channels;
+ state->enable = 1;
+
+ state->winlen = (1 << (wb-1))-1;
+ state->winlenbit = wb;
+ state->tabsize = 1 << wb;
+ state->fft_bits = wb;
+
+ state->lires1 = (REAL *)equ_malloc(sizeof(REAL)*state->tabsize * state->channels);
+ state->lires2 = (REAL *)equ_malloc(sizeof(REAL)*state->tabsize * state->channels);
+ state->irest = (REAL *)equ_malloc(sizeof(REAL)*state->tabsize);
+ state->fsamples = (REAL *)equ_malloc(sizeof(REAL)*state->tabsize);
+ state->finbuf = (REAL *)equ_malloc(state->winlen*state->channels*sizeof(REAL));
+ state->outbuf = (REAL *)equ_malloc(state->tabsize*state->channels*sizeof(REAL));
+ state->ditherbuf = (REAL *)equ_malloc(sizeof(REAL)*DITHERLEN);
+
+ memset (state->lires1, 0, sizeof(REAL)*state->tabsize * state->channels);
+ memset (state->lires2, 0, sizeof(REAL)*state->tabsize * state->channels);
+ memset (state->irest, 0, sizeof(REAL)*state->tabsize);
+ memset (state->fsamples, 0, sizeof(REAL)*state->tabsize);
+ memset (state->finbuf, 0, state->winlen*state->channels*sizeof(REAL));
+ memset (state->outbuf, 0, state->tabsize*state->channels*sizeof(REAL));
+ memset (state->ditherbuf, 0, sizeof(REAL)*DITHERLEN);
+
+ state->lires = state->lires1;
+ state->cur_ires = 1;
+ state->chg_ires = 1;
for(i=0;i<DITHERLEN;i++)
- ditherbuf[i] = (float(rand())/RAND_MAX-0.5);
-
- for(i=0;i<=M;i++)
- {
- fact[i] = 1;
- for(j=1;j<=i;j++) fact[i] *= j;
- }
-
- iza = izero(alpha(aa));
+ state->ditherbuf[i] = (float(rand())/RAND_MAX-0.5);
+
+ if (fact[0] < 1) {
+ for(i=0;i<=M;i++)
+ {
+ fact[i] = 1;
+ for(j=1;j<=i;j++) fact[i] *= j;
+ }
+ iza = izero(alpha(aa));
+ }
}
// -(N-1)/2 <= n <= (N-1)/2
@@ -168,7 +249,6 @@ void process_param(REAL *bc,paramlist *param,paramlist &param2,REAL fs,int ch)
for(e = param->elm;e != NULL;e = e->next)
{
- if ((ch == 0 && !e->left) || (ch == 1 && !e->right)) continue;
if (e->lower >= e->upper) continue;
for(p=param2.elm;p != NULL;p = p->next)
@@ -231,414 +311,164 @@ void process_param(REAL *bc,paramlist *param,paramlist &param2,REAL fs,int ch)
}
}
-extern "C" void equ_makeTable(REAL *lbc,REAL *rbc,paramlist *param,REAL fs)
+extern "C" void equ_makeTable(SuperEqState *state, REAL *lbc,void *_param,REAL fs)
{
- int i,cires = cur_ires;
+ paramlist *param = (paramlist *)_param;
+ int i,cires = state->cur_ires;
REAL *nires;
if (fs <= 0) return;
paramlist param2;
- // L
-
- process_param(lbc,param,param2,fs,0);
-
- for(i=0;i<winlen;i++)
- irest[i] = hn(i-winlen/2,param2,fs)*win(i-winlen/2,winlen);
-
- for(;i<tabsize;i++)
- irest[i] = 0;
+ for (int ch = 0; ch < state->channels; ch++) {
+ process_param(lbc,param,param2,fs,ch);
- rfft(tabsize,1,irest);
+ for(i=0;i<state->winlen;i++)
+ state->irest[i] = hn(i-state->winlen/2,param2,fs)*win(i-state->winlen/2,state->winlen);
- nires = cires == 1 ? lires2 : lires1;
+ for(;i<state->tabsize;i++)
+ state->irest[i] = 0;
- for(i=0;i<tabsize;i++)
- nires[i] = irest[i];
+ rfft(state->fft_bits,1,state->irest);
- process_param(rbc,param,param2,fs,1);
-
- // R
-
- for(i=0;i<winlen;i++)
- irest[i] = hn(i-winlen/2,param2,fs)*win(i-winlen/2,winlen);
+ nires = cires == 1 ? state->lires2 : state->lires1;
+ nires += ch * state->tabsize;
- for(;i<tabsize;i++)
- irest[i] = 0;
-
- rfft(tabsize,1,irest);
-
- nires = cires == 1 ? rires2 : rires1;
-
- for(i=0;i<tabsize;i++)
- nires[i] = irest[i];
-
- //
-
- chg_ires = cires == 1 ? 2 : 1;
+ for(i=0;i<state->tabsize;i++)
+ nires[i] = state->irest[i];
+ }
+ state->chg_ires = cires == 1 ? 2 : 1;
}
-extern "C" void equ_quit(void)
+extern "C" void equ_quit(SuperEqState *state)
{
- free(lires1);
- free(lires2);
- free(rires1);
- free(rires2);
- free(irest);
- free(fsamples);
- free(inbuf);
- free(outbuf);
- free(ditherbuf);
-
- lires1 = NULL;
- lires2 = NULL;
- rires1 = NULL;
- rires2 = NULL;
- irest = NULL;
- fsamples = NULL;
- inbuf = NULL;
- outbuf = NULL;
+ equ_free(state->lires1);
+ equ_free(state->lires2);
+ equ_free(state->irest);
+ equ_free(state->fsamples);
+ equ_free(state->finbuf);
+ equ_free(state->outbuf);
+ equ_free(state->ditherbuf);
+
+ state->lires1 = NULL;
+ state->lires2 = NULL;
+ state->irest = NULL;
+ state->fsamples = NULL;
+ state->finbuf = NULL;
+ state->outbuf = NULL;
rfft(0,0,NULL);
}
-extern "C" void equ_clearbuf(int bps,int srate)
+extern "C" void equ_clearbuf(SuperEqState *state)
{
int i;
- nbufsamples = 0;
- for(i=0;i<tabsize*NCH;i++) outbuf[i] = 0;
+ state->nbufsamples = 0;
+ for(i=0;i<state->tabsize*state->channels;i++) state->outbuf[i] = 0;
}
-extern "C" int equ_modifySamples(char *buf,int nsamples,int nch,int bps)
+extern "C" int equ_modifySamples_float (SuperEqState *state, char *buf,int nsamples,int nch)
{
int i,p,ch;
REAL *ires;
- int amax = (1 << (bps-1))-1;
- int amin = -(1 << (bps-1));
+ float amax = 1.0f;
+ float amin = -1.0f;
static float hm1 = 0, hm2 = 0;
- if (chg_ires) {
- cur_ires = chg_ires;
- lires = cur_ires == 1 ? lires1 : lires2;
- rires = cur_ires == 1 ? rires1 : rires2;
- chg_ires = 0;
+ if (state->chg_ires) {
+ state->cur_ires = state->chg_ires;
+ state->lires = state->cur_ires == 1 ? state->lires1 : state->lires2;
+ state->chg_ires = 0;
}
p = 0;
- while(nbufsamples+nsamples >= winlen)
+ while(state->nbufsamples+nsamples >= state->winlen)
{
- switch(bps)
- {
- case 8:
- for(i=0;i<(winlen-nbufsamples)*nch;i++)
- {
- inbuf[nbufsamples*nch+i] = ((unsigned char *)buf)[i+p*nch] - 0x80;
- float s = outbuf[nbufsamples*nch+i];
- if (dither) {
- float u;
- s -= hm1;
- u = s;
- s += ditherbuf[(ditherptr++) & (DITHERLEN-1)];
- if (s < amin) s = amin;
- if (amax < s) s = amax;
- s = RINT(s);
- hm1 = s - u;
- ((unsigned char *)buf)[i+p*nch] = s + 0x80;
- } else {
- if (s < amin) s = amin;
- if (amax < s) s = amax;
- ((unsigned char *)buf)[i+p*nch] = RINT(s) + 0x80;
- }
- }
- for(i=winlen*nch;i<tabsize*nch;i++)
- outbuf[i-winlen*nch] = outbuf[i];
-
- break;
-
- case 16:
- for(i=0;i<(winlen-nbufsamples)*nch;i++)
+ for(i=0;i<(state->winlen-state->nbufsamples)*nch;i++)
{
- inbuf[nbufsamples*nch+i] = ((short *)buf)[i+p*nch];
- float s = outbuf[nbufsamples*nch+i];
- if (dither) {
- float u;
- s -= hm1;
- u = s;
- s += ditherbuf[(ditherptr++) & (DITHERLEN-1)];
- if (s < amin) s = amin;
- if (amax < s) s = amax;
- s = RINT(s);
- hm1 = s - u;
- ((short *)buf)[i+p*nch] = s;
- } else {
- if (s < amin) s = amin;
- if (amax < s) s = amax;
- ((short *)buf)[i+p*nch] = RINT(s);
- }
- }
- for(i=winlen*nch;i<tabsize*nch;i++)
- outbuf[i-winlen*nch] = outbuf[i];
-
- break;
-
- case 24:
- for(i=0;i<(winlen-nbufsamples)*nch;i++)
- {
- ((int *)inbuf)[nbufsamples*nch+i] =
- (((unsigned char *)buf)[(i+p*nch)*3 ] ) +
- (((unsigned char *)buf)[(i+p*nch)*3+1] << 8) +
- ((( signed char *)buf)[(i+p*nch)*3+2] << 16) ;
-
- float s = outbuf[nbufsamples*nch+i];
+ state->finbuf[state->nbufsamples*nch+i] = ((float *)buf)[i+p*nch];
+ float s = state->outbuf[state->nbufsamples*nch+i];
//if (dither) s += ditherbuf[(ditherptr++) & (DITHERLEN-1)];
if (s < amin) s = amin;
if (amax < s) s = amax;
- int s2 = RINT(s);
- ((signed char *)buf)[(i+p*nch)*3 ] = s2 & 255; s2 >>= 8;
- ((signed char *)buf)[(i+p*nch)*3+1] = s2 & 255; s2 >>= 8;
- ((signed char *)buf)[(i+p*nch)*3+2] = s2 & 255;
+ ((float *)buf)[i+p*nch] = s;
}
- for(i=winlen*nch;i<tabsize*nch;i++)
- outbuf[i-winlen*nch] = outbuf[i];
+ for(i=state->winlen*nch;i<state->tabsize*nch;i++)
+ state->outbuf[i-state->winlen*nch] = state->outbuf[i];
- break;
- default:
- assert(0);
- }
-
- p += winlen-nbufsamples;
- nsamples -= winlen-nbufsamples;
- nbufsamples = 0;
+ p += state->winlen-state->nbufsamples;
+ nsamples -= state->winlen-state->nbufsamples;
+ state->nbufsamples = 0;
for(ch=0;ch<nch;ch++)
{
- ires = ch == 0 ? lires : rires;
+ ires = state->lires + ch * state->tabsize;
- if (bps == 24) {
- for(i=0;i<winlen;i++)
- fsamples[i] = ((int *)inbuf)[nch*i+ch];
- } else {
- for(i=0;i<winlen;i++)
- fsamples[i] = inbuf[nch*i+ch];
- }
+ for(i=0;i<state->winlen;i++)
+ state->fsamples[i] = state->finbuf[nch*i+ch];
- for(i=winlen;i<tabsize;i++)
- fsamples[i] = 0;
+ for(i=state->winlen;i<state->tabsize;i++)
+ state->fsamples[i] = 0;
- if (enable) {
- rfft(tabsize,1,fsamples);
+ if (state->enable) {
+ rfft(state->fft_bits,1,state->fsamples);
- fsamples[0] = ires[0]*fsamples[0];
- fsamples[1] = ires[1]*fsamples[1];
+ state->fsamples[0] = ires[0]*state->fsamples[0];
+ state->fsamples[1] = ires[1]*state->fsamples[1];
- for(i=1;i<tabsize/2;i++)
+ for(i=1;i<state->tabsize/2;i++)
{
REAL re,im;
- re = ires[i*2 ]*fsamples[i*2] - ires[i*2+1]*fsamples[i*2+1];
- im = ires[i*2+1]*fsamples[i*2] + ires[i*2 ]*fsamples[i*2+1];
+ re = ires[i*2 ]*state->fsamples[i*2] - ires[i*2+1]*state->fsamples[i*2+1];
+ im = ires[i*2+1]*state->fsamples[i*2] + ires[i*2 ]*state->fsamples[i*2+1];
- fsamples[i*2 ] = re;
- fsamples[i*2+1] = im;
+ state->fsamples[i*2 ] = re;
+ state->fsamples[i*2+1] = im;
}
- rfft(tabsize,-1,fsamples);
+ rfft(state->fft_bits,-1,state->fsamples);
} else {
- for(i=winlen-1+winlen/2;i>=winlen/2;i--) fsamples[i] = fsamples[i-winlen/2]*tabsize/2;
- for(;i>=0;i--) fsamples[i] = 0;
+ for(i=state->winlen-1+state->winlen/2;i>=state->winlen/2;i--) state->fsamples[i] = state->fsamples[i-state->winlen/2]*state->tabsize/2;
+ for(;i>=0;i--) state->fsamples[i] = 0;
}
- for(i=0;i<winlen;i++) outbuf[i*nch+ch] += fsamples[i]/tabsize*2;
+ for(i=0;i<state->winlen;i++) state->outbuf[i*nch+ch] += state->fsamples[i]/state->tabsize*2;
- for(i=winlen;i<tabsize;i++) outbuf[i*nch+ch] = fsamples[i]/tabsize*2;
+ for(i=state->winlen;i<state->tabsize;i++) state->outbuf[i*nch+ch] = state->fsamples[i]/state->tabsize*2;
}
}
- switch(bps)
- {
- case 8:
- for(i=0;i<nsamples*nch;i++)
- {
- inbuf[nbufsamples*nch+i] = ((unsigned char *)buf)[i+p*nch] - 0x80;
- float s = outbuf[nbufsamples*nch+i];
- if (dither) {
- float u;
- s -= hm1;
- u = s;
- s += ditherbuf[(ditherptr++) & (DITHERLEN-1)];
- if (s < amin) s = amin;
- if (amax < s) s = amax;
- s = RINT(s);
- hm1 = s - u;
- ((unsigned char *)buf)[i+p*nch] = s + 0x80;
- } else {
- if (s < amin) s = amin;
- if (amax < s) s = amax;
- ((unsigned char *)buf)[i+p*nch] = RINT(s) + 0x80;
- }
- }
- break;
-
- case 16:
for(i=0;i<nsamples*nch;i++)
{
- inbuf[nbufsamples*nch+i] = ((short *)buf)[i+p*nch];
- float s = outbuf[nbufsamples*nch+i];
- if (dither) {
+ state->finbuf[state->nbufsamples*nch+i] = ((float *)buf)[i+p*nch];
+ float s = state->outbuf[state->nbufsamples*nch+i];
+ if (state->dither) {
float u;
s -= hm1;
u = s;
- s += ditherbuf[(ditherptr++) & (DITHERLEN-1)];
+// s += ditherbuf[(ditherptr++) & (DITHERLEN-1)];
if (s < amin) s = amin;
if (amax < s) s = amax;
- s = RINT(s);
hm1 = s - u;
- ((short *)buf)[i+p*nch] = s;
+ ((float *)buf)[i+p*nch] = s;
} else {
if (s < amin) s = amin;
if (amax < s) s = amax;
- ((short *)buf)[i+p*nch] = RINT(s);
+ ((float *)buf)[i+p*nch] = s;
}
}
- break;
-
- case 24:
- for(i=0;i<nsamples*nch;i++)
- {
- ((int *)inbuf)[nbufsamples*nch+i] =
- (((unsigned char *)buf)[(i+p*nch)*3 ] ) +
- (((unsigned char *)buf)[(i+p*nch)*3+1] << 8) +
- ((( signed char *)buf)[(i+p*nch)*3+2] << 16) ;
-
- float s = outbuf[nbufsamples*nch+i];
- //if (dither) s += ditherbuf[(ditherptr++) & (DITHERLEN-1)];
- if (s < amin) s = amin;
- if (amax < s) s = amax;
- int s2 = RINT(s);
- ((signed char *)buf)[(i+p*nch)*3 ] = s2 & 255; s2 >>= 8;
- ((signed char *)buf)[(i+p*nch)*3+1] = s2 & 255; s2 >>= 8;
- ((signed char *)buf)[(i+p*nch)*3+2] = s2 & 255;
- }
- break;
-
- default:
- assert(0);
- }
p += nsamples;
- nbufsamples += nsamples;
+ state->nbufsamples += nsamples;
return p;
}
-#if 0
-void usage(void)
-{
- fprintf(stderr,"Ouch!\n");
-}
-
-int main(int argc,char **argv)
-{
- FILE *fpi,*fpo;
- char buf[576*2*2];
-
- static REAL bc[] =
- {1.0, 0,1.0, 0,1.0, 0,1.0, 0,1.0, 0,1.0, 0,1.0, 0,1.0, 0,1.0, 0};
-
- init(14);
- makeTable(bc,44100);
-
- if (argc != 3 && argc != 4) exit(-1);
-
- fpi = fopen(argv[1],"r");
- fpo = fopen(argv[2],"w");
-
- if (!fpi || !fpo) exit(-1);
-
- /* generate wav header */
-
- {
- short word;
- int dword;
-
- fwrite("RIFF",4,1,fpo);
- dword = 0;
- fwrite(&dword,4,1,fpo);
-
- fwrite("WAVEfmt ",8,1,fpo);
- dword = 16;
- fwrite(&dword,4,1,fpo);
- word = 1;
- fwrite(&word,2,1,fpo); /* format category, PCM */
- word = 2;
- fwrite(&word,2,1,fpo); /* channels */
- dword = 44100;
- fwrite(&dword,4,1,fpo); /* sampling rate */
- dword = 44100*2*2;
- fwrite(&dword,4,1,fpo); /* bytes per sec */
- word = 4;
- fwrite(&word,2,1,fpo); /* block alignment */
- word = 16;
- fwrite(&word,2,1,fpo); /* ??? */
-
- fwrite("data",4,1,fpo);
- dword = 0;
- fwrite(&dword,4,1,fpo);
- }
-
- preamp = 65536;
- maxamp = 0;
-
- if (argc == 4) {
- preamp = 32767*65536/atoi(argv[3]);
- fprintf(stderr,"preamp = %d\n",preamp);
- }
-
- for(;;)
- {
- int n,m;
-
- n = fread(buf,1,576*2*2,fpi);
- if (n <= 0) break;
- m = modifySamples((short *)buf,n/4,2);
- fwrite(buf,4,m,fpo);
- }
-
-#if 0
- for(;;)
- {
- int n = flushbuf((short *)buf,576);
- if (n == 0) break;
- fwrite(buf,4,n,fpo);
- }
-#endif
-
- {
- short word;
- int dword;
- int len = ftell(fpo);
-
- fseek(fpo,4,SEEK_SET);
- dword = len-8;
- fwrite(&dword,4,1,fpo);
-
- fseek(fpo,40,SEEK_SET);
- dword = len-44;
- fwrite(&dword,4,1,fpo);
- }
-
- if (maxamp != 0) {
- fprintf(stderr,"maxamp = %d\n",maxamp);
- }
-
- quit();
-}
-#endif
-
extern "C" void *paramlist_alloc (void) {
return (void *)(new paramlist);
}
diff --git a/plugins/supereq/Equ.h b/plugins/supereq/Equ.h
new file mode 100644
index 00000000..a315741a
--- /dev/null
+++ b/plugins/supereq/Equ.h
@@ -0,0 +1,56 @@
+/*
+ DeaDBeeF - ultimate music player for GNU/Linux systems with X11
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+#ifndef __EQU_H
+#define __EQU_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef float REAL;
+typedef struct {
+ REAL *lires,*lires1,*lires2;
+ REAL *irest;
+ REAL *fsamples;
+ REAL *ditherbuf;
+ int ditherptr;
+ volatile int chg_ires,cur_ires;
+ int winlen,winlenbit,tabsize,nbufsamples;
+ REAL *finbuf;
+ REAL *outbuf;
+ int dither;
+ int channels;
+ int enable;
+ int fft_bits;
+} SuperEqState;
+
+void *paramlist_alloc (void);
+void paramlist_free (void *);
+void equ_makeTable(SuperEqState *state, float *lbc,void *param,float fs);
+int equ_modifySamples(SuperEqState *state, char *buf,int nsamples,int nch,int bps);
+int equ_modifySamples_float (SuperEqState *state, char *buf,int nsamples,int nch);
+void equ_clearbuf(SuperEqState *state);
+void equ_init(SuperEqState *state, int wb, int channels);
+void equ_quit(SuperEqState *state);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/plugins/supereq/Fftsg_fl.cpp b/plugins/supereq/Fftsg_fl.cpp
index d48debfe..636f8b8a 100644
--- a/plugins/supereq/Fftsg_fl.cpp
+++ b/plugins/supereq/Fftsg_fl.cpp
@@ -285,6 +285,7 @@ Appendix :
w[] and ip[] are compatible with all routines.
*/
+extern "C" {
void cdft(int n, int isgn, REAL *a, int *ip, REAL *w)
{
@@ -2649,32 +2650,4 @@ void dstsub(int n, REAL *a, int nc, REAL *c)
}
a[m] *= c[0];
}
-
-void rfft(int n,int isign,REAL x[])
-{
- static int ipsize = 0,wsize=0;
- static int *ip = NULL;
- static REAL *w = NULL;
- int newipsize,newwsize;
-
- if (n == 0) {
- free(ip); ip = NULL; ipsize = 0;
- free(w); w = NULL; wsize = 0;
- return;
- }
-
- newipsize = 2+sqrt(n/2);
- if (newipsize > ipsize) {
- ipsize = newipsize;
- ip = (int *)realloc(ip,sizeof(int)*ipsize);
- ip[0] = 0;
- }
-
- newwsize = n/2;
- if (newwsize > wsize) {
- wsize = newwsize;
- w = (REAL *)realloc(w,sizeof(REAL)*wsize);
- }
-
- rdft(n,isign,x,ip,w);
}
diff --git a/plugins/supereq/Makefile.am b/plugins/supereq/Makefile.am
index 0fffd6d6..45010ec8 100644
--- a/plugins/supereq/Makefile.am
+++ b/plugins/supereq/Makefile.am
@@ -3,8 +3,51 @@ supereqdir = $(libdir)/$(PACKAGE)
pkglib_LTLIBRARIES = supereq.la
supereq_la_SOURCES = supereq.c supereq.h Equ.cpp Fftsg_fl.cpp paramlist.hpp
-supereq_la_LDFLAGS = -module
+#nsfft-1.00/simd/SIMDBaseUndiff.c\
+#nsfft-1.00/simd/SIMDBase.c\
+#nsfft-1.00/dft/DFT.c\
+#nsfft-1.00/dft/DFTUndiff.c\
+#nsfft-1.00/simd/SIMDBase.h\
+#nsfft-1.00/simd/SIMDBaseUndiff.h\
+#nsfft-1.00/dft/DFTUndiff.h\
+#nsfft-1.00/dft/DFT.h\
+#shibatch_rdft.c
+
+#ffmpeg_fft/libavutil/mem.c\
+#ffmpeg_fft/libavutil/mathematics.c\
+#ffmpeg_fft/libavutil/rational.c\
+#ffmpeg_fft/libavutil/intfloat_readwrite.c\
+#ffmpeg_fft/libavcodec/dct.c\
+#ffmpeg_fft/libavcodec/avfft.c\
+#ffmpeg_fft/libavcodec/fft.c\
+#ffmpeg_fft/libavcodec/dct32.c\
+#ffmpeg_fft/libavcodec/rdft.c\
+#ffmpeg_fft/libavutil/intfloat_readwrite.h\
+#ffmpeg_fft/libavutil/avutil.h\
+#ffmpeg_fft/libavutil/common.h\
+#ffmpeg_fft/libavutil/attributes.h\
+#ffmpeg_fft/libavutil/mem.h\
+#ffmpeg_fft/libavutil/avconfig.h\
+#ffmpeg_fft/libavutil/mathematics.h\
+#ffmpeg_fft/libavutil/rational.h\
+#ffmpeg_fft/publik.h\
+#ffmpeg_fft/ffmpeg_fft.h\
+#ffmpeg_fft/libavcodec/dct32.h\
+#ffmpeg_fft/libavcodec/fft.h\
+#ffmpeg_fft/libavcodec/avfft.h\
+#ffmpeg_fft/config.h\
+#ff_rdft.c
+
+#AM_CFLAGS = $(CFLAGS) -I ffmpeg_fft -I ffmpeg_fft/libavcodec -I ffmpeg_fft/libavutil -std=c99
+#AM_CPPFLAGS = $(CXXFLAGS) -fno-exceptions -fno-rtti -nostdlib -fno-unwind-tables -I ffmpeg_fft -I ffmpeg_fft/libavcodec -I ffmpeg_fft/libavutil
+
+#AM_CFLAGS = $(CFLAGS) -I nsfft-1.00/dft -I nsfft-1.00/simd -std=c99 -msse -DENABLE_SSE_FLOAT -DUSE_SHIBATCH
+#AM_CPPFLAGS = $(CXXFLAGS) -fno-exceptions -fno-rtti -nostdlib -fno-unwind-tables -I nsfft-1.00/dft -I nsfft-1.00/simd -msse -DENABLE_SSE_FLOAT -DUSE_SHIBATCH
+
+AM_CFLAGS = $(CFLAGS) -std=c99 -DUSE_OOURA
+AM_CPPFLAGS = $(CXXFLAGS) -fno-exceptions -fno-rtti -nostdlib -fno-unwind-tables -DUSE_OOURA
+
+supereq_la_LDFLAGS = -module -nostdlib -lsupc++
supereq_la_LIBADD = $(LDADD)
-AM_CFLAGS = -std=c99
endif
diff --git a/plugins/supereq/ff_rdft.c b/plugins/supereq/ff_rdft.c
new file mode 100644
index 00000000..70a09350
--- /dev/null
+++ b/plugins/supereq/ff_rdft.c
@@ -0,0 +1,63 @@
+#include <stdint.h>
+#include <complex.h>
+#include "libavcodec/avfft.h"
+#include "libavutil/avutil.h"
+
+void rfft(int n,int isign,float *x)
+{
+ static int wsize=0;
+ static float *w = NULL;
+ static RDFTContext *s = NULL;
+ static RDFTContext *si = NULL;
+ int newwsize;
+
+ if (n == 0) {
+ if (w) {
+ av_free(w);
+ w = NULL;
+ wsize = 0;
+ }
+ if (s) {
+ av_rdft_end (s);
+ s = NULL;
+ }
+ if (si) {
+ av_rdft_end (si);
+ si = NULL;
+ }
+ return;
+ }
+
+ newwsize = n/2;
+ if (newwsize > wsize) {
+ wsize = newwsize;
+ if (s) {
+ av_rdft_end (s);
+ s = NULL;
+ }
+ if (si) {
+ av_rdft_end (si);
+ si = NULL;
+ }
+ if (w) {
+ av_free (w);
+ w = NULL;
+ }
+ w = (float *)av_malloc(sizeof(float)*wsize);
+ }
+
+ if (!s) {
+ s = av_rdft_init(n,DFT_R2C);
+ }
+ if (!si) {
+ si = av_rdft_init(n,IDFT_C2R);
+ }
+
+ if (isign == 1) {
+ av_rdft_calc (s, x);
+ }
+ else {
+ av_rdft_calc (si, x);
+ }
+}
+
diff --git a/plugins/supereq/ffmpeg_fft/README b/plugins/supereq/ffmpeg_fft/README
new file mode 100644
index 00000000..f53b2447
--- /dev/null
+++ b/plugins/supereq/ffmpeg_fft/README
@@ -0,0 +1,9 @@
+purpose:
+
+* compare fftw and ffmpeg fourier transforms using benchfft and / or libbench
+* note: this is very specifically for neon. if you want to use ffmpeg_fft with
+ some other arch / fpu, then you will need to do some reorganization
+
+todo:
+
+1) fix benchees/ffmpeg/doitr.c
diff --git a/plugins/supereq/ffmpeg_fft/config.h b/plugins/supereq/ffmpeg_fft/config.h
new file mode 100644
index 00000000..0f36b47c
--- /dev/null
+++ b/plugins/supereq/ffmpeg_fft/config.h
@@ -0,0 +1,904 @@
+/* Automatically generated by configure - do not modify! */
+#ifndef FFMPEG_CONFIG_H
+#define FFMPEG_CONFIG_H
+#define FFMPEG_CONFIGURATION "--prefix=/usr --enable-neon --enable-pic --cpu=cortex-a8 --arch=arm --cross-prefix=arm-none-linux-gnueabi- --enable-cross-compile --target-os=linux --extra-cflags='-mfpu=neon -mcpu=cortex-a8 -mfloat-abi=softfp' --enable-shared --disable-debug"
+#define FFMPEG_LICENSE "LGPL version 2.1 or later"
+#define FFMPEG_DATADIR "/usr/share/ffmpeg"
+#define CC_TYPE "gcc"
+#define CC_VERSION __VERSION__
+#define restrict restrict
+#define ASMALIGN(ZEROBITS) ".p2align " #ZEROBITS "\n\t"
+#define EXTERN_PREFIX ""
+#define EXTERN_ASM
+#define ARCH_ALPHA 0
+#define ARCH_ARM 0
+#define ARCH_AVR32 0
+#define ARCH_AVR32_AP 0
+#define ARCH_AVR32_UC 0
+#define ARCH_BFIN 0
+#define ARCH_IA64 0
+#define ARCH_M68K 0
+#define ARCH_MIPS 0
+#define ARCH_MIPS64 0
+#define ARCH_PARISC 0
+#define ARCH_PPC 0
+#define ARCH_PPC64 0
+#define ARCH_S390 0
+#define ARCH_SH4 0
+#define ARCH_SPARC 0
+#define ARCH_SPARC64 0
+#define ARCH_TOMI 0
+#define ARCH_X86 1
+#define ARCH_X86_32 1
+#define ARCH_X86_64 0
+#define HAVE_ALTIVEC 0
+#define HAVE_AMD3DNOW 0
+#define HAVE_AMD3DNOWEXT 0
+#define HAVE_ARMV5TE 1
+#define HAVE_ARMV6 1
+#define HAVE_ARMV6T2 1
+#define HAVE_ARMVFP 1
+#define HAVE_IWMMXT 0
+#define HAVE_MMI 0
+#define HAVE_MMX 0
+#define HAVE_MMX2 0
+#define HAVE_NEON 1
+#define HAVE_PPC4XX 0
+#define HAVE_SSE 1
+#define HAVE_SSSE3 1
+#define HAVE_VIS 0
+#define HAVE_BIGENDIAN 0
+#define HAVE_PTHREADS 1
+#define HAVE_W32THREADS 0
+#define HAVE_ALSA_ASOUNDLIB_H 0
+#define HAVE_ALTIVEC_H 0
+#define HAVE_ARPA_INET_H 1
+#define HAVE_ATTRIBUTE_MAY_ALIAS 1
+#define HAVE_ATTRIBUTE_PACKED 1
+#define HAVE_BSWAP 0
+#define HAVE_CLOSESOCKET 0
+#define HAVE_CMOV 0
+#define HAVE_CONIO_H 0
+#define HAVE_DCBZL 0
+#define HAVE_DEV_BKTR_IOCTL_BT848_H 0
+#define HAVE_DEV_BKTR_IOCTL_METEOR_H 0
+#define HAVE_DEV_IC_BT8XX_H 0
+#define HAVE_DEV_VIDEO_METEOR_IOCTL_METEOR_H 0
+#define HAVE_DEV_VIDEO_BKTR_IOCTL_BT848_H 0
+#define HAVE_DLFCN_H 1
+#define HAVE_DLOPEN 1
+#define HAVE_DOS_PATHS 0
+#define HAVE_EBP_AVAILABLE 0
+#define HAVE_EBX_AVAILABLE 0
+#define HAVE_EXP2 1
+#define HAVE_EXP2F 1
+#define HAVE_FAST_64BIT 0
+#define HAVE_FAST_CLZ 1
+#define HAVE_FAST_CMOV 0
+#define HAVE_FAST_UNALIGNED 1
+#define HAVE_FCNTL 1
+#define HAVE_FORK 1
+#define HAVE_GETADDRINFO 1
+#define HAVE_GETHRTIME 0
+#define HAVE_GETPROCESSMEMORYINFO 0
+#define HAVE_GETPROCESSTIMES 0
+#define HAVE_GETRUSAGE 1
+#define HAVE_GNU_AS 1
+#define HAVE_STRUCT_RUSAGE_RU_MAXRSS 1
+#define HAVE_IBM_ASM 0
+#define HAVE_INET_ATON 1
+#define HAVE_INLINE_ASM 1
+#define HAVE_ISATTY 1
+#define HAVE_LDBRX 0
+#define HAVE_LIBDC1394_1 0
+#define HAVE_LIBDC1394_2 0
+#define HAVE_LLRINT 1
+#define HAVE_LLRINTF 1
+#define HAVE_LOCAL_ALIGNED_16 0
+#define HAVE_LOCAL_ALIGNED_8 0
+#define HAVE_LOG2 1
+#define HAVE_LOG2F 1
+#define HAVE_LOONGSON 0
+#define HAVE_LRINT 1
+#define HAVE_LRINTF 1
+#define HAVE_LZO1X_999_COMPRESS 0
+#define HAVE_MACHINE_IOCTL_BT848_H 0
+#define HAVE_MACHINE_IOCTL_METEOR_H 0
+#define HAVE_MALLOC_H 1
+#define HAVE_MEMALIGN 1
+#define HAVE_MKSTEMP 1
+#define HAVE_PLD 1
+#define HAVE_POSIX_MEMALIGN 1
+#define HAVE_ROUND 1
+#define HAVE_ROUNDF 1
+#define HAVE_SDL 0
+#define HAVE_SDL_VIDEO_SIZE 0
+#define HAVE_SETMODE 0
+#define HAVE_SOCKLEN_T 1
+#define HAVE_SOUNDCARD_H 0
+#define HAVE_POLL_H 1
+#define HAVE_SETRLIMIT 1
+#define HAVE_STRERROR_R 1
+#define HAVE_STRUCT_ADDRINFO 1
+#define HAVE_STRUCT_IPV6_MREQ 1
+#define HAVE_STRUCT_SOCKADDR_IN6 1
+#define HAVE_STRUCT_SOCKADDR_SA_LEN 0
+#define HAVE_STRUCT_SOCKADDR_STORAGE 1
+#define HAVE_SYMVER 1
+#define HAVE_SYMVER_GNU_ASM 1
+#define HAVE_SYMVER_ASM_LABEL 0
+#define HAVE_SYS_MMAN_H 1
+#define HAVE_SYS_RESOURCE_H 1
+#define HAVE_SYS_SELECT_H 1
+#define HAVE_SYS_SOUNDCARD_H 1
+#define HAVE_SYS_VIDEOIO_H 0
+#define HAVE_TEN_OPERANDS 0
+#define HAVE_TERMIOS_H 1
+#define HAVE_THREADS 1
+#define HAVE_TRUNCF 1
+#define HAVE_VFP_ARGS 0
+#define HAVE_VIRTUALALLOC 0
+#define HAVE_WINSOCK2_H 0
+#define HAVE_XFORM_ASM 0
+#define HAVE_YASM 0
+#define CONFIG_BSFS 1
+#define CONFIG_DECODERS 1
+#define CONFIG_DEMUXERS 1
+#define CONFIG_ENCODERS 1
+#define CONFIG_FILTERS 1
+#define CONFIG_HWACCELS 0
+#define CONFIG_INDEVS 1
+#define CONFIG_MUXERS 1
+#define CONFIG_OUTDEVS 1
+#define CONFIG_PARSERS 1
+#define CONFIG_PROTOCOLS 1
+#define CONFIG_AANDCT 1
+#define CONFIG_AVCODEC 1
+#define CONFIG_AVDEVICE 1
+#define CONFIG_AVFILTER 1
+#define CONFIG_AVFILTER_LAVF 0
+#define CONFIG_AVFORMAT 1
+#define CONFIG_AVISYNTH 0
+#define CONFIG_BZLIB 0
+#define CONFIG_DCT 1
+#define CONFIG_DOC 0
+#define CONFIG_DWT 1
+#define CONFIG_DXVA2 0
+#define CONFIG_FASTDIV 1
+#define CONFIG_FFMPEG 1
+#define CONFIG_FFPLAY 0
+#define CONFIG_FFPROBE 1
+#define CONFIG_FFSERVER 1
+#define CONFIG_FFT 1
+#define CONFIG_GOLOMB 1
+#define CONFIG_GPL 0
+#define CONFIG_GRAY 0
+#define CONFIG_H264DSP 1
+#define CONFIG_HARDCODED_TABLES 0
+#define CONFIG_LIBDC1394 0
+#define CONFIG_LIBDIRAC 0
+#define CONFIG_LIBFAAC 0
+#define CONFIG_LIBGSM 0
+#define CONFIG_LIBMP3LAME 0
+#define CONFIG_LIBNUT 0
+#define CONFIG_LIBOPENCORE_AMRNB 0
+#define CONFIG_LIBOPENCORE_AMRWB 0
+#define CONFIG_LIBOPENJPEG 0
+#define CONFIG_LIBRTMP 0
+#define CONFIG_LIBSCHROEDINGER 0
+#define CONFIG_LIBSPEEX 0
+#define CONFIG_LIBTHEORA 0
+#define CONFIG_LIBVORBIS 0
+#define CONFIG_LIBVPX 0
+#define CONFIG_LIBX264 0
+#define CONFIG_LIBXVID 0
+#define CONFIG_LPC 1
+#define CONFIG_LSP 1
+//#define CONFIG_MDCT 1
+#define CONFIG_MEMALIGN_HACK 0
+#define CONFIG_MLIB 0
+#define CONFIG_MPEGAUDIO_HP 1
+#define CONFIG_NETWORK 1
+#define CONFIG_NONFREE 0
+#define CONFIG_PIC 1
+#define CONFIG_POSTPROC 0
+#define CONFIG_RDFT 1
+#define CONFIG_RUNTIME_CPUDETECT 0
+#define CONFIG_SHARED 1
+#define CONFIG_SMALL 0
+#define CONFIG_SRAM 0
+#define CONFIG_STATIC 1
+#define CONFIG_SWSCALE 1
+#define CONFIG_SWSCALE_ALPHA 1
+#define CONFIG_VAAPI 0
+#define CONFIG_VDPAU 0
+#define CONFIG_VERSION3 0
+#define CONFIG_X11GRAB 0
+#define CONFIG_ZLIB 0
+#define CONFIG_AVUTIL 1
+#define CONFIG_GPLV3 0
+#define CONFIG_LGPLV3 0
+#define CONFIG_AASC_DECODER 1
+#define CONFIG_AMV_DECODER 1
+#define CONFIG_ANM_DECODER 1
+#define CONFIG_ASV1_DECODER 1
+#define CONFIG_ASV2_DECODER 1
+#define CONFIG_AURA_DECODER 1
+#define CONFIG_AURA2_DECODER 1
+#define CONFIG_AVS_DECODER 1
+#define CONFIG_BETHSOFTVID_DECODER 1
+#define CONFIG_BFI_DECODER 1
+#define CONFIG_BINK_DECODER 1
+#define CONFIG_BMP_DECODER 1
+#define CONFIG_C93_DECODER 1
+#define CONFIG_CAVS_DECODER 1
+#define CONFIG_CDGRAPHICS_DECODER 1
+#define CONFIG_CINEPAK_DECODER 1
+#define CONFIG_CLJR_DECODER 1
+#define CONFIG_CSCD_DECODER 1
+#define CONFIG_CYUV_DECODER 1
+#define CONFIG_DNXHD_DECODER 1
+#define CONFIG_DPX_DECODER 1
+#define CONFIG_DSICINVIDEO_DECODER 1
+#define CONFIG_DVVIDEO_DECODER 1
+#define CONFIG_DXA_DECODER 0
+#define CONFIG_EACMV_DECODER 1
+#define CONFIG_EAMAD_DECODER 1
+#define CONFIG_EATGQ_DECODER 1
+#define CONFIG_EATGV_DECODER 1
+#define CONFIG_EATQI_DECODER 1
+#define CONFIG_EIGHTBPS_DECODER 1
+#define CONFIG_EIGHTSVX_EXP_DECODER 1
+#define CONFIG_EIGHTSVX_FIB_DECODER 1
+#define CONFIG_ESCAPE124_DECODER 1
+#define CONFIG_FFV1_DECODER 1
+#define CONFIG_FFVHUFF_DECODER 1
+#define CONFIG_FLASHSV_DECODER 0
+#define CONFIG_FLIC_DECODER 1
+#define CONFIG_FLV_DECODER 1
+#define CONFIG_FOURXM_DECODER 1
+#define CONFIG_FRAPS_DECODER 1
+#define CONFIG_FRWU_DECODER 1
+#define CONFIG_GIF_DECODER 1
+#define CONFIG_H261_DECODER 1
+#define CONFIG_H263_DECODER 1
+#define CONFIG_H263I_DECODER 1
+#define CONFIG_H264_DECODER 1
+#define CONFIG_H264_VDPAU_DECODER 0
+#define CONFIG_HUFFYUV_DECODER 1
+#define CONFIG_IDCIN_DECODER 1
+#define CONFIG_IFF_BYTERUN1_DECODER 1
+#define CONFIG_IFF_ILBM_DECODER 1
+#define CONFIG_INDEO2_DECODER 1
+#define CONFIG_INDEO3_DECODER 1
+#define CONFIG_INDEO5_DECODER 1
+#define CONFIG_INTERPLAY_VIDEO_DECODER 1
+#define CONFIG_JPEGLS_DECODER 1
+#define CONFIG_KGV1_DECODER 1
+#define CONFIG_KMVC_DECODER 1
+#define CONFIG_LOCO_DECODER 1
+#define CONFIG_MDEC_DECODER 1
+#define CONFIG_MIMIC_DECODER 1
+#define CONFIG_MJPEG_DECODER 1
+#define CONFIG_MJPEGB_DECODER 1
+#define CONFIG_MMVIDEO_DECODER 1
+#define CONFIG_MOTIONPIXELS_DECODER 1
+#define CONFIG_MPEG_XVMC_DECODER 0
+#define CONFIG_MPEG1VIDEO_DECODER 1
+#define CONFIG_MPEG2VIDEO_DECODER 1
+#define CONFIG_MPEG4_DECODER 1
+#define CONFIG_MPEG4_VDPAU_DECODER 0
+#define CONFIG_MPEGVIDEO_DECODER 1
+#define CONFIG_MPEG_VDPAU_DECODER 0
+#define CONFIG_MPEG1_VDPAU_DECODER 0
+#define CONFIG_MSMPEG4V1_DECODER 1
+#define CONFIG_MSMPEG4V2_DECODER 1
+#define CONFIG_MSMPEG4V3_DECODER 1
+#define CONFIG_MSRLE_DECODER 1
+#define CONFIG_MSVIDEO1_DECODER 1
+#define CONFIG_MSZH_DECODER 1
+#define CONFIG_NUV_DECODER 1
+#define CONFIG_PAM_DECODER 1
+#define CONFIG_PBM_DECODER 1
+#define CONFIG_PCX_DECODER 1
+#define CONFIG_PGM_DECODER 1
+#define CONFIG_PGMYUV_DECODER 1
+#define CONFIG_PICTOR_DECODER 1
+#define CONFIG_PNG_DECODER 0
+#define CONFIG_PPM_DECODER 1
+#define CONFIG_PTX_DECODER 1
+#define CONFIG_QDRAW_DECODER 1
+#define CONFIG_QPEG_DECODER 1
+#define CONFIG_QTRLE_DECODER 1
+#define CONFIG_R210_DECODER 1
+#define CONFIG_RAWVIDEO_DECODER 1
+#define CONFIG_RL2_DECODER 1
+#define CONFIG_ROQ_DECODER 1
+#define CONFIG_RPZA_DECODER 1
+#define CONFIG_RV10_DECODER 1
+#define CONFIG_RV20_DECODER 1
+#define CONFIG_RV30_DECODER 1
+#define CONFIG_RV40_DECODER 1
+#define CONFIG_SGI_DECODER 1
+#define CONFIG_SMACKER_DECODER 1
+#define CONFIG_SMC_DECODER 1
+#define CONFIG_SNOW_DECODER 1
+#define CONFIG_SP5X_DECODER 1
+#define CONFIG_SUNRAST_DECODER 1
+#define CONFIG_SVQ1_DECODER 1
+#define CONFIG_SVQ3_DECODER 1
+#define CONFIG_TARGA_DECODER 1
+#define CONFIG_THEORA_DECODER 1
+#define CONFIG_THP_DECODER 1
+#define CONFIG_TIERTEXSEQVIDEO_DECODER 1
+#define CONFIG_TIFF_DECODER 1
+#define CONFIG_TMV_DECODER 1
+#define CONFIG_TRUEMOTION1_DECODER 1
+#define CONFIG_TRUEMOTION2_DECODER 1
+#define CONFIG_TSCC_DECODER 0
+#define CONFIG_TXD_DECODER 1
+#define CONFIG_ULTI_DECODER 1
+#define CONFIG_V210_DECODER 1
+#define CONFIG_V210X_DECODER 1
+#define CONFIG_VB_DECODER 1
+#define CONFIG_VC1_DECODER 1
+#define CONFIG_VC1_VDPAU_DECODER 0
+#define CONFIG_VCR1_DECODER 1
+#define CONFIG_VMDVIDEO_DECODER 1
+#define CONFIG_VMNC_DECODER 1
+#define CONFIG_VP3_DECODER 1
+#define CONFIG_VP5_DECODER 1
+#define CONFIG_VP6_DECODER 1
+#define CONFIG_VP6A_DECODER 1
+#define CONFIG_VP6F_DECODER 1
+#define CONFIG_VP8_DECODER 1
+#define CONFIG_VQA_DECODER 1
+#define CONFIG_WMV1_DECODER 1
+#define CONFIG_WMV2_DECODER 1
+#define CONFIG_WMV3_DECODER 1
+#define CONFIG_WMV3_VDPAU_DECODER 0
+#define CONFIG_WNV1_DECODER 1
+#define CONFIG_XAN_WC3_DECODER 1
+#define CONFIG_XL_DECODER 1
+#define CONFIG_YOP_DECODER 1
+#define CONFIG_ZLIB_DECODER 0
+#define CONFIG_ZMBV_DECODER 0
+#define CONFIG_AAC_DECODER 1
+#define CONFIG_AC3_DECODER 1
+#define CONFIG_ALAC_DECODER 1
+#define CONFIG_ALS_DECODER 1
+#define CONFIG_AMRNB_DECODER 1
+#define CONFIG_APE_DECODER 1
+#define CONFIG_ATRAC1_DECODER 1
+#define CONFIG_ATRAC3_DECODER 1
+#define CONFIG_BINKAUDIO_DCT_DECODER 1
+#define CONFIG_BINKAUDIO_RDFT_DECODER 1
+#define CONFIG_COOK_DECODER 1
+/* #define CONFIG_DCA_DECODER 1 */
+#define CONFIG_DSICINAUDIO_DECODER 1
+#define CONFIG_EAC3_DECODER 1
+#define CONFIG_FLAC_DECODER 1
+#define CONFIG_GSM_DECODER 1
+#define CONFIG_GSM_MS_DECODER 1
+#define CONFIG_IMC_DECODER 1
+#define CONFIG_MACE3_DECODER 1
+#define CONFIG_MACE6_DECODER 1
+#define CONFIG_MLP_DECODER 1
+#define CONFIG_MP1_DECODER 1
+#define CONFIG_MP1FLOAT_DECODER 1
+#define CONFIG_MP2_DECODER 1
+#define CONFIG_MP2FLOAT_DECODER 1
+#define CONFIG_MP3_DECODER 1
+#define CONFIG_MP3FLOAT_DECODER 1
+#define CONFIG_MP3ADU_DECODER 1
+#define CONFIG_MP3ADUFLOAT_DECODER 1
+#define CONFIG_MP3ON4_DECODER 1
+#define CONFIG_MP3ON4FLOAT_DECODER 1
+#define CONFIG_MPC7_DECODER 1
+#define CONFIG_MPC8_DECODER 1
+#define CONFIG_NELLYMOSER_DECODER 1
+#define CONFIG_QCELP_DECODER 1
+#define CONFIG_QDM2_DECODER 1
+#define CONFIG_RA_144_DECODER 1
+#define CONFIG_RA_288_DECODER 1
+#define CONFIG_SHORTEN_DECODER 1
+#define CONFIG_SIPR_DECODER 1
+#define CONFIG_SMACKAUD_DECODER 1
+#define CONFIG_SONIC_DECODER 1
+#define CONFIG_TRUEHD_DECODER 1
+#define CONFIG_TRUESPEECH_DECODER 1
+#define CONFIG_TTA_DECODER 1
+#define CONFIG_TWINVQ_DECODER 1
+#define CONFIG_VMDAUDIO_DECODER 1
+#define CONFIG_VORBIS_DECODER 1
+#define CONFIG_WAVPACK_DECODER 1
+#define CONFIG_WMAPRO_DECODER 1
+#define CONFIG_WMAV1_DECODER 1
+#define CONFIG_WMAV2_DECODER 1
+#define CONFIG_WMAVOICE_DECODER 1
+#define CONFIG_WS_SND1_DECODER 1
+#define CONFIG_PCM_ALAW_DECODER 1
+#define CONFIG_PCM_BLURAY_DECODER 1
+#define CONFIG_PCM_DVD_DECODER 1
+#define CONFIG_PCM_F32BE_DECODER 1
+#define CONFIG_PCM_F32LE_DECODER 1
+#define CONFIG_PCM_F64BE_DECODER 1
+#define CONFIG_PCM_F64LE_DECODER 1
+#define CONFIG_PCM_MULAW_DECODER 1
+#define CONFIG_PCM_S8_DECODER 1
+#define CONFIG_PCM_S16BE_DECODER 1
+#define CONFIG_PCM_S16LE_DECODER 1
+#define CONFIG_PCM_S16LE_PLANAR_DECODER 1
+#define CONFIG_PCM_S24BE_DECODER 1
+#define CONFIG_PCM_S24DAUD_DECODER 1
+#define CONFIG_PCM_S24LE_DECODER 1
+#define CONFIG_PCM_S32BE_DECODER 1
+#define CONFIG_PCM_S32LE_DECODER 1
+#define CONFIG_PCM_U8_DECODER 1
+#define CONFIG_PCM_U16BE_DECODER 1
+#define CONFIG_PCM_U16LE_DECODER 1
+#define CONFIG_PCM_U24BE_DECODER 1
+#define CONFIG_PCM_U24LE_DECODER 1
+#define CONFIG_PCM_U32BE_DECODER 1
+#define CONFIG_PCM_U32LE_DECODER 1
+#define CONFIG_PCM_ZORK_DECODER 1
+#define CONFIG_INTERPLAY_DPCM_DECODER 1
+#define CONFIG_ROQ_DPCM_DECODER 1
+#define CONFIG_SOL_DPCM_DECODER 1
+#define CONFIG_XAN_DPCM_DECODER 1
+#define CONFIG_ADPCM_4XM_DECODER 1
+#define CONFIG_ADPCM_ADX_DECODER 1
+#define CONFIG_ADPCM_CT_DECODER 1
+#define CONFIG_ADPCM_EA_DECODER 1
+#define CONFIG_ADPCM_EA_MAXIS_XA_DECODER 1
+#define CONFIG_ADPCM_EA_R1_DECODER 1
+#define CONFIG_ADPCM_EA_R2_DECODER 1
+#define CONFIG_ADPCM_EA_R3_DECODER 1
+#define CONFIG_ADPCM_EA_XAS_DECODER 1
+#define CONFIG_ADPCM_G726_DECODER 1
+#define CONFIG_ADPCM_IMA_AMV_DECODER 1
+#define CONFIG_ADPCM_IMA_DK3_DECODER 1
+#define CONFIG_ADPCM_IMA_DK4_DECODER 1
+#define CONFIG_ADPCM_IMA_EA_EACS_DECODER 1
+#define CONFIG_ADPCM_IMA_EA_SEAD_DECODER 1
+#define CONFIG_ADPCM_IMA_ISS_DECODER 1
+#define CONFIG_ADPCM_IMA_QT_DECODER 1
+#define CONFIG_ADPCM_IMA_SMJPEG_DECODER 1
+#define CONFIG_ADPCM_IMA_WAV_DECODER 1
+#define CONFIG_ADPCM_IMA_WS_DECODER 1
+#define CONFIG_ADPCM_MS_DECODER 1
+#define CONFIG_ADPCM_SBPRO_2_DECODER 1
+#define CONFIG_ADPCM_SBPRO_3_DECODER 1
+#define CONFIG_ADPCM_SBPRO_4_DECODER 1
+#define CONFIG_ADPCM_SWF_DECODER 1
+#define CONFIG_ADPCM_THP_DECODER 1
+#define CONFIG_ADPCM_XA_DECODER 1
+#define CONFIG_ADPCM_YAMAHA_DECODER 1
+#define CONFIG_DVBSUB_DECODER 1
+#define CONFIG_DVDSUB_DECODER 1
+#define CONFIG_PGSSUB_DECODER 1
+#define CONFIG_XSUB_DECODER 1
+#define CONFIG_LIBDIRAC_DECODER 0
+#define CONFIG_LIBGSM_DECODER 0
+#define CONFIG_LIBGSM_MS_DECODER 0
+#define CONFIG_LIBOPENCORE_AMRNB_DECODER 0
+#define CONFIG_LIBOPENCORE_AMRWB_DECODER 0
+#define CONFIG_LIBOPENJPEG_DECODER 0
+#define CONFIG_LIBSCHROEDINGER_DECODER 0
+#define CONFIG_LIBSPEEX_DECODER 0
+#define CONFIG_LIBVPX_DECODER 0
+#define CONFIG_ASV1_ENCODER 1
+#define CONFIG_ASV2_ENCODER 1
+#define CONFIG_BMP_ENCODER 1
+#define CONFIG_DNXHD_ENCODER 1
+#define CONFIG_DVVIDEO_ENCODER 1
+#define CONFIG_FFV1_ENCODER 1
+#define CONFIG_FFVHUFF_ENCODER 1
+#define CONFIG_FLASHSV_ENCODER 0
+#define CONFIG_FLV_ENCODER 1
+#define CONFIG_GIF_ENCODER 1
+#define CONFIG_H261_ENCODER 1
+#define CONFIG_H263_ENCODER 1
+#define CONFIG_H263P_ENCODER 1
+#define CONFIG_HUFFYUV_ENCODER 1
+#define CONFIG_JPEGLS_ENCODER 1
+#define CONFIG_LJPEG_ENCODER 1
+#define CONFIG_MJPEG_ENCODER 1
+#define CONFIG_MPEG1VIDEO_ENCODER 1
+#define CONFIG_MPEG2VIDEO_ENCODER 1
+#define CONFIG_MPEG4_ENCODER 1
+#define CONFIG_MSMPEG4V1_ENCODER 1
+#define CONFIG_MSMPEG4V2_ENCODER 1
+#define CONFIG_MSMPEG4V3_ENCODER 1
+#define CONFIG_PAM_ENCODER 1
+#define CONFIG_PBM_ENCODER 1
+#define CONFIG_PCX_ENCODER 1
+#define CONFIG_PGM_ENCODER 1
+#define CONFIG_PGMYUV_ENCODER 1
+#define CONFIG_PNG_ENCODER 0
+#define CONFIG_PPM_ENCODER 1
+#define CONFIG_QTRLE_ENCODER 1
+#define CONFIG_RAWVIDEO_ENCODER 1
+#define CONFIG_ROQ_ENCODER 1
+#define CONFIG_RV10_ENCODER 1
+#define CONFIG_RV20_ENCODER 1
+#define CONFIG_SGI_ENCODER 1
+#define CONFIG_SNOW_ENCODER 1
+#define CONFIG_SVQ1_ENCODER 1
+#define CONFIG_TARGA_ENCODER 1
+#define CONFIG_TIFF_ENCODER 1
+#define CONFIG_V210_ENCODER 1
+#define CONFIG_WMV1_ENCODER 1
+#define CONFIG_WMV2_ENCODER 1
+#define CONFIG_ZLIB_ENCODER 0
+#define CONFIG_ZMBV_ENCODER 0
+#define CONFIG_AAC_ENCODER 1
+#define CONFIG_AC3_ENCODER 1
+#define CONFIG_ALAC_ENCODER 1
+#define CONFIG_FLAC_ENCODER 1
+#define CONFIG_MP2_ENCODER 1
+#define CONFIG_NELLYMOSER_ENCODER 1
+#define CONFIG_RA_144_ENCODER 1
+#define CONFIG_SONIC_ENCODER 1
+#define CONFIG_SONIC_LS_ENCODER 1
+#define CONFIG_VORBIS_ENCODER 1
+#define CONFIG_WMAV1_ENCODER 1
+#define CONFIG_WMAV2_ENCODER 1
+#define CONFIG_PCM_ALAW_ENCODER 1
+#define CONFIG_PCM_F32BE_ENCODER 1
+#define CONFIG_PCM_F32LE_ENCODER 1
+#define CONFIG_PCM_F64BE_ENCODER 1
+#define CONFIG_PCM_F64LE_ENCODER 1
+#define CONFIG_PCM_MULAW_ENCODER 1
+#define CONFIG_PCM_S8_ENCODER 1
+#define CONFIG_PCM_S16BE_ENCODER 1
+#define CONFIG_PCM_S16LE_ENCODER 1
+#define CONFIG_PCM_S24BE_ENCODER 1
+#define CONFIG_PCM_S24DAUD_ENCODER 1
+#define CONFIG_PCM_S24LE_ENCODER 1
+#define CONFIG_PCM_S32BE_ENCODER 1
+#define CONFIG_PCM_S32LE_ENCODER 1
+#define CONFIG_PCM_U8_ENCODER 1
+#define CONFIG_PCM_U16BE_ENCODER 1
+#define CONFIG_PCM_U16LE_ENCODER 1
+#define CONFIG_PCM_U24BE_ENCODER 1
+#define CONFIG_PCM_U24LE_ENCODER 1
+#define CONFIG_PCM_U32BE_ENCODER 1
+#define CONFIG_PCM_U32LE_ENCODER 1
+#define CONFIG_PCM_ZORK_ENCODER 1
+#define CONFIG_ROQ_DPCM_ENCODER 1
+#define CONFIG_ADPCM_ADX_ENCODER 1
+#define CONFIG_ADPCM_G726_ENCODER 1
+#define CONFIG_ADPCM_IMA_QT_ENCODER 1
+#define CONFIG_ADPCM_IMA_WAV_ENCODER 1
+#define CONFIG_ADPCM_MS_ENCODER 1
+#define CONFIG_ADPCM_SWF_ENCODER 1
+#define CONFIG_ADPCM_YAMAHA_ENCODER 1
+#define CONFIG_DVBSUB_ENCODER 1
+#define CONFIG_DVDSUB_ENCODER 1
+#define CONFIG_XSUB_ENCODER 1
+#define CONFIG_LIBDIRAC_ENCODER 0
+#define CONFIG_LIBFAAC_ENCODER 0
+#define CONFIG_LIBGSM_ENCODER 0
+#define CONFIG_LIBGSM_MS_ENCODER 0
+#define CONFIG_LIBMP3LAME_ENCODER 0
+#define CONFIG_LIBOPENCORE_AMRNB_ENCODER 0
+#define CONFIG_LIBSCHROEDINGER_ENCODER 0
+#define CONFIG_LIBTHEORA_ENCODER 0
+#define CONFIG_LIBVORBIS_ENCODER 0
+#define CONFIG_LIBVPX_ENCODER 0
+#define CONFIG_LIBX264_ENCODER 0
+#define CONFIG_LIBXVID_ENCODER 0
+#define CONFIG_H263_VAAPI_HWACCEL 0
+#define CONFIG_H264_DXVA2_HWACCEL 0
+#define CONFIG_H264_VAAPI_HWACCEL 0
+#define CONFIG_MPEG2_DXVA2_HWACCEL 0
+#define CONFIG_MPEG2_VAAPI_HWACCEL 0
+#define CONFIG_MPEG4_VAAPI_HWACCEL 0
+#define CONFIG_VC1_DXVA2_HWACCEL 0
+#define CONFIG_VC1_VAAPI_HWACCEL 0
+#define CONFIG_WMV3_DXVA2_HWACCEL 0
+#define CONFIG_WMV3_VAAPI_HWACCEL 0
+#define CONFIG_AAC_PARSER 1
+#define CONFIG_AC3_PARSER 1
+#define CONFIG_CAVSVIDEO_PARSER 1
+#define CONFIG_DCA_PARSER 1
+#define CONFIG_DIRAC_PARSER 1
+#define CONFIG_DNXHD_PARSER 1
+#define CONFIG_DVBSUB_PARSER 1
+#define CONFIG_DVDSUB_PARSER 1
+#define CONFIG_H261_PARSER 1
+#define CONFIG_H263_PARSER 1
+#define CONFIG_H264_PARSER 1
+#define CONFIG_MJPEG_PARSER 1
+#define CONFIG_MLP_PARSER 1
+#define CONFIG_MPEG4VIDEO_PARSER 1
+#define CONFIG_MPEGAUDIO_PARSER 1
+#define CONFIG_MPEGVIDEO_PARSER 1
+#define CONFIG_PNM_PARSER 1
+#define CONFIG_VC1_PARSER 1
+#define CONFIG_VP3_PARSER 1
+#define CONFIG_VP8_PARSER 1
+#define CONFIG_AAC_ADTSTOASC_BSF 1
+#define CONFIG_CHOMP_BSF 1
+#define CONFIG_DUMP_EXTRADATA_BSF 1
+#define CONFIG_H264_MP4TOANNEXB_BSF 1
+#define CONFIG_IMX_DUMP_HEADER_BSF 1
+#define CONFIG_MJPEGA_DUMP_HEADER_BSF 1
+#define CONFIG_MP3_HEADER_COMPRESS_BSF 1
+#define CONFIG_MP3_HEADER_DECOMPRESS_BSF 1
+#define CONFIG_MOV2TEXTSUB_BSF 1
+#define CONFIG_NOISE_BSF 1
+#define CONFIG_REMOVE_EXTRADATA_BSF 1
+#define CONFIG_TEXT2MOVSUB_BSF 1
+#define CONFIG_AAC_DEMUXER 1
+#define CONFIG_AC3_DEMUXER 1
+#define CONFIG_AEA_DEMUXER 1
+#define CONFIG_AIFF_DEMUXER 1
+#define CONFIG_AMR_DEMUXER 1
+#define CONFIG_ANM_DEMUXER 1
+#define CONFIG_APC_DEMUXER 1
+#define CONFIG_APE_DEMUXER 1
+#define CONFIG_ASF_DEMUXER 1
+#define CONFIG_ASS_DEMUXER 1
+#define CONFIG_AU_DEMUXER 1
+#define CONFIG_AVI_DEMUXER 1
+#define CONFIG_AVISYNTH_DEMUXER 0
+#define CONFIG_AVS_DEMUXER 1
+#define CONFIG_BETHSOFTVID_DEMUXER 1
+#define CONFIG_BFI_DEMUXER 1
+#define CONFIG_BINK_DEMUXER 1
+#define CONFIG_C93_DEMUXER 1
+#define CONFIG_CAF_DEMUXER 1
+#define CONFIG_CAVSVIDEO_DEMUXER 1
+#define CONFIG_CDG_DEMUXER 1
+#define CONFIG_DAUD_DEMUXER 1
+#define CONFIG_DIRAC_DEMUXER 1
+#define CONFIG_DNXHD_DEMUXER 1
+#define CONFIG_DSICIN_DEMUXER 1
+#define CONFIG_DTS_DEMUXER 1
+#define CONFIG_DV_DEMUXER 1
+#define CONFIG_DXA_DEMUXER 1
+#define CONFIG_EA_DEMUXER 1
+#define CONFIG_EA_CDATA_DEMUXER 1
+#define CONFIG_EAC3_DEMUXER 1
+#define CONFIG_FFM_DEMUXER 1
+#define CONFIG_FILMSTRIP_DEMUXER 1
+#define CONFIG_FLAC_DEMUXER 1
+#define CONFIG_FLIC_DEMUXER 1
+#define CONFIG_FLV_DEMUXER 1
+#define CONFIG_FOURXM_DEMUXER 1
+#define CONFIG_GSM_DEMUXER 1
+#define CONFIG_GXF_DEMUXER 1
+#define CONFIG_H261_DEMUXER 1
+#define CONFIG_H263_DEMUXER 1
+#define CONFIG_H264_DEMUXER 1
+#define CONFIG_IDCIN_DEMUXER 1
+#define CONFIG_IFF_DEMUXER 1
+#define CONFIG_IMAGE2_DEMUXER 1
+#define CONFIG_IMAGE2PIPE_DEMUXER 1
+#define CONFIG_INGENIENT_DEMUXER 1
+#define CONFIG_IPMOVIE_DEMUXER 1
+#define CONFIG_ISS_DEMUXER 1
+#define CONFIG_IV8_DEMUXER 1
+#define CONFIG_IVF_DEMUXER 1
+#define CONFIG_LMLM4_DEMUXER 1
+#define CONFIG_M4V_DEMUXER 1
+#define CONFIG_MATROSKA_DEMUXER 1
+#define CONFIG_MJPEG_DEMUXER 1
+#define CONFIG_MLP_DEMUXER 1
+#define CONFIG_MM_DEMUXER 1
+#define CONFIG_MMF_DEMUXER 1
+#define CONFIG_MOV_DEMUXER 1
+#define CONFIG_MP3_DEMUXER 1
+#define CONFIG_MPC_DEMUXER 1
+#define CONFIG_MPC8_DEMUXER 1
+#define CONFIG_MPEGPS_DEMUXER 1
+#define CONFIG_MPEGTS_DEMUXER 1
+#define CONFIG_MPEGTSRAW_DEMUXER 1
+#define CONFIG_MPEGVIDEO_DEMUXER 1
+#define CONFIG_MSNWC_TCP_DEMUXER 1
+#define CONFIG_MTV_DEMUXER 1
+#define CONFIG_MVI_DEMUXER 1
+#define CONFIG_MXF_DEMUXER 1
+#define CONFIG_NC_DEMUXER 1
+#define CONFIG_NSV_DEMUXER 1
+#define CONFIG_NUT_DEMUXER 1
+#define CONFIG_NUV_DEMUXER 1
+#define CONFIG_OGG_DEMUXER 1
+#define CONFIG_OMA_DEMUXER 1
+#define CONFIG_PCM_ALAW_DEMUXER 1
+#define CONFIG_PCM_MULAW_DEMUXER 1
+#define CONFIG_PCM_F64BE_DEMUXER 1
+#define CONFIG_PCM_F64LE_DEMUXER 1
+#define CONFIG_PCM_F32BE_DEMUXER 1
+#define CONFIG_PCM_F32LE_DEMUXER 1
+#define CONFIG_PCM_S32BE_DEMUXER 1
+#define CONFIG_PCM_S32LE_DEMUXER 1
+#define CONFIG_PCM_S24BE_DEMUXER 1
+#define CONFIG_PCM_S24LE_DEMUXER 1
+#define CONFIG_PCM_S16BE_DEMUXER 1
+#define CONFIG_PCM_S16LE_DEMUXER 1
+#define CONFIG_PCM_S8_DEMUXER 1
+#define CONFIG_PCM_U32BE_DEMUXER 1
+#define CONFIG_PCM_U32LE_DEMUXER 1
+#define CONFIG_PCM_U24BE_DEMUXER 1
+#define CONFIG_PCM_U24LE_DEMUXER 1
+#define CONFIG_PCM_U16BE_DEMUXER 1
+#define CONFIG_PCM_U16LE_DEMUXER 1
+#define CONFIG_PCM_U8_DEMUXER 1
+#define CONFIG_PVA_DEMUXER 1
+#define CONFIG_QCP_DEMUXER 1
+#define CONFIG_R3D_DEMUXER 1
+#define CONFIG_RAWVIDEO_DEMUXER 1
+#define CONFIG_RL2_DEMUXER 1
+#define CONFIG_RM_DEMUXER 1
+#define CONFIG_ROQ_DEMUXER 1
+#define CONFIG_RPL_DEMUXER 1
+#define CONFIG_RTSP_DEMUXER 1
+#define CONFIG_SDP_DEMUXER 1
+#define CONFIG_SEGAFILM_DEMUXER 1
+#define CONFIG_SHORTEN_DEMUXER 1
+#define CONFIG_SIFF_DEMUXER 1
+#define CONFIG_SMACKER_DEMUXER 1
+#define CONFIG_SOL_DEMUXER 1
+#define CONFIG_SOX_DEMUXER 1
+#define CONFIG_STR_DEMUXER 1
+#define CONFIG_SWF_DEMUXER 1
+#define CONFIG_THP_DEMUXER 1
+#define CONFIG_TIERTEXSEQ_DEMUXER 1
+#define CONFIG_TMV_DEMUXER 1
+#define CONFIG_TRUEHD_DEMUXER 1
+#define CONFIG_TTA_DEMUXER 1
+#define CONFIG_TXD_DEMUXER 1
+#define CONFIG_VC1_DEMUXER 1
+#define CONFIG_VC1T_DEMUXER 1
+#define CONFIG_VMD_DEMUXER 1
+#define CONFIG_VOC_DEMUXER 1
+#define CONFIG_VQF_DEMUXER 1
+#define CONFIG_W64_DEMUXER 1
+#define CONFIG_WAV_DEMUXER 1
+#define CONFIG_WC3_DEMUXER 1
+#define CONFIG_WSAUD_DEMUXER 1
+#define CONFIG_WSVQA_DEMUXER 1
+#define CONFIG_WV_DEMUXER 1
+#define CONFIG_XA_DEMUXER 1
+#define CONFIG_YOP_DEMUXER 1
+#define CONFIG_YUV4MPEGPIPE_DEMUXER 1
+#define CONFIG_LIBNUT_DEMUXER 0
+#define CONFIG_AC3_MUXER 1
+#define CONFIG_ADTS_MUXER 1
+#define CONFIG_AIFF_MUXER 1
+#define CONFIG_AMR_MUXER 1
+#define CONFIG_ASF_MUXER 1
+#define CONFIG_ASS_MUXER 1
+#define CONFIG_ASF_STREAM_MUXER 1
+#define CONFIG_AU_MUXER 1
+#define CONFIG_AVI_MUXER 1
+#define CONFIG_AVM2_MUXER 1
+#define CONFIG_CRC_MUXER 1
+#define CONFIG_DAUD_MUXER 1
+#define CONFIG_DIRAC_MUXER 1
+#define CONFIG_DNXHD_MUXER 1
+#define CONFIG_DTS_MUXER 1
+#define CONFIG_DV_MUXER 1
+#define CONFIG_EAC3_MUXER 1
+#define CONFIG_FFM_MUXER 1
+#define CONFIG_FILMSTRIP_MUXER 1
+#define CONFIG_FLAC_MUXER 1
+#define CONFIG_FLV_MUXER 1
+#define CONFIG_FRAMECRC_MUXER 1
+#define CONFIG_FRAMEMD5_MUXER 1
+#define CONFIG_GIF_MUXER 1
+#define CONFIG_GXF_MUXER 1
+#define CONFIG_H261_MUXER 1
+#define CONFIG_H263_MUXER 1
+#define CONFIG_H264_MUXER 1
+#define CONFIG_IMAGE2_MUXER 1
+#define CONFIG_IMAGE2PIPE_MUXER 1
+#define CONFIG_IPOD_MUXER 1
+#define CONFIG_M4V_MUXER 1
+#define CONFIG_MD5_MUXER 1
+#define CONFIG_MATROSKA_MUXER 1
+#define CONFIG_MATROSKA_AUDIO_MUXER 1
+#define CONFIG_MJPEG_MUXER 1
+#define CONFIG_MLP_MUXER 1
+#define CONFIG_MMF_MUXER 1
+#define CONFIG_MOV_MUXER 1
+#define CONFIG_MP2_MUXER 1
+#define CONFIG_MP3_MUXER 1
+#define CONFIG_MP4_MUXER 1
+#define CONFIG_MPEG1SYSTEM_MUXER 1
+#define CONFIG_MPEG1VCD_MUXER 1
+#define CONFIG_MPEG1VIDEO_MUXER 1
+#define CONFIG_MPEG2DVD_MUXER 1
+#define CONFIG_MPEG2SVCD_MUXER 1
+#define CONFIG_MPEG2VIDEO_MUXER 1
+#define CONFIG_MPEG2VOB_MUXER 1
+#define CONFIG_MPEGTS_MUXER 1
+#define CONFIG_MPJPEG_MUXER 1
+#define CONFIG_MXF_MUXER 1
+#define CONFIG_MXF_D10_MUXER 1
+#define CONFIG_NULL_MUXER 1
+#define CONFIG_NUT_MUXER 1
+#define CONFIG_OGG_MUXER 1
+#define CONFIG_PCM_ALAW_MUXER 1
+#define CONFIG_PCM_MULAW_MUXER 1
+#define CONFIG_PCM_F64BE_MUXER 1
+#define CONFIG_PCM_F64LE_MUXER 1
+#define CONFIG_PCM_F32BE_MUXER 1
+#define CONFIG_PCM_F32LE_MUXER 1
+#define CONFIG_PCM_S32BE_MUXER 1
+#define CONFIG_PCM_S32LE_MUXER 1
+#define CONFIG_PCM_S24BE_MUXER 1
+#define CONFIG_PCM_S24LE_MUXER 1
+#define CONFIG_PCM_S16BE_MUXER 1
+#define CONFIG_PCM_S16LE_MUXER 1
+#define CONFIG_PCM_S8_MUXER 1
+#define CONFIG_PCM_U32BE_MUXER 1
+#define CONFIG_PCM_U32LE_MUXER 1
+#define CONFIG_PCM_U24BE_MUXER 1
+#define CONFIG_PCM_U24LE_MUXER 1
+#define CONFIG_PCM_U16BE_MUXER 1
+#define CONFIG_PCM_U16LE_MUXER 1
+#define CONFIG_PCM_U8_MUXER 1
+#define CONFIG_PSP_MUXER 1
+#define CONFIG_RAWVIDEO_MUXER 1
+#define CONFIG_RM_MUXER 1
+#define CONFIG_ROQ_MUXER 1
+#define CONFIG_RTP_MUXER 1
+#define CONFIG_RTSP_MUXER 1
+#define CONFIG_SOX_MUXER 1
+#define CONFIG_SPDIF_MUXER 1
+#define CONFIG_SWF_MUXER 1
+#define CONFIG_TG2_MUXER 1
+#define CONFIG_TGP_MUXER 1
+#define CONFIG_TRUEHD_MUXER 1
+#define CONFIG_VC1T_MUXER 1
+#define CONFIG_VOC_MUXER 1
+#define CONFIG_WAV_MUXER 1
+#define CONFIG_WEBM_MUXER 1
+#define CONFIG_YUV4MPEGPIPE_MUXER 1
+#define CONFIG_LIBNUT_MUXER 0
+#define CONFIG_ASPECT_FILTER 1
+#define CONFIG_CROP_FILTER 1
+#define CONFIG_FORMAT_FILTER 1
+#define CONFIG_NOFORMAT_FILTER 1
+#define CONFIG_NULL_FILTER 1
+#define CONFIG_PAD_FILTER 1
+#define CONFIG_PIXDESCTEST_FILTER 1
+#define CONFIG_PIXELASPECT_FILTER 1
+#define CONFIG_SCALE_FILTER 1
+#define CONFIG_SLICIFY_FILTER 1
+#define CONFIG_UNSHARP_FILTER 1
+#define CONFIG_VFLIP_FILTER 1
+#define CONFIG_BUFFER_FILTER 1
+#define CONFIG_NULLSRC_FILTER 1
+#define CONFIG_NULLSINK_FILTER 1
+#define CONFIG_FILE_PROTOCOL 1
+#define CONFIG_GOPHER_PROTOCOL 1
+#define CONFIG_HTTP_PROTOCOL 1
+#define CONFIG_MMST_PROTOCOL 1
+#define CONFIG_PIPE_PROTOCOL 1
+#define CONFIG_RTMP_PROTOCOL 1
+#define CONFIG_RTMPT_PROTOCOL 1
+#define CONFIG_RTMPE_PROTOCOL 1
+#define CONFIG_RTMPTE_PROTOCOL 1
+#define CONFIG_RTMPS_PROTOCOL 1
+#define CONFIG_RTP_PROTOCOL 1
+#define CONFIG_TCP_PROTOCOL 1
+#define CONFIG_UDP_PROTOCOL 1
+#define CONFIG_CONCAT_PROTOCOL 1
+#define CONFIG_ALSA_INDEV 0
+#define CONFIG_BKTR_INDEV 0
+#define CONFIG_DV1394_INDEV 1
+#define CONFIG_JACK_INDEV 0
+#define CONFIG_OSS_INDEV 1
+#define CONFIG_V4L2_INDEV 1
+#define CONFIG_V4L_INDEV 1
+#define CONFIG_VFWCAP_INDEV 0
+#define CONFIG_X11_GRAB_DEVICE_INDEV 0
+#define CONFIG_LIBDC1394_INDEV 0
+#define CONFIG_ALSA_OUTDEV 0
+#define CONFIG_OSS_OUTDEV 1
+#endif /* FFMPEG_CONFIG_H */
diff --git a/plugins/supereq/ffmpeg_fft/ffmpeg_fft.h b/plugins/supereq/ffmpeg_fft/ffmpeg_fft.h
new file mode 100644
index 00000000..b98313d2
--- /dev/null
+++ b/plugins/supereq/ffmpeg_fft/ffmpeg_fft.h
@@ -0,0 +1,95 @@
+/*
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVCODEC_AVFFT_H
+#define AVCODEC_AVFFT_H
+
+typedef float FFTSample;
+
+typedef struct FFTComplex {
+ FFTSample re, im;
+} FFTComplex;
+
+//#define FFTC_SZ 32
+typedef struct FFTContext FFTContext;
+
+/**
+ * Set up a complex FFT.
+ * @param nbits log2 of the length of the input array
+ * @param inverse if 0 perform the forward transform, if 1 perform the inverse
+ */
+FFTContext *av_fft_init(int nbits, int inverse);
+
+/**
+ * Do the permutation needed BEFORE calling ff_fft_calc().
+ */
+void av_fft_permute(FFTContext *s, FFTComplex *z);
+
+/**
+ * Do a complex FFT with the parameters defined in av_fft_init(). The
+ * input data must be permuted before. No 1.0/sqrt(n) normalization is done.
+ */
+void av_fft_calc(FFTContext *s, FFTComplex *z);
+
+void av_fft_end(FFTContext *s);
+
+/* Real Discrete Fourier Transform */
+
+enum RDFTransformType {
+ DFT_R2C,
+ IDFT_C2R,
+ IDFT_R2C,
+ DFT_C2R,
+};
+
+//#define RDFTC_SZ 56
+typedef struct RDFTContext RDFTContext;
+
+/**
+ * Set up a real FFT.
+ * @param nbits log2 of the length of the input array
+ * @param trans the type of transform
+ */
+RDFTContext *av_rdft_init(int nbits, enum RDFTransformType trans);
+void av_rdft_calc(RDFTContext *s, FFTSample *data);
+void av_rdft_end(RDFTContext *s);
+
+/* Discrete Cosine Transform */
+
+typedef struct DCTContext DCTContext;
+
+enum DCTTransformType {
+ DCT_II = 0,
+ DCT_III,
+ DCT_I,
+ DST_I,
+};
+
+/**
+ * Set up DCT.
+ * @param nbits size of the input array:
+ * (1 << nbits) for DCT-II, DCT-III and DST-I
+ * (1 << nbits) + 1 for DCT-I
+ *
+ * @note the first element of the input of DST-I is ignored
+ */
+DCTContext *av_dct_init(int nbits, enum DCTTransformType type);
+void av_dct_calc(DCTContext *s, FFTSample *data);
+void av_dct_end (DCTContext *s);
+
+#endif /* AVCODEC_AVFFT_H */
diff --git a/plugins/supereq/ffmpeg_fft/libavcodec/arm/asm.S b/plugins/supereq/ffmpeg_fft/libavcodec/arm/asm.S
new file mode 100644
index 00000000..6860f1cf
--- /dev/null
+++ b/plugins/supereq/ffmpeg_fft/libavcodec/arm/asm.S
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2008 Mans Rullgard <mans@mansr.com>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+
+#ifdef __ELF__
+# define ELF
+#else
+# define ELF @
+#endif
+
+.macro require8 val=1
+ELF .eabi_attribute 24, \val
+.endm
+
+.macro preserve8 val=1
+ELF .eabi_attribute 25, \val
+.endm
+
+/*
+.macro function name, export=0
+ .macro endfunc
+ELF .size \name, . - \name
+ .endfunc
+ .purgem endfunc
+ .endm
+ .text
+ .if \export
+ .global EXTERN_ASM\name
+EXTERN_ASM\name:
+ .endif
+ELF .type \name, %function
+ .func \name
+\name:
+.endm
+*/
+
+.macro function name, export=0
+ .macro endfunc
+ELF .size \name, . - \name
+ .endfunc
+ .purgem endfunc
+ .endm
+ .text
+ .if \export
+ .hidden EXTERN_ASM\name
+ .global EXTERN_ASM\name
+EXTERN_ASM\name:
+ .endif
+ELF .type \name, %function
+ .func \name
+\name:
+.endm
+
+.macro mov32 rd, val
+#if HAVE_ARMV6T2
+ movw \rd, #(\val) & 0xffff
+ .if (\val) >> 16
+ movt \rd, #(\val) >> 16
+ .endif
+#else
+ ldr \rd, =\val
+#endif
+.endm
+
+.macro movrel rd, val
+#if HAVE_ARMV6T2 && !CONFIG_PIC
+ movw \rd, #:lower16:\val
+ movt \rd, #:upper16:\val
+#else
+ ldr \rd, =\val
+#endif
+.endm
+
+#if HAVE_VFP_ARGS
+ .eabi_attribute 28, 1
+# define VFP
+# define NOVFP @
+#else
+# define VFP @
+# define NOVFP
+#endif
+
+#define GLUE(a, b) a ## b
+#define JOIN(a, b) GLUE(a, b)
+#define X(s) JOIN(EXTERN_ASM, s)
+
diff --git a/plugins/supereq/ffmpeg_fft/libavcodec/arm/fft_init_arm.c b/plugins/supereq/ffmpeg_fft/libavcodec/arm/fft_init_arm.c
new file mode 100644
index 00000000..28148e92
--- /dev/null
+++ b/plugins/supereq/ffmpeg_fft/libavcodec/arm/fft_init_arm.c
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2009 Mans Rullgard <mans@mansr.com>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libavcodec/fft.h"
+#if CONFIG_DCA_DECODER
+#include "libavcodec/synth_filter.h"
+#endif
+
+void ff_fft_permute_neon(FFTContext *s, FFTComplex *z);
+void ff_fft_calc_neon(FFTContext *s, FFTComplex *z);
+
+#if 0
+void ff_imdct_calc_neon(FFTContext *s, FFTSample *output, const FFTSample *input);
+void ff_imdct_half_neon(FFTContext *s, FFTSample *output, const FFTSample *input);
+void ff_mdct_calc_neon(FFTContext *s, FFTSample *output, const FFTSample *input);
+#endif
+
+void ff_rdft_calc_neon(struct RDFTContext *s, FFTSample *z);
+
+void ff_synth_filter_float_neon(FFTContext *imdct,
+ float *synth_buf_ptr, int *synth_buf_offset,
+ float synth_buf2[32], const float window[512],
+ float out[32], const float in[32],
+ float scale, float bias);
+
+av_cold void ff_fft_init_arm(FFTContext *s)
+{
+ if (HAVE_NEON) {
+ s->fft_permute = ff_fft_permute_neon;
+ s->fft_calc = ff_fft_calc_neon;
+#if 0
+ s->imdct_calc = ff_imdct_calc_neon;
+ s->imdct_half = ff_imdct_half_neon;
+ s->mdct_calc = ff_mdct_calc_neon;
+ s->permutation = FF_MDCT_PERM_INTERLEAVE;
+#endif
+ }
+}
+
+#if CONFIG_RDFT
+av_cold void ff_rdft_init_arm(RDFTContext *s)
+{
+ if (HAVE_NEON)
+ s->rdft_calc = ff_rdft_calc_neon;
+}
+#endif
+
+#if CONFIG_DCA_DECODER
+av_cold void ff_synth_filter_init_arm(SynthFilterContext *s)
+{
+ if (HAVE_NEON)
+ s->synth_filter_float = ff_synth_filter_float_neon;
+}
+#endif
diff --git a/plugins/supereq/ffmpeg_fft/libavcodec/arm/fft_neon.S b/plugins/supereq/ffmpeg_fft/libavcodec/arm/fft_neon.S
new file mode 100644
index 00000000..117f4fee
--- /dev/null
+++ b/plugins/supereq/ffmpeg_fft/libavcodec/arm/fft_neon.S
@@ -0,0 +1,372 @@
+/*
+ * ARM NEON optimised FFT
+ *
+ * Copyright (c) 2009 Mans Rullgard <mans@mansr.com>
+ * Copyright (c) 2009 Naotoshi Nojiri
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "asm.S"
+
+#define M_SQRT1_2 0.70710678118654752440
+
+ .text
+
+function fft4_neon
+ vld1.32 {d0-d3}, [r0,:128]
+
+ vext.32 q8, q1, q1, #1 @ i2,r3 d3=i3,r2
+ vsub.f32 d6, d0, d1 @ r0-r1,i0-i1
+ vsub.f32 d7, d16, d17 @ r3-r2,i2-i3
+ vadd.f32 d4, d0, d1 @ r0+r1,i0+i1
+ vadd.f32 d5, d2, d3 @ i2+i3,r2+r3
+ vadd.f32 d1, d6, d7
+ vsub.f32 d3, d6, d7
+ vadd.f32 d0, d4, d5
+ vsub.f32 d2, d4, d5
+
+ vst1.32 {d0-d3}, [r0,:128]
+
+ bx lr
+endfunc
+
+function fft8_neon
+ mov r1, r0
+ vld1.32 {d0-d3}, [r1,:128]!
+ vld1.32 {d16-d19}, [r1,:128]
+
+ movw r2, #0x04f3 @ sqrt(1/2)
+ movt r2, #0x3f35
+ eor r3, r2, #1<<31
+ vdup.32 d31, r2
+
+ vext.32 q11, q1, q1, #1 @ i2,r3,i3,r2
+ vadd.f32 d4, d16, d17 @ r4+r5,i4+i5
+ vmov d28, r3, r2
+ vadd.f32 d5, d18, d19 @ r6+r7,i6+i7
+ vsub.f32 d17, d16, d17 @ r4-r5,i4-i5
+ vsub.f32 d19, d18, d19 @ r6-r7,i6-i7
+ vrev64.32 d29, d28
+ vadd.f32 d20, d0, d1 @ r0+r1,i0+i1
+ vadd.f32 d21, d2, d3 @ r2+r3,i2+i3
+ vmul.f32 d26, d17, d28 @ -a2r*w,a2i*w
+ vext.32 q3, q2, q2, #1
+ vmul.f32 d27, d19, d29 @ a3r*w,-a3i*w
+ vsub.f32 d23, d22, d23 @ i2-i3,r3-r2
+ vsub.f32 d22, d0, d1 @ r0-r1,i0-i1
+ vmul.f32 d24, d17, d31 @ a2r*w,a2i*w
+ vmul.f32 d25, d19, d31 @ a3r*w,a3i*w
+ vadd.f32 d0, d20, d21
+ vsub.f32 d2, d20, d21
+ vadd.f32 d1, d22, d23
+ vrev64.32 q13, q13
+ vsub.f32 d3, d22, d23
+ vsub.f32 d6, d6, d7
+ vadd.f32 d24, d24, d26 @ a2r+a2i,a2i-a2r t1,t2
+ vadd.f32 d25, d25, d27 @ a3r-a3i,a3i+a3r t5,t6
+ vadd.f32 d7, d4, d5
+ vsub.f32 d18, d2, d6
+ vext.32 q13, q12, q12, #1
+ vadd.f32 d2, d2, d6
+ vsub.f32 d16, d0, d7
+ vadd.f32 d5, d25, d24
+ vsub.f32 d4, d26, d27
+ vadd.f32 d0, d0, d7
+ vsub.f32 d17, d1, d5
+ vsub.f32 d19, d3, d4
+ vadd.f32 d3, d3, d4
+ vadd.f32 d1, d1, d5
+
+ vst1.32 {d16-d19}, [r1,:128]
+ vst1.32 {d0-d3}, [r0,:128]
+
+ bx lr
+endfunc
+
+function fft16_neon
+ movrel r1, mppm
+ vld1.32 {d16-d19}, [r0,:128]! @ q8{r0,i0,r1,i1} q9{r2,i2,r3,i3}
+ pld [r0, #32]
+ vld1.32 {d2-d3}, [r1,:128]
+ vext.32 q13, q9, q9, #1
+ vld1.32 {d22-d25}, [r0,:128]! @ q11{r4,i4,r5,i5} q12{r6,i5,r7,i7}
+ vadd.f32 d4, d16, d17
+ vsub.f32 d5, d16, d17
+ vadd.f32 d18, d18, d19
+ vsub.f32 d19, d26, d27
+
+ vadd.f32 d20, d22, d23
+ vsub.f32 d22, d22, d23
+ vsub.f32 d23, d24, d25
+ vadd.f32 q8, q2, q9 @ {r0,i0,r1,i1}
+ vadd.f32 d21, d24, d25
+ vmul.f32 d24, d22, d2
+ vsub.f32 q9, q2, q9 @ {r2,i2,r3,i3}
+ vmul.f32 d25, d23, d3
+ vuzp.32 d16, d17 @ {r0,r1,i0,i1}
+ vmul.f32 q1, q11, d2[1]
+ vuzp.32 d18, d19 @ {r2,r3,i2,i3}
+ vrev64.32 q12, q12
+ vadd.f32 q11, q12, q1 @ {t1a,t2a,t5,t6}
+ vld1.32 {d24-d27}, [r0,:128]! @ q12{r8,i8,r9,i9} q13{r10,i10,r11,i11}
+ vzip.32 q10, q11
+ vld1.32 {d28-d31}, [r0,:128] @ q14{r12,i12,r13,i13} q15{r14,i14,r15,i15}
+ vadd.f32 d0, d22, d20
+ vadd.f32 d1, d21, d23
+ vsub.f32 d2, d21, d23
+ vsub.f32 d3, d22, d20
+ sub r0, r0, #96
+ vext.32 q13, q13, q13, #1
+ vsub.f32 q10, q8, q0 @ {r4,r5,i4,i5}
+ vadd.f32 q8, q8, q0 @ {r0,r1,i0,i1}
+ vext.32 q15, q15, q15, #1
+ vsub.f32 q11, q9, q1 @ {r6,r7,i6,i7}
+ vswp d25, d26 @ q12{r8,i8,i10,r11} q13{r9,i9,i11,r10}
+ vadd.f32 q9, q9, q1 @ {r2,r3,i2,i3}
+ vswp d29, d30 @ q14{r12,i12,i14,r15} q15{r13,i13,i15,r14}
+ vadd.f32 q0, q12, q13 @ {t1,t2,t5,t6}
+ vadd.f32 q1, q14, q15 @ {t1a,t2a,t5a,t6a}
+ movrel r2, X(ff_cos_16)
+ vsub.f32 q13, q12, q13 @ {t3,t4,t7,t8}
+ vrev64.32 d1, d1
+ vsub.f32 q15, q14, q15 @ {t3a,t4a,t7a,t8a}
+ vrev64.32 d3, d3
+ movrel r3, pmmp
+ vswp d1, d26 @ q0{t1,t2,t3,t4} q13{t6,t5,t7,t8}
+ vswp d3, d30 @ q1{t1a,t2a,t3a,t4a} q15{t6a,t5a,t7a,t8a}
+ vadd.f32 q12, q0, q13 @ {r8,i8,r9,i9}
+ vadd.f32 q14, q1, q15 @ {r12,i12,r13,i13}
+ vld1.32 {d4-d5}, [r2,:64]
+ vsub.f32 q13, q0, q13 @ {r10,i10,r11,i11}
+ vsub.f32 q15, q1, q15 @ {r14,i14,r15,i15}
+ vswp d25, d28 @ q12{r8,i8,r12,i12} q14{r9,i9,r13,i13}
+ vld1.32 {d6-d7}, [r3,:128]
+ vrev64.32 q1, q14
+ vmul.f32 q14, q14, d4[1]
+ vmul.f32 q1, q1, q3
+ vmla.f32 q14, q1, d5[1] @ {t1a,t2a,t5a,t6a}
+ vswp d27, d30 @ q13{r10,i10,r14,i14} q15{r11,i11,r15,i15}
+ vzip.32 q12, q14
+ vadd.f32 d0, d28, d24
+ vadd.f32 d1, d25, d29
+ vsub.f32 d2, d25, d29
+ vsub.f32 d3, d28, d24
+ vsub.f32 q12, q8, q0 @ {r8,r9,i8,i9}
+ vadd.f32 q8, q8, q0 @ {r0,r1,i0,i1}
+ vsub.f32 q14, q10, q1 @ {r12,r13,i12,i13}
+ mov r1, #32
+ vadd.f32 q10, q10, q1 @ {r4,r5,i4,i5}
+ vrev64.32 q0, q13
+ vmul.f32 q13, q13, d5[0]
+ vrev64.32 q1, q15
+ vmul.f32 q15, q15, d5[1]
+ vst2.32 {d16-d17},[r0,:128], r1
+ vmul.f32 q0, q0, q3
+ vst2.32 {d20-d21},[r0,:128], r1
+ vmul.f32 q1, q1, q3
+ vmla.f32 q13, q0, d5[0] @ {t1,t2,t5,t6}
+ vmla.f32 q15, q1, d4[1] @ {t1a,t2a,t5a,t6a}
+ vst2.32 {d24-d25},[r0,:128], r1
+ vst2.32 {d28-d29},[r0,:128]
+ vzip.32 q13, q15
+ sub r0, r0, #80
+ vadd.f32 d0, d30, d26
+ vadd.f32 d1, d27, d31
+ vsub.f32 d2, d27, d31
+ vsub.f32 d3, d30, d26
+ vsub.f32 q13, q9, q0 @ {r10,r11,i10,i11}
+ vadd.f32 q9, q9, q0 @ {r2,r3,i2,i3}
+ vsub.f32 q15, q11, q1 @ {r14,r15,i14,i15}
+ vadd.f32 q11, q11, q1 @ {r6,r7,i6,i7}
+ vst2.32 {d18-d19},[r0,:128], r1
+ vst2.32 {d22-d23},[r0,:128], r1
+ vst2.32 {d26-d27},[r0,:128], r1
+ vst2.32 {d30-d31},[r0,:128]
+ bx lr
+endfunc
+
+function fft_pass_neon
+ push {r4-r6,lr}
+ mov r6, r2 @ n
+ lsl r5, r2, #3 @ 2 * n * sizeof FFTSample
+ lsl r4, r2, #4 @ 2 * n * sizeof FFTComplex
+ lsl r2, r2, #5 @ 4 * n * sizeof FFTComplex
+ add r3, r2, r4
+ add r4, r4, r0 @ &z[o1]
+ add r2, r2, r0 @ &z[o2]
+ add r3, r3, r0 @ &z[o3]
+ vld1.32 {d20-d21},[r2,:128] @ {z[o2],z[o2+1]}
+ movrel r12, pmmp
+ vld1.32 {d22-d23},[r3,:128] @ {z[o3],z[o3+1]}
+ add r5, r5, r1 @ wim
+ vld1.32 {d6-d7}, [r12,:128] @ pmmp
+ vswp d21, d22
+ vld1.32 {d4}, [r1,:64]! @ {wre[0],wre[1]}
+ sub r5, r5, #4 @ wim--
+ vrev64.32 q1, q11
+ vmul.f32 q11, q11, d4[1]
+ vmul.f32 q1, q1, q3
+ vld1.32 {d5[0]}, [r5,:32] @ d5[0] = wim[-1]
+ vmla.f32 q11, q1, d5[0] @ {t1a,t2a,t5a,t6a}
+ vld2.32 {d16-d17},[r0,:128] @ {z[0],z[1]}
+ sub r6, r6, #1 @ n--
+ vld2.32 {d18-d19},[r4,:128] @ {z[o1],z[o1+1]}
+ vzip.32 q10, q11
+ vadd.f32 d0, d22, d20
+ vadd.f32 d1, d21, d23
+ vsub.f32 d2, d21, d23
+ vsub.f32 d3, d22, d20
+ vsub.f32 q10, q8, q0
+ vadd.f32 q8, q8, q0
+ vsub.f32 q11, q9, q1
+ vadd.f32 q9, q9, q1
+ vst2.32 {d20-d21},[r2,:128]! @ {z[o2],z[o2+1]}
+ vst2.32 {d16-d17},[r0,:128]! @ {z[0],z[1]}
+ vst2.32 {d22-d23},[r3,:128]! @ {z[o3],z[o3+1]}
+ vst2.32 {d18-d19},[r4,:128]! @ {z[o1],z[o1+1]}
+ sub r5, r5, #8 @ wim -= 2
+1:
+ vld1.32 {d20-d21},[r2,:128] @ {z[o2],z[o2+1]}
+ vld1.32 {d22-d23},[r3,:128] @ {z[o3],z[o3+1]}
+ vswp d21, d22
+ vld1.32 {d4}, [r1]! @ {wre[0],wre[1]}
+ vrev64.32 q0, q10
+ vmul.f32 q10, q10, d4[0]
+ vrev64.32 q1, q11
+ vmul.f32 q11, q11, d4[1]
+ vld1.32 {d5}, [r5] @ {wim[-1],wim[0]}
+ vmul.f32 q0, q0, q3
+ sub r5, r5, #8 @ wim -= 2
+ vmul.f32 q1, q1, q3
+ vmla.f32 q10, q0, d5[1] @ {t1,t2,t5,t6}
+ vmla.f32 q11, q1, d5[0] @ {t1a,t2a,t5a,t6a}
+ vld2.32 {d16-d17},[r0,:128] @ {z[0],z[1]}
+ subs r6, r6, #1 @ n--
+ vld2.32 {d18-d19},[r4,:128] @ {z[o1],z[o1+1]}
+ vzip.32 q10, q11
+ vadd.f32 d0, d22, d20
+ vadd.f32 d1, d21, d23
+ vsub.f32 d2, d21, d23
+ vsub.f32 d3, d22, d20
+ vsub.f32 q10, q8, q0
+ vadd.f32 q8, q8, q0
+ vsub.f32 q11, q9, q1
+ vadd.f32 q9, q9, q1
+ vst2.32 {d20-d21}, [r2,:128]! @ {z[o2],z[o2+1]}
+ vst2.32 {d16-d17}, [r0,:128]! @ {z[0],z[1]}
+ vst2.32 {d22-d23}, [r3,:128]! @ {z[o3],z[o3+1]}
+ vst2.32 {d18-d19}, [r4,:128]! @ {z[o1],z[o1+1]}
+ bne 1b
+
+ pop {r4-r6,pc}
+endfunc
+
+.macro def_fft n, n2, n4
+ .align 6
+function fft\n\()_neon
+ push {r4, lr}
+ mov r4, r0
+ bl fft\n2\()_neon
+ add r0, r4, #\n4*2*8
+ bl fft\n4\()_neon
+ add r0, r4, #\n4*3*8
+ bl fft\n4\()_neon
+ mov r0, r4
+ pop {r4, lr}
+ movrel r1, X(ff_cos_\n)
+ mov r2, #\n4/2
+ b fft_pass_neon
+endfunc
+.endm
+
+ def_fft 32, 16, 8
+ def_fft 64, 32, 16
+ def_fft 128, 64, 32
+ def_fft 256, 128, 64
+ def_fft 512, 256, 128
+ def_fft 1024, 512, 256
+ def_fft 2048, 1024, 512
+ def_fft 4096, 2048, 1024
+ def_fft 8192, 4096, 2048
+ def_fft 16384, 8192, 4096
+ def_fft 32768, 16384, 8192
+ def_fft 65536, 32768, 16384
+
+function ff_fft_calc_neon, export=1
+ ldr r2, [r0]
+ sub r2, r2, #2
+ movrel r3, fft_tab_neon
+ ldr r3, [r3, r2, lsl #2]
+ mov r0, r1
+ bx r3
+endfunc
+
+function ff_fft_permute_neon, export=1
+ push {r4,lr}
+ mov r12, #1
+ ldr r2, [r0] @ nbits
+ ldr r3, [r0, #12] @ tmp_buf
+ ldr r0, [r0, #8] @ revtab
+ lsl r12, r12, r2
+ mov r2, r12
+1:
+ vld1.32 {d0-d1}, [r1,:128]!
+ ldr r4, [r0], #4
+ uxth lr, r4
+ uxth r4, r4, ror #16
+ add lr, r3, lr, lsl #3
+ add r4, r3, r4, lsl #3
+ vst1.32 {d0}, [lr,:64]
+ vst1.32 {d1}, [r4,:64]
+ subs r12, r12, #2
+ bgt 1b
+
+ sub r1, r1, r2, lsl #3
+1:
+ vld1.32 {d0-d3}, [r3,:128]!
+ vst1.32 {d0-d3}, [r1,:128]!
+ subs r2, r2, #4
+ bgt 1b
+
+ pop {r4,pc}
+endfunc
+
+ .section .rodata
+ .align 4
+fft_tab_neon:
+ .word fft4_neon
+ .word fft8_neon
+ .word fft16_neon
+ .word fft32_neon
+ .word fft64_neon
+ .word fft128_neon
+ .word fft256_neon
+ .word fft512_neon
+ .word fft1024_neon
+ .word fft2048_neon
+ .word fft4096_neon
+ .word fft8192_neon
+ .word fft16384_neon
+ .word fft32768_neon
+ .word fft65536_neon
+ELF .size fft_tab_neon, . - fft_tab_neon
+
+ .align 4
+pmmp: .float +1.0, -1.0, -1.0, +1.0
+mppm: .float -M_SQRT1_2, M_SQRT1_2, M_SQRT1_2, -M_SQRT1_2
+
diff --git a/plugins/supereq/ffmpeg_fft/libavcodec/arm/rdft_neon.S b/plugins/supereq/ffmpeg_fft/libavcodec/arm/rdft_neon.S
new file mode 100644
index 00000000..4f8a1032
--- /dev/null
+++ b/plugins/supereq/ffmpeg_fft/libavcodec/arm/rdft_neon.S
@@ -0,0 +1,151 @@
+/*
+ * ARM NEON optimised RDFT
+ * Copyright (c) 2009 Mans Rullgard <mans@mansr.com>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "asm.S"
+
+ preserve8
+
+function ff_rdft_calc_neon, export=1
+ push {r4-r8,lr}
+
+ ldr r6, [r0, #4] @ inverse
+ mov r4, r0
+ mov r5, r1
+
+ lsls r6, r6, #31
+ bne 1f
+ add r0, r4, #20
+ bl X(ff_fft_permute_neon)
+ add r0, r4, #20
+ mov r1, r5
+ bl X(ff_fft_calc_neon)
+1:
+ ldr r12, [r4, #0] @ nbits
+ mov r2, #1
+ lsl r12, r2, r12
+ add r0, r5, #8
+ add r1, r5, r12, lsl #2
+ lsr r12, r12, #2
+ ldr r2, [r4, #12] @ tcos
+ sub r12, r12, #2
+ ldr r3, [r4, #16] @ tsin
+ mov r7, r0
+ sub r1, r1, #8
+ mov lr, r1
+ mov r8, #-8
+ vld1.32 {d0}, [r0,:64]! @ d1[0,1]
+ vld1.32 {d1}, [r1,:64], r8 @ d2[0,1]
+ vld1.32 {d4}, [r2,:64]! @ tcos[i]
+ vld1.32 {d5}, [r3,:64]! @ tsin[i]
+ vmov.f32 d18, #0.5 @ k1
+ vdup.32 d19, r6
+ pld [r0, #32]
+ veor d19, d18, d19 @ k2
+ vmov.i32 d16, #0
+ vmov.i32 d17, #1<<31
+ pld [r1, #-32]
+ vtrn.32 d16, d17
+ pld [r2, #32]
+ vrev64.32 d16, d16 @ d16=1,0 d17=0,1
+ pld [r3, #32]
+2:
+ veor q1, q0, q8 @ -d1[0],d1[1], d2[0],-d2[1]
+ vld1.32 {d24}, [r0,:64]! @ d1[0,1]
+ vadd.f32 d0, d0, d3 @ d1[0]+d2[0], d1[1]-d2[1]
+ vld1.32 {d25}, [r1,:64], r8 @ d2[0,1]
+ vadd.f32 d1, d2, d1 @ -d1[0]+d2[0], d1[1]+d2[1]
+ veor q3, q12, q8 @ -d1[0],d1[1], d2[0],-d2[1]
+ pld [r0, #32]
+ vmul.f32 q10, q0, q9 @ ev.re, ev.im, od.im, od.re
+ pld [r1, #-32]
+ vadd.f32 d0, d24, d7 @ d1[0]+d2[0], d1[1]-d2[1]
+ vadd.f32 d1, d6, d25 @ -d1[0]+d2[0], d1[1]+d2[1]
+ vmul.f32 q11, q0, q9 @ ev.re, ev.im, od.im, od.re
+ veor d7, d21, d16 @ -od.im, od.re
+ vrev64.32 d3, d21 @ od.re, od.im
+ veor d6, d20, d17 @ ev.re,-ev.im
+ veor d2, d3, d16 @ -od.re, od.im
+ vmla.f32 d20, d3, d4[1]
+ vmla.f32 d20, d7, d5[1]
+ vmla.f32 d6, d2, d4[1]
+ vmla.f32 d6, d21, d5[1]
+ vld1.32 {d4}, [r2,:64]! @ tcos[i]
+ veor d7, d23, d16 @ -od.im, od.re
+ vld1.32 {d5}, [r3,:64]! @ tsin[i]
+ veor d24, d22, d17 @ ev.re,-ev.im
+ vrev64.32 d3, d23 @ od.re, od.im
+ pld [r2, #32]
+ veor d2, d3, d16 @ -od.re, od.im
+ pld [r3, #32]
+ vmla.f32 d22, d3, d4[0]
+ vmla.f32 d22, d7, d5[0]
+ vmla.f32 d24, d2, d4[0]
+ vmla.f32 d24, d23, d5[0]
+ vld1.32 {d0}, [r0,:64]! @ d1[0,1]
+ vld1.32 {d1}, [r1,:64], r8 @ d2[0,1]
+ vst1.32 {d20}, [r7,:64]!
+ vst1.32 {d6}, [lr,:64], r8
+ vst1.32 {d22}, [r7,:64]!
+ vst1.32 {d24}, [lr,:64], r8
+ subs r12, r12, #2
+ bgt 2b
+
+ veor q1, q0, q8 @ -d1[0],d1[1], d2[0],-d2[1]
+ vadd.f32 d0, d0, d3 @ d1[0]+d2[0], d1[1]-d2[1]
+ vadd.f32 d1, d2, d1 @ -d1[0]+d2[0], d1[1]+d2[1]
+ ldr r2, [r4, #8] @ sign_convention
+ vmul.f32 q10, q0, q9 @ ev.re, ev.im, od.im, od.re
+ add r0, r0, #4
+ bfc r2, #0, #31
+ vld1.32 {d0[0]}, [r0,:32]
+ veor d7, d21, d16 @ -od.im, od.re
+ vrev64.32 d3, d21 @ od.re, od.im
+ veor d6, d20, d17 @ ev.re,-ev.im
+ vld1.32 {d22}, [r5,:64]
+ vdup.32 d1, r2
+ vmov d23, d22
+ veor d2, d3, d16 @ -od.re, od.im
+ vtrn.32 d22, d23
+ veor d0, d0, d1
+ veor d23, d23, d17
+ vmla.f32 d20, d3, d4[1]
+ vmla.f32 d20, d7, d5[1]
+ vmla.f32 d6, d2, d4[1]
+ vmla.f32 d6, d21, d5[1]
+ vadd.f32 d22, d22, d23
+ vst1.32 {d20}, [r7,:64]
+ vst1.32 {d6}, [lr,:64]
+ vst1.32 {d0[0]}, [r0,:32]
+ vst1.32 {d22}, [r5,:64]
+
+ cmp r6, #0
+ popeq {r4-r8,pc}
+
+ vmul.f32 d22, d22, d18
+ vst1.32 {d22}, [r5,:64]
+ add r0, r4, #20
+ mov r1, r5
+ bl X(ff_fft_permute_neon)
+ add r0, r4, #20
+ mov r1, r5
+ pop {r4-r8,lr}
+ b X(ff_fft_calc_neon)
+endfunc
diff --git a/plugins/supereq/ffmpeg_fft/libavcodec/arm/simple_idct_neon.S b/plugins/supereq/ffmpeg_fft/libavcodec/arm/simple_idct_neon.S
new file mode 100644
index 00000000..17cde583
--- /dev/null
+++ b/plugins/supereq/ffmpeg_fft/libavcodec/arm/simple_idct_neon.S
@@ -0,0 +1,372 @@
+/*
+ * ARM NEON IDCT
+ *
+ * Copyright (c) 2008 Mans Rullgard <mans@mansr.com>
+ *
+ * Based on Simple IDCT
+ * Copyright (c) 2001 Michael Niedermayer <michaelni@gmx.at>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "asm.S"
+
+#define W1 22725 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
+#define W2 21407 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
+#define W3 19266 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
+#define W4 16383 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
+#define W5 12873 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
+#define W6 8867 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
+#define W7 4520 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
+#define W4c ((1<<(COL_SHIFT-1))/W4)
+#define ROW_SHIFT 11
+#define COL_SHIFT 20
+
+#define w1 d0[0]
+#define w2 d0[1]
+#define w3 d0[2]
+#define w4 d0[3]
+#define w5 d1[0]
+#define w6 d1[1]
+#define w7 d1[2]
+#define w4c d1[3]
+
+ .macro idct_col4_top
+ vmull.s16 q7, d6, w2 /* q9 = W2 * col[2] */
+ vmull.s16 q8, d6, w6 /* q10 = W6 * col[2] */
+ vmull.s16 q9, d4, w1 /* q9 = W1 * col[1] */
+ vadd.i32 q11, q15, q7
+ vmull.s16 q10, d4, w3 /* q10 = W3 * col[1] */
+ vadd.i32 q12, q15, q8
+ vmull.s16 q5, d4, w5 /* q5 = W5 * col[1] */
+ vsub.i32 q13, q15, q8
+ vmull.s16 q6, d4, w7 /* q6 = W7 * col[1] */
+ vsub.i32 q14, q15, q7
+
+ vmlal.s16 q9, d8, w3 /* q9 += W3 * col[3] */
+ vmlsl.s16 q10, d8, w7 /* q10 -= W7 * col[3] */
+ vmlsl.s16 q5, d8, w1 /* q5 -= W1 * col[3] */
+ vmlsl.s16 q6, d8, w5 /* q6 -= W5 * col[3] */
+ .endm
+
+ .text
+ .align 6
+
+function idct_row4_pld_neon
+ pld [r0]
+ add r3, r0, r1, lsl #2
+ pld [r0, r1]
+ pld [r0, r1, lsl #1]
+ pld [r3, -r1]
+ pld [r3]
+ pld [r3, r1]
+ add r3, r3, r1, lsl #1
+ pld [r3]
+ pld [r3, r1]
+endfunc
+
+function idct_row4_neon
+ vmov.i32 q15, #(1<<(ROW_SHIFT-1))
+ vld1.64 {d2-d5}, [r2,:128]!
+ vmlal.s16 q15, d2, w4 /* q15 += W4 * col[0] */
+ vld1.64 {d6,d7}, [r2,:128]!
+ vorr d10, d3, d5
+ vld1.64 {d8,d9}, [r2,:128]!
+ add r2, r2, #-64
+
+ vorr d11, d7, d9
+ vorr d10, d10, d11
+ vmov r3, r4, d10
+
+ idct_col4_top
+
+ orrs r3, r3, r4
+ beq 1f
+
+ vmull.s16 q7, d3, w4 /* q7 = W4 * col[4] */
+ vmlal.s16 q9, d5, w5 /* q9 += W5 * col[5] */
+ vmlsl.s16 q10, d5, w1 /* q10 -= W1 * col[5] */
+ vmull.s16 q8, d7, w2 /* q8 = W2 * col[6] */
+ vmlal.s16 q5, d5, w7 /* q5 += W7 * col[5] */
+ vadd.i32 q11, q11, q7
+ vsub.i32 q12, q12, q7
+ vsub.i32 q13, q13, q7
+ vadd.i32 q14, q14, q7
+ vmlal.s16 q6, d5, w3 /* q6 += W3 * col[5] */
+ vmull.s16 q7, d7, w6 /* q7 = W6 * col[6] */
+ vmlal.s16 q9, d9, w7
+ vmlsl.s16 q10, d9, w5
+ vmlal.s16 q5, d9, w3
+ vmlsl.s16 q6, d9, w1
+ vadd.i32 q11, q11, q7
+ vsub.i32 q12, q12, q8
+ vadd.i32 q13, q13, q8
+ vsub.i32 q14, q14, q7
+
+1: vadd.i32 q3, q11, q9
+ vadd.i32 q4, q12, q10
+ vshrn.i32 d2, q3, #ROW_SHIFT
+ vshrn.i32 d4, q4, #ROW_SHIFT
+ vadd.i32 q7, q13, q5
+ vadd.i32 q8, q14, q6
+ vtrn.16 d2, d4
+ vshrn.i32 d6, q7, #ROW_SHIFT
+ vshrn.i32 d8, q8, #ROW_SHIFT
+ vsub.i32 q14, q14, q6
+ vsub.i32 q11, q11, q9
+ vtrn.16 d6, d8
+ vsub.i32 q13, q13, q5
+ vshrn.i32 d3, q14, #ROW_SHIFT
+ vtrn.32 d2, d6
+ vsub.i32 q12, q12, q10
+ vtrn.32 d4, d8
+ vshrn.i32 d5, q13, #ROW_SHIFT
+ vshrn.i32 d7, q12, #ROW_SHIFT
+ vshrn.i32 d9, q11, #ROW_SHIFT
+
+ vtrn.16 d3, d5
+ vtrn.16 d7, d9
+ vtrn.32 d3, d7
+ vtrn.32 d5, d9
+
+ vst1.64 {d2-d5}, [r2,:128]!
+ vst1.64 {d6-d9}, [r2,:128]!
+
+ bx lr
+endfunc
+
+function idct_col4_neon
+ mov ip, #16
+ vld1.64 {d2}, [r2,:64], ip /* d2 = col[0] */
+ vdup.16 d30, w4c
+ vld1.64 {d4}, [r2,:64], ip /* d3 = col[1] */
+ vadd.i16 d30, d30, d2
+ vld1.64 {d6}, [r2,:64], ip /* d4 = col[2] */
+ vmull.s16 q15, d30, w4 /* q15 = W4*(col[0]+(1<<COL_SHIFT-1)/W4)*/
+ vld1.64 {d8}, [r2,:64], ip /* d5 = col[3] */
+
+ ldrd r4, [r2]
+ ldrd r6, [r2, #16]
+ orrs r4, r4, r5
+
+ idct_col4_top
+ addeq r2, r2, #16
+ beq 1f
+
+ vld1.64 {d3}, [r2,:64], ip /* d6 = col[4] */
+ vmull.s16 q7, d3, w4 /* q7 = W4 * col[4] */
+ vadd.i32 q11, q11, q7
+ vsub.i32 q12, q12, q7
+ vsub.i32 q13, q13, q7
+ vadd.i32 q14, q14, q7
+
+1: orrs r6, r6, r7
+ ldrd r4, [r2, #16]
+ addeq r2, r2, #16
+ beq 2f
+
+ vld1.64 {d5}, [r2,:64], ip /* d7 = col[5] */
+ vmlal.s16 q9, d5, w5 /* q9 += W5 * col[5] */
+ vmlsl.s16 q10, d5, w1 /* q10 -= W1 * col[5] */
+ vmlal.s16 q5, d5, w7 /* q5 += W7 * col[5] */
+ vmlal.s16 q6, d5, w3 /* q6 += W3 * col[5] */
+
+2: orrs r4, r4, r5
+ ldrd r4, [r2, #16]
+ addeq r2, r2, #16
+ beq 3f
+
+ vld1.64 {d7}, [r2,:64], ip /* d8 = col[6] */
+ vmull.s16 q7, d7, w6 /* q7 = W6 * col[6] */
+ vmull.s16 q8, d7, w2 /* q8 = W2 * col[6] */
+ vadd.i32 q11, q11, q7
+ vsub.i32 q14, q14, q7
+ vsub.i32 q12, q12, q8
+ vadd.i32 q13, q13, q8
+
+3: orrs r4, r4, r5
+ addeq r2, r2, #16
+ beq 4f
+
+ vld1.64 {d9}, [r2,:64], ip /* d9 = col[7] */
+ vmlal.s16 q9, d9, w7
+ vmlsl.s16 q10, d9, w5
+ vmlal.s16 q5, d9, w3
+ vmlsl.s16 q6, d9, w1
+
+4: vaddhn.i32 d2, q11, q9
+ vaddhn.i32 d3, q12, q10
+ vaddhn.i32 d4, q13, q5
+ vaddhn.i32 d5, q14, q6
+ vsubhn.i32 d9, q11, q9
+ vsubhn.i32 d8, q12, q10
+ vsubhn.i32 d7, q13, q5
+ vsubhn.i32 d6, q14, q6
+
+ bx lr
+endfunc
+
+ .align 6
+
+function idct_col4_st8_neon
+ vqshrun.s16 d2, q1, #COL_SHIFT-16
+ vqshrun.s16 d3, q2, #COL_SHIFT-16
+ vqshrun.s16 d4, q3, #COL_SHIFT-16
+ vqshrun.s16 d5, q4, #COL_SHIFT-16
+ vst1.32 {d2[0]}, [r0,:32], r1
+ vst1.32 {d2[1]}, [r0,:32], r1
+ vst1.32 {d3[0]}, [r0,:32], r1
+ vst1.32 {d3[1]}, [r0,:32], r1
+ vst1.32 {d4[0]}, [r0,:32], r1
+ vst1.32 {d4[1]}, [r0,:32], r1
+ vst1.32 {d5[0]}, [r0,:32], r1
+ vst1.32 {d5[1]}, [r0,:32], r1
+
+ bx lr
+endfunc
+
+ .section .rodata
+ .align 4
+idct_coeff_neon:
+ .short W1, W2, W3, W4, W5, W6, W7, W4c
+
+ .macro idct_start data
+ push {r4-r7, lr}
+ pld [\data]
+ pld [\data, #64]
+ vpush {d8-d15}
+ movrel r3, idct_coeff_neon
+ vld1.64 {d0,d1}, [r3,:128]
+ .endm
+
+ .macro idct_end
+ vpop {d8-d15}
+ pop {r4-r7, pc}
+ .endm
+
+/* void ff_simple_idct_put_neon(uint8_t *dst, int line_size, DCTELEM *data); */
+function ff_simple_idct_put_neon, export=1
+ idct_start r2
+
+ bl idct_row4_pld_neon
+ bl idct_row4_neon
+ add r2, r2, #-128
+ bl idct_col4_neon
+ bl idct_col4_st8_neon
+ sub r0, r0, r1, lsl #3
+ add r0, r0, #4
+ add r2, r2, #-120
+ bl idct_col4_neon
+ bl idct_col4_st8_neon
+
+ idct_end
+endfunc
+
+ .align 6
+
+function idct_col4_add8_neon
+ mov ip, r0
+
+ vld1.32 {d10[0]}, [r0,:32], r1
+ vshr.s16 q1, q1, #COL_SHIFT-16
+ vld1.32 {d10[1]}, [r0,:32], r1
+ vshr.s16 q2, q2, #COL_SHIFT-16
+ vld1.32 {d11[0]}, [r0,:32], r1
+ vshr.s16 q3, q3, #COL_SHIFT-16
+ vld1.32 {d11[1]}, [r0,:32], r1
+ vshr.s16 q4, q4, #COL_SHIFT-16
+ vld1.32 {d12[0]}, [r0,:32], r1
+ vaddw.u8 q1, q1, d10
+ vld1.32 {d12[1]}, [r0,:32], r1
+ vaddw.u8 q2, q2, d11
+ vld1.32 {d13[0]}, [r0,:32], r1
+ vqmovun.s16 d2, q1
+ vld1.32 {d13[1]}, [r0,:32], r1
+ vaddw.u8 q3, q3, d12
+ vst1.32 {d2[0]}, [ip,:32], r1
+ vqmovun.s16 d3, q2
+ vst1.32 {d2[1]}, [ip,:32], r1
+ vaddw.u8 q4, q4, d13
+ vst1.32 {d3[0]}, [ip,:32], r1
+ vqmovun.s16 d4, q3
+ vst1.32 {d3[1]}, [ip,:32], r1
+ vqmovun.s16 d5, q4
+ vst1.32 {d4[0]}, [ip,:32], r1
+ vst1.32 {d4[1]}, [ip,:32], r1
+ vst1.32 {d5[0]}, [ip,:32], r1
+ vst1.32 {d5[1]}, [ip,:32], r1
+
+ bx lr
+endfunc
+
+/* void ff_simple_idct_add_neon(uint8_t *dst, int line_size, DCTELEM *data); */
+function ff_simple_idct_add_neon, export=1
+ idct_start r2
+
+ bl idct_row4_pld_neon
+ bl idct_row4_neon
+ add r2, r2, #-128
+ bl idct_col4_neon
+ bl idct_col4_add8_neon
+ sub r0, r0, r1, lsl #3
+ add r0, r0, #4
+ add r2, r2, #-120
+ bl idct_col4_neon
+ bl idct_col4_add8_neon
+
+ idct_end
+endfunc
+
+ .align 6
+
+function idct_col4_st16_neon
+ mov ip, #16
+
+ vshr.s16 q1, q1, #COL_SHIFT-16
+ vshr.s16 q2, q2, #COL_SHIFT-16
+ vst1.64 {d2}, [r2,:64], ip
+ vshr.s16 q3, q3, #COL_SHIFT-16
+ vst1.64 {d3}, [r2,:64], ip
+ vshr.s16 q4, q4, #COL_SHIFT-16
+ vst1.64 {d4}, [r2,:64], ip
+ vst1.64 {d5}, [r2,:64], ip
+ vst1.64 {d6}, [r2,:64], ip
+ vst1.64 {d7}, [r2,:64], ip
+ vst1.64 {d8}, [r2,:64], ip
+ vst1.64 {d9}, [r2,:64], ip
+
+ bx lr
+endfunc
+
+/* void ff_simple_idct_neon(DCTELEM *data); */
+function ff_simple_idct_neon, export=1
+ idct_start r0
+
+ mov r2, r0
+ bl idct_row4_neon
+ bl idct_row4_neon
+ add r2, r2, #-128
+ bl idct_col4_neon
+ add r2, r2, #-128
+ bl idct_col4_st16_neon
+ add r2, r2, #-120
+ bl idct_col4_neon
+ add r2, r2, #-128
+ bl idct_col4_st16_neon
+
+ idct_end
+endfunc
diff --git a/plugins/supereq/ffmpeg_fft/libavcodec/avfft.c b/plugins/supereq/ffmpeg_fft/libavcodec/avfft.c
new file mode 100644
index 00000000..25fc4e09
--- /dev/null
+++ b/plugins/supereq/ffmpeg_fft/libavcodec/avfft.c
@@ -0,0 +1,142 @@
+/*
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libavutil/mem.h"
+#include "avfft.h"
+#include "fft.h"
+
+/* FFT */
+
+FFTContext *av_fft_init(int nbits, int inverse)
+{
+ FFTContext *s = av_malloc(sizeof(*s));
+
+ if (s)
+ ff_fft_init(s, nbits, inverse);
+
+ return s;
+}
+
+void av_fft_permute(FFTContext *s, FFTComplex *z)
+{
+ s->fft_permute(s, z);
+}
+
+void av_fft_calc(FFTContext *s, FFTComplex *z)
+{
+ s->fft_calc(s, z);
+}
+
+void av_fft_end(FFTContext *s)
+{
+ if (s) {
+ ff_fft_end(s);
+ av_free(s);
+ }
+}
+
+#if CONFIG_MDCT
+
+FFTContext *av_mdct_init(int nbits, int inverse, double scale)
+{
+ FFTContext *s = av_malloc(sizeof(*s));
+
+ if (s)
+ ff_mdct_init(s, nbits, inverse, scale);
+
+ return s;
+}
+
+void av_imdct_calc(FFTContext *s, FFTSample *output, const FFTSample *input)
+{
+ s->imdct_calc(s, output, input);
+}
+
+void av_imdct_half(FFTContext *s, FFTSample *output, const FFTSample *input)
+{
+ s->imdct_half(s, output, input);
+}
+
+void av_mdct_calc(FFTContext *s, FFTSample *output, const FFTSample *input)
+{
+ s->mdct_calc(s, output, input);
+}
+
+void av_mdct_end(FFTContext *s)
+{
+ if (s) {
+ ff_mdct_end(s);
+ av_free(s);
+ }
+}
+
+#endif /* CONFIG_MDCT */
+
+#if CONFIG_RDFT
+
+RDFTContext *av_rdft_init(int nbits, enum RDFTransformType trans)
+{
+ RDFTContext *s = av_malloc(sizeof(*s));
+
+ if (s)
+ ff_rdft_init(s, nbits, trans);
+
+ return s;
+}
+
+void av_rdft_calc(RDFTContext *s, FFTSample *data)
+{
+ ff_rdft_calc(s, data);
+}
+
+void av_rdft_end(RDFTContext *s)
+{
+ if (s) {
+ ff_rdft_end(s);
+ av_free(s);
+ }
+}
+
+#endif /* CONFIG_RDFT */
+
+#if CONFIG_DCT
+
+DCTContext *av_dct_init(int nbits, enum DCTTransformType inverse)
+{
+ DCTContext *s = av_malloc(sizeof(*s));
+
+ if (s)
+ ff_dct_init(s, nbits, inverse);
+
+ return s;
+}
+
+void av_dct_calc(DCTContext *s, FFTSample *data)
+{
+ ff_dct_calc(s, data);
+}
+
+void av_dct_end(DCTContext *s)
+{
+ if (s) {
+ ff_dct_end(s);
+ av_free(s);
+ }
+}
+
+#endif /* CONFIG_DCT */
diff --git a/plugins/supereq/ffmpeg_fft/libavcodec/avfft.h b/plugins/supereq/ffmpeg_fft/libavcodec/avfft.h
new file mode 100644
index 00000000..fdf30237
--- /dev/null
+++ b/plugins/supereq/ffmpeg_fft/libavcodec/avfft.h
@@ -0,0 +1,103 @@
+/*
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVCODEC_AVFFT_H
+#define AVCODEC_AVFFT_H
+
+#include "publik.h"
+
+typedef float FFTSample;
+
+typedef struct FFTComplex {
+ FFTSample re, im;
+} FFTComplex;
+
+typedef struct FFTContext FFTContext;
+
+/**
+ * Set up a complex FFT.
+ * @param nbits log2 of the length of the input array
+ * @param inverse if 0 perform the forward transform, if 1 perform the inverse
+ */
+PUBLIK FFTContext *av_fft_init(int nbits, int inverse);
+
+/**
+ * Do the permutation needed BEFORE calling ff_fft_calc().
+ */
+PUBLIK void av_fft_permute(FFTContext *s, FFTComplex *z);
+
+/**
+ * Do a complex FFT with the parameters defined in av_fft_init(). The
+ * input data must be permuted before. No 1.0/sqrt(n) normalization is done.
+ */
+PUBLIK void av_fft_calc(FFTContext *s, FFTComplex *z);
+
+PUBLIK void av_fft_end(FFTContext *s);
+
+#if 0
+FFTContext *av_mdct_init(int nbits, int inverse, double scale);
+void av_imdct_calc(FFTContext *s, FFTSample *output, const FFTSample *input);
+void av_imdct_half(FFTContext *s, FFTSample *output, const FFTSample *input);
+void av_mdct_calc(FFTContext *s, FFTSample *output, const FFTSample *input);
+void av_mdct_end(FFTContext *s);
+#endif
+
+/* Real Discrete Fourier Transform */
+
+enum RDFTransformType {
+ DFT_R2C,
+ IDFT_C2R,
+ IDFT_R2C,
+ DFT_C2R,
+};
+
+typedef struct RDFTContext RDFTContext;
+
+/**
+ * Set up a real FFT.
+ * @param nbits log2 of the length of the input array
+ * @param trans the type of transform
+ */
+PUBLIK RDFTContext *av_rdft_init(int nbits, enum RDFTransformType trans);
+PUBLIK void av_rdft_calc(RDFTContext *s, FFTSample *data);
+PUBLIK void av_rdft_end(RDFTContext *s);
+
+/* Discrete Cosine Transform */
+
+typedef struct DCTContext DCTContext;
+
+enum DCTTransformType {
+ DCT_II = 0,
+ DCT_III,
+ DCT_I,
+ DST_I,
+};
+
+/**
+ * Set up DCT.
+ * @param nbits size of the input array:
+ * (1 << nbits) for DCT-II, DCT-III and DST-I
+ * (1 << nbits) + 1 for DCT-I
+ *
+ * @note the first element of the input of DST-I is ignored
+ */
+PUBLIK DCTContext *av_dct_init(int nbits, enum DCTTransformType type);
+PUBLIK void av_dct_calc(DCTContext *s, FFTSample *data);
+PUBLIK void av_dct_end (DCTContext *s);
+
+#endif /* AVCODEC_AVFFT_H */
diff --git a/plugins/supereq/ffmpeg_fft/libavcodec/dct.c b/plugins/supereq/ffmpeg_fft/libavcodec/dct.c
new file mode 100644
index 00000000..6ea1936e
--- /dev/null
+++ b/plugins/supereq/ffmpeg_fft/libavcodec/dct.c
@@ -0,0 +1,228 @@
+/*
+ * (I)DCT Transforms
+ * Copyright (c) 2009 Peter Ross <pross@xvid.org>
+ * Copyright (c) 2010 Alex Converse <alex.converse@gmail.com>
+ * Copyright (c) 2010 Vitor Sessak
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * (Inverse) Discrete Cosine Transforms. These are also known as the
+ * type II and type III DCTs respectively.
+ */
+
+#include <math.h>
+#include "libavutil/mathematics.h"
+#include "fft.h"
+#ifndef ARCH_ARM
+#include "x86/fft.h"
+#endif
+
+#define DCT32_FLOAT
+#include "dct32.h"
+
+/* sin((M_PI * x / (2*n)) */
+#define SIN(s,n,x) (s->costab[(n) - (x)])
+
+/* cos((M_PI * x / (2*n)) */
+#define COS(s,n,x) (s->costab[x])
+
+static void ff_dst_calc_I_c(DCTContext *ctx, FFTSample *data)
+{
+ int n = 1 << ctx->nbits;
+ int i;
+
+ data[0] = 0;
+ for(i = 1; i < n/2; i++) {
+ float tmp1 = data[i ];
+ float tmp2 = data[n - i];
+ float s = SIN(ctx, n, 2*i);
+
+ s *= tmp1 + tmp2;
+ tmp1 = (tmp1 - tmp2) * 0.5f;
+ data[i ] = s + tmp1;
+ data[n - i] = s - tmp1;
+ }
+
+ data[n/2] *= 2;
+ ff_rdft_calc(&ctx->rdft, data);
+
+ data[0] *= 0.5f;
+
+ for(i = 1; i < n-2; i += 2) {
+ data[i + 1] += data[i - 1];
+ data[i ] = -data[i + 2];
+ }
+
+ data[n-1] = 0;
+}
+
+static void ff_dct_calc_I_c(DCTContext *ctx, FFTSample *data)
+{
+ int n = 1 << ctx->nbits;
+ int i;
+ float next = -0.5f * (data[0] - data[n]);
+
+ for(i = 0; i < n/2; i++) {
+ float tmp1 = data[i ];
+ float tmp2 = data[n - i];
+ float s = SIN(ctx, n, 2*i);
+ float c = COS(ctx, n, 2*i);
+
+ c *= tmp1 - tmp2;
+ s *= tmp1 - tmp2;
+
+ next += c;
+
+ tmp1 = (tmp1 + tmp2) * 0.5f;
+ data[i ] = tmp1 - s;
+ data[n - i] = tmp1 + s;
+ }
+
+ ff_rdft_calc(&ctx->rdft, data);
+ data[n] = data[1];
+ data[1] = next;
+
+ for(i = 3; i <= n; i += 2)
+ data[i] = data[i - 2] - data[i];
+}
+
+static void ff_dct_calc_III_c(DCTContext *ctx, FFTSample *data)
+{
+ int n = 1 << ctx->nbits;
+ int i;
+
+ float next = data[n - 1];
+ float inv_n = 1.0f / n;
+
+ for (i = n - 2; i >= 2; i -= 2) {
+ float val1 = data[i ];
+ float val2 = data[i - 1] - data[i + 1];
+ float c = COS(ctx, n, i);
+ float s = SIN(ctx, n, i);
+
+ data[i ] = c * val1 + s * val2;
+ data[i + 1] = s * val1 - c * val2;
+ }
+
+ data[1] = 2 * next;
+
+ ff_rdft_calc(&ctx->rdft, data);
+
+ for (i = 0; i < n / 2; i++) {
+ float tmp1 = data[i ] * inv_n;
+ float tmp2 = data[n - i - 1] * inv_n;
+ float csc = ctx->csc2[i] * (tmp1 - tmp2);
+
+ tmp1 += tmp2;
+ data[i ] = tmp1 + csc;
+ data[n - i - 1] = tmp1 - csc;
+ }
+}
+
+static void ff_dct_calc_II_c(DCTContext *ctx, FFTSample *data)
+{
+ int n = 1 << ctx->nbits;
+ int i;
+ float next;
+
+ for (i=0; i < n/2; i++) {
+ float tmp1 = data[i ];
+ float tmp2 = data[n - i - 1];
+ float s = SIN(ctx, n, 2*i + 1);
+
+ s *= tmp1 - tmp2;
+ tmp1 = (tmp1 + tmp2) * 0.5f;
+
+ data[i ] = tmp1 + s;
+ data[n-i-1] = tmp1 - s;
+ }
+
+ ff_rdft_calc(&ctx->rdft, data);
+
+ next = data[1] * 0.5;
+ data[1] *= -1;
+
+ for (i = n - 2; i >= 0; i -= 2) {
+ float inr = data[i ];
+ float ini = data[i + 1];
+ float c = COS(ctx, n, i);
+ float s = SIN(ctx, n, i);
+
+ data[i ] = c * inr + s * ini;
+
+ data[i+1] = next;
+
+ next += s * inr - c * ini;
+ }
+}
+
+static void dct32_func(DCTContext *ctx, FFTSample *data)
+{
+ ctx->dct32(data, data);
+}
+
+void ff_dct_calc(DCTContext *s, FFTSample *data)
+{
+ s->dct_calc(s, data);
+}
+
+av_cold int ff_dct_init(DCTContext *s, int nbits, enum DCTTransformType inverse)
+{
+ int n = 1 << nbits;
+ int i;
+
+ s->nbits = nbits;
+ s->inverse = inverse;
+
+ ff_init_ff_cos_tabs(nbits+2);
+
+ s->costab = ff_cos_tabs[nbits+2];
+
+ s->csc2 = av_malloc(n/2 * sizeof(FFTSample));
+
+ if (ff_rdft_init(&s->rdft, nbits, inverse == DCT_III) < 0) {
+ av_free(s->csc2);
+ return -1;
+ }
+
+ for (i = 0; i < n/2; i++)
+ s->csc2[i] = 0.5 / sin((M_PI / (2*n) * (2*i + 1)));
+
+ switch(inverse) {
+ case DCT_I : s->dct_calc = ff_dct_calc_I_c; break;
+ case DCT_II : s->dct_calc = ff_dct_calc_II_c ; break;
+ case DCT_III: s->dct_calc = ff_dct_calc_III_c; break;
+ case DST_I : s->dct_calc = ff_dst_calc_I_c; break;
+ }
+
+ if (inverse == DCT_II && nbits == 5)
+ s->dct_calc = dct32_func;
+
+ s->dct32 = dct32;
+ if (HAVE_MMX) ff_dct_init_mmx(s);
+
+ return 0;
+}
+
+av_cold void ff_dct_end(DCTContext *s)
+{
+ ff_rdft_end(&s->rdft);
+ av_free(s->csc2);
+}
diff --git a/plugins/supereq/ffmpeg_fft/libavcodec/dct32.c b/plugins/supereq/ffmpeg_fft/libavcodec/dct32.c
new file mode 100644
index 00000000..3e6ad78d
--- /dev/null
+++ b/plugins/supereq/ffmpeg_fft/libavcodec/dct32.c
@@ -0,0 +1,262 @@
+/*
+ * Template for the Discrete Cosine Transform for 32 samples
+ * Copyright (c) 2001, 2002 Fabrice Bellard
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "dct32.h"
+
+/* tab[i][j] = 1.0 / (2.0 * cos(pi*(2*k+1) / 2^(6 - j))) */
+
+/* cos(i*pi/64) */
+
+#define COS0_0 FIXHR(0.50060299823519630134/2)
+#define COS0_1 FIXHR(0.50547095989754365998/2)
+#define COS0_2 FIXHR(0.51544730992262454697/2)
+#define COS0_3 FIXHR(0.53104259108978417447/2)
+#define COS0_4 FIXHR(0.55310389603444452782/2)
+#define COS0_5 FIXHR(0.58293496820613387367/2)
+#define COS0_6 FIXHR(0.62250412303566481615/2)
+#define COS0_7 FIXHR(0.67480834145500574602/2)
+#define COS0_8 FIXHR(0.74453627100229844977/2)
+#define COS0_9 FIXHR(0.83934964541552703873/2)
+#define COS0_10 FIXHR(0.97256823786196069369/2)
+#define COS0_11 FIXHR(1.16943993343288495515/4)
+#define COS0_12 FIXHR(1.48416461631416627724/4)
+#define COS0_13 FIXHR(2.05778100995341155085/8)
+#define COS0_14 FIXHR(3.40760841846871878570/8)
+#define COS0_15 FIXHR(10.19000812354805681150/32)
+
+#define COS1_0 FIXHR(0.50241928618815570551/2)
+#define COS1_1 FIXHR(0.52249861493968888062/2)
+#define COS1_2 FIXHR(0.56694403481635770368/2)
+#define COS1_3 FIXHR(0.64682178335999012954/2)
+#define COS1_4 FIXHR(0.78815462345125022473/2)
+#define COS1_5 FIXHR(1.06067768599034747134/4)
+#define COS1_6 FIXHR(1.72244709823833392782/4)
+#define COS1_7 FIXHR(5.10114861868916385802/16)
+
+#define COS2_0 FIXHR(0.50979557910415916894/2)
+#define COS2_1 FIXHR(0.60134488693504528054/2)
+#define COS2_2 FIXHR(0.89997622313641570463/2)
+#define COS2_3 FIXHR(2.56291544774150617881/8)
+
+#define COS3_0 FIXHR(0.54119610014619698439/2)
+#define COS3_1 FIXHR(1.30656296487637652785/4)
+
+#define COS4_0 FIXHR(0.70710678118654752439/2)
+
+/* butterfly operator */
+#define BF(a, b, c, s)\
+{\
+ tmp0 = val##a + val##b;\
+ tmp1 = val##a - val##b;\
+ val##a = tmp0;\
+ val##b = MULH3(tmp1, c, 1<<(s));\
+}
+
+#define BF0(a, b, c, s)\
+{\
+ tmp0 = tab[a] + tab[b];\
+ tmp1 = tab[a] - tab[b];\
+ val##a = tmp0;\
+ val##b = MULH3(tmp1, c, 1<<(s));\
+}
+
+#define BF1(a, b, c, d)\
+{\
+ BF(a, b, COS4_0, 1);\
+ BF(c, d,-COS4_0, 1);\
+ val##c += val##d;\
+}
+
+#define BF2(a, b, c, d)\
+{\
+ BF(a, b, COS4_0, 1);\
+ BF(c, d,-COS4_0, 1);\
+ val##c += val##d;\
+ val##a += val##c;\
+ val##c += val##b;\
+ val##b += val##d;\
+}
+
+#define ADD(a, b) val##a += val##b
+
+/* DCT32 without 1/sqrt(2) coef zero scaling. */
+void dct32(INTFLOAT *out, const INTFLOAT *tab)
+{
+ INTFLOAT tmp0, tmp1;
+
+ INTFLOAT val0 , val1 , val2 , val3 , val4 , val5 , val6 , val7 ,
+ val8 , val9 , val10, val11, val12, val13, val14, val15,
+ val16, val17, val18, val19, val20, val21, val22, val23,
+ val24, val25, val26, val27, val28, val29, val30, val31;
+
+ /* pass 1 */
+ BF0( 0, 31, COS0_0 , 1);
+ BF0(15, 16, COS0_15, 5);
+ /* pass 2 */
+ BF( 0, 15, COS1_0 , 1);
+ BF(16, 31,-COS1_0 , 1);
+ /* pass 1 */
+ BF0( 7, 24, COS0_7 , 1);
+ BF0( 8, 23, COS0_8 , 1);
+ /* pass 2 */
+ BF( 7, 8, COS1_7 , 4);
+ BF(23, 24,-COS1_7 , 4);
+ /* pass 3 */
+ BF( 0, 7, COS2_0 , 1);
+ BF( 8, 15,-COS2_0 , 1);
+ BF(16, 23, COS2_0 , 1);
+ BF(24, 31,-COS2_0 , 1);
+ /* pass 1 */
+ BF0( 3, 28, COS0_3 , 1);
+ BF0(12, 19, COS0_12, 2);
+ /* pass 2 */
+ BF( 3, 12, COS1_3 , 1);
+ BF(19, 28,-COS1_3 , 1);
+ /* pass 1 */
+ BF0( 4, 27, COS0_4 , 1);
+ BF0(11, 20, COS0_11, 2);
+ /* pass 2 */
+ BF( 4, 11, COS1_4 , 1);
+ BF(20, 27,-COS1_4 , 1);
+ /* pass 3 */
+ BF( 3, 4, COS2_3 , 3);
+ BF(11, 12,-COS2_3 , 3);
+ BF(19, 20, COS2_3 , 3);
+ BF(27, 28,-COS2_3 , 3);
+ /* pass 4 */
+ BF( 0, 3, COS3_0 , 1);
+ BF( 4, 7,-COS3_0 , 1);
+ BF( 8, 11, COS3_0 , 1);
+ BF(12, 15,-COS3_0 , 1);
+ BF(16, 19, COS3_0 , 1);
+ BF(20, 23,-COS3_0 , 1);
+ BF(24, 27, COS3_0 , 1);
+ BF(28, 31,-COS3_0 , 1);
+
+
+
+ /* pass 1 */
+ BF0( 1, 30, COS0_1 , 1);
+ BF0(14, 17, COS0_14, 3);
+ /* pass 2 */
+ BF( 1, 14, COS1_1 , 1);
+ BF(17, 30,-COS1_1 , 1);
+ /* pass 1 */
+ BF0( 6, 25, COS0_6 , 1);
+ BF0( 9, 22, COS0_9 , 1);
+ /* pass 2 */
+ BF( 6, 9, COS1_6 , 2);
+ BF(22, 25,-COS1_6 , 2);
+ /* pass 3 */
+ BF( 1, 6, COS2_1 , 1);
+ BF( 9, 14,-COS2_1 , 1);
+ BF(17, 22, COS2_1 , 1);
+ BF(25, 30,-COS2_1 , 1);
+
+ /* pass 1 */
+ BF0( 2, 29, COS0_2 , 1);
+ BF0(13, 18, COS0_13, 3);
+ /* pass 2 */
+ BF( 2, 13, COS1_2 , 1);
+ BF(18, 29,-COS1_2 , 1);
+ /* pass 1 */
+ BF0( 5, 26, COS0_5 , 1);
+ BF0(10, 21, COS0_10, 1);
+ /* pass 2 */
+ BF( 5, 10, COS1_5 , 2);
+ BF(21, 26,-COS1_5 , 2);
+ /* pass 3 */
+ BF( 2, 5, COS2_2 , 1);
+ BF(10, 13,-COS2_2 , 1);
+ BF(18, 21, COS2_2 , 1);
+ BF(26, 29,-COS2_2 , 1);
+ /* pass 4 */
+ BF( 1, 2, COS3_1 , 2);
+ BF( 5, 6,-COS3_1 , 2);
+ BF( 9, 10, COS3_1 , 2);
+ BF(13, 14,-COS3_1 , 2);
+ BF(17, 18, COS3_1 , 2);
+ BF(21, 22,-COS3_1 , 2);
+ BF(25, 26, COS3_1 , 2);
+ BF(29, 30,-COS3_1 , 2);
+
+ /* pass 5 */
+ BF1( 0, 1, 2, 3);
+ BF2( 4, 5, 6, 7);
+ BF1( 8, 9, 10, 11);
+ BF2(12, 13, 14, 15);
+ BF1(16, 17, 18, 19);
+ BF2(20, 21, 22, 23);
+ BF1(24, 25, 26, 27);
+ BF2(28, 29, 30, 31);
+
+ /* pass 6 */
+
+ ADD( 8, 12);
+ ADD(12, 10);
+ ADD(10, 14);
+ ADD(14, 9);
+ ADD( 9, 13);
+ ADD(13, 11);
+ ADD(11, 15);
+
+ out[ 0] = val0;
+ out[16] = val1;
+ out[ 8] = val2;
+ out[24] = val3;
+ out[ 4] = val4;
+ out[20] = val5;
+ out[12] = val6;
+ out[28] = val7;
+ out[ 2] = val8;
+ out[18] = val9;
+ out[10] = val10;
+ out[26] = val11;
+ out[ 6] = val12;
+ out[22] = val13;
+ out[14] = val14;
+ out[30] = val15;
+
+ ADD(24, 28);
+ ADD(28, 26);
+ ADD(26, 30);
+ ADD(30, 25);
+ ADD(25, 29);
+ ADD(29, 27);
+ ADD(27, 31);
+
+ out[ 1] = val16 + val24;
+ out[17] = val17 + val25;
+ out[ 9] = val18 + val26;
+ out[25] = val19 + val27;
+ out[ 5] = val20 + val28;
+ out[21] = val21 + val29;
+ out[13] = val22 + val30;
+ out[29] = val23 + val31;
+ out[ 3] = val24 + val20;
+ out[19] = val25 + val21;
+ out[11] = val26 + val22;
+ out[27] = val27 + val23;
+ out[ 7] = val28 + val18;
+ out[23] = val29 + val19;
+ out[15] = val30 + val17;
+ out[31] = val31;
+}
diff --git a/plugins/supereq/ffmpeg_fft/libavcodec/dct32.h b/plugins/supereq/ffmpeg_fft/libavcodec/dct32.h
new file mode 100644
index 00000000..dc2d847a
--- /dev/null
+++ b/plugins/supereq/ffmpeg_fft/libavcodec/dct32.h
@@ -0,0 +1,10 @@
+#ifndef DCT_32_H
+#define DCT_32_H
+
+#define FIXHR(x) ((float)(x))
+#define MULH3(x, y, s) ((s)*(y)*(x))
+#define INTFLOAT float
+
+void dct32(INTFLOAT *out, const INTFLOAT *tab);
+
+#endif
diff --git a/plugins/supereq/ffmpeg_fft/libavcodec/fft.c b/plugins/supereq/ffmpeg_fft/libavcodec/fft.c
new file mode 100644
index 00000000..04082bf4
--- /dev/null
+++ b/plugins/supereq/ffmpeg_fft/libavcodec/fft.c
@@ -0,0 +1,300 @@
+/*
+ * FFT/IFFT transforms
+ * Copyright (c) 2008 Loren Merritt
+ * Copyright (c) 2002 Fabrice Bellard
+ * Partly based on libdjbfft by D. J. Bernstein
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * FFT/IFFT transforms.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include "libavutil/mathematics.h"
+#include "fft.h"
+
+/* cos(2*pi*x/n) for 0<=x<=n/4, followed by its reverse */
+#if !CONFIG_HARDCODED_TABLES
+COSTABLE(16);
+COSTABLE(32);
+COSTABLE(64);
+COSTABLE(128);
+COSTABLE(256);
+COSTABLE(512);
+COSTABLE(1024);
+COSTABLE(2048);
+COSTABLE(4096);
+COSTABLE(8192);
+COSTABLE(16384);
+COSTABLE(32768);
+COSTABLE(65536);
+#endif
+COSTABLE_CONST FFTSample * const ff_cos_tabs[] = {
+ NULL, NULL, NULL, NULL,
+ ff_cos_16, ff_cos_32, ff_cos_64, ff_cos_128, ff_cos_256, ff_cos_512, ff_cos_1024,
+ ff_cos_2048, ff_cos_4096, ff_cos_8192, ff_cos_16384, ff_cos_32768, ff_cos_65536,
+};
+
+static int split_radix_permutation(int i, int n, int inverse)
+{
+ int m;
+ if(n <= 2) return i&1;
+ m = n >> 1;
+ if(!(i&m)) return split_radix_permutation(i, m, inverse)*2;
+ m >>= 1;
+ if(inverse == !(i&m)) return split_radix_permutation(i, m, inverse)*4 + 1;
+ else return split_radix_permutation(i, m, inverse)*4 - 1;
+}
+
+av_cold void ff_init_ff_cos_tabs(int index)
+{
+#if !CONFIG_HARDCODED_TABLES
+ int i;
+ int m = 1<<index;
+ double freq = 2*M_PI/m;
+ FFTSample *tab = ff_cos_tabs[index];
+ for(i=0; i<=m/4; i++)
+ tab[i] = cos(i*freq);
+ for(i=1; i<m/4; i++)
+ tab[m/2-i] = tab[i];
+#endif
+}
+
+av_cold int ff_fft_init(FFTContext *s, int nbits, int inverse)
+{
+ int i, j, n;
+
+ if (nbits < 2 || nbits > 16)
+ goto fail;
+ s->nbits = nbits;
+ n = 1 << nbits;
+
+ s->revtab = av_malloc(n * sizeof(uint16_t));
+ if (!s->revtab)
+ goto fail;
+ s->tmp_buf = av_malloc(n * sizeof(FFTComplex));
+ if (!s->tmp_buf)
+ goto fail;
+ s->inverse = inverse;
+
+ s->fft_permute = ff_fft_permute_c;
+ s->fft_calc = ff_fft_calc_c;
+#if CONFIG_MDCT
+ s->imdct_calc = ff_imdct_calc_c;
+ s->imdct_half = ff_imdct_half_c;
+ s->mdct_calc = ff_mdct_calc_c;
+#endif
+
+#if ARCH_ARM
+ ff_fft_init_arm(s);
+#elif HAVE_ALTIVEC
+ if (HAVE_ALTIVEC) ff_fft_init_altivec(s);
+#elif HAVE_MMX
+ if (HAVE_MMX) ff_fft_init_mmx(s);
+#endif
+
+ for(j=4; j<=nbits; j++) {
+ ff_init_ff_cos_tabs(j);
+ }
+ for(i=0; i<n; i++)
+ s->revtab[-split_radix_permutation(i, n, s->inverse) & (n-1)] = i;
+
+ return 0;
+ fail:
+ av_freep(&s->revtab);
+ av_freep(&s->tmp_buf);
+ return -1;
+}
+
+void ff_fft_permute_c(FFTContext *s, FFTComplex *z)
+{
+ int j, np;
+ const uint16_t *revtab = s->revtab;
+ np = 1 << s->nbits;
+ /* TODO: handle split-radix permute in a more optimal way, probably in-place */
+ for(j=0;j<np;j++) s->tmp_buf[revtab[j]] = z[j];
+ memcpy(z, s->tmp_buf, np * sizeof(FFTComplex));
+}
+
+av_cold void ff_fft_end(FFTContext *s)
+{
+ av_freep(&s->revtab);
+ av_freep(&s->tmp_buf);
+}
+
+#define sqrthalf (float)M_SQRT1_2
+
+#define BF(x,y,a,b) {\
+ x = a - b;\
+ y = a + b;\
+}
+
+#define BUTTERFLIES(a0,a1,a2,a3) {\
+ BF(t3, t5, t5, t1);\
+ BF(a2.re, a0.re, a0.re, t5);\
+ BF(a3.im, a1.im, a1.im, t3);\
+ BF(t4, t6, t2, t6);\
+ BF(a3.re, a1.re, a1.re, t4);\
+ BF(a2.im, a0.im, a0.im, t6);\
+}
+
+// force loading all the inputs before storing any.
+// this is slightly slower for small data, but avoids store->load aliasing
+// for addresses separated by large powers of 2.
+#define BUTTERFLIES_BIG(a0,a1,a2,a3) {\
+ FFTSample r0=a0.re, i0=a0.im, r1=a1.re, i1=a1.im;\
+ BF(t3, t5, t5, t1);\
+ BF(a2.re, a0.re, r0, t5);\
+ BF(a3.im, a1.im, i1, t3);\
+ BF(t4, t6, t2, t6);\
+ BF(a3.re, a1.re, r1, t4);\
+ BF(a2.im, a0.im, i0, t6);\
+}
+
+#define TRANSFORM(a0,a1,a2,a3,wre,wim) {\
+ t1 = a2.re * wre + a2.im * wim;\
+ t2 = a2.im * wre - a2.re * wim;\
+ t5 = a3.re * wre - a3.im * wim;\
+ t6 = a3.im * wre + a3.re * wim;\
+ BUTTERFLIES(a0,a1,a2,a3)\
+}
+
+#define TRANSFORM_ZERO(a0,a1,a2,a3) {\
+ t1 = a2.re;\
+ t2 = a2.im;\
+ t5 = a3.re;\
+ t6 = a3.im;\
+ BUTTERFLIES(a0,a1,a2,a3)\
+}
+
+/* z[0...8n-1], w[1...2n-1] */
+#define PASS(name)\
+static void name(FFTComplex *z, const FFTSample *wre, unsigned int n)\
+{\
+ FFTSample t1, t2, t3, t4, t5, t6;\
+ int o1 = 2*n;\
+ int o2 = 4*n;\
+ int o3 = 6*n;\
+ const FFTSample *wim = wre+o1;\
+ n--;\
+\
+ TRANSFORM_ZERO(z[0],z[o1],z[o2],z[o3]);\
+ TRANSFORM(z[1],z[o1+1],z[o2+1],z[o3+1],wre[1],wim[-1]);\
+ do {\
+ z += 2;\
+ wre += 2;\
+ wim -= 2;\
+ TRANSFORM(z[0],z[o1],z[o2],z[o3],wre[0],wim[0]);\
+ TRANSFORM(z[1],z[o1+1],z[o2+1],z[o3+1],wre[1],wim[-1]);\
+ } while(--n);\
+}
+
+PASS(pass)
+#undef BUTTERFLIES
+#define BUTTERFLIES BUTTERFLIES_BIG
+PASS(pass_big)
+
+#define DECL_FFT(n,n2,n4)\
+static void fft##n(FFTComplex *z)\
+{\
+ fft##n2(z);\
+ fft##n4(z+n4*2);\
+ fft##n4(z+n4*3);\
+ pass(z,ff_cos_##n,n4/2);\
+}
+
+static void fft4(FFTComplex *z)
+{
+ FFTSample t1, t2, t3, t4, t5, t6, t7, t8;
+
+ BF(t3, t1, z[0].re, z[1].re);
+ BF(t8, t6, z[3].re, z[2].re);
+ BF(z[2].re, z[0].re, t1, t6);
+ BF(t4, t2, z[0].im, z[1].im);
+ BF(t7, t5, z[2].im, z[3].im);
+ BF(z[3].im, z[1].im, t4, t8);
+ BF(z[3].re, z[1].re, t3, t7);
+ BF(z[2].im, z[0].im, t2, t5);
+}
+
+static void fft8(FFTComplex *z)
+{
+ FFTSample t1, t2, t3, t4, t5, t6, t7, t8;
+
+ fft4(z);
+
+ BF(t1, z[5].re, z[4].re, -z[5].re);
+ BF(t2, z[5].im, z[4].im, -z[5].im);
+ BF(t3, z[7].re, z[6].re, -z[7].re);
+ BF(t4, z[7].im, z[6].im, -z[7].im);
+ BF(t8, t1, t3, t1);
+ BF(t7, t2, t2, t4);
+ BF(z[4].re, z[0].re, z[0].re, t1);
+ BF(z[4].im, z[0].im, z[0].im, t2);
+ BF(z[6].re, z[2].re, z[2].re, t7);
+ BF(z[6].im, z[2].im, z[2].im, t8);
+
+ TRANSFORM(z[1],z[3],z[5],z[7],sqrthalf,sqrthalf);
+}
+
+#if !CONFIG_SMALL
+static void fft16(FFTComplex *z)
+{
+ FFTSample t1, t2, t3, t4, t5, t6;
+
+ fft8(z);
+ fft4(z+8);
+ fft4(z+12);
+
+ TRANSFORM_ZERO(z[0],z[4],z[8],z[12]);
+ TRANSFORM(z[2],z[6],z[10],z[14],sqrthalf,sqrthalf);
+ TRANSFORM(z[1],z[5],z[9],z[13],ff_cos_16[1],ff_cos_16[3]);
+ TRANSFORM(z[3],z[7],z[11],z[15],ff_cos_16[3],ff_cos_16[1]);
+}
+#else
+DECL_FFT(16,8,4)
+#endif
+DECL_FFT(32,16,8)
+DECL_FFT(64,32,16)
+DECL_FFT(128,64,32)
+DECL_FFT(256,128,64)
+DECL_FFT(512,256,128)
+#if !CONFIG_SMALL
+#define pass pass_big
+#endif
+DECL_FFT(1024,512,256)
+DECL_FFT(2048,1024,512)
+DECL_FFT(4096,2048,1024)
+DECL_FFT(8192,4096,2048)
+DECL_FFT(16384,8192,4096)
+DECL_FFT(32768,16384,8192)
+DECL_FFT(65536,32768,16384)
+
+static void (* const fft_dispatch[])(FFTComplex*) = {
+ fft4, fft8, fft16, fft32, fft64, fft128, fft256, fft512, fft1024,
+ fft2048, fft4096, fft8192, fft16384, fft32768, fft65536,
+};
+
+void ff_fft_calc_c(FFTContext *s, FFTComplex *z)
+{
+ fft_dispatch[s->nbits-2](z);
+}
+
diff --git a/plugins/supereq/ffmpeg_fft/libavcodec/fft.h b/plugins/supereq/ffmpeg_fft/libavcodec/fft.h
new file mode 100644
index 00000000..b2e0f540
--- /dev/null
+++ b/plugins/supereq/ffmpeg_fft/libavcodec/fft.h
@@ -0,0 +1,244 @@
+/*
+ * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
+ * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVCODEC_FFT_H
+#define AVCODEC_FFT_H
+
+#include <stdint.h>
+#include "../config.h"
+#include "libavutil/mem.h"
+#include "avfft.h"
+
+/* FFT computation */
+
+struct FFTContext {
+ int nbits;
+ int inverse;
+ uint16_t *revtab;
+ FFTComplex *tmp_buf;
+ int mdct_size; /* size of MDCT (i.e. number of input data * 2) */
+ int mdct_bits; /* n = 2^nbits */
+ /* pre/post rotation tables */
+ FFTSample *tcos;
+ FFTSample *tsin;
+ void (*fft_permute)(struct FFTContext *s, FFTComplex *z);
+ void (*fft_calc)(struct FFTContext *s, FFTComplex *z);
+ void (*imdct_calc)(struct FFTContext *s, FFTSample *output, const FFTSample *input);
+ void (*imdct_half)(struct FFTContext *s, FFTSample *output, const FFTSample *input);
+ void (*mdct_calc)(struct FFTContext *s, FFTSample *output, const FFTSample *input);
+ int permutation;
+#define FF_MDCT_PERM_NONE 0
+#define FF_MDCT_PERM_INTERLEAVE 1
+};
+
+#if CONFIG_HARDCODED_TABLES
+#define COSTABLE_CONST const
+#define SINTABLE_CONST const
+#define SINETABLE_CONST const
+#else
+#define COSTABLE_CONST
+#define SINTABLE_CONST
+#define SINETABLE_CONST
+#endif
+
+#define COSTABLE(size) \
+ COSTABLE_CONST DECLARE_ALIGNED(16, FFTSample, ff_cos_##size)[size/2]
+#define SINTABLE(size) \
+ SINTABLE_CONST DECLARE_ALIGNED(16, FFTSample, ff_sin_##size)[size/2]
+#define SINETABLE(size) \
+ SINETABLE_CONST DECLARE_ALIGNED(16, float, ff_sine_##size)[size]
+extern COSTABLE(16);
+extern COSTABLE(32);
+extern COSTABLE(64);
+extern COSTABLE(128);
+extern COSTABLE(256);
+extern COSTABLE(512);
+extern COSTABLE(1024);
+extern COSTABLE(2048);
+extern COSTABLE(4096);
+extern COSTABLE(8192);
+extern COSTABLE(16384);
+extern COSTABLE(32768);
+extern COSTABLE(65536);
+extern COSTABLE_CONST FFTSample* const ff_cos_tabs[17];
+
+/**
+ * Initialize the cosine table in ff_cos_tabs[index]
+ * \param index index in ff_cos_tabs array of the table to initialize
+ */
+void ff_init_ff_cos_tabs(int index);
+
+extern SINTABLE(16);
+extern SINTABLE(32);
+extern SINTABLE(64);
+extern SINTABLE(128);
+extern SINTABLE(256);
+extern SINTABLE(512);
+extern SINTABLE(1024);
+extern SINTABLE(2048);
+extern SINTABLE(4096);
+extern SINTABLE(8192);
+extern SINTABLE(16384);
+extern SINTABLE(32768);
+extern SINTABLE(65536);
+
+/**
+ * Set up a complex FFT.
+ * @param nbits log2 of the length of the input array
+ * @param inverse if 0 perform the forward transform, if 1 perform the inverse
+ */
+int ff_fft_init(FFTContext *s, int nbits, int inverse);
+void ff_fft_permute_c(FFTContext *s, FFTComplex *z);
+void ff_fft_calc_c(FFTContext *s, FFTComplex *z);
+
+void ff_fft_init_altivec(FFTContext *s);
+void ff_fft_init_mmx(FFTContext *s);
+void ff_fft_init_arm(FFTContext *s);
+void ff_dct_init_mmx(DCTContext *s);
+
+/**
+ * Do the permutation needed BEFORE calling ff_fft_calc().
+ */
+static inline void ff_fft_permute(FFTContext *s, FFTComplex *z)
+{
+ s->fft_permute(s, z);
+}
+/**
+ * Do a complex FFT with the parameters defined in ff_fft_init(). The
+ * input data must be permuted before. No 1.0/sqrt(n) normalization is done.
+ */
+static inline void ff_fft_calc(FFTContext *s, FFTComplex *z)
+{
+ s->fft_calc(s, z);
+}
+void ff_fft_end(FFTContext *s);
+
+/* MDCT computation */
+
+static inline void ff_imdct_calc(FFTContext *s, FFTSample *output, const FFTSample *input)
+{
+ s->imdct_calc(s, output, input);
+}
+static inline void ff_imdct_half(FFTContext *s, FFTSample *output, const FFTSample *input)
+{
+ s->imdct_half(s, output, input);
+}
+
+static inline void ff_mdct_calc(FFTContext *s, FFTSample *output,
+ const FFTSample *input)
+{
+ s->mdct_calc(s, output, input);
+}
+
+/**
+ * Maximum window size for ff_kbd_window_init.
+ */
+#define FF_KBD_WINDOW_MAX 1024
+
+/**
+ * Generate a Kaiser-Bessel Derived Window.
+ * @param window pointer to half window
+ * @param alpha determines window shape
+ * @param n size of half window, max FF_KBD_WINDOW_MAX
+ */
+void ff_kbd_window_init(float *window, float alpha, int n);
+
+/**
+ * Generate a sine window.
+ * @param window pointer to half window
+ * @param n size of half window
+ */
+void ff_sine_window_init(float *window, int n);
+
+/**
+ * initialize the specified entry of ff_sine_windows
+ */
+void ff_init_ff_sine_windows(int index);
+extern SINETABLE( 32);
+extern SINETABLE( 64);
+extern SINETABLE( 128);
+extern SINETABLE( 256);
+extern SINETABLE( 512);
+extern SINETABLE(1024);
+extern SINETABLE(2048);
+extern SINETABLE(4096);
+extern SINETABLE_CONST float * const ff_sine_windows[13];
+
+int ff_mdct_init(FFTContext *s, int nbits, int inverse, double scale);
+void ff_imdct_calc_c(FFTContext *s, FFTSample *output, const FFTSample *input);
+void ff_imdct_half_c(FFTContext *s, FFTSample *output, const FFTSample *input);
+void ff_mdct_calc_c(FFTContext *s, FFTSample *output, const FFTSample *input);
+void ff_mdct_end(FFTContext *s);
+
+/* Real Discrete Fourier Transform */
+
+struct RDFTContext {
+ int nbits;
+ int inverse;
+ int sign_convention;
+
+ /* pre/post rotation tables */
+ const FFTSample *tcos;
+ SINTABLE_CONST FFTSample *tsin;
+ FFTContext fft;
+ void (*rdft_calc)(struct RDFTContext *s, FFTSample *z);
+};
+
+/**
+ * Set up a real FFT.
+ * @param nbits log2 of the length of the input array
+ * @param trans the type of transform
+ */
+int ff_rdft_init(RDFTContext *s, int nbits, enum RDFTransformType trans);
+void ff_rdft_end(RDFTContext *s);
+
+void ff_rdft_init_arm(RDFTContext *s);
+
+static av_always_inline void ff_rdft_calc(RDFTContext *s, FFTSample *data)
+{
+ s->rdft_calc(s, data);
+}
+
+/* Discrete Cosine Transform */
+
+struct DCTContext {
+ int nbits;
+ int inverse;
+ RDFTContext rdft;
+ const float *costab;
+ FFTSample *csc2;
+ void (*dct_calc)(struct DCTContext *s, FFTSample *data);
+ void (*dct32)(FFTSample *out, const FFTSample *in);
+};
+
+/**
+ * Set up DCT.
+ * @param nbits size of the input array:
+ * (1 << nbits) for DCT-II, DCT-III and DST-I
+ * (1 << nbits) + 1 for DCT-I
+ *
+ * @note the first element of the input of DST-I is ignored
+ */
+int ff_dct_init(DCTContext *s, int nbits, enum DCTTransformType type);
+void ff_dct_calc(DCTContext *s, FFTSample *data);
+void ff_dct_end (DCTContext *s);
+
+#endif /* AVCODEC_FFT_H */
diff --git a/plugins/supereq/ffmpeg_fft/libavcodec/rdft.c b/plugins/supereq/ffmpeg_fft/libavcodec/rdft.c
new file mode 100644
index 00000000..fe6014fb
--- /dev/null
+++ b/plugins/supereq/ffmpeg_fft/libavcodec/rdft.c
@@ -0,0 +1,137 @@
+/*
+ * (I)RDFT transforms
+ * Copyright (c) 2009 Alex Converse <alex dot converse at gmail dot com>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include <stdlib.h>
+#include <math.h>
+#include "libavutil/mathematics.h"
+#include "fft.h"
+
+/**
+ * @file
+ * (Inverse) Real Discrete Fourier Transforms.
+ */
+
+/* sin(2*pi*x/n) for 0<=x<n/4, followed by n/2<=x<3n/4 */
+#if !CONFIG_HARDCODED_TABLES
+SINTABLE(16);
+SINTABLE(32);
+SINTABLE(64);
+SINTABLE(128);
+SINTABLE(256);
+SINTABLE(512);
+SINTABLE(1024);
+SINTABLE(2048);
+SINTABLE(4096);
+SINTABLE(8192);
+SINTABLE(16384);
+SINTABLE(32768);
+SINTABLE(65536);
+#endif
+SINTABLE_CONST FFTSample * const ff_sin_tabs[] = {
+ NULL, NULL, NULL, NULL,
+ ff_sin_16, ff_sin_32, ff_sin_64, ff_sin_128, ff_sin_256, ff_sin_512, ff_sin_1024,
+ ff_sin_2048, ff_sin_4096, ff_sin_8192, ff_sin_16384, ff_sin_32768, ff_sin_65536,
+};
+
+/** Map one real FFT into two parallel real even and odd FFTs. Then interleave
+ * the two real FFTs into one complex FFT. Unmangle the results.
+ * ref: http://www.engineeringproductivitytools.com/stuff/T0001/PT10.HTM
+ */
+static void ff_rdft_calc_c(RDFTContext* s, FFTSample* data)
+{
+ int i, i1, i2;
+ FFTComplex ev, od;
+ const int n = 1 << s->nbits;
+ const float k1 = 0.5;
+ const float k2 = 0.5 - s->inverse;
+ const FFTSample *tcos = s->tcos;
+ const FFTSample *tsin = s->tsin;
+
+ if (!s->inverse) {
+ ff_fft_permute(&s->fft, (FFTComplex*)data);
+ ff_fft_calc(&s->fft, (FFTComplex*)data);
+ }
+ /* i=0 is a special case because of packing, the DC term is real, so we
+ are going to throw the N/2 term (also real) in with it. */
+ ev.re = data[0];
+ data[0] = ev.re+data[1];
+ data[1] = ev.re-data[1];
+ for (i = 1; i < (n>>2); i++) {
+ i1 = 2*i;
+ i2 = n-i1;
+ /* Separate even and odd FFTs */
+ ev.re = k1*(data[i1 ]+data[i2 ]);
+ od.im = -k2*(data[i1 ]-data[i2 ]);
+ ev.im = k1*(data[i1+1]-data[i2+1]);
+ od.re = k2*(data[i1+1]+data[i2+1]);
+ /* Apply twiddle factors to the odd FFT and add to the even FFT */
+ data[i1 ] = ev.re + od.re*tcos[i] - od.im*tsin[i];
+ data[i1+1] = ev.im + od.im*tcos[i] + od.re*tsin[i];
+ data[i2 ] = ev.re - od.re*tcos[i] + od.im*tsin[i];
+ data[i2+1] = -ev.im + od.im*tcos[i] + od.re*tsin[i];
+ }
+ data[2*i+1]=s->sign_convention*data[2*i+1];
+ if (s->inverse) {
+ data[0] *= k1;
+ data[1] *= k1;
+ ff_fft_permute(&s->fft, (FFTComplex*)data);
+ ff_fft_calc(&s->fft, (FFTComplex*)data);
+ }
+}
+
+av_cold int ff_rdft_init(RDFTContext *s, int nbits, enum RDFTransformType trans)
+{
+ int n = 1 << nbits;
+ int i;
+ const double theta = (trans == DFT_R2C || trans == DFT_C2R ? -1 : 1)*2*M_PI/n;
+
+ s->nbits = nbits;
+ s->inverse = trans == IDFT_C2R || trans == DFT_C2R;
+ s->sign_convention = trans == IDFT_R2C || trans == DFT_C2R ? 1 : -1;
+
+ if (nbits < 4 || nbits > 16) {
+ return -1;
+ }
+
+ if (ff_fft_init(&s->fft, nbits-1, trans == IDFT_C2R || trans == IDFT_R2C) < 0) {
+ return -1;
+ }
+
+ ff_init_ff_cos_tabs(nbits);
+ s->tcos = ff_cos_tabs[nbits];
+ s->tsin = ff_sin_tabs[nbits]+(trans == DFT_R2C || trans == DFT_C2R)*(n>>2);
+#if !CONFIG_HARDCODED_TABLES
+ for (i = 0; i < (n>>2); i++) {
+ s->tsin[i] = sin(i*theta);
+ }
+#endif
+ s->rdft_calc = ff_rdft_calc_c;
+
+#if ARCH_ARM
+ ff_rdft_init_arm(s);
+#endif
+
+ return 0;
+}
+
+av_cold void ff_rdft_end(RDFTContext *s)
+{
+ ff_fft_end(&s->fft);
+}
diff --git a/plugins/supereq/ffmpeg_fft/libavutil/attributes.h b/plugins/supereq/ffmpeg_fft/libavutil/attributes.h
new file mode 100644
index 00000000..50fbfc31
--- /dev/null
+++ b/plugins/supereq/ffmpeg_fft/libavutil/attributes.h
@@ -0,0 +1,122 @@
+/*
+ * copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * Macro definitions for various function/variable attributes
+ */
+
+#ifndef AVUTIL_ATTRIBUTES_H
+#define AVUTIL_ATTRIBUTES_H
+
+#ifdef __GNUC__
+# define AV_GCC_VERSION_AT_LEAST(x,y) (__GNUC__ > x || __GNUC__ == x && __GNUC_MINOR__ >= y)
+#else
+# define AV_GCC_VERSION_AT_LEAST(x,y) 0
+#endif
+
+#ifndef av_always_inline
+#if AV_GCC_VERSION_AT_LEAST(3,1)
+# define av_always_inline __attribute__((always_inline)) inline
+#else
+# define av_always_inline inline
+#endif
+#endif
+
+#ifndef av_noinline
+#if AV_GCC_VERSION_AT_LEAST(3,1)
+# define av_noinline __attribute__((noinline))
+#else
+# define av_noinline
+#endif
+#endif
+
+#ifndef av_pure
+#if AV_GCC_VERSION_AT_LEAST(3,1)
+# define av_pure __attribute__((pure))
+#else
+# define av_pure
+#endif
+#endif
+
+#ifndef av_const
+#if AV_GCC_VERSION_AT_LEAST(2,6)
+# define av_const __attribute__((const))
+#else
+# define av_const
+#endif
+#endif
+
+#ifndef av_cold
+#if (!defined(__ICC) || __ICC > 1110) && AV_GCC_VERSION_AT_LEAST(4,3)
+# define av_cold __attribute__((cold))
+#else
+# define av_cold
+#endif
+#endif
+
+#ifndef av_flatten
+#if (!defined(__ICC) || __ICC > 1110) && AV_GCC_VERSION_AT_LEAST(4,1)
+# define av_flatten __attribute__((flatten))
+#else
+# define av_flatten
+#endif
+#endif
+
+#ifndef attribute_deprecated
+#if AV_GCC_VERSION_AT_LEAST(3,1)
+# define attribute_deprecated __attribute__((deprecated))
+#else
+# define attribute_deprecated
+#endif
+#endif
+
+#ifndef av_unused
+#if defined(__GNUC__)
+# define av_unused __attribute__((unused))
+#else
+# define av_unused
+#endif
+#endif
+
+#ifndef av_alias
+#if (!defined(__ICC) || __ICC > 1110) && AV_GCC_VERSION_AT_LEAST(3,3)
+# define av_alias __attribute__((may_alias))
+#else
+# define av_alias
+#endif
+#endif
+
+#ifndef av_uninit
+#if defined(__GNUC__) && !defined(__ICC)
+# define av_uninit(x) x=x
+#else
+# define av_uninit(x) x
+#endif
+#endif
+
+#ifdef __GNUC__
+# define av_builtin_constant_p __builtin_constant_p
+#else
+# define av_builtin_constant_p(x) 0
+#endif
+
+#endif /* AVUTIL_ATTRIBUTES_H */
+
diff --git a/plugins/supereq/ffmpeg_fft/libavutil/avconfig.h b/plugins/supereq/ffmpeg_fft/libavutil/avconfig.h
new file mode 100644
index 00000000..b028bb4f
--- /dev/null
+++ b/plugins/supereq/ffmpeg_fft/libavutil/avconfig.h
@@ -0,0 +1,5 @@
+/* Generated by ffconf */
+#ifndef AVUTIL_AVCONFIG_H
+#define AVUTIL_AVCONFIG_H
+#define AV_HAVE_BIGENDIAN 0
+#endif /* AVUTIL_AVCONFIG_H */
diff --git a/plugins/supereq/ffmpeg_fft/libavutil/avutil.h b/plugins/supereq/ffmpeg_fft/libavutil/avutil.h
new file mode 100644
index 00000000..f5d364be
--- /dev/null
+++ b/plugins/supereq/ffmpeg_fft/libavutil/avutil.h
@@ -0,0 +1,90 @@
+/*
+ * copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVUTIL_AVUTIL_H
+#define AVUTIL_AVUTIL_H
+
+/**
+ * @file
+ * external API header
+ */
+
+
+#define AV_STRINGIFY(s) AV_TOSTRING(s)
+#define AV_TOSTRING(s) #s
+
+#define AV_GLUE(a, b) a ## b
+#define AV_JOIN(a, b) AV_GLUE(a, b)
+
+#define AV_PRAGMA(s) _Pragma(#s)
+
+#define AV_VERSION_INT(a, b, c) (a<<16 | b<<8 | c)
+#define AV_VERSION_DOT(a, b, c) a ##.## b ##.## c
+#define AV_VERSION(a, b, c) AV_VERSION_DOT(a, b, c)
+
+#define LIBAVUTIL_VERSION_MAJOR 50
+#define LIBAVUTIL_VERSION_MINOR 21
+#define LIBAVUTIL_VERSION_MICRO 0
+
+#define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
+ LIBAVUTIL_VERSION_MINOR, \
+ LIBAVUTIL_VERSION_MICRO)
+#define LIBAVUTIL_VERSION AV_VERSION(LIBAVUTIL_VERSION_MAJOR, \
+ LIBAVUTIL_VERSION_MINOR, \
+ LIBAVUTIL_VERSION_MICRO)
+#define LIBAVUTIL_BUILD LIBAVUTIL_VERSION_INT
+
+#define LIBAVUTIL_IDENT "Lavu" AV_STRINGIFY(LIBAVUTIL_VERSION)
+
+/**
+ * Return the LIBAVUTIL_VERSION_INT constant.
+ */
+unsigned avutil_version(void);
+
+/**
+ * Return the libavutil build-time configuration.
+ */
+const char *avutil_configuration(void);
+
+/**
+ * Return the libavutil license.
+ */
+const char *avutil_license(void);
+
+enum AVMediaType {
+ AVMEDIA_TYPE_UNKNOWN = -1,
+ AVMEDIA_TYPE_VIDEO,
+ AVMEDIA_TYPE_AUDIO,
+ AVMEDIA_TYPE_DATA,
+ AVMEDIA_TYPE_SUBTITLE,
+ AVMEDIA_TYPE_ATTACHMENT,
+ AVMEDIA_TYPE_NB
+};
+
+#include "common.h"
+/* #include "error.h" */
+#include "mathematics.h"
+#include "rational.h"
+#include "intfloat_readwrite.h"
+/* #include "log.h" */
+/* #include "pixfmt.h" */
+
+#endif /* AVUTIL_AVUTIL_H */
+
diff --git a/plugins/supereq/ffmpeg_fft/libavutil/common.h b/plugins/supereq/ffmpeg_fft/libavutil/common.h
new file mode 100644
index 00000000..9dff1435
--- /dev/null
+++ b/plugins/supereq/ffmpeg_fft/libavutil/common.h
@@ -0,0 +1,347 @@
+/*
+ * copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * common internal and external API header
+ */
+
+#ifndef AVUTIL_COMMON_H
+#define AVUTIL_COMMON_H
+
+#include <ctype.h>
+#include <errno.h>
+#include <inttypes.h>
+#include <limits.h>
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "attributes.h"
+
+//rounded division & shift
+#define RSHIFT(a,b) ((a) > 0 ? ((a) + ((1<<(b))>>1))>>(b) : ((a) + ((1<<(b))>>1)-1)>>(b))
+/* assume b>0 */
+#define ROUNDED_DIV(a,b) (((a)>0 ? (a) + ((b)>>1) : (a) - ((b)>>1))/(b))
+#define FFABS(a) ((a) >= 0 ? (a) : (-(a)))
+#define FFSIGN(a) ((a) > 0 ? 1 : -1)
+
+#define FFMAX(a,b) ((a) > (b) ? (a) : (b))
+#define FFMAX3(a,b,c) FFMAX(FFMAX(a,b),c)
+#define FFMIN(a,b) ((a) > (b) ? (b) : (a))
+#define FFMIN3(a,b,c) FFMIN(FFMIN(a,b),c)
+
+#define FFSWAP(type,a,b) do{type SWAP_tmp= b; b= a; a= SWAP_tmp;}while(0)
+#define FF_ARRAY_ELEMS(a) (sizeof(a) / sizeof((a)[0]))
+#define FFALIGN(x, a) (((x)+(a)-1)&~((a)-1))
+
+/* misc math functions */
+extern const uint8_t ff_log2_tab[256];
+
+extern const uint8_t av_reverse[256];
+
+static inline av_const int av_log2_c(unsigned int v)
+{
+ int n = 0;
+ if (v & 0xffff0000) {
+ v >>= 16;
+ n += 16;
+ }
+ if (v & 0xff00) {
+ v >>= 8;
+ n += 8;
+ }
+ n += ff_log2_tab[v];
+
+ return n;
+}
+
+static inline av_const int av_log2_16bit_c(unsigned int v)
+{
+ int n = 0;
+ if (v & 0xff00) {
+ v >>= 8;
+ n += 8;
+ }
+ n += ff_log2_tab[v];
+
+ return n;
+}
+
+#ifdef HAVE_AV_CONFIG_H
+# include "config.h"
+# include "intmath.h"
+#endif
+
+/* Pull in unguarded fallback defines at the end of this file. */
+#include "common.h"
+
+/**
+ * Clip a signed integer value into the amin-amax range.
+ * @param a value to clip
+ * @param amin minimum value of the clip range
+ * @param amax maximum value of the clip range
+ * @return clipped value
+ */
+static inline av_const int av_clip_c(int a, int amin, int amax)
+{
+ if (a < amin) return amin;
+ else if (a > amax) return amax;
+ else return a;
+}
+
+/**
+ * Clip a signed integer value into the 0-255 range.
+ * @param a value to clip
+ * @return clipped value
+ */
+static inline av_const uint8_t av_clip_uint8_c(int a)
+{
+ if (a&(~0xFF)) return (-a)>>31;
+ else return a;
+}
+
+/**
+ * Clip a signed integer value into the -128,127 range.
+ * @param a value to clip
+ * @return clipped value
+ */
+static inline av_const int8_t av_clip_int8_c(int a)
+{
+ if ((a+0x80) & ~0xFF) return (a>>31) ^ 0x7F;
+ else return a;
+}
+
+/**
+ * Clip a signed integer value into the 0-65535 range.
+ * @param a value to clip
+ * @return clipped value
+ */
+static inline av_const uint16_t av_clip_uint16_c(int a)
+{
+ if (a&(~0xFFFF)) return (-a)>>31;
+ else return a;
+}
+
+/**
+ * Clip a signed integer value into the -32768,32767 range.
+ * @param a value to clip
+ * @return clipped value
+ */
+static inline av_const int16_t av_clip_int16_c(int a)
+{
+ if ((a+0x8000) & ~0xFFFF) return (a>>31) ^ 0x7FFF;
+ else return a;
+}
+
+/**
+ * Clip a signed 64-bit integer value into the -2147483648,2147483647 range.
+ * @param a value to clip
+ * @return clipped value
+ */
+static inline av_const int32_t av_clipl_int32_c(int64_t a)
+{
+ if ((a+0x80000000u) & ~UINT64_C(0xFFFFFFFF)) return (a>>63) ^ 0x7FFFFFFF;
+ else return a;
+}
+
+/**
+ * Clip a float value into the amin-amax range.
+ * @param a value to clip
+ * @param amin minimum value of the clip range
+ * @param amax maximum value of the clip range
+ * @return clipped value
+ */
+static inline av_const float av_clipf_c(float a, float amin, float amax)
+{
+ if (a < amin) return amin;
+ else if (a > amax) return amax;
+ else return a;
+}
+
+/** Compute ceil(log2(x)).
+ * @param x value used to compute ceil(log2(x))
+ * @return computed ceiling of log2(x)
+ */
+static inline av_const int av_ceil_log2_c(int x)
+{
+ return av_log2((x - 1) << 1);
+}
+
+#define MKTAG(a,b,c,d) ((a) | ((b) << 8) | ((c) << 16) | ((d) << 24))
+#define MKBETAG(a,b,c,d) ((d) | ((c) << 8) | ((b) << 16) | ((a) << 24))
+
+/**
+ * Convert a UTF-8 character (up to 4 bytes) to its 32-bit UCS-4 encoded form.
+ *
+ * @param val Output value, must be an lvalue of type uint32_t.
+ * @param GET_BYTE Expression reading one byte from the input.
+ * Evaluated up to 7 times (4 for the currently
+ * assigned Unicode range). With a memory buffer
+ * input, this could be *ptr++.
+ * @param ERROR Expression to be evaluated on invalid input,
+ * typically a goto statement.
+ */
+#define GET_UTF8(val, GET_BYTE, ERROR)\
+ val= GET_BYTE;\
+ {\
+ int ones= 7 - av_log2(val ^ 255);\
+ if(ones==1)\
+ ERROR\
+ val&= 127>>ones;\
+ while(--ones > 0){\
+ int tmp= GET_BYTE - 128;\
+ if(tmp>>6)\
+ ERROR\
+ val= (val<<6) + tmp;\
+ }\
+ }
+
+/**
+ * Convert a UTF-16 character (2 or 4 bytes) to its 32-bit UCS-4 encoded form.
+ *
+ * @param val Output value, must be an lvalue of type uint32_t.
+ * @param GET_16BIT Expression returning two bytes of UTF-16 data converted
+ * to native byte order. Evaluated one or two times.
+ * @param ERROR Expression to be evaluated on invalid input,
+ * typically a goto statement.
+ */
+#define GET_UTF16(val, GET_16BIT, ERROR)\
+ val = GET_16BIT;\
+ {\
+ unsigned int hi = val - 0xD800;\
+ if (hi < 0x800) {\
+ val = GET_16BIT - 0xDC00;\
+ if (val > 0x3FFU || hi > 0x3FFU)\
+ ERROR\
+ val += (hi<<10) + 0x10000;\
+ }\
+ }\
+
+/*!
+ * \def PUT_UTF8(val, tmp, PUT_BYTE)
+ * Convert a 32-bit Unicode character to its UTF-8 encoded form (up to 4 bytes long).
+ * \param val is an input-only argument and should be of type uint32_t. It holds
+ * a UCS-4 encoded Unicode character that is to be converted to UTF-8. If
+ * val is given as a function it is executed only once.
+ * \param tmp is a temporary variable and should be of type uint8_t. It
+ * represents an intermediate value during conversion that is to be
+ * output by PUT_BYTE.
+ * \param PUT_BYTE writes the converted UTF-8 bytes to any proper destination.
+ * It could be a function or a statement, and uses tmp as the input byte.
+ * For example, PUT_BYTE could be "*output++ = tmp;" PUT_BYTE will be
+ * executed up to 4 times for values in the valid UTF-8 range and up to
+ * 7 times in the general case, depending on the length of the converted
+ * Unicode character.
+ */
+#define PUT_UTF8(val, tmp, PUT_BYTE)\
+ {\
+ int bytes, shift;\
+ uint32_t in = val;\
+ if (in < 0x80) {\
+ tmp = in;\
+ PUT_BYTE\
+ } else {\
+ bytes = (av_log2(in) + 4) / 5;\
+ shift = (bytes - 1) * 6;\
+ tmp = (256 - (256 >> bytes)) | (in >> shift);\
+ PUT_BYTE\
+ while (shift >= 6) {\
+ shift -= 6;\
+ tmp = 0x80 | ((in >> shift) & 0x3f);\
+ PUT_BYTE\
+ }\
+ }\
+ }
+
+/*!
+ * \def PUT_UTF16(val, tmp, PUT_16BIT)
+ * Convert a 32-bit Unicode character to its UTF-16 encoded form (2 or 4 bytes).
+ * \param val is an input-only argument and should be of type uint32_t. It holds
+ * a UCS-4 encoded Unicode character that is to be converted to UTF-16. If
+ * val is given as a function it is executed only once.
+ * \param tmp is a temporary variable and should be of type uint16_t. It
+ * represents an intermediate value during conversion that is to be
+ * output by PUT_16BIT.
+ * \param PUT_16BIT writes the converted UTF-16 data to any proper destination
+ * in desired endianness. It could be a function or a statement, and uses tmp
+ * as the input byte. For example, PUT_BYTE could be "*output++ = tmp;"
+ * PUT_BYTE will be executed 1 or 2 times depending on input character.
+ */
+#define PUT_UTF16(val, tmp, PUT_16BIT)\
+ {\
+ uint32_t in = val;\
+ if (in < 0x10000) {\
+ tmp = in;\
+ PUT_16BIT\
+ } else {\
+ tmp = 0xD800 | ((in - 0x10000) >> 10);\
+ PUT_16BIT\
+ tmp = 0xDC00 | ((in - 0x10000) & 0x3FF);\
+ PUT_16BIT\
+ }\
+ }\
+
+
+
+#include "mem.h"
+
+#ifdef HAVE_AV_CONFIG_H
+# include "internal.h"
+#endif /* HAVE_AV_CONFIG_H */
+
+#endif /* AVUTIL_COMMON_H */
+
+/*
+ * The following definitions are outside the multiple inclusion guard
+ * to ensure they are immediately available in intmath.h.
+ */
+
+#ifndef av_log2
+# define av_log2 av_log2_c
+#endif
+#ifndef av_log2_16bit
+# define av_log2_16bit av_log2_16bit_c
+#endif
+#ifndef av_ceil_log2
+# define av_ceil_log2 av_ceil_log2_c
+#endif
+#ifndef av_clip
+# define av_clip av_clip_c
+#endif
+#ifndef av_clip_uint8
+# define av_clip_uint8 av_clip_uint8_c
+#endif
+#ifndef av_clip_int8
+# define av_clip_int8 av_clip_int8_c
+#endif
+#ifndef av_clip_uint16
+# define av_clip_uint16 av_clip_uint16_c
+#endif
+#ifndef av_clip_int16
+# define av_clip_int16 av_clip_int16_c
+#endif
+#ifndef av_clipl_int32
+# define av_clipl_int32 av_clipl_int32_c
+#endif
+#ifndef av_clipf
+# define av_clipf av_clipf_c
+#endif
+
diff --git a/plugins/supereq/ffmpeg_fft/libavutil/intfloat_readwrite.c b/plugins/supereq/ffmpeg_fft/libavutil/intfloat_readwrite.c
new file mode 100644
index 00000000..79fe1867
--- /dev/null
+++ b/plugins/supereq/ffmpeg_fft/libavutil/intfloat_readwrite.c
@@ -0,0 +1,98 @@
+/*
+ * portable IEEE float/double read/write functions
+ *
+ * Copyright (c) 2005 Michael Niedermayer <michaelni@gmx.at>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * portable IEEE float/double read/write functions
+ */
+
+#include <stdint.h>
+#include <math.h>
+#include "intfloat_readwrite.h"
+
+double av_int2dbl(int64_t v){
+ if(v+v > 0xFFEULL<<52)
+ return 0.0/0.0;
+ return ldexp(((v&((1LL<<52)-1)) + (1LL<<52)) * (v>>63|1), (v>>52&0x7FF)-1075);
+}
+
+float av_int2flt(int32_t v){
+ if(v+v > 0xFF000000U)
+ return 0.0/0.0;
+ return ldexp(((v&0x7FFFFF) + (1<<23)) * (v>>31|1), (v>>23&0xFF)-150);
+}
+
+double av_ext2dbl(const AVExtFloat ext){
+ uint64_t m = 0;
+ int e, i;
+
+ for (i = 0; i < 8; i++)
+ m = (m<<8) + ext.mantissa[i];
+ e = (((int)ext.exponent[0]&0x7f)<<8) | ext.exponent[1];
+ if (e == 0x7fff && m)
+ return 0.0/0.0;
+ e -= 16383 + 63; /* In IEEE 80 bits, the whole (i.e. 1.xxxx)
+ * mantissa bit is written as opposed to the
+ * single and double precision formats. */
+ if (ext.exponent[0]&0x80)
+ m= -m;
+ return ldexp(m, e);
+}
+
+int64_t av_dbl2int(double d){
+ int e;
+ if ( !d) return 0;
+ else if(d-d) return 0x7FF0000000000000LL + ((int64_t)(d<0)<<63) + (d!=d);
+ d= frexp(d, &e);
+ return (int64_t)(d<0)<<63 | (e+1022LL)<<52 | (int64_t)((fabs(d)-0.5)*(1LL<<53));
+}
+
+int32_t av_flt2int(float d){
+ int e;
+ if ( !d) return 0;
+ else if(d-d) return 0x7F800000 + ((d<0)<<31) + (d!=d);
+ d= frexp(d, &e);
+ return (d<0)<<31 | (e+126)<<23 | (int64_t)((fabs(d)-0.5)*(1<<24));
+}
+
+AVExtFloat av_dbl2ext(double d){
+ struct AVExtFloat ext= {{0}};
+ int e, i; double f; uint64_t m;
+
+ f = fabs(frexp(d, &e));
+ if (f >= 0.5 && f < 1) {
+ e += 16382;
+ ext.exponent[0] = e>>8;
+ ext.exponent[1] = e;
+ m = (uint64_t)ldexp(f, 64);
+ for (i=0; i < 8; i++)
+ ext.mantissa[i] = m>>(56-(i<<3));
+ } else if (f != 0.0) {
+ ext.exponent[0] = 0x7f; ext.exponent[1] = 0xff;
+ if (f != 1/0.0)
+ ext.mantissa[0] = ~0;
+ }
+ if (d < 0)
+ ext.exponent[0] |= 0x80;
+ return ext;
+}
+
diff --git a/plugins/supereq/ffmpeg_fft/libavutil/intfloat_readwrite.h b/plugins/supereq/ffmpeg_fft/libavutil/intfloat_readwrite.h
new file mode 100644
index 00000000..644b3e64
--- /dev/null
+++ b/plugins/supereq/ffmpeg_fft/libavutil/intfloat_readwrite.h
@@ -0,0 +1,41 @@
+/*
+ * copyright (c) 2005 Michael Niedermayer <michaelni@gmx.at>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVUTIL_INTFLOAT_READWRITE_H
+#define AVUTIL_INTFLOAT_READWRITE_H
+
+#include <stdint.h>
+#include "attributes.h"
+
+/* IEEE 80 bits extended float */
+typedef struct AVExtFloat {
+ uint8_t exponent[2];
+ uint8_t mantissa[8];
+} AVExtFloat;
+
+double av_int2dbl(int64_t v) av_const;
+float av_int2flt(int32_t v) av_const;
+double av_ext2dbl(const AVExtFloat ext) av_const;
+int64_t av_dbl2int(double d) av_const;
+int32_t av_flt2int(float d) av_const;
+AVExtFloat av_dbl2ext(double d) av_const;
+
+#endif /* AVUTIL_INTFLOAT_READWRITE_H */
+
diff --git a/plugins/supereq/ffmpeg_fft/libavutil/mathematics.c b/plugins/supereq/ffmpeg_fft/libavutil/mathematics.c
new file mode 100644
index 00000000..c6851cb7
--- /dev/null
+++ b/plugins/supereq/ffmpeg_fft/libavutil/mathematics.c
@@ -0,0 +1,181 @@
+/*
+ * Copyright (c) 2005 Michael Niedermayer <michaelni@gmx.at>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * miscellaneous math routines and tables
+ */
+
+#include <assert.h>
+#include <stdint.h>
+#include <limits.h>
+#include "mathematics.h"
+
+const uint8_t ff_sqrt_tab[256]={
+ 0, 16, 23, 28, 32, 36, 40, 43, 46, 48, 51, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 77, 79, 80, 82, 84, 85, 87, 88, 90,
+ 91, 92, 94, 95, 96, 98, 99,100,102,103,104,105,107,108,109,110,111,112,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
+128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,144,145,146,147,148,149,150,151,151,152,153,154,155,156,156,
+157,158,159,160,160,161,162,163,164,164,165,166,167,168,168,169,170,171,171,172,173,174,174,175,176,176,177,178,179,179,180,181,
+182,182,183,184,184,185,186,186,187,188,188,189,190,190,191,192,192,193,194,194,195,196,196,197,198,198,199,200,200,201,202,202,
+203,204,204,205,205,206,207,207,208,208,209,210,210,211,212,212,213,213,214,215,215,216,216,217,218,218,219,219,220,220,221,222,
+222,223,223,224,224,225,226,226,227,227,228,228,229,230,230,231,231,232,232,233,233,234,235,235,236,236,237,237,238,238,239,239,
+240,240,241,242,242,243,243,244,244,245,245,246,246,247,247,248,248,249,249,250,250,251,251,252,252,253,253,254,254,255,255,255
+};
+
+const uint8_t ff_log2_tab[256]={
+ 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
+ 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+ 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+ 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
+};
+
+const uint8_t av_reverse[256]={
+0x00,0x80,0x40,0xC0,0x20,0xA0,0x60,0xE0,0x10,0x90,0x50,0xD0,0x30,0xB0,0x70,0xF0,
+0x08,0x88,0x48,0xC8,0x28,0xA8,0x68,0xE8,0x18,0x98,0x58,0xD8,0x38,0xB8,0x78,0xF8,
+0x04,0x84,0x44,0xC4,0x24,0xA4,0x64,0xE4,0x14,0x94,0x54,0xD4,0x34,0xB4,0x74,0xF4,
+0x0C,0x8C,0x4C,0xCC,0x2C,0xAC,0x6C,0xEC,0x1C,0x9C,0x5C,0xDC,0x3C,0xBC,0x7C,0xFC,
+0x02,0x82,0x42,0xC2,0x22,0xA2,0x62,0xE2,0x12,0x92,0x52,0xD2,0x32,0xB2,0x72,0xF2,
+0x0A,0x8A,0x4A,0xCA,0x2A,0xAA,0x6A,0xEA,0x1A,0x9A,0x5A,0xDA,0x3A,0xBA,0x7A,0xFA,
+0x06,0x86,0x46,0xC6,0x26,0xA6,0x66,0xE6,0x16,0x96,0x56,0xD6,0x36,0xB6,0x76,0xF6,
+0x0E,0x8E,0x4E,0xCE,0x2E,0xAE,0x6E,0xEE,0x1E,0x9E,0x5E,0xDE,0x3E,0xBE,0x7E,0xFE,
+0x01,0x81,0x41,0xC1,0x21,0xA1,0x61,0xE1,0x11,0x91,0x51,0xD1,0x31,0xB1,0x71,0xF1,
+0x09,0x89,0x49,0xC9,0x29,0xA9,0x69,0xE9,0x19,0x99,0x59,0xD9,0x39,0xB9,0x79,0xF9,
+0x05,0x85,0x45,0xC5,0x25,0xA5,0x65,0xE5,0x15,0x95,0x55,0xD5,0x35,0xB5,0x75,0xF5,
+0x0D,0x8D,0x4D,0xCD,0x2D,0xAD,0x6D,0xED,0x1D,0x9D,0x5D,0xDD,0x3D,0xBD,0x7D,0xFD,
+0x03,0x83,0x43,0xC3,0x23,0xA3,0x63,0xE3,0x13,0x93,0x53,0xD3,0x33,0xB3,0x73,0xF3,
+0x0B,0x8B,0x4B,0xCB,0x2B,0xAB,0x6B,0xEB,0x1B,0x9B,0x5B,0xDB,0x3B,0xBB,0x7B,0xFB,
+0x07,0x87,0x47,0xC7,0x27,0xA7,0x67,0xE7,0x17,0x97,0x57,0xD7,0x37,0xB7,0x77,0xF7,
+0x0F,0x8F,0x4F,0xCF,0x2F,0xAF,0x6F,0xEF,0x1F,0x9F,0x5F,0xDF,0x3F,0xBF,0x7F,0xFF,
+};
+
+int64_t av_gcd(int64_t a, int64_t b){
+ if(b) return av_gcd(b, a%b);
+ else return a;
+}
+
+int64_t av_rescale_rnd(int64_t a, int64_t b, int64_t c, enum AVRounding rnd){
+ int64_t r=0;
+ assert(c > 0);
+ assert(b >=0);
+ assert((unsigned)rnd<=5 && rnd!=4);
+
+ if(a<0 && a != INT64_MIN) return -av_rescale_rnd(-a, b, c, rnd ^ ((rnd>>1)&1));
+
+ if(rnd==AV_ROUND_NEAR_INF) r= c/2;
+ else if(rnd&1) r= c-1;
+
+ if(b<=INT_MAX && c<=INT_MAX){
+ if(a<=INT_MAX)
+ return (a * b + r)/c;
+ else
+ return a/c*b + (a%c*b + r)/c;
+ }else{
+#if 1
+ uint64_t a0= a&0xFFFFFFFF;
+ uint64_t a1= a>>32;
+ uint64_t b0= b&0xFFFFFFFF;
+ uint64_t b1= b>>32;
+ uint64_t t1= a0*b1 + a1*b0;
+ uint64_t t1a= t1<<32;
+ int i;
+
+ a0 = a0*b0 + t1a;
+ a1 = a1*b1 + (t1>>32) + (a0<t1a);
+ a0 += r;
+ a1 += a0<r;
+
+ for(i=63; i>=0; i--){
+// int o= a1 & 0x8000000000000000ULL;
+ a1+= a1 + ((a0>>i)&1);
+ t1+=t1;
+ if(/*o || */c <= a1){
+ a1 -= c;
+ t1++;
+ }
+ }
+ return t1;
+ }
+#else
+ AVInteger ai;
+ ai= av_mul_i(av_int2i(a), av_int2i(b));
+ ai= av_add_i(ai, av_int2i(r));
+
+ return av_i2int(av_div_i(ai, av_int2i(c)));
+ }
+#endif
+}
+
+int64_t av_rescale(int64_t a, int64_t b, int64_t c){
+ return av_rescale_rnd(a, b, c, AV_ROUND_NEAR_INF);
+}
+
+int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq){
+ int64_t b= bq.num * (int64_t)cq.den;
+ int64_t c= cq.num * (int64_t)bq.den;
+ return av_rescale_rnd(a, b, c, AV_ROUND_NEAR_INF);
+}
+
+int av_compare_ts(int64_t ts_a, AVRational tb_a, int64_t ts_b, AVRational tb_b){
+ int64_t a= tb_a.num * (int64_t)tb_b.den;
+ int64_t b= tb_b.num * (int64_t)tb_a.den;
+ if (av_rescale_rnd(ts_a, a, b, AV_ROUND_DOWN) < ts_b) return -1;
+ if (av_rescale_rnd(ts_b, b, a, AV_ROUND_DOWN) < ts_a) return 1;
+ return 0;
+}
+
+int64_t av_compare_mod(uint64_t a, uint64_t b, uint64_t mod){
+ int64_t c= (a-b) & (mod-1);
+ if(c > (mod>>1))
+ c-= mod;
+ return c;
+}
+
+#ifdef TEST
+#include "integer.h"
+#undef printf
+int main(void){
+ int64_t a,b,c,d,e;
+
+ for(a=7; a<(1LL<<62); a+=a/3+1){
+ for(b=3; b<(1LL<<62); b+=b/4+1){
+ for(c=9; c<(1LL<<62); c+=(c*2)/5+3){
+ int64_t r= c/2;
+ AVInteger ai;
+ ai= av_mul_i(av_int2i(a), av_int2i(b));
+ ai= av_add_i(ai, av_int2i(r));
+
+ d= av_i2int(av_div_i(ai, av_int2i(c)));
+
+ e= av_rescale(a,b,c);
+
+ if((double)a * (double)b / (double)c > (1LL<<63))
+ continue;
+
+ if(d!=e) printf("%"PRId64"*%"PRId64"/%"PRId64"= %"PRId64"=%"PRId64"\n", a, b, c, d, e);
+ }
+ }
+ }
+ return 0;
+}
+#endif
diff --git a/plugins/supereq/ffmpeg_fft/libavutil/mathematics.h b/plugins/supereq/ffmpeg_fft/libavutil/mathematics.h
new file mode 100644
index 00000000..06d36e09
--- /dev/null
+++ b/plugins/supereq/ffmpeg_fft/libavutil/mathematics.h
@@ -0,0 +1,110 @@
+/*
+ * copyright (c) 2005 Michael Niedermayer <michaelni@gmx.at>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVUTIL_MATHEMATICS_H
+#define AVUTIL_MATHEMATICS_H
+
+#include <stdint.h>
+#include <math.h>
+#include "attributes.h"
+#include "rational.h"
+
+#ifndef M_E
+#define M_E 2.7182818284590452354 /* e */
+#endif
+#ifndef M_LN2
+#define M_LN2 0.69314718055994530942 /* log_e 2 */
+#endif
+#ifndef M_LN10
+#define M_LN10 2.30258509299404568402 /* log_e 10 */
+#endif
+#ifndef M_LOG2_10
+#define M_LOG2_10 3.32192809488736234787 /* log_2 10 */
+#endif
+#ifndef M_PI
+#define M_PI 3.14159265358979323846 /* pi */
+#endif
+#ifndef M_SQRT1_2
+#define M_SQRT1_2 0.70710678118654752440 /* 1/sqrt(2) */
+#endif
+#ifndef M_SQRT2
+#define M_SQRT2 1.41421356237309504880 /* sqrt(2) */
+#endif
+#ifndef NAN
+#define NAN (0.0/0.0)
+#endif
+#ifndef INFINITY
+#define INFINITY (1.0/0.0)
+#endif
+
+enum AVRounding {
+ AV_ROUND_ZERO = 0, ///< Round toward zero.
+ AV_ROUND_INF = 1, ///< Round away from zero.
+ AV_ROUND_DOWN = 2, ///< Round toward -infinity.
+ AV_ROUND_UP = 3, ///< Round toward +infinity.
+ AV_ROUND_NEAR_INF = 5, ///< Round to nearest and halfway cases away from zero.
+};
+
+/**
+ * Return the greatest common divisor of a and b.
+ * If both a and b are 0 or either or both are <0 then behavior is
+ * undefined.
+ */
+int64_t av_const av_gcd(int64_t a, int64_t b);
+
+/**
+ * Rescale a 64-bit integer with rounding to nearest.
+ * A simple a*b/c isn't possible as it can overflow.
+ */
+int64_t av_rescale(int64_t a, int64_t b, int64_t c) av_const;
+
+/**
+ * Rescale a 64-bit integer with specified rounding.
+ * A simple a*b/c isn't possible as it can overflow.
+ */
+int64_t av_rescale_rnd(int64_t a, int64_t b, int64_t c, enum AVRounding) av_const;
+
+/**
+ * Rescale a 64-bit integer by 2 rational numbers.
+ */
+int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq) av_const;
+
+/**
+ * Compare 2 timestamps each in its own timebases.
+ * The result of the function is undefined if one of the timestamps
+ * is outside the int64_t range when represented in the others timebase.
+ * @return -1 if ts_a is before ts_b, 1 if ts_a is after ts_b or 0 if they represent the same position
+ */
+int av_compare_ts(int64_t ts_a, AVRational tb_a, int64_t ts_b, AVRational tb_b);
+
+/**
+ * Compare 2 integers modulo mod.
+ * That is we compare integers a and b for which only the least
+ * significant log2(mod) bits are known.
+ *
+ * @param mod must be a power of 2
+ * @return a negative value if a is smaller than b
+ * a positive value if a is greater than b
+ * 0 if a equals b
+ */
+int64_t av_compare_mod(uint64_t a, uint64_t b, uint64_t mod);
+
+#endif /* AVUTIL_MATHEMATICS_H */
+
diff --git a/plugins/supereq/ffmpeg_fft/libavutil/mem.c b/plugins/supereq/ffmpeg_fft/libavutil/mem.c
new file mode 100644
index 00000000..8cad089a
--- /dev/null
+++ b/plugins/supereq/ffmpeg_fft/libavutil/mem.c
@@ -0,0 +1,176 @@
+/*
+ * default memory allocator for libavutil
+ * Copyright (c) 2002 Fabrice Bellard
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * default memory allocator for libavutil
+ */
+
+#include "config.h"
+
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+#if HAVE_MALLOC_H
+#include <malloc.h>
+#endif
+
+#include "avutil.h"
+#include "mem.h"
+
+/* here we can use OS-dependent allocation functions */
+#undef free
+#undef malloc
+#undef realloc
+
+#ifdef MALLOC_PREFIX
+
+#define malloc AV_JOIN(MALLOC_PREFIX, malloc)
+#define memalign AV_JOIN(MALLOC_PREFIX, memalign)
+#define posix_memalign AV_JOIN(MALLOC_PREFIX, posix_memalign)
+#define realloc AV_JOIN(MALLOC_PREFIX, realloc)
+#define free AV_JOIN(MALLOC_PREFIX, free)
+
+void *malloc(size_t size);
+void *memalign(size_t align, size_t size);
+int posix_memalign(void **ptr, size_t align, size_t size);
+void *realloc(void *ptr, size_t size);
+void free(void *ptr);
+
+#endif /* MALLOC_PREFIX */
+
+/* You can redefine av_malloc and av_free in your project to use your
+ memory allocator. You do not need to suppress this file because the
+ linker will do it automatically. */
+
+void *av_malloc(unsigned int size)
+{
+ void *ptr = NULL;
+#if CONFIG_MEMALIGN_HACK
+ long diff;
+#endif
+
+ /* let's disallow possible ambiguous cases */
+ if(size > (INT_MAX-16) )
+ return NULL;
+
+#if CONFIG_MEMALIGN_HACK
+ ptr = malloc(size+16);
+ if(!ptr)
+ return ptr;
+ diff= ((-(long)ptr - 1)&15) + 1;
+ ptr = (char*)ptr + diff;
+ ((char*)ptr)[-1]= diff;
+#elif HAVE_POSIX_MEMALIGN
+ if (posix_memalign(&ptr,16,size))
+ ptr = NULL;
+#elif HAVE_MEMALIGN
+ ptr = memalign(16,size);
+ /* Why 64?
+ Indeed, we should align it:
+ on 4 for 386
+ on 16 for 486
+ on 32 for 586, PPro - K6-III
+ on 64 for K7 (maybe for P3 too).
+ Because L1 and L2 caches are aligned on those values.
+ But I don't want to code such logic here!
+ */
+ /* Why 16?
+ Because some CPUs need alignment, for example SSE2 on P4, & most RISC CPUs
+ it will just trigger an exception and the unaligned load will be done in the
+ exception handler or it will just segfault (SSE2 on P4).
+ Why not larger? Because I did not see a difference in benchmarks ...
+ */
+ /* benchmarks with P3
+ memalign(64)+1 3071,3051,3032
+ memalign(64)+2 3051,3032,3041
+ memalign(64)+4 2911,2896,2915
+ memalign(64)+8 2545,2554,2550
+ memalign(64)+16 2543,2572,2563
+ memalign(64)+32 2546,2545,2571
+ memalign(64)+64 2570,2533,2558
+
+ BTW, malloc seems to do 8-byte alignment by default here.
+ */
+#else
+ ptr = malloc(size);
+#endif
+ return ptr;
+}
+
+void *av_realloc(void *ptr, unsigned int size)
+{
+#if CONFIG_MEMALIGN_HACK
+ int diff;
+#endif
+
+ /* let's disallow possible ambiguous cases */
+ if(size > (INT_MAX-16) )
+ return NULL;
+
+#if CONFIG_MEMALIGN_HACK
+ //FIXME this isn't aligned correctly, though it probably isn't needed
+ if(!ptr) return av_malloc(size);
+ diff= ((char*)ptr)[-1];
+ return (char*)realloc((char*)ptr - diff, size + diff) + diff;
+#else
+ return realloc(ptr, size);
+#endif
+}
+
+void av_free(void *ptr)
+{
+ /* XXX: this test should not be needed on most libcs */
+ if (ptr)
+#if CONFIG_MEMALIGN_HACK
+ free((char*)ptr - ((char*)ptr)[-1]);
+#else
+ free(ptr);
+#endif
+}
+
+void av_freep(void *arg)
+{
+ void **ptr= (void**)arg;
+ av_free(*ptr);
+ *ptr = NULL;
+}
+
+void *av_mallocz(unsigned int size)
+{
+ void *ptr = av_malloc(size);
+ if (ptr)
+ memset(ptr, 0, size);
+ return ptr;
+}
+
+char *av_strdup(const char *s)
+{
+ char *ptr= NULL;
+ if(s){
+ int len = strlen(s) + 1;
+ ptr = av_malloc(len);
+ if (ptr)
+ memcpy(ptr, s, len);
+ }
+ return ptr;
+}
+
diff --git a/plugins/supereq/ffmpeg_fft/libavutil/mem.h b/plugins/supereq/ffmpeg_fft/libavutil/mem.h
new file mode 100644
index 00000000..7da0a15f
--- /dev/null
+++ b/plugins/supereq/ffmpeg_fft/libavutil/mem.h
@@ -0,0 +1,128 @@
+/*
+ * copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * memory handling functions
+ */
+
+#ifndef AVUTIL_MEM_H
+#define AVUTIL_MEM_H
+
+#include "attributes.h"
+#include "avutil.h"
+#include "publik.h"
+
+#if defined(__ICC) && _ICC < 1200 || defined(__SUNPRO_C)
+ #define DECLARE_ALIGNED(n,t,v) t __attribute__ ((aligned (n))) v
+ #define DECLARE_ASM_CONST(n,t,v) const t __attribute__ ((aligned (n))) v
+#elif defined(__TI_COMPILER_VERSION__)
+ #define DECLARE_ALIGNED(n,t,v) \
+ AV_PRAGMA(DATA_ALIGN(v,n)) \
+ t __attribute__((aligned(n))) v
+ #define DECLARE_ASM_CONST(n,t,v) \
+ AV_PRAGMA(DATA_ALIGN(v,n)) \
+ static const t __attribute__((aligned(n))) v
+#elif defined(__GNUC__)
+ #define DECLARE_ALIGNED(n,t,v) t __attribute__ ((aligned (n))) v
+ #define DECLARE_ASM_CONST(n,t,v) static const t attribute_used __attribute__ ((aligned (n))) v
+#elif defined(_MSC_VER)
+ #define DECLARE_ALIGNED(n,t,v) __declspec(align(n)) t v
+ #define DECLARE_ASM_CONST(n,t,v) __declspec(align(n)) static const t v
+#else
+ #define DECLARE_ALIGNED(n,t,v) t v
+ #define DECLARE_ASM_CONST(n,t,v) static const t v
+#endif
+
+#if AV_GCC_VERSION_AT_LEAST(3,1)
+ #define av_malloc_attrib __attribute__((__malloc__))
+#else
+ #define av_malloc_attrib
+#endif
+
+#if (!defined(__ICC) || __ICC > 1110) && AV_GCC_VERSION_AT_LEAST(4,3)
+ #define av_alloc_size(n) __attribute__((alloc_size(n)))
+#else
+ #define av_alloc_size(n)
+#endif
+
+/**
+ * Allocate a block of size bytes with alignment suitable for all
+ * memory accesses (including vectors if available on the CPU).
+ * @param size Size in bytes for the memory block to be allocated.
+ * @return Pointer to the allocated block, NULL if the block cannot
+ * be allocated.
+ * @see av_mallocz()
+ */
+PUBLIK void *av_malloc(unsigned int size) av_malloc_attrib av_alloc_size(1);
+
+/**
+ * Allocate or reallocate a block of memory.
+ * If ptr is NULL and size > 0, allocate a new block. If
+ * size is zero, free the memory block pointed to by ptr.
+ * @param size Size in bytes for the memory block to be allocated or
+ * reallocated.
+ * @param ptr Pointer to a memory block already allocated with
+ * av_malloc(z)() or av_realloc() or NULL.
+ * @return Pointer to a newly reallocated block or NULL if the block
+ * cannot be reallocated or the function is used to free the memory block.
+ * @see av_fast_realloc()
+ */
+void *av_realloc(void *ptr, unsigned int size) av_alloc_size(2);
+
+/**
+ * Free a memory block which has been allocated with av_malloc(z)() or
+ * av_realloc().
+ * @param ptr Pointer to the memory block which should be freed.
+ * @note ptr = NULL is explicitly allowed.
+ * @note It is recommended that you use av_freep() instead.
+ * @see av_freep()
+ */
+PUBLIK void av_free(void *ptr);
+
+/**
+ * Allocate a block of size bytes with alignment suitable for all
+ * memory accesses (including vectors if available on the CPU) and
+ * zero all the bytes of the block.
+ * @param size Size in bytes for the memory block to be allocated.
+ * @return Pointer to the allocated block, NULL if it cannot be allocated.
+ * @see av_malloc()
+ */
+void *av_mallocz(unsigned int size) av_malloc_attrib av_alloc_size(1);
+
+/**
+ * Duplicate the string s.
+ * @param s string to be duplicated
+ * @return Pointer to a newly allocated string containing a
+ * copy of s or NULL if the string cannot be allocated.
+ */
+char *av_strdup(const char *s) av_malloc_attrib;
+
+/**
+ * Free a memory block which has been allocated with av_malloc(z)() or
+ * av_realloc() and set the pointer pointing to it to NULL.
+ * @param ptr Pointer to the pointer to the memory block which should
+ * be freed.
+ * @see av_free()
+ */
+void av_freep(void *ptr);
+
+#endif /* AVUTIL_MEM_H */
+
diff --git a/plugins/supereq/ffmpeg_fft/libavutil/rational.c b/plugins/supereq/ffmpeg_fft/libavutil/rational.c
new file mode 100644
index 00000000..3e8b885d
--- /dev/null
+++ b/plugins/supereq/ffmpeg_fft/libavutil/rational.c
@@ -0,0 +1,131 @@
+/*
+ * rational numbers
+ * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * rational numbers
+ * @author Michael Niedermayer <michaelni@gmx.at>
+ */
+
+#include <assert.h>
+//#include <math.h>
+#include <limits.h>
+
+#include "common.h"
+#include "mathematics.h"
+#include "rational.h"
+
+int av_reduce(int *dst_num, int *dst_den, int64_t num, int64_t den, int64_t max){
+ AVRational a0={0,1}, a1={1,0};
+ int sign= (num<0) ^ (den<0);
+ int64_t gcd= av_gcd(FFABS(num), FFABS(den));
+
+ if(gcd){
+ num = FFABS(num)/gcd;
+ den = FFABS(den)/gcd;
+ }
+ if(num<=max && den<=max){
+ a1= (AVRational){num, den};
+ den=0;
+ }
+
+ while(den){
+ uint64_t x = num / den;
+ int64_t next_den= num - den*x;
+ int64_t a2n= x*a1.num + a0.num;
+ int64_t a2d= x*a1.den + a0.den;
+
+ if(a2n > max || a2d > max){
+ if(a1.num) x= (max - a0.num) / a1.num;
+ if(a1.den) x= FFMIN(x, (max - a0.den) / a1.den);
+
+ if (den*(2*x*a1.den + a0.den) > num*a1.den)
+ a1 = (AVRational){x*a1.num + a0.num, x*a1.den + a0.den};
+ break;
+ }
+
+ a0= a1;
+ a1= (AVRational){a2n, a2d};
+ num= den;
+ den= next_den;
+ }
+ assert(av_gcd(a1.num, a1.den) <= 1U);
+
+ *dst_num = sign ? -a1.num : a1.num;
+ *dst_den = a1.den;
+
+ return den==0;
+}
+
+AVRational av_mul_q(AVRational b, AVRational c){
+ av_reduce(&b.num, &b.den, b.num * (int64_t)c.num, b.den * (int64_t)c.den, INT_MAX);
+ return b;
+}
+
+AVRational av_div_q(AVRational b, AVRational c){
+ return av_mul_q(b, (AVRational){c.den, c.num});
+}
+
+AVRational av_add_q(AVRational b, AVRational c){
+ av_reduce(&b.num, &b.den, b.num * (int64_t)c.den + c.num * (int64_t)b.den, b.den * (int64_t)c.den, INT_MAX);
+ return b;
+}
+
+AVRational av_sub_q(AVRational b, AVRational c){
+ return av_add_q(b, (AVRational){-c.num, c.den});
+}
+
+AVRational av_d2q(double d, int max){
+ AVRational a;
+#define LOG2 0.69314718055994530941723212145817656807550013436025
+ int exponent= FFMAX( (int)(log(fabs(d) + 1e-20)/LOG2), 0);
+ int64_t den= 1LL << (61 - exponent);
+ if (isnan(d))
+ return (AVRational){0,0};
+ av_reduce(&a.num, &a.den, (int64_t)(d * den + 0.5), den, max);
+
+ return a;
+}
+
+int av_nearer_q(AVRational q, AVRational q1, AVRational q2)
+{
+ /* n/d is q, a/b is the median between q1 and q2 */
+ int64_t a = q1.num * (int64_t)q2.den + q2.num * (int64_t)q1.den;
+ int64_t b = 2 * (int64_t)q1.den * q2.den;
+
+ /* rnd_up(a*d/b) > n => a*d/b > n */
+ int64_t x_up = av_rescale_rnd(a, q.den, b, AV_ROUND_UP);
+
+ /* rnd_down(a*d/b) < n => a*d/b < n */
+ int64_t x_down = av_rescale_rnd(a, q.den, b, AV_ROUND_DOWN);
+
+ return ((x_up > q.num) - (x_down < q.num)) * av_cmp_q(q2, q1);
+}
+
+int av_find_nearest_q_idx(AVRational q, const AVRational* q_list)
+{
+ int i, nearest_q_idx = 0;
+ for(i=0; q_list[i].den; i++)
+ if (av_nearer_q(q, q_list[i], q_list[nearest_q_idx]) > 0)
+ nearest_q_idx = i;
+
+ return nearest_q_idx;
+}
diff --git a/plugins/supereq/ffmpeg_fft/libavutil/rational.h b/plugins/supereq/ffmpeg_fft/libavutil/rational.h
new file mode 100644
index 00000000..cd0a945a
--- /dev/null
+++ b/plugins/supereq/ffmpeg_fft/libavutil/rational.h
@@ -0,0 +1,130 @@
+/*
+ * rational numbers
+ * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * rational numbers
+ * @author Michael Niedermayer <michaelni@gmx.at>
+ */
+
+#ifndef AVUTIL_RATIONAL_H
+#define AVUTIL_RATIONAL_H
+
+#include <stdint.h>
+#include "attributes.h"
+
+/**
+ * rational number numerator/denominator
+ */
+typedef struct AVRational{
+ int num; ///< numerator
+ int den; ///< denominator
+} AVRational;
+
+/**
+ * Compare two rationals.
+ * @param a first rational
+ * @param b second rational
+ * @return 0 if a==b, 1 if a>b and -1 if a<b
+ */
+static inline int av_cmp_q(AVRational a, AVRational b){
+ const int64_t tmp= a.num * (int64_t)b.den - b.num * (int64_t)a.den;
+
+ if(tmp) return (tmp>>63)|1;
+ else return 0;
+}
+
+/**
+ * Convert rational to double.
+ * @param a rational to convert
+ * @return (double) a
+ */
+static inline double av_q2d(AVRational a){
+ return a.num / (double) a.den;
+}
+
+/**
+ * Reduce a fraction.
+ * This is useful for framerate calculations.
+ * @param dst_num destination numerator
+ * @param dst_den destination denominator
+ * @param num source numerator
+ * @param den source denominator
+ * @param max the maximum allowed for dst_num & dst_den
+ * @return 1 if exact, 0 otherwise
+ */
+int av_reduce(int *dst_num, int *dst_den, int64_t num, int64_t den, int64_t max);
+
+/**
+ * Multiply two rationals.
+ * @param b first rational
+ * @param c second rational
+ * @return b*c
+ */
+AVRational av_mul_q(AVRational b, AVRational c) av_const;
+
+/**
+ * Divide one rational by another.
+ * @param b first rational
+ * @param c second rational
+ * @return b/c
+ */
+AVRational av_div_q(AVRational b, AVRational c) av_const;
+
+/**
+ * Add two rationals.
+ * @param b first rational
+ * @param c second rational
+ * @return b+c
+ */
+AVRational av_add_q(AVRational b, AVRational c) av_const;
+
+/**
+ * Subtract one rational from another.
+ * @param b first rational
+ * @param c second rational
+ * @return b-c
+ */
+AVRational av_sub_q(AVRational b, AVRational c) av_const;
+
+/**
+ * Convert a double precision floating point number to a rational.
+ * @param d double to convert
+ * @param max the maximum allowed numerator and denominator
+ * @return (AVRational) d
+ */
+AVRational av_d2q(double d, int max) av_const;
+
+/**
+ * @return 1 if q1 is nearer to q than q2, -1 if q2 is nearer
+ * than q1, 0 if they have the same distance.
+ */
+int av_nearer_q(AVRational q, AVRational q1, AVRational q2);
+
+/**
+ * Find the nearest value in q_list to q.
+ * @param q_list an array of rationals terminated by {0, 0}
+ * @return the index of the nearest value found in the array
+ */
+int av_find_nearest_q_idx(AVRational q, const AVRational* q_list);
+
+#endif /* AVUTIL_RATIONAL_H */
+
diff --git a/plugins/supereq/ffmpeg_fft/libffmpeg_fft.ver b/plugins/supereq/ffmpeg_fft/libffmpeg_fft.ver
new file mode 100644
index 00000000..07b44318
--- /dev/null
+++ b/plugins/supereq/ffmpeg_fft/libffmpeg_fft.ver
@@ -0,0 +1,4 @@
+LIBFFMPEG_FFT_52 {
+ global: *;
+};
+
diff --git a/plugins/supereq/ffmpeg_fft/publik.h b/plugins/supereq/ffmpeg_fft/publik.h
new file mode 100644
index 00000000..bb044756
--- /dev/null
+++ b/plugins/supereq/ffmpeg_fft/publik.h
@@ -0,0 +1,6 @@
+#ifndef PUBLIK_H_
+#define PUBLIK_H_
+
+#define PUBLIK __attribute__ ((visibility ("default")))
+
+#endif /* PUBLIK_H_ */
diff --git a/plugins/supereq/nsfft-1.00/README b/plugins/supereq/nsfft-1.00/README
new file mode 100644
index 00000000..1ca873b1
--- /dev/null
+++ b/plugins/supereq/nsfft-1.00/README
@@ -0,0 +1,15 @@
+
+NSFFT (Nonrestrictive SIMD FFT) is yet another FFT library for
+performing 1-dimensional fast Fourier transforms. NSDFT is a simple,
+small and portable library, and it is efficient since it can utilize
+SIMD instruction sets in modern processors. It performs multiple
+transforms simultaneously, and thus it is especially suitable for
+digital signal processing. It does not need so much computation to
+make a good execution plan. This library is in public domain, so that
+you can incorporate this library into your product without any
+obligation.
+
+Visit http://shibatch.sourceforge.net/ to get the latest version of
+this library.
+
+Contact : Naoki Shibata shibatch@users.sourceforge.net
diff --git a/plugins/supereq/nsfft-1.00/dft/DFT.c b/plugins/supereq/nsfft-1.00/dft/DFT.c
new file mode 100644
index 00000000..d59e6ab8
--- /dev/null
+++ b/plugins/supereq/nsfft-1.00/dft/DFT.c
@@ -0,0 +1,327 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <stdint.h>
+#include <sys/time.h>
+
+#include "SIMDBase.h"
+#include "DFT.h"
+#include "DFTUndiff.h"
+
+int32_t getModeParamInt_purec_float(int32_t paramId);
+int32_t getModeParamInt_purec_double(int32_t paramId);
+int32_t getModeParamInt_purec_longdouble(int32_t paramId);
+int32_t getModeParamInt_sse_float(int32_t paramId);
+int32_t getModeParamInt_sse2_double(int32_t paramId);
+int32_t getModeParamInt_neon_float(int32_t paramId);
+int32_t getModeParamInt_avx_float(int32_t paramId);
+int32_t getModeParamInt_avx_double(int32_t paramId);
+int32_t getModeParamInt_altivec_float(int32_t paramId);
+
+char * getModeParamString_purec_float(int32_t paramId);
+char * getModeParamString_purec_double(int32_t paramId);
+char * getModeParamString_purec_longdouble(int32_t paramId);
+char * getModeParamString_sse_float(int32_t paramId);
+char * getModeParamString_sse2_double(int32_t paramId);
+char * getModeParamString_neon_float(int32_t paramId);
+char * getModeParamString_avx_float(int32_t paramId);
+char * getModeParamString_avx_double(int32_t paramId);
+char * getModeParamString_altivec_float(int32_t paramId);
+
+void *makePlan_purec_float(uint64_t n, uint64_t flags);
+void *makePlan_purec_double(uint64_t n, uint64_t flags);
+void *makePlan_purec_longdouble(uint64_t n, uint64_t flags);
+void *makePlan_sse_float(uint64_t n, uint64_t flags);
+void *makePlan_sse2_double(uint64_t n, uint64_t flags);
+void *makePlan_neon_float(uint64_t n, uint64_t flags);
+void *makePlan_avx_float(uint64_t n, uint64_t flags);
+void *makePlan_avx_double(uint64_t n, uint64_t flags);
+void *makePlan_altivec_float(uint64_t n, uint64_t flags);
+
+void *makePlanSub_purec_float(uint64_t n, int32_t radix2thres, int32_t useCobra, uint64_t flags);
+void *makePlanSub_purec_double(uint64_t n, int32_t radix2thres, int32_t useCobra, uint64_t flags);
+void *makePlanSub_purec_longdouble(uint64_t n, int32_t radix2thres, int32_t useCobra, uint64_t flags);
+void *makePlanSub_sse_float(uint64_t n, int32_t radix2thres, int32_t useCobra, uint64_t flags);
+void *makePlanSub_sse2_double(uint64_t n, int32_t radix2thres, int32_t useCobra, uint64_t flags);
+void *makePlanSub_neon_float(uint64_t n, int32_t radix2thres, int32_t useCobra, uint64_t flags);
+void *makePlanSub_avx_float(uint64_t n, int32_t radix2thres, int32_t useCobra, uint64_t flags);
+void *makePlanSub_avx_double(uint64_t n, int32_t radix2thres, int32_t useCobra, uint64_t flags);
+void *makePlanSub_altivec_float(uint64_t n, int32_t radix2thres, int32_t useCobra, uint64_t flags);
+
+void destroyPlan_purec_float(void *p);
+void destroyPlan_purec_double(void *p);
+void destroyPlan_purec_longdouble(void *p);
+void destroyPlan_sse_float(void *p);
+void destroyPlan_sse2_double(void *p);
+void destroyPlan_neon_float(void *p);
+void destroyPlan_avx_float(void *p);
+void destroyPlan_avx_double(void *p);
+void destroyPlan_altivec_float(void *p);
+
+void execute_purec_float(void *p, void *s, int32_t dir);
+void execute_purec_double(void *p, void *s, int32_t dir);
+void execute_purec_longdouble(void *p, void *s, int32_t dir);
+void execute_sse_float(void *p, void *s, int32_t dir);
+void execute_sse2_double(void *p, void *s, int32_t dir);
+void execute_neon_float(void *p, void *s, int32_t dir);
+void execute_avx_float(void *p, void *s, int32_t dir);
+void execute_avx_double(void *p, void *s, int32_t dir);
+void execute_altivec_float(void *p, void *s, int32_t dir);
+
+void *DFT_init(int32_t mode, uint64_t n, uint64_t flags) {
+ switch(mode) {
+#if defined(ENABLE_PUREC_FLOAT)
+ case 1: return makePlan_purec_float(n, flags); break;
+#endif
+#if defined(ENABLE_PUREC_DOUBLE)
+ case 2: return makePlan_purec_double(n, flags); break;
+#endif
+#if defined(ENABLE_PUREC_LONGDOUBLE)
+ case 3: return makePlan_purec_longdouble(n, flags); break;
+#endif
+#if defined(ENABLE_SSE_FLOAT)
+ case 4: return makePlan_sse_float(n, flags); break;
+#endif
+#if defined(ENABLE_SSE2_DOUBLE)
+ case 5: return makePlan_sse2_double(n, flags); break;
+#endif
+#if defined(ENABLE_NEON_FLOAT)
+ case 6: return makePlan_neon_float(n, flags); break;
+#endif
+#if defined(ENABLE_AVX_FLOAT)
+ case 7: return makePlan_avx_float(n, flags); break;
+#endif
+#if defined(ENABLE_AVX_DOUBLE)
+ case 8: return makePlan_avx_double(n, flags); break;
+#endif
+#if defined(ENABLE_ALTIVEC_FLOAT)
+ case 9: return makePlan_altivec_float(n, flags); break;
+#endif
+ default: break;
+ }
+
+ return NULL;
+}
+
+void DFT_dispose(void *p, int32_t mode) {
+ switch(mode) {
+#if defined(ENABLE_PUREC_FLOAT)
+ case 1: destroyPlan_purec_float(p); break;
+#endif
+#if defined(ENABLE_PUREC_DOUBLE)
+ case 2: destroyPlan_purec_double(p); break;
+#endif
+#if defined(ENABLE_PUREC_LONGDOUBLE)
+ case 3: destroyPlan_purec_longdouble(p); break;
+#endif
+#if defined(ENABLE_SSE_FLOAT)
+ case 4: destroyPlan_sse_float(p); break;
+#endif
+#if defined(ENABLE_SSE2_DOUBLE)
+ case 5: destroyPlan_sse2_double(p); break;
+#endif
+#if defined(ENABLE_NEON_FLOAT)
+ case 6: destroyPlan_neon_float(p); break;
+#endif
+#if defined(ENABLE_AVX_FLOAT)
+ case 7: destroyPlan_avx_float(p); break;
+#endif
+#if defined(ENABLE_AVX_DOUBLE)
+ case 8: destroyPlan_avx_double(p); break;
+#endif
+#if defined(ENABLE_ALTIVEC_FLOAT)
+ case 9: destroyPlan_altivec_float(p); break;
+#endif
+ default: break;
+ }
+}
+
+void DFT_execute(void *p, int32_t mode, void *s, int32_t dir) {
+ switch(mode) {
+#if defined(ENABLE_PUREC_FLOAT)
+ case 1: return execute_purec_float(p, s, dir); break;
+#endif
+#if defined(ENABLE_PUREC_DOUBLE)
+ case 2: return execute_purec_double(p, s, dir); break;
+#endif
+#if defined(ENABLE_PUREC_LONGDOUBLE)
+ case 3: return execute_purec_longdouble(p, s, dir); break;
+#endif
+#if defined(ENABLE_SSE_FLOAT)
+ case 4: return execute_sse_float(p, s, dir); break;
+#endif
+#if defined(ENABLE_SSE2_DOUBLE)
+ case 5: return execute_sse2_double(p, s, dir); break;
+#endif
+#if defined(ENABLE_NEON_FLOAT)
+ case 6: return execute_neon_float(p, s, dir); break;
+#endif
+#if defined(ENABLE_AVX_FLOAT)
+ case 7: return execute_avx_float(p, s, dir); break;
+#endif
+#if defined(ENABLE_AVX_DOUBLE)
+ case 8: return execute_avx_double(p, s, dir); break;
+#endif
+#if defined(ENABLE_ALTIVEC_FLOAT)
+ case 9: return execute_altivec_float(p, s, dir); break;
+#endif
+ default: break;
+ }
+}
+
+#define FILE_FORMAT_VERSION 0
+
+int32_t DFT_fwrite(void *p2, FILE *fp) {
+ DFTUndiff *p = (DFTUndiff *)p2;
+ if (p->magic != MAGIC_DFT) abort();
+
+ if (fprintf(fp, "nsfft file format : %d\n", FILE_FORMAT_VERSION) <= 0) return 0;
+ if (fprintf(fp, "arch : %s\n", SIMDBase_getProcessorNameString()) <= 0) return 0;
+ if (fprintf(fp, "computation mode : %d\n", p->mode) <= 0) return 0;
+ if (fprintf(fp, "length : %d\n", ((p->flags & DFT_FLAG_REAL) != 0 || (p->flags & DFT_FLAG_ALT_REAL) != 0)? p->length * 2 : p->length) <= 0) return 0;
+ if (fprintf(fp, "radix2 threshold : %d\n", p->radix2thres) <= 0) return 0;
+ if (fprintf(fp, "transpose : %d\n", p->flagTrans) <= 0) return 0;
+ if (fprintf(fp, "bit reversal : %d\n", p->useCobra) <= 0) return 0;
+ if (fprintf(fp, "flags : %llx\n", (unsigned long long int)p->flags) <= 0) return 0;
+ if (fprintf(fp, "%s\n", "end :") <= 0) return 0;
+
+ return 1;
+}
+
+static char *startsWith(char *str1, char *str2) {
+ if (strncmp(str1, str2, strlen(str2)) == 0) {
+ return str1 + strlen(str2);
+ }
+
+ return NULL;
+}
+
+DFT *DFT_fread(FILE *fp, int32_t *errcode) {
+ int length = -1, radix2thres = -1, flagTrans = -1, useCobra = -1;
+ int mode = -1, formatver = -1;
+ unsigned long long int flags = (1ULL << 63);
+
+ if (errcode != NULL) *errcode = DFT_ERROR_NOERROR;
+
+ for(;;) {
+ char buf[256], *q;
+ if (fgets(buf, 255, fp) == NULL) { if (errcode != NULL) *errcode = DFT_ERROR_UNEXPECTED_EOF; return NULL; }
+
+ if ((q = startsWith(buf, "nsfft file format :")) != NULL) {
+ if (1 != sscanf(q, "%d", &formatver)) { if (errcode != NULL) *errcode = DFT_ERROR_FILE_IO; return NULL; }
+ } else if ((q = startsWith(buf, "computation mode :")) != NULL) {
+ if (1 != sscanf(q, "%d", &mode)) { if (errcode != NULL) *errcode = DFT_ERROR_FILE_IO; return NULL; }
+ } else if ((q = startsWith(buf, "length :")) != NULL) {
+ if (1 != sscanf(q, "%d", &length)) { if (errcode != NULL) *errcode = DFT_ERROR_FILE_IO; return NULL; }
+ } else if ((q = startsWith(buf, "radix2 threshold :")) != NULL) {
+ if (1 != sscanf(q, "%d", &radix2thres)) { if (errcode != NULL) *errcode = DFT_ERROR_FILE_IO; return NULL; }
+ } else if ((q = startsWith(buf, "transpose :")) != NULL) {
+ if (1 != sscanf(q, "%d", &flagTrans)) { if (errcode != NULL) *errcode = DFT_ERROR_FILE_IO; return NULL; }
+ } else if ((q = startsWith(buf, "bit reversal :")) != NULL) {
+ if (1 != sscanf(q, "%d", &useCobra)) { if (errcode != NULL) *errcode = DFT_ERROR_FILE_IO; return NULL; }
+ } else if ((q = startsWith(buf, "flags :")) != NULL) {
+ if (1 != sscanf(q, "%llx", &flags)) { if (errcode != NULL) *errcode = DFT_ERROR_FILE_IO; return NULL; }
+ } else if ((q = startsWith(buf, "end :")) != NULL) {
+ break;
+ }
+ }
+
+ if (formatver > FILE_FORMAT_VERSION) {
+ if (errcode != NULL) *errcode = DFT_ERROR_FILE_VERSION;
+ return NULL;
+ }
+
+ switch(SIMDBase_detect(mode)) {
+ case 1:
+ break;
+ case 0:
+ if (errcode != NULL) *errcode = DFT_ERROR_MODE_NOT_AVAILABLE;
+ return NULL;
+ case -1:
+ if (errcode != NULL) *errcode = DFT_ERROR_MODE_NOT_COMPILED_IN;
+ return NULL;
+ }
+
+ switch(mode) {
+#if defined(ENABLE_PUREC_FLOAT)
+ case 1: return makePlanSub_purec_float(length, radix2thres, useCobra, flags);
+#endif
+#if defined(ENABLE_PUREC_DOUBLE)
+ case 2: return makePlanSub_purec_double(length, radix2thres, useCobra, flags);
+#endif
+#if defined(ENABLE_PUREC_LONGDOUBLE)
+ case 3: return makePlanSub_purec_longdouble(length, radix2thres, useCobra, flags);
+#endif
+#if defined(ENABLE_SSE_FLOAT)
+ case 4: return makePlanSub_sse_float(length, radix2thres, useCobra, flags);
+#endif
+#if defined(ENABLE_SSE2_DOUBLE)
+ case 5: return makePlanSub_sse2_double(length, radix2thres, useCobra, flags);
+#endif
+#if defined(ENABLE_NEON_FLOAT)
+ case 6: return makePlanSub_neon_float(length, radix2thres, useCobra, flags);
+#endif
+#if defined(ENABLE_AVX_FLOAT)
+ case 7: return makePlanSub_avx_float(length, radix2thres, useCobra, flags);
+#endif
+#if defined(ENABLE_AVX_DOUBLE)
+ case 8: return makePlanSub_avx_double(length, radix2thres, useCobra, flags);
+#endif
+#if defined(ENABLE_ALTIVEC_FLOAT)
+ case 9: return makePlanSub_altivec_float(length, radix2thres, useCobra, flags);
+#endif
+ }
+
+ if (errcode != NULL) *errcode = DFT_ERROR_UNKNOWN_MODE;
+
+ return NULL;
+}
+
+int32_t DFT_getPlanParamInt(int32_t paramId, void *p2) {
+ DFTUndiff *p = (DFTUndiff *)p2;
+ if (p->magic != MAGIC_DFT) abort();
+
+ switch(paramId) {
+ case DFT_PARAMID_MODE: return p->mode;
+ case DFT_PARAMID_FFT_LENGTH:
+ if ((p->flags & DFT_FLAG_REAL) != 0) return p->length * 2;
+ if ((p->flags & DFT_FLAG_ALT_REAL) != 0) return p->length * 2;
+ return p->length;
+ case DFT_PARAMID_IS_REAL_TRANSFORM: return (p->flags & DFT_FLAG_REAL) ? 1 : 0;
+ case DFT_PARAMID_IS_ALT_REAL_TRANSFORM: return (p->flags & DFT_FLAG_ALT_REAL) ? 1 : 0;
+ case DFT_PARAMID_NO_BIT_REVERSAL: return (p->flags & DFT_FLAG_NO_BITREVERSAL) ? 1 : 0;
+ case DFT_PARAMID_TEST_RUN: return p->flags & 3;
+ }
+
+ return -1;
+}
+
+#if 0
+char *DFT_getPlanParamString(int32_t paramId, void *p2) {
+ dft_t *p = (dft_t *)p2;
+ if (p->magic != MAGIC_NSDFT) abort();
+
+ return NULL;
+}
+#endif
+
+uint32_t DFT_ilog2(uint32_t q) {
+ static const uint32_t tab[] = {0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4};
+ uint32_t r = 0,qq;
+
+ if (q & 0xffff0000) r = 16;
+
+ q >>= r;
+ qq = q | (q >> 1);
+ qq |= (qq >> 2);
+ qq = ((qq & 0x10) >> 4) | ((qq & 0x100) >> 7) | ((qq & 0x1000) >> 10);
+
+ return r + tab[qq] * 4 + tab[q >> (tab[qq] * 4)] - 1;
+}
+
+double DFT_timeofday(void) {
+ struct timeval tp;
+ gettimeofday(&tp, NULL);
+ return (double)tp.tv_sec+(1e-6)*tp.tv_usec;
+}
diff --git a/plugins/supereq/nsfft-1.00/dft/DFT.h b/plugins/supereq/nsfft-1.00/dft/DFT.h
new file mode 100644
index 00000000..facb701a
--- /dev/null
+++ b/plugins/supereq/nsfft-1.00/dft/DFT.h
@@ -0,0 +1,56 @@
+#ifndef __DFT_H__
+#define __DFT_H__
+
+#include <stdio.h>
+#include <stdint.h>
+
+typedef void DFT;
+
+int32_t DFT_getParamInt(int32_t paramId);
+char *DFT_getParamString(int32_t paramId);
+
+int32_t DFT_getModeParamInt(int32_t paramId, int32_t mode);
+char *DFT_getModeParamString(int32_t paramId, int32_t mode);
+
+DFT *DFT_init(int32_t mode, uint64_t n, uint64_t flags);
+void DFT_dispose(DFT *p, int32_t mode);
+
+int32_t DFT_fwrite(DFT *p, FILE *fp);
+DFT *DFT_fread(FILE *fp, int32_t *errcode);
+
+int32_t DFT_getPlanParamInt(int32_t paramId, void *p);
+
+void DFT_execute(DFT *p, int32_t mode, void *s, int32_t dir);
+
+uint32_t DFT_ilog2(uint32_t q);
+double DFT_timeofday(void);
+
+#define DFT_FLAG_NO_TEST_RUN ( 0ULL << 0)
+#define DFT_FLAG_LIGHT_TEST_RUN ( 1ULL << 0)
+#define DFT_FLAG_HEAVY_TEST_RUN ( 2ULL << 0)
+#define DFT_FLAG_EXHAUSTIVE_TEST_RUN ( 3ULL << 0)
+
+#define DFT_FLAG_REAL (1ULL << 2)
+#define DFT_FLAG_ALT_REAL (1ULL << 3)
+#define DFT_FLAG_VERBOSE (1ULL << 4)
+#define DFT_FLAG_NO_BITREVERSAL (1ULL << 5)
+#define DFT_FLAG_FORCE_RECURSIVE (1ULL << 6)
+#define DFT_FLAG_FORCE_COBRA (1ULL << 7)
+
+#define DFT_PARAMID_TYPE ( 1 | ( 3 << 24 ))
+#define DFT_PARAMID_MODE ( 2 | ( 3 << 24 ))
+#define DFT_PARAMID_FFT_LENGTH ( 3 | ( 3 << 24 ))
+#define DFT_PARAMID_IS_REAL_TRANSFORM ( 4 | ( 3 << 24 ))
+#define DFT_PARAMID_IS_ALT_REAL_TRANSFORM ( 5 | ( 3 << 24 ))
+#define DFT_PARAMID_NO_BIT_REVERSAL ( 6 | ( 3 << 24 ))
+#define DFT_PARAMID_TEST_RUN ( 7 | ( 3 << 24 ))
+
+#define DFT_ERROR_NOERROR 0
+#define DFT_ERROR_FILE_VERSION 1
+#define DFT_ERROR_FILE_IO 2
+#define DFT_ERROR_UNEXPECTED_EOF 3
+#define DFT_ERROR_MODE_NOT_COMPILED_IN 4
+#define DFT_ERROR_MODE_NOT_AVAILABLE 5
+#define DFT_ERROR_UNKNOWN_MODE 6
+
+#endif
diff --git a/plugins/supereq/nsfft-1.00/dft/DFTUndiff.c b/plugins/supereq/nsfft-1.00/dft/DFTUndiff.c
new file mode 100644
index 00000000..4985da33
--- /dev/null
+++ b/plugins/supereq/nsfft-1.00/dft/DFTUndiff.c
@@ -0,0 +1,1807 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <stdint.h>
+
+#include "SIMDBase.h"
+#include "SIMDBaseUndiff.h"
+#include "DFT.h"
+#include "DFTUndiff.h"
+
+//
+
+#define SIN(x) sin(x)
+#define COS(x) cos(x)
+
+#define SQRT2_2 .7071067811865475244008443621048490392848359376884740365883398689953L
+
+#ifndef M_PIl
+#define M_PIl 3.141592653589793238462643383279502884197169399375105820974944592307L
+#endif
+
+//
+
+static inline void srBut2(DFTUndiff *p) {
+ SIMDBase_VECT *s = p->s;
+ int32_t o = p->offset1;
+ SIMDBase_VECT t0, t1;
+
+ t0 = SIMDBase_ADDm(&s[o ], &s[o+2]); t1 = SIMDBase_SUBm(&s[o ], &s[o+2]);
+ SIMDBase_STOR(&s[o ], t0); SIMDBase_STOR(&s[o+2], t1);
+ t0 = SIMDBase_ADDm(&s[o+1], &s[o+3]); t1 = SIMDBase_SUBm(&s[o+1], &s[o+3]);
+ SIMDBase_STOR(&s[o+1], t0); SIMDBase_STOR(&s[o+3], t1);
+}
+
+static inline void srButForward4(DFTUndiff *p) {
+ SIMDBase_VECT *s = p->s;
+ int32_t o = p->offset1;
+ SIMDBase_VECT t0r, t0i, t1r, t1i, t2r, t2i, t3r, t3i;
+
+ t0r = SIMDBase_ADDm(&s[o+0], &s[o+4]); t2r = SIMDBase_SUBm(&s[o+0], &s[o+4]);
+ t0i = SIMDBase_ADDm(&s[o+1], &s[o+5]); t2i = SIMDBase_SUBm(&s[o+1], &s[o+5]);
+ t1r = SIMDBase_ADDm(&s[o+2], &s[o+6]); t3i = SIMDBase_SUBm(&s[o+2], &s[o+6]);
+ t1i = SIMDBase_ADDm(&s[o+7], &s[o+3]); t3r = SIMDBase_SUBm(&s[o+7], &s[o+3]);
+
+ SIMDBase_STOR(&s[o+0], SIMDBase_ADDi(t0r, t1r)); SIMDBase_STOR(&s[o+1], SIMDBase_ADDi(t0i, t1i));
+ SIMDBase_STOR(&s[o+2], SIMDBase_SUBi(t0r, t1r)); SIMDBase_STOR(&s[o+3], SIMDBase_SUBi(t0i, t1i));
+ SIMDBase_STOR(&s[o+4], SIMDBase_SUBi(t2r, t3r)); SIMDBase_STOR(&s[o+5], SIMDBase_SUBi(t2i, t3i));
+ SIMDBase_STOR(&s[o+6], SIMDBase_ADDi(t2r, t3r)); SIMDBase_STOR(&s[o+7], SIMDBase_ADDi(t2i, t3i));
+}
+
+static inline void srButBackward4(DFTUndiff *p) {
+ SIMDBase_VECT *s = p->s;
+ int32_t o = p->offset1;
+
+ SIMDBase_VECT t0r, t0i, t1r, t1i;
+ SIMDBase_VECT s0 = SIMDBase_LOAD(&s[o+0]), s1 = SIMDBase_LOAD(&s[o+1]), s2 = SIMDBase_LOAD(&s[o+2]), s3 = SIMDBase_LOAD(&s[o+3]);
+
+ t0r = SIMDBase_ADDi(s0, s2); t0i = SIMDBase_SUBi(s0, s2); s0 = t0r; s2 = t0i;
+ t0r = SIMDBase_ADDi(s1, s3); t0i = SIMDBase_SUBi(s1, s3); s1 = t0r; s3 = t0i;
+ t0r = SIMDBase_ADDm(&s[o+4], &s[o+6]); t1i = SIMDBase_SUBm(&s[o+4], &s[o+6]);
+ t0i = SIMDBase_ADDm(&s[o+7], &s[o+5]); t1r = SIMDBase_SUBm(&s[o+7], &s[o+5]);
+
+ SIMDBase_STOR(&s[o+4], SIMDBase_SUBi(s0, t0r)); SIMDBase_STOR(&s[o+5], SIMDBase_SUBi(s1, t0i));
+ SIMDBase_STOR(&s[o+6], SIMDBase_SUBi(s2, t1r)); SIMDBase_STOR(&s[o+7], SIMDBase_SUBi(s3, t1i));
+ SIMDBase_STOR(&s[o+0], SIMDBase_ADDi(s0, t0r)); SIMDBase_STOR(&s[o+1], SIMDBase_ADDi(s1, t0i));
+ SIMDBase_STOR(&s[o+2], SIMDBase_ADDi(s2, t1r)); SIMDBase_STOR(&s[o+3], SIMDBase_ADDi(s3, t1i));
+}
+
+static inline void srButForward8(DFTUndiff *p) {
+ SIMDBase_VECT *s = p->s;
+ int32_t o = p->offset1;
+ SIMDBase_VECT t0r, t0i, t1r, t1i, t2r, t2i, t3r, t3i;
+
+ SIMDBase_VECT s0 = SIMDBase_LOAD(&s[o+ 0]), s1 = SIMDBase_LOAD(&s[o+ 1]), s2 = SIMDBase_LOAD(&s[o+ 2]), s3 = SIMDBase_LOAD(&s[o+ 3]);
+ SIMDBase_VECT s4 = SIMDBase_LOAD(&s[o+ 4]), s5 = SIMDBase_LOAD(&s[o+ 5]), s6 = SIMDBase_LOAD(&s[o+ 6]), s7 = SIMDBase_LOAD(&s[o+ 7]);
+ SIMDBase_VECT s8 = SIMDBase_LOAD(&s[o+ 8]), s9 = SIMDBase_LOAD(&s[o+ 9]), sa = SIMDBase_LOAD(&s[o+10]) ,sb = SIMDBase_LOAD(&s[o+11]);
+ SIMDBase_VECT sc = SIMDBase_LOAD(&s[o+12]), sd = SIMDBase_LOAD(&s[o+13]), se = SIMDBase_LOAD(&s[o+14]), sf = SIMDBase_LOAD(&s[o+15]);
+
+ t2r = SIMDBase_SUBi(s0, s8); t2i = SIMDBase_SUBi(s1, s9);
+ t3r = SIMDBase_SUBi(sd, s5); t3i = SIMDBase_SUBi(s4, sc);
+
+ s0 = SIMDBase_ADDi(s0, s8); s1 = SIMDBase_ADDi(s1, s9);
+ s4 = SIMDBase_ADDi(s4, sc); s5 = SIMDBase_ADDi(s5, sd);
+
+ s8 = SIMDBase_SUBi(t2r, t3r); s9 = SIMDBase_SUBi(t2i, t3i);
+ sc = SIMDBase_ADDi(t2r, t3r); sd = SIMDBase_ADDi(t2i, t3i);
+
+ t2r = SIMDBase_SUBi(s2, sa); t2i = SIMDBase_SUBi(s3, sb);
+ t3r = SIMDBase_SUBi(sf, s7); t3i = SIMDBase_SUBi(s6, se);
+
+ s2 = SIMDBase_ADDi(s2, sa); s3 = SIMDBase_ADDi(s3, sb);
+ s6 = SIMDBase_ADDi(s6, se); s7 = SIMDBase_ADDi(s7, sf);
+
+ t0r = SIMDBase_SUBi(t2r, t3r); t1r = SIMDBase_ADDi(t2r, t3r);
+ t0i = SIMDBase_SUBi(t2i, t3i); t1i = SIMDBase_ADDi(t2i, t3i);
+
+ sa = SIMDBase_MULi(SIMDBase_ADDi(t0r, t0i), SIMDBase_SET1( SQRT2_2));
+ sb = SIMDBase_MULi(SIMDBase_SUBi(t0i, t0r), SIMDBase_SET1( SQRT2_2));
+ se = SIMDBase_MULi(SIMDBase_SUBi(t1i, t1r), SIMDBase_SET1( SQRT2_2));
+ sf = SIMDBase_MULi(SIMDBase_ADDi(t1r, t1i), SIMDBase_SET1(-SQRT2_2));
+
+ SIMDBase_STOR(&s[o+ 8], SIMDBase_ADDi(s8, sa)); SIMDBase_STOR(&s[o+ 9], SIMDBase_ADDi(s9, sb));
+ SIMDBase_STOR(&s[o+10], SIMDBase_SUBi(s8, sa)); SIMDBase_STOR(&s[o+11], SIMDBase_SUBi(s9, sb));
+
+ SIMDBase_STOR(&s[o+12], SIMDBase_ADDi(sc, se)); SIMDBase_STOR(&s[o+13], SIMDBase_ADDi(sd, sf));
+ SIMDBase_STOR(&s[o+14], SIMDBase_SUBi(sc, se)); SIMDBase_STOR(&s[o+15], SIMDBase_SUBi(sd, sf));
+
+ t0r = SIMDBase_ADDi(s0, s4); t2r = SIMDBase_SUBi(s0, s4);
+ t0i = SIMDBase_ADDi(s1, s5); t2i = SIMDBase_SUBi(s1, s5);
+
+ t1r = SIMDBase_ADDi(s2, s6); t3i = SIMDBase_SUBi(s2, s6);
+ t1i = SIMDBase_ADDi(s3, s7); t3r = SIMDBase_SUBi(s7, s3);
+
+ SIMDBase_STOR(&s[o+0], SIMDBase_ADDi(t0r, t1r)); SIMDBase_STOR(&s[o+1], SIMDBase_ADDi(t0i, t1i));
+ SIMDBase_STOR(&s[o+2], SIMDBase_SUBi(t0r, t1r)); SIMDBase_STOR(&s[o+3], SIMDBase_SUBi(t0i, t1i));
+ SIMDBase_STOR(&s[o+4], SIMDBase_SUBi(t2r, t3r)); SIMDBase_STOR(&s[o+5], SIMDBase_SUBi(t2i, t3i));
+ SIMDBase_STOR(&s[o+6], SIMDBase_ADDi(t2r, t3r)); SIMDBase_STOR(&s[o+7], SIMDBase_ADDi(t2i, t3i));
+}
+
+static void srButBackward8(DFTUndiff *p) {
+ SIMDBase_VECT *s = p->s;
+ int32_t o = p->offset1;
+ SIMDBase_VECT t0r, t0i, t1r, t1i;
+
+ SIMDBase_VECT s0 = SIMDBase_LOAD(&s[o+ 0]), s1 = SIMDBase_LOAD(&s[o+ 1]), s2 = SIMDBase_LOAD(&s[o+ 2]), s3 = SIMDBase_LOAD(&s[o+ 3]);
+ SIMDBase_VECT s4 = SIMDBase_LOAD(&s[o+ 4]), s5 = SIMDBase_LOAD(&s[o+ 5]), s6 = SIMDBase_LOAD(&s[o+ 6]), s7 = SIMDBase_LOAD(&s[o+ 7]);
+ SIMDBase_VECT s8 = SIMDBase_LOAD(&s[o+ 8]), s9 = SIMDBase_LOAD(&s[o+ 9]), sa = SIMDBase_LOAD(&s[o+10]) ,sb = SIMDBase_LOAD(&s[o+11]);
+ SIMDBase_VECT sc = SIMDBase_LOAD(&s[o+12]), sd = SIMDBase_LOAD(&s[o+13]), se = SIMDBase_LOAD(&s[o+14]), sf = SIMDBase_LOAD(&s[o+15]);
+
+ t0r = SIMDBase_ADDi(s8, sa); t0i = SIMDBase_SUBi(s8, sa); s8 = t0r; sa = t0i;
+ t0r = SIMDBase_ADDi(s9, sb); t0i = SIMDBase_SUBi(s9, sb); s9 = t0r; sb = t0i;
+ t0r = SIMDBase_ADDi(sc, se); t0i = SIMDBase_SUBi(sc, se); sc = t0r; se = t0i;
+ t0r = SIMDBase_ADDi(sd, sf); t0i = SIMDBase_SUBi(sd, sf); sd = t0r; sf = t0i;
+ t0r = SIMDBase_ADDi(s0, s2); t0i = SIMDBase_SUBi(s0, s2); s0 = t0r; s2 = t0i;
+ t0r = SIMDBase_ADDi(s1, s3); t0i = SIMDBase_SUBi(s1, s3); s1 = t0r; s3 = t0i;
+
+ t0r = SIMDBase_ADDi(s4, s6); t0i = SIMDBase_ADDi(s7, s5);
+ t1r = SIMDBase_SUBi(s7, s5); t1i = SIMDBase_SUBi(s4, s6);
+
+ s4 = SIMDBase_SUBi(s0, t0r); s5 = SIMDBase_SUBi(s1, t0i);
+ s6 = SIMDBase_SUBi(s2, t1r); s7 = SIMDBase_SUBi(s3, t1i);
+ s0 = SIMDBase_ADDi(s0, t0r); s1 = SIMDBase_ADDi(s1, t0i);
+ s2 = SIMDBase_ADDi(s2, t1r); s3 = SIMDBase_ADDi(s3, t1i);
+
+ t0r = SIMDBase_ADDi(s8, sc); t0i = SIMDBase_ADDi(s9, sd);
+ t1r = SIMDBase_SUBi(sd, s9); t1i = SIMDBase_SUBi(s8, sc);
+
+ s8 = SIMDBase_SUBi(s0, t0r); s9 = SIMDBase_SUBi(s1, t0i);
+ sc = SIMDBase_SUBi(s4, t1r); sd = SIMDBase_SUBi(s5, t1i);
+ s0 = SIMDBase_ADDi(s0, t0r); s1 = SIMDBase_ADDi(s1, t0i);
+ s4 = SIMDBase_ADDi(s4, t1r); s5 = SIMDBase_ADDi(s5, t1i);
+
+ t0r = SIMDBase_MULi(SIMDBase_SUBi(sa, sb), SIMDBase_SET1( SQRT2_2));
+ t0i = SIMDBase_MULi(SIMDBase_ADDi(sa, sb), SIMDBase_SET1( SQRT2_2));
+ t1r = SIMDBase_MULi(SIMDBase_ADDi(se, sf), SIMDBase_SET1(-SQRT2_2));
+ t1i = SIMDBase_MULi(SIMDBase_SUBi(se, sf), SIMDBase_SET1( SQRT2_2));
+
+ sa = t0r; sb = t0i; se = t1r; sf = t1i;
+
+ t0r = SIMDBase_ADDi(sa, se); t0i = SIMDBase_ADDi(sb, sf);
+ t1r = SIMDBase_SUBi(sf, sb); t1i = SIMDBase_SUBi(sa, se);
+
+ sa = SIMDBase_SUBi(s2, t0r); sb = SIMDBase_SUBi(s3, t0i);
+ se = SIMDBase_SUBi(s6, t1r); sf = SIMDBase_SUBi(s7, t1i);
+ s2 = SIMDBase_ADDi(s2, t0r); s3 = SIMDBase_ADDi(s3, t0i);
+ s6 = SIMDBase_ADDi(s6, t1r); s7 = SIMDBase_ADDi(s7, t1i);
+
+ SIMDBase_STOR(&s[o+ 0], s0); SIMDBase_STOR(&s[o+ 1], s1); SIMDBase_STOR(&s[o+ 2], s2); SIMDBase_STOR(&s[o+ 3], s3);
+ SIMDBase_STOR(&s[o+ 4], s4); SIMDBase_STOR(&s[o+ 5], s5); SIMDBase_STOR(&s[o+ 6], s6); SIMDBase_STOR(&s[o+ 7], s7);
+ SIMDBase_STOR(&s[o+ 8], s8); SIMDBase_STOR(&s[o+ 9], s9); SIMDBase_STOR(&s[o+10], sa); SIMDBase_STOR(&s[o+11], sb);
+ SIMDBase_STOR(&s[o+12], sc); SIMDBase_STOR(&s[o+13], sd); SIMDBase_STOR(&s[o+14], se); SIMDBase_STOR(&s[o+15], sf);
+}
+
+#if 0
+static inline void srButForwardSub(DFTUndiff *p) {
+ SIMDBase_VECT *s = p->s;
+ SIMDBase_REAL *tbl = p->ptTable[p->log2butlen];
+
+ int32_t i0 = p->offset1;
+ int32_t i1 = i0 + p->stride;
+ int32_t i2 = i1 + p->stride;
+ int32_t i3 = i2 + p->stride;
+ int32_t im = i1;
+
+ int32_t p0 = p->offset2 & (p->butlen*4-1);
+
+ while(i0 < im) {
+ SIMDBase_VECT t0r, t0i, t1r, t1i;
+ SIMDBase_VECT s00, s01, s10, s11, s20, s21, s30, s31;
+ SIMDBase_VECT a0, a1, a2, a3;
+
+ s00 = SIMDBase_LOAD(&s[i0+0]), s01 = SIMDBase_LOAD(&s[i0+1]);
+ s10 = SIMDBase_LOAD(&s[i1+0]), s11 = SIMDBase_LOAD(&s[i1+1]);
+ s20 = SIMDBase_LOAD(&s[i2+0]), s21 = SIMDBase_LOAD(&s[i2+1]);
+ s30 = SIMDBase_LOAD(&s[i3+0]), s31 = SIMDBase_LOAD(&s[i3+1]);
+
+ t0r = SIMDBase_SUBi(SIMDBase_SUBi(s00, s20), SIMDBase_SUBi(s31, s11));
+ t0i = SIMDBase_SUBi(SIMDBase_SUBi(s01, s21), SIMDBase_SUBi(s10, s30));
+
+ t1r = SIMDBase_ADDi(SIMDBase_SUBi(s00, s20), SIMDBase_SUBi(s31, s11));
+ t1i = SIMDBase_ADDi(SIMDBase_SUBi(s01, s21), SIMDBase_SUBi(s10, s30));
+
+ a0 = SIMDBase_LOAD1(&tbl[p0+0]); a1 = SIMDBase_LOAD1(&tbl[p0+1]);
+ a2 = SIMDBase_LOAD1(&tbl[p0+2]); a3 = SIMDBase_LOAD1(&tbl[p0+3]);
+
+ SIMDBase_STOR(&s[i0 ], SIMDBase_ADDi(s00, s20)); SIMDBase_STOR(&s[i0+1], SIMDBase_ADDi(s01, s21));
+ SIMDBase_STOR(&s[i1 ], SIMDBase_ADDi(s10, s30)); SIMDBase_STOR(&s[i1+1], SIMDBase_ADDi(s11, s31));
+
+#ifndef SIMDBase_FMADD_AVAILABLE
+ SIMDBase_STOR(&s[i2 ], SIMDBase_SUBi(SIMDBase_MULi(t0r, a0), SIMDBase_MULi(t0i, a1)));
+ SIMDBase_STOR(&s[i2+1], SIMDBase_ADDi(SIMDBase_MULi(t0r, a1), SIMDBase_MULi(t0i, a0)));
+ SIMDBase_STOR(&s[i3 ], SIMDBase_SUBi(SIMDBase_MULi(t1r, a2), SIMDBase_MULi(t1i, a3)));
+ SIMDBase_STOR(&s[i3+1], SIMDBase_ADDi(SIMDBase_MULi(t1r, a3), SIMDBase_MULi(t1i, a2)));
+#else
+ SIMDBase_STOR(&s[i2 ], SIMDBase_FMSUBi(t0i, a1, SIMDBase_MULi(t0r, a0)));
+ SIMDBase_STOR(&s[i2+1], SIMDBase_FMADDi(t0r, a1, SIMDBase_MULi(t0i, a0)));
+ SIMDBase_STOR(&s[i3 ], SIMDBase_FMSUBi(t1i, a3, SIMDBase_MULi(t1r, a2)));
+ SIMDBase_STOR(&s[i3+1], SIMDBase_FMADDi(t1r, a3, SIMDBase_MULi(t1i, a2)));
+#endif
+
+ i0 += 2; i1 += 2; i2 += 2; i3 += 2;
+ p0 += 4;
+ }
+}
+#endif
+
+#if 0
+static inline void srButBackwardSub(DFTUndiff *p) {
+ SIMDBase_VECT *s = p->s;
+ SIMDBase_REAL *tbl = p->ptTable[p->log2butlen];
+
+ int32_t i0 = p->offset1;
+ int32_t i1 = i0 + p->stride;
+ int32_t i2 = i1 + p->stride;
+ int32_t i3 = i2 + p->stride;
+ int32_t im = i1;
+
+ int32_t p0 = p->offset2 & (p->butlen*4-1);
+
+ while(i0 < im) {
+ SIMDBase_VECT t0r, t0i, t1r, t1i, u, v;
+ SIMDBase_VECT s00, s01, s10, s11, s20, s21, s30, s31;
+ SIMDBase_VECT a0, a1, a2, a3;
+
+ s20 = SIMDBase_LOAD(&s[i2+0]); s21 = SIMDBase_LOAD(&s[i2+1]);
+ a0 = SIMDBase_LOAD1(&tbl[p0+0]); a1 = SIMDBase_LOAD1(&tbl[p0+1]);
+ u = SIMDBase_ADDi(SIMDBase_MULi(s20, a0), SIMDBase_MULi(s21, a1));
+
+ s30 = SIMDBase_LOAD(&s[i3+0]); s31 = SIMDBase_LOAD(&s[i3+1]);
+ a2 = SIMDBase_LOAD1(&tbl[p0+2]); a3 = SIMDBase_LOAD1(&tbl[p0+3]);
+ v = SIMDBase_ADDi(SIMDBase_MULi(s30, a2), SIMDBase_MULi(s31, a3));
+
+ t0r = SIMDBase_ADDi(u, v); t1i = SIMDBase_SUBi(u, v);
+ u = SIMDBase_SUBi(SIMDBase_MULi(s31, a2), SIMDBase_MULi(s30, a3));
+ v = SIMDBase_SUBi(SIMDBase_MULi(s21, a0), SIMDBase_MULi(s20, a1));
+ t0i = SIMDBase_ADDi(u, v); t1r = SIMDBase_SUBi(u, v);
+
+ s00 = SIMDBase_LOAD(&s[i0+0]); s01 = SIMDBase_LOAD(&s[i0+1]);
+ s10 = SIMDBase_LOAD(&s[i1+0]); s11 = SIMDBase_LOAD(&s[i1+1]);
+
+ SIMDBase_STOR(&s[i2+0], SIMDBase_SUBi(s00, t0r)); SIMDBase_STOR(&s[i0+0], SIMDBase_ADDi(s00, t0r));
+ SIMDBase_STOR(&s[i2+1], SIMDBase_SUBi(s01, t0i)); SIMDBase_STOR(&s[i0+1], SIMDBase_ADDi(s01, t0i));
+ SIMDBase_STOR(&s[i3+0], SIMDBase_SUBi(s10, t1r)); SIMDBase_STOR(&s[i1+0], SIMDBase_ADDi(s10, t1r));
+ SIMDBase_STOR(&s[i3+1], SIMDBase_SUBi(s11, t1i)); SIMDBase_STOR(&s[i1+1], SIMDBase_ADDi(s11, t1i));
+
+ i0 += 2; i1 += 2; i2 += 2; i3 += 2;
+ p0 += 4;
+ }
+}
+
+static void srButBackwardSubUnrolled(DFTUndiff *p) {
+ srButBackwardSub(p);
+}
+#endif
+
+static inline void srButForwardSubUnrolled(DFTUndiff *p) {
+ SIMDBase_VECT *s = p->s;
+ SIMDBase_REAL *tbl = p->ptTable[p->log2butlen];
+
+ int32_t i0 = p->offset1;
+ int32_t i1 = i0 + p->stride;
+ int32_t i2 = i1 + p->stride;
+ int32_t i3 = i2 + p->stride;
+ int32_t im = i1;
+
+ int32_t p0 = p->offset2 & (p->butlen*4-1);
+
+ while(i0 < im) {
+ SIMDBase_VECT t0r, t0i, t1r, t1i;
+ SIMDBase_VECT s00, s01, s10, s11, s20, s21, s30, s31;
+ SIMDBase_VECT a0, a1, a2, a3;
+
+ //
+
+ s00 = SIMDBase_LOAD(&s[i0+0]); s01 = SIMDBase_LOAD(&s[i0+1]);
+ s10 = SIMDBase_LOAD(&s[i1+0]); s11 = SIMDBase_LOAD(&s[i1+1]);
+ s20 = SIMDBase_LOAD(&s[i2+0]); s21 = SIMDBase_LOAD(&s[i2+1]);
+ s30 = SIMDBase_LOAD(&s[i3+0]); s31 = SIMDBase_LOAD(&s[i3+1]);
+
+ t0r = SIMDBase_SUBi(SIMDBase_SUBi(s00, s20), SIMDBase_SUBi(s31, s11));
+ t0i = SIMDBase_SUBi(SIMDBase_SUBi(s01, s21), SIMDBase_SUBi(s10, s30));
+
+ t1r = SIMDBase_ADDi(SIMDBase_SUBi(s00, s20), SIMDBase_SUBi(s31, s11));
+ t1i = SIMDBase_ADDi(SIMDBase_SUBi(s01, s21), SIMDBase_SUBi(s10, s30));
+
+ a0 = SIMDBase_LOAD1(&tbl[p0+0]); a1 = SIMDBase_LOAD1(&tbl[p0+1]);
+ a2 = SIMDBase_LOAD1(&tbl[p0+2]); a3 = SIMDBase_LOAD1(&tbl[p0+3]);
+
+ SIMDBase_STOR(&s[i0 ], SIMDBase_ADDi(s00, s20)); SIMDBase_STOR(&s[i0+1], SIMDBase_ADDi(s01, s21));
+ SIMDBase_STOR(&s[i1 ], SIMDBase_ADDi(s10, s30)); SIMDBase_STOR(&s[i1+1], SIMDBase_ADDi(s11, s31));
+
+#ifndef SIMDBase_FMADD_AVAILABLE
+ SIMDBase_STOR(&s[i2 ], SIMDBase_SUBi(SIMDBase_MULi(t0r, a0), SIMDBase_MULi(t0i, a1)));
+ SIMDBase_STOR(&s[i2+1], SIMDBase_ADDi(SIMDBase_MULi(t0r, a1), SIMDBase_MULi(t0i, a0)));
+ SIMDBase_STOR(&s[i3 ], SIMDBase_SUBi(SIMDBase_MULi(t1r, a2), SIMDBase_MULi(t1i, a3)));
+ SIMDBase_STOR(&s[i3+1], SIMDBase_ADDi(SIMDBase_MULi(t1r, a3), SIMDBase_MULi(t1i, a2)));
+#else
+ SIMDBase_STOR(&s[i2 ], SIMDBase_FMSUBi(t0i, a1, SIMDBase_MULi(t0r, a0)));
+ SIMDBase_STOR(&s[i2+1], SIMDBase_FMADDi(t0r, a1, SIMDBase_MULi(t0i, a0)));
+ SIMDBase_STOR(&s[i3 ], SIMDBase_FMSUBi(t1i, a3, SIMDBase_MULi(t1r, a2)));
+ SIMDBase_STOR(&s[i3+1], SIMDBase_FMADDi(t1r, a3, SIMDBase_MULi(t1i, a2)));
+#endif
+
+ //
+
+ s00 = SIMDBase_LOAD(&s[i0+2]); s01 = SIMDBase_LOAD(&s[i0+3]);
+ s10 = SIMDBase_LOAD(&s[i1+2]); s11 = SIMDBase_LOAD(&s[i1+3]);
+ s20 = SIMDBase_LOAD(&s[i2+2]); s21 = SIMDBase_LOAD(&s[i2+3]);
+ s30 = SIMDBase_LOAD(&s[i3+2]); s31 = SIMDBase_LOAD(&s[i3+3]);
+
+ t0r = SIMDBase_SUBi(SIMDBase_SUBi(s00, s20), SIMDBase_SUBi(s31, s11));
+ t0i = SIMDBase_SUBi(SIMDBase_SUBi(s01, s21), SIMDBase_SUBi(s10, s30));
+
+ t1r = SIMDBase_ADDi(SIMDBase_SUBi(s00, s20), SIMDBase_SUBi(s31, s11));
+ t1i = SIMDBase_ADDi(SIMDBase_SUBi(s01, s21), SIMDBase_SUBi(s10, s30));
+
+ a0 = SIMDBase_LOAD1(&tbl[p0+4]); a1 = SIMDBase_LOAD1(&tbl[p0+5]);
+ a2 = SIMDBase_LOAD1(&tbl[p0+6]); a3 = SIMDBase_LOAD1(&tbl[p0+7]);
+
+ SIMDBase_STOR(&s[i0+2], SIMDBase_ADDi(s00, s20)); SIMDBase_STOR(&s[i0+3], SIMDBase_ADDi(s01, s21));
+ SIMDBase_STOR(&s[i1+2], SIMDBase_ADDi(s10, s30)); SIMDBase_STOR(&s[i1+3], SIMDBase_ADDi(s11, s31));
+
+#ifndef SIMDBase_FMADD_AVAILABLE
+ SIMDBase_STOR(&s[i2+2], SIMDBase_SUBi(SIMDBase_MULi(t0r, a0), SIMDBase_MULi(t0i, a1)));
+ SIMDBase_STOR(&s[i2+3], SIMDBase_ADDi(SIMDBase_MULi(t0r, a1), SIMDBase_MULi(t0i, a0)));
+ SIMDBase_STOR(&s[i3+2], SIMDBase_SUBi(SIMDBase_MULi(t1r, a2), SIMDBase_MULi(t1i, a3)));
+ SIMDBase_STOR(&s[i3+3], SIMDBase_ADDi(SIMDBase_MULi(t1r, a3), SIMDBase_MULi(t1i, a2)));
+#else
+ SIMDBase_STOR(&s[i2+2], SIMDBase_FMSUBi(t0i, a1, SIMDBase_MULi(t0r, a0)));
+ SIMDBase_STOR(&s[i2+3], SIMDBase_FMADDi(t0r, a1, SIMDBase_MULi(t0i, a0)));
+ SIMDBase_STOR(&s[i3+2], SIMDBase_FMSUBi(t1i, a3, SIMDBase_MULi(t1r, a2)));
+ SIMDBase_STOR(&s[i3+3], SIMDBase_FMADDi(t1r, a3, SIMDBase_MULi(t1i, a2)));
+#endif
+
+ //
+
+ s00 = SIMDBase_LOAD(&s[i0+4]); s01 = SIMDBase_LOAD(&s[i0+5]);
+ s10 = SIMDBase_LOAD(&s[i1+4]); s11 = SIMDBase_LOAD(&s[i1+5]);
+ s20 = SIMDBase_LOAD(&s[i2+4]); s21 = SIMDBase_LOAD(&s[i2+5]);
+ s30 = SIMDBase_LOAD(&s[i3+4]); s31 = SIMDBase_LOAD(&s[i3+5]);
+
+ t0r = SIMDBase_SUBi(SIMDBase_SUBi(s00, s20), SIMDBase_SUBi(s31, s11));
+ t0i = SIMDBase_SUBi(SIMDBase_SUBi(s01, s21), SIMDBase_SUBi(s10, s30));
+
+ t1r = SIMDBase_ADDi(SIMDBase_SUBi(s00, s20), SIMDBase_SUBi(s31, s11));
+ t1i = SIMDBase_ADDi(SIMDBase_SUBi(s01, s21), SIMDBase_SUBi(s10, s30));
+
+ a0 = SIMDBase_LOAD1(&tbl[p0+ 8]); a1 = SIMDBase_LOAD1(&tbl[p0+ 9]);
+ a2 = SIMDBase_LOAD1(&tbl[p0+10]); a3 = SIMDBase_LOAD1(&tbl[p0+11]);
+
+ SIMDBase_STOR(&s[i0+4], SIMDBase_ADDi(s00, s20)); SIMDBase_STOR(&s[i0+5], SIMDBase_ADDi(s01, s21));
+ SIMDBase_STOR(&s[i1+4], SIMDBase_ADDi(s10, s30)); SIMDBase_STOR(&s[i1+5], SIMDBase_ADDi(s11, s31));
+
+#ifndef SIMDBase_FMADD_AVAILABLE
+ SIMDBase_STOR(&s[i2+4], SIMDBase_SUBi(SIMDBase_MULi(t0r, a0), SIMDBase_MULi(t0i, a1)));
+ SIMDBase_STOR(&s[i2+5], SIMDBase_ADDi(SIMDBase_MULi(t0r, a1), SIMDBase_MULi(t0i, a0)));
+ SIMDBase_STOR(&s[i3+4], SIMDBase_SUBi(SIMDBase_MULi(t1r, a2), SIMDBase_MULi(t1i, a3)));
+ SIMDBase_STOR(&s[i3+5], SIMDBase_ADDi(SIMDBase_MULi(t1r, a3), SIMDBase_MULi(t1i, a2)));
+#else
+ SIMDBase_STOR(&s[i2+4], SIMDBase_FMSUBi(t0i, a1, SIMDBase_MULi(t0r, a0)));
+ SIMDBase_STOR(&s[i2+5], SIMDBase_FMADDi(t0r, a1, SIMDBase_MULi(t0i, a0)));
+ SIMDBase_STOR(&s[i3+4], SIMDBase_FMSUBi(t1i, a3, SIMDBase_MULi(t1r, a2)));
+ SIMDBase_STOR(&s[i3+5], SIMDBase_FMADDi(t1r, a3, SIMDBase_MULi(t1i, a2)));
+#endif
+
+ //
+
+ s00 = SIMDBase_LOAD(&s[i0+6]); s01 = SIMDBase_LOAD(&s[i0+7]);
+ s10 = SIMDBase_LOAD(&s[i1+6]); s11 = SIMDBase_LOAD(&s[i1+7]);
+ s20 = SIMDBase_LOAD(&s[i2+6]); s21 = SIMDBase_LOAD(&s[i2+7]);
+ s30 = SIMDBase_LOAD(&s[i3+6]); s31 = SIMDBase_LOAD(&s[i3+7]);
+
+ t0r = SIMDBase_SUBi(SIMDBase_SUBi(s00, s20), SIMDBase_SUBi(s31, s11));
+ t0i = SIMDBase_SUBi(SIMDBase_SUBi(s01, s21), SIMDBase_SUBi(s10, s30));
+
+ t1r = SIMDBase_ADDi(SIMDBase_SUBi(s00, s20), SIMDBase_SUBi(s31, s11));
+ t1i = SIMDBase_ADDi(SIMDBase_SUBi(s01, s21), SIMDBase_SUBi(s10, s30));
+
+ a0 = SIMDBase_LOAD1(&tbl[p0+12]); a1 = SIMDBase_LOAD1(&tbl[p0+13]);
+ a2 = SIMDBase_LOAD1(&tbl[p0+14]); a3 = SIMDBase_LOAD1(&tbl[p0+15]);
+
+ SIMDBase_STOR(&s[i0+6], SIMDBase_ADDi(s00, s20)); SIMDBase_STOR(&s[i0+7], SIMDBase_ADDi(s01, s21));
+ SIMDBase_STOR(&s[i1+6], SIMDBase_ADDi(s10, s30)); SIMDBase_STOR(&s[i1+7], SIMDBase_ADDi(s11, s31));
+
+#ifndef SIMDBase_FMADD_AVAILABLE
+ SIMDBase_STOR(&s[i2+6], SIMDBase_SUBi(SIMDBase_MULi(t0r, a0), SIMDBase_MULi(t0i, a1)));
+ SIMDBase_STOR(&s[i2+7], SIMDBase_ADDi(SIMDBase_MULi(t0r, a1), SIMDBase_MULi(t0i, a0)));
+ SIMDBase_STOR(&s[i3+6], SIMDBase_SUBi(SIMDBase_MULi(t1r, a2), SIMDBase_MULi(t1i, a3)));
+ SIMDBase_STOR(&s[i3+7], SIMDBase_ADDi(SIMDBase_MULi(t1r, a3), SIMDBase_MULi(t1i, a2)));
+#else
+ SIMDBase_STOR(&s[i2+6], SIMDBase_FMSUBi(t0i, a1, SIMDBase_MULi(t0r, a0)));
+ SIMDBase_STOR(&s[i2+7], SIMDBase_FMADDi(t0r, a1, SIMDBase_MULi(t0i, a0)));
+ SIMDBase_STOR(&s[i3+6], SIMDBase_FMSUBi(t1i, a3, SIMDBase_MULi(t1r, a2)));
+ SIMDBase_STOR(&s[i3+7], SIMDBase_FMADDi(t1r, a3, SIMDBase_MULi(t1i, a2)));
+#endif
+
+ //
+
+ i0 += 8; i1 += 8; i2 += 8; i3 += 8;
+ p0 += 16;
+ }
+}
+
+#if 1
+static void srButBackwardSubUnrolled(DFTUndiff *p) {
+ SIMDBase_VECT *s = p->s;
+ SIMDBase_REAL *tbl = p->ptTable[p->log2butlen];
+
+ int32_t i0 = p->offset1;
+ int32_t i1 = i0 + p->stride;
+ int32_t i2 = i1 + p->stride;
+ int32_t i3 = i2 + p->stride;
+ int32_t im = i1;
+
+ int32_t p0 = p->offset2 & (p->butlen*4-1);
+
+ while(i0 < im) {
+ SIMDBase_VECT t0r, t0i, t1r, t1i, u, v;
+ SIMDBase_VECT s00, s01, s10, s11, s20, s21, s30, s31;
+ SIMDBase_VECT a0, a1, a2, a3;
+
+ //
+
+ s20 = SIMDBase_LOAD(&s[i2+ 0]); s21 = SIMDBase_LOAD(&s[i2+ 1]);
+ a0 = SIMDBase_LOAD1(&tbl[p0+ 0]); a1 = SIMDBase_LOAD1(&tbl[p0+ 1]);
+#ifndef SIMDBase_FMADD_AVAILABLE
+ u = SIMDBase_ADDi(SIMDBase_MULi(s20, a0), SIMDBase_MULi(s21, a1));
+#else
+ u = SIMDBase_FMADDi(s20, a0, SIMDBase_MULi(s21, a1));
+#endif
+
+ s30 = SIMDBase_LOAD(&s[i3+ 0]); s31 = SIMDBase_LOAD(&s[i3+ 1]);
+ a2 = SIMDBase_LOAD1(&tbl[p0+ 2]); a3 = SIMDBase_LOAD1(&tbl[p0+ 3]);
+#ifndef SIMDBase_FMADD_AVAILABLE
+ v = SIMDBase_ADDi(SIMDBase_MULi(s30, a2), SIMDBase_MULi(s31, a3));
+#else
+ v = SIMDBase_FMADDi(s30, a2, SIMDBase_MULi(s31, a3));
+#endif
+
+ t0r = SIMDBase_ADDi(u, v); t1i = SIMDBase_SUBi(u, v);
+
+#ifndef SIMDBase_FMADD_AVAILABLE
+ u = SIMDBase_SUBi(SIMDBase_MULi(s31, a2), SIMDBase_MULi(s30, a3));
+ v = SIMDBase_SUBi(SIMDBase_MULi(s21, a0), SIMDBase_MULi(s20, a1));
+#else
+ u = SIMDBase_FMSUBi(s30, a3, SIMDBase_MULi(s31, a2));
+ v = SIMDBase_FMSUBi(s20, a1, SIMDBase_MULi(s21, a0));
+#endif
+ t0i = SIMDBase_ADDi(u, v); t1r = SIMDBase_SUBi(u, v);
+
+ s00 = SIMDBase_LOAD(&s[i0+ 0]); s01 = SIMDBase_LOAD(&s[i0+ 1]);
+ s10 = SIMDBase_LOAD(&s[i1+ 0]); s11 = SIMDBase_LOAD(&s[i1+ 1]);
+
+ SIMDBase_STOR(&s[i2+ 0], SIMDBase_SUBi(s00, t0r)); SIMDBase_STOR(&s[i0+ 0], SIMDBase_ADDi(s00, t0r));
+ SIMDBase_STOR(&s[i2+ 1], SIMDBase_SUBi(s01, t0i)); SIMDBase_STOR(&s[i0+ 1], SIMDBase_ADDi(s01, t0i));
+ SIMDBase_STOR(&s[i3+ 0], SIMDBase_SUBi(s10, t1r)); SIMDBase_STOR(&s[i1+ 0], SIMDBase_ADDi(s10, t1r));
+ SIMDBase_STOR(&s[i3+ 1], SIMDBase_SUBi(s11, t1i)); SIMDBase_STOR(&s[i1+ 1], SIMDBase_ADDi(s11, t1i));
+
+ //
+
+ s20 = SIMDBase_LOAD(&s[i2+ 2]); s21 = SIMDBase_LOAD(&s[i2+ 3]);
+ a0 = SIMDBase_LOAD1(&tbl[p0+ 4]); a1 = SIMDBase_LOAD1(&tbl[p0+ 5]);
+#ifndef SIMDBase_FMADD_AVAILABLE
+ u = SIMDBase_ADDi(SIMDBase_MULi(s20, a0), SIMDBase_MULi(s21, a1));
+#else
+ u = SIMDBase_FMADDi(s20, a0, SIMDBase_MULi(s21, a1));
+#endif
+
+ s30 = SIMDBase_LOAD(&s[i3+ 2]); s31 = SIMDBase_LOAD(&s[i3+ 3]);
+ a2 = SIMDBase_LOAD1(&tbl[p0+ 6]); a3 = SIMDBase_LOAD1(&tbl[p0+ 7]);
+#ifndef SIMDBase_FMADD_AVAILABLE
+ v = SIMDBase_ADDi(SIMDBase_MULi(s30, a2), SIMDBase_MULi(s31, a3));
+#else
+ v = SIMDBase_FMADDi(s30, a2, SIMDBase_MULi(s31, a3));
+#endif
+
+ t0r = SIMDBase_ADDi(u, v); t1i = SIMDBase_SUBi(u, v);
+
+#ifndef SIMDBase_FMADD_AVAILABLE
+ u = SIMDBase_SUBi(SIMDBase_MULi(s31, a2), SIMDBase_MULi(s30, a3));
+ v = SIMDBase_SUBi(SIMDBase_MULi(s21, a0), SIMDBase_MULi(s20, a1));
+#else
+ u = SIMDBase_FMSUBi(s30, a3, SIMDBase_MULi(s31, a2));
+ v = SIMDBase_FMSUBi(s20, a1, SIMDBase_MULi(s21, a0));
+#endif
+ t0i = SIMDBase_ADDi(u, v); t1r = SIMDBase_SUBi(u, v);
+
+ s00 = SIMDBase_LOAD(&s[i0+ 2]); s01 = SIMDBase_LOAD(&s[i0+ 3]);
+ s10 = SIMDBase_LOAD(&s[i1+ 2]); s11 = SIMDBase_LOAD(&s[i1+ 3]);
+
+ SIMDBase_STOR(&s[i2+ 2], SIMDBase_SUBi(s00, t0r)); SIMDBase_STOR(&s[i0+ 2], SIMDBase_ADDi(s00, t0r));
+ SIMDBase_STOR(&s[i2+ 3], SIMDBase_SUBi(s01, t0i)); SIMDBase_STOR(&s[i0+ 3], SIMDBase_ADDi(s01, t0i));
+ SIMDBase_STOR(&s[i3+ 2], SIMDBase_SUBi(s10, t1r)); SIMDBase_STOR(&s[i1+ 2], SIMDBase_ADDi(s10, t1r));
+ SIMDBase_STOR(&s[i3+ 3], SIMDBase_SUBi(s11, t1i)); SIMDBase_STOR(&s[i1+ 3], SIMDBase_ADDi(s11, t1i));
+
+ //
+
+ s20 = SIMDBase_LOAD(&s[i2+ 4]); s21 = SIMDBase_LOAD(&s[i2+ 5]);
+ a0 = SIMDBase_LOAD1(&tbl[p0+ 8]); a1 = SIMDBase_LOAD1(&tbl[p0+ 9]);
+#ifndef SIMDBase_FMADD_AVAILABLE
+ u = SIMDBase_ADDi(SIMDBase_MULi(s20, a0), SIMDBase_MULi(s21, a1));
+#else
+ u = SIMDBase_FMADDi(s20, a0, SIMDBase_MULi(s21, a1));
+#endif
+
+ s30 = SIMDBase_LOAD(&s[i3+ 4]); s31 = SIMDBase_LOAD(&s[i3+ 5]);
+ a2 = SIMDBase_LOAD1(&tbl[p0+10]); a3 = SIMDBase_LOAD1(&tbl[p0+11]);
+#ifndef SIMDBase_FMADD_AVAILABLE
+ v = SIMDBase_ADDi(SIMDBase_MULi(s30, a2), SIMDBase_MULi(s31, a3));
+#else
+ v = SIMDBase_FMADDi(s30, a2, SIMDBase_MULi(s31, a3));
+#endif
+
+ t0r = SIMDBase_ADDi(u, v); t1i = SIMDBase_SUBi(u, v);
+
+#ifndef SIMDBase_FMADD_AVAILABLE
+ u = SIMDBase_SUBi(SIMDBase_MULi(s31, a2), SIMDBase_MULi(s30, a3));
+ v = SIMDBase_SUBi(SIMDBase_MULi(s21, a0), SIMDBase_MULi(s20, a1));
+#else
+ u = SIMDBase_FMSUBi(s30, a3, SIMDBase_MULi(s31, a2));
+ v = SIMDBase_FMSUBi(s20, a1, SIMDBase_MULi(s21, a0));
+#endif
+ t0i = SIMDBase_ADDi(u, v); t1r = SIMDBase_SUBi(u, v);
+
+ s00 = SIMDBase_LOAD(&s[i0+ 4]); s01 = SIMDBase_LOAD(&s[i0+ 5]);
+ s10 = SIMDBase_LOAD(&s[i1+ 4]); s11 = SIMDBase_LOAD(&s[i1+ 5]);
+
+ SIMDBase_STOR(&s[i2+ 4], SIMDBase_SUBi(s00, t0r)); SIMDBase_STOR(&s[i0+ 4], SIMDBase_ADDi(s00, t0r));
+ SIMDBase_STOR(&s[i2+ 5], SIMDBase_SUBi(s01, t0i)); SIMDBase_STOR(&s[i0+ 5], SIMDBase_ADDi(s01, t0i));
+ SIMDBase_STOR(&s[i3+ 4], SIMDBase_SUBi(s10, t1r)); SIMDBase_STOR(&s[i1+ 4], SIMDBase_ADDi(s10, t1r));
+ SIMDBase_STOR(&s[i3+ 5], SIMDBase_SUBi(s11, t1i)); SIMDBase_STOR(&s[i1+ 5], SIMDBase_ADDi(s11, t1i));
+
+ //
+
+ s20 = SIMDBase_LOAD(&s[i2+ 6]); s21 = SIMDBase_LOAD(&s[i2+ 7]);
+ a0 = SIMDBase_LOAD1(&tbl[p0+12]); a1 = SIMDBase_LOAD1(&tbl[p0+13]);
+#ifndef SIMDBase_FMADD_AVAILABLE
+ u = SIMDBase_ADDi(SIMDBase_MULi(s20, a0), SIMDBase_MULi(s21, a1));
+#else
+ u = SIMDBase_FMADDi(s20, a0, SIMDBase_MULi(s21, a1));
+#endif
+
+ s30 = SIMDBase_LOAD(&s[i3+ 6]); s31 = SIMDBase_LOAD(&s[i3+ 7]);
+ a2 = SIMDBase_LOAD1(&tbl[p0+14]); a3 = SIMDBase_LOAD1(&tbl[p0+15]);
+#ifndef SIMDBase_FMADD_AVAILABLE
+ v = SIMDBase_ADDi(SIMDBase_MULi(s30, a2), SIMDBase_MULi(s31, a3));
+#else
+ v = SIMDBase_FMADDi(s30, a2, SIMDBase_MULi(s31, a3));
+#endif
+
+ t0r = SIMDBase_ADDi(u, v); t1i = SIMDBase_SUBi(u, v);
+
+#ifndef SIMDBase_FMADD_AVAILABLE
+ u = SIMDBase_SUBi(SIMDBase_MULi(s31, a2), SIMDBase_MULi(s30, a3));
+ v = SIMDBase_SUBi(SIMDBase_MULi(s21, a0), SIMDBase_MULi(s20, a1));
+#else
+ u = SIMDBase_FMSUBi(s30, a3, SIMDBase_MULi(s31, a2));
+ v = SIMDBase_FMSUBi(s20, a1, SIMDBase_MULi(s21, a0));
+#endif
+ t0i = SIMDBase_ADDi(u, v); t1r = SIMDBase_SUBi(u, v);
+
+ s00 = SIMDBase_LOAD(&s[i0+ 6]); s01 = SIMDBase_LOAD(&s[i0+ 7]);
+ s10 = SIMDBase_LOAD(&s[i1+ 6]); s11 = SIMDBase_LOAD(&s[i1+ 7]);
+
+ SIMDBase_STOR(&s[i2+ 6], SIMDBase_SUBi(s00, t0r)); SIMDBase_STOR(&s[i0+ 6], SIMDBase_ADDi(s00, t0r));
+ SIMDBase_STOR(&s[i2+ 7], SIMDBase_SUBi(s01, t0i)); SIMDBase_STOR(&s[i0+ 7], SIMDBase_ADDi(s01, t0i));
+ SIMDBase_STOR(&s[i3+ 6], SIMDBase_SUBi(s10, t1r)); SIMDBase_STOR(&s[i1+ 6], SIMDBase_ADDi(s10, t1r));
+ SIMDBase_STOR(&s[i3+ 7], SIMDBase_SUBi(s11, t1i)); SIMDBase_STOR(&s[i1+ 7], SIMDBase_ADDi(s11, t1i));
+
+ //
+
+ i0 += 8; i1 += 8; i2 += 8; i3 += 8;
+ p0 += 16;
+ }
+}
+#endif
+
+static void r2ButForwardSub(DFTUndiff *p) {
+ SIMDBase_VECT *s = p->s;
+
+ SIMDBase_REAL *tbl = p->ptTable[p->log2butlen];
+
+ int32_t i0 = p->offset1;
+ int32_t i2 = i0 + p->stride*2;
+ int32_t cp = 0, sp = p->butlen/4;
+
+ do {
+ SIMDBase_VECT t0r, t0i, s0, s1, s2, s3, t0, t1;
+
+ s0 = SIMDBase_LOAD(&s[i0+0]); s2 = SIMDBase_LOAD(&s[i0+1]);
+ s1 = SIMDBase_LOAD(&s[i2+0]); s3 = SIMDBase_LOAD(&s[i2+1]);
+ t0 = SIMDBase_LOAD1(&tbl[cp+0]); t1 = SIMDBase_LOAD1(&tbl[sp-0]);
+ t0r = SIMDBase_SUBi(s0, s1); SIMDBase_STOR(&s[i0+0], SIMDBase_ADDi(s0, s1));
+ t0i = SIMDBase_SUBi(s2, s3); SIMDBase_STOR(&s[i0+1], SIMDBase_ADDi(s2, s3));
+ SIMDBase_STOR(&s[i2+0], SIMDBase_ADDi(SIMDBase_MULi(t0r, t0), SIMDBase_MULi(t0i, t1)));
+ SIMDBase_STOR(&s[i2+1], SIMDBase_SUBi(SIMDBase_MULi(t0i, t0), SIMDBase_MULi(t0r, t1)));
+
+ s0 = SIMDBase_LOAD(&s[i0+2]); s2 = SIMDBase_LOAD(&s[i0+3]);
+ s1 = SIMDBase_LOAD(&s[i2+2]); s3 = SIMDBase_LOAD(&s[i2+3]);
+ t0 = SIMDBase_LOAD1(&tbl[cp+1]); t1 = SIMDBase_LOAD1(&tbl[sp-1]);
+ t0r = SIMDBase_SUBi(s0, s1); SIMDBase_STOR(&s[i0+2], SIMDBase_ADDi(s0, s1));
+ t0i = SIMDBase_SUBi(s2, s3); SIMDBase_STOR(&s[i0+3], SIMDBase_ADDi(s2, s3));
+ SIMDBase_STOR(&s[i2+2], SIMDBase_ADDi(SIMDBase_MULi(t0r, t0), SIMDBase_MULi(t0i, t1)));
+ SIMDBase_STOR(&s[i2+3], SIMDBase_SUBi(SIMDBase_MULi(t0i, t0), SIMDBase_MULi(t0r, t1)));
+
+ s0 = SIMDBase_LOAD(&s[i0+4]); s2 = SIMDBase_LOAD(&s[i0+5]);
+ s1 = SIMDBase_LOAD(&s[i2+4]); s3 = SIMDBase_LOAD(&s[i2+5]);
+ t0 = SIMDBase_LOAD1(&tbl[cp+2]); t1 = SIMDBase_LOAD1(&tbl[sp-2]);
+ t0r = SIMDBase_SUBi(s0, s1); SIMDBase_STOR(&s[i0+4], SIMDBase_ADDi(s0, s1));
+ t0i = SIMDBase_SUBi(s2, s3); SIMDBase_STOR(&s[i0+5], SIMDBase_ADDi(s2, s3));
+ SIMDBase_STOR(&s[i2+4], SIMDBase_ADDi(SIMDBase_MULi(t0r, t0), SIMDBase_MULi(t0i, t1)));
+ SIMDBase_STOR(&s[i2+5], SIMDBase_SUBi(SIMDBase_MULi(t0i, t0), SIMDBase_MULi(t0r, t1)));
+
+ s0 = SIMDBase_LOAD(&s[i0+6]); s2 = SIMDBase_LOAD(&s[i0+7]);
+ s1 = SIMDBase_LOAD(&s[i2+6]); s3 = SIMDBase_LOAD(&s[i2+7]);
+ t0 = SIMDBase_LOAD1(&tbl[cp+3]); t1 = SIMDBase_LOAD1(&tbl[sp-3]);
+ t0r = SIMDBase_SUBi(s0, s1); SIMDBase_STOR(&s[i0+6], SIMDBase_ADDi(s0, s1));
+ t0i = SIMDBase_SUBi(s2, s3); SIMDBase_STOR(&s[i0+7], SIMDBase_ADDi(s2, s3));
+ SIMDBase_STOR(&s[i2+6], SIMDBase_ADDi(SIMDBase_MULi(t0r, t0), SIMDBase_MULi(t0i, t1)));
+ SIMDBase_STOR(&s[i2+7], SIMDBase_SUBi(SIMDBase_MULi(t0i, t0), SIMDBase_MULi(t0r, t1)));
+
+ //
+
+ i0 += 8; i2 += 8; cp += 4; sp -= 4;
+ } while(sp > 0);
+
+ do {
+ SIMDBase_VECT t0r, t0i, s0, s1, s2, s3, t0, t1;
+
+ s0 = SIMDBase_LOAD(&s[i0+0]); s2 = SIMDBase_LOAD(&s[i0+1]);
+ s1 = SIMDBase_LOAD(&s[i2+0]); s3 = SIMDBase_LOAD(&s[i2+1]);
+ t0 = SIMDBase_LOAD1(&tbl[cp-0]); t1 = SIMDBase_LOAD1(&tbl[sp+0]);
+ t0r = SIMDBase_SUBi(s0, s1); SIMDBase_STOR(&s[i0+0], SIMDBase_ADDi(s0, s1));
+ t0i = SIMDBase_SUBi(s2, s3); SIMDBase_STOR(&s[i0+1], SIMDBase_ADDi(s2, s3));
+ SIMDBase_STOR(&s[i2+0], SIMDBase_SUBi(SIMDBase_MULi(t0i, t1), SIMDBase_MULi(t0r, t0)));
+ SIMDBase_STOR(&s[i2+1], SIMDBase_NEGi(SIMDBase_ADDi(SIMDBase_MULi(t0i, t0), SIMDBase_MULi(t0r, t1))));
+
+ s0 = SIMDBase_LOAD(&s[i0+2]); s2 = SIMDBase_LOAD(&s[i0+3]);
+ s1 = SIMDBase_LOAD(&s[i2+2]); s3 = SIMDBase_LOAD(&s[i2+3]);
+ t0 = SIMDBase_LOAD1(&tbl[cp-1]); t1 = SIMDBase_LOAD1(&tbl[sp+1]);
+ t0r = SIMDBase_SUBi(s0, s1); SIMDBase_STOR(&s[i0+2], SIMDBase_ADDi(s0, s1));
+ t0i = SIMDBase_SUBi(s2, s3); SIMDBase_STOR(&s[i0+3], SIMDBase_ADDi(s2, s3));
+ SIMDBase_STOR(&s[i2+2], SIMDBase_SUBi(SIMDBase_MULi(t0i, t1), SIMDBase_MULi(t0r, t0)));
+ SIMDBase_STOR(&s[i2+3], SIMDBase_NEGi(SIMDBase_ADDi(SIMDBase_MULi(t0i, t0), SIMDBase_MULi(t0r, t1))));
+
+ s0 = SIMDBase_LOAD(&s[i0+4]); s2 = SIMDBase_LOAD(&s[i0+5]);
+ s1 = SIMDBase_LOAD(&s[i2+4]); s3 = SIMDBase_LOAD(&s[i2+5]);
+ t0 = SIMDBase_LOAD1(&tbl[cp-2]); t1 = SIMDBase_LOAD1(&tbl[sp+2]);
+ t0r = SIMDBase_SUBi(s0, s1); SIMDBase_STOR(&s[i0+4], SIMDBase_ADDi(s0, s1));
+ t0i = SIMDBase_SUBi(s2, s3); SIMDBase_STOR(&s[i0+5], SIMDBase_ADDi(s2, s3));
+ SIMDBase_STOR(&s[i2+4], SIMDBase_SUBi(SIMDBase_MULi(t0i, t1), SIMDBase_MULi(t0r, t0)));
+ SIMDBase_STOR(&s[i2+5], SIMDBase_NEGi(SIMDBase_ADDi(SIMDBase_MULi(t0i, t0), SIMDBase_MULi(t0r, t1))));
+
+ s0 = SIMDBase_LOAD(&s[i0+6]); s2 = SIMDBase_LOAD(&s[i0+7]);
+ s1 = SIMDBase_LOAD(&s[i2+6]); s3 = SIMDBase_LOAD(&s[i2+7]);
+ t0 = SIMDBase_LOAD1(&tbl[cp-3]); t1 = SIMDBase_LOAD1(&tbl[sp+3]);
+ t0r = SIMDBase_SUBi(s0, s1); SIMDBase_STOR(&s[i0+6], SIMDBase_ADDi(s0, s1));
+ t0i = SIMDBase_SUBi(s2, s3); SIMDBase_STOR(&s[i0+7], SIMDBase_ADDi(s2, s3));
+ SIMDBase_STOR(&s[i2+6], SIMDBase_SUBi(SIMDBase_MULi(t0i, t1), SIMDBase_MULi(t0r, t0)));
+ SIMDBase_STOR(&s[i2+7], SIMDBase_NEGi(SIMDBase_ADDi(SIMDBase_MULi(t0i, t0), SIMDBase_MULi(t0r, t1))));
+
+ //
+
+ i0 += 8; i2 += 8; cp -= 4; sp += 4;
+ } while(cp > 0);
+}
+
+static void r2ButBackwardSub(DFTUndiff *p) {
+ SIMDBase_VECT *s = p->s;
+
+ SIMDBase_REAL *tbl = p->ptTable[p->log2butlen];
+
+ int i0 = p->offset1;
+ int i2 = i0 + p->stride*2;
+
+ int cp = 0, sp = p->butlen/4;
+
+ do {
+ SIMDBase_VECT t0r, t0i, s0, s1, s2, s3, t0, t1;
+
+ s0 = SIMDBase_LOAD(&s[i0+0]); s2 = SIMDBase_LOAD(&s[i0+1]);
+ s1 = SIMDBase_LOAD(&s[i2+0]); s3 = SIMDBase_LOAD(&s[i2+1]);
+ t0 = SIMDBase_LOAD1(&tbl[cp+0]); t1 = SIMDBase_LOAD1(&tbl[sp-0]);
+ t0r = SIMDBase_SUBi(SIMDBase_MULi(s1, t0), SIMDBase_MULi(s3, t1));
+ t0i = SIMDBase_ADDi(SIMDBase_MULi(s1, t1), SIMDBase_MULi(s3, t0));
+ SIMDBase_STOR(&s[i2+0], SIMDBase_SUBi(s0, t0r)); SIMDBase_STOR(&s[i0+0], SIMDBase_ADDi(s0, t0r));
+ SIMDBase_STOR(&s[i2+1], SIMDBase_SUBi(s2, t0i)); SIMDBase_STOR(&s[i0+1], SIMDBase_ADDi(s2, t0i));
+
+ s0 = SIMDBase_LOAD(&s[i0+2]); s2 = SIMDBase_LOAD(&s[i0+3]);
+ s1 = SIMDBase_LOAD(&s[i2+2]); s3 = SIMDBase_LOAD(&s[i2+3]);
+ t0 = SIMDBase_LOAD1(&tbl[cp+1]); t1 = SIMDBase_LOAD1(&tbl[sp-1]);
+ t0r = SIMDBase_SUBi(SIMDBase_MULi(s1, t0), SIMDBase_MULi(s3, t1));
+ t0i = SIMDBase_ADDi(SIMDBase_MULi(s1, t1), SIMDBase_MULi(s3, t0));
+ SIMDBase_STOR(&s[i2+2], SIMDBase_SUBi(s0, t0r)); SIMDBase_STOR(&s[i0+2], SIMDBase_ADDi(s0, t0r));
+ SIMDBase_STOR(&s[i2+3], SIMDBase_SUBi(s2, t0i)); SIMDBase_STOR(&s[i0+3], SIMDBase_ADDi(s2, t0i));
+
+ s0 = SIMDBase_LOAD(&s[i0+4]); s2 = SIMDBase_LOAD(&s[i0+5]);
+ s1 = SIMDBase_LOAD(&s[i2+4]); s3 = SIMDBase_LOAD(&s[i2+5]);
+ t0 = SIMDBase_LOAD1(&tbl[cp+2]); t1 = SIMDBase_LOAD1(&tbl[sp-2]);
+ t0r = SIMDBase_SUBi(SIMDBase_MULi(s1, t0), SIMDBase_MULi(s3, t1));
+ t0i = SIMDBase_ADDi(SIMDBase_MULi(s1, t1), SIMDBase_MULi(s3, t0));
+ SIMDBase_STOR(&s[i2+4], SIMDBase_SUBi(s0, t0r)); SIMDBase_STOR(&s[i0+4], SIMDBase_ADDi(s0, t0r));
+ SIMDBase_STOR(&s[i2+5], SIMDBase_SUBi(s2, t0i)); SIMDBase_STOR(&s[i0+5], SIMDBase_ADDi(s2, t0i));
+
+ s0 = SIMDBase_LOAD(&s[i0+6]); s2 = SIMDBase_LOAD(&s[i0+7]);
+ s1 = SIMDBase_LOAD(&s[i2+6]); s3 = SIMDBase_LOAD(&s[i2+7]);
+ t0 = SIMDBase_LOAD1(&tbl[cp+3]); t1 = SIMDBase_LOAD1(&tbl[sp-3]);
+ t0r = SIMDBase_SUBi(SIMDBase_MULi(s1, t0), SIMDBase_MULi(s3, t1));
+ t0i = SIMDBase_ADDi(SIMDBase_MULi(s1, t1), SIMDBase_MULi(s3, t0));
+ SIMDBase_STOR(&s[i2+6], SIMDBase_SUBi(s0, t0r)); SIMDBase_STOR(&s[i0+6], SIMDBase_ADDi(s0, t0r));
+ SIMDBase_STOR(&s[i2+7], SIMDBase_SUBi(s2, t0i)); SIMDBase_STOR(&s[i0+7], SIMDBase_ADDi(s2, t0i));
+
+ i0 += 8; i2 += 8; cp += 4; sp -= 4;
+ } while(sp > 0);
+
+ do {
+ SIMDBase_VECT t0r, t0i, s0, s1, s2, s3, t0, t1;
+
+ s0 = SIMDBase_LOAD(&s[i0+0]); s2 = SIMDBase_LOAD(&s[i0+1]);
+ s1 = SIMDBase_LOAD(&s[i2+0]); s3 = SIMDBase_LOAD(&s[i2+1]);
+ t0 = SIMDBase_LOAD1(&tbl[cp-0]); t1 = SIMDBase_LOAD1(&tbl[sp+0]);
+ t0r = SIMDBase_NEGi(SIMDBase_ADDi(SIMDBase_MULi(s1, t0), SIMDBase_MULi(s3, t1)));
+ t0i = SIMDBase_SUBi(SIMDBase_MULi(s1, t1), SIMDBase_MULi(s3, t0));
+ SIMDBase_STOR(&s[i2+0], SIMDBase_SUBi(s0, t0r)); SIMDBase_STOR(&s[i0+0], SIMDBase_ADDi(s0, t0r));
+ SIMDBase_STOR(&s[i2+1], SIMDBase_SUBi(s2, t0i)); SIMDBase_STOR(&s[i0+1], SIMDBase_ADDi(s2, t0i));
+
+ s0 = SIMDBase_LOAD(&s[i0+2]); s2 = SIMDBase_LOAD(&s[i0+3]);
+ s1 = SIMDBase_LOAD(&s[i2+2]); s3 = SIMDBase_LOAD(&s[i2+3]);
+ t0 = SIMDBase_LOAD1(&tbl[cp-1]); t1 = SIMDBase_LOAD1(&tbl[sp+1]);
+ t0r = SIMDBase_NEGi(SIMDBase_ADDi(SIMDBase_MULi(s1, t0), SIMDBase_MULi(s3, t1)));
+ t0i = SIMDBase_SUBi(SIMDBase_MULi(s1, t1), SIMDBase_MULi(s3, t0));
+ SIMDBase_STOR(&s[i2+2], SIMDBase_SUBi(s0, t0r)); SIMDBase_STOR(&s[i0+2], SIMDBase_ADDi(s0, t0r));
+ SIMDBase_STOR(&s[i2+3], SIMDBase_SUBi(s2, t0i)); SIMDBase_STOR(&s[i0+3], SIMDBase_ADDi(s2, t0i));
+
+ s0 = SIMDBase_LOAD(&s[i0+4]); s2 = SIMDBase_LOAD(&s[i0+5]);
+ s1 = SIMDBase_LOAD(&s[i2+4]); s3 = SIMDBase_LOAD(&s[i2+5]);
+ t0 = SIMDBase_LOAD1(&tbl[cp-2]); t1 = SIMDBase_LOAD1(&tbl[sp+2]);
+ t0r = SIMDBase_NEGi(SIMDBase_ADDi(SIMDBase_MULi(s1, t0), SIMDBase_MULi(s3, t1)));
+ t0i = SIMDBase_SUBi(SIMDBase_MULi(s1, t1), SIMDBase_MULi(s3, t0));
+ SIMDBase_STOR(&s[i2+4], SIMDBase_SUBi(s0, t0r)); SIMDBase_STOR(&s[i0+4], SIMDBase_ADDi(s0, t0r));
+ SIMDBase_STOR(&s[i2+5], SIMDBase_SUBi(s2, t0i)); SIMDBase_STOR(&s[i0+5], SIMDBase_ADDi(s2, t0i));
+
+ s0 = SIMDBase_LOAD(&s[i0+6]); s2 = SIMDBase_LOAD(&s[i0+7]);
+ s1 = SIMDBase_LOAD(&s[i2+6]); s3 = SIMDBase_LOAD(&s[i2+7]);
+ t0 = SIMDBase_LOAD1(&tbl[cp-3]); t1 = SIMDBase_LOAD1(&tbl[sp+3]);
+ t0r = SIMDBase_NEGi(SIMDBase_ADDi(SIMDBase_MULi(s1, t0), SIMDBase_MULi(s3, t1)));
+ t0i = SIMDBase_SUBi(SIMDBase_MULi(s1, t1), SIMDBase_MULi(s3, t0));
+ SIMDBase_STOR(&s[i2+6], SIMDBase_SUBi(s0, t0r)); SIMDBase_STOR(&s[i0+6], SIMDBase_ADDi(s0, t0r));
+ SIMDBase_STOR(&s[i2+7], SIMDBase_SUBi(s2, t0i)); SIMDBase_STOR(&s[i0+7], SIMDBase_ADDi(s2, t0i));
+
+ i0 += 8; i2 += 8; cp -= 4; sp += 4;
+ } while(cp > 0);
+}
+
+static void srButForward16(DFTUndiff *p) {
+ int32_t o = p->offset1;
+
+ p->butlen = 16; p->log2butlen = 4; p->stride = p->butlen/2;
+ srButForwardSubUnrolled(p);
+
+ p->offset1 = o + 16*6/4;
+ srButForward4(p);
+
+ p->offset1 = o + 16*4/4;
+ srButForward4(p);
+
+ p->offset1 = o;
+ srButForward8(p);
+}
+
+static void srButBackward16(DFTUndiff *p) {
+ int32_t o = p->offset1;
+
+ p->offset1 = o + 16*6/4;
+ srButBackward4(p);
+
+ p->offset1 = o + 16*4/4;
+ srButBackward4(p);
+
+ p->offset1 = o;
+ srButBackward8(p);
+
+ p->butlen = 16; p->log2butlen = 4; p->stride = p->butlen/2;
+ srButBackwardSubUnrolled(p);
+}
+
+static void srButForward32(DFTUndiff *p) {
+ int32_t o = p->offset1;
+
+ p->butlen = 32; p->log2butlen = 5; p->stride = p->butlen/2;
+ srButForwardSubUnrolled(p);
+
+ p->offset1 = o + 32*6/4;
+ srButForward8 (p);
+
+ p->offset1 = o + 32*4/4;
+ srButForward8 (p);
+
+ p->offset1 = o;
+ srButForward16(p);
+}
+
+static void srButBackward32(DFTUndiff *p) {
+ int32_t o = p->offset1;
+
+ p->offset1 = o + 32*6/4;
+ srButBackward8 (p);
+
+ p->offset1 = o + 32*4/4;
+ srButBackward8 (p);
+
+ p->offset1 = o;
+ srButBackward16(p);
+
+ p->butlen = 32; p->log2butlen = 5; p->stride = p->butlen/2;
+ srButBackwardSubUnrolled(p);
+}
+
+//
+
+#if 1
+static inline void bitReversalUnit(SIMDBase_VECT *p, SIMDBase_VECT *q) {
+ SIMDBase_VECT w, x, y, z;
+
+ w = SIMDBase_LOAD(p); x = SIMDBase_LOAD(p+1);
+ y = SIMDBase_LOAD(q); z = SIMDBase_LOAD(q+1);
+
+ SIMDBase_STOR(q, w); SIMDBase_STOR(q+1, x);
+ SIMDBase_STOR(p, y); SIMDBase_STOR(p+1, z);
+}
+#else
+#define bitReversalUnit(p0, q0) { \
+ SIMDBase_VECT *px = (p0), *qx = (q0); \
+ SIMDBase_VECT wx, xx, yx, zx; \
+ \
+ wx = SIMDBase_LOAD(px); xx = SIMDBase_LOAD(px+1); \
+ yx = SIMDBase_LOAD(qx); zx = SIMDBase_LOAD(qx+1); \
+ \
+ SIMDBase_STOR(qx, wx); SIMDBase_STOR(qx+1, xx); \
+ SIMDBase_STOR(px, yx); SIMDBase_STOR(px+1, zx); \
+}
+#endif
+
+static inline void bitReversal4s(SIMDBase_VECT *s, int32_t sc, int32_t o1, int32_t o2) {
+ SIMDBase_VECT *p = &s[o1*2], *q = &s[o2*2];
+ int b1 = sc*2*1, b2 = b1*2;
+ p += b1; q += b2;
+ bitReversalUnit(p, q);
+}
+
+static inline void bitReversal8s(SIMDBase_VECT *s, int32_t sc, int32_t o1, int32_t o2) {
+ SIMDBase_VECT *p = &s[o1*2], *q = &s[o2*2];
+ int b1 = sc*2*1, b2 = b1*2, b4 = b2*2;
+ p += b1; q += b4;
+ bitReversalUnit(p, q); p += b2; q += b2;
+ bitReversalUnit(p, q);
+}
+
+static inline void bitReversal8d(SIMDBase_VECT *s, int32_t sc, int32_t o1, int32_t o2) {
+ SIMDBase_VECT *p = &s[o1*2], *q = &s[o2*2];
+ int32_t b1 = sc*2*1, b2 = b1*2, b4 = b2*2;
+ bitReversalUnit(p, q); p += b1; q += b4;
+ bitReversalUnit(p, q); p += b2; q += b2;
+ bitReversalUnit(p, q); p -= b1; q -= b4;
+ bitReversalUnit(p, q); p += b4; q += b1;
+ bitReversalUnit(p, q); p += b1; q += b4;
+ bitReversalUnit(p, q); p -= b2; q -= b2;
+ bitReversalUnit(p, q); p -= b1; q -= b4;
+ bitReversalUnit(p, q);
+}
+
+static inline void bitReversal16s(SIMDBase_VECT *s, int32_t sc, int32_t o1, int32_t o2) {
+ SIMDBase_VECT *p = &s[o1*2], *q = &s[o2*2];
+ int32_t b1 = sc*2*1, b2 = b1*2, b4 = b2*2, b8 = b4*2;
+ p += b1; q += b8;
+ bitReversalUnit(p, q); p += b2; q += b4;
+ bitReversalUnit(p, q); p -= b1; q -= b8;
+ bitReversalUnit(p, q); p += b1 + b4; q += b2 + b8;
+ bitReversalUnit(p, q); p -= b2; q -= b4;
+ bitReversalUnit(p, q); p += b2 + b4; q += b1 + b2;
+ bitReversalUnit(p, q);
+}
+
+static inline void bitReversal16d(SIMDBase_VECT *s, int32_t sc, int32_t o1, int32_t o2) {
+ SIMDBase_VECT *p = &s[o1*2], *q = &s[o2*2];
+ int32_t b1 = sc*2*1, b2 = b1*2, b4 = b2*2, b8 = b4*2;
+ bitReversalUnit(p, q); p += b1; q += b8;
+ bitReversalUnit(p, q); p += b2; q += b4;
+ bitReversalUnit(p, q); p -= b1; q -= b8;
+ bitReversalUnit(p, q); p += b4; q += b2;
+ bitReversalUnit(p, q); p += b1; q += b8;
+ bitReversalUnit(p, q); p -= b2; q -= b4;
+ bitReversalUnit(p, q); p -= b1; q -= b8;
+ bitReversalUnit(p, q); p += b8; q += b1;
+ bitReversalUnit(p, q); p += b1; q += b8;
+ bitReversalUnit(p, q); p += b2; q += b4;
+ bitReversalUnit(p, q); p -= b1; q -= b8;
+ bitReversalUnit(p, q); p -= b4; q -= b2;
+ bitReversalUnit(p, q); p += b1; q += b8;
+ bitReversalUnit(p, q); p -= b2; q -= b4;
+ bitReversalUnit(p, q); p -= b1; q -= b8;
+ bitReversalUnit(p, q);
+}
+
+static inline void bitReversal32s(SIMDBase_VECT *s, int32_t sc, int32_t o1, int32_t o2) {
+ SIMDBase_VECT *p = &s[o1*2], *q = &s[o2*2];
+ int32_t b1 = sc*2*1, b2 = b1*2, b4 = b2*2, b8 = b4*2, b16 = b8*2;
+ p += b1; q += b16;
+ bitReversalUnit(p, q); p += b2; q += b8;
+ bitReversalUnit(p, q); p -= b1; q -= b16;
+ bitReversalUnit(p, q); p += b4; q += b4;
+ bitReversalUnit(p, q); p += b1; q += b16;
+ bitReversalUnit(p, q); p -= b2; q -= b8;
+ bitReversalUnit(p, q); p += b8; q += b2;
+ bitReversalUnit(p, q); p += b2; q += b8;
+ bitReversalUnit(p, q); p -= b4; q -= b4;
+ bitReversalUnit(p, q); p -= b2; q -= b8;
+ bitReversalUnit(p, q); p += b16 - b2; q += b1 + b2 + b8;
+ bitReversalUnit(p, q); p -= b4; q -= b4;
+ bitReversalUnit(p, q);
+}
+
+static void bitReversal32d(SIMDBase_VECT *s, int32_t sc, int32_t o1, int32_t o2) {
+ const int32_t k = 32;
+
+ bitReversal8d(s,2*sc, sc*(k/2 )+o1, sc* 1 +o2);
+ bitReversal8d(s,2*sc, sc* 0 +o1, sc* 0 +o2);
+ bitReversal8d(s,2*sc, sc* 1 +o1, sc*(k/2 )+o2);
+ bitReversal8d(s,2*sc, sc*(k/2+1)+o1, sc*(k/2+1)+o2);
+}
+
+static void bitReversalRecursive(SIMDBase_VECT *s, int32_t n, int32_t sc, int32_t o1, int32_t o2) {
+ if (n >= 64) {
+ if (o1 != o2) bitReversalRecursive(s, n/4, 2*sc, sc*(n/2)+o1, sc*1+o2);
+
+ bitReversalRecursive(s, n/4, 2*sc, sc* 0 +o1, sc* 0 +o2);
+ bitReversalRecursive(s, n/4, 2*sc, sc* 1 +o1, sc*(n/2 )+o2);
+ bitReversalRecursive(s, n/4, 2*sc, sc*(n/2+1)+o1, sc*(n/2+1)+o2);
+ } else {
+ if (o1 == o2) {
+ switch(n) {
+ case 4: bitReversal4s (s,sc,o1,o2); return;
+ case 8: bitReversal8s (s,sc,o1,o2); return;
+ case 16: bitReversal16s(s,sc,o1,o2); return;
+ case 32: bitReversal32s(s,sc,o1,o2); return;
+ }
+ } else {
+ switch(n) {
+ case 8: bitReversal8d (s,sc,o1,o2); return;
+ case 16: bitReversal16d(s,sc,o1,o2); return;
+ case 32: bitReversal32d(s,sc,o1,o2); return;
+ }
+ }
+ }
+}
+
+//
+
+static int bitR(int a, int logN) {
+ int ret = 0;
+ int i,j,k;
+ for(i=0,j=1,k=1<<(logN-1);i<logN;i++,j=j<<1,k=k>>1) {
+ if ((a & j) != 0) ret |= k;
+ }
+ return ret;
+}
+
+static void bitReversalCobraInplace(DFTUndiff *p) {
+ SIMDBase_VECT *s = p->s;
+ int cobraQ = p->cobraQ;
+ SIMDBase_VECT *cobraT = p->cobraT;
+ int *cobraR = p->cobraR;
+ int logN = p->log2len;
+
+ int b;
+
+ for(b=0;b<(1 << (logN-2*cobraQ));b++) {
+ int a,c;
+ int b2 = bitR(b, logN-2*cobraQ);
+
+ if (b2 < b) continue;
+
+ if (b2 == b) {
+ for(a=0;a<(1 << cobraQ);a++) {
+ int abc = ((a << (logN-2*cobraQ)) | b) << (cobraQ + 1);
+
+ int a2c = (cobraR[a] << cobraQ) << 1, a2cm = a2c+(1 << cobraQ)*2;
+
+ while(a2c < a2cm) {
+ SIMDBase_STOR(&cobraT[a2c++], SIMDBase_LOAD(&s[abc++])); SIMDBase_STOR(&cobraT[a2c++], SIMDBase_LOAD(&s[abc++]));
+ SIMDBase_STOR(&cobraT[a2c++], SIMDBase_LOAD(&s[abc++])); SIMDBase_STOR(&cobraT[a2c++], SIMDBase_LOAD(&s[abc++]));
+ SIMDBase_STOR(&cobraT[a2c++], SIMDBase_LOAD(&s[abc++])); SIMDBase_STOR(&cobraT[a2c++], SIMDBase_LOAD(&s[abc++]));
+ SIMDBase_STOR(&cobraT[a2c++], SIMDBase_LOAD(&s[abc++])); SIMDBase_STOR(&cobraT[a2c++], SIMDBase_LOAD(&s[abc++]));
+ SIMDBase_STOR(&cobraT[a2c++], SIMDBase_LOAD(&s[abc++])); SIMDBase_STOR(&cobraT[a2c++], SIMDBase_LOAD(&s[abc++]));
+ SIMDBase_STOR(&cobraT[a2c++], SIMDBase_LOAD(&s[abc++])); SIMDBase_STOR(&cobraT[a2c++], SIMDBase_LOAD(&s[abc++]));
+ SIMDBase_STOR(&cobraT[a2c++], SIMDBase_LOAD(&s[abc++])); SIMDBase_STOR(&cobraT[a2c++], SIMDBase_LOAD(&s[abc++]));
+ SIMDBase_STOR(&cobraT[a2c++], SIMDBase_LOAD(&s[abc++])); SIMDBase_STOR(&cobraT[a2c++], SIMDBase_LOAD(&s[abc++]));
+ SIMDBase_STOR(&cobraT[a2c++], SIMDBase_LOAD(&s[abc++])); SIMDBase_STOR(&cobraT[a2c++], SIMDBase_LOAD(&s[abc++]));
+ SIMDBase_STOR(&cobraT[a2c++], SIMDBase_LOAD(&s[abc++])); SIMDBase_STOR(&cobraT[a2c++], SIMDBase_LOAD(&s[abc++]));
+ SIMDBase_STOR(&cobraT[a2c++], SIMDBase_LOAD(&s[abc++])); SIMDBase_STOR(&cobraT[a2c++], SIMDBase_LOAD(&s[abc++]));
+ SIMDBase_STOR(&cobraT[a2c++], SIMDBase_LOAD(&s[abc++])); SIMDBase_STOR(&cobraT[a2c++], SIMDBase_LOAD(&s[abc++]));
+ SIMDBase_STOR(&cobraT[a2c++], SIMDBase_LOAD(&s[abc++])); SIMDBase_STOR(&cobraT[a2c++], SIMDBase_LOAD(&s[abc++]));
+ SIMDBase_STOR(&cobraT[a2c++], SIMDBase_LOAD(&s[abc++])); SIMDBase_STOR(&cobraT[a2c++], SIMDBase_LOAD(&s[abc++]));
+ SIMDBase_STOR(&cobraT[a2c++], SIMDBase_LOAD(&s[abc++])); SIMDBase_STOR(&cobraT[a2c++], SIMDBase_LOAD(&s[abc++]));
+ SIMDBase_STOR(&cobraT[a2c++], SIMDBase_LOAD(&s[abc++])); SIMDBase_STOR(&cobraT[a2c++], SIMDBase_LOAD(&s[abc++]));
+ }
+ }
+
+ for(c=0;c<(1 << cobraQ);c++) {
+ int c2 = cobraR[c];
+ int c2b2a2 = ((c2 << (logN-2*cobraQ)) | b2) << (cobraQ+1);
+
+ int a2c = c << 1;
+ int a2ci = 1 << (cobraQ+1);
+ int c2b2a2m = c2b2a2 + (1 << cobraQ)*2;
+
+ while(c2b2a2 < c2b2a2m) {
+ SIMDBase_STOR(&s[c2b2a2++], SIMDBase_LOAD(&cobraT[a2c ])); SIMDBase_STOR(&s[c2b2a2++], SIMDBase_LOAD(&cobraT[a2c+1])); a2c += a2ci;
+ SIMDBase_STOR(&s[c2b2a2++], SIMDBase_LOAD(&cobraT[a2c ])); SIMDBase_STOR(&s[c2b2a2++], SIMDBase_LOAD(&cobraT[a2c+1])); a2c += a2ci;
+ SIMDBase_STOR(&s[c2b2a2++], SIMDBase_LOAD(&cobraT[a2c ])); SIMDBase_STOR(&s[c2b2a2++], SIMDBase_LOAD(&cobraT[a2c+1])); a2c += a2ci;
+ SIMDBase_STOR(&s[c2b2a2++], SIMDBase_LOAD(&cobraT[a2c ])); SIMDBase_STOR(&s[c2b2a2++], SIMDBase_LOAD(&cobraT[a2c+1])); a2c += a2ci;
+ SIMDBase_STOR(&s[c2b2a2++], SIMDBase_LOAD(&cobraT[a2c ])); SIMDBase_STOR(&s[c2b2a2++], SIMDBase_LOAD(&cobraT[a2c+1])); a2c += a2ci;
+ SIMDBase_STOR(&s[c2b2a2++], SIMDBase_LOAD(&cobraT[a2c ])); SIMDBase_STOR(&s[c2b2a2++], SIMDBase_LOAD(&cobraT[a2c+1])); a2c += a2ci;
+ SIMDBase_STOR(&s[c2b2a2++], SIMDBase_LOAD(&cobraT[a2c ])); SIMDBase_STOR(&s[c2b2a2++], SIMDBase_LOAD(&cobraT[a2c+1])); a2c += a2ci;
+ SIMDBase_STOR(&s[c2b2a2++], SIMDBase_LOAD(&cobraT[a2c ])); SIMDBase_STOR(&s[c2b2a2++], SIMDBase_LOAD(&cobraT[a2c+1])); a2c += a2ci;
+ SIMDBase_STOR(&s[c2b2a2++], SIMDBase_LOAD(&cobraT[a2c ])); SIMDBase_STOR(&s[c2b2a2++], SIMDBase_LOAD(&cobraT[a2c+1])); a2c += a2ci;
+ SIMDBase_STOR(&s[c2b2a2++], SIMDBase_LOAD(&cobraT[a2c ])); SIMDBase_STOR(&s[c2b2a2++], SIMDBase_LOAD(&cobraT[a2c+1])); a2c += a2ci;
+ SIMDBase_STOR(&s[c2b2a2++], SIMDBase_LOAD(&cobraT[a2c ])); SIMDBase_STOR(&s[c2b2a2++], SIMDBase_LOAD(&cobraT[a2c+1])); a2c += a2ci;
+ SIMDBase_STOR(&s[c2b2a2++], SIMDBase_LOAD(&cobraT[a2c ])); SIMDBase_STOR(&s[c2b2a2++], SIMDBase_LOAD(&cobraT[a2c+1])); a2c += a2ci;
+ SIMDBase_STOR(&s[c2b2a2++], SIMDBase_LOAD(&cobraT[a2c ])); SIMDBase_STOR(&s[c2b2a2++], SIMDBase_LOAD(&cobraT[a2c+1])); a2c += a2ci;
+ SIMDBase_STOR(&s[c2b2a2++], SIMDBase_LOAD(&cobraT[a2c ])); SIMDBase_STOR(&s[c2b2a2++], SIMDBase_LOAD(&cobraT[a2c+1])); a2c += a2ci;
+ SIMDBase_STOR(&s[c2b2a2++], SIMDBase_LOAD(&cobraT[a2c ])); SIMDBase_STOR(&s[c2b2a2++], SIMDBase_LOAD(&cobraT[a2c+1])); a2c += a2ci;
+ SIMDBase_STOR(&s[c2b2a2++], SIMDBase_LOAD(&cobraT[a2c ])); SIMDBase_STOR(&s[c2b2a2++], SIMDBase_LOAD(&cobraT[a2c+1])); a2c += a2ci;
+ }
+ }
+ } else {
+ for(a=0;a<(1 << cobraQ);a++) {
+ int a2c = (cobraR[a] << cobraQ) << 1, a2cm = a2c+(1 << cobraQ)*2;
+ int abc = ((a << (logN-2*cobraQ)) | b) << (cobraQ + 1);
+
+ while(a2c < a2cm) {
+ SIMDBase_STOR(&cobraT[a2c++], SIMDBase_LOAD(&s[abc++])); SIMDBase_STOR(&cobraT[a2c++], SIMDBase_LOAD(&s[abc++]));
+ SIMDBase_STOR(&cobraT[a2c++], SIMDBase_LOAD(&s[abc++])); SIMDBase_STOR(&cobraT[a2c++], SIMDBase_LOAD(&s[abc++]));
+ SIMDBase_STOR(&cobraT[a2c++], SIMDBase_LOAD(&s[abc++])); SIMDBase_STOR(&cobraT[a2c++], SIMDBase_LOAD(&s[abc++]));
+ SIMDBase_STOR(&cobraT[a2c++], SIMDBase_LOAD(&s[abc++])); SIMDBase_STOR(&cobraT[a2c++], SIMDBase_LOAD(&s[abc++]));
+ SIMDBase_STOR(&cobraT[a2c++], SIMDBase_LOAD(&s[abc++])); SIMDBase_STOR(&cobraT[a2c++], SIMDBase_LOAD(&s[abc++]));
+ SIMDBase_STOR(&cobraT[a2c++], SIMDBase_LOAD(&s[abc++])); SIMDBase_STOR(&cobraT[a2c++], SIMDBase_LOAD(&s[abc++]));
+ SIMDBase_STOR(&cobraT[a2c++], SIMDBase_LOAD(&s[abc++])); SIMDBase_STOR(&cobraT[a2c++], SIMDBase_LOAD(&s[abc++]));
+ SIMDBase_STOR(&cobraT[a2c++], SIMDBase_LOAD(&s[abc++])); SIMDBase_STOR(&cobraT[a2c++], SIMDBase_LOAD(&s[abc++]));
+ SIMDBase_STOR(&cobraT[a2c++], SIMDBase_LOAD(&s[abc++])); SIMDBase_STOR(&cobraT[a2c++], SIMDBase_LOAD(&s[abc++]));
+ SIMDBase_STOR(&cobraT[a2c++], SIMDBase_LOAD(&s[abc++])); SIMDBase_STOR(&cobraT[a2c++], SIMDBase_LOAD(&s[abc++]));
+ SIMDBase_STOR(&cobraT[a2c++], SIMDBase_LOAD(&s[abc++])); SIMDBase_STOR(&cobraT[a2c++], SIMDBase_LOAD(&s[abc++]));
+ SIMDBase_STOR(&cobraT[a2c++], SIMDBase_LOAD(&s[abc++])); SIMDBase_STOR(&cobraT[a2c++], SIMDBase_LOAD(&s[abc++]));
+ SIMDBase_STOR(&cobraT[a2c++], SIMDBase_LOAD(&s[abc++])); SIMDBase_STOR(&cobraT[a2c++], SIMDBase_LOAD(&s[abc++]));
+ SIMDBase_STOR(&cobraT[a2c++], SIMDBase_LOAD(&s[abc++])); SIMDBase_STOR(&cobraT[a2c++], SIMDBase_LOAD(&s[abc++]));
+ SIMDBase_STOR(&cobraT[a2c++], SIMDBase_LOAD(&s[abc++])); SIMDBase_STOR(&cobraT[a2c++], SIMDBase_LOAD(&s[abc++]));
+ SIMDBase_STOR(&cobraT[a2c++], SIMDBase_LOAD(&s[abc++])); SIMDBase_STOR(&cobraT[a2c++], SIMDBase_LOAD(&s[abc++]));
+ }
+ }
+
+ for(c=0;c<(1 << cobraQ);c++) {
+ int c2 = cobraR[c];
+ int c2b2a2 = ((c2 << (logN-2*cobraQ)) | b2) << (cobraQ+1);
+
+ int a2c = c << 1;
+ int a2ci = 1 << (cobraQ+1);
+ int c2b2a2m = c2b2a2 + (1 << cobraQ)*2;
+
+ while(c2b2a2 < c2b2a2m) {
+ SIMDBase_VECT t0, t1, t2, t3, t4, t5, t6, t7;
+
+ t0 = SIMDBase_LOAD(&s[c2b2a2+0]); t1 = SIMDBase_LOAD(&s[c2b2a2+1]);
+ t2 = SIMDBase_LOAD(&s[c2b2a2+2]); t3 = SIMDBase_LOAD(&s[c2b2a2+3]);
+ t4 = SIMDBase_LOAD(&s[c2b2a2+4]); t5 = SIMDBase_LOAD(&s[c2b2a2+5]);
+ t6 = SIMDBase_LOAD(&s[c2b2a2+6]); t7 = SIMDBase_LOAD(&s[c2b2a2+7]);
+
+ SIMDBase_STOR(&s[c2b2a2++], SIMDBase_LOAD(&cobraT[a2c ])); SIMDBase_STOR(&cobraT[a2c ], t0);
+ SIMDBase_STOR(&s[c2b2a2++], SIMDBase_LOAD(&cobraT[a2c+1])); SIMDBase_STOR(&cobraT[a2c+1], t1); a2c += a2ci;
+ SIMDBase_STOR(&s[c2b2a2++], SIMDBase_LOAD(&cobraT[a2c ])); SIMDBase_STOR(&cobraT[a2c ], t2);
+ SIMDBase_STOR(&s[c2b2a2++], SIMDBase_LOAD(&cobraT[a2c+1])); SIMDBase_STOR(&cobraT[a2c+1], t3); a2c += a2ci;
+ SIMDBase_STOR(&s[c2b2a2++], SIMDBase_LOAD(&cobraT[a2c ])); SIMDBase_STOR(&cobraT[a2c ], t4);
+ SIMDBase_STOR(&s[c2b2a2++], SIMDBase_LOAD(&cobraT[a2c+1])); SIMDBase_STOR(&cobraT[a2c+1], t5); a2c += a2ci;
+ SIMDBase_STOR(&s[c2b2a2++], SIMDBase_LOAD(&cobraT[a2c ])); SIMDBase_STOR(&cobraT[a2c ], t6);
+ SIMDBase_STOR(&s[c2b2a2++], SIMDBase_LOAD(&cobraT[a2c+1])); SIMDBase_STOR(&cobraT[a2c+1], t7); a2c += a2ci;
+
+ t0 = SIMDBase_LOAD(&s[c2b2a2+0]); t1 = SIMDBase_LOAD(&s[c2b2a2+1]);
+ t2 = SIMDBase_LOAD(&s[c2b2a2+2]); t3 = SIMDBase_LOAD(&s[c2b2a2+3]);
+ t4 = SIMDBase_LOAD(&s[c2b2a2+4]); t5 = SIMDBase_LOAD(&s[c2b2a2+5]);
+ t6 = SIMDBase_LOAD(&s[c2b2a2+6]); t7 = SIMDBase_LOAD(&s[c2b2a2+7]);
+
+ SIMDBase_STOR(&s[c2b2a2++], SIMDBase_LOAD(&cobraT[a2c ])); SIMDBase_STOR(&cobraT[a2c ], t0);
+ SIMDBase_STOR(&s[c2b2a2++], SIMDBase_LOAD(&cobraT[a2c+1])); SIMDBase_STOR(&cobraT[a2c+1], t1); a2c += a2ci;
+ SIMDBase_STOR(&s[c2b2a2++], SIMDBase_LOAD(&cobraT[a2c ])); SIMDBase_STOR(&cobraT[a2c ], t2);
+ SIMDBase_STOR(&s[c2b2a2++], SIMDBase_LOAD(&cobraT[a2c+1])); SIMDBase_STOR(&cobraT[a2c+1], t3); a2c += a2ci;
+ SIMDBase_STOR(&s[c2b2a2++], SIMDBase_LOAD(&cobraT[a2c ])); SIMDBase_STOR(&cobraT[a2c ], t4);
+ SIMDBase_STOR(&s[c2b2a2++], SIMDBase_LOAD(&cobraT[a2c+1])); SIMDBase_STOR(&cobraT[a2c+1], t5); a2c += a2ci;
+ SIMDBase_STOR(&s[c2b2a2++], SIMDBase_LOAD(&cobraT[a2c ])); SIMDBase_STOR(&cobraT[a2c ], t6);
+ SIMDBase_STOR(&s[c2b2a2++], SIMDBase_LOAD(&cobraT[a2c+1])); SIMDBase_STOR(&cobraT[a2c+1], t7); a2c += a2ci;
+
+ t0 = SIMDBase_LOAD(&s[c2b2a2+0]); t1 = SIMDBase_LOAD(&s[c2b2a2+1]);
+ t2 = SIMDBase_LOAD(&s[c2b2a2+2]); t3 = SIMDBase_LOAD(&s[c2b2a2+3]);
+ t4 = SIMDBase_LOAD(&s[c2b2a2+4]); t5 = SIMDBase_LOAD(&s[c2b2a2+5]);
+ t6 = SIMDBase_LOAD(&s[c2b2a2+6]); t7 = SIMDBase_LOAD(&s[c2b2a2+7]);
+
+ SIMDBase_STOR(&s[c2b2a2++], SIMDBase_LOAD(&cobraT[a2c ])); SIMDBase_STOR(&cobraT[a2c ], t0);
+ SIMDBase_STOR(&s[c2b2a2++], SIMDBase_LOAD(&cobraT[a2c+1])); SIMDBase_STOR(&cobraT[a2c+1], t1); a2c += a2ci;
+ SIMDBase_STOR(&s[c2b2a2++], SIMDBase_LOAD(&cobraT[a2c ])); SIMDBase_STOR(&cobraT[a2c ], t2);
+ SIMDBase_STOR(&s[c2b2a2++], SIMDBase_LOAD(&cobraT[a2c+1])); SIMDBase_STOR(&cobraT[a2c+1], t3); a2c += a2ci;
+ SIMDBase_STOR(&s[c2b2a2++], SIMDBase_LOAD(&cobraT[a2c ])); SIMDBase_STOR(&cobraT[a2c ], t4);
+ SIMDBase_STOR(&s[c2b2a2++], SIMDBase_LOAD(&cobraT[a2c+1])); SIMDBase_STOR(&cobraT[a2c+1], t5); a2c += a2ci;
+ SIMDBase_STOR(&s[c2b2a2++], SIMDBase_LOAD(&cobraT[a2c ])); SIMDBase_STOR(&cobraT[a2c ], t6);
+ SIMDBase_STOR(&s[c2b2a2++], SIMDBase_LOAD(&cobraT[a2c+1])); SIMDBase_STOR(&cobraT[a2c+1], t7); a2c += a2ci;
+
+ t0 = SIMDBase_LOAD(&s[c2b2a2+0]); t1 = SIMDBase_LOAD(&s[c2b2a2+1]);
+ t2 = SIMDBase_LOAD(&s[c2b2a2+2]); t3 = SIMDBase_LOAD(&s[c2b2a2+3]);
+ t4 = SIMDBase_LOAD(&s[c2b2a2+4]); t5 = SIMDBase_LOAD(&s[c2b2a2+5]);
+ t6 = SIMDBase_LOAD(&s[c2b2a2+6]); t7 = SIMDBase_LOAD(&s[c2b2a2+7]);
+
+ SIMDBase_STOR(&s[c2b2a2++], SIMDBase_LOAD(&cobraT[a2c ])); SIMDBase_STOR(&cobraT[a2c ], t0);
+ SIMDBase_STOR(&s[c2b2a2++], SIMDBase_LOAD(&cobraT[a2c+1])); SIMDBase_STOR(&cobraT[a2c+1], t1); a2c += a2ci;
+ SIMDBase_STOR(&s[c2b2a2++], SIMDBase_LOAD(&cobraT[a2c ])); SIMDBase_STOR(&cobraT[a2c ], t2);
+ SIMDBase_STOR(&s[c2b2a2++], SIMDBase_LOAD(&cobraT[a2c+1])); SIMDBase_STOR(&cobraT[a2c+1], t3); a2c += a2ci;
+ SIMDBase_STOR(&s[c2b2a2++], SIMDBase_LOAD(&cobraT[a2c ])); SIMDBase_STOR(&cobraT[a2c ], t4);
+ SIMDBase_STOR(&s[c2b2a2++], SIMDBase_LOAD(&cobraT[a2c+1])); SIMDBase_STOR(&cobraT[a2c+1], t5); a2c += a2ci;
+ SIMDBase_STOR(&s[c2b2a2++], SIMDBase_LOAD(&cobraT[a2c ])); SIMDBase_STOR(&cobraT[a2c ], t6);
+ SIMDBase_STOR(&s[c2b2a2++], SIMDBase_LOAD(&cobraT[a2c+1])); SIMDBase_STOR(&cobraT[a2c+1], t7); a2c += a2ci;
+ }
+ }
+
+ for(a=0;a<(1 << cobraQ);a++) {
+ int a2c = (cobraR[a] << cobraQ) << 1, a2cm = a2c+(1 << cobraQ)*2;
+ int abc = ((a << (logN-2*cobraQ)) | b) << (cobraQ + 1);
+
+ while(a2c < a2cm) {
+ SIMDBase_STOR(&s[abc++], SIMDBase_LOAD(&cobraT[a2c++])); SIMDBase_STOR(&s[abc++], SIMDBase_LOAD(&cobraT[a2c++]));
+ SIMDBase_STOR(&s[abc++], SIMDBase_LOAD(&cobraT[a2c++])); SIMDBase_STOR(&s[abc++], SIMDBase_LOAD(&cobraT[a2c++]));
+ SIMDBase_STOR(&s[abc++], SIMDBase_LOAD(&cobraT[a2c++])); SIMDBase_STOR(&s[abc++], SIMDBase_LOAD(&cobraT[a2c++]));
+ SIMDBase_STOR(&s[abc++], SIMDBase_LOAD(&cobraT[a2c++])); SIMDBase_STOR(&s[abc++], SIMDBase_LOAD(&cobraT[a2c++]));
+ SIMDBase_STOR(&s[abc++], SIMDBase_LOAD(&cobraT[a2c++])); SIMDBase_STOR(&s[abc++], SIMDBase_LOAD(&cobraT[a2c++]));
+ SIMDBase_STOR(&s[abc++], SIMDBase_LOAD(&cobraT[a2c++])); SIMDBase_STOR(&s[abc++], SIMDBase_LOAD(&cobraT[a2c++]));
+ SIMDBase_STOR(&s[abc++], SIMDBase_LOAD(&cobraT[a2c++])); SIMDBase_STOR(&s[abc++], SIMDBase_LOAD(&cobraT[a2c++]));
+ SIMDBase_STOR(&s[abc++], SIMDBase_LOAD(&cobraT[a2c++])); SIMDBase_STOR(&s[abc++], SIMDBase_LOAD(&cobraT[a2c++]));
+ SIMDBase_STOR(&s[abc++], SIMDBase_LOAD(&cobraT[a2c++])); SIMDBase_STOR(&s[abc++], SIMDBase_LOAD(&cobraT[a2c++]));
+ SIMDBase_STOR(&s[abc++], SIMDBase_LOAD(&cobraT[a2c++])); SIMDBase_STOR(&s[abc++], SIMDBase_LOAD(&cobraT[a2c++]));
+ SIMDBase_STOR(&s[abc++], SIMDBase_LOAD(&cobraT[a2c++])); SIMDBase_STOR(&s[abc++], SIMDBase_LOAD(&cobraT[a2c++]));
+ SIMDBase_STOR(&s[abc++], SIMDBase_LOAD(&cobraT[a2c++])); SIMDBase_STOR(&s[abc++], SIMDBase_LOAD(&cobraT[a2c++]));
+ SIMDBase_STOR(&s[abc++], SIMDBase_LOAD(&cobraT[a2c++])); SIMDBase_STOR(&s[abc++], SIMDBase_LOAD(&cobraT[a2c++]));
+ SIMDBase_STOR(&s[abc++], SIMDBase_LOAD(&cobraT[a2c++])); SIMDBase_STOR(&s[abc++], SIMDBase_LOAD(&cobraT[a2c++]));
+ SIMDBase_STOR(&s[abc++], SIMDBase_LOAD(&cobraT[a2c++])); SIMDBase_STOR(&s[abc++], SIMDBase_LOAD(&cobraT[a2c++]));
+ SIMDBase_STOR(&s[abc++], SIMDBase_LOAD(&cobraT[a2c++])); SIMDBase_STOR(&s[abc++], SIMDBase_LOAD(&cobraT[a2c++]));
+ }
+ }
+ }
+ }
+}
+
+//
+
+static void srForwardMain2(DFTUndiff *p) {
+ int32_t o = p->offset1;
+ int32_t butlen = p->butlen;
+ int32_t log2butlen = p->log2butlen;
+
+ if (butlen >= p->radix2thres) {
+ p->stride = p->butlen/2;
+ r2ButForwardSub(p);
+
+ p->offset1 = o + butlen*4/4;
+ p->butlen = butlen/2;
+ p->log2butlen = log2butlen-1;
+ srForwardMain2(p);
+
+ p->offset1 = o;
+ p->butlen = butlen/2;
+ p->log2butlen = log2butlen-1;
+ srForwardMain2(p);
+
+ return;
+ }
+
+ if (butlen >= 256) {
+ p->stride = p->butlen/2;
+ srButForwardSubUnrolled(p);
+
+ p->offset1 = o + butlen*6/4;
+ p->butlen = butlen/4;
+ p->log2butlen = log2butlen-2;
+ srForwardMain2(p);
+
+ p->offset1 = o + butlen*4/4;
+ p->butlen = butlen/4;
+ p->log2butlen = log2butlen-2;
+ srForwardMain2(p);
+
+ p->offset1 = o;
+ p->butlen = butlen/2;
+ p->log2butlen = log2butlen-1;
+ srForwardMain2(p);
+
+ return;
+ }
+
+ if (butlen == 128) {
+ p->stride = p->butlen/2;
+ srButForwardSubUnrolled(p);
+
+ p->offset1 = o + butlen*6/4;
+ srButForward32(p);
+
+ p->offset1 = o + butlen*4/4;
+ srButForward32(p);
+
+ p->offset1 = o;
+ p->butlen = butlen/2;
+ p->log2butlen = log2butlen-1;
+ srForwardMain2 (p);
+
+ return;
+ }
+
+ // butlen == 64
+
+ p->stride = p->butlen/2;
+ srButForwardSubUnrolled(p);
+
+ p->offset1 = o + butlen*6/4;
+ srButForward16(p);
+
+ p->offset1 = o + butlen*4/4;
+ srButForward16(p);
+
+ p->offset1 = o;
+ srButForward32(p);
+}
+
+static void srBackwardMain2(DFTUndiff *p) {
+ int32_t o = p->offset1;
+ int32_t butlen = p->butlen;
+ int32_t log2butlen = p->log2butlen;
+
+ if (butlen >= p->radix2thres) {
+ p->offset1 = o + butlen*4/4;
+ p->butlen = butlen/2;
+ p->log2butlen = log2butlen-1;
+ srBackwardMain2(p);
+
+ p->offset1 = o;
+ p->butlen = butlen/2;
+ p->log2butlen = log2butlen-1;
+ srBackwardMain2(p);
+
+ p->butlen = butlen;
+ p->stride = p->butlen/2;
+ p->log2butlen = log2butlen;
+ r2ButBackwardSub(p);
+
+ return;
+ }
+
+ if (butlen >= 256) {
+ p->offset1 = o + butlen*6/4;
+ p->butlen = butlen/4;
+ p->log2butlen = log2butlen-2;
+ srBackwardMain2(p);
+
+ p->offset1 = o + butlen*4/4;
+ p->butlen = butlen/4;
+ p->log2butlen = log2butlen-2;
+ srBackwardMain2(p);
+
+ p->offset1 = o;
+ p->butlen = butlen/2;
+ p->log2butlen = log2butlen-1;
+ srBackwardMain2(p);
+
+ p->butlen = butlen;
+ p->stride = p->butlen/2;
+ p->log2butlen = log2butlen;
+ srButBackwardSubUnrolled(p);
+
+ return;
+ }
+
+ if (butlen == 128) {
+ p->offset1 = o + butlen*6/4;
+ srButBackward32(p);
+
+ p->offset1 = o + butlen*4/4;
+ srButBackward32(p);
+
+ p->offset1 = o;
+ p->butlen = butlen/2;
+ p->log2butlen = log2butlen-1;
+ srBackwardMain2 (p);
+
+ p->butlen = butlen;
+ p->stride = p->butlen/2;
+ p->log2butlen = log2butlen;
+ srButBackwardSubUnrolled(p);
+
+ return;
+ }
+
+ // butlen == 64
+
+ p->offset1 = o + butlen*6/4;
+ srButBackward16(p);
+
+ p->offset1 = o + butlen*4/4;
+ srButBackward16(p);
+
+ p->offset1 = o;
+ srButBackward32(p);
+
+ p->butlen = butlen;
+ p->stride = p->butlen/2;
+ p->log2butlen = log2butlen;
+ srButBackwardSubUnrolled(p);
+}
+
+static void srForwardMain(DFTUndiff *p) {
+ if (p->length >= 64) {
+ p->butlen = p->length;
+ p->log2butlen = p->log2len;
+ p->offset1 = p->offset2 = 0;
+
+ srForwardMain2(p);
+ } else {
+ switch(p->length) {
+ case 32:
+ srButForward32(p);
+ break;
+ case 16:
+ srButForward16(p);
+ break;
+ case 8:
+ srButForward8(p);
+ break;
+ case 4:
+ srButForward4(p);
+ break;
+ case 2:
+ srBut2(p);
+ break;
+ }
+ }
+}
+
+static void srBackwardMain(DFTUndiff *p) {
+ if (p->length >= 64) {
+ p->butlen = p->length;
+ p->log2butlen = p->log2len;
+ p->offset1 = p->offset2 = 0;
+
+ srBackwardMain2(p);
+ } else {
+ switch(p->length) {
+ case 32:
+ srButBackward32(p);
+ break;
+ case 16:
+ srButBackward16(p);
+ break;
+ case 8:
+ srButBackward8(p);
+ break;
+ case 4:
+ srButBackward4(p);
+ break;
+ case 2:
+ srBut2(p);
+ break;
+ }
+ }
+}
+
+static void realSub0(DFTUndiff *p, SIMDBase_VECT *s, int32_t ts) {
+ SIMDBase_VECT tr, ti, ur, ui, mr, mi;
+ int32_t n = p->length*2;
+ int32_t k;
+
+ for(k=1;k<n/4;k++) {
+ SIMDBase_VECT s00 = SIMDBase_LOAD(&s[k*2+0]), s01 = SIMDBase_LOAD(&s[k*2+1]);
+ SIMDBase_VECT s10 = SIMDBase_LOAD(&s[(n/2-k)*2+0]), s11 = SIMDBase_LOAD(&s[(n/2-k)*2+1]);
+
+ tr = SIMDBase_SUBi(s00, s10); ti = SIMDBase_ADDi(s01, s11);
+ ur = SIMDBase_LOAD1(&(p->rtTable[ts][k*2+0]));
+ ui = SIMDBase_LOAD1(&(p->rtTable[ts][k*2+1]));
+ mr = SIMDBase_SUBi(SIMDBase_MULi(tr, ur), SIMDBase_MULi(ti, ui));
+ mi = SIMDBase_ADDi(SIMDBase_MULi(tr, ui), SIMDBase_MULi(ti, ur));
+ SIMDBase_STOR(&s[k*2+0], SIMDBase_SUBi(s00, mr));
+ SIMDBase_STOR(&s[k*2+1], SIMDBase_SUBi(s01, mi));
+ SIMDBase_STOR(&s[(n/2-k)*2+0], SIMDBase_ADDi(s10, mr));
+ SIMDBase_STOR(&s[(n/2-k)*2+1], SIMDBase_SUBi(s11, mi));
+ }
+
+ tr = SIMDBase_LOAD(&s[0]); ti = SIMDBase_LOAD(&s[1]);
+ SIMDBase_STOR(&s[0], SIMDBase_ADDi(tr, ti));
+ SIMDBase_STOR(&s[1], SIMDBase_SUBi(tr, ti));
+}
+
+static void realSub1(DFTUndiff *p, SIMDBase_VECT *s, int32_t ts) {
+ SIMDBase_VECT tr, ti, ur, ui, mr, mi;
+ int32_t n = p->length*2;
+ int32_t k;
+
+ tr = SIMDBase_LOAD(&s[0]); ti = SIMDBase_LOAD(&s[1]);
+ SIMDBase_STOR(&s[0], SIMDBase_MULi(SIMDBase_ADDi(tr, ti), SIMDBase_SET1(0.5)));
+ SIMDBase_STOR(&s[1], SIMDBase_MULi(SIMDBase_SUBi(tr, ti), SIMDBase_SET1(0.5)));
+
+ for(k=1;k<n/4;k++) {
+ SIMDBase_VECT s00 = SIMDBase_LOAD(&s[k*2+0]), s01 = SIMDBase_LOAD(&s[k*2+1]);
+ SIMDBase_VECT s10 = SIMDBase_LOAD(&s[(n/2-k)*2+0]), s11 = SIMDBase_LOAD(&s[(n/2-k)*2+1]);
+
+ tr = SIMDBase_SUBi(s00, s10); ti = SIMDBase_ADDi(s01, s11);
+ ur = SIMDBase_LOAD1(&(p->rtTable[ts][k*2+0]));
+ ui = SIMDBase_LOAD1(&(p->rtTable[ts][k*2+1]));
+ mr = SIMDBase_SUBi(SIMDBase_MULi(tr, ur), SIMDBase_MULi(ti, ui));
+ mi = SIMDBase_ADDi(SIMDBase_MULi(tr, ui), SIMDBase_MULi(ti, ur));
+ tr = SIMDBase_SUBi(s00, mr); ti = SIMDBase_SUBi(mi, s01);
+ SIMDBase_STOR(&s[k*2+0], SIMDBase_ADDi(mr, s10));
+ SIMDBase_STOR(&s[k*2+1], SIMDBase_SUBi(mi, s11));
+ SIMDBase_STOR(&s[(n/2-k)*2+0], tr);
+ SIMDBase_STOR(&s[(n/2-k)*2+1], ti);
+ }
+}
+
+void DFTUndiff_EXECUTE(void *p2, void *s2, int32_t dir) {
+ DFTUndiff *p = (DFTUndiff *)p2;
+ SIMDBase_VECT *s = (SIMDBase_VECT *)s2;
+
+ if (p->magic != MAGIC_DFT) abort();
+
+ p->s = s;
+
+ if (dir == -1) {
+ if ((p->flags & DFT_FLAG_ALT_REAL) != 0) {
+ realSub1(p, s, 0);
+ }
+
+ srForwardMain(p);
+
+ if ((p->flags & DFT_FLAG_NO_BITREVERSAL) == 0) {
+ if (p->useCobra) {
+ bitReversalCobraInplace(p);
+ } else {
+ bitReversalRecursive(p->s, p->length, 1, 0, 0);
+ }
+ }
+
+ if ((p->flags & DFT_FLAG_REAL) != 0) {
+ realSub0(p, s, 0);
+ s[p->length+1] = SIMDBase_NEGi(s[p->length+1]);
+ }
+ } else {
+ if ((p->flags & DFT_FLAG_REAL) != 0) {
+ s[p->length+1] = SIMDBase_NEGi(s[p->length+1]);
+ realSub1(p, s, 1);
+ }
+
+ if ((p->flags & DFT_FLAG_NO_BITREVERSAL) == 0) {
+ if (p->useCobra) {
+ bitReversalCobraInplace(p);
+ } else {
+ bitReversalRecursive(p->s, p->length, 1, 0, 0);
+ }
+ }
+
+ srBackwardMain(p);
+
+ if ((p->flags & DFT_FLAG_ALT_REAL) != 0) {
+ realSub0(p, s, 1);
+ }
+ }
+}
+
+void DFTUndiff_DESTROYPLAN(void *p2) {
+ DFTUndiff *plan = (DFTUndiff *)p2;
+ if (plan->magic != MAGIC_DFT) abort();
+
+ free(*(plan->ptTable));
+ free(plan->ptTable);
+ free(plan->cobraT);
+ free(plan->cobraR);
+ //free(plan->t);
+ if (plan->rtTable != NULL) {
+ free(plan->rtTable[0]);
+ free(plan->rtTable[1]);
+ free(plan->rtTable);
+ }
+
+ plan->magic = 0;
+ free(plan);
+}
+
+DFTUndiff *DFTUndiff_MAKEPLANSUB(uint64_t n, int32_t radix2thres, int32_t useCobra, uint64_t flags) {
+ int32_t i, j, k;
+
+ uint32_t linesize = SIMDBase_sizeOfCachelineInByte();
+ uint32_t cachesize = SIMDBase_sizeOfDataCacheInByte();
+
+ //
+
+ if ((flags & DFT_FLAG_REAL) != 0 || (flags & DFT_FLAG_ALT_REAL) != 0) n /= 2;
+
+ DFTUndiff *d = calloc(1, sizeof(DFTUndiff));
+
+ d->magic = MAGIC_DFT;
+ d->mode = SIMDBase_MODE;
+ d->flags = flags;
+
+ d->radix2thres = radix2thres;
+ d->useCobra = useCobra;
+
+ d->length = (uint32_t) n;
+ d->log2len = DFT_ilog2((uint32_t) n);
+
+ //
+
+ SIMDBase_REAL *trigTable = SIMDBase_alignedMalloc(sizeof(SIMDBase_REAL)*n*2);
+ d->ptTable = malloc(sizeof(SIMDBase_REAL *) * (d->log2len+1));
+
+ SIMDBase_REAL *p = trigTable, **pp = d->ptTable;
+
+ for(j=0;j<(int32_t)d->log2len+1;j++) {
+ *pp++ = p;
+
+ if ((1 << j) >= d->radix2thres) {
+ for(i=0;i<(1 << j)/4+1;i++) {
+ *p++ = (SIMDBase_REAL)COS(-2*M_PIl*i/(1 << j));
+ }
+ const int32_t step = linesize / sizeof(SIMDBase_REAL);
+ p += (step - (p - trigTable) % step) % step;
+ } else {
+ for(i=0;i<(1 << j)/4;i++) {
+ *p++ = (SIMDBase_REAL)COS(-2*M_PIl*i/(1 << j));
+ *p++ = (SIMDBase_REAL)SIN(-2*M_PIl*i/(1 << j));
+ *p++ = (SIMDBase_REAL)COS(-6*M_PIl*i/(1 << j));
+ *p++ = (SIMDBase_REAL)SIN(-6*M_PIl*i/(1 << j));
+ }
+ }
+ }
+
+ //
+
+ int32_t cobraQ;
+
+ cobraQ = linesize / (sizeof(SIMDBase_VECT) * 2);
+
+ for(;;) {
+ if (1 << (cobraQ*2) >
+ (cachesize / (sizeof(SIMDBase_VECT) * 2)/2))
+ break;
+
+ cobraQ++;
+ }
+ cobraQ--;
+
+ d->cobraQ = cobraQ;
+
+ if (cobraQ >= 4 && d->log2len >= 2*cobraQ) {
+ SIMDBase_VECT *cobraT;
+ int32_t *cobraR;
+
+ if (d->log2len <= 2*cobraQ) cobraQ = d->log2len / 2;
+
+ cobraT = SIMDBase_alignedMalloc(sizeof(SIMDBase_VECT)*2 * (1 << (cobraQ*2)));
+ cobraR = (int32_t *)SIMDBase_alignedMalloc(sizeof(int32_t) * (1 << cobraQ));
+
+ for(i=0;i<(1 << cobraQ);i++) cobraR[i] = bitR(i, cobraQ);
+
+ d->cobraT = cobraT; d->cobraR = cobraR;
+ } else {
+ d->useCobra = 0;
+ }
+
+ //
+
+ if ((d->flags & DFT_FLAG_REAL) != 0 || (d->flags & DFT_FLAG_ALT_REAL) != 0) {
+ int32_t m = n*2;
+
+ d->rtTable = malloc(sizeof(SIMDBase_REAL *)*2);
+ d->rtTable[0] = SIMDBase_alignedMalloc(sizeof(SIMDBase_REAL)*m/2);
+ d->rtTable[1] = SIMDBase_alignedMalloc(sizeof(SIMDBase_REAL)*m/2);
+
+ for(k=0;k<m/4;k++) {
+ d->rtTable[0][k*2+0] = 0.5-0.5*SIN(-2*M_PIl*k/m);
+ d->rtTable[0][k*2+1] = 0.5*COS(-2*M_PIl*k/m);
+ d->rtTable[1][k*2+0] = 0.5-0.5*SIN( 2*M_PIl*k/m);
+ d->rtTable[1][k*2+1] = 0.5*COS( 2*M_PIl*k/m);
+ }
+ }
+
+ //
+
+ return (void *)d;
+}
+
+void *DFTUndiff_MAKEPLAN(uint64_t n, uint64_t flags) {
+ if (flags & DFT_FLAG_VERBOSE) {
+ printf("\n--------------------------------\n");
+ printf("Making plan, mode = %s, dft length = %d\n", SIMDBase_NAME, (int)n);
+ printf("Processor : %s\n", SIMDBase_getProcessorNameString());
+ printf("Cache size (L2 + L3) : %d kbytes / thread\n", SIMDBase_sizeOfDataCacheInByte() / 1024);
+ printf("Cache Line Size : %d bytes\n", SIMDBase_sizeOfCachelineInByte());
+ }
+
+ if (n <= 256 || (flags & 3) == 0) {
+ return DFTUndiff_MAKEPLANSUB(n, n*2, (flags & DFT_FLAG_FORCE_COBRA) != 0, flags);
+ }
+
+ SIMDBase_REAL *s1 = SIMDBase_alignedMalloc(sizeof(SIMDBase_VECT)*n*2);
+
+ int32_t i, j, ts, tsbest, useCobra = 0;
+ double tick, tickmin;
+
+ if (flags & DFT_FLAG_VERBOSE) {
+ printf("\nWarming up before calibration ...");
+ fflush(stdout);
+ }
+
+ // warming up
+ tick = DFT_timeofday();
+ while(DFT_timeofday() - tick < 0.5)
+ ;
+
+ if (flags & DFT_FLAG_VERBOSE) {
+ printf(" done\n");
+ }
+
+ int32_t ntimes = 20000000.0 / n / DFT_ilog2(n);
+ if (ntimes == 0) ntimes = 1;
+
+ if (flags & DFT_FLAG_VERBOSE) {
+ printf("nTimes = %d\n", ntimes);
+ }
+
+ //
+
+ DFTUndiff *plan = DFTUndiff_MAKEPLANSUB(n, n*2, 0, flags);
+
+ for(i=0;i<n*2*SIMDBase_VECTLEN;i++) {
+ s1[i] = 0;
+ }
+
+ plan->s = (SIMDBase_VECT *)s1;
+
+ if (plan->cobraT != NULL) {
+ double tcobra = 0, trecur = 0;
+
+ if (flags & DFT_FLAG_VERBOSE) {
+ printf("\nChecking which bit-reversal method is faster\n");
+ }
+
+ //
+
+ bitReversalCobraInplace(plan);
+
+ tick = DFT_timeofday();
+
+ for(j=0;j<ntimes*4;j++) {
+ bitReversalCobraInplace(plan);
+ }
+
+ tcobra += DFT_timeofday() - tick;
+
+ //
+
+ bitReversalRecursive(plan->s, plan->length, 1, 0, 0);
+
+ tick = DFT_timeofday();
+
+ for(j=0;j<ntimes*4;j++) {
+ bitReversalRecursive(plan->s, plan->length, 1, 0, 0);
+ }
+
+ trecur += DFT_timeofday() - tick;
+
+ //
+
+ bitReversalCobraInplace(plan);
+
+ tick = DFT_timeofday();
+
+ for(j=0;j<ntimes*4;j++) {
+ bitReversalCobraInplace(plan);
+ }
+
+ tcobra += DFT_timeofday() - tick;
+
+ //
+
+ bitReversalRecursive(plan->s, plan->length, 1, 0, 0);
+
+ tick = DFT_timeofday();
+
+ for(j=0;j<ntimes*4;j++) {
+ bitReversalRecursive(plan->s, plan->length, 1, 0, 0);
+ }
+
+ trecur += DFT_timeofday() - tick;
+
+ //
+
+ useCobra = tcobra < trecur;
+
+ if ((flags & DFT_FLAG_FORCE_RECURSIVE) != 0) useCobra = 0;
+ if ((flags & DFT_FLAG_FORCE_COBRA) != 0) useCobra = 1;
+
+ if (flags & DFT_FLAG_VERBOSE) {
+ printf("cobra : %g\n", tcobra);
+ printf("recur : %g\n", trecur);
+ if (useCobra) {
+ printf("will use Cobra\n");
+ } else {
+ printf("will use the recursive reverser\n");
+ }
+ }
+ }
+
+ DFTUndiff_DESTROYPLAN(plan);
+
+ //
+
+ if (flags & DFT_FLAG_VERBOSE) {
+ printf("\nDetermining radix 2 threshold\n");
+ }
+
+ plan = DFTUndiff_MAKEPLANSUB(n, n*2, useCobra, flags);
+
+ for(j=0;j<ntimes;j++) {
+ DFTUndiff_EXECUTE(plan, s1, -1);
+ DFTUndiff_EXECUTE(plan, s1, 1);
+ }
+
+ DFTUndiff_DESTROYPLAN(plan);
+
+ tsbest = -1;
+ tickmin = 0;
+
+ for(ts = 1024;ts <= n*2;ts *= 2) {
+ plan = DFTUndiff_MAKEPLANSUB(n, ts, useCobra, flags);
+
+ tick = DFT_timeofday();
+
+ for(j=0;j<ntimes;j++) {
+ DFTUndiff_EXECUTE(plan, s1, -1);
+ DFTUndiff_EXECUTE(plan, s1, 1);
+ }
+
+ tick = DFT_timeofday() - tick;
+
+ DFTUndiff_DESTROYPLAN(plan);
+
+ if (tickmin == 0) tickmin = tick;
+
+ if (flags & DFT_FLAG_VERBOSE) {
+ printf("%d : %g\n",ts, (double)tick);
+ }
+
+ if (tick < tickmin) {
+ tickmin = tick;
+ tsbest = ts;
+ }
+ }
+
+ if (tsbest == -1) tsbest = n*2;;
+
+ if (flags & DFT_FLAG_VERBOSE) {
+ //printf("forcing tsbest = 1024\n");
+ //tsbest = 1024;
+ printf("radix 2 threshold : %d\n\n", tsbest);
+
+ double t = tickmin / ntimes / 2;
+ double nf = 5 * n * log(n) / log(2) / (t * 1000000);
+
+ printf("nFlops = %d x %g\n", SIMDBase_VECTLEN, nf);
+ }
+
+ plan = DFTUndiff_MAKEPLANSUB(n, tsbest, useCobra, flags);
+
+ if (flags & DFT_FLAG_VERBOSE) {
+ printf("\nDone making plan\n--------------------------------\n");
+ }
+
+ return plan;
+}
diff --git a/plugins/supereq/nsfft-1.00/dft/DFTUndiff.h b/plugins/supereq/nsfft-1.00/dft/DFTUndiff.h
new file mode 100644
index 00000000..d26b0d9b
--- /dev/null
+++ b/plugins/supereq/nsfft-1.00/dft/DFTUndiff.h
@@ -0,0 +1,114 @@
+#ifndef __DFTIMPL_H__
+#define __DFTIMPL_H__
+
+#include "SIMDBaseUndiff.h"
+
+#define MAGIC_DFT 0x18839f6d82bb02b6ULL
+
+typedef struct {
+ uint64_t magic;
+
+ SIMDBase_VECT *s;
+ uint32_t offset1, offset2;
+ uint32_t butlen, log2butlen;
+ uint32_t stride;
+
+ SIMDBase_REAL **ptTable;
+ uint32_t length, log2len;
+
+ int32_t radix2thres, flagTrans, useCobra;
+
+ int32_t cobraQ;
+ SIMDBase_VECT *cobraT;
+ int32_t *cobraR;
+
+ SIMDBase_REAL **rtTable;
+
+ uint64_t flags;
+ int32_t mode;
+} DFTUndiff;
+
+#if defined(ENABLE_PUREC_FLOAT) ////////////////////////////////////////////
+
+#define DFTUndiff_GETMODEPARAMINT getModeParamInt_purec_float
+#define DFTUndiff_GETMODEPARAMSTRING getModeParamString_purec_float
+#define DFTUndiff_EXECUTE execute_purec_float
+#define DFTUndiff_MAKEPLAN makePlan_purec_float
+#define DFTUndiff_MAKEPLANSUB makePlanSub_purec_float
+#define DFTUndiff_DESTROYPLAN destroyPlan_purec_float
+
+#elif defined(ENABLE_PUREC_DOUBLE) ////////////////////////////////////////////
+
+#define DFTUndiff_GETMODEPARAMINT getModeParamInt_purec_double
+#define DFTUndiff_GETMODEPARAMSTRING getModeParamString_purec_double
+#define DFTUndiff_EXECUTE execute_purec_double
+#define DFTUndiff_MAKEPLAN makePlan_purec_double
+#define DFTUndiff_MAKEPLANSUB makePlanSub_purec_double
+#define DFTUndiff_DESTROYPLAN destroyPlan_purec_double
+
+#elif defined(ENABLE_PUREC_LONGDOUBLE) ////////////////////////////////////////////
+
+#define DFTUndiff_GETMODEPARAMINT getModeParamInt_purec_longdouble
+#define DFTUndiff_GETMODEPARAMSTRING getModeParamString_purec_longdouble
+#define DFTUndiff_EXECUTE execute_purec_longdouble
+#define DFTUndiff_MAKEPLAN makePlan_purec_longdouble
+#define DFTUndiff_MAKEPLANSUB makePlanSub_purec_longdouble
+#define DFTUndiff_DESTROYPLAN destroyPlan_purec_longdouble
+
+#elif defined(ENABLE_SSE_FLOAT) ////////////////////////////////////////////
+
+#define DFTUndiff_GETMODEPARAMINT getModeParamInt_sse_float
+#define DFTUndiff_GETMODEPARAMSTRING getModeParamString_sse_float
+#define DFTUndiff_EXECUTE execute_sse_float
+#define DFTUndiff_MAKEPLAN makePlan_sse_float
+#define DFTUndiff_MAKEPLANSUB makePlanSub_sse_float
+#define DFTUndiff_DESTROYPLAN destroyPlan_sse_float
+
+#elif defined(ENABLE_SSE2_DOUBLE) ////////////////////////////////////////////
+
+#define DFTUndiff_GETMODEPARAMINT getModeParamInt_sse2_double
+#define DFTUndiff_GETMODEPARAMSTRING getModeParamString_sse2_double
+#define DFTUndiff_EXECUTE execute_sse2_double
+#define DFTUndiff_MAKEPLAN makePlan_sse2_double
+#define DFTUndiff_MAKEPLANSUB makePlanSub_sse2_double
+#define DFTUndiff_DESTROYPLAN destroyPlan_sse2_double
+
+#elif defined(ENABLE_NEON_FLOAT) ////////////////////////////////////////////
+
+#define DFTUndiff_GETMODEPARAMINT getModeParamInt_neon_float
+#define DFTUndiff_GETMODEPARAMSTRING getModeParamString_neon_float
+#define DFTUndiff_EXECUTE execute_neon_float
+#define DFTUndiff_MAKEPLAN makePlan_neon_float
+#define DFTUndiff_MAKEPLANSUB makePlanSub_neon_float
+#define DFTUndiff_DESTROYPLAN destroyPlan_neon_float
+
+#elif defined(ENABLE_AVX_FLOAT) ////////////////////////////////////////////
+
+#define DFTUndiff_GETMODEPARAMINT getModeParamInt_avx_float
+#define DFTUndiff_GETMODEPARAMSTRING getModeParamString_avx_float
+#define DFTUndiff_EXECUTE execute_avx_float
+#define DFTUndiff_MAKEPLAN makePlan_avx_float
+#define DFTUndiff_MAKEPLANSUB makePlanSub_avx_float
+#define DFTUndiff_DESTROYPLAN destroyPlan_avx_float
+
+#elif defined(ENABLE_AVX_DOUBLE) ////////////////////////////////////////////
+
+#define DFTUndiff_GETMODEPARAMINT getModeParamInt_avx_double
+#define DFTUndiff_GETMODEPARAMSTRING getModeParamString_avx_double
+#define DFTUndiff_EXECUTE execute_avx_double
+#define DFTUndiff_MAKEPLAN makePlan_avx_double
+#define DFTUndiff_MAKEPLANSUB makePlanSub_avx_double
+#define DFTUndiff_DESTROYPLAN destroyPlan_avx_double
+
+#elif defined(ENABLE_ALTIVEC_FLOAT) ////////////////////////////////////////////
+
+#define DFTUndiff_GETMODEPARAMINT getModeParamInt_altivec_float
+#define DFTUndiff_GETMODEPARAMSTRING getModeParamString_altivec_float
+#define DFTUndiff_EXECUTE execute_altivec_float
+#define DFTUndiff_MAKEPLAN makePlan_altivec_float
+#define DFTUndiff_MAKEPLANSUB makePlanSub_altivec_float
+#define DFTUndiff_DESTROYPLAN destroyPlan_altivec_float
+
+#endif ////////////////////////////////////////////////////////////////////
+
+#endif
diff --git a/plugins/supereq/nsfft-1.00/dft/Makefile b/plugins/supereq/nsfft-1.00/dft/Makefile
new file mode 120000
index 00000000..fc484116
--- /dev/null
+++ b/plugins/supereq/nsfft-1.00/dft/Makefile
@@ -0,0 +1 @@
+Makefile.x86 \ No newline at end of file
diff --git a/plugins/supereq/nsfft-1.00/dft/Makefile.altivec b/plugins/supereq/nsfft-1.00/dft/Makefile.altivec
new file mode 100644
index 00000000..fe7fc993
--- /dev/null
+++ b/plugins/supereq/nsfft-1.00/dft/Makefile.altivec
@@ -0,0 +1,26 @@
+CC=gcc
+BASEOPT=-Wall -I ../simd -maltivec -mabi=altivec
+OPT=$(BASEOPT) -O3
+
+all : libDFT.a
+
+DFTpurecfloat.o : DFTUndiff.c DFT.h ../simd/SIMDBase.h ../simd/SIMDBaseUndiff.h
+ $(CC) $(OPT) -DENABLE_PUREC_FLOAT DFTUndiff.c -c -o DFTpurecfloat.o
+
+DFTpurecdouble.o : DFTUndiff.c DFT.h ../simd/SIMDBase.h ../simd/SIMDBaseUndiff.h
+ $(CC) $(OPT) -DENABLE_PUREC_DOUBLE DFTUndiff.c -c -o DFTpurecdouble.o
+
+DFTpureclongdouble.o : DFTUndiff.c DFT.h ../simd/SIMDBase.h ../simd/SIMDBaseUndiff.h
+ $(CC) $(OPT) -DENABLE_PUREC_LONGDOUBLE DFTUndiff.c -c -o DFTpureclongdouble.o
+
+DFTaltivecfloat.o : DFTUndiff.c DFT.h ../simd/SIMDBase.h ../simd/SIMDBaseUndiff.h
+ $(CC) $(OPT) -DENABLE_ALTIVEC_FLOAT DFTUndiff.c -c -o DFTaltivecfloat.o
+
+DFT.o : DFT.c DFT.h
+ $(CC) $(OPT) -DENABLE_PUREC_FLOAT -DENABLE_PUREC_DOUBLE -DENABLE_PUREC_LONGDOUBLE -DENABLE_ALTIVEC_FLOAT DFT.c -c -o DFT.o
+
+libDFT.a : DFTpurecfloat.o DFTpurecdouble.o DFTpureclongdouble.o DFTaltivecfloat.o DFT.o
+ rm -f libDFT.a; ar -cvq libDFT.a DFTpurecfloat.o DFTpurecdouble.o DFTpureclongdouble.o DFTaltivecfloat.o DFT.o
+
+clean :
+ rm -f *~ *.o *.s *.a
diff --git a/plugins/supereq/nsfft-1.00/dft/Makefile.neon b/plugins/supereq/nsfft-1.00/dft/Makefile.neon
new file mode 100644
index 00000000..111a04ae
--- /dev/null
+++ b/plugins/supereq/nsfft-1.00/dft/Makefile.neon
@@ -0,0 +1,26 @@
+CC=gcc
+BASEOPT=-Wall -I ../simd -mfloat-abi=softfp
+OPT=$(BASEOPT) -O3
+
+all : libDFT.a
+
+DFTpurecfloat.o : DFTUndiff.c DFT.h ../simd/SIMDBase.h
+ $(CC) $(OPT) -DENABLE_PUREC_FLOAT DFTUndiff.c -c -o DFTpurecfloat.o
+
+DFTpurecdouble.o : DFTUndiff.c DFT.h ../simd/SIMDBase.h
+ $(CC) $(OPT) -DENABLE_PUREC_DOUBLE DFTUndiff.c -c -o DFTpurecdouble.o
+
+DFTpureclongdouble.o : DFTUndiff.c DFT.h ../simd/SIMDBase.h
+ $(CC) $(OPT) -DENABLE_PUREC_LONGDOUBLE DFTUndiff.c -c -o DFTpureclongdouble.o
+
+DFTneonfloat.o : DFTUndiff.c DFT.h ../simd/SIMDBase.h
+ $(CC) $(OPT) -mfpu=neon -DENABLE_NEON_FLOAT DFTUndiff.c -c -o DFTneonfloat.o
+
+DFT.o : DFT.c DFT.h
+ $(CC) $(OPT) -DENABLE_PUREC_FLOAT -DENABLE_PUREC_DOUBLE -DENABLE_PUREC_LONGDOUBLE -DENABLE_NEON_FLOAT DFT.c -c -o DFT.o
+
+libDFT.a : DFTpurecfloat.o DFTpurecdouble.o DFTpureclongdouble.o DFTneonfloat.o DFT.o
+ rm -f libDFT.a; ar -cvq libDFT.a DFTpurecfloat.o DFTpurecdouble.o DFTpureclongdouble.o DFTneonfloat.o DFT.o
+
+clean :
+ rm -f *~ *.o *.s *.a
diff --git a/plugins/supereq/nsfft-1.00/dft/Makefile.purec b/plugins/supereq/nsfft-1.00/dft/Makefile.purec
new file mode 100644
index 00000000..2c8b04f1
--- /dev/null
+++ b/plugins/supereq/nsfft-1.00/dft/Makefile.purec
@@ -0,0 +1,35 @@
+CC=gcc
+BASEOPT=-Wall
+OPT=$(BASEOPT) -O3
+
+all : libDFT.a
+
+DFTpurecfloat.o : DFTUndiff.c DFT.h SIMDBase.h
+ $(CC) $(OPT) -DENABLE_PUREC_FLOAT DFTUndiff.c -c -o DFTpurecfloat.o
+
+DFTpurecdouble.o : DFTUndiff.c DFT.h SIMDBase.h
+ $(CC) $(OPT) -DENABLE_PUREC_DOUBLE DFTUndiff.c -c -o DFTpurecdouble.o
+
+DFTpureclongdouble.o : DFTUndiff.c DFT.h SIMDBase.h
+ $(CC) $(OPT) -DENABLE_PUREC_LONGDOUBLE DFTUndiff.c -c -o DFTpureclongdouble.o
+
+SIMDBaseUndiff_purecfloat.o : SIMDBaseUndiff.c SIMDBase.h SIMDBaseUndiff.h
+ $(CC) $(OPT) -DENABLE_PUREC_FLOAT SIMDBaseUndiff.c -c -o SIMDBaseUndiff_purecfloat.o
+
+SIMDBaseUndiff_purecdouble.o : SIMDBaseUndiff.c DFT.h SIMDBase.h SIMDBaseUndiff.h
+ $(CC) $(OPT) -DENABLE_PUREC_DOUBLE SIMDBaseUndiff.c -c -o SIMDBaseUndiff_purecdouble.o
+
+SIMDBaseUndiff_pureclongdouble.o : SIMDBaseUndiff.c SIMDBase.h SIMDBaseUndiff.h
+ $(CC) $(OPT) -DENABLE_PUREC_LONGDOUBLE SIMDBaseUndiff.c -c -o SIMDBaseUndiff_pureclongdouble.o
+
+SIMDBase.o : SIMDBase.c SIMDBase.h
+ $(CC) $(BASEOPT) -O -DENABLE_PUREC_FLOAT -DENABLE_PUREC_DOUBLE -DENABLE_PUREC_LONGDOUBLE SIMDBase.c -c -o SIMDBase.o
+
+DFT.o : DFT.c DFT.h
+ $(CC) $(OPT) -DENABLE_PUREC_FLOAT -DENABLE_PUREC_DOUBLE -DENABLE_PUREC_LONGDOUBLE DFT.c -c -o DFT.o
+
+libDFT.a : DFTpurecfloat.o DFTpurecdouble.o DFTpureclongdouble.o DFT.o SIMDBase.o SIMDBaseUndiff_purecfloat.o SIMDBaseUndiff_purecdouble.o SIMDBaseUndiff_pureclongdouble.o
+ rm -f libDFT.a; ar -cvq libDFT.a DFTpurecfloat.o DFTpurecdouble.o DFTpureclongdouble.o DFT.o SIMDBase.o SIMDBaseUndiff_purecfloat.o SIMDBaseUndiff_purecdouble.o SIMDBaseUndiff_pureclongdouble.o
+
+clean :
+ rm -f *~ *.o *.s *.a
diff --git a/plugins/supereq/nsfft-1.00/dft/Makefile.x86 b/plugins/supereq/nsfft-1.00/dft/Makefile.x86
new file mode 100644
index 00000000..6ecbacec
--- /dev/null
+++ b/plugins/supereq/nsfft-1.00/dft/Makefile.x86
@@ -0,0 +1,29 @@
+CC=gcc
+BASEOPT=-Wall -I ../simd
+OPT=$(BASEOPT) -O3
+
+all : libDFT.a
+
+DFTpurecfloat.o : DFTUndiff.c DFT.h ../simd/SIMDBase.h ../simd/SIMDBaseUndiff.h
+ $(CC) $(OPT) -DENABLE_PUREC_FLOAT DFTUndiff.c -c -o DFTpurecfloat.o
+
+DFTpurecdouble.o : DFTUndiff.c DFT.h ../simd/SIMDBase.h ../simd/SIMDBaseUndiff.h
+ $(CC) $(OPT) -DENABLE_PUREC_DOUBLE DFTUndiff.c -c -o DFTpurecdouble.o
+
+DFTpureclongdouble.o : DFTUndiff.c DFT.h ../simd/SIMDBase.h ../simd/SIMDBaseUndiff.h
+ $(CC) $(OPT) -DENABLE_PUREC_LONGDOUBLE DFTUndiff.c -c -o DFTpureclongdouble.o
+
+DFTssefloat.o : DFTUndiff.c DFT.h ../simd/SIMDBase.h ../simd/SIMDBaseUndiff.h
+ $(CC) $(OPT) -msse -DENABLE_SSE_FLOAT DFTUndiff.c -c -o DFTssefloat.o
+
+DFTsse2double.o : DFTUndiff.c DFT.h ../simd/SIMDBase.h ../simd/SIMDBaseUndiff.h
+ $(CC) $(OPT) -msse2 -DENABLE_SSE2_DOUBLE DFTUndiff.c -c -o DFTsse2double.o
+
+DFT.o : DFT.c DFT.h
+ $(CC) $(OPT) -DENABLE_PUREC_FLOAT -DENABLE_PUREC_DOUBLE -DENABLE_PUREC_LONGDOUBLE -DENABLE_SSE_FLOAT -DENABLE_SSE2_DOUBLE DFT.c -c -o DFT.o
+
+libDFT.a : DFTpurecfloat.o DFTpurecdouble.o DFTpureclongdouble.o DFTssefloat.o DFTsse2double.o DFT.o
+ rm -f libDFT.a; ar -cvq libDFT.a DFTpurecfloat.o DFTpurecdouble.o DFTpureclongdouble.o DFTssefloat.o DFTsse2double.o DFT.o
+
+clean :
+ rm -f *~ *.o *.s *.a a.out
diff --git a/plugins/supereq/nsfft-1.00/dft/Makefile.x86avx b/plugins/supereq/nsfft-1.00/dft/Makefile.x86avx
new file mode 100644
index 00000000..b38909cb
--- /dev/null
+++ b/plugins/supereq/nsfft-1.00/dft/Makefile.x86avx
@@ -0,0 +1,35 @@
+CC=gcc
+BASEOPT=-Wall -I ../simd
+OPT=$(BASEOPT) -O3
+
+all : libDFT.a
+
+DFTpurecfloat.o : DFTUndiff.c DFT.h ../simd/SIMDBase.h ../simd/SIMDBaseUndiff.h
+ $(CC) $(OPT) -DENABLE_PUREC_FLOAT DFTUndiff.c -c -o DFTpurecfloat.o
+
+DFTpurecdouble.o : DFTUndiff.c DFT.h ../simd/SIMDBase.h ../simd/SIMDBaseUndiff.h
+ $(CC) $(OPT) -DENABLE_PUREC_DOUBLE DFTUndiff.c -c -o DFTpurecdouble.o
+
+DFTpureclongdouble.o : DFTUndiff.c DFT.h ../simd/SIMDBase.h ../simd/SIMDBaseUndiff.h
+ $(CC) $(OPT) -DENABLE_PUREC_LONGDOUBLE DFTUndiff.c -c -o DFTpureclongdouble.o
+
+DFTssefloat.o : DFTUndiff.c DFT.h ../simd/SIMDBase.h ../simd/SIMDBaseUndiff.h
+ $(CC) $(OPT) -msse -DENABLE_SSE_FLOAT DFTUndiff.c -c -o DFTssefloat.o
+
+DFTsse2double.o : DFTUndiff.c DFT.h ../simd/SIMDBase.h ../simd/SIMDBaseUndiff.h
+ $(CC) $(OPT) -msse2 -DENABLE_SSE2_DOUBLE DFTUndiff.c -c -o DFTsse2double.o
+
+DFTavxfloat.o : DFTUndiff.c DFT.h ../simd/SIMDBase.h ../simd/SIMDBaseUndiff.h
+ $(CC) $(OPT) -mavx -DENABLE_AVX_FLOAT DFTUndiff.c -c -o DFTavxfloat.o
+
+DFTavxdouble.o : DFTUndiff.c DFT.h ../simd/SIMDBase.h ../simd/SIMDBaseUndiff.h
+ $(CC) $(OPT) -mavx -DENABLE_AVX_DOUBLE DFTUndiff.c -c -o DFTavxdouble.o
+
+DFT.o : DFT.c DFT.h
+ $(CC) $(OPT) -DENABLE_PUREC_FLOAT -DENABLE_PUREC_DOUBLE -DENABLE_PUREC_LONGDOUBLE -DENABLE_SSE_FLOAT -DENABLE_SSE2_DOUBLE -DENABLE_AVX_FLOAT -DENABLE_AVX_DOUBLE DFT.c -c -o DFT.o
+
+libDFT.a : DFTpurecfloat.o DFTpurecdouble.o DFTpureclongdouble.o DFTssefloat.o DFTsse2double.o DFTavxfloat.o DFTavxdouble.o DFT.o
+ rm -f libDFT.a; ar -cvq libDFT.a DFTpurecfloat.o DFTpurecdouble.o DFTpureclongdouble.o DFTssefloat.o DFTsse2double.o DFTavxfloat.o DFTavxdouble.o DFT.o
+
+clean :
+ rm -f *~ *.o *.s *.a a.out
diff --git a/plugins/supereq/nsfft-1.00/dfttest/DFTExample.c b/plugins/supereq/nsfft-1.00/dfttest/DFTExample.c
new file mode 100644
index 00000000..78ff14dc
--- /dev/null
+++ b/plugins/supereq/nsfft-1.00/dfttest/DFTExample.c
@@ -0,0 +1,88 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <stdint.h>
+#include <complex.h>
+
+#include "SIMDBase.h"
+#include "DFT.h"
+
+typedef float REAL;
+#define TYPE SIMDBase_TYPE_FLOAT
+
+#define THRES 1e-3
+
+double complex omega(double n, double kn) {
+ return cexp((-2 * M_PI * _Complex_I / n) * kn);
+}
+
+void forward(double complex *ts, double complex *fs, int len) {
+ int k, n;
+
+ for(k=0;k<len;k++) {
+ fs[k] = 0;
+
+ for(n=0;n<len;n++) {
+ fs[k] += ts[n] * omega(len, n*k);
+ }
+ }
+}
+
+int main(int argc, char **argv) {
+ const int n = 256;
+
+ int mode = SIMDBase_chooseBestMode(TYPE);
+ printf("mode : %d, %s\n", mode, SIMDBase_getModeParamString(SIMDBase_PARAMID_MODE_NAME, mode));
+
+ int veclen = SIMDBase_getModeParamInt(SIMDBase_PARAMID_VECTOR_LEN, mode);
+ int sizeOfVect = SIMDBase_getModeParamInt(SIMDBase_PARAMID_SIZE_OF_VECT, mode);
+
+ //
+
+ int i, j;
+
+ DFT *p = DFT_init(mode, n, 0);
+ REAL *sx = SIMDBase_alignedMalloc(sizeOfVect*n*2);
+
+ //
+
+ double complex ts[veclen][n], fs[veclen][n];
+
+ for(j=0;j<veclen;j++) {
+ for(i=0;i<n;i++) {
+ ts[j][i] = (random() / (double)RAND_MAX) + (random() / (double)RAND_MAX) * _Complex_I;
+ sx[(i*2+0)*veclen+j] = creal(ts[j][i]);
+ sx[(i*2+1)*veclen+j] = cimag(ts[j][i]);
+ }
+ }
+
+ //
+
+ DFT_execute(p, mode, sx, -1);
+
+ for(j=0;j<veclen;j++) {
+ forward(ts[j], fs[j], n);
+ }
+
+ //
+
+ int success = 1;
+
+ for(j=0;j<veclen;j++) {
+ for(i=0;i<n;i++) {
+ if ((fabs(sx[(i*2+0)*veclen+j] - creal(fs[j][i])) > THRES) ||
+ (fabs(sx[(i*2+1)*veclen+j] - cimag(fs[j][i])) > THRES)) {
+ success = 0;
+ }
+ }
+ }
+
+ printf("%s\n", success ? "OK" : "NG");
+
+ //
+
+ SIMDBase_alignedFree(sx);
+ DFT_dispose(p, mode);
+
+ exit(0);
+}
diff --git a/plugins/supereq/nsfft-1.00/dfttest/DFTTestFFTW.c b/plugins/supereq/nsfft-1.00/dfttest/DFTTestFFTW.c
new file mode 100644
index 00000000..42825ed9
--- /dev/null
+++ b/plugins/supereq/nsfft-1.00/dfttest/DFTTestFFTW.c
@@ -0,0 +1,317 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <stdint.h>
+#include <time.h>
+#include <complex.h>
+
+#include <fftw3.h>
+
+#include "SIMDBase.h"
+#include "DFT.h"
+
+#if 1
+typedef float REAL;
+#define TYPE SIMDBase_TYPE_FLOAT
+#else
+typedef double REAL;
+#define TYPE SIMDBase_TYPE_DOUBLE
+#endif
+
+#define THRES 1e-3
+
+// complex forward
+int check_cf(int n, int mode, int veclen, int sizeOfVect) {
+ int i, j;
+
+ DFT *p = DFT_init(mode, n, 0);
+ fftw_plan w[n];
+
+ fftw_complex *in[sizeOfVect], *out[sizeOfVect];
+
+ REAL *sx = SIMDBase_alignedMalloc(sizeOfVect*n*2);
+
+ //
+
+ for(j=0;j<veclen;j++) {
+ in[j] = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * n);
+ out[j] = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * n);
+ w[j] = fftw_plan_dft_1d(n, in[j], out[j], FFTW_FORWARD, FFTW_ESTIMATE);
+
+ for(i=0;i<n;i++) {
+ double re = random() / (double)RAND_MAX;
+ double im = random() / (double)RAND_MAX;
+ sx[(i*2+0)*veclen+j] = re;
+ sx[(i*2+1)*veclen+j] = im;
+ in[j][i] = re + im * _Complex_I;
+ }
+ }
+
+ //
+
+ DFT_execute(p, mode, sx, -1);
+
+ for(j=0;j<veclen;j++) {
+ fftw_execute(w[j]);
+ }
+
+ //
+
+ int success = 1;
+
+ for(j=0;j<veclen;j++) {
+ for(i=0;i<n;i++) {
+ if (fabs(sx[(i*2+0)*veclen+j] - creal(out[j][i])) > THRES) success = 0;
+ if (fabs(sx[(i*2+1)*veclen+j] - cimag(out[j][i])) > THRES) success = 0;
+ }
+ }
+
+ //
+
+ for(j=0;j<veclen;j++) {
+ fftw_destroy_plan(w[j]);
+ fftw_free(in[j]);
+ fftw_free(out[j]);
+ }
+
+ SIMDBase_alignedFree(sx);
+
+ DFT_dispose(p, mode);
+
+ //
+
+ return success;
+}
+
+// complex backward
+int check_cb(int n, int mode, int veclen, int sizeOfVect) {
+ int i, j;
+
+ DFT *p = DFT_init(mode, n, 0);
+ fftw_plan w[n];
+
+ fftw_complex *in[sizeOfVect], *out[sizeOfVect];
+
+ REAL *sx = SIMDBase_alignedMalloc(sizeOfVect*n*2);
+
+ //
+
+ for(j=0;j<veclen;j++) {
+ in[j] = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * n);
+ out[j] = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * n);
+ w[j] = fftw_plan_dft_1d(n, in[j], out[j], FFTW_BACKWARD, FFTW_ESTIMATE);
+
+ for(i=0;i<n;i++) {
+ double re = random() / (double)RAND_MAX;
+ double im = random() / (double)RAND_MAX;
+ sx[(i*2+0)*veclen+j] = re;
+ sx[(i*2+1)*veclen+j] = im;
+ in[j][i] = re + im * _Complex_I;
+ }
+ }
+
+ //
+
+ DFT_execute(p, mode, sx, 1);
+
+ for(j=0;j<veclen;j++) {
+ fftw_execute(w[j]);
+ }
+
+ //
+
+ int success = 1;
+
+ for(j=0;j<veclen;j++) {
+ for(i=0;i<n;i++) {
+ if (fabs(sx[(i*2+0)*veclen+j] - creal(out[j][i])) > THRES) success = 0;
+ if (fabs(sx[(i*2+1)*veclen+j] - cimag(out[j][i])) > THRES) success = 0;
+ }
+ }
+
+ //
+
+ for(j=0;j<veclen;j++) {
+ fftw_destroy_plan(w[j]);
+ fftw_free(in[j]);
+ fftw_free(out[j]);
+ }
+
+ SIMDBase_alignedFree(sx);
+
+ DFT_dispose(p, mode);
+
+ //
+
+ return success;
+}
+
+// real forward
+int check_rf(int n, int mode, int veclen, int sizeOfVect) {
+ int i, j;
+
+ DFT *p = DFT_init(mode, n, DFT_FLAG_REAL);
+ fftw_plan w[n];
+
+ double *in[sizeOfVect];
+ fftw_complex *out[sizeOfVect];
+
+ REAL *sx = SIMDBase_alignedMalloc(sizeOfVect*n*2);
+
+ //
+
+ for(j=0;j<veclen;j++) {
+ in[j] = (double *) fftw_malloc(sizeof(double) * n);
+ out[j] = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * (n/2+1));
+ w[j] = fftw_plan_dft_r2c_1d(n, in[j], out[j], FFTW_ESTIMATE);
+
+ for(i=0;i<n;i++) {
+ double re = random() / (double)RAND_MAX;
+ sx[i*veclen+j] = re;
+ in[j][i] = re;
+ }
+ }
+
+ //
+
+ DFT_execute(p, mode, sx, -1);
+
+ for(j=0;j<veclen;j++) {
+ fftw_execute(w[j]);
+ }
+
+ //
+
+ int success = 1;
+
+ for(j=0;j<veclen;j++) {
+ for(i=0;i<n/2;i++) {
+ if (i == 0) {
+ if (fabs(sx[(i*2+0)*veclen+j] - creal(out[j][0])) > THRES) success = 0;
+ if (fabs(sx[(i*2+1)*veclen+j] - creal(out[j][n/2])) > THRES) success = 0;
+ } else {
+ if (fabs(sx[(i*2+0)*veclen+j] - creal(out[j][i])) > THRES) success = 0;
+ if (fabs(sx[(i*2+1)*veclen+j] - cimag(out[j][i])) > THRES) success = 0;
+ }
+ }
+ }
+
+ //
+
+ for(j=0;j<veclen;j++) {
+ fftw_destroy_plan(w[j]);
+ fftw_free(in[j]);
+ fftw_free(out[j]);
+ }
+
+ SIMDBase_alignedFree(sx);
+
+ DFT_dispose(p, mode);
+
+ //
+
+ return success;
+}
+
+// real backward
+int check_rb(int n, int mode, int veclen, int sizeOfVect) {
+ int i, j;
+
+ DFT *p = DFT_init(mode, n, DFT_FLAG_REAL);
+ fftw_plan w[n];
+
+ fftw_complex *in[sizeOfVect];
+ double *out[sizeOfVect];
+
+ REAL *sx = SIMDBase_alignedMalloc(sizeOfVect*n*2);
+
+ //
+
+ for(j=0;j<veclen;j++) {
+ in[j] = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * (n/2+1));
+ out[j] = (double *) fftw_malloc(sizeof(double) * n);
+ w[j] = fftw_plan_dft_c2r_1d(n, in[j], out[j], FFTW_ESTIMATE);
+
+ for(i=0;i<n/2;i++) {
+ if (i == 0) {
+ in[j][0 ] = (random() / (double)RAND_MAX);
+ in[j][n/2] = (random() / (double)RAND_MAX);
+ } else {
+ in[j][i ] = (random() / (double)RAND_MAX) + (random() / (double)RAND_MAX) * _Complex_I;
+ }
+ }
+
+ for(i=0;i<n/2;i++) {
+ if (i == 0) {
+ sx[(2*0+0) * veclen + j] = creal(in[j][0 ]);
+ sx[(2*0+1) * veclen + j] = creal(in[j][n/2]);
+ } else {
+ sx[(2*i+0) * veclen + j] = creal(in[j][i]);
+ sx[(2*i+1) * veclen + j] = cimag(in[j][i]);
+ }
+ }
+ }
+
+ //
+
+ DFT_execute(p, mode, sx, 1);
+
+ for(j=0;j<veclen;j++) {
+ fftw_execute(w[j]);
+ }
+
+ //
+
+ int success = 1;
+
+ for(j=0;j<veclen;j++) {
+ for(i=0;i<n/2;i++) {
+ if ((fabs(sx[i * veclen + j]*2 - out[j][i]) > THRES)) {
+ success = 0;
+ }
+ }
+ }
+
+ //
+
+ for(j=0;j<veclen;j++) {
+ fftw_destroy_plan(w[j]);
+ fftw_free(in[j]);
+ fftw_free(out[j]);
+ }
+
+ SIMDBase_alignedFree(sx);
+
+ DFT_dispose(p, mode);
+
+ //
+
+ return success;
+}
+
+int main(int argc, char **argv) {
+ if (argc != 2) {
+ fprintf(stderr, "%s <log2n>\n", argv[0]);
+ exit(-1);
+ }
+
+ const int n = 1 << atoi(argv[1]);
+
+ srandom(time(NULL));
+
+ //
+
+ int mode = SIMDBase_chooseBestMode(TYPE);
+
+ printf("mode : %d, %s\n", mode, SIMDBase_getModeParamString(SIMDBase_PARAMID_MODE_NAME, mode));
+
+ int veclen = SIMDBase_getModeParamInt(SIMDBase_PARAMID_VECTOR_LEN, mode);
+ int sizeOfVect = SIMDBase_getModeParamInt(SIMDBase_PARAMID_SIZE_OF_VECT, mode);
+
+ printf("complex forward : %s\n", check_cf(n, mode, veclen, sizeOfVect) ? "OK" : "NG");
+ printf("complex backward : %s\n", check_cb(n, mode, veclen, sizeOfVect) ? "OK" : "NG");
+ printf("real forward : %s\n", check_rf(n, mode, veclen, sizeOfVect) ? "OK" : "NG");
+ printf("real backward : %s\n", check_rb(n, mode, veclen, sizeOfVect) ? "OK" : "NG");
+
+ exit(0);
+}
diff --git a/plugins/supereq/nsfft-1.00/dfttest/DFTTestNaive.c b/plugins/supereq/nsfft-1.00/dfttest/DFTTestNaive.c
new file mode 100644
index 00000000..9d4bdaae
--- /dev/null
+++ b/plugins/supereq/nsfft-1.00/dfttest/DFTTestNaive.c
@@ -0,0 +1,419 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <stdint.h>
+#include <time.h>
+#include <complex.h>
+
+#include "SIMDBase.h"
+#include "DFT.h"
+
+#if 1
+typedef float REAL;
+#define TYPE SIMDBase_TYPE_FLOAT
+#else
+typedef double REAL;
+#define TYPE SIMDBase_TYPE_DOUBLE
+#endif
+
+#define THRES 1e-3
+
+double complex omega(double n, double kn) {
+ return cexp((-2 * M_PI * _Complex_I / n) * kn);
+}
+
+void forward(double complex *ts, double complex *fs, int len) {
+ int k, n;
+
+ for(k=0;k<len;k++) {
+ fs[k] = 0;
+
+ for(n=0;n<len;n++) {
+ fs[k] += ts[n] * omega(len, n*k);
+ }
+ }
+}
+
+void backward(double complex *fs, double complex *ts, int len) {
+ int k, n;
+
+ for(k=0;k<len;k++) {
+ ts[k] = 0;
+
+ for(n=0;n<len;n++) {
+ ts[k] += fs[n] * omega(-len, n*k);
+ }
+ }
+}
+
+// complex forward
+int check_cf(int n, int mode, int veclen, int sizeOfVect) {
+ int i, j;
+
+ DFT *p = DFT_init(mode, n, 0);
+ REAL *sx = SIMDBase_alignedMalloc(sizeOfVect*n*2);
+
+ //
+
+ double complex ts[veclen][n], fs[veclen][n];
+
+ for(j=0;j<veclen;j++) {
+ for(i=0;i<n;i++) {
+ ts[j][i] = (random() / (double)RAND_MAX) + (random() / (double)RAND_MAX) * _Complex_I;
+ sx[(i*2+0)*veclen+j] = creal(ts[j][i]);
+ sx[(i*2+1)*veclen+j] = cimag(ts[j][i]);
+ }
+ }
+
+ //
+
+ DFT_execute(p, mode, sx, -1);
+
+ for(j=0;j<veclen;j++) {
+ forward(ts[j], fs[j], n);
+ }
+
+ //
+
+ int success = 1;
+
+ for(j=0;j<veclen;j++) {
+ for(i=0;i<n;i++) {
+ if ((fabs(sx[(i*2+0)*veclen+j] - creal(fs[j][i])) > THRES) ||
+ (fabs(sx[(i*2+1)*veclen+j] - cimag(fs[j][i])) > THRES)) {
+ success = 0;
+ }
+ }
+ }
+
+ //
+
+ SIMDBase_alignedFree(sx);
+ DFT_dispose(p, mode);
+
+ //
+
+ return success;
+}
+
+// complex backward
+int check_cb(int n, int mode, int veclen, int sizeOfVect) {
+ int i,j;
+
+ DFT *p = DFT_init(mode, n, 0);
+ REAL *sx = SIMDBase_alignedMalloc(sizeOfVect*n*2);
+
+ //
+
+ double complex fs[veclen][n], ts[veclen][n];
+
+ for(j=0;j<veclen;j++) {
+ for(i=0;i<n;i++) {
+ fs[j][i] = (random() / (double)RAND_MAX) + (random() / (double)RAND_MAX) * _Complex_I;
+
+ sx[(i*2+0)*veclen+j] = creal(fs[j][i]);
+ sx[(i*2+1)*veclen+j] = cimag(fs[j][i]);
+ }
+ }
+
+ //
+
+ DFT_execute(p, mode, sx, 1);
+
+ for(j=0;j<veclen;j++) {
+ backward(fs[j], ts[j], n);
+ }
+
+ //
+
+ int success = 1;
+
+ for(j=0;j<veclen;j++) {
+ for(i=0;i<n;i++) {
+ if ((fabs(sx[(i*2+0)*veclen+j] - creal(ts[j][i])) > THRES) ||
+ (fabs(sx[(i*2+1)*veclen+j] - cimag(ts[j][i])) > THRES)) {
+ success = 0;
+ }
+ }
+ }
+
+ //
+
+ SIMDBase_alignedFree(sx);
+ DFT_dispose(p, mode);
+
+ //
+
+ return success;
+}
+
+// real forward
+int check_rf(int n, int mode, int veclen, int sizeOfVect) {
+ int i,j;
+
+ DFT *p = DFT_init(mode, n, DFT_FLAG_REAL);
+ REAL *sx = SIMDBase_alignedMalloc(sizeOfVect*n);
+
+ //
+
+ double complex ts[veclen][n], fs[veclen][n];
+
+ for(j=0;j<veclen;j++) {
+ for(i=0;i<n;i++) {
+ ts[j][i] = (random() / (double)RAND_MAX);
+ sx[i*veclen+j] = creal(ts[j][i]);
+ }
+ }
+
+ //
+
+ DFT_execute(p, mode, sx, -1);
+
+ for(j=0;j<veclen;j++) {
+ forward(ts[j], fs[j], n);
+ }
+
+ //
+
+ int success = 1;
+
+ for(j=0;j<veclen;j++) {
+ for(i=0;i<n/2;i++) {
+ if (i == 0) {
+ if (fabs(sx[(2*0+0) * veclen + j] - creal(fs[j][0 ])) > THRES) success = 0;
+ if (fabs(sx[(2*0+1) * veclen + j] - creal(fs[j][n/2])) > THRES) success = 0;
+ } else {
+ if (fabs(sx[(2*i+0) * veclen + j] - creal(fs[j][i])) > THRES) success = 0;
+ if (fabs(sx[(2*i+1) * veclen + j] - cimag(fs[j][i])) > THRES) success = 0;
+ }
+ }
+ }
+
+ //
+
+ SIMDBase_alignedFree(sx);
+ DFT_dispose(p, mode);
+
+ //
+
+ return success;
+}
+
+// real backward
+int check_rb(int n, int mode, int veclen, int sizeOfVect) {
+ int i,j;
+
+ DFT *p = DFT_init(mode, n, DFT_FLAG_REAL);
+ REAL *sx = SIMDBase_alignedMalloc(sizeOfVect*n);
+
+ //
+
+ double complex fs[veclen][n], ts[veclen][n];
+
+ for(j=0;j<veclen;j++) {
+ for(i=0;i<n/2;i++) {
+ if (i == 0) {
+ fs[j][0 ] = (random() / (double)RAND_MAX);
+ fs[j][n/2] = (random() / (double)RAND_MAX);
+ } else {
+ fs[j][i ] = (random() / (double)RAND_MAX) + (random() / (double)RAND_MAX) * _Complex_I;
+ fs[j][n-i] = conj(fs[j][i]);
+ }
+ }
+ }
+
+ for(j=0;j<veclen;j++) {
+ for(i=0;i<n/2;i++) {
+ if (i == 0) {
+ sx[(2*0+0) * veclen + j] = creal(fs[j][0 ]);
+ sx[(2*0+1) * veclen + j] = creal(fs[j][n/2]);
+ } else {
+ sx[(2*i+0) * veclen + j] = creal(fs[j][i]);
+ sx[(2*i+1) * veclen + j] = cimag(fs[j][i]);
+ }
+ }
+ }
+
+ //
+
+ for(j=0;j<veclen;j++) {
+ backward(fs[j], ts[j], n);
+ }
+
+ DFT_execute(p, mode, sx, 1);
+
+ //
+
+ int success = 1;
+
+ for(j=0;j<veclen;j++) {
+ for(i=0;i<n;i++) {
+ if (fabs(cimag(ts[j][i])) > THRES) {
+ success = 0;
+ }
+
+ if ((fabs(sx[i * veclen + j]*2 - creal(ts[j][i])) > THRES)) {
+ success = 0;
+ }
+ }
+ }
+
+ //
+
+ SIMDBase_alignedFree(sx);
+ DFT_dispose(p, mode);
+
+ //
+
+ return success;
+}
+
+// alt real forward
+int check_arf(int n, int mode, int veclen, int sizeOfVect) {
+ int i,j;
+
+ DFT *p = DFT_init(mode, n, DFT_FLAG_ALT_REAL);
+ REAL *sx = SIMDBase_alignedMalloc(sizeOfVect*n);
+
+ //
+
+ double complex ts[veclen][n], fs[veclen][n];
+
+ for(j=0;j<veclen;j++) {
+ for(i=0;i<n;i++) {
+ ts[j][i] = (random() / (double)RAND_MAX);
+ sx[i*veclen+j] = creal(ts[j][i]);
+ }
+ }
+
+ //
+
+ DFT_execute(p, mode, sx, 1);
+
+ for(j=0;j<veclen;j++) {
+ backward(ts[j], fs[j], n);
+ }
+
+ //
+
+ int success = 1;
+
+ for(j=0;j<veclen;j++) {
+ for(i=0;i<n/2;i++) {
+ if (i == 0) {
+ if (fabs(sx[(2*0+0) * veclen + j] - creal(fs[j][0 ])) > THRES) success = 0;
+ if (fabs(sx[(2*0+1) * veclen + j] - creal(fs[j][n/2])) > THRES) success = 0;
+ } else {
+ if (fabs(sx[(2*i+0) * veclen + j] - creal(fs[j][i])) > THRES) success = 0;
+ if (fabs(sx[(2*i+1) * veclen + j] - cimag(fs[j][i])) > THRES) success = 0;
+ }
+ }
+ }
+
+ //
+
+ SIMDBase_alignedFree(sx);
+ DFT_dispose(p, mode);
+
+ //
+
+ return success;
+}
+
+// alt real backward
+int check_arb(int n, int mode, int veclen, int sizeOfVect) {
+ int i,j;
+
+ DFT *p = DFT_init(mode, n, DFT_FLAG_ALT_REAL);
+ REAL *sx = SIMDBase_alignedMalloc(sizeOfVect*n);
+
+ //
+
+ double complex fs[veclen][n], ts[veclen][n];
+
+ for(j=0;j<veclen;j++) {
+ for(i=0;i<n/2;i++) {
+ if (i == 0) {
+ fs[j][0 ] = (random() / (double)RAND_MAX);
+ fs[j][n/2] = (random() / (double)RAND_MAX);
+ } else {
+ fs[j][i ] = (random() / (double)RAND_MAX) + (random() / (double)RAND_MAX) * _Complex_I;
+ fs[j][n-i] = conj(fs[j][i]);
+ }
+ }
+ }
+
+ for(j=0;j<veclen;j++) {
+ for(i=0;i<n/2;i++) {
+ if (i == 0) {
+ sx[(2*0+0) * veclen + j] = creal(fs[j][0 ]);
+ sx[(2*0+1) * veclen + j] = creal(fs[j][n/2]);
+ } else {
+ sx[(2*i+0) * veclen + j] = creal(fs[j][i]);
+ sx[(2*i+1) * veclen + j] = cimag(fs[j][i]);
+ }
+ }
+ }
+
+ //
+
+ for(j=0;j<veclen;j++) {
+ forward(fs[j], ts[j], n);
+ }
+
+ DFT_execute(p, mode, sx, -1);
+
+ //
+
+ int success = 1;
+
+ for(j=0;j<veclen;j++) {
+ for(i=0;i<n;i++) {
+ if (fabs(cimag(ts[j][i])) > THRES) {
+ success = 0;
+ }
+
+ if ((fabs(sx[i * veclen + j]*2 - creal(ts[j][i])) > THRES)) {
+ success = 0;
+ }
+ }
+ }
+
+ //
+
+ SIMDBase_alignedFree(sx);
+ DFT_dispose(p, mode);
+
+ //
+
+ return success;
+}
+
+int main(int argc, char **argv) {
+ if (argc != 2) {
+ fprintf(stderr, "%s <log2n>\n", argv[0]);
+ exit(-1);
+ }
+
+ const int n = 1 << atoi(argv[1]);
+
+ srandom(time(NULL));
+
+ //
+
+ int mode = SIMDBase_chooseBestMode(TYPE);
+
+ printf("mode : %d, %s\n", mode, SIMDBase_getModeParamString(SIMDBase_PARAMID_MODE_NAME, mode));
+
+ int veclen = SIMDBase_getModeParamInt(SIMDBase_PARAMID_VECTOR_LEN, mode);
+ int sizeOfVect = SIMDBase_getModeParamInt(SIMDBase_PARAMID_SIZE_OF_VECT, mode);
+
+ printf("complex forward : %s\n", check_cf(n, mode, veclen, sizeOfVect) ? "OK" : "NG");
+ printf("complex backward : %s\n", check_cb(n, mode, veclen, sizeOfVect) ? "OK" : "NG");
+ printf("real forward : %s\n", check_rf(n, mode, veclen, sizeOfVect) ? "OK" : "NG");
+ printf("real backward : %s\n", check_rb(n, mode, veclen, sizeOfVect) ? "OK" : "NG");
+ printf("alt real forward : %s\n", check_arf(n, mode, veclen, sizeOfVect) ? "OK" : "NG");
+ printf("alt real backward : %s\n", check_arb(n, mode, veclen, sizeOfVect) ? "OK" : "NG");
+
+ exit(0);
+}
diff --git a/plugins/supereq/nsfft-1.00/dfttest/DFTTestOoura.c b/plugins/supereq/nsfft-1.00/dfttest/DFTTestOoura.c
new file mode 100644
index 00000000..08c8315f
--- /dev/null
+++ b/plugins/supereq/nsfft-1.00/dfttest/DFTTestOoura.c
@@ -0,0 +1,260 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <stdint.h>
+#include <time.h>
+
+#include "SIMDBase.h"
+#include "DFT.h"
+
+void cdft(int, int, double *, int *, double *);
+void rdft(int, int, double *, int *, double *);
+
+#if 1
+typedef float REAL;
+#define TYPE SIMDBase_TYPE_FLOAT
+#else
+typedef double REAL;
+#define TYPE SIMDBase_TYPE_DOUBLE
+#endif
+
+#define THRES 1e-3
+
+// complex forward
+int check_cf(int n, int mode, int veclen, int sizeOfVect) {
+ int i, j;
+
+ DFT *p = DFT_init(mode, n, 0);
+
+ int *ip = calloc(n, sizeof(int));
+ double *trigTable = SIMDBase_alignedMalloc(sizeof(double)*n/2);
+
+ REAL *sx = SIMDBase_alignedMalloc(sizeOfVect*n*2);
+ double *sy = SIMDBase_alignedMalloc(veclen * sizeof(double) *n*2);
+
+ //
+
+ for(j=0;j<veclen;j++) {
+ for(i=0;i<n*2;i++) {
+ sx[i*veclen + j] = random() / (double)RAND_MAX;
+ sy[j*n*2 + i] = sx[i*veclen + j];
+ }
+ }
+
+ //
+
+ DFT_execute(p, mode, sx, -1);
+
+ for(j=0;j<veclen;j++) {
+ cdft(n*2, -1, &sy[j*n*2], ip, trigTable);
+ }
+
+ //
+
+ int success = 1;
+
+ for(j=0;j<veclen;j++) {
+ for(i=0;i<n*2;i++) {
+ if (fabs(sx[i*veclen+j] - sy[j*n*2 + i]) > THRES) success = 0;
+ }
+ }
+
+ //
+
+ SIMDBase_alignedFree(sy);
+ SIMDBase_alignedFree(sx);
+ SIMDBase_alignedFree(trigTable);
+ free(ip);
+
+ DFT_dispose(p, mode);
+
+ //
+
+ return success;
+}
+
+// complex backward
+int check_cb(int n, int mode, int veclen, int sizeOfVect) {
+ int i, j;
+
+ DFT *p = DFT_init(mode, n, 0);
+
+ int *ip = calloc(n, sizeof(int));
+ double *trigTable = SIMDBase_alignedMalloc(sizeof(double)*n/2);
+
+ REAL *sx = SIMDBase_alignedMalloc(sizeOfVect*n*2);
+ double *sy = SIMDBase_alignedMalloc(veclen * sizeof(double) *n*2);
+
+ //
+
+ for(j=0;j<veclen;j++) {
+ for(i=0;i<n*2;i++) {
+ sx[i*veclen + j] = random() / (double)RAND_MAX;
+ sy[j*n*2 + i] = sx[i*veclen + j];
+ }
+ }
+
+ //
+
+ DFT_execute(p, mode, sx, 1);
+
+ for(j=0;j<veclen;j++) {
+ cdft(n*2, 1, &sy[j*n*2], ip, trigTable);
+ }
+
+ //
+
+ int success = 1;
+
+ for(j=0;j<veclen;j++) {
+ for(i=0;i<n*2;i++) {
+ if (fabs(sx[i*veclen+j] - sy[j*n*2 + i]) > THRES) success = 0;
+ }
+ }
+
+ //
+
+ SIMDBase_alignedFree(sy);
+ SIMDBase_alignedFree(sx);
+ SIMDBase_alignedFree(trigTable);
+ free(ip);
+
+ DFT_dispose(p, mode);
+
+ //
+
+ return success;
+}
+
+// real forward
+int check_rf(int n, int mode, int veclen, int sizeOfVect) {
+ int i, j;
+
+ DFT *p = DFT_init(mode, n, DFT_FLAG_ALT_REAL);
+
+ int *ip = calloc(n, sizeof(int));
+ double *trigTable = SIMDBase_alignedMalloc(sizeof(double)*n/2);
+
+ REAL *sx = SIMDBase_alignedMalloc(sizeOfVect*n);
+ double *sy = SIMDBase_alignedMalloc(veclen * sizeof(double) *n);
+
+ //
+
+ for(j=0;j<veclen;j++) {
+ for(i=0;i<n;i++) {
+ sx[i*veclen + j] = random() / (double)RAND_MAX;
+ sy[j*n + i] = sx[i*veclen + j];
+ }
+ }
+
+ //
+
+ DFT_execute(p, mode, sx, -1);
+
+ for(j=0;j<veclen;j++) {
+ rdft(n, -1, &sy[j*n], ip, trigTable);
+ }
+
+ //
+
+ int success = 1;
+
+ for(j=0;j<veclen;j++) {
+ for(i=0;i<n;i++) {
+ if (fabs(sx[i*veclen+j] - sy[j*n + i]) > THRES) success = 0;
+ }
+ }
+
+ //
+
+ SIMDBase_alignedFree(sy);
+ SIMDBase_alignedFree(sx);
+ SIMDBase_alignedFree(trigTable);
+ free(ip);
+
+ DFT_dispose(p, mode);
+
+ //
+
+ return success;
+}
+
+// real backward
+int check_rb(int n, int mode, int veclen, int sizeOfVect) {
+ int i, j;
+
+ DFT *p = DFT_init(mode, n, DFT_FLAG_ALT_REAL);
+
+ int *ip = calloc(n, sizeof(int));
+ double *trigTable = SIMDBase_alignedMalloc(sizeof(double)*n/2);
+
+ REAL *sx = SIMDBase_alignedMalloc(sizeOfVect*n);
+ double *sy = SIMDBase_alignedMalloc(veclen * sizeof(double) *n);
+
+ //
+
+ for(j=0;j<veclen;j++) {
+ for(i=0;i<n;i++) {
+ sx[i*veclen + j] = random() / (double)RAND_MAX;
+ sy[j*n + i] = sx[i*veclen + j];
+ }
+ }
+
+ //
+
+ DFT_execute(p, mode, sx, 1);
+
+ for(j=0;j<veclen;j++) {
+ rdft(n, 1, &sy[j*n], ip, trigTable);
+ }
+
+ //
+
+ int success = 1;
+
+ for(j=0;j<veclen;j++) {
+ for(i=0;i<n;i++) {
+ if (fabs(sx[i*veclen+j] - sy[j*n + i]) > THRES) success = 0;
+ }
+ }
+
+ //
+
+ SIMDBase_alignedFree(sy);
+ SIMDBase_alignedFree(sx);
+ SIMDBase_alignedFree(trigTable);
+ free(ip);
+
+ DFT_dispose(p, mode);
+
+ //
+
+ return success;
+}
+
+int main(int argc, char **argv) {
+ if (argc != 2) {
+ fprintf(stderr, "%s <log2n>\n", argv[0]);
+ exit(-1);
+ }
+
+ const int n = 1 << atoi(argv[1]);
+
+ srandom(time(NULL));
+
+ //
+
+ int mode = SIMDBase_chooseBestMode(TYPE);
+
+ printf("mode : %d, %s\n", mode, SIMDBase_getModeParamString(SIMDBase_PARAMID_MODE_NAME, mode));
+
+ int veclen = SIMDBase_getModeParamInt(SIMDBase_PARAMID_VECTOR_LEN, mode);
+ int sizeOfVect = SIMDBase_getModeParamInt(SIMDBase_PARAMID_SIZE_OF_VECT, mode);
+
+ printf("complex forward : %s\n", check_cf(n, mode, veclen, sizeOfVect) ? "OK" : "NG");
+ printf("complex backward : %s\n", check_cb(n, mode, veclen, sizeOfVect) ? "OK" : "NG");
+ printf("real forward : %s\n", check_rf(n, mode, veclen, sizeOfVect) ? "OK" : "NG");
+ printf("real backward : %s\n", check_rb(n, mode, veclen, sizeOfVect) ? "OK" : "NG");
+
+ exit(0);
+}
diff --git a/plugins/supereq/nsfft-1.00/dfttest/Makefile b/plugins/supereq/nsfft-1.00/dfttest/Makefile
new file mode 100644
index 00000000..924b8656
--- /dev/null
+++ b/plugins/supereq/nsfft-1.00/dfttest/Makefile
@@ -0,0 +1,35 @@
+CC=gcc
+BASEOPT=-Wall -g -I ../simd -I ../dft -L../simd -L../dft
+OPT=$(BASEOPT) -O
+
+all : DFTExample DFTTestNaive
+
+clean :
+ rm -f *~ *.o nsfftplan.*.txt *.log *.dat a.out DFTExample DFTTestNaive DFTTestOoura DFTTestFFTW pi_fft_mod pi_fft_mod.c
+
+../simd/libSIMD.a :
+ @cd ../simd; make
+
+../dft/libDFT.a :
+ @cd ../dft; make
+
+../ooura/fftsg.o :
+ @cd ../ooura; make
+
+DFTExample : DFTExample.c ../simd/libSIMD.a ../dft/libDFT.a
+ $(CC) $(OPT) DFTExample.c -lDFT -lSIMD -lm -o DFTExample
+
+DFTTestNaive : DFTTestNaive.c ../simd/libSIMD.a ../dft/libDFT.a
+ $(CC) $(OPT) DFTTestNaive.c -lDFT -lSIMD -lm -o DFTTestNaive
+
+DFTTestOoura : DFTTestOoura.c ../ooura/fftsg.o ../simd/libSIMD.a ../dft/libDFT.a
+ $(CC) $(OPT) DFTTestOoura.c ../ooura/fftsg.o -lDFT -lSIMD -lm -o DFTTestOoura
+
+DFTTestFFTW : DFTTestFFTW.c ../simd/libSIMD.a ../dft/libDFT.a
+ $(CC) $(OPT) DFTTestFFTW.c -lDFT -lSIMD -lfftw3 -lm -o DFTTestFFTW
+
+pi_fft_mod.c : ../ooura/pi_fft.c pi_fft.c.patch
+ patch -o pi_fft_mod.c ../ooura/pi_fft.c pi_fft.c.patch
+
+pi_fft_mod : ../simd/libSIMD.a ../dft/libDFT.a pi_fft_mod.c
+ $(CC) $(OPT) pi_fft_mod.c -I ../dft -I ../simd -L../dft -L../simd -lm -lDFT -lSIMD -o pi_fft_mod
diff --git a/plugins/supereq/nsfft-1.00/dfttest/pi_fft.c.patch b/plugins/supereq/nsfft-1.00/dfttest/pi_fft.c.patch
new file mode 100644
index 00000000..c50133cc
--- /dev/null
+++ b/plugins/supereq/nsfft-1.00/dfttest/pi_fft.c.patch
@@ -0,0 +1,131 @@
+--- pi_fft.c 2010-07-30 13:04:25.000000000 +0900
++++ pi_fft_mod.c 2010-07-31 20:50:11.000000000 +0900
+@@ -25,7 +25,75 @@
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <time.h>
++#include <sys/time.h>
++#include <unistd.h>
+
++/****/
++
++#include <stdint.h>
++#include "SIMDBase.h"
++#include "DFT.h"
++
++DFT* dft[64];
++
++void initdft(int n) {
++ int i, logn = 31 - __builtin_clz(n), writeflag = 0;
++ char buf[20], fn[256];
++ gethostname(buf, 19);
++ sprintf(fn, "nsfftplan.%s.txt", buf);
++ FILE *fp = fopen(fn, "r");
++ if (fp != NULL) {
++ for(i=1;i<=logn;i++) {
++ int err;
++ dft[i] = DFT_fread(fp, &err);
++ if (err != DFT_ERROR_NOERROR) {
++ printf("error when reading plan %d : %d\n", i, err);
++ break;
++ }
++ if (DFT_getPlanParamInt(DFT_PARAMID_MODE, dft[i]) != SIMDBase_MODE_PUREC_DOUBLE ||
++ DFT_getPlanParamInt(DFT_PARAMID_FFT_LENGTH, dft[i]) != (1 << i) ||
++ DFT_getPlanParamInt(DFT_PARAMID_IS_ALT_REAL_TRANSFORM, dft[i]) != 1) {
++ fprintf(stderr, "plan not compatible : %d\n", i);
++ break;
++ }
++ }
++ }
++ if (fp != NULL) fclose(fp);
++
++ for(i=1;i<=logn;i++) {
++ if (dft[i] == NULL) {
++ dft[i] = DFT_init(SIMDBase_MODE_PUREC_DOUBLE, 1 << i, DFT_FLAG_ALT_REAL | DFT_FLAG_LIGHT_TEST_RUN | DFT_FLAG_VERBOSE);
++ if (dft[i] == NULL) {
++ printf("dft[%d] == NULL\n", i);
++ exit(-1);
++ }
++ writeflag = 1;
++ }
++ }
++
++ if (writeflag) {
++ fp = fopen(fn, "w");
++ if (fp != NULL) {
++ for(i=1;i<=logn;i++) {
++ DFT_fwrite(dft[i], fp);
++ }
++ fclose(fp);
++ }
++ }
++}
++
++void rdft(int n, int isgn, double *a, int *ip, double *w) {
++ int logn = 31 - __builtin_clz(n);
++ DFT_execute(dft[logn], SIMDBase_MODE_PUREC_DOUBLE, a, isgn);
++}
++
++double timeofday(void) {
++ struct timeval tp;
++ gettimeofday(&tp, NULL);
++ return (double)tp.tv_sec+(1e-6)*tp.tv_usec;
++}
++
++/****/
+
+ void mp_load_0(int n, int radix, int out[]);
+ void mp_load_1(int n, int radix, int out[]);
+@@ -67,7 +135,7 @@
+ double err, d_time, n_op;
+ int *a, *b, *c, *e, *i1, *i2, *ip;
+ double *d1, *d2, *d3, *w;
+- time_t t_1, t_2;
++ double t_1, t_2;
+ FILE *f_log, *f_out;
+
+ f_log = fopen("pi.log", "w");
+@@ -96,6 +164,8 @@
+ exit(1);
+ }
+ ip[0] = 0;
++
++ initdft(nfft);
+ /* ---- radix test ---- */
+ log10_radix = 1;
+ radix = 10;
+@@ -111,7 +181,7 @@
+ printf("calculating %d digits of PI...\n", log10_radix * (n - 2));
+ fprintf(f_log, "calculating %d digits of PI...\n", log10_radix * (n - 2));
+ /* ---- time check ---- */
+- time(&t_1);
++ t_1 = timeofday();
+ /*
+ * ---- a formula based on the AGM (Arithmetic-Geometric Mean) ----
+ * c = sqrt(0.125);
+@@ -216,10 +286,10 @@
+ mp_mul(n, radix, a, b, a, i1, nfft, d1, d2, d3, ip, w);
+ mp_idiv(n, radix, a, npow, a);
+ /* ---- time check ---- */
+- time(&t_2);
++ t_2 = timeofday();
+ /* ---- output ---- */
+ f_out = fopen("pi_mod.dat", "w");
+- printf("writing pi.dat...\n");
++ printf("writing pi_mod.dat...\n");
+ mp_fprintf(n - 1, log10_radix, a, f_out);
+ fclose(f_out);
+ free(d3);
+@@ -238,9 +308,9 @@
+ printf("floating point operation: %g op.\n", n_op);
+ fprintf(f_log, "floating point operation: %g op.\n", n_op);
+ /* ---- difftime ---- */
+- d_time = difftime(t_2, t_1);
+- printf("execution time: %g sec. (real time)\n", d_time);
+- fprintf(f_log, "execution time: %g sec. (real time)\n", d_time);
++ d_time = t_2 - t_1;
++ printf("execution time: %.5g sec. (real time)\n", d_time);
++ fprintf(f_log, "execution time: %.5g sec. (real time)\n", d_time);
+ fclose(f_log);
+ return 0;
+ }
diff --git a/plugins/supereq/nsfft-1.00/doc/default.css b/plugins/supereq/nsfft-1.00/doc/default.css
new file mode 100644
index 00000000..09721163
--- /dev/null
+++ b/plugins/supereq/nsfft-1.00/doc/default.css
@@ -0,0 +1,34 @@
+body {margin-left: 1.5cm; padding-left: 0.1cm; margin-right: 1.5cm; padding-right: 0.1cm; margin-top: 2.5cm; padding-top: 0.5cm; margin-bottom: 1cm; padding-bottom: 1.0cm; border-top-style:solid; border-bottom-style:solid; }
+h1 {font-family: arial, sansserif; font-weight: bold; font-style: italic; margin-top: 0.8cm; }
+h2 {font-family: arial, sansserif; font-weight: bold; font-style: italic; margin-top: 0.8cm; }
+h3 {font-family: arial, sansserif; font-weight: bold; margin-top: 1.2cm; margin-bottom: 0.8cm; }
+h4 {font-family: arial, sansserif; font-weight: bold; margin-top: 1.2cm; margin-bottom: 0.8cm; }
+p {font-family: Georgia, "Times New Roman", times, serif; margin-top: 0.3cm; margin-left: 0.5cm; margin-bottom: 0.3cm;}
+p.dir {font-family: arial, sansserif; margin-top: 0cm; margin-bottom: 0cm;}
+dl { margin-left: 0.5cm; }
+dt { font-weight: bold; }
+a:link {color: black;}
+a:visited {color: black;}
+ul.disc {list-style-type: disc; font-family: times, serif;}
+ul.circle {list-style-type: circle; font-family: times, serif;}
+ul.square {list-style-type: square; font-family: times, serif;}
+ul.none {list-style-type: none; font-family: times, serif;}
+pre.code { margin-top: 1.0cm; margin-bottom: 1.0cm; margin-left: 1.0cm; margin-right: 1.0cm; border:3px solid #c0c0c0; padding: 0.5cm; font-family: tahoma, sansserif; font-weight: normal; background-color:#f8f8f8; }
+pre.command { margin-top: 1.0cm; margin-bottom: 1.0cm; margin-left: 1.5cm; margin-right: 0.0cm; border:0px; padding:0.0cm; font-family: tahoma, sansserif; font-weight: bold; background-color:#f8fffc; }
+ol.level1 { font-family: arial, sansserif; font-weight: bold; font-style: italic; font-size:1.5em; }
+ol.level2 { font-family: "Times New Roman", serif; font-weight: normal; font-style: normal; font-size:0.85em; margin-top: 0.2cm; margin-bottom: 0.5cm; }
+table.figure { margin-left:auto; margin-right:auto; margin-top:1.0cm; margin-bottom:1.0cm; }
+
+td.caption { font-family: arial, sansserif; font-size: 75%; color: black; }
+td { font-family: times, serif; }
+
+table.lt { border-collapse: collapse; border-style: none; }
+td.lt- { margin: 0px; padding: 4px; padding-left:0.3cm; padding-right:0.3cm; border-width: 1px; border-style: none; padding-left=0.2cm; padding-right=0.2cm; }
+td.lt-r { margin: 0px; padding: 4px; padding-left:0.3cm; padding-right:0.3cm; border-style: none; border-right-style: solid; border-width: 1px; border-color: black; }
+td.lt-l { margin: 0px; padding: 4px; padding-left:0.3cm; padding-right:0.3cm; border-style: none; border-left-style: solid; border-width: 1px; border-color: black; }
+td.lt-lr { margin: 0px; padding: 4px; padding-left:0.3cm; padding-right:0.3cm; border-style: none; border-right-style: solid; border-left-style: solid; border-width: 1px; border-color: black; }
+td.lt-b { margin: 0px; padding: 4px; padding-left:0.3cm; padding-right:0.3cm; border-style: none; border-bottom-style: solid; border-width: 1px; border-color: black; }
+td.lt-hl { margin: 0px; border-style: none; border-bottom-style: solid; border-width: 1px; border-color: black; height: 2px; }
+td.lt-bl { margin: 0px; padding: 4px; padding-left:0.3cm; padding-right:0.3cm; border-style: none; border-bottom-style: solid; border-left-style: solid; border-width: 1px; border-color: black; }
+td.lt-br { margin: 0px; padding: 4px; padding-left:0.3cm; padding-right:0.3cm; border-style: none; border-bottom-style: solid; border-right-style: solid; border-width: 1px; border-color: black; }
+td.lt-blr { margin: 0px; padding: 4px; padding-left:0.3cm; padding-right:0.3cm; border-style: none; border-bottom-style: solid; border-left-style: solid; border-right-style: solid; border-width: 1px; border-color: black; }
diff --git a/plugins/supereq/nsfft-1.00/doc/index.xhtml b/plugins/supereq/nsfft-1.00/doc/index.xhtml
new file mode 100644
index 00000000..8b7e2c97
--- /dev/null
+++ b/plugins/supereq/nsfft-1.00/doc/index.xhtml
@@ -0,0 +1,2016 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1 plus MathML 2.0//EN" "http://www.w3.org/Math/DTD/mathml2/xhtml-math11-f.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+<link rel="stylesheet" type="text/css" href="default.css"/>
+<title>NSFFT Reference Manual</title>
+</head>
+<body>
+<h1>NSFFT Reference Manual</h1>
+
+<h3>Introduction</h3>
+
+<p>
+This is a library for performing 1-dimensional discrete Fourier
+transforms. NSDFT is a simple, small and portable library, and it is
+efficient since it can utilize SIMD instruction sets in modern
+processors. It performs multiple transforms simultaneously, and thus
+it is especially suitable for digital signal processing. It does not
+need so much computation to make a good execution plan. This library
+is in public domain, so that you can incorporate this library into
+your product without any obligation.
+</p>
+
+<h3>API Reference</h3>
+
+<p>
+In this section, the API functions are explained.
+</p>
+
+<h4>Include files</h4>
+
+<p>
+You have to include two include files in dft directory.
+</p>
+
+<pre class="code">
+#include &lt;stdint.h&gt;
+#include "SIMDBase.h"
+#include "DFT.h"
+</pre>
+
+<h4>Data types</h4>
+
+<p>
+First, you have to choose a data type to represent an element in the
+input and output sequence of numbers. You can choose from the
+following three types.
+</p>
+
+<table class="figure">
+ <tr align="center">
+ <td>
+ <table class="lt">
+ <tr>
+ <td class="lt-hl"></td>
+ <td class="lt-hl"></td>
+ </tr>
+ <tr>
+ <td class="lt-br" align="center">Symbol</td>
+ <td class="lt-b" align="center">Data Type</td>
+ </tr>
+ <tr>
+ <td class="lt-hl"></td>
+ <td class="lt-hl"></td>
+ </tr>
+ <tr>
+ <td class="lt-r" align="left">SIMDBase_TYPE_FLOAT</td>
+ <td class="lt-" align="left">float type in C language</td>
+ </tr>
+ <tr>
+ <td class="lt-r" align="left">SIMDBase_TYPE_DOUBLE</td>
+ <td class="lt-" align="left">double type in C language</td>
+ </tr>
+ <tr>
+ <td class="lt-br" align="left">SIMDBase_TYPE_LONGDOUBLE</td>
+ <td class="lt-b" align="left">long double type in C language</td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ <tr align="center">
+ <td class="caption">Table 1 Data types</td>
+ </tr>
+</table>
+
+
+<h4>Computation modes</h4>
+
+<p>
+Next, a compuation mode have to be chosen. You can choose from the
+following modes.
+</p>
+
+<table class="figure">
+ <tr align="center">
+ <td>
+ <table class="lt">
+ <tr>
+ <td class="lt-hl"></td>
+ <td class="lt-hl"></td>
+ <td class="lt-hl"></td>
+ <td class="lt-hl"></td>
+ </tr>
+ <tr>
+ <td class="lt-br" align="center">Symbol</td>
+ <td class="lt-br" align="center">Type</td>
+ <td class="lt-br" align="center">Vector Length</td>
+ <td class="lt-b" align="center">Computation Mode</td>
+ </tr>
+ <tr>
+ <td class="lt-hl"></td>
+ <td class="lt-hl"></td>
+ <td class="lt-hl"></td>
+ <td class="lt-hl"></td>
+ </tr>
+ <tr>
+ <td class="lt-r" align="left">SIMDBase_MODE_PUREC_FLOAT</td>
+ <td class="lt-r" align="center">float</td>
+ <td class="lt-r" align="center">1</td>
+ <td class="lt-" align="center">Scalar float</td>
+ </tr>
+ <tr>
+ <td class="lt-r" align="left">SIMDBase_MODE_PUREC_DOUBLE</td>
+ <td class="lt-r" align="center">double</td>
+ <td class="lt-r" align="center">1</td>
+ <td class="lt-" align="center">Scalar double</td>
+ </tr>
+ <tr>
+ <td class="lt-r" align="left">SIMDBase_MODE_PUREC_LONGDOUBLE</td>
+ <td class="lt-r" align="center">long double</td>
+ <td class="lt-r" align="center">1</td>
+ <td class="lt-" align="center">Scalar long double</td>
+ </tr>
+ <tr>
+ <td class="lt-r" align="left">SIMDBase_MODE_SSE_FLOAT</td>
+ <td class="lt-r" align="center">float</td>
+ <td class="lt-r" align="center">4</td>
+ <td class="lt-" align="center">x86 SSE</td>
+ </tr>
+ <tr>
+ <td class="lt-r" align="left">SIMDBase_MODE_SSE2_DOUBLE</td>
+ <td class="lt-r" align="center">double</td>
+ <td class="lt-r" align="center">2</td>
+ <td class="lt-" align="center">x86 SSE2</td>
+ </tr>
+ <tr>
+ <td class="lt-r" align="left">SIMDBase_MODE_NEON_FLOAT</td>
+ <td class="lt-r" align="center">float</td>
+ <td class="lt-r" align="center">4</td>
+ <td class="lt-" align="center">ARM NEON</td>
+ </tr>
+ <tr>
+ <td class="lt-r" align="left">SIMDBase_MODE_AVX_FLOAT</td>
+ <td class="lt-r" align="center">float</td>
+ <td class="lt-r" align="center">8</td>
+ <td class="lt-" align="center">x86 AVX (float)</td>
+ </tr>
+ <tr>
+ <td class="lt-r" align="left">SIMDBase_MODE_AVX_DOUBLE</td>
+ <td class="lt-r" align="center">double</td>
+ <td class="lt-r" align="center">4</td>
+ <td class="lt-" align="center">x86 AVX (double)</td>
+ </tr>
+ <tr>
+ <td class="lt-br" align="left">SIMDBase_MODE_ALTIVEC_FLOAT</td>
+ <td class="lt-br" align="center">float</td>
+ <td class="lt-br" align="center">4</td>
+ <td class="lt-b" align="center">PowerPC Altivec</td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ <tr align="center">
+ <td class="caption">Table 2 Computation modes</td>
+ </tr>
+</table>
+
+<p>
+The following function automatically checks the availability of each
+instruction set on your computer, and chooses the best computation
+mode.
+</p>
+
+<pre class="code">
+int32_t SIMDBase_chooseBestMode(int32_t type);
+</pre>
+
+<p>
+The return value is the best mode chosen by this routine.
+<i>type</i> is the data type you chose.
+</p>
+
+
+<h4>Retrieving parameters</h4>
+
+<p>
+You can make queries for any mode using the following function.
+</p>
+
+<pre class="code">
+int32_t SIMDBase_getModeParamInt(int32_t paramId, int32_t mode);
+</pre>
+
+<p>
+<i>mode</i> is the computation mode you chose. <i>paramId</i> is one
+of the following.
+</p>
+
+<table class="figure">
+ <tr align="center">
+ <td>
+ <table class="lt">
+ <tr>
+ <td class="lt-hl"></td>
+ <td class="lt-hl"></td>
+ </tr>
+ <tr>
+ <td class="lt-br" align="center">Symbol</td>
+ <td class="lt-b" align="center">Meaning</td>
+ </tr>
+ <tr>
+ <td class="lt-hl"></td>
+ <td class="lt-hl"></td>
+ </tr>
+ <tr>
+ <td class="lt-r" align="left">SIMDBase_PARAMID_SIZE_OF_REAL</td>
+ <td class="lt-" align="left">Size of an element in a vector in byte</td>
+ </tr>
+ <tr>
+ <td class="lt-r" align="left">SIMDBase_PARAMID_SIZE_OF_VECT</td>
+ <td class="lt-" align="left">Size of the vector in byte</td>
+ </tr>
+ <tr>
+ <td class="lt-r" align="left">SIMDBase_PARAMID_VECTOR_LEN</td>
+ <td class="lt-" align="left">Number of elements in a vector</td>
+ </tr>
+ <tr>
+ <td class="lt-br" align="left">SIMDBase_PARAMID_MODE_AVAILABILITY</td>
+ <td class="lt-b" align="left">Whether the given mode is available or not</td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ <tr align="center">
+ <td class="caption">Table 3 Querying parameter for computation mode</td>
+ </tr>
+</table>
+
+<p>
+Here, a vector is a set of multiple primitive data element (single or
+double precision FP number) which can be stored in one SIMD register,
+and can be processed by one SIMD instruction at the same time.
+</p>
+
+<p>
+You can get the mode name in string data type. In this
+case, <i>paramId</i> must be SIMDBase_PARAMID_MODE_NAME.
+</p>
+
+<pre class="code">
+char *SIMDBase_getModeParamString(int32_t paramId, int32_t mode);
+</pre>
+
+<p>
+You should not modify the data returned by the above function.
+</p>
+
+
+<h4>Making and destroying execution plan</h4>
+
+<p>
+An execution plan can be made by the following function.
+</p>
+
+<pre class="code">
+DFT *DFT_init(int32_t mode, int32_t n, int32_t flags);
+</pre>
+
+<p>
+The return value is a pointer to a newly made plan.
+<i>mode</i> is the mode you chose above. <i>n</i> is the length of a
+transform. You can specify a bitwise OR of the following symbols
+as <i>flags</i>. You should not specify more than one flags regarding
+to test run. You should not specify DFT_FLAG_FORCE_RECURSIVE and
+DFT_FLAG_FORCE_COBRA at the same time. If neither DFT_FLAG_REAL nor
+DFT_FLAG_ALT_REAL is specified, an execution plan for complex
+transforms are made.
+</p>
+
+<table class="figure">
+ <tr align="center">
+ <td>
+ <table class="lt">
+ <tr>
+ <td class="lt-hl"></td>
+ <td class="lt-hl"></td>
+ </tr>
+ <tr>
+ <td class="lt-br" align="center">Symbol</td>
+ <td class="lt-b" align="center">Meaning</td>
+ </tr>
+ <tr>
+ <td class="lt-hl"></td>
+ <td class="lt-hl"></td>
+ </tr>
+ <tr>
+ <td class="lt-r" align="left">DFT_FLAG_NO_TEST_RUN</td>
+ <td class="lt-" align="left">Make execution plan without performing a test run</td>
+ </tr>
+ <tr>
+ <td class="lt-r" align="left">DFT_FLAG_LIGHT_TEST_RUN</td>
+ <td class="lt-" align="left">Perform small amount of test run to make an execution plan</td>
+ </tr>
+ <tr>
+ <td class="lt-r" align="left">DFT_FLAG_HEAVY_TEST_RUN</td>
+ <td class="lt-" align="left">Perform large amount of test run to make an execution plan</td>
+ </tr>
+ <tr>
+ <td class="lt-r" align="left">DFT_FLAG_EXHAUSTIVE_TEST_RUN</td>
+ <td class="lt-" align="left">Perform exhaustive search of parameters and find the optimal execution plan</td>
+ </tr>
+ <tr>
+ <td class="lt-r" align="left">DFT_FLAG_REAL</td>
+ <td class="lt-" align="left">Make an execution plan for a real transform</td>
+ </tr>
+ <tr>
+ <td class="lt-r" align="left">DFT_FLAG_ALT_REAL</td>
+ <td class="lt-" align="left">Make an execution plan for an alternative real transform</td>
+ </tr>
+ <tr>
+ <td class="lt-r" align="left">DFT_FLAG_VERBOSE</td>
+ <td class="lt-" align="left">Make some noise during making an execution plan</td>
+ </tr>
+ <tr>
+ <td class="lt-r" align="left">DFT_FLAG_NOBITREVERSAL</td>
+ <td class="lt-" align="left">Does not perforam bitreversal operation during a transform</td>
+ </tr>
+ <tr>
+ <td class="lt-r" align="left">DFT_FLAG_FORCE_RECURSIVE</td>
+ <td class="lt-" align="left">Force using the recursive bit-reveral routine. This routine is suited for small transforms.</td>
+ </tr>
+ <tr>
+ <td class="lt-br" align="left">DFT_FLAG_FORCE_COBRA</td>
+ <td class="lt-b" align="left">Force using the Cobra bit-reveral routine. This routine is suited for large transforms.</td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ <tr align="center">
+ <td class="caption">Table 4 Options for making execution plan</td>
+ </tr>
+</table>
+
+<p>
+You can destroy the plan you made by the following function.
+</p>
+
+<pre class="code">
+void DFT_dispose(DFT *p, int32_t mode);
+</pre>
+
+<p>
+<i>p</i> is a pointer to the execution plan. <i>mode</i> is the
+corresponding execution mode.
+</p>
+
+<p>
+You can retrieve parameters of a plan using the following function.
+</p>
+
+<pre class="code">
+int32_t DFT_getPlanParamInt(int32_t paramId, void *p);
+</pre>
+
+<p>
+<i>p</i> is a pointer to an execution plan. <i>paramId</i> is one
+of the following.
+</p>
+
+<table class="figure">
+ <tr align="center">
+ <td>
+ <table class="lt">
+ <tr>
+ <td class="lt-hl"></td>
+ <td class="lt-hl"></td>
+ </tr>
+ <tr>
+ <td class="lt-br" align="center">Symbol</td>
+ <td class="lt-b" align="center">Meaning</td>
+ </tr>
+ <tr>
+ <td class="lt-hl"></td>
+ <td class="lt-hl"></td>
+ </tr>
+ <tr>
+ <td class="lt-r" align="left">DFT_PARAMID_TYPE</td>
+ <td class="lt-" align="left">Data type</td>
+ </tr>
+ <tr>
+ <td class="lt-r" align="left">DFT_PARAMID_MODE</td>
+ <td class="lt-" align="left">Computation mode</td>
+ </tr>
+ <tr>
+ <td class="lt-r" align="left">DFT_PARAMID_FFT_LENGTH</td>
+ <td class="lt-" align="left">Length of the transform</td>
+ </tr>
+ <tr>
+ <td class="lt-r" align="left">DFT_PARAMID_IS_REAL_TRANSFORM</td>
+ <td class="lt-" align="left">Whether the plan is for real transforms</td>
+ </tr>
+ <tr>
+ <td class="lt-r" align="left">DFT_PARAMID_NO_BIT_REVERSAL</td>
+ <td class="lt-" align="left">Whether the plan does not perform bit reversal operation</td>
+ </tr>
+ <tr>
+ <td class="lt-br" align="left">DFT_PARAMID_TEST_RUN</td>
+ <td class="lt-b" align="left">How much test run is performed when making this plan</td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ <tr align="center">
+ <td class="caption">Table 5 Querying parameter for execution plan</td>
+ </tr>
+</table>
+
+<h4>Writing and reading execution plan to/from file</h4>
+
+<p>
+You can write or read an execution plan to/from a file using the following functions.
+</p>
+
+<pre class="code">
+int32_t DFT_fwrite(DFT *p, FILE *fp);
+DFT *DFT_fread(FILE *fp, int32_t *errcode);
+</pre>
+
+<p>
+<i>p</i> is a pointer to a plan. <i>fp</i> is a file
+pointer. DFT_fwrite returns 1 if the plan is successfully written, and
+0 if an error occurs. DFT_fread returns the pointer to the read plan
+if the plan is successfully read, and NULL if an error occurs. If an
+error occurs, an error code is returned to a variable whose pointer is
+specified by <i>errcode</i>. The interpretation of error codes is
+given below.
+</p>
+
+<table class="figure">
+ <tr align="center">
+ <td>
+ <table class="lt">
+ <tr>
+ <td class="lt-hl"></td>
+ <td class="lt-hl"></td>
+ </tr>
+ <tr>
+ <td class="lt-br" align="center">Symbol</td>
+ <td class="lt-b" align="center">Meaning</td>
+ </tr>
+ <tr>
+ <td class="lt-hl"></td>
+ <td class="lt-hl"></td>
+ </tr>
+ <tr>
+ <td class="lt-r" align="left">DFT_ERROR_NOERROR</td>
+ <td class="lt-" align="left">No error</td>
+ </tr>
+ <tr>
+ <td class="lt-r" align="left">DFT_ERROR_FILE_VERSION</td>
+ <td class="lt-" align="left">File format version mismatch</td>
+ </tr>
+ <tr>
+ <td class="lt-r" align="left">DFT_ERROR_FILE_IO</td>
+ <td class="lt-" align="left">I/O error</td>
+ </tr>
+ <tr>
+ <td class="lt-r" align="left">DFT_ERROR_UNEXPECTED_EOF</td>
+ <td class="lt-" align="left">Unexpected EOF</td>
+ </tr>
+ <tr>
+ <td class="lt-r" align="left">DFT_ERROR_MODE_NOT_COMPILED_IN</td>
+ <td class="lt-" align="left">Tried to read a plan with mode that is not compiled in</td>
+ </tr>
+ <tr>
+ <td class="lt-r" align="left">DFT_ERROR_MODE_NOT_AVAILABLE</td>
+ <td class="lt-" align="left">Tried to read a plan with mode that is not supported by hardware</td>
+ </tr>
+ <tr>
+ <td class="lt-br" align="left">DFT_ERROR_UNKNOWN_MODE</td>
+ <td class="lt-b" align="left">Tried to read a plan with mode that is unknown by library</td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ <tr align="center">
+ <td class="caption">Table 6 Errors that may happen during file I/O</td>
+ </tr>
+</table>
+
+
+<h4>Allocating and freeing buffers for transforms</h4>
+
+<p>
+In order to allocate word-aligned buffers for storing data which is
+fed to the FFT routine, you have to use the following function.
+</p>
+
+<pre class="code">
+void *DFT_alignedMalloc(uint64_t size);
+</pre>
+
+<p>
+This function allocates <i>size</i> bytes of word-aligned memory and
+returns the pointer. In order to free this memory, you have to use the
+following function.
+</p>
+
+<pre class="code">
+void DFT_alignedFree(void *ptr);
+</pre>
+
+<p>
+<i>ptr</i> is the pointer returned from DFT_alignedMalloc function.
+</p>
+
+<h4>Executing transform</h4>
+
+<p>
+By the following function, the planned transform can be executed.
+</p>
+
+<pre class="code">
+void DFT_execute(DFT *p, int32_t mode, void *s, int32_t dir);
+</pre>
+
+<p>
+<i>p</i> is a pointer to the plan. <i>mode</i> is the computation
+mode. <i>s</i> is the pointer to the buffer in which the sequence of
+input values is stored. This pointer must be a pointer returned from
+DFT_alignedMalloc function.
+<i>dir</i> specifies the direction of transform.
+</p>
+
+<p>
+The forward and backward discrete Fourier transforms are defined by
+the following formula (1) and (2), respectively.
+</p>
+
+<table border="0" style="margin-right:1.0cm; margin-left:1.0cm; margin-top:0.5cm; margin-bottom:0.5cm;">
+ <tr>
+ <td align="center" style="width:100%;">
+ <math mode="display" style="font-size:1.2em;" xmlns="http://www.w3.org/1998/Math/MathML">
+ <mrow>
+ <msub><mi>X</mi><mi>k</mi></msub>
+ <mo>=</mo>
+ <munderover>
+ <mo style="font-size:140%;">&Sum;</mo>
+ <mrow><mi>n</mi><mo>=</mo><mn>0</mn></mrow>
+ <mrow><mi>N</mi><mo>-</mo><mn>1</mn></mrow>
+ </munderover>
+ <msub><mi>x</mi><mi>n</mi></msub>
+ <msup>
+ <mi>e</mi>
+ <mrow>
+ <mo>-</mo>
+ <mfrac>
+ <mrow><mn>2</mn><mi>&pi;</mi><mi>i</mi></mrow>
+ <mi>N</mi>
+ </mfrac>
+ <mi>k</mi><mi>n</mi>
+ </mrow>
+ </msup>
+
+ <mo>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</mo>
+
+ <mi>k</mi>
+ <mo>=</mo>
+ <mn>0</mn>
+ <mo>,</mo>
+ <mo>&middot;</mo>
+ <mo>&middot;</mo>
+ <mo>&middot;</mo>
+ <mo>,</mo>
+ <mi>N</mi>
+ <mo>-</mo>
+ <mn>1</mn>
+ </mrow>
+ </math>
+ </td>
+ <td>
+ <p>(1)</p>
+ </td>
+ </tr>
+ <tr>
+ <td align="center" style="width:100%;">
+ <math mode="display" style="font-size:1.2em;" xmlns="http://www.w3.org/1998/Math/MathML">
+ <mrow>
+ <msub><mi>x</mi><mi>n</mi></msub>
+ <mo>=</mo>
+ <mfrac>
+ <mn>1</mn>
+ <mi>N</mi>
+ </mfrac>
+ <munderover>
+ <mo style="font-size:140%;">&Sum;</mo>
+ <mrow><mi>k</mi><mo>=</mo><mn>0</mn></mrow>
+ <mrow><mi>N</mi><mo>-</mo><mn>1</mn></mrow>
+ </munderover>
+ <msub><mi>X</mi><mi>k</mi></msub>
+ <msup>
+ <mi>e</mi>
+ <mrow>
+ <mfrac>
+ <mrow><mn>2</mn><mi>&pi;</mi><mi>i</mi></mrow>
+ <mi>N</mi>
+ </mfrac>
+ <mi>k</mi><mi>n</mi>
+ </mrow>
+ </msup>
+
+ <mo>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</mo>
+
+ <mi>n</mi>
+ <mo>=</mo>
+ <mn>0</mn>
+ <mo>,</mo>
+ <mo>&middot;</mo>
+ <mo>&middot;</mo>
+ <mo>&middot;</mo>
+ <mo>,</mo>
+ <mi>N</mi>
+ <mo>-</mo>
+ <mn>1</mn>
+
+ </mrow>
+ </math>
+ </td>
+ <td>
+ <p>(2)</p>
+ </td>
+ </tr>
+</table>
+
+<p>
+The complex forward and backward transforms perform the transforms
+defined by the following formula (3) and (4), respectively. <i>V</i>
+is the vector length mentioned above. Again, calling DFT_execute once
+performs <i>V</i> forward or backward transforms at a time. Please
+note that (4) gives values multiplied by <i>N</i> compared to
+(2). Specifying -1 as the direction of transform performs the
+transform defined by (3). In this case, the input should be given as
+in (5) , and the output is given as in (6). Specifying 1 as the
+direction of transform performs the transform defined by (4), and in
+this case, the input should be given as in (6) , and the output is
+given as in (5).
+</p>
+
+<table border="0" style="margin-right:1.0cm; margin-left:1.0cm; margin-top:0.5cm; margin-bottom:0.5cm;">
+ <tr>
+ <td align="center" style="width:100%;">
+ <math mode="display" style="font-size:1.2em;" xmlns="http://www.w3.org/1998/Math/MathML">
+ <mrow>
+ <msub><mi>X</mi><mrow><mi>k</mi><mo>,</mo><mi>v</mi></mrow></msub>
+ <mo>=</mo>
+ <munderover>
+ <mo style="font-size:140%;">&Sum;</mo>
+ <mrow><mi>n</mi><mo>=</mo><mn>0</mn></mrow>
+ <mrow><mi>N</mi><mo>-</mo><mn>1</mn></mrow>
+ </munderover>
+ <msub><mi>x</mi><mrow><mi>n</mi><mo>,</mo><mi>v</mi></mrow></msub>
+ <msup>
+ <mi>e</mi>
+ <mrow>
+ <mo>-</mo>
+ <mfrac>
+ <mrow><mn>2</mn><mi>&pi;</mi><mi>i</mi></mrow>
+ <mi>N</mi>
+ </mfrac>
+ <mi>k</mi><mi>n</mi>
+ </mrow>
+ </msup>
+
+ <mo>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</mo>
+
+ <mrow style="font-size:100%;">
+ <mi>k</mi>
+ <mo>=</mo>
+ <mn>0</mn>
+ <mo>,</mo>
+ <mo>&middot;</mo>
+ <mo>&middot;</mo>
+ <mo>&middot;</mo>
+ <mo>,</mo>
+ <mi>N</mi>
+ <mo>-</mo>
+ <mn>1</mn>
+
+ <mo>&nbsp;&nbsp;</mo>
+ <mo>,</mo>
+ <mo>&nbsp;&nbsp;</mo>
+
+ <mi>v</mi>
+ <mo>=</mo>
+ <mn>0</mn>
+ <mo>,</mo>
+ <mo>&middot;</mo>
+ <mo>&middot;</mo>
+ <mo>&middot;</mo>
+ <mo>,</mo>
+ <mi>V</mi>
+ <mo>-</mo>
+ <mn>1</mn>
+ </mrow>
+ </mrow>
+ </math>
+ </td>
+ <td>
+ <p>(3)</p>
+ </td>
+ </tr>
+ <tr>
+ <td align="center" style="width:100%;">
+ <math mode="display" style="font-size:1.2em;" xmlns="http://www.w3.org/1998/Math/MathML">
+ <mrow>
+ <msub><mi>x</mi><mrow><mi>n</mi><mo>,</mo><mi>v</mi></mrow></msub>
+ <mo>=</mo>
+ <munderover>
+ <mo style="font-size:140%;">&Sum;</mo>
+ <mrow><mi>k</mi><mo>=</mo><mn>0</mn></mrow>
+ <mrow><mi>N</mi><mo>-</mo><mn>1</mn></mrow>
+ </munderover>
+ <msub><mi>X</mi><mrow><mi>k</mi><mo>,</mo><mi>v</mi></mrow></msub>
+ <msup>
+ <mi>e</mi>
+ <mrow>
+ <mfrac>
+ <mrow><mn>2</mn><mi>&pi;</mi><mi>i</mi></mrow>
+ <mi>N</mi>
+ </mfrac>
+ <mi>k</mi><mi>n</mi>
+ </mrow>
+ </msup>
+
+ <mo>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</mo>
+
+ <mrow style="font-size:100%;">
+ <mi>n</mi>
+ <mo>=</mo>
+ <mn>0</mn>
+ <mo>,</mo>
+ <mo>&middot;</mo>
+ <mo>&middot;</mo>
+ <mo>&middot;</mo>
+ <mo>,</mo>
+ <mi>N</mi>
+ <mo>-</mo>
+ <mn>1</mn>
+
+ <mo>&nbsp;&nbsp;</mo>
+ <mo>,</mo>
+ <mo>&nbsp;&nbsp;</mo>
+
+ <mi>v</mi>
+ <mo>=</mo>
+ <mn>0</mn>
+ <mo>,</mo>
+ <mo>&middot;</mo>
+ <mo>&middot;</mo>
+ <mo>&middot;</mo>
+ <mo>,</mo>
+ <mi>V</mi>
+ <mo>-</mo>
+ <mn>1</mn>
+ </mrow>
+ </mrow>
+ </math>
+ </td>
+ <td>
+ <p>(4)</p>
+ </td>
+ </tr>
+</table>
+
+<table border="0" style="margin-right:1.0cm; margin-left:1.0cm; margin-top:0.5cm; margin-bottom:0.5cm;">
+ <tr>
+ <td align="center" style="width:100%;">
+ <math mode="display" style="font-size:1.2em;" xmlns="http://www.w3.org/1998/Math/MathML">
+ <mrow>
+ <mfenced open="{" close="">
+ <mtable>
+ <mtr>
+ <mtd>
+ <mrow>
+ <mi>s</mi>
+ <mo>[</mo>
+ <mo>(</mo>
+ <mn>2</mn>
+ <mi>n</mi>
+ <mo>+</mo>
+ <mn>0</mn>
+ <mo>)</mo>
+ <mi>V</mi>
+ <mo>+</mo>
+ <mi>v</mi>
+ <mo>]</mo>
+
+ <mo>=</mo>
+
+ <mi>Re</mi>
+ <mo>(</mo>
+ <msub><mi>x</mi><mrow><mi>n</mi><mo>,</mo><mi>v</mi></mrow></msub>
+ <mo>)</mo>
+ </mrow>
+ </mtd>
+ </mtr>
+
+ <mtr>
+ <mtd>
+ <mrow>
+ <mi>s</mi>
+ <mo>[</mo>
+ <mo>(</mo>
+ <mn>2</mn>
+ <mi>n</mi>
+ <mo>+</mo>
+ <mn>1</mn>
+ <mo>)</mo>
+ <mi>V</mi>
+ <mo>+</mo>
+ <mi>v</mi>
+ <mo>]</mo>
+
+ <mo>=</mo>
+
+ <mi>Im</mi>
+ <mo>(</mo>
+ <msub><mi>x</mi><mrow><mi>n</mi><mo>,</mo><mi>v</mi></mrow></msub>
+ <mo>)</mo>
+ </mrow>
+ </mtd>
+ </mtr>
+
+ </mtable>
+ </mfenced>
+
+ <mo>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</mo>
+
+ <mrow style="font-size:100%;">
+ <mi>n</mi>
+ <mo>=</mo>
+ <mn>0</mn>
+ <mo>,</mo>
+ <mo>&middot;</mo>
+ <mo>&middot;</mo>
+ <mo>&middot;</mo>
+ <mo>,</mo>
+ <mi>N</mi>
+ <mo>-</mo>
+ <mn>1</mn>
+
+ <mo>&nbsp;&nbsp;</mo>
+ <mo>,</mo>
+ <mo>&nbsp;&nbsp;</mo>
+
+ <mi>v</mi>
+ <mo>=</mo>
+ <mn>0</mn>
+ <mo>,</mo>
+ <mo>&middot;</mo>
+ <mo>&middot;</mo>
+ <mo>&middot;</mo>
+ <mo>,</mo>
+ <mi>V</mi>
+ <mo>-</mo>
+ <mn>1</mn>
+ </mrow>
+ </mrow>
+ </math>
+ </td>
+ <td>
+ <p>(5)</p>
+ </td>
+ </tr>
+</table>
+
+<table border="0" style="margin-right:1.0cm; margin-left:1.0cm; margin-top:0.5cm; margin-bottom:0.5cm;">
+ <tr>
+ <td align="center" style="width:100%;">
+ <math mode="display" style="font-size:1.2em;" xmlns="http://www.w3.org/1998/Math/MathML">
+ <mrow>
+ <mfenced open="{" close="">
+ <mtable>
+ <mtr>
+ <mtd>
+ <mrow>
+ <mi>s</mi>
+ <mo>[</mo>
+ <mo>(</mo>
+ <mn>2</mn>
+ <mi>k</mi>
+ <mo>+</mo>
+ <mn>0</mn>
+ <mo>)</mo>
+ <mi>V</mi>
+ <mo>+</mo>
+ <mi>v</mi>
+ <mo>]</mo>
+
+ <mo>=</mo>
+
+ <mi>Re</mi>
+ <mo>(</mo>
+ <msub><mi>X</mi><mrow><mi>k</mi><mo>,</mo><mi>v</mi></mrow></msub>
+ <mo>)</mo>
+ </mrow>
+ </mtd>
+ </mtr>
+
+ <mtr>
+ <mtd>
+ <mrow>
+ <mi>s</mi>
+ <mo>[</mo>
+ <mo>(</mo>
+ <mn>2</mn>
+ <mi>k</mi>
+ <mo>+</mo>
+ <mn>1</mn>
+ <mo>)</mo>
+ <mi>V</mi>
+ <mo>+</mo>
+ <mi>v</mi>
+ <mo>]</mo>
+
+ <mo>=</mo>
+
+ <mi>Im</mi>
+ <mo>(</mo>
+ <msub><mi>X</mi><mrow><mi>k</mi><mo>,</mo><mi>v</mi></mrow></msub>
+ <mo>)</mo>
+ </mrow>
+ </mtd>
+ </mtr>
+
+ </mtable>
+ </mfenced>
+
+ <mo>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</mo>
+
+ <mrow style="font-size:100%;">
+ <mi>k</mi>
+ <mo>=</mo>
+ <mn>0</mn>
+ <mo>,</mo>
+ <mo>&middot;</mo>
+ <mo>&middot;</mo>
+ <mo>&middot;</mo>
+ <mo>,</mo>
+ <mi>N</mi>
+ <mo>-</mo>
+ <mn>1</mn>
+
+ <mo>&nbsp;&nbsp;</mo>
+ <mo>,</mo>
+ <mo>&nbsp;&nbsp;</mo>
+
+ <mi>v</mi>
+ <mo>=</mo>
+ <mn>0</mn>
+ <mo>,</mo>
+ <mo>&middot;</mo>
+ <mo>&middot;</mo>
+ <mo>&middot;</mo>
+ <mo>,</mo>
+ <mi>V</mi>
+ <mo>-</mo>
+ <mn>1</mn>
+ </mrow>
+ </mrow>
+ </math>
+ </td>
+ <td>
+ <p>(6)</p>
+ </td>
+ </tr>
+</table>
+
+<p>
+The real forward transform performs the transform defined by (3) when
+the condition (7) is satisfied. In this case, the output satisfies
+(8). You should specify -1 as the direction of transform, and the
+input should be given as in (9), and the output is given as in (10).
+The real backward transform is the opposite of the real forward
+transform. The input should satisfy (8) and the output satisfies (7).
+You should specify 1 as the direction of transform, and the input
+should be given as in (10), and the output is given as in (11).
+</p>
+
+<table border="0" style="margin-right:1.0cm; margin-left:1.0cm; margin-top:0.5cm; margin-bottom:0.5cm;">
+ <tr>
+ <td align="center" style="width:100%;">
+ <math mode="display" style="font-size:1.2em;" xmlns="http://www.w3.org/1998/Math/MathML">
+ <mrow>
+ <mi>Im</mi>
+ <mo>(</mo>
+ <msub><mi>x</mi><mrow><mi>n</mi><mo>,</mo><mi>v</mi></mrow></msub>
+ <mo>)</mo>
+ <mo>=</mo>
+ <mn>0</mn>
+
+ <mo>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</mo>
+
+ <mrow style="font-size:100%;">
+ <mi>n</mi>
+ <mo>=</mo>
+ <mn>0</mn>
+ <mo>,</mo>
+ <mo>&middot;</mo>
+ <mo>&middot;</mo>
+ <mo>&middot;</mo>
+ <mo>,</mo>
+ <mi>N</mi>
+ <mo>-</mo>
+ <mn>1</mn>
+
+ <mo>&nbsp;&nbsp;</mo>
+ <mo>,</mo>
+ <mo>&nbsp;&nbsp;</mo>
+
+ <mi>v</mi>
+ <mo>=</mo>
+ <mn>0</mn>
+ <mo>,</mo>
+ <mo>&middot;</mo>
+ <mo>&middot;</mo>
+ <mo>&middot;</mo>
+ <mo>,</mo>
+ <mi>V</mi>
+ <mo>-</mo>
+ <mn>1</mn>
+ </mrow>
+
+ </mrow>
+ </math>
+ </td>
+ <td>
+ <p>(7)</p>
+ </td>
+ </tr>
+</table>
+
+<table border="0" style="margin-right:1.0cm; margin-left:1.0cm; margin-top:0.5cm; margin-bottom:0.5cm;">
+ <tr>
+ <td align="center" style="width:100%;">
+ <math mode="display" style="font-size:1.2em;" xmlns="http://www.w3.org/1998/Math/MathML">
+ <mrow>
+ <mfenced open="{" close="">
+ <mtable>
+ <mtr>
+ <mtd>
+ <mrow>
+ <msub><mi>X</mi><mrow><mi>k</mi><mo>,</mo><mi>v</mi></mrow></msub>
+ <mo>=</mo>
+ <msubsup>
+ <mi>X</mi>
+ <mrow><mi>N</mi><mo>-</mo><mi>k</mi><mo>,</mo><mi>v</mi></mrow>
+ <mo>*</mo>
+ </msubsup>
+ </mrow>
+ </mtd>
+
+ <mtd>
+ <mo>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</mo>
+ </mtd>
+
+ <mtd>
+ <mrow style="font-size:100%;">
+ <mi>k</mi>
+ <mo>=</mo>
+ <mn>1</mn>
+ <mo>,</mo>
+ <mo>&middot;</mo>
+ <mo>&middot;</mo>
+ <mo>&middot;</mo>
+ <mo>,</mo>
+ <mfrac>
+ <mi>N</mi>
+ <mn>2</mn>
+ </mfrac>
+ <mo>-</mo>
+ <mn>1</mn>
+ </mrow>
+ </mtd>
+ </mtr>
+
+ <mtr>
+ <mtd>
+ <mrow>
+ <mi>Im</mi>
+ <mo>(</mo>
+ <msub><mi>X</mi><mrow><mi>k</mi><mo>,</mo><mi>v</mi></mrow></msub>
+ <mo>)</mo>
+ <mo>=</mo>
+ <mn>0</mn>
+ </mrow>
+ </mtd>
+
+ <mtd>
+ <mo>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</mo>
+ </mtd>
+
+ <mtd>
+ <mrow style="font-size:100%;">
+ <mi>k</mi>
+ <mo>=</mo>
+ <mn>0</mn>
+ <mo>,</mo>
+ <mfrac>
+ <mi>N</mi>
+ <mn>2</mn>
+ </mfrac>
+ </mrow>
+ </mtd>
+ </mtr>
+
+ </mtable>
+ </mfenced>
+
+ <mo>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</mo>
+
+ <mrow style="font-size:100%;">
+ <mi>v</mi>
+ <mo>=</mo>
+ <mn>0</mn>
+ <mo>,</mo>
+ <mo>&middot;</mo>
+ <mo>&middot;</mo>
+ <mo>&middot;</mo>
+ <mo>,</mo>
+ <mi>V</mi>
+ <mo>-</mo>
+ <mn>1</mn>
+ </mrow>
+ </mrow>
+ </math>
+ </td>
+ <td>
+ <p>(8)</p>
+ </td>
+ </tr>
+</table>
+
+<table border="0" style="margin-right:1.0cm; margin-left:1.0cm; margin-top:0.5cm; margin-bottom:0.5cm;">
+ <tr>
+ <td align="center" style="width:100%;">
+ <math mode="display" style="font-size:1.2em;" xmlns="http://www.w3.org/1998/Math/MathML">
+ <mrow>
+ <mrow>
+ <mi>s</mi>
+ <mo>[</mo>
+ <mi>n</mi>
+ <mi>V</mi>
+ <mo>+</mo>
+ <mi>v</mi>
+ <mo>]</mo>
+
+ <mo>=</mo>
+
+ <mi>Re</mi>
+ <mo>(</mo>
+ <msub><mi>x</mi><mrow><mi>n</mi><mo>,</mo><mi>v</mi></mrow></msub>
+ <mo>)</mo>
+ </mrow>
+
+ <mo>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</mo>
+
+ <mrow style="font-size:100%;">
+ <mi>n</mi>
+ <mo>=</mo>
+ <mn>0</mn>
+ <mo>,</mo>
+ <mo>&middot;</mo>
+ <mo>&middot;</mo>
+ <mo>&middot;</mo>
+ <mo>,</mo>
+ <mi>N</mi>
+ <mo>-</mo>
+ <mn>1</mn>
+
+ <mo>&nbsp;&nbsp;</mo>
+ <mo>,</mo>
+ <mo>&nbsp;&nbsp;</mo>
+
+ <mi>v</mi>
+ <mo>=</mo>
+ <mn>0</mn>
+ <mo>,</mo>
+ <mo>&middot;</mo>
+ <mo>&middot;</mo>
+ <mo>&middot;</mo>
+ <mo>,</mo>
+ <mi>V</mi>
+ <mo>-</mo>
+ <mn>1</mn>
+ </mrow>
+ </mrow>
+ </math>
+ </td>
+ <td>
+ <p>(9)</p>
+ </td>
+ </tr>
+</table>
+
+<table border="0" style="margin-right:1.0cm; margin-left:1.0cm; margin-top:0.5cm; margin-bottom:0.5cm;">
+ <tr>
+ <td align="center" style="width:100%;">
+ <math mode="display" style="font-size:1.2em;" xmlns="http://www.w3.org/1998/Math/MathML">
+ <mrow>
+ <mfenced open="{" close="">
+ <mtable>
+ <mtr>
+ <mtd>
+ <mrow>
+ <mi>s</mi>
+ <mo>[</mo>
+ <mo>(</mo>
+ <mn>2</mn>
+ <mi>k</mi>
+ <mo>+</mo>
+ <mn>0</mn>
+ <mo>)</mo>
+ <mi>V</mi>
+ <mo>+</mo>
+ <mi>v</mi>
+ <mo>]</mo>
+ </mrow>
+ </mtd>
+
+ <mtd>
+ <mo>=</mo>
+ </mtd>
+
+ <mtd>
+ <mrow>
+ <mi>Re</mi>
+ <mo>(</mo>
+ <msub><mi>X</mi><mrow><mi>k</mi><mo>,</mo><mi>v</mi></mrow></msub>
+ <mo>)</mo>
+ </mrow>
+ </mtd>
+
+ <mtd>
+ <mrow style="font-size:100%;">
+ <mi>k</mi>
+ <mo>=</mo>
+ <mn>0</mn>
+ <mo>,</mo>
+ <mo>&middot;</mo>
+ <mo>&middot;</mo>
+ <mo>&middot;</mo>
+ <mo>,</mo>
+ <mfrac>
+ <mi>N</mi>
+ <mn>2</mn>
+ </mfrac>
+ <mo>-</mo>
+ <mn>1</mn>
+ </mrow>
+ </mtd>
+ </mtr>
+
+ <mtr>
+ <mtd>
+ <mrow>
+ <mi>s</mi>
+ <mo>[</mo>
+ <mi>V</mi>
+ <mo>+</mo>
+ <mi>v</mi>
+ <mo>]</mo>
+ </mrow>
+ </mtd>
+
+ <mtd>
+ <mo>=</mo>
+ </mtd>
+
+ <mtd>
+ <mrow>
+ <mi>Re</mi>
+ <mo>(</mo>
+ <msub><mi>X</mi><mrow><mi>N</mi><mo>/</mo><mn>2</mn><mo>,</mo><mi>v</mi></mrow></msub>
+ <mo>)</mo>
+ </mrow>
+ </mtd>
+
+ <mtd>
+ </mtd>
+ </mtr>
+
+ <mtr>
+ <mtd>
+ <mrow>
+ <mi>s</mi>
+ <mo>[</mo>
+ <mo>(</mo>
+ <mn>2</mn>
+ <mi>k</mi>
+ <mo>+</mo>
+ <mn>1</mn>
+ <mo>)</mo>
+ <mi>V</mi>
+ <mo>+</mo>
+ <mi>v</mi>
+ <mo>]</mo>
+ </mrow>
+ </mtd>
+
+ <mtd>
+ <mo>=</mo>
+ </mtd>
+
+ <mtd>
+ <mrow>
+ <mi>Im</mi>
+ <mo>(</mo>
+ <msub><mi>X</mi><mrow><mi>k</mi><mo>,</mo><mi>v</mi></mrow></msub>
+ <mo>)</mo>
+ </mrow>
+ </mtd>
+
+ <mtd>
+ <mrow style="font-size:100%;">
+ <mi>k</mi>
+ <mo>=</mo>
+ <mn>1</mn>
+ <mo>,</mo>
+ <mo>&middot;</mo>
+ <mo>&middot;</mo>
+ <mo>&middot;</mo>
+ <mo>,</mo>
+ <mfrac>
+ <mi>N</mi>
+ <mn>2</mn>
+ </mfrac>
+ <mo>-</mo>
+ <mn>1</mn>
+ </mrow>
+ </mtd>
+ </mtr>
+
+ </mtable>
+ </mfenced>
+
+ <mo>&nbsp;&nbsp;&nbsp;&nbsp;</mo>
+
+ <mrow style="font-size:100%;">
+ <mi>v</mi>
+ <mo>=</mo>
+ <mn>0</mn>
+ <mo>,</mo>
+ <mo>&middot;</mo>
+ <mo>&middot;</mo>
+ <mo>&middot;</mo>
+ <mo>,</mo>
+ <mi>V</mi>
+ <mo>-</mo>
+ <mn>1</mn>
+ </mrow>
+ </mrow>
+ </math>
+ </td>
+ <td>
+ <p>(10)</p>
+ </td>
+ </tr>
+</table>
+
+<table border="0" style="margin-right:1.0cm; margin-left:1.0cm; margin-top:0.5cm; margin-bottom:0.5cm;">
+ <tr>
+ <td align="center" style="width:100%;">
+ <math mode="display" style="font-size:1.2em;" xmlns="http://www.w3.org/1998/Math/MathML">
+ <mrow>
+ <mrow>
+ <mn>2</mn>
+ <mo> &nbsp; </mo>
+ <mi>s</mi>
+ <mo>[</mo>
+ <mi>n</mi>
+ <mi>V</mi>
+ <mo>+</mo>
+ <mi>v</mi>
+ <mo>]</mo>
+
+ <mo>=</mo>
+
+ <mi>Re</mi>
+ <mo>(</mo>
+ <msub><mi>x</mi><mrow><mi>n</mi><mo>,</mo><mi>v</mi></mrow></msub>
+ <mo>)</mo>
+ </mrow>
+
+ <mo>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</mo>
+
+ <mrow style="font-size:100%;">
+ <mi>n</mi>
+ <mo>=</mo>
+ <mn>0</mn>
+ <mo>,</mo>
+ <mo>&middot;</mo>
+ <mo>&middot;</mo>
+ <mo>&middot;</mo>
+ <mo>,</mo>
+ <mi>N</mi>
+ <mo>-</mo>
+ <mn>1</mn>
+
+ <mo>&nbsp;&nbsp;</mo>
+ <mo>,</mo>
+ <mo>&nbsp;&nbsp;</mo>
+
+ <mi>v</mi>
+ <mo>=</mo>
+ <mn>0</mn>
+ <mo>,</mo>
+ <mo>&middot;</mo>
+ <mo>&middot;</mo>
+ <mo>&middot;</mo>
+ <mo>,</mo>
+ <mi>V</mi>
+ <mo>-</mo>
+ <mn>1</mn>
+ </mrow>
+ </mrow>
+ </math>
+ </td>
+ <td>
+ <p>(11)</p>
+ </td>
+ </tr>
+</table>
+
+<p>
+The alternative real transforms are defined by (12) to (16), similarly
+to the real transforms. The alternative transforms are handy if you
+are migrating from the FFT library made by Prof. Takuya Ooura. You
+should specify 1 as the direction in order to perform a forward
+transform, and -1 when you perform a backward transform.
+</p>
+
+<table border="0" style="margin-right:1.0cm; margin-left:1.0cm; margin-top:0.5cm; margin-bottom:0.5cm;">
+ <tr>
+ <td align="center" style="width:100%;">
+ <math mode="display" style="font-size:1.2em;" xmlns="http://www.w3.org/1998/Math/MathML">
+ <mrow>
+ <mi>Im</mi>
+ <mo>(</mo>
+ <msub><mi>X</mi><mrow><mi>k</mi><mo>,</mo><mi>v</mi></mrow></msub>
+ <mo>)</mo>
+ <mo>=</mo>
+ <mn>0</mn>
+
+ <mo>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</mo>
+
+ <mrow style="font-size:100%;">
+ <mi>k</mi>
+ <mo>=</mo>
+ <mn>0</mn>
+ <mo>,</mo>
+ <mo>&middot;</mo>
+ <mo>&middot;</mo>
+ <mo>&middot;</mo>
+ <mo>,</mo>
+ <mi>N</mi>
+ <mo>-</mo>
+ <mn>1</mn>
+
+ <mo>&nbsp;&nbsp;</mo>
+ <mo>,</mo>
+ <mo>&nbsp;&nbsp;</mo>
+
+ <mi>v</mi>
+ <mo>=</mo>
+ <mn>0</mn>
+ <mo>,</mo>
+ <mo>&middot;</mo>
+ <mo>&middot;</mo>
+ <mo>&middot;</mo>
+ <mo>,</mo>
+ <mi>V</mi>
+ <mo>-</mo>
+ <mn>1</mn>
+ </mrow>
+
+ </mrow>
+ </math>
+ </td>
+ <td>
+ <p>(12)</p>
+ </td>
+ </tr>
+</table>
+
+<table border="0" style="margin-right:1.0cm; margin-left:1.0cm; margin-top:0.5cm; margin-bottom:0.5cm;">
+ <tr>
+ <td align="center" style="width:100%;">
+ <math mode="display" style="font-size:1.2em;" xmlns="http://www.w3.org/1998/Math/MathML">
+ <mrow>
+ <mfenced open="{" close="">
+ <mtable>
+ <mtr>
+ <mtd>
+ <mrow>
+ <msub><mi>x</mi><mrow><mi>n</mi><mo>,</mo><mi>v</mi></mrow></msub>
+ <mo>=</mo>
+ <msubsup>
+ <mi>x</mi>
+ <mrow><mi>N</mi><mo>-</mo><mi>n</mi><mo>,</mo><mi>v</mi></mrow>
+ <mo>*</mo>
+ </msubsup>
+ </mrow>
+ </mtd>
+
+ <mtd>
+ <mo>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</mo>
+ </mtd>
+
+ <mtd>
+ <mrow style="font-size:100%;">
+ <mi>n</mi>
+ <mo>=</mo>
+ <mn>1</mn>
+ <mo>,</mo>
+ <mo>&middot;</mo>
+ <mo>&middot;</mo>
+ <mo>&middot;</mo>
+ <mo>,</mo>
+ <mfrac>
+ <mi>N</mi>
+ <mn>2</mn>
+ </mfrac>
+ <mo>-</mo>
+ <mn>1</mn>
+ </mrow>
+ </mtd>
+ </mtr>
+
+ <mtr>
+ <mtd>
+ <mrow>
+ <mi>Im</mi>
+ <mo>(</mo>
+ <msub><mi>x</mi><mrow><mi>n</mi><mo>,</mo><mi>v</mi></mrow></msub>
+ <mo>)</mo>
+ <mo>=</mo>
+ <mn>0</mn>
+ </mrow>
+ </mtd>
+
+ <mtd>
+ <mo>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</mo>
+ </mtd>
+
+ <mtd>
+ <mrow style="font-size:100%;">
+ <mi>n</mi>
+ <mo>=</mo>
+ <mn>0</mn>
+ <mo>,</mo>
+ <mfrac>
+ <mi>N</mi>
+ <mn>2</mn>
+ </mfrac>
+ </mrow>
+ </mtd>
+ </mtr>
+
+ </mtable>
+ </mfenced>
+
+ <mo>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</mo>
+
+ <mrow style="font-size:100%;">
+ <mi>v</mi>
+ <mo>=</mo>
+ <mn>0</mn>
+ <mo>,</mo>
+ <mo>&middot;</mo>
+ <mo>&middot;</mo>
+ <mo>&middot;</mo>
+ <mo>,</mo>
+ <mi>V</mi>
+ <mo>-</mo>
+ <mn>1</mn>
+ </mrow>
+ </mrow>
+ </math>
+ </td>
+ <td>
+ <p>(13)</p>
+ </td>
+ </tr>
+</table>
+
+<table border="0" style="margin-right:1.0cm; margin-left:1.0cm; margin-top:0.5cm; margin-bottom:0.5cm;">
+ <tr>
+ <td align="center" style="width:100%;">
+ <math mode="display" style="font-size:1.2em;" xmlns="http://www.w3.org/1998/Math/MathML">
+ <mrow>
+ <mrow>
+ <mi>s</mi>
+ <mo>[</mo>
+ <mi>n</mi>
+ <mi>V</mi>
+ <mo>+</mo>
+ <mi>v</mi>
+ <mo>]</mo>
+
+ <mo>=</mo>
+
+ <mi>Re</mi>
+ <mo>(</mo>
+ <msub><mi>X</mi><mrow><mi>k</mi><mo>,</mo><mi>v</mi></mrow></msub>
+ <mo>)</mo>
+ </mrow>
+
+ <mo>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</mo>
+
+ <mrow style="font-size:100%;">
+ <mi>k</mi>
+ <mo>=</mo>
+ <mn>0</mn>
+ <mo>,</mo>
+ <mo>&middot;</mo>
+ <mo>&middot;</mo>
+ <mo>&middot;</mo>
+ <mo>,</mo>
+ <mi>N</mi>
+ <mo>-</mo>
+ <mn>1</mn>
+
+ <mo>&nbsp;&nbsp;</mo>
+ <mo>,</mo>
+ <mo>&nbsp;&nbsp;</mo>
+
+ <mi>v</mi>
+ <mo>=</mo>
+ <mn>0</mn>
+ <mo>,</mo>
+ <mo>&middot;</mo>
+ <mo>&middot;</mo>
+ <mo>&middot;</mo>
+ <mo>,</mo>
+ <mi>V</mi>
+ <mo>-</mo>
+ <mn>1</mn>
+ </mrow>
+ </mrow>
+ </math>
+ </td>
+ <td>
+ <p>(14)</p>
+ </td>
+ </tr>
+</table>
+
+<table border="0" style="margin-right:1.0cm; margin-left:1.0cm; margin-top:0.5cm; margin-bottom:0.5cm;">
+ <tr>
+ <td align="center" style="width:100%;">
+ <math mode="display" style="font-size:1.2em;" xmlns="http://www.w3.org/1998/Math/MathML">
+ <mrow>
+ <mfenced open="{" close="">
+ <mtable>
+ <mtr>
+ <mtd>
+ <mrow>
+ <mi>s</mi>
+ <mo>[</mo>
+ <mo>(</mo>
+ <mn>2</mn>
+ <mi>n</mi>
+ <mo>+</mo>
+ <mn>0</mn>
+ <mo>)</mo>
+ <mi>V</mi>
+ <mo>+</mo>
+ <mi>v</mi>
+ <mo>]</mo>
+ </mrow>
+ </mtd>
+
+ <mtd>
+ <mo>=</mo>
+ </mtd>
+
+ <mtd>
+ <mrow>
+ <mi>Re</mi>
+ <mo>(</mo>
+ <msub><mi>x</mi><mrow><mi>n</mi><mo>,</mo><mi>v</mi></mrow></msub>
+ <mo>)</mo>
+ </mrow>
+ </mtd>
+
+ <mtd>
+ <mrow style="font-size:100%;">
+ <mi>n</mi>
+ <mo>=</mo>
+ <mn>0</mn>
+ <mo>,</mo>
+ <mo>&middot;</mo>
+ <mo>&middot;</mo>
+ <mo>&middot;</mo>
+ <mo>,</mo>
+ <mfrac>
+ <mi>N</mi>
+ <mn>2</mn>
+ </mfrac>
+ <mo>-</mo>
+ <mn>1</mn>
+ </mrow>
+ </mtd>
+ </mtr>
+
+ <mtr>
+ <mtd>
+ <mrow>
+ <mi>s</mi>
+ <mo>[</mo>
+ <mi>V</mi>
+ <mo>+</mo>
+ <mi>v</mi>
+ <mo>]</mo>
+ </mrow>
+ </mtd>
+
+ <mtd>
+ <mo>=</mo>
+ </mtd>
+
+ <mtd>
+ <mrow>
+ <mi>Re</mi>
+ <mo>(</mo>
+ <msub><mi>x</mi><mrow><mi>N</mi><mo>/</mo><mn>2</mn><mo>,</mo><mi>v</mi></mrow></msub>
+ <mo>)</mo>
+ </mrow>
+ </mtd>
+
+ <mtd>
+ </mtd>
+ </mtr>
+
+ <mtr>
+ <mtd>
+ <mrow>
+ <mi>s</mi>
+ <mo>[</mo>
+ <mo>(</mo>
+ <mn>2</mn>
+ <mi>n</mi>
+ <mo>+</mo>
+ <mn>1</mn>
+ <mo>)</mo>
+ <mi>V</mi>
+ <mo>+</mo>
+ <mi>v</mi>
+ <mo>]</mo>
+ </mrow>
+ </mtd>
+
+ <mtd>
+ <mo>=</mo>
+ </mtd>
+
+ <mtd>
+ <mrow>
+ <mi>Im</mi>
+ <mo>(</mo>
+ <msub><mi>x</mi><mrow><mi>n</mi><mo>,</mo><mi>v</mi></mrow></msub>
+ <mo>)</mo>
+ </mrow>
+ </mtd>
+
+ <mtd>
+ <mrow style="font-size:100%;">
+ <mi>n</mi>
+ <mo>=</mo>
+ <mn>1</mn>
+ <mo>,</mo>
+ <mo>&middot;</mo>
+ <mo>&middot;</mo>
+ <mo>&middot;</mo>
+ <mo>,</mo>
+ <mfrac>
+ <mi>N</mi>
+ <mn>2</mn>
+ </mfrac>
+ <mo>-</mo>
+ <mn>1</mn>
+ </mrow>
+ </mtd>
+ </mtr>
+
+ </mtable>
+ </mfenced>
+
+ <mo>&nbsp;&nbsp;&nbsp;&nbsp;</mo>
+
+ <mrow style="font-size:100%;">
+ <mi>v</mi>
+ <mo>=</mo>
+ <mn>0</mn>
+ <mo>,</mo>
+ <mo>&middot;</mo>
+ <mo>&middot;</mo>
+ <mo>&middot;</mo>
+ <mo>,</mo>
+ <mi>V</mi>
+ <mo>-</mo>
+ <mn>1</mn>
+ </mrow>
+ </mrow>
+ </math>
+ </td>
+ <td>
+ <p>(15)</p>
+ </td>
+ </tr>
+</table>
+
+<table border="0" style="margin-right:1.0cm; margin-left:1.0cm; margin-top:0.5cm; margin-bottom:0.5cm;">
+ <tr>
+ <td align="center" style="width:100%;">
+ <math mode="display" style="font-size:1.2em;" xmlns="http://www.w3.org/1998/Math/MathML">
+ <mrow>
+ <mrow>
+ <mn>2</mn>
+ <mo> &nbsp; </mo>
+ <mi>s</mi>
+ <mo>[</mo>
+ <mi>n</mi>
+ <mi>V</mi>
+ <mo>+</mo>
+ <mi>v</mi>
+ <mo>]</mo>
+
+ <mo>=</mo>
+
+ <mi>Re</mi>
+ <mo>(</mo>
+ <msub><mi>X</mi><mrow><mi>k</mi><mo>,</mo><mi>v</mi></mrow></msub>
+ <mo>)</mo>
+ </mrow>
+
+ <mo>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</mo>
+
+ <mrow style="font-size:100%;">
+ <mi>k</mi>
+ <mo>=</mo>
+ <mn>0</mn>
+ <mo>,</mo>
+ <mo>&middot;</mo>
+ <mo>&middot;</mo>
+ <mo>&middot;</mo>
+ <mo>,</mo>
+ <mi>N</mi>
+ <mo>-</mo>
+ <mn>1</mn>
+
+ <mo>&nbsp;&nbsp;</mo>
+ <mo>,</mo>
+ <mo>&nbsp;&nbsp;</mo>
+
+ <mi>v</mi>
+ <mo>=</mo>
+ <mn>0</mn>
+ <mo>,</mo>
+ <mo>&middot;</mo>
+ <mo>&middot;</mo>
+ <mo>&middot;</mo>
+ <mo>,</mo>
+ <mi>V</mi>
+ <mo>-</mo>
+ <mn>1</mn>
+ </mrow>
+ </mrow>
+ </math>
+ </td>
+ <td>
+ <p>(16)</p>
+ </td>
+ </tr>
+</table>
+
+
+<h3>Examples</h3>
+
+<p>
+Below is an example code using nsfft library.
+</p>
+
+<pre class="code">
+#include &lt;stdio.h&gt;
+#include &lt;stdlib.h&gt;
+#include &lt;math.h&gt;
+#include &lt;stdint.h&gt;
+#include &lt;complex.h&gt;
+
+#include "SIMDBase.h"
+#include "DFT.h"
+
+typedef float REAL;
+#define TYPE SIMDBase_TYPE_FLOAT
+
+#define THRES 1e-3
+
+double complex omega(double n, double kn) {
+ return cexp((-2 * M_PI * _Complex_I / n) * kn);
+}
+
+void forward(double complex *ts, double complex *fs, int len) {
+ int k, n;
+
+ for(k=0;k&lt;len;k++) {
+ fs[k] = 0;
+
+ for(n=0;n&lt;len;n++) {
+ fs[k] += ts[n] * omega(len, n*k);
+ }
+ }
+}
+
+int main(int argc, char **argv) {
+ const int n = 256;
+
+ int mode = SIMDBase_chooseBestMode(TYPE);
+ printf("mode : %d, %s\n", mode, SIMDBase_getModeParamString(SIMDBase_PARAMID_MODE_NAME, mode));
+
+ int veclen = SIMDBase_getModeParamInt(SIMDBase_PARAMID_VECTOR_LEN, mode);
+ int sizeOfVect = SIMDBase_getModeParamInt(SIMDBase_PARAMID_SIZE_OF_VECT, mode);
+
+ //
+
+ int i, j;
+
+ DFT *p = DFT_init(mode, n, 0);
+ REAL *sx = SIMDBase_alignedMalloc(sizeOfVect*n*2);
+
+ //
+
+ double complex ts[veclen][n], fs[veclen][n];
+
+ for(j=0;j&lt;veclen;j++) {
+ for(i=0;i&lt;n;i++) {
+ ts[j][i] = (random() / (double)RAND_MAX) + (random() / (double)RAND_MAX) * _Complex_I;
+ sx[(i*2+0)*veclen+j] = creal(ts[j][i]);
+ sx[(i*2+1)*veclen+j] = cimag(ts[j][i]);
+ }
+ }
+
+ //
+
+ DFT_execute(p, mode, sx, -1);
+
+ for(j=0;j&lt;veclen;j++) {
+ forward(ts[j], fs[j], n);
+ }
+
+ //
+
+ int success = 1;
+
+ for(j=0;j&lt;veclen;j++) {
+ for(i=0;i&lt;n;i++) {
+ if ((fabs(sx[(i*2+0)*veclen+j] - creal(fs[j][i])) &gt; THRES) ||
+ (fabs(sx[(i*2+1)*veclen+j] - cimag(fs[j][i])) &gt; THRES)) {
+ success = 0;
+ }
+ }
+ }
+
+ printf("%s\n", success ? "OK" : "NG");
+
+ //
+
+ SIMDBase_alignedFree(sx);
+ DFT_dispose(p, mode);
+
+ exit(0);
+}
+</pre>
+
+<p>
+You should put this code under a directory in the root directory of
+the library, and then you can compile this code with the following
+command.
+</p>
+
+<pre class="code">
+gcc -Wall -g -I ../simd -I ../dft -L../simd -L../dft -O DFTExample.c -lDFT -lSIMD -lm -o DFTExample
+</pre>
+
+<h3>Compilation</h3>
+
+<p>
+The nsfft source package include a few makefiles for various
+architectures. You should make symbolic links to makefiles suited for
+your computer under <i>dft</i> and <i>simd</i> directories.
+</p>
+
+</body>
+</html>
diff --git a/plugins/supereq/nsfft-1.00/doc/nsfft.pdf b/plugins/supereq/nsfft-1.00/doc/nsfft.pdf
new file mode 100644
index 00000000..ed4ad5db
--- /dev/null
+++ b/plugins/supereq/nsfft-1.00/doc/nsfft.pdf
Binary files differ
diff --git a/plugins/supereq/nsfft-1.00/ooura/Makefile b/plugins/supereq/nsfft-1.00/ooura/Makefile
new file mode 100644
index 00000000..bad1679e
--- /dev/null
+++ b/plugins/supereq/nsfft-1.00/ooura/Makefile
@@ -0,0 +1,11 @@
+CC=gcc
+BASEOPT=-Wall -g
+OPT=$(BASEOPT) -O3
+
+all : fftsg.o
+
+clean :
+ rm -f *~ *.o a.out
+
+fftsg.o : fftsg.c
+ $(CC) $(OPT) -c fftsg.c
diff --git a/plugins/supereq/nsfft-1.00/ooura/README b/plugins/supereq/nsfft-1.00/ooura/README
new file mode 100644
index 00000000..d7ddefc2
--- /dev/null
+++ b/plugins/supereq/nsfft-1.00/ooura/README
@@ -0,0 +1,2 @@
+Please put fftsg.c and pi_fft.c which is included in Prof. Takuya
+Ooura's FFT package.
diff --git a/plugins/supereq/nsfft-1.00/ooura/fftsg.c b/plugins/supereq/nsfft-1.00/ooura/fftsg.c
new file mode 100644
index 00000000..43d75344
--- /dev/null
+++ b/plugins/supereq/nsfft-1.00/ooura/fftsg.c
@@ -0,0 +1,3314 @@
+/*
+Fast Fourier/Cosine/Sine Transform
+ dimension :one
+ data length :power of 2
+ decimation :frequency
+ radix :split-radix
+ data :inplace
+ table :use
+functions
+ cdft: Complex Discrete Fourier Transform
+ rdft: Real Discrete Fourier Transform
+ ddct: Discrete Cosine Transform
+ ddst: Discrete Sine Transform
+ dfct: Cosine Transform of RDFT (Real Symmetric DFT)
+ dfst: Sine Transform of RDFT (Real Anti-symmetric DFT)
+function prototypes
+ void cdft(int, int, double *, int *, double *);
+ void rdft(int, int, double *, int *, double *);
+ void ddct(int, int, double *, int *, double *);
+ void ddst(int, int, double *, int *, double *);
+ void dfct(int, double *, double *, int *, double *);
+ void dfst(int, double *, double *, int *, double *);
+macro definitions
+ USE_CDFT_PTHREADS : default=not defined
+ CDFT_THREADS_BEGIN_N : must be >= 512, default=8192
+ CDFT_4THREADS_BEGIN_N : must be >= 512, default=65536
+ USE_CDFT_WINTHREADS : default=not defined
+ CDFT_THREADS_BEGIN_N : must be >= 512, default=32768
+ CDFT_4THREADS_BEGIN_N : must be >= 512, default=524288
+
+
+-------- Complex DFT (Discrete Fourier Transform) --------
+ [definition]
+ <case1>
+ X[k] = sum_j=0^n-1 x[j]*exp(2*pi*i*j*k/n), 0<=k<n
+ <case2>
+ X[k] = sum_j=0^n-1 x[j]*exp(-2*pi*i*j*k/n), 0<=k<n
+ (notes: sum_j=0^n-1 is a summation from j=0 to n-1)
+ [usage]
+ <case1>
+ ip[0] = 0; // first time only
+ cdft(2*n, 1, a, ip, w);
+ <case2>
+ ip[0] = 0; // first time only
+ cdft(2*n, -1, a, ip, w);
+ [parameters]
+ 2*n :data length (int)
+ n >= 1, n = power of 2
+ a[0...2*n-1] :input/output data (double *)
+ input data
+ a[2*j] = Re(x[j]),
+ a[2*j+1] = Im(x[j]), 0<=j<n
+ output data
+ a[2*k] = Re(X[k]),
+ a[2*k+1] = Im(X[k]), 0<=k<n
+ ip[0...*] :work area for bit reversal (int *)
+ length of ip >= 2+sqrt(n)
+ strictly,
+ length of ip >=
+ 2+(1<<(int)(log(n+0.5)/log(2))/2).
+ ip[0],ip[1] are pointers of the cos/sin table.
+ w[0...n/2-1] :cos/sin table (double *)
+ w[],ip[] are initialized if ip[0] == 0.
+ [remark]
+ Inverse of
+ cdft(2*n, -1, a, ip, w);
+ is
+ cdft(2*n, 1, a, ip, w);
+ for (j = 0; j <= 2 * n - 1; j++) {
+ a[j] *= 1.0 / n;
+ }
+ .
+
+
+-------- Real DFT / Inverse of Real DFT --------
+ [definition]
+ <case1> RDFT
+ R[k] = sum_j=0^n-1 a[j]*cos(2*pi*j*k/n), 0<=k<=n/2
+ I[k] = sum_j=0^n-1 a[j]*sin(2*pi*j*k/n), 0<k<n/2
+ <case2> IRDFT (excluding scale)
+ a[k] = (R[0] + R[n/2]*cos(pi*k))/2 +
+ sum_j=1^n/2-1 R[j]*cos(2*pi*j*k/n) +
+ sum_j=1^n/2-1 I[j]*sin(2*pi*j*k/n), 0<=k<n
+ [usage]
+ <case1>
+ ip[0] = 0; // first time only
+ rdft(n, 1, a, ip, w);
+ <case2>
+ ip[0] = 0; // first time only
+ rdft(n, -1, a, ip, w);
+ [parameters]
+ n :data length (int)
+ n >= 2, n = power of 2
+ a[0...n-1] :input/output data (double *)
+ <case1>
+ output data
+ a[2*k] = R[k], 0<=k<n/2
+ a[2*k+1] = I[k], 0<k<n/2
+ a[1] = R[n/2]
+ <case2>
+ input data
+ a[2*j] = R[j], 0<=j<n/2
+ a[2*j+1] = I[j], 0<j<n/2
+ a[1] = R[n/2]
+ ip[0...*] :work area for bit reversal (int *)
+ length of ip >= 2+sqrt(n/2)
+ strictly,
+ length of ip >=
+ 2+(1<<(int)(log(n/2+0.5)/log(2))/2).
+ ip[0],ip[1] are pointers of the cos/sin table.
+ w[0...n/2-1] :cos/sin table (double *)
+ w[],ip[] are initialized if ip[0] == 0.
+ [remark]
+ Inverse of
+ rdft(n, 1, a, ip, w);
+ is
+ rdft(n, -1, a, ip, w);
+ for (j = 0; j <= n - 1; j++) {
+ a[j] *= 2.0 / n;
+ }
+ .
+
+
+-------- DCT (Discrete Cosine Transform) / Inverse of DCT --------
+ [definition]
+ <case1> IDCT (excluding scale)
+ C[k] = sum_j=0^n-1 a[j]*cos(pi*j*(k+1/2)/n), 0<=k<n
+ <case2> DCT
+ C[k] = sum_j=0^n-1 a[j]*cos(pi*(j+1/2)*k/n), 0<=k<n
+ [usage]
+ <case1>
+ ip[0] = 0; // first time only
+ ddct(n, 1, a, ip, w);
+ <case2>
+ ip[0] = 0; // first time only
+ ddct(n, -1, a, ip, w);
+ [parameters]
+ n :data length (int)
+ n >= 2, n = power of 2
+ a[0...n-1] :input/output data (double *)
+ output data
+ a[k] = C[k], 0<=k<n
+ ip[0...*] :work area for bit reversal (int *)
+ length of ip >= 2+sqrt(n/2)
+ strictly,
+ length of ip >=
+ 2+(1<<(int)(log(n/2+0.5)/log(2))/2).
+ ip[0],ip[1] are pointers of the cos/sin table.
+ w[0...n*5/4-1] :cos/sin table (double *)
+ w[],ip[] are initialized if ip[0] == 0.
+ [remark]
+ Inverse of
+ ddct(n, -1, a, ip, w);
+ is
+ a[0] *= 0.5;
+ ddct(n, 1, a, ip, w);
+ for (j = 0; j <= n - 1; j++) {
+ a[j] *= 2.0 / n;
+ }
+ .
+
+
+-------- DST (Discrete Sine Transform) / Inverse of DST --------
+ [definition]
+ <case1> IDST (excluding scale)
+ S[k] = sum_j=1^n A[j]*sin(pi*j*(k+1/2)/n), 0<=k<n
+ <case2> DST
+ S[k] = sum_j=0^n-1 a[j]*sin(pi*(j+1/2)*k/n), 0<k<=n
+ [usage]
+ <case1>
+ ip[0] = 0; // first time only
+ ddst(n, 1, a, ip, w);
+ <case2>
+ ip[0] = 0; // first time only
+ ddst(n, -1, a, ip, w);
+ [parameters]
+ n :data length (int)
+ n >= 2, n = power of 2
+ a[0...n-1] :input/output data (double *)
+ <case1>
+ input data
+ a[j] = A[j], 0<j<n
+ a[0] = A[n]
+ output data
+ a[k] = S[k], 0<=k<n
+ <case2>
+ output data
+ a[k] = S[k], 0<k<n
+ a[0] = S[n]
+ ip[0...*] :work area for bit reversal (int *)
+ length of ip >= 2+sqrt(n/2)
+ strictly,
+ length of ip >=
+ 2+(1<<(int)(log(n/2+0.5)/log(2))/2).
+ ip[0],ip[1] are pointers of the cos/sin table.
+ w[0...n*5/4-1] :cos/sin table (double *)
+ w[],ip[] are initialized if ip[0] == 0.
+ [remark]
+ Inverse of
+ ddst(n, -1, a, ip, w);
+ is
+ a[0] *= 0.5;
+ ddst(n, 1, a, ip, w);
+ for (j = 0; j <= n - 1; j++) {
+ a[j] *= 2.0 / n;
+ }
+ .
+
+
+-------- Cosine Transform of RDFT (Real Symmetric DFT) --------
+ [definition]
+ C[k] = sum_j=0^n a[j]*cos(pi*j*k/n), 0<=k<=n
+ [usage]
+ ip[0] = 0; // first time only
+ dfct(n, a, t, ip, w);
+ [parameters]
+ n :data length - 1 (int)
+ n >= 2, n = power of 2
+ a[0...n] :input/output data (double *)
+ output data
+ a[k] = C[k], 0<=k<=n
+ t[0...n/2] :work area (double *)
+ ip[0...*] :work area for bit reversal (int *)
+ length of ip >= 2+sqrt(n/4)
+ strictly,
+ length of ip >=
+ 2+(1<<(int)(log(n/4+0.5)/log(2))/2).
+ ip[0],ip[1] are pointers of the cos/sin table.
+ w[0...n*5/8-1] :cos/sin table (double *)
+ w[],ip[] are initialized if ip[0] == 0.
+ [remark]
+ Inverse of
+ a[0] *= 0.5;
+ a[n] *= 0.5;
+ dfct(n, a, t, ip, w);
+ is
+ a[0] *= 0.5;
+ a[n] *= 0.5;
+ dfct(n, a, t, ip, w);
+ for (j = 0; j <= n; j++) {
+ a[j] *= 2.0 / n;
+ }
+ .
+
+
+-------- Sine Transform of RDFT (Real Anti-symmetric DFT) --------
+ [definition]
+ S[k] = sum_j=1^n-1 a[j]*sin(pi*j*k/n), 0<k<n
+ [usage]
+ ip[0] = 0; // first time only
+ dfst(n, a, t, ip, w);
+ [parameters]
+ n :data length + 1 (int)
+ n >= 2, n = power of 2
+ a[0...n-1] :input/output data (double *)
+ output data
+ a[k] = S[k], 0<k<n
+ (a[0] is used for work area)
+ t[0...n/2-1] :work area (double *)
+ ip[0...*] :work area for bit reversal (int *)
+ length of ip >= 2+sqrt(n/4)
+ strictly,
+ length of ip >=
+ 2+(1<<(int)(log(n/4+0.5)/log(2))/2).
+ ip[0],ip[1] are pointers of the cos/sin table.
+ w[0...n*5/8-1] :cos/sin table (double *)
+ w[],ip[] are initialized if ip[0] == 0.
+ [remark]
+ Inverse of
+ dfst(n, a, t, ip, w);
+ is
+ dfst(n, a, t, ip, w);
+ for (j = 1; j <= n - 1; j++) {
+ a[j] *= 2.0 / n;
+ }
+ .
+
+
+Appendix :
+ The cos/sin table is recalculated when the larger table required.
+ w[] and ip[] are compatible with all routines.
+*/
+
+
+void cdft(int n, int isgn, double *a, int *ip, double *w)
+{
+ void makewt(int nw, int *ip, double *w);
+ void cftfsub(int n, double *a, int *ip, int nw, double *w);
+ void cftbsub(int n, double *a, int *ip, int nw, double *w);
+ int nw;
+
+ nw = ip[0];
+ if (n > (nw << 2)) {
+ nw = n >> 2;
+ makewt(nw, ip, w);
+ }
+ if (isgn >= 0) {
+ cftfsub(n, a, ip, nw, w);
+ } else {
+ cftbsub(n, a, ip, nw, w);
+ }
+}
+
+
+void rdft(int n, int isgn, double *a, int *ip, double *w)
+{
+ void makewt(int nw, int *ip, double *w);
+ void makect(int nc, int *ip, double *c);
+ void cftfsub(int n, double *a, int *ip, int nw, double *w);
+ void cftbsub(int n, double *a, int *ip, int nw, double *w);
+ void rftfsub(int n, double *a, int nc, double *c);
+ void rftbsub(int n, double *a, int nc, double *c);
+ int nw, nc;
+ double xi;
+
+ nw = ip[0];
+ if (n > (nw << 2)) {
+ nw = n >> 2;
+ makewt(nw, ip, w);
+ }
+ nc = ip[1];
+ if (n > (nc << 2)) {
+ nc = n >> 2;
+ makect(nc, ip, w + nw);
+ }
+ if (isgn >= 0) {
+ if (n > 4) {
+ cftfsub(n, a, ip, nw, w);
+ rftfsub(n, a, nc, w + nw);
+ } else if (n == 4) {
+ cftfsub(n, a, ip, nw, w);
+ }
+ xi = a[0] - a[1];
+ a[0] += a[1];
+ a[1] = xi;
+ } else {
+ a[1] = 0.5 * (a[0] - a[1]);
+ a[0] -= a[1];
+ if (n > 4) {
+ rftbsub(n, a, nc, w + nw);
+ cftbsub(n, a, ip, nw, w);
+ } else if (n == 4) {
+ cftbsub(n, a, ip, nw, w);
+ }
+ }
+}
+
+
+void ddct(int n, int isgn, double *a, int *ip, double *w)
+{
+ void makewt(int nw, int *ip, double *w);
+ void makect(int nc, int *ip, double *c);
+ void cftfsub(int n, double *a, int *ip, int nw, double *w);
+ void cftbsub(int n, double *a, int *ip, int nw, double *w);
+ void rftfsub(int n, double *a, int nc, double *c);
+ void rftbsub(int n, double *a, int nc, double *c);
+ void dctsub(int n, double *a, int nc, double *c);
+ int j, nw, nc;
+ double xr;
+
+ nw = ip[0];
+ if (n > (nw << 2)) {
+ nw = n >> 2;
+ makewt(nw, ip, w);
+ }
+ nc = ip[1];
+ if (n > nc) {
+ nc = n;
+ makect(nc, ip, w + nw);
+ }
+ if (isgn < 0) {
+ xr = a[n - 1];
+ for (j = n - 2; j >= 2; j -= 2) {
+ a[j + 1] = a[j] - a[j - 1];
+ a[j] += a[j - 1];
+ }
+ a[1] = a[0] - xr;
+ a[0] += xr;
+ if (n > 4) {
+ rftbsub(n, a, nc, w + nw);
+ cftbsub(n, a, ip, nw, w);
+ } else if (n == 4) {
+ cftbsub(n, a, ip, nw, w);
+ }
+ }
+ dctsub(n, a, nc, w + nw);
+ if (isgn >= 0) {
+ if (n > 4) {
+ cftfsub(n, a, ip, nw, w);
+ rftfsub(n, a, nc, w + nw);
+ } else if (n == 4) {
+ cftfsub(n, a, ip, nw, w);
+ }
+ xr = a[0] - a[1];
+ a[0] += a[1];
+ for (j = 2; j < n; j += 2) {
+ a[j - 1] = a[j] - a[j + 1];
+ a[j] += a[j + 1];
+ }
+ a[n - 1] = xr;
+ }
+}
+
+
+void ddst(int n, int isgn, double *a, int *ip, double *w)
+{
+ void makewt(int nw, int *ip, double *w);
+ void makect(int nc, int *ip, double *c);
+ void cftfsub(int n, double *a, int *ip, int nw, double *w);
+ void cftbsub(int n, double *a, int *ip, int nw, double *w);
+ void rftfsub(int n, double *a, int nc, double *c);
+ void rftbsub(int n, double *a, int nc, double *c);
+ void dstsub(int n, double *a, int nc, double *c);
+ int j, nw, nc;
+ double xr;
+
+ nw = ip[0];
+ if (n > (nw << 2)) {
+ nw = n >> 2;
+ makewt(nw, ip, w);
+ }
+ nc = ip[1];
+ if (n > nc) {
+ nc = n;
+ makect(nc, ip, w + nw);
+ }
+ if (isgn < 0) {
+ xr = a[n - 1];
+ for (j = n - 2; j >= 2; j -= 2) {
+ a[j + 1] = -a[j] - a[j - 1];
+ a[j] -= a[j - 1];
+ }
+ a[1] = a[0] + xr;
+ a[0] -= xr;
+ if (n > 4) {
+ rftbsub(n, a, nc, w + nw);
+ cftbsub(n, a, ip, nw, w);
+ } else if (n == 4) {
+ cftbsub(n, a, ip, nw, w);
+ }
+ }
+ dstsub(n, a, nc, w + nw);
+ if (isgn >= 0) {
+ if (n > 4) {
+ cftfsub(n, a, ip, nw, w);
+ rftfsub(n, a, nc, w + nw);
+ } else if (n == 4) {
+ cftfsub(n, a, ip, nw, w);
+ }
+ xr = a[0] - a[1];
+ a[0] += a[1];
+ for (j = 2; j < n; j += 2) {
+ a[j - 1] = -a[j] - a[j + 1];
+ a[j] -= a[j + 1];
+ }
+ a[n - 1] = -xr;
+ }
+}
+
+
+void dfct(int n, double *a, double *t, int *ip, double *w)
+{
+ void makewt(int nw, int *ip, double *w);
+ void makect(int nc, int *ip, double *c);
+ void cftfsub(int n, double *a, int *ip, int nw, double *w);
+ void rftfsub(int n, double *a, int nc, double *c);
+ void dctsub(int n, double *a, int nc, double *c);
+ int j, k, l, m, mh, nw, nc;
+ double xr, xi, yr, yi;
+
+ nw = ip[0];
+ if (n > (nw << 3)) {
+ nw = n >> 3;
+ makewt(nw, ip, w);
+ }
+ nc = ip[1];
+ if (n > (nc << 1)) {
+ nc = n >> 1;
+ makect(nc, ip, w + nw);
+ }
+ m = n >> 1;
+ yi = a[m];
+ xi = a[0] + a[n];
+ a[0] -= a[n];
+ t[0] = xi - yi;
+ t[m] = xi + yi;
+ if (n > 2) {
+ mh = m >> 1;
+ for (j = 1; j < mh; j++) {
+ k = m - j;
+ xr = a[j] - a[n - j];
+ xi = a[j] + a[n - j];
+ yr = a[k] - a[n - k];
+ yi = a[k] + a[n - k];
+ a[j] = xr;
+ a[k] = yr;
+ t[j] = xi - yi;
+ t[k] = xi + yi;
+ }
+ t[mh] = a[mh] + a[n - mh];
+ a[mh] -= a[n - mh];
+ dctsub(m, a, nc, w + nw);
+ if (m > 4) {
+ cftfsub(m, a, ip, nw, w);
+ rftfsub(m, a, nc, w + nw);
+ } else if (m == 4) {
+ cftfsub(m, a, ip, nw, w);
+ }
+ a[n - 1] = a[0] - a[1];
+ a[1] = a[0] + a[1];
+ for (j = m - 2; j >= 2; j -= 2) {
+ a[2 * j + 1] = a[j] + a[j + 1];
+ a[2 * j - 1] = a[j] - a[j + 1];
+ }
+ l = 2;
+ m = mh;
+ while (m >= 2) {
+ dctsub(m, t, nc, w + nw);
+ if (m > 4) {
+ cftfsub(m, t, ip, nw, w);
+ rftfsub(m, t, nc, w + nw);
+ } else if (m == 4) {
+ cftfsub(m, t, ip, nw, w);
+ }
+ a[n - l] = t[0] - t[1];
+ a[l] = t[0] + t[1];
+ k = 0;
+ for (j = 2; j < m; j += 2) {
+ k += l << 2;
+ a[k - l] = t[j] - t[j + 1];
+ a[k + l] = t[j] + t[j + 1];
+ }
+ l <<= 1;
+ mh = m >> 1;
+ for (j = 0; j < mh; j++) {
+ k = m - j;
+ t[j] = t[m + k] - t[m + j];
+ t[k] = t[m + k] + t[m + j];
+ }
+ t[mh] = t[m + mh];
+ m = mh;
+ }
+ a[l] = t[0];
+ a[n] = t[2] - t[1];
+ a[0] = t[2] + t[1];
+ } else {
+ a[1] = a[0];
+ a[2] = t[0];
+ a[0] = t[1];
+ }
+}
+
+
+void dfst(int n, double *a, double *t, int *ip, double *w)
+{
+ void makewt(int nw, int *ip, double *w);
+ void makect(int nc, int *ip, double *c);
+ void cftfsub(int n, double *a, int *ip, int nw, double *w);
+ void rftfsub(int n, double *a, int nc, double *c);
+ void dstsub(int n, double *a, int nc, double *c);
+ int j, k, l, m, mh, nw, nc;
+ double xr, xi, yr, yi;
+
+ nw = ip[0];
+ if (n > (nw << 3)) {
+ nw = n >> 3;
+ makewt(nw, ip, w);
+ }
+ nc = ip[1];
+ if (n > (nc << 1)) {
+ nc = n >> 1;
+ makect(nc, ip, w + nw);
+ }
+ if (n > 2) {
+ m = n >> 1;
+ mh = m >> 1;
+ for (j = 1; j < mh; j++) {
+ k = m - j;
+ xr = a[j] + a[n - j];
+ xi = a[j] - a[n - j];
+ yr = a[k] + a[n - k];
+ yi = a[k] - a[n - k];
+ a[j] = xr;
+ a[k] = yr;
+ t[j] = xi + yi;
+ t[k] = xi - yi;
+ }
+ t[0] = a[mh] - a[n - mh];
+ a[mh] += a[n - mh];
+ a[0] = a[m];
+ dstsub(m, a, nc, w + nw);
+ if (m > 4) {
+ cftfsub(m, a, ip, nw, w);
+ rftfsub(m, a, nc, w + nw);
+ } else if (m == 4) {
+ cftfsub(m, a, ip, nw, w);
+ }
+ a[n - 1] = a[1] - a[0];
+ a[1] = a[0] + a[1];
+ for (j = m - 2; j >= 2; j -= 2) {
+ a[2 * j + 1] = a[j] - a[j + 1];
+ a[2 * j - 1] = -a[j] - a[j + 1];
+ }
+ l = 2;
+ m = mh;
+ while (m >= 2) {
+ dstsub(m, t, nc, w + nw);
+ if (m > 4) {
+ cftfsub(m, t, ip, nw, w);
+ rftfsub(m, t, nc, w + nw);
+ } else if (m == 4) {
+ cftfsub(m, t, ip, nw, w);
+ }
+ a[n - l] = t[1] - t[0];
+ a[l] = t[0] + t[1];
+ k = 0;
+ for (j = 2; j < m; j += 2) {
+ k += l << 2;
+ a[k - l] = -t[j] - t[j + 1];
+ a[k + l] = t[j] - t[j + 1];
+ }
+ l <<= 1;
+ mh = m >> 1;
+ for (j = 1; j < mh; j++) {
+ k = m - j;
+ t[j] = t[m + k] + t[m + j];
+ t[k] = t[m + k] - t[m + j];
+ }
+ t[0] = t[m + mh];
+ m = mh;
+ }
+ a[l] = t[0];
+ }
+ a[0] = 0;
+}
+
+
+/* -------- initializing routines -------- */
+
+
+#include <math.h>
+
+void makewt(int nw, int *ip, double *w)
+{
+ void makeipt(int nw, int *ip);
+ int j, nwh, nw0, nw1;
+ double delta, wn4r, wk1r, wk1i, wk3r, wk3i;
+
+ ip[0] = nw;
+ ip[1] = 1;
+ if (nw > 2) {
+ nwh = nw >> 1;
+ delta = atan(1.0) / nwh;
+ wn4r = cos(delta * nwh);
+ w[0] = 1;
+ w[1] = wn4r;
+ if (nwh == 4) {
+ w[2] = cos(delta * 2);
+ w[3] = sin(delta * 2);
+ } else if (nwh > 4) {
+ makeipt(nw, ip);
+ w[2] = 0.5 / cos(delta * 2);
+ w[3] = 0.5 / cos(delta * 6);
+ for (j = 4; j < nwh; j += 4) {
+ w[j] = cos(delta * j);
+ w[j + 1] = sin(delta * j);
+ w[j + 2] = cos(3 * delta * j);
+ w[j + 3] = -sin(3 * delta * j);
+ }
+ }
+ nw0 = 0;
+ while (nwh > 2) {
+ nw1 = nw0 + nwh;
+ nwh >>= 1;
+ w[nw1] = 1;
+ w[nw1 + 1] = wn4r;
+ if (nwh == 4) {
+ wk1r = w[nw0 + 4];
+ wk1i = w[nw0 + 5];
+ w[nw1 + 2] = wk1r;
+ w[nw1 + 3] = wk1i;
+ } else if (nwh > 4) {
+ wk1r = w[nw0 + 4];
+ wk3r = w[nw0 + 6];
+ w[nw1 + 2] = 0.5 / wk1r;
+ w[nw1 + 3] = 0.5 / wk3r;
+ for (j = 4; j < nwh; j += 4) {
+ wk1r = w[nw0 + 2 * j];
+ wk1i = w[nw0 + 2 * j + 1];
+ wk3r = w[nw0 + 2 * j + 2];
+ wk3i = w[nw0 + 2 * j + 3];
+ w[nw1 + j] = wk1r;
+ w[nw1 + j + 1] = wk1i;
+ w[nw1 + j + 2] = wk3r;
+ w[nw1 + j + 3] = wk3i;
+ }
+ }
+ nw0 = nw1;
+ }
+ }
+}
+
+
+void makeipt(int nw, int *ip)
+{
+ int j, l, m, m2, p, q;
+
+ ip[2] = 0;
+ ip[3] = 16;
+ m = 2;
+ for (l = nw; l > 32; l >>= 2) {
+ m2 = m << 1;
+ q = m2 << 3;
+ for (j = m; j < m2; j++) {
+ p = ip[j] << 2;
+ ip[m + j] = p;
+ ip[m2 + j] = p + q;
+ }
+ m = m2;
+ }
+}
+
+
+void makect(int nc, int *ip, double *c)
+{
+ int j, nch;
+ double delta;
+
+ ip[1] = nc;
+ if (nc > 1) {
+ nch = nc >> 1;
+ delta = atan(1.0) / nch;
+ c[0] = cos(delta * nch);
+ c[nch] = 0.5 * c[0];
+ for (j = 1; j < nch; j++) {
+ c[j] = 0.5 * cos(delta * j);
+ c[nc - j] = 0.5 * sin(delta * j);
+ }
+ }
+}
+
+
+/* -------- child routines -------- */
+
+
+#ifdef USE_CDFT_PTHREADS
+#define USE_CDFT_THREADS
+#ifndef CDFT_THREADS_BEGIN_N
+#define CDFT_THREADS_BEGIN_N 8192
+#endif
+#ifndef CDFT_4THREADS_BEGIN_N
+#define CDFT_4THREADS_BEGIN_N 65536
+#endif
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#define cdft_thread_t pthread_t
+#define cdft_thread_create(thp,func,argp) { \
+ if (pthread_create(thp, NULL, func, (void *) argp) != 0) { \
+ fprintf(stderr, "cdft thread error\n"); \
+ exit(1); \
+ } \
+}
+#define cdft_thread_wait(th) { \
+ if (pthread_join(th, NULL) != 0) { \
+ fprintf(stderr, "cdft thread error\n"); \
+ exit(1); \
+ } \
+}
+#endif /* USE_CDFT_PTHREADS */
+
+
+#ifdef USE_CDFT_WINTHREADS
+#define USE_CDFT_THREADS
+#ifndef CDFT_THREADS_BEGIN_N
+#define CDFT_THREADS_BEGIN_N 32768
+#endif
+#ifndef CDFT_4THREADS_BEGIN_N
+#define CDFT_4THREADS_BEGIN_N 524288
+#endif
+#include <windows.h>
+#include <stdio.h>
+#include <stdlib.h>
+#define cdft_thread_t HANDLE
+#define cdft_thread_create(thp,func,argp) { \
+ DWORD thid; \
+ *(thp) = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) func, (LPVOID) argp, 0, &thid); \
+ if (*(thp) == 0) { \
+ fprintf(stderr, "cdft thread error\n"); \
+ exit(1); \
+ } \
+}
+#define cdft_thread_wait(th) { \
+ WaitForSingleObject(th, INFINITE); \
+ CloseHandle(th); \
+}
+#endif /* USE_CDFT_WINTHREADS */
+
+
+void cftfsub(int n, double *a, int *ip, int nw, double *w)
+{
+ void bitrv2(int n, int *ip, double *a);
+ void bitrv216(double *a);
+ void bitrv208(double *a);
+ void cftf1st(int n, double *a, double *w);
+ void cftrec4(int n, double *a, int nw, double *w);
+ void cftleaf(int n, int isplt, double *a, int nw, double *w);
+ void cftfx41(int n, double *a, int nw, double *w);
+ void cftf161(double *a, double *w);
+ void cftf081(double *a, double *w);
+ void cftf040(double *a);
+ void cftx020(double *a);
+#ifdef USE_CDFT_THREADS
+ void cftrec4_th(int n, double *a, int nw, double *w);
+#endif /* USE_CDFT_THREADS */
+
+ if (n > 8) {
+ if (n > 32) {
+ cftf1st(n, a, &w[nw - (n >> 2)]);
+#ifdef USE_CDFT_THREADS
+ if (n > CDFT_THREADS_BEGIN_N) {
+ cftrec4_th(n, a, nw, w);
+ } else
+#endif /* USE_CDFT_THREADS */
+ if (n > 512) {
+ cftrec4(n, a, nw, w);
+ } else if (n > 128) {
+ cftleaf(n, 1, a, nw, w);
+ } else {
+ cftfx41(n, a, nw, w);
+ }
+ bitrv2(n, ip, a);
+ } else if (n == 32) {
+ cftf161(a, &w[nw - 8]);
+ bitrv216(a);
+ } else {
+ cftf081(a, w);
+ bitrv208(a);
+ }
+ } else if (n == 8) {
+ cftf040(a);
+ } else if (n == 4) {
+ cftx020(a);
+ }
+}
+
+
+void cftbsub(int n, double *a, int *ip, int nw, double *w)
+{
+ void bitrv2conj(int n, int *ip, double *a);
+ void bitrv216neg(double *a);
+ void bitrv208neg(double *a);
+ void cftb1st(int n, double *a, double *w);
+ void cftrec4(int n, double *a, int nw, double *w);
+ void cftleaf(int n, int isplt, double *a, int nw, double *w);
+ void cftfx41(int n, double *a, int nw, double *w);
+ void cftf161(double *a, double *w);
+ void cftf081(double *a, double *w);
+ void cftb040(double *a);
+ void cftx020(double *a);
+#ifdef USE_CDFT_THREADS
+ void cftrec4_th(int n, double *a, int nw, double *w);
+#endif /* USE_CDFT_THREADS */
+
+ if (n > 8) {
+ if (n > 32) {
+ cftb1st(n, a, &w[nw - (n >> 2)]);
+#ifdef USE_CDFT_THREADS
+ if (n > CDFT_THREADS_BEGIN_N) {
+ cftrec4_th(n, a, nw, w);
+ } else
+#endif /* USE_CDFT_THREADS */
+ if (n > 512) {
+ cftrec4(n, a, nw, w);
+ } else if (n > 128) {
+ cftleaf(n, 1, a, nw, w);
+ } else {
+ cftfx41(n, a, nw, w);
+ }
+ bitrv2conj(n, ip, a);
+ } else if (n == 32) {
+ cftf161(a, &w[nw - 8]);
+ bitrv216neg(a);
+ } else {
+ cftf081(a, w);
+ bitrv208neg(a);
+ }
+ } else if (n == 8) {
+ cftb040(a);
+ } else if (n == 4) {
+ cftx020(a);
+ }
+}
+
+
+void bitrv2(int n, int *ip, double *a)
+{
+ int j, j1, k, k1, l, m, nh, nm;
+ double xr, xi, yr, yi;
+
+ m = 1;
+ for (l = n >> 2; l > 8; l >>= 2) {
+ m <<= 1;
+ }
+ nh = n >> 1;
+ nm = 4 * m;
+ if (l == 8) {
+ for (k = 0; k < m; k++) {
+ for (j = 0; j < k; j++) {
+ j1 = 4 * j + 2 * ip[m + k];
+ k1 = 4 * k + 2 * ip[m + j];
+ xr = a[j1];
+ xi = a[j1 + 1];
+ yr = a[k1];
+ yi = a[k1 + 1];
+ a[j1] = yr;
+ a[j1 + 1] = yi;
+ a[k1] = xr;
+ a[k1 + 1] = xi;
+ j1 += nm;
+ k1 += 2 * nm;
+ xr = a[j1];
+ xi = a[j1 + 1];
+ yr = a[k1];
+ yi = a[k1 + 1];
+ a[j1] = yr;
+ a[j1 + 1] = yi;
+ a[k1] = xr;
+ a[k1 + 1] = xi;
+ j1 += nm;
+ k1 -= nm;
+ xr = a[j1];
+ xi = a[j1 + 1];
+ yr = a[k1];
+ yi = a[k1 + 1];
+ a[j1] = yr;
+ a[j1 + 1] = yi;
+ a[k1] = xr;
+ a[k1 + 1] = xi;
+ j1 += nm;
+ k1 += 2 * nm;
+ xr = a[j1];
+ xi = a[j1 + 1];
+ yr = a[k1];
+ yi = a[k1 + 1];
+ a[j1] = yr;
+ a[j1 + 1] = yi;
+ a[k1] = xr;
+ a[k1 + 1] = xi;
+ j1 += nh;
+ k1 += 2;
+ xr = a[j1];
+ xi = a[j1 + 1];
+ yr = a[k1];
+ yi = a[k1 + 1];
+ a[j1] = yr;
+ a[j1 + 1] = yi;
+ a[k1] = xr;
+ a[k1 + 1] = xi;
+ j1 -= nm;
+ k1 -= 2 * nm;
+ xr = a[j1];
+ xi = a[j1 + 1];
+ yr = a[k1];
+ yi = a[k1 + 1];
+ a[j1] = yr;
+ a[j1 + 1] = yi;
+ a[k1] = xr;
+ a[k1 + 1] = xi;
+ j1 -= nm;
+ k1 += nm;
+ xr = a[j1];
+ xi = a[j1 + 1];
+ yr = a[k1];
+ yi = a[k1 + 1];
+ a[j1] = yr;
+ a[j1 + 1] = yi;
+ a[k1] = xr;
+ a[k1 + 1] = xi;
+ j1 -= nm;
+ k1 -= 2 * nm;
+ xr = a[j1];
+ xi = a[j1 + 1];
+ yr = a[k1];
+ yi = a[k1 + 1];
+ a[j1] = yr;
+ a[j1 + 1] = yi;
+ a[k1] = xr;
+ a[k1 + 1] = xi;
+ j1 += 2;
+ k1 += nh;
+ xr = a[j1];
+ xi = a[j1 + 1];
+ yr = a[k1];
+ yi = a[k1 + 1];
+ a[j1] = yr;
+ a[j1 + 1] = yi;
+ a[k1] = xr;
+ a[k1 + 1] = xi;
+ j1 += nm;
+ k1 += 2 * nm;
+ xr = a[j1];
+ xi = a[j1 + 1];
+ yr = a[k1];
+ yi = a[k1 + 1];
+ a[j1] = yr;
+ a[j1 + 1] = yi;
+ a[k1] = xr;
+ a[k1 + 1] = xi;
+ j1 += nm;
+ k1 -= nm;
+ xr = a[j1];
+ xi = a[j1 + 1];
+ yr = a[k1];
+ yi = a[k1 + 1];
+ a[j1] = yr;
+ a[j1 + 1] = yi;
+ a[k1] = xr;
+ a[k1 + 1] = xi;
+ j1 += nm;
+ k1 += 2 * nm;
+ xr = a[j1];
+ xi = a[j1 + 1];
+ yr = a[k1];
+ yi = a[k1 + 1];
+ a[j1] = yr;
+ a[j1 + 1] = yi;
+ a[k1] = xr;
+ a[k1 + 1] = xi;
+ j1 -= nh;
+ k1 -= 2;
+ xr = a[j1];
+ xi = a[j1 + 1];
+ yr = a[k1];
+ yi = a[k1 + 1];
+ a[j1] = yr;
+ a[j1 + 1] = yi;
+ a[k1] = xr;
+ a[k1 + 1] = xi;
+ j1 -= nm;
+ k1 -= 2 * nm;
+ xr = a[j1];
+ xi = a[j1 + 1];
+ yr = a[k1];
+ yi = a[k1 + 1];
+ a[j1] = yr;
+ a[j1 + 1] = yi;
+ a[k1] = xr;
+ a[k1 + 1] = xi;
+ j1 -= nm;
+ k1 += nm;
+ xr = a[j1];
+ xi = a[j1 + 1];
+ yr = a[k1];
+ yi = a[k1 + 1];
+ a[j1] = yr;
+ a[j1 + 1] = yi;
+ a[k1] = xr;
+ a[k1 + 1] = xi;
+ j1 -= nm;
+ k1 -= 2 * nm;
+ xr = a[j1];
+ xi = a[j1 + 1];
+ yr = a[k1];
+ yi = a[k1 + 1];
+ a[j1] = yr;
+ a[j1 + 1] = yi;
+ a[k1] = xr;
+ a[k1 + 1] = xi;
+ }
+ k1 = 4 * k + 2 * ip[m + k];
+ j1 = k1 + 2;
+ k1 += nh;
+ xr = a[j1];
+ xi = a[j1 + 1];
+ yr = a[k1];
+ yi = a[k1 + 1];
+ a[j1] = yr;
+ a[j1 + 1] = yi;
+ a[k1] = xr;
+ a[k1 + 1] = xi;
+ j1 += nm;
+ k1 += 2 * nm;
+ xr = a[j1];
+ xi = a[j1 + 1];
+ yr = a[k1];
+ yi = a[k1 + 1];
+ a[j1] = yr;
+ a[j1 + 1] = yi;
+ a[k1] = xr;
+ a[k1 + 1] = xi;
+ j1 += nm;
+ k1 -= nm;
+ xr = a[j1];
+ xi = a[j1 + 1];
+ yr = a[k1];
+ yi = a[k1 + 1];
+ a[j1] = yr;
+ a[j1 + 1] = yi;
+ a[k1] = xr;
+ a[k1 + 1] = xi;
+ j1 -= 2;
+ k1 -= nh;
+ xr = a[j1];
+ xi = a[j1 + 1];
+ yr = a[k1];
+ yi = a[k1 + 1];
+ a[j1] = yr;
+ a[j1 + 1] = yi;
+ a[k1] = xr;
+ a[k1 + 1] = xi;
+ j1 += nh + 2;
+ k1 += nh + 2;
+ xr = a[j1];
+ xi = a[j1 + 1];
+ yr = a[k1];
+ yi = a[k1 + 1];
+ a[j1] = yr;
+ a[j1 + 1] = yi;
+ a[k1] = xr;
+ a[k1 + 1] = xi;
+ j1 -= nh - nm;
+ k1 += 2 * nm - 2;
+ xr = a[j1];
+ xi = a[j1 + 1];
+ yr = a[k1];
+ yi = a[k1 + 1];
+ a[j1] = yr;
+ a[j1 + 1] = yi;
+ a[k1] = xr;
+ a[k1 + 1] = xi;
+ }
+ } else {
+ for (k = 0; k < m; k++) {
+ for (j = 0; j < k; j++) {
+ j1 = 4 * j + ip[m + k];
+ k1 = 4 * k + ip[m + j];
+ xr = a[j1];
+ xi = a[j1 + 1];
+ yr = a[k1];
+ yi = a[k1 + 1];
+ a[j1] = yr;
+ a[j1 + 1] = yi;
+ a[k1] = xr;
+ a[k1 + 1] = xi;
+ j1 += nm;
+ k1 += nm;
+ xr = a[j1];
+ xi = a[j1 + 1];
+ yr = a[k1];
+ yi = a[k1 + 1];
+ a[j1] = yr;
+ a[j1 + 1] = yi;
+ a[k1] = xr;
+ a[k1 + 1] = xi;
+ j1 += nh;
+ k1 += 2;
+ xr = a[j1];
+ xi = a[j1 + 1];
+ yr = a[k1];
+ yi = a[k1 + 1];
+ a[j1] = yr;
+ a[j1 + 1] = yi;
+ a[k1] = xr;
+ a[k1 + 1] = xi;
+ j1 -= nm;
+ k1 -= nm;
+ xr = a[j1];
+ xi = a[j1 + 1];
+ yr = a[k1];
+ yi = a[k1 + 1];
+ a[j1] = yr;
+ a[j1 + 1] = yi;
+ a[k1] = xr;
+ a[k1 + 1] = xi;
+ j1 += 2;
+ k1 += nh;
+ xr = a[j1];
+ xi = a[j1 + 1];
+ yr = a[k1];
+ yi = a[k1 + 1];
+ a[j1] = yr;
+ a[j1 + 1] = yi;
+ a[k1] = xr;
+ a[k1 + 1] = xi;
+ j1 += nm;
+ k1 += nm;
+ xr = a[j1];
+ xi = a[j1 + 1];
+ yr = a[k1];
+ yi = a[k1 + 1];
+ a[j1] = yr;
+ a[j1 + 1] = yi;
+ a[k1] = xr;
+ a[k1 + 1] = xi;
+ j1 -= nh;
+ k1 -= 2;
+ xr = a[j1];
+ xi = a[j1 + 1];
+ yr = a[k1];
+ yi = a[k1 + 1];
+ a[j1] = yr;
+ a[j1 + 1] = yi;
+ a[k1] = xr;
+ a[k1 + 1] = xi;
+ j1 -= nm;
+ k1 -= nm;
+ xr = a[j1];
+ xi = a[j1 + 1];
+ yr = a[k1];
+ yi = a[k1 + 1];
+ a[j1] = yr;
+ a[j1 + 1] = yi;
+ a[k1] = xr;
+ a[k1 + 1] = xi;
+ }
+ k1 = 4 * k + ip[m + k];
+ j1 = k1 + 2;
+ k1 += nh;
+ xr = a[j1];
+ xi = a[j1 + 1];
+ yr = a[k1];
+ yi = a[k1 + 1];
+ a[j1] = yr;
+ a[j1 + 1] = yi;
+ a[k1] = xr;
+ a[k1 + 1] = xi;
+ j1 += nm;
+ k1 += nm;
+ xr = a[j1];
+ xi = a[j1 + 1];
+ yr = a[k1];
+ yi = a[k1 + 1];
+ a[j1] = yr;
+ a[j1 + 1] = yi;
+ a[k1] = xr;
+ a[k1 + 1] = xi;
+ }
+ }
+}
+
+
+void bitrv2conj(int n, int *ip, double *a)
+{
+ int j, j1, k, k1, l, m, nh, nm;
+ double xr, xi, yr, yi;
+
+ m = 1;
+ for (l = n >> 2; l > 8; l >>= 2) {
+ m <<= 1;
+ }
+ nh = n >> 1;
+ nm = 4 * m;
+ if (l == 8) {
+ for (k = 0; k < m; k++) {
+ for (j = 0; j < k; j++) {
+ j1 = 4 * j + 2 * ip[m + k];
+ k1 = 4 * k + 2 * ip[m + j];
+ xr = a[j1];
+ xi = -a[j1 + 1];
+ yr = a[k1];
+ yi = -a[k1 + 1];
+ a[j1] = yr;
+ a[j1 + 1] = yi;
+ a[k1] = xr;
+ a[k1 + 1] = xi;
+ j1 += nm;
+ k1 += 2 * nm;
+ xr = a[j1];
+ xi = -a[j1 + 1];
+ yr = a[k1];
+ yi = -a[k1 + 1];
+ a[j1] = yr;
+ a[j1 + 1] = yi;
+ a[k1] = xr;
+ a[k1 + 1] = xi;
+ j1 += nm;
+ k1 -= nm;
+ xr = a[j1];
+ xi = -a[j1 + 1];
+ yr = a[k1];
+ yi = -a[k1 + 1];
+ a[j1] = yr;
+ a[j1 + 1] = yi;
+ a[k1] = xr;
+ a[k1 + 1] = xi;
+ j1 += nm;
+ k1 += 2 * nm;
+ xr = a[j1];
+ xi = -a[j1 + 1];
+ yr = a[k1];
+ yi = -a[k1 + 1];
+ a[j1] = yr;
+ a[j1 + 1] = yi;
+ a[k1] = xr;
+ a[k1 + 1] = xi;
+ j1 += nh;
+ k1 += 2;
+ xr = a[j1];
+ xi = -a[j1 + 1];
+ yr = a[k1];
+ yi = -a[k1 + 1];
+ a[j1] = yr;
+ a[j1 + 1] = yi;
+ a[k1] = xr;
+ a[k1 + 1] = xi;
+ j1 -= nm;
+ k1 -= 2 * nm;
+ xr = a[j1];
+ xi = -a[j1 + 1];
+ yr = a[k1];
+ yi = -a[k1 + 1];
+ a[j1] = yr;
+ a[j1 + 1] = yi;
+ a[k1] = xr;
+ a[k1 + 1] = xi;
+ j1 -= nm;
+ k1 += nm;
+ xr = a[j1];
+ xi = -a[j1 + 1];
+ yr = a[k1];
+ yi = -a[k1 + 1];
+ a[j1] = yr;
+ a[j1 + 1] = yi;
+ a[k1] = xr;
+ a[k1 + 1] = xi;
+ j1 -= nm;
+ k1 -= 2 * nm;
+ xr = a[j1];
+ xi = -a[j1 + 1];
+ yr = a[k1];
+ yi = -a[k1 + 1];
+ a[j1] = yr;
+ a[j1 + 1] = yi;
+ a[k1] = xr;
+ a[k1 + 1] = xi;
+ j1 += 2;
+ k1 += nh;
+ xr = a[j1];
+ xi = -a[j1 + 1];
+ yr = a[k1];
+ yi = -a[k1 + 1];
+ a[j1] = yr;
+ a[j1 + 1] = yi;
+ a[k1] = xr;
+ a[k1 + 1] = xi;
+ j1 += nm;
+ k1 += 2 * nm;
+ xr = a[j1];
+ xi = -a[j1 + 1];
+ yr = a[k1];
+ yi = -a[k1 + 1];
+ a[j1] = yr;
+ a[j1 + 1] = yi;
+ a[k1] = xr;
+ a[k1 + 1] = xi;
+ j1 += nm;
+ k1 -= nm;
+ xr = a[j1];
+ xi = -a[j1 + 1];
+ yr = a[k1];
+ yi = -a[k1 + 1];
+ a[j1] = yr;
+ a[j1 + 1] = yi;
+ a[k1] = xr;
+ a[k1 + 1] = xi;
+ j1 += nm;
+ k1 += 2 * nm;
+ xr = a[j1];
+ xi = -a[j1 + 1];
+ yr = a[k1];
+ yi = -a[k1 + 1];
+ a[j1] = yr;
+ a[j1 + 1] = yi;
+ a[k1] = xr;
+ a[k1 + 1] = xi;
+ j1 -= nh;
+ k1 -= 2;
+ xr = a[j1];
+ xi = -a[j1 + 1];
+ yr = a[k1];
+ yi = -a[k1 + 1];
+ a[j1] = yr;
+ a[j1 + 1] = yi;
+ a[k1] = xr;
+ a[k1 + 1] = xi;
+ j1 -= nm;
+ k1 -= 2 * nm;
+ xr = a[j1];
+ xi = -a[j1 + 1];
+ yr = a[k1];
+ yi = -a[k1 + 1];
+ a[j1] = yr;
+ a[j1 + 1] = yi;
+ a[k1] = xr;
+ a[k1 + 1] = xi;
+ j1 -= nm;
+ k1 += nm;
+ xr = a[j1];
+ xi = -a[j1 + 1];
+ yr = a[k1];
+ yi = -a[k1 + 1];
+ a[j1] = yr;
+ a[j1 + 1] = yi;
+ a[k1] = xr;
+ a[k1 + 1] = xi;
+ j1 -= nm;
+ k1 -= 2 * nm;
+ xr = a[j1];
+ xi = -a[j1 + 1];
+ yr = a[k1];
+ yi = -a[k1 + 1];
+ a[j1] = yr;
+ a[j1 + 1] = yi;
+ a[k1] = xr;
+ a[k1 + 1] = xi;
+ }
+ k1 = 4 * k + 2 * ip[m + k];
+ j1 = k1 + 2;
+ k1 += nh;
+ a[j1 - 1] = -a[j1 - 1];
+ xr = a[j1];
+ xi = -a[j1 + 1];
+ yr = a[k1];
+ yi = -a[k1 + 1];
+ a[j1] = yr;
+ a[j1 + 1] = yi;
+ a[k1] = xr;
+ a[k1 + 1] = xi;
+ a[k1 + 3] = -a[k1 + 3];
+ j1 += nm;
+ k1 += 2 * nm;
+ xr = a[j1];
+ xi = -a[j1 + 1];
+ yr = a[k1];
+ yi = -a[k1 + 1];
+ a[j1] = yr;
+ a[j1 + 1] = yi;
+ a[k1] = xr;
+ a[k1 + 1] = xi;
+ j1 += nm;
+ k1 -= nm;
+ xr = a[j1];
+ xi = -a[j1 + 1];
+ yr = a[k1];
+ yi = -a[k1 + 1];
+ a[j1] = yr;
+ a[j1 + 1] = yi;
+ a[k1] = xr;
+ a[k1 + 1] = xi;
+ j1 -= 2;
+ k1 -= nh;
+ xr = a[j1];
+ xi = -a[j1 + 1];
+ yr = a[k1];
+ yi = -a[k1 + 1];
+ a[j1] = yr;
+ a[j1 + 1] = yi;
+ a[k1] = xr;
+ a[k1 + 1] = xi;
+ j1 += nh + 2;
+ k1 += nh + 2;
+ xr = a[j1];
+ xi = -a[j1 + 1];
+ yr = a[k1];
+ yi = -a[k1 + 1];
+ a[j1] = yr;
+ a[j1 + 1] = yi;
+ a[k1] = xr;
+ a[k1 + 1] = xi;
+ j1 -= nh - nm;
+ k1 += 2 * nm - 2;
+ a[j1 - 1] = -a[j1 - 1];
+ xr = a[j1];
+ xi = -a[j1 + 1];
+ yr = a[k1];
+ yi = -a[k1 + 1];
+ a[j1] = yr;
+ a[j1 + 1] = yi;
+ a[k1] = xr;
+ a[k1 + 1] = xi;
+ a[k1 + 3] = -a[k1 + 3];
+ }
+ } else {
+ for (k = 0; k < m; k++) {
+ for (j = 0; j < k; j++) {
+ j1 = 4 * j + ip[m + k];
+ k1 = 4 * k + ip[m + j];
+ xr = a[j1];
+ xi = -a[j1 + 1];
+ yr = a[k1];
+ yi = -a[k1 + 1];
+ a[j1] = yr;
+ a[j1 + 1] = yi;
+ a[k1] = xr;
+ a[k1 + 1] = xi;
+ j1 += nm;
+ k1 += nm;
+ xr = a[j1];
+ xi = -a[j1 + 1];
+ yr = a[k1];
+ yi = -a[k1 + 1];
+ a[j1] = yr;
+ a[j1 + 1] = yi;
+ a[k1] = xr;
+ a[k1 + 1] = xi;
+ j1 += nh;
+ k1 += 2;
+ xr = a[j1];
+ xi = -a[j1 + 1];
+ yr = a[k1];
+ yi = -a[k1 + 1];
+ a[j1] = yr;
+ a[j1 + 1] = yi;
+ a[k1] = xr;
+ a[k1 + 1] = xi;
+ j1 -= nm;
+ k1 -= nm;
+ xr = a[j1];
+ xi = -a[j1 + 1];
+ yr = a[k1];
+ yi = -a[k1 + 1];
+ a[j1] = yr;
+ a[j1 + 1] = yi;
+ a[k1] = xr;
+ a[k1 + 1] = xi;
+ j1 += 2;
+ k1 += nh;
+ xr = a[j1];
+ xi = -a[j1 + 1];
+ yr = a[k1];
+ yi = -a[k1 + 1];
+ a[j1] = yr;
+ a[j1 + 1] = yi;
+ a[k1] = xr;
+ a[k1 + 1] = xi;
+ j1 += nm;
+ k1 += nm;
+ xr = a[j1];
+ xi = -a[j1 + 1];
+ yr = a[k1];
+ yi = -a[k1 + 1];
+ a[j1] = yr;
+ a[j1 + 1] = yi;
+ a[k1] = xr;
+ a[k1 + 1] = xi;
+ j1 -= nh;
+ k1 -= 2;
+ xr = a[j1];
+ xi = -a[j1 + 1];
+ yr = a[k1];
+ yi = -a[k1 + 1];
+ a[j1] = yr;
+ a[j1 + 1] = yi;
+ a[k1] = xr;
+ a[k1 + 1] = xi;
+ j1 -= nm;
+ k1 -= nm;
+ xr = a[j1];
+ xi = -a[j1 + 1];
+ yr = a[k1];
+ yi = -a[k1 + 1];
+ a[j1] = yr;
+ a[j1 + 1] = yi;
+ a[k1] = xr;
+ a[k1 + 1] = xi;
+ }
+ k1 = 4 * k + ip[m + k];
+ j1 = k1 + 2;
+ k1 += nh;
+ a[j1 - 1] = -a[j1 - 1];
+ xr = a[j1];
+ xi = -a[j1 + 1];
+ yr = a[k1];
+ yi = -a[k1 + 1];
+ a[j1] = yr;
+ a[j1 + 1] = yi;
+ a[k1] = xr;
+ a[k1 + 1] = xi;
+ a[k1 + 3] = -a[k1 + 3];
+ j1 += nm;
+ k1 += nm;
+ a[j1 - 1] = -a[j1 - 1];
+ xr = a[j1];
+ xi = -a[j1 + 1];
+ yr = a[k1];
+ yi = -a[k1 + 1];
+ a[j1] = yr;
+ a[j1 + 1] = yi;
+ a[k1] = xr;
+ a[k1 + 1] = xi;
+ a[k1 + 3] = -a[k1 + 3];
+ }
+ }
+}
+
+
+void bitrv216(double *a)
+{
+ double x1r, x1i, x2r, x2i, x3r, x3i, x4r, x4i,
+ x5r, x5i, x7r, x7i, x8r, x8i, x10r, x10i,
+ x11r, x11i, x12r, x12i, x13r, x13i, x14r, x14i;
+
+ x1r = a[2];
+ x1i = a[3];
+ x2r = a[4];
+ x2i = a[5];
+ x3r = a[6];
+ x3i = a[7];
+ x4r = a[8];
+ x4i = a[9];
+ x5r = a[10];
+ x5i = a[11];
+ x7r = a[14];
+ x7i = a[15];
+ x8r = a[16];
+ x8i = a[17];
+ x10r = a[20];
+ x10i = a[21];
+ x11r = a[22];
+ x11i = a[23];
+ x12r = a[24];
+ x12i = a[25];
+ x13r = a[26];
+ x13i = a[27];
+ x14r = a[28];
+ x14i = a[29];
+ a[2] = x8r;
+ a[3] = x8i;
+ a[4] = x4r;
+ a[5] = x4i;
+ a[6] = x12r;
+ a[7] = x12i;
+ a[8] = x2r;
+ a[9] = x2i;
+ a[10] = x10r;
+ a[11] = x10i;
+ a[14] = x14r;
+ a[15] = x14i;
+ a[16] = x1r;
+ a[17] = x1i;
+ a[20] = x5r;
+ a[21] = x5i;
+ a[22] = x13r;
+ a[23] = x13i;
+ a[24] = x3r;
+ a[25] = x3i;
+ a[26] = x11r;
+ a[27] = x11i;
+ a[28] = x7r;
+ a[29] = x7i;
+}
+
+
+void bitrv216neg(double *a)
+{
+ double x1r, x1i, x2r, x2i, x3r, x3i, x4r, x4i,
+ x5r, x5i, x6r, x6i, x7r, x7i, x8r, x8i,
+ x9r, x9i, x10r, x10i, x11r, x11i, x12r, x12i,
+ x13r, x13i, x14r, x14i, x15r, x15i;
+
+ x1r = a[2];
+ x1i = a[3];
+ x2r = a[4];
+ x2i = a[5];
+ x3r = a[6];
+ x3i = a[7];
+ x4r = a[8];
+ x4i = a[9];
+ x5r = a[10];
+ x5i = a[11];
+ x6r = a[12];
+ x6i = a[13];
+ x7r = a[14];
+ x7i = a[15];
+ x8r = a[16];
+ x8i = a[17];
+ x9r = a[18];
+ x9i = a[19];
+ x10r = a[20];
+ x10i = a[21];
+ x11r = a[22];
+ x11i = a[23];
+ x12r = a[24];
+ x12i = a[25];
+ x13r = a[26];
+ x13i = a[27];
+ x14r = a[28];
+ x14i = a[29];
+ x15r = a[30];
+ x15i = a[31];
+ a[2] = x15r;
+ a[3] = x15i;
+ a[4] = x7r;
+ a[5] = x7i;
+ a[6] = x11r;
+ a[7] = x11i;
+ a[8] = x3r;
+ a[9] = x3i;
+ a[10] = x13r;
+ a[11] = x13i;
+ a[12] = x5r;
+ a[13] = x5i;
+ a[14] = x9r;
+ a[15] = x9i;
+ a[16] = x1r;
+ a[17] = x1i;
+ a[18] = x14r;
+ a[19] = x14i;
+ a[20] = x6r;
+ a[21] = x6i;
+ a[22] = x10r;
+ a[23] = x10i;
+ a[24] = x2r;
+ a[25] = x2i;
+ a[26] = x12r;
+ a[27] = x12i;
+ a[28] = x4r;
+ a[29] = x4i;
+ a[30] = x8r;
+ a[31] = x8i;
+}
+
+
+void bitrv208(double *a)
+{
+ double x1r, x1i, x3r, x3i, x4r, x4i, x6r, x6i;
+
+ x1r = a[2];
+ x1i = a[3];
+ x3r = a[6];
+ x3i = a[7];
+ x4r = a[8];
+ x4i = a[9];
+ x6r = a[12];
+ x6i = a[13];
+ a[2] = x4r;
+ a[3] = x4i;
+ a[6] = x6r;
+ a[7] = x6i;
+ a[8] = x1r;
+ a[9] = x1i;
+ a[12] = x3r;
+ a[13] = x3i;
+}
+
+
+void bitrv208neg(double *a)
+{
+ double x1r, x1i, x2r, x2i, x3r, x3i, x4r, x4i,
+ x5r, x5i, x6r, x6i, x7r, x7i;
+
+ x1r = a[2];
+ x1i = a[3];
+ x2r = a[4];
+ x2i = a[5];
+ x3r = a[6];
+ x3i = a[7];
+ x4r = a[8];
+ x4i = a[9];
+ x5r = a[10];
+ x5i = a[11];
+ x6r = a[12];
+ x6i = a[13];
+ x7r = a[14];
+ x7i = a[15];
+ a[2] = x7r;
+ a[3] = x7i;
+ a[4] = x3r;
+ a[5] = x3i;
+ a[6] = x5r;
+ a[7] = x5i;
+ a[8] = x1r;
+ a[9] = x1i;
+ a[10] = x6r;
+ a[11] = x6i;
+ a[12] = x2r;
+ a[13] = x2i;
+ a[14] = x4r;
+ a[15] = x4i;
+}
+
+
+void cftf1st(int n, double *a, double *w)
+{
+ int j, j0, j1, j2, j3, k, m, mh;
+ double wn4r, csc1, csc3, wk1r, wk1i, wk3r, wk3i,
+ wd1r, wd1i, wd3r, wd3i;
+ double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i,
+ y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i;
+
+ mh = n >> 3;
+ m = 2 * mh;
+ j1 = m;
+ j2 = j1 + m;
+ j3 = j2 + m;
+ x0r = a[0] + a[j2];
+ x0i = a[1] + a[j2 + 1];
+ x1r = a[0] - a[j2];
+ x1i = a[1] - a[j2 + 1];
+ x2r = a[j1] + a[j3];
+ x2i = a[j1 + 1] + a[j3 + 1];
+ x3r = a[j1] - a[j3];
+ x3i = a[j1 + 1] - a[j3 + 1];
+ a[0] = x0r + x2r;
+ a[1] = x0i + x2i;
+ a[j1] = x0r - x2r;
+ a[j1 + 1] = x0i - x2i;
+ a[j2] = x1r - x3i;
+ a[j2 + 1] = x1i + x3r;
+ a[j3] = x1r + x3i;
+ a[j3 + 1] = x1i - x3r;
+ wn4r = w[1];
+ csc1 = w[2];
+ csc3 = w[3];
+ wd1r = 1;
+ wd1i = 0;
+ wd3r = 1;
+ wd3i = 0;
+ k = 0;
+ for (j = 2; j < mh - 2; j += 4) {
+ k += 4;
+ wk1r = csc1 * (wd1r + w[k]);
+ wk1i = csc1 * (wd1i + w[k + 1]);
+ wk3r = csc3 * (wd3r + w[k + 2]);
+ wk3i = csc3 * (wd3i + w[k + 3]);
+ wd1r = w[k];
+ wd1i = w[k + 1];
+ wd3r = w[k + 2];
+ wd3i = w[k + 3];
+ j1 = j + m;
+ j2 = j1 + m;
+ j3 = j2 + m;
+ x0r = a[j] + a[j2];
+ x0i = a[j + 1] + a[j2 + 1];
+ x1r = a[j] - a[j2];
+ x1i = a[j + 1] - a[j2 + 1];
+ y0r = a[j + 2] + a[j2 + 2];
+ y0i = a[j + 3] + a[j2 + 3];
+ y1r = a[j + 2] - a[j2 + 2];
+ y1i = a[j + 3] - a[j2 + 3];
+ x2r = a[j1] + a[j3];
+ x2i = a[j1 + 1] + a[j3 + 1];
+ x3r = a[j1] - a[j3];
+ x3i = a[j1 + 1] - a[j3 + 1];
+ y2r = a[j1 + 2] + a[j3 + 2];
+ y2i = a[j1 + 3] + a[j3 + 3];
+ y3r = a[j1 + 2] - a[j3 + 2];
+ y3i = a[j1 + 3] - a[j3 + 3];
+ a[j] = x0r + x2r;
+ a[j + 1] = x0i + x2i;
+ a[j + 2] = y0r + y2r;
+ a[j + 3] = y0i + y2i;
+ a[j1] = x0r - x2r;
+ a[j1 + 1] = x0i - x2i;
+ a[j1 + 2] = y0r - y2r;
+ a[j1 + 3] = y0i - y2i;
+ x0r = x1r - x3i;
+ x0i = x1i + x3r;
+ a[j2] = wk1r * x0r - wk1i * x0i;
+ a[j2 + 1] = wk1r * x0i + wk1i * x0r;
+ x0r = y1r - y3i;
+ x0i = y1i + y3r;
+ a[j2 + 2] = wd1r * x0r - wd1i * x0i;
+ a[j2 + 3] = wd1r * x0i + wd1i * x0r;
+ x0r = x1r + x3i;
+ x0i = x1i - x3r;
+ a[j3] = wk3r * x0r + wk3i * x0i;
+ a[j3 + 1] = wk3r * x0i - wk3i * x0r;
+ x0r = y1r + y3i;
+ x0i = y1i - y3r;
+ a[j3 + 2] = wd3r * x0r + wd3i * x0i;
+ a[j3 + 3] = wd3r * x0i - wd3i * x0r;
+ j0 = m - j;
+ j1 = j0 + m;
+ j2 = j1 + m;
+ j3 = j2 + m;
+ x0r = a[j0] + a[j2];
+ x0i = a[j0 + 1] + a[j2 + 1];
+ x1r = a[j0] - a[j2];
+ x1i = a[j0 + 1] - a[j2 + 1];
+ y0r = a[j0 - 2] + a[j2 - 2];
+ y0i = a[j0 - 1] + a[j2 - 1];
+ y1r = a[j0 - 2] - a[j2 - 2];
+ y1i = a[j0 - 1] - a[j2 - 1];
+ x2r = a[j1] + a[j3];
+ x2i = a[j1 + 1] + a[j3 + 1];
+ x3r = a[j1] - a[j3];
+ x3i = a[j1 + 1] - a[j3 + 1];
+ y2r = a[j1 - 2] + a[j3 - 2];
+ y2i = a[j1 - 1] + a[j3 - 1];
+ y3r = a[j1 - 2] - a[j3 - 2];
+ y3i = a[j1 - 1] - a[j3 - 1];
+ a[j0] = x0r + x2r;
+ a[j0 + 1] = x0i + x2i;
+ a[j0 - 2] = y0r + y2r;
+ a[j0 - 1] = y0i + y2i;
+ a[j1] = x0r - x2r;
+ a[j1 + 1] = x0i - x2i;
+ a[j1 - 2] = y0r - y2r;
+ a[j1 - 1] = y0i - y2i;
+ x0r = x1r - x3i;
+ x0i = x1i + x3r;
+ a[j2] = wk1i * x0r - wk1r * x0i;
+ a[j2 + 1] = wk1i * x0i + wk1r * x0r;
+ x0r = y1r - y3i;
+ x0i = y1i + y3r;
+ a[j2 - 2] = wd1i * x0r - wd1r * x0i;
+ a[j2 - 1] = wd1i * x0i + wd1r * x0r;
+ x0r = x1r + x3i;
+ x0i = x1i - x3r;
+ a[j3] = wk3i * x0r + wk3r * x0i;
+ a[j3 + 1] = wk3i * x0i - wk3r * x0r;
+ x0r = y1r + y3i;
+ x0i = y1i - y3r;
+ a[j3 - 2] = wd3i * x0r + wd3r * x0i;
+ a[j3 - 1] = wd3i * x0i - wd3r * x0r;
+ }
+ wk1r = csc1 * (wd1r + wn4r);
+ wk1i = csc1 * (wd1i + wn4r);
+ wk3r = csc3 * (wd3r - wn4r);
+ wk3i = csc3 * (wd3i - wn4r);
+ j0 = mh;
+ j1 = j0 + m;
+ j2 = j1 + m;
+ j3 = j2 + m;
+ x0r = a[j0 - 2] + a[j2 - 2];
+ x0i = a[j0 - 1] + a[j2 - 1];
+ x1r = a[j0 - 2] - a[j2 - 2];
+ x1i = a[j0 - 1] - a[j2 - 1];
+ x2r = a[j1 - 2] + a[j3 - 2];
+ x2i = a[j1 - 1] + a[j3 - 1];
+ x3r = a[j1 - 2] - a[j3 - 2];
+ x3i = a[j1 - 1] - a[j3 - 1];
+ a[j0 - 2] = x0r + x2r;
+ a[j0 - 1] = x0i + x2i;
+ a[j1 - 2] = x0r - x2r;
+ a[j1 - 1] = x0i - x2i;
+ x0r = x1r - x3i;
+ x0i = x1i + x3r;
+ a[j2 - 2] = wk1r * x0r - wk1i * x0i;
+ a[j2 - 1] = wk1r * x0i + wk1i * x0r;
+ x0r = x1r + x3i;
+ x0i = x1i - x3r;
+ a[j3 - 2] = wk3r * x0r + wk3i * x0i;
+ a[j3 - 1] = wk3r * x0i - wk3i * x0r;
+ x0r = a[j0] + a[j2];
+ x0i = a[j0 + 1] + a[j2 + 1];
+ x1r = a[j0] - a[j2];
+ x1i = a[j0 + 1] - a[j2 + 1];
+ x2r = a[j1] + a[j3];
+ x2i = a[j1 + 1] + a[j3 + 1];
+ x3r = a[j1] - a[j3];
+ x3i = a[j1 + 1] - a[j3 + 1];
+ a[j0] = x0r + x2r;
+ a[j0 + 1] = x0i + x2i;
+ a[j1] = x0r - x2r;
+ a[j1 + 1] = x0i - x2i;
+ x0r = x1r - x3i;
+ x0i = x1i + x3r;
+ a[j2] = wn4r * (x0r - x0i);
+ a[j2 + 1] = wn4r * (x0i + x0r);
+ x0r = x1r + x3i;
+ x0i = x1i - x3r;
+ a[j3] = -wn4r * (x0r + x0i);
+ a[j3 + 1] = -wn4r * (x0i - x0r);
+ x0r = a[j0 + 2] + a[j2 + 2];
+ x0i = a[j0 + 3] + a[j2 + 3];
+ x1r = a[j0 + 2] - a[j2 + 2];
+ x1i = a[j0 + 3] - a[j2 + 3];
+ x2r = a[j1 + 2] + a[j3 + 2];
+ x2i = a[j1 + 3] + a[j3 + 3];
+ x3r = a[j1 + 2] - a[j3 + 2];
+ x3i = a[j1 + 3] - a[j3 + 3];
+ a[j0 + 2] = x0r + x2r;
+ a[j0 + 3] = x0i + x2i;
+ a[j1 + 2] = x0r - x2r;
+ a[j1 + 3] = x0i - x2i;
+ x0r = x1r - x3i;
+ x0i = x1i + x3r;
+ a[j2 + 2] = wk1i * x0r - wk1r * x0i;
+ a[j2 + 3] = wk1i * x0i + wk1r * x0r;
+ x0r = x1r + x3i;
+ x0i = x1i - x3r;
+ a[j3 + 2] = wk3i * x0r + wk3r * x0i;
+ a[j3 + 3] = wk3i * x0i - wk3r * x0r;
+}
+
+
+void cftb1st(int n, double *a, double *w)
+{
+ int j, j0, j1, j2, j3, k, m, mh;
+ double wn4r, csc1, csc3, wk1r, wk1i, wk3r, wk3i,
+ wd1r, wd1i, wd3r, wd3i;
+ double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i,
+ y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i;
+
+ mh = n >> 3;
+ m = 2 * mh;
+ j1 = m;
+ j2 = j1 + m;
+ j3 = j2 + m;
+ x0r = a[0] + a[j2];
+ x0i = -a[1] - a[j2 + 1];
+ x1r = a[0] - a[j2];
+ x1i = -a[1] + a[j2 + 1];
+ x2r = a[j1] + a[j3];
+ x2i = a[j1 + 1] + a[j3 + 1];
+ x3r = a[j1] - a[j3];
+ x3i = a[j1 + 1] - a[j3 + 1];
+ a[0] = x0r + x2r;
+ a[1] = x0i - x2i;
+ a[j1] = x0r - x2r;
+ a[j1 + 1] = x0i + x2i;
+ a[j2] = x1r + x3i;
+ a[j2 + 1] = x1i + x3r;
+ a[j3] = x1r - x3i;
+ a[j3 + 1] = x1i - x3r;
+ wn4r = w[1];
+ csc1 = w[2];
+ csc3 = w[3];
+ wd1r = 1;
+ wd1i = 0;
+ wd3r = 1;
+ wd3i = 0;
+ k = 0;
+ for (j = 2; j < mh - 2; j += 4) {
+ k += 4;
+ wk1r = csc1 * (wd1r + w[k]);
+ wk1i = csc1 * (wd1i + w[k + 1]);
+ wk3r = csc3 * (wd3r + w[k + 2]);
+ wk3i = csc3 * (wd3i + w[k + 3]);
+ wd1r = w[k];
+ wd1i = w[k + 1];
+ wd3r = w[k + 2];
+ wd3i = w[k + 3];
+ j1 = j + m;
+ j2 = j1 + m;
+ j3 = j2 + m;
+ x0r = a[j] + a[j2];
+ x0i = -a[j + 1] - a[j2 + 1];
+ x1r = a[j] - a[j2];
+ x1i = -a[j + 1] + a[j2 + 1];
+ y0r = a[j + 2] + a[j2 + 2];
+ y0i = -a[j + 3] - a[j2 + 3];
+ y1r = a[j + 2] - a[j2 + 2];
+ y1i = -a[j + 3] + a[j2 + 3];
+ x2r = a[j1] + a[j3];
+ x2i = a[j1 + 1] + a[j3 + 1];
+ x3r = a[j1] - a[j3];
+ x3i = a[j1 + 1] - a[j3 + 1];
+ y2r = a[j1 + 2] + a[j3 + 2];
+ y2i = a[j1 + 3] + a[j3 + 3];
+ y3r = a[j1 + 2] - a[j3 + 2];
+ y3i = a[j1 + 3] - a[j3 + 3];
+ a[j] = x0r + x2r;
+ a[j + 1] = x0i - x2i;
+ a[j + 2] = y0r + y2r;
+ a[j + 3] = y0i - y2i;
+ a[j1] = x0r - x2r;
+ a[j1 + 1] = x0i + x2i;
+ a[j1 + 2] = y0r - y2r;
+ a[j1 + 3] = y0i + y2i;
+ x0r = x1r + x3i;
+ x0i = x1i + x3r;
+ a[j2] = wk1r * x0r - wk1i * x0i;
+ a[j2 + 1] = wk1r * x0i + wk1i * x0r;
+ x0r = y1r + y3i;
+ x0i = y1i + y3r;
+ a[j2 + 2] = wd1r * x0r - wd1i * x0i;
+ a[j2 + 3] = wd1r * x0i + wd1i * x0r;
+ x0r = x1r - x3i;
+ x0i = x1i - x3r;
+ a[j3] = wk3r * x0r + wk3i * x0i;
+ a[j3 + 1] = wk3r * x0i - wk3i * x0r;
+ x0r = y1r - y3i;
+ x0i = y1i - y3r;
+ a[j3 + 2] = wd3r * x0r + wd3i * x0i;
+ a[j3 + 3] = wd3r * x0i - wd3i * x0r;
+ j0 = m - j;
+ j1 = j0 + m;
+ j2 = j1 + m;
+ j3 = j2 + m;
+ x0r = a[j0] + a[j2];
+ x0i = -a[j0 + 1] - a[j2 + 1];
+ x1r = a[j0] - a[j2];
+ x1i = -a[j0 + 1] + a[j2 + 1];
+ y0r = a[j0 - 2] + a[j2 - 2];
+ y0i = -a[j0 - 1] - a[j2 - 1];
+ y1r = a[j0 - 2] - a[j2 - 2];
+ y1i = -a[j0 - 1] + a[j2 - 1];
+ x2r = a[j1] + a[j3];
+ x2i = a[j1 + 1] + a[j3 + 1];
+ x3r = a[j1] - a[j3];
+ x3i = a[j1 + 1] - a[j3 + 1];
+ y2r = a[j1 - 2] + a[j3 - 2];
+ y2i = a[j1 - 1] + a[j3 - 1];
+ y3r = a[j1 - 2] - a[j3 - 2];
+ y3i = a[j1 - 1] - a[j3 - 1];
+ a[j0] = x0r + x2r;
+ a[j0 + 1] = x0i - x2i;
+ a[j0 - 2] = y0r + y2r;
+ a[j0 - 1] = y0i - y2i;
+ a[j1] = x0r - x2r;
+ a[j1 + 1] = x0i + x2i;
+ a[j1 - 2] = y0r - y2r;
+ a[j1 - 1] = y0i + y2i;
+ x0r = x1r + x3i;
+ x0i = x1i + x3r;
+ a[j2] = wk1i * x0r - wk1r * x0i;
+ a[j2 + 1] = wk1i * x0i + wk1r * x0r;
+ x0r = y1r + y3i;
+ x0i = y1i + y3r;
+ a[j2 - 2] = wd1i * x0r - wd1r * x0i;
+ a[j2 - 1] = wd1i * x0i + wd1r * x0r;
+ x0r = x1r - x3i;
+ x0i = x1i - x3r;
+ a[j3] = wk3i * x0r + wk3r * x0i;
+ a[j3 + 1] = wk3i * x0i - wk3r * x0r;
+ x0r = y1r - y3i;
+ x0i = y1i - y3r;
+ a[j3 - 2] = wd3i * x0r + wd3r * x0i;
+ a[j3 - 1] = wd3i * x0i - wd3r * x0r;
+ }
+ wk1r = csc1 * (wd1r + wn4r);
+ wk1i = csc1 * (wd1i + wn4r);
+ wk3r = csc3 * (wd3r - wn4r);
+ wk3i = csc3 * (wd3i - wn4r);
+ j0 = mh;
+ j1 = j0 + m;
+ j2 = j1 + m;
+ j3 = j2 + m;
+ x0r = a[j0 - 2] + a[j2 - 2];
+ x0i = -a[j0 - 1] - a[j2 - 1];
+ x1r = a[j0 - 2] - a[j2 - 2];
+ x1i = -a[j0 - 1] + a[j2 - 1];
+ x2r = a[j1 - 2] + a[j3 - 2];
+ x2i = a[j1 - 1] + a[j3 - 1];
+ x3r = a[j1 - 2] - a[j3 - 2];
+ x3i = a[j1 - 1] - a[j3 - 1];
+ a[j0 - 2] = x0r + x2r;
+ a[j0 - 1] = x0i - x2i;
+ a[j1 - 2] = x0r - x2r;
+ a[j1 - 1] = x0i + x2i;
+ x0r = x1r + x3i;
+ x0i = x1i + x3r;
+ a[j2 - 2] = wk1r * x0r - wk1i * x0i;
+ a[j2 - 1] = wk1r * x0i + wk1i * x0r;
+ x0r = x1r - x3i;
+ x0i = x1i - x3r;
+ a[j3 - 2] = wk3r * x0r + wk3i * x0i;
+ a[j3 - 1] = wk3r * x0i - wk3i * x0r;
+ x0r = a[j0] + a[j2];
+ x0i = -a[j0 + 1] - a[j2 + 1];
+ x1r = a[j0] - a[j2];
+ x1i = -a[j0 + 1] + a[j2 + 1];
+ x2r = a[j1] + a[j3];
+ x2i = a[j1 + 1] + a[j3 + 1];
+ x3r = a[j1] - a[j3];
+ x3i = a[j1 + 1] - a[j3 + 1];
+ a[j0] = x0r + x2r;
+ a[j0 + 1] = x0i - x2i;
+ a[j1] = x0r - x2r;
+ a[j1 + 1] = x0i + x2i;
+ x0r = x1r + x3i;
+ x0i = x1i + x3r;
+ a[j2] = wn4r * (x0r - x0i);
+ a[j2 + 1] = wn4r * (x0i + x0r);
+ x0r = x1r - x3i;
+ x0i = x1i - x3r;
+ a[j3] = -wn4r * (x0r + x0i);
+ a[j3 + 1] = -wn4r * (x0i - x0r);
+ x0r = a[j0 + 2] + a[j2 + 2];
+ x0i = -a[j0 + 3] - a[j2 + 3];
+ x1r = a[j0 + 2] - a[j2 + 2];
+ x1i = -a[j0 + 3] + a[j2 + 3];
+ x2r = a[j1 + 2] + a[j3 + 2];
+ x2i = a[j1 + 3] + a[j3 + 3];
+ x3r = a[j1 + 2] - a[j3 + 2];
+ x3i = a[j1 + 3] - a[j3 + 3];
+ a[j0 + 2] = x0r + x2r;
+ a[j0 + 3] = x0i - x2i;
+ a[j1 + 2] = x0r - x2r;
+ a[j1 + 3] = x0i + x2i;
+ x0r = x1r + x3i;
+ x0i = x1i + x3r;
+ a[j2 + 2] = wk1i * x0r - wk1r * x0i;
+ a[j2 + 3] = wk1i * x0i + wk1r * x0r;
+ x0r = x1r - x3i;
+ x0i = x1i - x3r;
+ a[j3 + 2] = wk3i * x0r + wk3r * x0i;
+ a[j3 + 3] = wk3i * x0i - wk3r * x0r;
+}
+
+
+#ifdef USE_CDFT_THREADS
+struct cdft_arg_st {
+ int n0;
+ int n;
+ double *a;
+ int nw;
+ double *w;
+};
+typedef struct cdft_arg_st cdft_arg_t;
+
+
+void cftrec4_th(int n, double *a, int nw, double *w)
+{
+ void *cftrec1_th(void *p);
+ void *cftrec2_th(void *p);
+ int i, idiv4, m, nthread;
+ cdft_thread_t th[4];
+ cdft_arg_t ag[4];
+
+ nthread = 2;
+ idiv4 = 0;
+ m = n >> 1;
+ if (n > CDFT_4THREADS_BEGIN_N) {
+ nthread = 4;
+ idiv4 = 1;
+ m >>= 1;
+ }
+ for (i = 0; i < nthread; i++) {
+ ag[i].n0 = n;
+ ag[i].n = m;
+ ag[i].a = &a[i * m];
+ ag[i].nw = nw;
+ ag[i].w = w;
+ if (i != idiv4) {
+ cdft_thread_create(&th[i], cftrec1_th, &ag[i]);
+ } else {
+ cdft_thread_create(&th[i], cftrec2_th, &ag[i]);
+ }
+ }
+ for (i = 0; i < nthread; i++) {
+ cdft_thread_wait(th[i]);
+ }
+}
+
+
+void *cftrec1_th(void *p)
+{
+ int cfttree(int n, int j, int k, double *a, int nw, double *w);
+ void cftleaf(int n, int isplt, double *a, int nw, double *w);
+ void cftmdl1(int n, double *a, double *w);
+ int isplt, j, k, m, n, n0, nw;
+ double *a, *w;
+
+ n0 = ((cdft_arg_t *) p)->n0;
+ n = ((cdft_arg_t *) p)->n;
+ a = ((cdft_arg_t *) p)->a;
+ nw = ((cdft_arg_t *) p)->nw;
+ w = ((cdft_arg_t *) p)->w;
+ m = n0;
+ while (m > 512) {
+ m >>= 2;
+ cftmdl1(m, &a[n - m], &w[nw - (m >> 1)]);
+ }
+ cftleaf(m, 1, &a[n - m], nw, w);
+ k = 0;
+ for (j = n - m; j > 0; j -= m) {
+ k++;
+ isplt = cfttree(m, j, k, a, nw, w);
+ cftleaf(m, isplt, &a[j - m], nw, w);
+ }
+ return (void *) 0;
+}
+
+
+void *cftrec2_th(void *p)
+{
+ int cfttree(int n, int j, int k, double *a, int nw, double *w);
+ void cftleaf(int n, int isplt, double *a, int nw, double *w);
+ void cftmdl2(int n, double *a, double *w);
+ int isplt, j, k, m, n, n0, nw;
+ double *a, *w;
+
+ n0 = ((cdft_arg_t *) p)->n0;
+ n = ((cdft_arg_t *) p)->n;
+ a = ((cdft_arg_t *) p)->a;
+ nw = ((cdft_arg_t *) p)->nw;
+ w = ((cdft_arg_t *) p)->w;
+ k = 1;
+ m = n0;
+ while (m > 512) {
+ m >>= 2;
+ k <<= 2;
+ cftmdl2(m, &a[n - m], &w[nw - m]);
+ }
+ cftleaf(m, 0, &a[n - m], nw, w);
+ k >>= 1;
+ for (j = n - m; j > 0; j -= m) {
+ k++;
+ isplt = cfttree(m, j, k, a, nw, w);
+ cftleaf(m, isplt, &a[j - m], nw, w);
+ }
+ return (void *) 0;
+}
+#endif /* USE_CDFT_THREADS */
+
+
+void cftrec4(int n, double *a, int nw, double *w)
+{
+ int cfttree(int n, int j, int k, double *a, int nw, double *w);
+ void cftleaf(int n, int isplt, double *a, int nw, double *w);
+ void cftmdl1(int n, double *a, double *w);
+ int isplt, j, k, m;
+
+ m = n;
+ while (m > 512) {
+ m >>= 2;
+ cftmdl1(m, &a[n - m], &w[nw - (m >> 1)]);
+ }
+ cftleaf(m, 1, &a[n - m], nw, w);
+ k = 0;
+ for (j = n - m; j > 0; j -= m) {
+ k++;
+ isplt = cfttree(m, j, k, a, nw, w);
+ cftleaf(m, isplt, &a[j - m], nw, w);
+ }
+}
+
+
+int cfttree(int n, int j, int k, double *a, int nw, double *w)
+{
+ void cftmdl1(int n, double *a, double *w);
+ void cftmdl2(int n, double *a, double *w);
+ int i, isplt, m;
+
+ if ((k & 3) != 0) {
+ isplt = k & 1;
+ if (isplt != 0) {
+ cftmdl1(n, &a[j - n], &w[nw - (n >> 1)]);
+ } else {
+ cftmdl2(n, &a[j - n], &w[nw - n]);
+ }
+ } else {
+ m = n;
+ for (i = k; (i & 3) == 0; i >>= 2) {
+ m <<= 2;
+ }
+ isplt = i & 1;
+ if (isplt != 0) {
+ while (m > 128) {
+ cftmdl1(m, &a[j - m], &w[nw - (m >> 1)]);
+ m >>= 2;
+ }
+ } else {
+ while (m > 128) {
+ cftmdl2(m, &a[j - m], &w[nw - m]);
+ m >>= 2;
+ }
+ }
+ }
+ return isplt;
+}
+
+
+void cftleaf(int n, int isplt, double *a, int nw, double *w)
+{
+ void cftmdl1(int n, double *a, double *w);
+ void cftmdl2(int n, double *a, double *w);
+ void cftf161(double *a, double *w);
+ void cftf162(double *a, double *w);
+ void cftf081(double *a, double *w);
+ void cftf082(double *a, double *w);
+
+ if (n == 512) {
+ cftmdl1(128, a, &w[nw - 64]);
+ cftf161(a, &w[nw - 8]);
+ cftf162(&a[32], &w[nw - 32]);
+ cftf161(&a[64], &w[nw - 8]);
+ cftf161(&a[96], &w[nw - 8]);
+ cftmdl2(128, &a[128], &w[nw - 128]);
+ cftf161(&a[128], &w[nw - 8]);
+ cftf162(&a[160], &w[nw - 32]);
+ cftf161(&a[192], &w[nw - 8]);
+ cftf162(&a[224], &w[nw - 32]);
+ cftmdl1(128, &a[256], &w[nw - 64]);
+ cftf161(&a[256], &w[nw - 8]);
+ cftf162(&a[288], &w[nw - 32]);
+ cftf161(&a[320], &w[nw - 8]);
+ cftf161(&a[352], &w[nw - 8]);
+ if (isplt != 0) {
+ cftmdl1(128, &a[384], &w[nw - 64]);
+ cftf161(&a[480], &w[nw - 8]);
+ } else {
+ cftmdl2(128, &a[384], &w[nw - 128]);
+ cftf162(&a[480], &w[nw - 32]);
+ }
+ cftf161(&a[384], &w[nw - 8]);
+ cftf162(&a[416], &w[nw - 32]);
+ cftf161(&a[448], &w[nw - 8]);
+ } else {
+ cftmdl1(64, a, &w[nw - 32]);
+ cftf081(a, &w[nw - 8]);
+ cftf082(&a[16], &w[nw - 8]);
+ cftf081(&a[32], &w[nw - 8]);
+ cftf081(&a[48], &w[nw - 8]);
+ cftmdl2(64, &a[64], &w[nw - 64]);
+ cftf081(&a[64], &w[nw - 8]);
+ cftf082(&a[80], &w[nw - 8]);
+ cftf081(&a[96], &w[nw - 8]);
+ cftf082(&a[112], &w[nw - 8]);
+ cftmdl1(64, &a[128], &w[nw - 32]);
+ cftf081(&a[128], &w[nw - 8]);
+ cftf082(&a[144], &w[nw - 8]);
+ cftf081(&a[160], &w[nw - 8]);
+ cftf081(&a[176], &w[nw - 8]);
+ if (isplt != 0) {
+ cftmdl1(64, &a[192], &w[nw - 32]);
+ cftf081(&a[240], &w[nw - 8]);
+ } else {
+ cftmdl2(64, &a[192], &w[nw - 64]);
+ cftf082(&a[240], &w[nw - 8]);
+ }
+ cftf081(&a[192], &w[nw - 8]);
+ cftf082(&a[208], &w[nw - 8]);
+ cftf081(&a[224], &w[nw - 8]);
+ }
+}
+
+
+void cftmdl1(int n, double *a, double *w)
+{
+ int j, j0, j1, j2, j3, k, m, mh;
+ double wn4r, wk1r, wk1i, wk3r, wk3i;
+ double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;
+
+ mh = n >> 3;
+ m = 2 * mh;
+ j1 = m;
+ j2 = j1 + m;
+ j3 = j2 + m;
+ x0r = a[0] + a[j2];
+ x0i = a[1] + a[j2 + 1];
+ x1r = a[0] - a[j2];
+ x1i = a[1] - a[j2 + 1];
+ x2r = a[j1] + a[j3];
+ x2i = a[j1 + 1] + a[j3 + 1];
+ x3r = a[j1] - a[j3];
+ x3i = a[j1 + 1] - a[j3 + 1];
+ a[0] = x0r + x2r;
+ a[1] = x0i + x2i;
+ a[j1] = x0r - x2r;
+ a[j1 + 1] = x0i - x2i;
+ a[j2] = x1r - x3i;
+ a[j2 + 1] = x1i + x3r;
+ a[j3] = x1r + x3i;
+ a[j3 + 1] = x1i - x3r;
+ wn4r = w[1];
+ k = 0;
+ for (j = 2; j < mh; j += 2) {
+ k += 4;
+ wk1r = w[k];
+ wk1i = w[k + 1];
+ wk3r = w[k + 2];
+ wk3i = w[k + 3];
+ j1 = j + m;
+ j2 = j1 + m;
+ j3 = j2 + m;
+ x0r = a[j] + a[j2];
+ x0i = a[j + 1] + a[j2 + 1];
+ x1r = a[j] - a[j2];
+ x1i = a[j + 1] - a[j2 + 1];
+ x2r = a[j1] + a[j3];
+ x2i = a[j1 + 1] + a[j3 + 1];
+ x3r = a[j1] - a[j3];
+ x3i = a[j1 + 1] - a[j3 + 1];
+ a[j] = x0r + x2r;
+ a[j + 1] = x0i + x2i;
+ a[j1] = x0r - x2r;
+ a[j1 + 1] = x0i - x2i;
+ x0r = x1r - x3i;
+ x0i = x1i + x3r;
+ a[j2] = wk1r * x0r - wk1i * x0i;
+ a[j2 + 1] = wk1r * x0i + wk1i * x0r;
+ x0r = x1r + x3i;
+ x0i = x1i - x3r;
+ a[j3] = wk3r * x0r + wk3i * x0i;
+ a[j3 + 1] = wk3r * x0i - wk3i * x0r;
+ j0 = m - j;
+ j1 = j0 + m;
+ j2 = j1 + m;
+ j3 = j2 + m;
+ x0r = a[j0] + a[j2];
+ x0i = a[j0 + 1] + a[j2 + 1];
+ x1r = a[j0] - a[j2];
+ x1i = a[j0 + 1] - a[j2 + 1];
+ x2r = a[j1] + a[j3];
+ x2i = a[j1 + 1] + a[j3 + 1];
+ x3r = a[j1] - a[j3];
+ x3i = a[j1 + 1] - a[j3 + 1];
+ a[j0] = x0r + x2r;
+ a[j0 + 1] = x0i + x2i;
+ a[j1] = x0r - x2r;
+ a[j1 + 1] = x0i - x2i;
+ x0r = x1r - x3i;
+ x0i = x1i + x3r;
+ a[j2] = wk1i * x0r - wk1r * x0i;
+ a[j2 + 1] = wk1i * x0i + wk1r * x0r;
+ x0r = x1r + x3i;
+ x0i = x1i - x3r;
+ a[j3] = wk3i * x0r + wk3r * x0i;
+ a[j3 + 1] = wk3i * x0i - wk3r * x0r;
+ }
+ j0 = mh;
+ j1 = j0 + m;
+ j2 = j1 + m;
+ j3 = j2 + m;
+ x0r = a[j0] + a[j2];
+ x0i = a[j0 + 1] + a[j2 + 1];
+ x1r = a[j0] - a[j2];
+ x1i = a[j0 + 1] - a[j2 + 1];
+ x2r = a[j1] + a[j3];
+ x2i = a[j1 + 1] + a[j3 + 1];
+ x3r = a[j1] - a[j3];
+ x3i = a[j1 + 1] - a[j3 + 1];
+ a[j0] = x0r + x2r;
+ a[j0 + 1] = x0i + x2i;
+ a[j1] = x0r - x2r;
+ a[j1 + 1] = x0i - x2i;
+ x0r = x1r - x3i;
+ x0i = x1i + x3r;
+ a[j2] = wn4r * (x0r - x0i);
+ a[j2 + 1] = wn4r * (x0i + x0r);
+ x0r = x1r + x3i;
+ x0i = x1i - x3r;
+ a[j3] = -wn4r * (x0r + x0i);
+ a[j3 + 1] = -wn4r * (x0i - x0r);
+}
+
+
+void cftmdl2(int n, double *a, double *w)
+{
+ int j, j0, j1, j2, j3, k, kr, m, mh;
+ double wn4r, wk1r, wk1i, wk3r, wk3i, wd1r, wd1i, wd3r, wd3i;
+ double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i, y0r, y0i, y2r, y2i;
+
+ mh = n >> 3;
+ m = 2 * mh;
+ wn4r = w[1];
+ j1 = m;
+ j2 = j1 + m;
+ j3 = j2 + m;
+ x0r = a[0] - a[j2 + 1];
+ x0i = a[1] + a[j2];
+ x1r = a[0] + a[j2 + 1];
+ x1i = a[1] - a[j2];
+ x2r = a[j1] - a[j3 + 1];
+ x2i = a[j1 + 1] + a[j3];
+ x3r = a[j1] + a[j3 + 1];
+ x3i = a[j1 + 1] - a[j3];
+ y0r = wn4r * (x2r - x2i);
+ y0i = wn4r * (x2i + x2r);
+ a[0] = x0r + y0r;
+ a[1] = x0i + y0i;
+ a[j1] = x0r - y0r;
+ a[j1 + 1] = x0i - y0i;
+ y0r = wn4r * (x3r - x3i);
+ y0i = wn4r * (x3i + x3r);
+ a[j2] = x1r - y0i;
+ a[j2 + 1] = x1i + y0r;
+ a[j3] = x1r + y0i;
+ a[j3 + 1] = x1i - y0r;
+ k = 0;
+ kr = 2 * m;
+ for (j = 2; j < mh; j += 2) {
+ k += 4;
+ wk1r = w[k];
+ wk1i = w[k + 1];
+ wk3r = w[k + 2];
+ wk3i = w[k + 3];
+ kr -= 4;
+ wd1i = w[kr];
+ wd1r = w[kr + 1];
+ wd3i = w[kr + 2];
+ wd3r = w[kr + 3];
+ j1 = j + m;
+ j2 = j1 + m;
+ j3 = j2 + m;
+ x0r = a[j] - a[j2 + 1];
+ x0i = a[j + 1] + a[j2];
+ x1r = a[j] + a[j2 + 1];
+ x1i = a[j + 1] - a[j2];
+ x2r = a[j1] - a[j3 + 1];
+ x2i = a[j1 + 1] + a[j3];
+ x3r = a[j1] + a[j3 + 1];
+ x3i = a[j1 + 1] - a[j3];
+ y0r = wk1r * x0r - wk1i * x0i;
+ y0i = wk1r * x0i + wk1i * x0r;
+ y2r = wd1r * x2r - wd1i * x2i;
+ y2i = wd1r * x2i + wd1i * x2r;
+ a[j] = y0r + y2r;
+ a[j + 1] = y0i + y2i;
+ a[j1] = y0r - y2r;
+ a[j1 + 1] = y0i - y2i;
+ y0r = wk3r * x1r + wk3i * x1i;
+ y0i = wk3r * x1i - wk3i * x1r;
+ y2r = wd3r * x3r + wd3i * x3i;
+ y2i = wd3r * x3i - wd3i * x3r;
+ a[j2] = y0r + y2r;
+ a[j2 + 1] = y0i + y2i;
+ a[j3] = y0r - y2r;
+ a[j3 + 1] = y0i - y2i;
+ j0 = m - j;
+ j1 = j0 + m;
+ j2 = j1 + m;
+ j3 = j2 + m;
+ x0r = a[j0] - a[j2 + 1];
+ x0i = a[j0 + 1] + a[j2];
+ x1r = a[j0] + a[j2 + 1];
+ x1i = a[j0 + 1] - a[j2];
+ x2r = a[j1] - a[j3 + 1];
+ x2i = a[j1 + 1] + a[j3];
+ x3r = a[j1] + a[j3 + 1];
+ x3i = a[j1 + 1] - a[j3];
+ y0r = wd1i * x0r - wd1r * x0i;
+ y0i = wd1i * x0i + wd1r * x0r;
+ y2r = wk1i * x2r - wk1r * x2i;
+ y2i = wk1i * x2i + wk1r * x2r;
+ a[j0] = y0r + y2r;
+ a[j0 + 1] = y0i + y2i;
+ a[j1] = y0r - y2r;
+ a[j1 + 1] = y0i - y2i;
+ y0r = wd3i * x1r + wd3r * x1i;
+ y0i = wd3i * x1i - wd3r * x1r;
+ y2r = wk3i * x3r + wk3r * x3i;
+ y2i = wk3i * x3i - wk3r * x3r;
+ a[j2] = y0r + y2r;
+ a[j2 + 1] = y0i + y2i;
+ a[j3] = y0r - y2r;
+ a[j3 + 1] = y0i - y2i;
+ }
+ wk1r = w[m];
+ wk1i = w[m + 1];
+ j0 = mh;
+ j1 = j0 + m;
+ j2 = j1 + m;
+ j3 = j2 + m;
+ x0r = a[j0] - a[j2 + 1];
+ x0i = a[j0 + 1] + a[j2];
+ x1r = a[j0] + a[j2 + 1];
+ x1i = a[j0 + 1] - a[j2];
+ x2r = a[j1] - a[j3 + 1];
+ x2i = a[j1 + 1] + a[j3];
+ x3r = a[j1] + a[j3 + 1];
+ x3i = a[j1 + 1] - a[j3];
+ y0r = wk1r * x0r - wk1i * x0i;
+ y0i = wk1r * x0i + wk1i * x0r;
+ y2r = wk1i * x2r - wk1r * x2i;
+ y2i = wk1i * x2i + wk1r * x2r;
+ a[j0] = y0r + y2r;
+ a[j0 + 1] = y0i + y2i;
+ a[j1] = y0r - y2r;
+ a[j1 + 1] = y0i - y2i;
+ y0r = wk1i * x1r - wk1r * x1i;
+ y0i = wk1i * x1i + wk1r * x1r;
+ y2r = wk1r * x3r - wk1i * x3i;
+ y2i = wk1r * x3i + wk1i * x3r;
+ a[j2] = y0r - y2r;
+ a[j2 + 1] = y0i - y2i;
+ a[j3] = y0r + y2r;
+ a[j3 + 1] = y0i + y2i;
+}
+
+
+void cftfx41(int n, double *a, int nw, double *w)
+{
+ void cftf161(double *a, double *w);
+ void cftf162(double *a, double *w);
+ void cftf081(double *a, double *w);
+ void cftf082(double *a, double *w);
+
+ if (n == 128) {
+ cftf161(a, &w[nw - 8]);
+ cftf162(&a[32], &w[nw - 32]);
+ cftf161(&a[64], &w[nw - 8]);
+ cftf161(&a[96], &w[nw - 8]);
+ } else {
+ cftf081(a, &w[nw - 8]);
+ cftf082(&a[16], &w[nw - 8]);
+ cftf081(&a[32], &w[nw - 8]);
+ cftf081(&a[48], &w[nw - 8]);
+ }
+}
+
+
+void cftf161(double *a, double *w)
+{
+ double wn4r, wk1r, wk1i,
+ x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i,
+ y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i,
+ y4r, y4i, y5r, y5i, y6r, y6i, y7r, y7i,
+ y8r, y8i, y9r, y9i, y10r, y10i, y11r, y11i,
+ y12r, y12i, y13r, y13i, y14r, y14i, y15r, y15i;
+
+ wn4r = w[1];
+ wk1r = w[2];
+ wk1i = w[3];
+ x0r = a[0] + a[16];
+ x0i = a[1] + a[17];
+ x1r = a[0] - a[16];
+ x1i = a[1] - a[17];
+ x2r = a[8] + a[24];
+ x2i = a[9] + a[25];
+ x3r = a[8] - a[24];
+ x3i = a[9] - a[25];
+ y0r = x0r + x2r;
+ y0i = x0i + x2i;
+ y4r = x0r - x2r;
+ y4i = x0i - x2i;
+ y8r = x1r - x3i;
+ y8i = x1i + x3r;
+ y12r = x1r + x3i;
+ y12i = x1i - x3r;
+ x0r = a[2] + a[18];
+ x0i = a[3] + a[19];
+ x1r = a[2] - a[18];
+ x1i = a[3] - a[19];
+ x2r = a[10] + a[26];
+ x2i = a[11] + a[27];
+ x3r = a[10] - a[26];
+ x3i = a[11] - a[27];
+ y1r = x0r + x2r;
+ y1i = x0i + x2i;
+ y5r = x0r - x2r;
+ y5i = x0i - x2i;
+ x0r = x1r - x3i;
+ x0i = x1i + x3r;
+ y9r = wk1r * x0r - wk1i * x0i;
+ y9i = wk1r * x0i + wk1i * x0r;
+ x0r = x1r + x3i;
+ x0i = x1i - x3r;
+ y13r = wk1i * x0r - wk1r * x0i;
+ y13i = wk1i * x0i + wk1r * x0r;
+ x0r = a[4] + a[20];
+ x0i = a[5] + a[21];
+ x1r = a[4] - a[20];
+ x1i = a[5] - a[21];
+ x2r = a[12] + a[28];
+ x2i = a[13] + a[29];
+ x3r = a[12] - a[28];
+ x3i = a[13] - a[29];
+ y2r = x0r + x2r;
+ y2i = x0i + x2i;
+ y6r = x0r - x2r;
+ y6i = x0i - x2i;
+ x0r = x1r - x3i;
+ x0i = x1i + x3r;
+ y10r = wn4r * (x0r - x0i);
+ y10i = wn4r * (x0i + x0r);
+ x0r = x1r + x3i;
+ x0i = x1i - x3r;
+ y14r = wn4r * (x0r + x0i);
+ y14i = wn4r * (x0i - x0r);
+ x0r = a[6] + a[22];
+ x0i = a[7] + a[23];
+ x1r = a[6] - a[22];
+ x1i = a[7] - a[23];
+ x2r = a[14] + a[30];
+ x2i = a[15] + a[31];
+ x3r = a[14] - a[30];
+ x3i = a[15] - a[31];
+ y3r = x0r + x2r;
+ y3i = x0i + x2i;
+ y7r = x0r - x2r;
+ y7i = x0i - x2i;
+ x0r = x1r - x3i;
+ x0i = x1i + x3r;
+ y11r = wk1i * x0r - wk1r * x0i;
+ y11i = wk1i * x0i + wk1r * x0r;
+ x0r = x1r + x3i;
+ x0i = x1i - x3r;
+ y15r = wk1r * x0r - wk1i * x0i;
+ y15i = wk1r * x0i + wk1i * x0r;
+ x0r = y12r - y14r;
+ x0i = y12i - y14i;
+ x1r = y12r + y14r;
+ x1i = y12i + y14i;
+ x2r = y13r - y15r;
+ x2i = y13i - y15i;
+ x3r = y13r + y15r;
+ x3i = y13i + y15i;
+ a[24] = x0r + x2r;
+ a[25] = x0i + x2i;
+ a[26] = x0r - x2r;
+ a[27] = x0i - x2i;
+ a[28] = x1r - x3i;
+ a[29] = x1i + x3r;
+ a[30] = x1r + x3i;
+ a[31] = x1i - x3r;
+ x0r = y8r + y10r;
+ x0i = y8i + y10i;
+ x1r = y8r - y10r;
+ x1i = y8i - y10i;
+ x2r = y9r + y11r;
+ x2i = y9i + y11i;
+ x3r = y9r - y11r;
+ x3i = y9i - y11i;
+ a[16] = x0r + x2r;
+ a[17] = x0i + x2i;
+ a[18] = x0r - x2r;
+ a[19] = x0i - x2i;
+ a[20] = x1r - x3i;
+ a[21] = x1i + x3r;
+ a[22] = x1r + x3i;
+ a[23] = x1i - x3r;
+ x0r = y5r - y7i;
+ x0i = y5i + y7r;
+ x2r = wn4r * (x0r - x0i);
+ x2i = wn4r * (x0i + x0r);
+ x0r = y5r + y7i;
+ x0i = y5i - y7r;
+ x3r = wn4r * (x0r - x0i);
+ x3i = wn4r * (x0i + x0r);
+ x0r = y4r - y6i;
+ x0i = y4i + y6r;
+ x1r = y4r + y6i;
+ x1i = y4i - y6r;
+ a[8] = x0r + x2r;
+ a[9] = x0i + x2i;
+ a[10] = x0r - x2r;
+ a[11] = x0i - x2i;
+ a[12] = x1r - x3i;
+ a[13] = x1i + x3r;
+ a[14] = x1r + x3i;
+ a[15] = x1i - x3r;
+ x0r = y0r + y2r;
+ x0i = y0i + y2i;
+ x1r = y0r - y2r;
+ x1i = y0i - y2i;
+ x2r = y1r + y3r;
+ x2i = y1i + y3i;
+ x3r = y1r - y3r;
+ x3i = y1i - y3i;
+ a[0] = x0r + x2r;
+ a[1] = x0i + x2i;
+ a[2] = x0r - x2r;
+ a[3] = x0i - x2i;
+ a[4] = x1r - x3i;
+ a[5] = x1i + x3r;
+ a[6] = x1r + x3i;
+ a[7] = x1i - x3r;
+}
+
+
+void cftf162(double *a, double *w)
+{
+ double wn4r, wk1r, wk1i, wk2r, wk2i, wk3r, wk3i,
+ x0r, x0i, x1r, x1i, x2r, x2i,
+ y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i,
+ y4r, y4i, y5r, y5i, y6r, y6i, y7r, y7i,
+ y8r, y8i, y9r, y9i, y10r, y10i, y11r, y11i,
+ y12r, y12i, y13r, y13i, y14r, y14i, y15r, y15i;
+
+ wn4r = w[1];
+ wk1r = w[4];
+ wk1i = w[5];
+ wk3r = w[6];
+ wk3i = -w[7];
+ wk2r = w[8];
+ wk2i = w[9];
+ x1r = a[0] - a[17];
+ x1i = a[1] + a[16];
+ x0r = a[8] - a[25];
+ x0i = a[9] + a[24];
+ x2r = wn4r * (x0r - x0i);
+ x2i = wn4r * (x0i + x0r);
+ y0r = x1r + x2r;
+ y0i = x1i + x2i;
+ y4r = x1r - x2r;
+ y4i = x1i - x2i;
+ x1r = a[0] + a[17];
+ x1i = a[1] - a[16];
+ x0r = a[8] + a[25];
+ x0i = a[9] - a[24];
+ x2r = wn4r * (x0r - x0i);
+ x2i = wn4r * (x0i + x0r);
+ y8r = x1r - x2i;
+ y8i = x1i + x2r;
+ y12r = x1r + x2i;
+ y12i = x1i - x2r;
+ x0r = a[2] - a[19];
+ x0i = a[3] + a[18];
+ x1r = wk1r * x0r - wk1i * x0i;
+ x1i = wk1r * x0i + wk1i * x0r;
+ x0r = a[10] - a[27];
+ x0i = a[11] + a[26];
+ x2r = wk3i * x0r - wk3r * x0i;
+ x2i = wk3i * x0i + wk3r * x0r;
+ y1r = x1r + x2r;
+ y1i = x1i + x2i;
+ y5r = x1r - x2r;
+ y5i = x1i - x2i;
+ x0r = a[2] + a[19];
+ x0i = a[3] - a[18];
+ x1r = wk3r * x0r - wk3i * x0i;
+ x1i = wk3r * x0i + wk3i * x0r;
+ x0r = a[10] + a[27];
+ x0i = a[11] - a[26];
+ x2r = wk1r * x0r + wk1i * x0i;
+ x2i = wk1r * x0i - wk1i * x0r;
+ y9r = x1r - x2r;
+ y9i = x1i - x2i;
+ y13r = x1r + x2r;
+ y13i = x1i + x2i;
+ x0r = a[4] - a[21];
+ x0i = a[5] + a[20];
+ x1r = wk2r * x0r - wk2i * x0i;
+ x1i = wk2r * x0i + wk2i * x0r;
+ x0r = a[12] - a[29];
+ x0i = a[13] + a[28];
+ x2r = wk2i * x0r - wk2r * x0i;
+ x2i = wk2i * x0i + wk2r * x0r;
+ y2r = x1r + x2r;
+ y2i = x1i + x2i;
+ y6r = x1r - x2r;
+ y6i = x1i - x2i;
+ x0r = a[4] + a[21];
+ x0i = a[5] - a[20];
+ x1r = wk2i * x0r - wk2r * x0i;
+ x1i = wk2i * x0i + wk2r * x0r;
+ x0r = a[12] + a[29];
+ x0i = a[13] - a[28];
+ x2r = wk2r * x0r - wk2i * x0i;
+ x2i = wk2r * x0i + wk2i * x0r;
+ y10r = x1r - x2r;
+ y10i = x1i - x2i;
+ y14r = x1r + x2r;
+ y14i = x1i + x2i;
+ x0r = a[6] - a[23];
+ x0i = a[7] + a[22];
+ x1r = wk3r * x0r - wk3i * x0i;
+ x1i = wk3r * x0i + wk3i * x0r;
+ x0r = a[14] - a[31];
+ x0i = a[15] + a[30];
+ x2r = wk1i * x0r - wk1r * x0i;
+ x2i = wk1i * x0i + wk1r * x0r;
+ y3r = x1r + x2r;
+ y3i = x1i + x2i;
+ y7r = x1r - x2r;
+ y7i = x1i - x2i;
+ x0r = a[6] + a[23];
+ x0i = a[7] - a[22];
+ x1r = wk1i * x0r + wk1r * x0i;
+ x1i = wk1i * x0i - wk1r * x0r;
+ x0r = a[14] + a[31];
+ x0i = a[15] - a[30];
+ x2r = wk3i * x0r - wk3r * x0i;
+ x2i = wk3i * x0i + wk3r * x0r;
+ y11r = x1r + x2r;
+ y11i = x1i + x2i;
+ y15r = x1r - x2r;
+ y15i = x1i - x2i;
+ x1r = y0r + y2r;
+ x1i = y0i + y2i;
+ x2r = y1r + y3r;
+ x2i = y1i + y3i;
+ a[0] = x1r + x2r;
+ a[1] = x1i + x2i;
+ a[2] = x1r - x2r;
+ a[3] = x1i - x2i;
+ x1r = y0r - y2r;
+ x1i = y0i - y2i;
+ x2r = y1r - y3r;
+ x2i = y1i - y3i;
+ a[4] = x1r - x2i;
+ a[5] = x1i + x2r;
+ a[6] = x1r + x2i;
+ a[7] = x1i - x2r;
+ x1r = y4r - y6i;
+ x1i = y4i + y6r;
+ x0r = y5r - y7i;
+ x0i = y5i + y7r;
+ x2r = wn4r * (x0r - x0i);
+ x2i = wn4r * (x0i + x0r);
+ a[8] = x1r + x2r;
+ a[9] = x1i + x2i;
+ a[10] = x1r - x2r;
+ a[11] = x1i - x2i;
+ x1r = y4r + y6i;
+ x1i = y4i - y6r;
+ x0r = y5r + y7i;
+ x0i = y5i - y7r;
+ x2r = wn4r * (x0r - x0i);
+ x2i = wn4r * (x0i + x0r);
+ a[12] = x1r - x2i;
+ a[13] = x1i + x2r;
+ a[14] = x1r + x2i;
+ a[15] = x1i - x2r;
+ x1r = y8r + y10r;
+ x1i = y8i + y10i;
+ x2r = y9r - y11r;
+ x2i = y9i - y11i;
+ a[16] = x1r + x2r;
+ a[17] = x1i + x2i;
+ a[18] = x1r - x2r;
+ a[19] = x1i - x2i;
+ x1r = y8r - y10r;
+ x1i = y8i - y10i;
+ x2r = y9r + y11r;
+ x2i = y9i + y11i;
+ a[20] = x1r - x2i;
+ a[21] = x1i + x2r;
+ a[22] = x1r + x2i;
+ a[23] = x1i - x2r;
+ x1r = y12r - y14i;
+ x1i = y12i + y14r;
+ x0r = y13r + y15i;
+ x0i = y13i - y15r;
+ x2r = wn4r * (x0r - x0i);
+ x2i = wn4r * (x0i + x0r);
+ a[24] = x1r + x2r;
+ a[25] = x1i + x2i;
+ a[26] = x1r - x2r;
+ a[27] = x1i - x2i;
+ x1r = y12r + y14i;
+ x1i = y12i - y14r;
+ x0r = y13r - y15i;
+ x0i = y13i + y15r;
+ x2r = wn4r * (x0r - x0i);
+ x2i = wn4r * (x0i + x0r);
+ a[28] = x1r - x2i;
+ a[29] = x1i + x2r;
+ a[30] = x1r + x2i;
+ a[31] = x1i - x2r;
+}
+
+
+void cftf081(double *a, double *w)
+{
+ double wn4r, x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i,
+ y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i,
+ y4r, y4i, y5r, y5i, y6r, y6i, y7r, y7i;
+
+ wn4r = w[1];
+ x0r = a[0] + a[8];
+ x0i = a[1] + a[9];
+ x1r = a[0] - a[8];
+ x1i = a[1] - a[9];
+ x2r = a[4] + a[12];
+ x2i = a[5] + a[13];
+ x3r = a[4] - a[12];
+ x3i = a[5] - a[13];
+ y0r = x0r + x2r;
+ y0i = x0i + x2i;
+ y2r = x0r - x2r;
+ y2i = x0i - x2i;
+ y1r = x1r - x3i;
+ y1i = x1i + x3r;
+ y3r = x1r + x3i;
+ y3i = x1i - x3r;
+ x0r = a[2] + a[10];
+ x0i = a[3] + a[11];
+ x1r = a[2] - a[10];
+ x1i = a[3] - a[11];
+ x2r = a[6] + a[14];
+ x2i = a[7] + a[15];
+ x3r = a[6] - a[14];
+ x3i = a[7] - a[15];
+ y4r = x0r + x2r;
+ y4i = x0i + x2i;
+ y6r = x0r - x2r;
+ y6i = x0i - x2i;
+ x0r = x1r - x3i;
+ x0i = x1i + x3r;
+ x2r = x1r + x3i;
+ x2i = x1i - x3r;
+ y5r = wn4r * (x0r - x0i);
+ y5i = wn4r * (x0r + x0i);
+ y7r = wn4r * (x2r - x2i);
+ y7i = wn4r * (x2r + x2i);
+ a[8] = y1r + y5r;
+ a[9] = y1i + y5i;
+ a[10] = y1r - y5r;
+ a[11] = y1i - y5i;
+ a[12] = y3r - y7i;
+ a[13] = y3i + y7r;
+ a[14] = y3r + y7i;
+ a[15] = y3i - y7r;
+ a[0] = y0r + y4r;
+ a[1] = y0i + y4i;
+ a[2] = y0r - y4r;
+ a[3] = y0i - y4i;
+ a[4] = y2r - y6i;
+ a[5] = y2i + y6r;
+ a[6] = y2r + y6i;
+ a[7] = y2i - y6r;
+}
+
+
+void cftf082(double *a, double *w)
+{
+ double wn4r, wk1r, wk1i, x0r, x0i, x1r, x1i,
+ y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i,
+ y4r, y4i, y5r, y5i, y6r, y6i, y7r, y7i;
+
+ wn4r = w[1];
+ wk1r = w[2];
+ wk1i = w[3];
+ y0r = a[0] - a[9];
+ y0i = a[1] + a[8];
+ y1r = a[0] + a[9];
+ y1i = a[1] - a[8];
+ x0r = a[4] - a[13];
+ x0i = a[5] + a[12];
+ y2r = wn4r * (x0r - x0i);
+ y2i = wn4r * (x0i + x0r);
+ x0r = a[4] + a[13];
+ x0i = a[5] - a[12];
+ y3r = wn4r * (x0r - x0i);
+ y3i = wn4r * (x0i + x0r);
+ x0r = a[2] - a[11];
+ x0i = a[3] + a[10];
+ y4r = wk1r * x0r - wk1i * x0i;
+ y4i = wk1r * x0i + wk1i * x0r;
+ x0r = a[2] + a[11];
+ x0i = a[3] - a[10];
+ y5r = wk1i * x0r - wk1r * x0i;
+ y5i = wk1i * x0i + wk1r * x0r;
+ x0r = a[6] - a[15];
+ x0i = a[7] + a[14];
+ y6r = wk1i * x0r - wk1r * x0i;
+ y6i = wk1i * x0i + wk1r * x0r;
+ x0r = a[6] + a[15];
+ x0i = a[7] - a[14];
+ y7r = wk1r * x0r - wk1i * x0i;
+ y7i = wk1r * x0i + wk1i * x0r;
+ x0r = y0r + y2r;
+ x0i = y0i + y2i;
+ x1r = y4r + y6r;
+ x1i = y4i + y6i;
+ a[0] = x0r + x1r;
+ a[1] = x0i + x1i;
+ a[2] = x0r - x1r;
+ a[3] = x0i - x1i;
+ x0r = y0r - y2r;
+ x0i = y0i - y2i;
+ x1r = y4r - y6r;
+ x1i = y4i - y6i;
+ a[4] = x0r - x1i;
+ a[5] = x0i + x1r;
+ a[6] = x0r + x1i;
+ a[7] = x0i - x1r;
+ x0r = y1r - y3i;
+ x0i = y1i + y3r;
+ x1r = y5r - y7r;
+ x1i = y5i - y7i;
+ a[8] = x0r + x1r;
+ a[9] = x0i + x1i;
+ a[10] = x0r - x1r;
+ a[11] = x0i - x1i;
+ x0r = y1r + y3i;
+ x0i = y1i - y3r;
+ x1r = y5r + y7r;
+ x1i = y5i + y7i;
+ a[12] = x0r - x1i;
+ a[13] = x0i + x1r;
+ a[14] = x0r + x1i;
+ a[15] = x0i - x1r;
+}
+
+
+void cftf040(double *a)
+{
+ double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;
+
+ x0r = a[0] + a[4];
+ x0i = a[1] + a[5];
+ x1r = a[0] - a[4];
+ x1i = a[1] - a[5];
+ x2r = a[2] + a[6];
+ x2i = a[3] + a[7];
+ x3r = a[2] - a[6];
+ x3i = a[3] - a[7];
+ a[0] = x0r + x2r;
+ a[1] = x0i + x2i;
+ a[2] = x1r - x3i;
+ a[3] = x1i + x3r;
+ a[4] = x0r - x2r;
+ a[5] = x0i - x2i;
+ a[6] = x1r + x3i;
+ a[7] = x1i - x3r;
+}
+
+
+void cftb040(double *a)
+{
+ double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;
+
+ x0r = a[0] + a[4];
+ x0i = a[1] + a[5];
+ x1r = a[0] - a[4];
+ x1i = a[1] - a[5];
+ x2r = a[2] + a[6];
+ x2i = a[3] + a[7];
+ x3r = a[2] - a[6];
+ x3i = a[3] - a[7];
+ a[0] = x0r + x2r;
+ a[1] = x0i + x2i;
+ a[2] = x1r + x3i;
+ a[3] = x1i - x3r;
+ a[4] = x0r - x2r;
+ a[5] = x0i - x2i;
+ a[6] = x1r - x3i;
+ a[7] = x1i + x3r;
+}
+
+
+void cftx020(double *a)
+{
+ double x0r, x0i;
+
+ x0r = a[0] - a[2];
+ x0i = a[1] - a[3];
+ a[0] += a[2];
+ a[1] += a[3];
+ a[2] = x0r;
+ a[3] = x0i;
+}
+
+
+void rftfsub(int n, double *a, int nc, double *c)
+{
+ int j, k, kk, ks, m;
+ double wkr, wki, xr, xi, yr, yi;
+
+ m = n >> 1;
+ ks = 2 * nc / m;
+ kk = 0;
+ for (j = 2; j < m; j += 2) {
+ k = n - j;
+ kk += ks;
+ wkr = 0.5 - c[nc - kk];
+ wki = c[kk];
+ xr = a[j] - a[k];
+ xi = a[j + 1] + a[k + 1];
+ yr = wkr * xr - wki * xi;
+ yi = wkr * xi + wki * xr;
+ a[j] -= yr;
+ a[j + 1] -= yi;
+ a[k] += yr;
+ a[k + 1] -= yi;
+ }
+}
+
+
+void rftbsub(int n, double *a, int nc, double *c)
+{
+ int j, k, kk, ks, m;
+ double wkr, wki, xr, xi, yr, yi;
+
+ m = n >> 1;
+ ks = 2 * nc / m;
+ kk = 0;
+ for (j = 2; j < m; j += 2) {
+ k = n - j;
+ kk += ks;
+ wkr = 0.5 - c[nc - kk];
+ wki = c[kk];
+ xr = a[j] - a[k];
+ xi = a[j + 1] + a[k + 1];
+ yr = wkr * xr + wki * xi;
+ yi = wkr * xi - wki * xr;
+ a[j] -= yr;
+ a[j + 1] -= yi;
+ a[k] += yr;
+ a[k + 1] -= yi;
+ }
+}
+
+
+void dctsub(int n, double *a, int nc, double *c)
+{
+ int j, k, kk, ks, m;
+ double wkr, wki, xr;
+
+ m = n >> 1;
+ ks = nc / n;
+ kk = 0;
+ for (j = 1; j < m; j++) {
+ k = n - j;
+ kk += ks;
+ wkr = c[kk] - c[nc - kk];
+ wki = c[kk] + c[nc - kk];
+ xr = wki * a[j] - wkr * a[k];
+ a[j] = wkr * a[j] + wki * a[k];
+ a[k] = xr;
+ }
+ a[m] *= c[0];
+}
+
+
+void dstsub(int n, double *a, int nc, double *c)
+{
+ int j, k, kk, ks, m;
+ double wkr, wki, xr;
+
+ m = n >> 1;
+ ks = nc / n;
+ kk = 0;
+ for (j = 1; j < m; j++) {
+ k = n - j;
+ kk += ks;
+ wkr = c[kk] - c[nc - kk];
+ wki = c[kk] + c[nc - kk];
+ xr = wki * a[k] - wkr * a[j];
+ a[k] = wkr * a[k] + wki * a[j];
+ a[j] = xr;
+ }
+ a[m] *= c[0];
+}
+
diff --git a/plugins/supereq/nsfft-1.00/ooura/pi_fft.c b/plugins/supereq/nsfft-1.00/ooura/pi_fft.c
new file mode 100644
index 00000000..c9a76bf8
--- /dev/null
+++ b/plugins/supereq/nsfft-1.00/ooura/pi_fft.c
@@ -0,0 +1,1616 @@
+/*
+---- calculation of PI(= 3.14159...) using FFT ----
+ by T.Ooura, ver. LG1.1.2-MP1.5a Sep. 2001.
+
+This is a test program to estimate the performance of
+the FFT routines: fft*g.c.
+
+Example compilation:
+ GNU : gcc -O6 -ffast-math pi_fft.c fftsg.c -lm -o pi_fftsg
+ SUN : cc -fast -xO5 pi_fft.c fft8g.c -lm -o pi_fft8g
+ Microsoft: cl /O2 /G6 pi_fft.c fft4g.c /Fepi_fft4g.exe
+ ...
+ etc.
+*/
+
+/* Please check the following macros before compiling */
+#ifndef DBL_ERROR_MARGIN
+#define DBL_ERROR_MARGIN 0.3 /* must be < 0.5 */
+#endif
+
+
+#include <math.h>
+#include <limits.h>
+#include <float.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+
+
+void mp_load_0(int n, int radix, int out[]);
+void mp_load_1(int n, int radix, int out[]);
+void mp_copy(int n, int radix, int in[], int out[]);
+void mp_round(int n, int radix, int m, int inout[]);
+int mp_cmp(int n, int radix, int in1[], int in2[]);
+void mp_add(int n, int radix, int in1[], int in2[], int out[]);
+void mp_sub(int n, int radix, int in1[], int in2[], int out[]);
+void mp_imul(int n, int radix, int in1[], int in2, int out[]);
+int mp_idiv(int n, int radix, int in1[], int in2, int out[]);
+void mp_idiv_2(int n, int radix, int in[], int out[]);
+double mp_mul_radix_test(int n, int radix, int nfft,
+ double tmpfft[], int ip[], double w[]);
+void mp_mul(int n, int radix, int in1[], int in2[], int out[],
+ int tmp[], int nfft, double tmp1fft[], double tmp2fft[],
+ double tmp3fft[], int ip[], double w[]);
+void mp_squ(int n, int radix, int in[], int out[], int tmp[],
+ int nfft, double tmp1fft[], double tmp2fft[],
+ int ip[], double w[]);
+void mp_mulh(int n, int radix, int in1[], int in2[], int out[],
+ int nfft, double in1fft[], double outfft[],
+ int ip[], double w[]);
+void mp_squh(int n, int radix, int in[], int out[],
+ int nfft, double inoutfft[], int ip[], double w[]);
+int mp_inv(int n, int radix, int in[], int out[],
+ int tmp1[], int tmp2[], int nfft,
+ double tmp1fft[], double tmp2fft[], int ip[], double w[]);
+int mp_sqrt(int n, int radix, int in[], int out[],
+ int tmp1[], int tmp2[], int nfft,
+ double tmp1fft[], double tmp2fft[], int ip[], double w[]);
+void mp_sprintf(int n, int log10_radix, int in[], char out[]);
+void mp_sscanf(int n, int log10_radix, char in[], int out[]);
+void mp_fprintf(int n, int log10_radix, int in[], FILE *fout);
+
+
+int main()
+{
+ int nfft, log2_nfft, radix, log10_radix, n, npow, nprc;
+ double err, d_time, n_op;
+ int *a, *b, *c, *e, *i1, *i2, *ip;
+ double *d1, *d2, *d3, *w;
+ time_t t_1, t_2;
+ FILE *f_log, *f_out;
+
+ f_log = fopen("pi.log", "w");
+ printf("PI calculation to estimate the FFT benchmarks\n");
+ fprintf(f_log, "PI calculation to estimate the FFT benchmarks\n");
+ printf("length of FFT =?\n");
+ scanf("%d", &nfft);
+
+ printf("initializing...\n");
+ for (log2_nfft = 1; (1 << log2_nfft) < nfft; log2_nfft++);
+ nfft = 1 << log2_nfft;
+ n = nfft + 2;
+ ip = (int *) malloc((3 + (int) sqrt(0.5 * nfft)) * sizeof(int));
+ w = (double *) malloc(nfft / 2 * sizeof(double));
+ a = (int *) malloc((n + 2) * sizeof(int));
+ b = (int *) malloc((n + 2) * sizeof(int));
+ c = (int *) malloc((n + 2) * sizeof(int));
+ e = (int *) malloc((n + 2) * sizeof(int));
+ i1 = (int *) malloc((n + 2) * sizeof(int));
+ i2 = (int *) malloc((n + 2) * sizeof(int));
+ d1 = (double *) malloc((nfft + 2) * sizeof(double));
+ d2 = (double *) malloc((nfft + 2) * sizeof(double));
+ d3 = (double *) malloc((nfft + 2) * sizeof(double));
+ if (d3 == NULL) {
+ printf("Allocation Failure!\n");
+ exit(1);
+ }
+ ip[0] = 0;
+ /* ---- radix test ---- */
+ log10_radix = 1;
+ radix = 10;
+ err = mp_mul_radix_test(n, radix, nfft, d1, ip, w);
+ err += DBL_EPSILON * (n * radix * radix / 4);
+ while (100 * err < DBL_ERROR_MARGIN && radix <= INT_MAX / 20) {
+ err *= 100;
+ log10_radix++;
+ radix *= 10;
+ }
+ printf("nfft= %d\nradix= %d\nerror_margin= %g\n", nfft, radix, err);
+ fprintf(f_log, "nfft= %d\nradix= %d\nerror_margin= %g\n", nfft, radix, err);
+ printf("calculating %d digits of PI...\n", log10_radix * (n - 2));
+ fprintf(f_log, "calculating %d digits of PI...\n", log10_radix * (n - 2));
+ /* ---- time check ---- */
+ time(&t_1);
+ /*
+ * ---- a formula based on the AGM (Arithmetic-Geometric Mean) ----
+ * c = sqrt(0.125);
+ * a = 1 + 3 * c;
+ * b = sqrt(a);
+ * e = b - 0.625;
+ * b = 2 * b;
+ * c = e - c;
+ * a = a + e;
+ * npow = 4;
+ * do {
+ * npow = 2 * npow;
+ * e = (a + b) / 2;
+ * b = sqrt(a * b);
+ * e = e - b;
+ * b = 2 * b;
+ * c = c - e;
+ * a = e + b;
+ * } while (e > SQRT_SQRT_EPSILON);
+ * e = e * e / 4;
+ * a = a + b;
+ * pi = (a * a - e - e / 2) / (a * c - e) / npow;
+ * ---- modification ----
+ * This is a modified version of Gauss-Legendre formula
+ * (by T.Ooura). It is faster than original version.
+ * ---- reference ----
+ * 1. E.Salamin,
+ * Computation of PI Using Arithmetic-Geometric Mean,
+ * Mathematics of Computation, Vol.30 1976.
+ * 2. R.P.Brent,
+ * Fast Multiple-Precision Evaluation of Elementary Functions,
+ * J. ACM 23 1976.
+ * 3. D.Takahasi, Y.Kanada,
+ * Calculation of PI to 51.5 Billion Decimal Digits on
+ * Distributed Memoriy Parallel Processors,
+ * Transactions of Information Processing Society of Japan,
+ * Vol.39 No.7 1998.
+ * 4. T.Ooura,
+ * Improvement of the PI Calculation Algorithm and
+ * Implementation of Fast Multiple-Precision Computation,
+ * Information Processing Society of Japan SIG Notes,
+ * 98-HPC-74, 1998.
+ */
+ /* ---- c = sqrt(0.125) ---- */
+ mp_sscanf(n, log10_radix, "0.125", a);
+ mp_sqrt(n, radix, a, c, i1, i2, nfft, d1, d2, ip, w);
+ /* ---- a = 1 + 3 * c ---- */
+ mp_imul(n, radix, c, 3, e);
+ mp_sscanf(n, log10_radix, "1", a);
+ mp_add(n, radix, a, e, a);
+ /* ---- b = sqrt(a) ---- */
+ mp_sqrt(n, radix, a, b, i1, i2, nfft, d1, d2, ip, w);
+ /* ---- e = b - 0.625 ---- */
+ mp_sscanf(n, log10_radix, "0.625", e);
+ mp_sub(n, radix, b, e, e);
+ /* ---- b = 2 * b ---- */
+ mp_add(n, radix, b, b, b);
+ /* ---- c = e - c ---- */
+ mp_sub(n, radix, e, c, c);
+ /* ---- a = a + e ---- */
+ mp_add(n, radix, a, e, a);
+ printf("AGM iteration\n");
+ fprintf(f_log, "AGM iteration\n");
+ npow = 4;
+ do {
+ npow *= 2;
+ /* ---- e = (a + b) / 2 ---- */
+ mp_add(n, radix, a, b, e);
+ mp_idiv_2(n, radix, e, e);
+ /* ---- b = sqrt(a * b) ---- */
+ mp_mul(n, radix, a, b, a, i1, nfft, d1, d2, d3, ip, w);
+ mp_sqrt(n, radix, a, b, i1, i2, nfft, d1, d2, ip, w);
+ /* ---- e = e - b ---- */
+ mp_sub(n, radix, e, b, e);
+ /* ---- b = 2 * b ---- */
+ mp_add(n, radix, b, b, b);
+ /* ---- c = c - e ---- */
+ mp_sub(n, radix, c, e, c);
+ /* ---- a = e + b ---- */
+ mp_add(n, radix, e, b, a);
+ /* ---- convergence check ---- */
+ nprc = -e[1];
+ if (e[0] == 0) {
+ nprc = n;
+ }
+ printf("precision= %d\n", 4 * nprc * log10_radix);
+ fprintf(f_log, "precision= %d\n", 4 * nprc * log10_radix);
+ } while (4 * nprc <= n);
+ /* ---- e = e * e / 4 (half precision) ---- */
+ mp_idiv_2(n, radix, e, e);
+ mp_squh(n, radix, e, e, nfft, d1, ip, w);
+ /* ---- a = a + b ---- */
+ mp_add(n, radix, a, b, a);
+ /* ---- a = (a * a - e - e / 2) / (a * c - e) / npow ---- */
+ mp_mul(n, radix, a, c, c, i1, nfft, d1, d2, d3, ip, w);
+ mp_sub(n, radix, c, e, c);
+ mp_inv(n, radix, c, b, i1, i2, nfft, d1, d2, ip, w);
+ mp_squ(n, radix, a, a, i1, nfft, d1, d2, ip, w);
+ mp_sub(n, radix, a, e, a);
+ mp_idiv_2(n, radix, e, e);
+ mp_sub(n, radix, a, e, a);
+ mp_mul(n, radix, a, b, a, i1, nfft, d1, d2, d3, ip, w);
+ mp_idiv(n, radix, a, npow, a);
+ /* ---- time check ---- */
+ time(&t_2);
+ /* ---- output ---- */
+ f_out = fopen("pi.dat", "w");
+ printf("writing pi.dat...\n");
+ mp_fprintf(n - 1, log10_radix, a, f_out);
+ fclose(f_out);
+ free(d3);
+ free(d2);
+ free(d1);
+ free(i2);
+ free(i1);
+ free(e);
+ free(c);
+ free(b);
+ free(a);
+ free(w);
+ free(ip);
+ /* ---- benchmark ---- */
+ n_op = 50.0 * nfft * log2_nfft * log2_nfft;
+ printf("floating point operation: %g op.\n", n_op);
+ fprintf(f_log, "floating point operation: %g op.\n", n_op);
+ /* ---- difftime ---- */
+ d_time = difftime(t_2, t_1);
+ printf("execution time: %g sec. (real time)\n", d_time);
+ fprintf(f_log, "execution time: %g sec. (real time)\n", d_time);
+ fclose(f_log);
+ return 0;
+}
+
+
+/* -------- multiple precision routines -------- */
+
+
+#include <math.h>
+#include <float.h>
+#include <stdio.h>
+
+/* ---- floating point format ----
+ data := data[0] * pow(radix, data[1]) *
+ (data[2] + data[3]/radix + data[4]/radix/radix + ...),
+ data[0] : sign (1;data>0, -1;data<0, 0;data==0)
+ data[1] : exponent (0;data==0)
+ data[2...n+1] : digits
+ ---- function prototypes ----
+ void mp_load_0(int n, int radix, int out[]);
+ void mp_load_1(int n, int radix, int out[]);
+ void mp_copy(int n, int radix, int in[], int out[]);
+ void mp_round(int n, int radix, int m, int inout[]);
+ int mp_cmp(int n, int radix, int in1[], int in2[]);
+ void mp_add(int n, int radix, int in1[], int in2[], int out[]);
+ void mp_sub(int n, int radix, int in1[], int in2[], int out[]);
+ void mp_imul(int n, int radix, int in1[], int in2, int out[]);
+ int mp_idiv(int n, int radix, int in1[], int in2, int out[]);
+ void mp_idiv_2(int n, int radix, int in[], int out[]);
+ double mp_mul_radix_test(int n, int radix, int nfft,
+ double tmpfft[], int ip[], double w[]);
+ void mp_mul(int n, int radix, int in1[], int in2[], int out[],
+ int tmp[], int nfft, double tmp1fft[], double tmp2fft[],
+ double tmp3fft[], int ip[], double w[]);
+ void mp_squ(int n, int radix, int in[], int out[], int tmp[],
+ int nfft, double tmp1fft[], double tmp2fft[],
+ int ip[], double w[]);
+ void mp_mulh(int n, int radix, int in1[], int in2[], int out[],
+ int nfft, double in1fft[], double outfft[],
+ int ip[], double w[]);
+ void mp_squh(int n, int radix, int in[], int out[],
+ int nfft, double inoutfft[], int ip[], double w[]);
+ int mp_inv(int n, int radix, int in[], int out[],
+ int tmp1[], int tmp2[], int nfft,
+ double tmp1fft[], double tmp2fft[], int ip[], double w[]);
+ int mp_sqrt(int n, int radix, int in[], int out[],
+ int tmp1[], int tmp2[], int nfft,
+ double tmp1fft[], double tmp2fft[], int ip[], double w[]);
+ void mp_sprintf(int n, int log10_radix, int in[], char out[]);
+ void mp_sscanf(int n, int log10_radix, char in[], int out[]);
+ void mp_fprintf(int n, int log10_radix, int in[], FILE *fout);
+ ----
+*/
+
+
+/* -------- mp_load routines -------- */
+
+
+void mp_load_0(int n, int radix, int out[])
+{
+ int j;
+
+ for (j = 0; j <= n + 1; j++) {
+ out[j] = 0;
+ }
+}
+
+
+void mp_load_1(int n, int radix, int out[])
+{
+ int j;
+
+ out[0] = 1;
+ out[1] = 0;
+ out[2] = 1;
+ for (j = 3; j <= n + 1; j++) {
+ out[j] = 0;
+ }
+}
+
+
+void mp_copy(int n, int radix, int in[], int out[])
+{
+ int j;
+
+ for (j = 0; j <= n + 1; j++) {
+ out[j] = in[j];
+ }
+}
+
+
+void mp_round(int n, int radix, int m, int inout[])
+{
+ int j, x;
+
+ if (m < n) {
+ for (j = n + 1; j > m + 2; j--) {
+ inout[j] = 0;
+ }
+ x = 2 * inout[m + 2];
+ inout[m + 2] = 0;
+ if (x >= radix) {
+ for (j = m + 1; j >= 2; j--) {
+ x = inout[j] + 1;
+ if (x < radix) {
+ inout[j] = x;
+ break;
+ }
+ inout[j] = 0;
+ }
+ if (x >= radix) {
+ inout[2] = 1;
+ inout[1]++;
+ }
+ }
+ }
+}
+
+
+/* -------- mp_add routines -------- */
+
+
+int mp_cmp(int n, int radix, int in1[], int in2[])
+{
+ int mp_unsgn_cmp(int n, int in1[], int in2[]);
+
+ if (in1[0] > in2[0]) {
+ return 1;
+ } else if (in1[0] < in2[0]) {
+ return -1;
+ }
+ return in1[0] * mp_unsgn_cmp(n, &in1[1], &in2[1]);
+}
+
+
+void mp_add(int n, int radix, int in1[], int in2[], int out[])
+{
+ int mp_unsgn_cmp(int n, int in1[], int in2[]);
+ int mp_unexp_add(int n, int radix, int expdif,
+ int in1[], int in2[], int out[]);
+ int mp_unexp_sub(int n, int radix, int expdif,
+ int in1[], int in2[], int out[]);
+ int outsgn, outexp, expdif;
+
+ expdif = in1[1] - in2[1];
+ outexp = in1[1];
+ if (expdif < 0) {
+ outexp = in2[1];
+ }
+ outsgn = in1[0] * in2[0];
+ if (outsgn >= 0) {
+ if (outsgn > 0) {
+ outsgn = in1[0];
+ } else {
+ outsgn = in1[0] + in2[0];
+ outexp = in1[1] + in2[1];
+ expdif = 0;
+ }
+ if (expdif >= 0) {
+ outexp += mp_unexp_add(n, radix, expdif,
+ &in1[2], &in2[2], &out[2]);
+ } else {
+ outexp += mp_unexp_add(n, radix, -expdif,
+ &in2[2], &in1[2], &out[2]);
+ }
+ } else {
+ outsgn = mp_unsgn_cmp(n, &in1[1], &in2[1]);
+ if (outsgn >= 0) {
+ expdif = mp_unexp_sub(n, radix, expdif,
+ &in1[2], &in2[2], &out[2]);
+ } else {
+ expdif = mp_unexp_sub(n, radix, -expdif,
+ &in2[2], &in1[2], &out[2]);
+ }
+ outexp -= expdif;
+ outsgn *= in1[0];
+ if (expdif == n) {
+ outsgn = 0;
+ }
+ }
+ if (outsgn == 0) {
+ outexp = 0;
+ }
+ out[0] = outsgn;
+ out[1] = outexp;
+}
+
+
+void mp_sub(int n, int radix, int in1[], int in2[], int out[])
+{
+ int mp_unsgn_cmp(int n, int in1[], int in2[]);
+ int mp_unexp_add(int n, int radix, int expdif,
+ int in1[], int in2[], int out[]);
+ int mp_unexp_sub(int n, int radix, int expdif,
+ int in1[], int in2[], int out[]);
+ int outsgn, outexp, expdif;
+
+ expdif = in1[1] - in2[1];
+ outexp = in1[1];
+ if (expdif < 0) {
+ outexp = in2[1];
+ }
+ outsgn = in1[0] * in2[0];
+ if (outsgn <= 0) {
+ if (outsgn < 0) {
+ outsgn = in1[0];
+ } else {
+ outsgn = in1[0] - in2[0];
+ outexp = in1[1] + in2[1];
+ expdif = 0;
+ }
+ if (expdif >= 0) {
+ outexp += mp_unexp_add(n, radix, expdif,
+ &in1[2], &in2[2], &out[2]);
+ } else {
+ outexp += mp_unexp_add(n, radix, -expdif,
+ &in2[2], &in1[2], &out[2]);
+ }
+ } else {
+ outsgn = mp_unsgn_cmp(n, &in1[1], &in2[1]);
+ if (outsgn >= 0) {
+ expdif = mp_unexp_sub(n, radix, expdif,
+ &in1[2], &in2[2], &out[2]);
+ } else {
+ expdif = mp_unexp_sub(n, radix, -expdif,
+ &in2[2], &in1[2], &out[2]);
+ }
+ outexp -= expdif;
+ outsgn *= in1[0];
+ if (expdif == n) {
+ outsgn = 0;
+ }
+ }
+ if (outsgn == 0) {
+ outexp = 0;
+ }
+ out[0] = outsgn;
+ out[1] = outexp;
+}
+
+
+/* -------- mp_add child routines -------- */
+
+
+int mp_unsgn_cmp(int n, int in1[], int in2[])
+{
+ int j, cmp;
+
+ cmp = 0;
+ for (j = 0; j <= n && cmp == 0; j++) {
+ cmp = in1[j] - in2[j];
+ }
+ if (cmp > 0) {
+ cmp = 1;
+ } else if (cmp < 0) {
+ cmp = -1;
+ }
+ return cmp;
+}
+
+
+int mp_unexp_add(int n, int radix, int expdif,
+ int in1[], int in2[], int out[])
+{
+ int j, x, carry;
+
+ carry = 0;
+ if (expdif == 0 && in1[0] + in2[0] >= radix) {
+ x = in1[n - 1] + in2[n - 1];
+ carry = x >= radix ? -1 : 0;
+ for (j = n - 1; j > 0; j--) {
+ x = in1[j - 1] + in2[j - 1] - carry;
+ carry = x >= radix ? -1 : 0;
+ out[j] = x - (radix & carry);
+ }
+ out[0] = -carry;
+ } else {
+ if (expdif > n) {
+ expdif = n;
+ }
+ for (j = n - 1; j >= expdif; j--) {
+ x = in1[j] + in2[j - expdif] - carry;
+ carry = x >= radix ? -1 : 0;
+ out[j] = x - (radix & carry);
+ }
+ for (j = expdif - 1; j >= 0; j--) {
+ x = in1[j] - carry;
+ carry = x >= radix ? -1 : 0;
+ out[j] = x - (radix & carry);
+ }
+ if (carry != 0) {
+ for (j = n - 1; j > 0; j--) {
+ out[j] = out[j - 1];
+ }
+ out[0] = -carry;
+ }
+ }
+ return -carry;
+}
+
+
+int mp_unexp_sub(int n, int radix, int expdif,
+ int in1[], int in2[], int out[])
+{
+ int j, x, borrow, ncancel;
+
+ if (expdif > n) {
+ expdif = n;
+ }
+ borrow = 0;
+ for (j = n - 1; j >= expdif; j--) {
+ x = in1[j] - in2[j - expdif] + borrow;
+ borrow = x < 0 ? -1 : 0;
+ out[j] = x + (radix & borrow);
+ }
+ for (j = expdif - 1; j >= 0; j--) {
+ x = in1[j] + borrow;
+ borrow = x < 0 ? -1 : 0;
+ out[j] = x + (radix & borrow);
+ }
+ ncancel = 0;
+ for (j = 0; j < n && out[j] == 0; j++) {
+ ncancel = j + 1;
+ }
+ if (ncancel > 0 && ncancel < n) {
+ for (j = 0; j < n - ncancel; j++) {
+ out[j] = out[j + ncancel];
+ }
+ for (j = n - ncancel; j < n; j++) {
+ out[j] = 0;
+ }
+ }
+ return ncancel;
+}
+
+
+/* -------- mp_imul routines -------- */
+
+
+void mp_imul(int n, int radix, int in1[], int in2, int out[])
+{
+ void mp_unsgn_imul(int n, double dradix, int in1[], double din2,
+ int out[]);
+
+ if (in2 > 0) {
+ out[0] = in1[0];
+ } else if (in2 < 0) {
+ out[0] = -in1[0];
+ in2 = -in2;
+ } else {
+ out[0] = 0;
+ }
+ mp_unsgn_imul(n, radix, &in1[1], in2, &out[1]);
+ if (out[0] == 0) {
+ out[1] = 0;
+ }
+}
+
+
+int mp_idiv(int n, int radix, int in1[], int in2, int out[])
+{
+ void mp_load_0(int n, int radix, int out[]);
+ void mp_unsgn_idiv(int n, double dradix, int in1[], double din2,
+ int out[]);
+
+ if (in2 == 0) {
+ return -1;
+ }
+ if (in2 > 0) {
+ out[0] = in1[0];
+ } else {
+ out[0] = -in1[0];
+ in2 = -in2;
+ }
+ if (in1[0] == 0) {
+ mp_load_0(n, radix, out);
+ return 0;
+ }
+ mp_unsgn_idiv(n, radix, &in1[1], in2, &out[1]);
+ return 0;
+}
+
+
+void mp_idiv_2(int n, int radix, int in[], int out[])
+{
+ int j, ix, carry, shift;
+
+ out[0] = in[0];
+ shift = 0;
+ if (in[2] == 1) {
+ shift = 1;
+ }
+ out[1] = in[1] - shift;
+ carry = -shift;
+ for (j = 2; j <= n + 1 - shift; j++) {
+ ix = in[j + shift] + (radix & carry);
+ carry = -(ix & 1);
+ out[j] = ix >> 1;
+ }
+ if (shift > 0) {
+ out[n + 1] = (radix & carry) >> 1;
+ }
+}
+
+
+/* -------- mp_imul child routines -------- */
+
+
+void mp_unsgn_imul(int n, double dradix, int in1[], double din2,
+ int out[])
+{
+ int j, carry, shift;
+ double x, d1_radix;
+
+ d1_radix = 1.0 / dradix;
+ carry = 0;
+ for (j = n; j >= 1; j--) {
+ x = din2 * in1[j] + carry + 0.5;
+ carry = (int) (d1_radix * x);
+ out[j] = (int) (x - dradix * carry);
+ }
+ shift = 0;
+ x = carry + 0.5;
+ while (x > 1) {
+ x *= d1_radix;
+ shift++;
+ }
+ out[0] = in1[0] + shift;
+ if (shift > 0) {
+ while (shift > n) {
+ carry = (int) (d1_radix * carry + 0.5);
+ shift--;
+ }
+ for (j = n; j >= shift + 1; j--) {
+ out[j] = out[j - shift];
+ }
+ for (j = shift; j >= 1; j--) {
+ x = carry + 0.5;
+ carry = (int) (d1_radix * x);
+ out[j] = (int) (x - dradix * carry);
+ }
+ }
+}
+
+
+void mp_unsgn_idiv(int n, double dradix, int in1[], double din2,
+ int out[])
+{
+ int j, ix, carry, shift;
+ double x, d1_in2;
+
+ d1_in2 = 1.0 / din2;
+ shift = 0;
+ x = 0;
+ do {
+ shift++;
+ x *= dradix;
+ if (shift <= n) {
+ x += in1[shift];
+ }
+ } while (x < din2 - 0.5);
+ x += 0.5;
+ ix = (int) (d1_in2 * x);
+ carry = (int) (x - din2 * ix);
+ out[1] = ix;
+ shift--;
+ out[0] = in1[0] - shift;
+ if (shift >= n) {
+ shift = n - 1;
+ }
+ for (j = 2; j <= n - shift; j++) {
+ x = in1[j + shift] + dradix * carry + 0.5;
+ ix = (int) (d1_in2 * x);
+ carry = (int) (x - din2 * ix);
+ out[j] = ix;
+ }
+ for (j = n - shift + 1; j <= n; j++) {
+ x = dradix * carry + 0.5;
+ ix = (int) (d1_in2 * x);
+ carry = (int) (x - din2 * ix);
+ out[j] = ix;
+ }
+}
+
+
+/* -------- mp_mul routines -------- */
+
+
+double mp_mul_radix_test(int n, int radix, int nfft,
+ double tmpfft[], int ip[], double w[])
+{
+ void rdft(int n, int isgn, double *a, int *ip, double *w);
+ void mp_mul_csqu(int nfft, double dinout[]);
+ double mp_mul_d2i_test(int radix, int nfft, double din[]);
+ int j, ndata, radix_2;
+
+ ndata = (nfft >> 1) + 1;
+ if (ndata > n) {
+ ndata = n;
+ }
+ tmpfft[nfft + 1] = radix - 1;
+ for (j = nfft; j > ndata; j--) {
+ tmpfft[j] = 0;
+ }
+ radix_2 = (radix + 1) / 2;
+ for (j = ndata; j > 2; j--) {
+ tmpfft[j] = radix_2;
+ }
+ tmpfft[2] = radix;
+ tmpfft[1] = radix - 1;
+ tmpfft[0] = 0;
+ rdft(nfft, 1, &tmpfft[1], ip, w);
+ mp_mul_csqu(nfft, tmpfft);
+ rdft(nfft, -1, &tmpfft[1], ip, w);
+ return 2 * mp_mul_d2i_test(radix, nfft, tmpfft);
+}
+
+
+void mp_mul(int n, int radix, int in1[], int in2[], int out[],
+ int tmp[], int nfft, double tmp1fft[], double tmp2fft[],
+ double tmp3fft[], int ip[], double w[])
+{
+ void mp_copy(int n, int radix, int in[], int out[]);
+ void mp_add(int n, int radix, int in1[], int in2[], int out[]);
+ void rdft(int n, int isgn, double *a, int *ip, double *w);
+ void mp_mul_i2d(int n, int radix, int nfft, int shift,
+ int in[], double dout[]);
+ void mp_mul_cmul(int nfft, double din[], double dinout[]);
+ void mp_mul_cmuladd(int nfft, double din1[], double din2[],
+ double dinout[]);
+ void mp_mul_d2i(int n, int radix, int nfft, double din[], int out[]);
+ int n_h, shift;
+
+ shift = (nfft >> 1) + 1;
+ while (n > shift) {
+ if (in1[shift + 2] + in2[shift + 2] != 0) {
+ break;
+ }
+ shift++;
+ }
+ n_h = n / 2 + 1;
+ if (n_h < n - shift) {
+ n_h = n - shift;
+ }
+ /* ---- tmp3fft = (upper) in1 * (lower) in2 ---- */
+ mp_mul_i2d(n, radix, nfft, 0, in1, tmp1fft);
+ rdft(nfft, 1, &tmp1fft[1], ip, w);
+ mp_mul_i2d(n, radix, nfft, shift, in2, tmp3fft);
+ rdft(nfft, 1, &tmp3fft[1], ip, w);
+ mp_mul_cmul(nfft, tmp1fft, tmp3fft);
+ /* ---- tmp = (upper) in1 * (upper) in2 ---- */
+ mp_mul_i2d(n, radix, nfft, 0, in2, tmp2fft);
+ rdft(nfft, 1, &tmp2fft[1], ip, w);
+ mp_mul_cmul(nfft, tmp2fft, tmp1fft);
+ rdft(nfft, -1, &tmp1fft[1], ip, w);
+ mp_mul_d2i(n, radix, nfft, tmp1fft, tmp);
+ /* ---- tmp3fft += (upper) in2 * (lower) in1 ---- */
+ mp_mul_i2d(n, radix, nfft, shift, in1, tmp1fft);
+ rdft(nfft, 1, &tmp1fft[1], ip, w);
+ mp_mul_cmuladd(nfft, tmp1fft, tmp2fft, tmp3fft);
+ /* ---- out = tmp + tmp3fft ---- */
+ rdft(nfft, -1, &tmp3fft[1], ip, w);
+ mp_mul_d2i(n_h, radix, nfft, tmp3fft, out);
+ if (out[0] != 0) {
+ mp_add(n, radix, out, tmp, out);
+ } else {
+ mp_copy(n, radix, tmp, out);
+ }
+}
+
+
+void mp_squ(int n, int radix, int in[], int out[], int tmp[],
+ int nfft, double tmp1fft[], double tmp2fft[],
+ int ip[], double w[])
+{
+ void mp_add(int n, int radix, int in1[], int in2[], int out[]);
+ void rdft(int n, int isgn, double *a, int *ip, double *w);
+ void mp_mul_i2d(int n, int radix, int nfft, int shift,
+ int in[], double dout[]);
+ void mp_mul_cmul(int nfft, double din[], double dinout[]);
+ void mp_mul_csqu(int nfft, double dinout[]);
+ void mp_mul_d2i(int n, int radix, int nfft, double din[], int out[]);
+ int n_h, shift;
+
+ shift = (nfft >> 1) + 1;
+ while (n > shift) {
+ if (in[shift + 2] != 0) {
+ break;
+ }
+ shift++;
+ }
+ n_h = n / 2 + 1;
+ if (n_h < n - shift) {
+ n_h = n - shift;
+ }
+ /* ---- tmp = (upper) in * (lower) in ---- */
+ mp_mul_i2d(n, radix, nfft, 0, in, tmp1fft);
+ rdft(nfft, 1, &tmp1fft[1], ip, w);
+ mp_mul_i2d(n, radix, nfft, shift, in, tmp2fft);
+ rdft(nfft, 1, &tmp2fft[1], ip, w);
+ mp_mul_cmul(nfft, tmp1fft, tmp2fft);
+ rdft(nfft, -1, &tmp2fft[1], ip, w);
+ mp_mul_d2i(n_h, radix, nfft, tmp2fft, tmp);
+ /* ---- out = 2 * tmp + ((upper) in)^2 ---- */
+ mp_mul_csqu(nfft, tmp1fft);
+ rdft(nfft, -1, &tmp1fft[1], ip, w);
+ mp_mul_d2i(n, radix, nfft, tmp1fft, out);
+ if (tmp[0] != 0) {
+ mp_add(n_h, radix, tmp, tmp, tmp);
+ mp_add(n, radix, out, tmp, out);
+ }
+}
+
+
+void mp_mulh(int n, int radix, int in1[], int in2[], int out[],
+ int nfft, double in1fft[], double outfft[], int ip[], double w[])
+{
+ void rdft(int n, int isgn, double *a, int *ip, double *w);
+ void mp_mul_i2d(int n, int radix, int nfft, int shift,
+ int in[], double dout[]);
+ void mp_mul_cmul(int nfft, double din[], double dinout[]);
+ void mp_mul_d2i(int n, int radix, int nfft, double din[], int out[]);
+
+ mp_mul_i2d(n, radix, nfft, 0, in1, in1fft);
+ rdft(nfft, 1, &in1fft[1], ip, w);
+ mp_mul_i2d(n, radix, nfft, 0, in2, outfft);
+ rdft(nfft, 1, &outfft[1], ip, w);
+ mp_mul_cmul(nfft, in1fft, outfft);
+ rdft(nfft, -1, &outfft[1], ip, w);
+ mp_mul_d2i(n, radix, nfft, outfft, out);
+}
+
+
+void mp_mulh_use_in1fft(int n, int radix, double in1fft[],
+ int shift, int in2[], int out[], int nfft, double outfft[],
+ int ip[], double w[])
+{
+ void rdft(int n, int isgn, double *a, int *ip, double *w);
+ void mp_mul_i2d(int n, int radix, int nfft, int shift,
+ int in[], double dout[]);
+ void mp_mul_cmul(int nfft, double din[], double dinout[]);
+ void mp_mul_d2i(int n, int radix, int nfft, double din[], int out[]);
+ int n_h;
+
+ while (n > shift) {
+ if (in2[shift + 2] != 0) {
+ break;
+ }
+ shift++;
+ }
+ n_h = n / 2 + 1;
+ if (n_h < n - shift) {
+ n_h = n - shift;
+ }
+ mp_mul_i2d(n, radix, nfft, shift, in2, outfft);
+ rdft(nfft, 1, &outfft[1], ip, w);
+ mp_mul_cmul(nfft, in1fft, outfft);
+ rdft(nfft, -1, &outfft[1], ip, w);
+ mp_mul_d2i(n_h, radix, nfft, outfft, out);
+}
+
+
+void mp_squh(int n, int radix, int in[], int out[],
+ int nfft, double inoutfft[], int ip[], double w[])
+{
+ void rdft(int n, int isgn, double *a, int *ip, double *w);
+ void mp_mul_i2d(int n, int radix, int nfft, int shift,
+ int in[], double dout[]);
+ void mp_mul_csqu(int nfft, double dinout[]);
+ void mp_mul_d2i(int n, int radix, int nfft, double din[], int out[]);
+
+ mp_mul_i2d(n, radix, nfft, 0, in, inoutfft);
+ rdft(nfft, 1, &inoutfft[1], ip, w);
+ mp_mul_csqu(nfft, inoutfft);
+ rdft(nfft, -1, &inoutfft[1], ip, w);
+ mp_mul_d2i(n, radix, nfft, inoutfft, out);
+}
+
+
+void mp_squh_use_in1fft(int n, int radix, double inoutfft[], int out[],
+ int nfft, int ip[], double w[])
+{
+ void rdft(int n, int isgn, double *a, int *ip, double *w);
+ void mp_mul_csqu(int nfft, double dinout[]);
+ void mp_mul_d2i(int n, int radix, int nfft, double din[], int out[]);
+
+ mp_mul_csqu(nfft, inoutfft);
+ rdft(nfft, -1, &inoutfft[1], ip, w);
+ mp_mul_d2i(n, radix, nfft, inoutfft, out);
+}
+
+
+/* -------- mp_mul child routines -------- */
+
+
+void mp_mul_i2d(int n, int radix, int nfft, int shift,
+ int in[], double dout[])
+{
+ int j, x, carry, ndata, radix_2, topdgt;
+
+ ndata = 0;
+ topdgt = 0;
+ if (n > shift) {
+ topdgt = in[shift + 2];
+ ndata = (nfft >> 1) + 1;
+ if (ndata > n - shift) {
+ ndata = n - shift;
+ }
+ }
+ dout[nfft + 1] = in[0] * topdgt;
+ for (j = nfft; j > ndata; j--) {
+ dout[j] = 0;
+ }
+ /* ---- abs(dout[j]) <= radix/2 (to keep FFT precision) ---- */
+ if (ndata > 1) {
+ radix_2 = radix / 2;
+ carry = 0;
+ for (j = ndata + 1; j > 3; j--) {
+ x = in[j + shift] - carry;
+ carry = x >= radix_2 ? -1 : 0;
+ dout[j - 1] = x - (radix & carry);
+ }
+ dout[2] = in[shift + 3] - carry;
+ }
+ dout[1] = topdgt;
+ dout[0] = in[1] - shift;
+}
+
+
+void mp_mul_cmul(int nfft, double din[], double dinout[])
+{
+ int j;
+ double xr, xi, yr, yi;
+
+ dinout[0] += din[0];
+ dinout[1] *= din[1];
+ dinout[2] *= din[2];
+ for (j = 3; j < nfft; j += 2) {
+ xr = din[j];
+ xi = din[j + 1];
+ yr = dinout[j];
+ yi = dinout[j + 1];
+ dinout[j] = xr * yr - xi * yi;
+ dinout[j + 1] = xr * yi + xi * yr;
+ }
+ dinout[nfft + 1] *= din[nfft + 1];
+}
+
+
+void mp_mul_cmuladd(int nfft, double din1[], double din2[],
+ double dinout[])
+{
+ int j;
+ double xr, xi, yr, yi;
+
+ dinout[1] += din1[1] * din2[1];
+ dinout[2] += din1[2] * din2[2];
+ for (j = 3; j < nfft; j += 2) {
+ xr = din1[j];
+ xi = din1[j + 1];
+ yr = din2[j];
+ yi = din2[j + 1];
+ dinout[j] += xr * yr - xi * yi;
+ dinout[j + 1] += xr * yi + xi * yr;
+ }
+ dinout[nfft + 1] += din1[nfft + 1] * din2[nfft + 1];
+}
+
+
+void mp_mul_csqu(int nfft, double dinout[])
+{
+ int j;
+ double xr, xi;
+
+ dinout[0] *= 2;
+ dinout[1] *= dinout[1];
+ dinout[2] *= dinout[2];
+ for (j = 3; j < nfft; j += 2) {
+ xr = dinout[j];
+ xi = dinout[j + 1];
+ dinout[j] = xr * xr - xi * xi;
+ dinout[j + 1] = 2 * xr * xi;
+ }
+ dinout[nfft + 1] *= dinout[nfft + 1];
+}
+
+
+void mp_mul_d2i(int n, int radix, int nfft, double din[], int out[])
+{
+ int j, carry, carry1, carry2, shift, ndata;
+ double x, scale, d1_radix, d1_radix2, pow_radix, topdgt;
+
+ scale = 2.0 / nfft;
+ d1_radix = 1.0 / radix;
+ d1_radix2 = d1_radix * d1_radix;
+ topdgt = din[nfft + 1];
+ x = topdgt < 0 ? -topdgt : topdgt;
+ shift = x + 0.5 >= radix ? 1 : 0;
+ /* ---- correction of cyclic convolution of din[1] ---- */
+ x *= nfft * 0.5;
+ din[nfft + 1] = din[1] - x;
+ din[1] = x;
+ /* ---- output of digits ---- */
+ ndata = n;
+ if (n > nfft + 1 + shift) {
+ ndata = nfft + 1 + shift;
+ for (j = n + 1; j > ndata + 1; j--) {
+ out[j] = 0;
+ }
+ }
+ x = 0;
+ pow_radix = 1;
+ for (j = ndata + 1 - shift; j <= nfft + 1; j++) {
+ x += pow_radix * din[j];
+ pow_radix *= d1_radix;
+ if (pow_radix < DBL_EPSILON) {
+ break;
+ }
+ }
+ x = d1_radix2 * (scale * x + 0.5);
+ carry2 = ((int) x) - 1;
+ carry = (int) (radix * (x - carry2) + 0.5);
+ for (j = ndata; j > 1; j--) {
+ x = d1_radix2 * (scale * din[j - shift] + carry + 0.5);
+ carry = carry2;
+ carry2 = ((int) x) - 1;
+ x = radix * (x - carry2);
+ carry1 = (int) x;
+ out[j + 1] = (int) (radix * (x - carry1));
+ carry += carry1;
+ }
+ x = carry + ((double) radix) * carry2 + 0.5;
+ if (shift == 0) {
+ x += scale * din[1];
+ }
+ carry = (int) (d1_radix * x);
+ out[2] = (int) (x - ((double) radix) * carry);
+ if (carry > 0) {
+ for (j = n + 1; j > 2; j--) {
+ out[j] = out[j - 1];
+ }
+ out[2] = carry;
+ shift++;
+ }
+ /* ---- output of exp, sgn ---- */
+ x = din[0] + shift + 0.5;
+ shift = ((int) x) - 1;
+ out[1] = shift + ((int) (x - shift));
+ out[0] = topdgt > 0.5 ? 1 : -1;
+ if (out[2] == 0) {
+ out[0] = 0;
+ out[1] = 0;
+ }
+}
+
+
+double mp_mul_d2i_test(int radix, int nfft, double din[])
+{
+ int j, carry, carry1, carry2;
+ double x, scale, d1_radix, d1_radix2, err;
+
+ scale = 2.0 / nfft;
+ d1_radix = 1.0 / radix;
+ d1_radix2 = d1_radix * d1_radix;
+ /* ---- correction of cyclic convolution of din[1] ---- */
+ x = din[nfft + 1] * nfft * 0.5;
+ if (x < 0) {
+ x = -x;
+ }
+ din[nfft + 1] = din[1] - x;
+ /* ---- check of digits ---- */
+ err = 0;
+ carry = 0;
+ carry2 = 0;
+ for (j = nfft + 1; j > 1; j--) {
+ x = d1_radix2 * (scale * din[j] + carry + 0.5);
+ carry = carry2;
+ carry2 = ((int) x) - 1;
+ x = radix * (x - carry2);
+ carry1 = (int) x;
+ x = radix * (x - carry1);
+ carry += carry1;
+ x = x - 0.5 - ((int) x);
+ if (x > err) {
+ err = x;
+ } else if (-x > err) {
+ err = -x;
+ }
+ }
+ return err;
+}
+
+
+/* -------- mp_inv routines -------- */
+
+
+int mp_inv(int n, int radix, int in[], int out[],
+ int tmp1[], int tmp2[], int nfft,
+ double tmp1fft[], double tmp2fft[], int ip[], double w[])
+{
+ int mp_get_nfft_init(int radix, int nfft_max);
+ void mp_inv_init(int n, int radix, int in[], int out[]);
+ int mp_inv_newton(int n, int radix, int in[], int inout[],
+ int tmp1[], int tmp2[], int nfft, double tmp1fft[],
+ double tmp2fft[], int ip[], double w[]);
+ int n_nwt, nfft_nwt, thr, prc;
+
+ if (in[0] == 0) {
+ return -1;
+ }
+ nfft_nwt = mp_get_nfft_init(radix, nfft);
+ n_nwt = nfft_nwt + 2;
+ if (n_nwt > n) {
+ n_nwt = n;
+ }
+ mp_inv_init(n_nwt, radix, in, out);
+ thr = 8;
+ do {
+ n_nwt = nfft_nwt + 2;
+ if (n_nwt > n) {
+ n_nwt = n;
+ }
+ prc = mp_inv_newton(n_nwt, radix, in, out,
+ tmp1, tmp2, nfft_nwt, tmp1fft, tmp2fft, ip, w);
+ if (thr * nfft_nwt >= nfft) {
+ thr = 0;
+ if (2 * prc <= n_nwt - 2) {
+ nfft_nwt >>= 1;
+ }
+ } else {
+ if (3 * prc < n_nwt - 2) {
+ nfft_nwt >>= 1;
+ }
+ }
+ nfft_nwt <<= 1;
+ } while (nfft_nwt <= nfft);
+ return 0;
+}
+
+
+int mp_sqrt(int n, int radix, int in[], int out[],
+ int tmp1[], int tmp2[], int nfft,
+ double tmp1fft[], double tmp2fft[], int ip[], double w[])
+{
+ void mp_load_0(int n, int radix, int out[]);
+ int mp_get_nfft_init(int radix, int nfft_max);
+ void mp_sqrt_init(int n, int radix, int in[], int out[], int out_rev[]);
+ int mp_sqrt_newton(int n, int radix, int in[], int inout[],
+ int inout_rev[], int tmp[], int nfft, double tmp1fft[],
+ double tmp2fft[], int ip[], double w[], int *n_tmp1fft);
+ int n_nwt, nfft_nwt, thr, prc, n_tmp1fft;
+
+ if (in[0] < 0) {
+ return -1;
+ } else if (in[0] == 0) {
+ mp_load_0(n, radix, out);
+ return 0;
+ }
+ nfft_nwt = mp_get_nfft_init(radix, nfft);
+ n_nwt = nfft_nwt + 2;
+ if (n_nwt > n) {
+ n_nwt = n;
+ }
+ mp_sqrt_init(n_nwt, radix, in, out, tmp1);
+ n_tmp1fft = 0;
+ thr = 8;
+ do {
+ n_nwt = nfft_nwt + 2;
+ if (n_nwt > n) {
+ n_nwt = n;
+ }
+ prc = mp_sqrt_newton(n_nwt, radix, in, out,
+ tmp1, tmp2, nfft_nwt, tmp1fft, tmp2fft,
+ ip, w, &n_tmp1fft);
+ if (thr * nfft_nwt >= nfft) {
+ thr = 0;
+ if (2 * prc <= n_nwt - 2) {
+ nfft_nwt >>= 1;
+ }
+ } else {
+ if (3 * prc < n_nwt - 2) {
+ nfft_nwt >>= 1;
+ }
+ }
+ nfft_nwt <<= 1;
+ } while (nfft_nwt <= nfft);
+ return 0;
+}
+
+
+/* -------- mp_inv child routines -------- */
+
+
+int mp_get_nfft_init(int radix, int nfft_max)
+{
+ int nfft_init;
+ double r;
+
+ r = radix;
+ nfft_init = 1;
+ do {
+ r *= r;
+ nfft_init <<= 1;
+ } while (DBL_EPSILON * r < 1 && nfft_init < nfft_max);
+ return nfft_init;
+}
+
+
+void mp_inv_init(int n, int radix, int in[], int out[])
+{
+ void mp_unexp_d2mp(int n, int radix, double din, int out[]);
+ double mp_unexp_mp2d(int n, int radix, int in[]);
+ int outexp;
+ double din;
+
+ out[0] = in[0];
+ outexp = -in[1];
+ din = 1.0 / mp_unexp_mp2d(n, radix, &in[2]);
+ while (din < 1) {
+ din *= radix;
+ outexp--;
+ }
+ out[1] = outexp;
+ mp_unexp_d2mp(n, radix, din, &out[2]);
+}
+
+
+void mp_sqrt_init(int n, int radix, int in[], int out[], int out_rev[])
+{
+ void mp_unexp_d2mp(int n, int radix, double din, int out[]);
+ double mp_unexp_mp2d(int n, int radix, int in[]);
+ int outexp;
+ double din;
+
+ out[0] = 1;
+ out_rev[0] = 1;
+ outexp = in[1];
+ din = mp_unexp_mp2d(n, radix, &in[2]);
+ if (outexp % 2 != 0) {
+ din *= radix;
+ outexp--;
+ }
+ outexp /= 2;
+ din = sqrt(din);
+ if (din < 1) {
+ din *= radix;
+ outexp--;
+ }
+ out[1] = outexp;
+ mp_unexp_d2mp(n, radix, din, &out[2]);
+ outexp = -outexp;
+ din = 1.0 / din;
+ while (din < 1) {
+ din *= radix;
+ outexp--;
+ }
+ out_rev[1] = outexp;
+ mp_unexp_d2mp(n, radix, din, &out_rev[2]);
+}
+
+
+void mp_unexp_d2mp(int n, int radix, double din, int out[])
+{
+ int j, x;
+
+ for (j = 0; j < n; j++) {
+ x = (int) din;
+ if (x >= radix) {
+ x = radix - 1;
+ din = radix;
+ }
+ din = radix * (din - x);
+ out[j] = x;
+ }
+}
+
+
+double mp_unexp_mp2d(int n, int radix, int in[])
+{
+ int j;
+ double d1_radix, dout;
+
+ d1_radix = 1.0 / radix;
+ dout = 0;
+ for (j = n - 1; j >= 0; j--) {
+ dout = d1_radix * dout + in[j];
+ }
+ return dout;
+}
+
+
+int mp_inv_newton(int n, int radix, int in[], int inout[],
+ int tmp1[], int tmp2[], int nfft, double tmp1fft[],
+ double tmp2fft[], int ip[], double w[])
+{
+ void mp_load_1(int n, int radix, int out[]);
+ void mp_round(int n, int radix, int m, int inout[]);
+ void mp_add(int n, int radix, int in1[], int in2[], int out[]);
+ void mp_sub(int n, int radix, int in1[], int in2[], int out[]);
+ void mp_mulh(int n, int radix, int in1[], int in2[], int out[],
+ int nfft, double in1fft[], double outfft[],
+ int ip[], double w[]);
+ void mp_mulh_use_in1fft(int n, int radix, double in1fft[],
+ int shift, int in2[], int out[], int nfft, double outfft[],
+ int ip[], double w[]);
+ int n_h, shift, prc;
+
+ shift = (nfft >> 1) + 1;
+ n_h = n / 2 + 1;
+ if (n_h < n - shift) {
+ n_h = n - shift;
+ }
+ /* ---- tmp1 = inout * (upper) in (half to normal precision) ---- */
+ mp_round(n, radix, shift, inout);
+ mp_mulh(n, radix, inout, in, tmp1,
+ nfft, tmp1fft, tmp2fft, ip, w);
+ /* ---- tmp2 = 1 - tmp1 ---- */
+ mp_load_1(n, radix, tmp2);
+ mp_sub(n, radix, tmp2, tmp1, tmp2);
+ /* ---- tmp2 -= inout * (lower) in (half precision) ---- */
+ mp_mulh_use_in1fft(n, radix, tmp1fft, shift, in, tmp1,
+ nfft, tmp2fft, ip, w);
+ mp_sub(n_h, radix, tmp2, tmp1, tmp2);
+ /* ---- get precision ---- */
+ prc = -tmp2[1];
+ if (tmp2[0] == 0) {
+ prc = nfft + 1;
+ }
+ /* ---- tmp2 *= inout (half precision) ---- */
+ mp_mulh_use_in1fft(n_h, radix, tmp1fft, 0, tmp2, tmp2,
+ nfft, tmp2fft, ip, w);
+ /* ---- inout += tmp2 ---- */
+ if (tmp2[0] != 0) {
+ mp_add(n, radix, inout, tmp2, inout);
+ }
+ return prc;
+}
+
+
+int mp_sqrt_newton(int n, int radix, int in[], int inout[],
+ int inout_rev[], int tmp[], int nfft, double tmp1fft[],
+ double tmp2fft[], int ip[], double w[], int *n_tmp1fft)
+{
+ void mp_round(int n, int radix, int m, int inout[]);
+ void mp_add(int n, int radix, int in1[], int in2[], int out[]);
+ void mp_sub(int n, int radix, int in1[], int in2[], int out[]);
+ void mp_idiv_2(int n, int radix, int in[], int out[]);
+ void mp_mulh(int n, int radix, int in1[], int in2[], int out[],
+ int nfft, double in1fft[], double outfft[],
+ int ip[], double w[]);
+ void mp_squh(int n, int radix, int in[], int out[],
+ int nfft, double inoutfft[], int ip[], double w[]);
+ void mp_squh_use_in1fft(int n, int radix, double inoutfft[], int out[],
+ int nfft, int ip[], double w[]);
+ int n_h, nfft_h, shift, prc;
+
+ nfft_h = nfft >> 1;
+ shift = nfft_h + 1;
+ if (nfft_h < 2) {
+ nfft_h = 2;
+ }
+ n_h = n / 2 + 1;
+ if (n_h < n - shift) {
+ n_h = n - shift;
+ }
+ /* ---- tmp = inout_rev^2 (1/4 to half precision) ---- */
+ mp_round(n_h, radix, (nfft_h >> 1) + 1, inout_rev);
+ if (*n_tmp1fft != nfft_h) {
+ mp_squh(n_h, radix, inout_rev, tmp,
+ nfft_h, tmp1fft, ip, w);
+ } else {
+ mp_squh_use_in1fft(n_h, radix, tmp1fft, tmp,
+ nfft_h, ip, w);
+ }
+ /* ---- tmp = inout_rev - inout * tmp (half precision) ---- */
+ mp_round(n, radix, shift, inout);
+ mp_mulh(n_h, radix, inout, tmp, tmp,
+ nfft, tmp1fft, tmp2fft, ip, w);
+ mp_sub(n_h, radix, inout_rev, tmp, tmp);
+ /* ---- inout_rev += tmp ---- */
+ mp_add(n_h, radix, inout_rev, tmp, inout_rev);
+ /* ---- tmp = in - inout^2 (half to normal precision) ---- */
+ mp_squh_use_in1fft(n, radix, tmp1fft, tmp,
+ nfft, ip, w);
+ mp_sub(n, radix, in, tmp, tmp);
+ /* ---- get precision ---- */
+ prc = in[1] - tmp[1];
+ if (in[2] > tmp[2]) {
+ prc++;
+ }
+ if (tmp[0] == 0) {
+ prc = nfft + 1;
+ }
+ /* ---- tmp = tmp * inout_rev / 2 (half precision) ---- */
+ mp_round(n_h, radix, shift, inout_rev);
+ mp_mulh(n_h, radix, inout_rev, tmp, tmp,
+ nfft, tmp1fft, tmp2fft, ip, w);
+ *n_tmp1fft = nfft;
+ mp_idiv_2(n_h, radix, tmp, tmp);
+ /* ---- inout += tmp ---- */
+ if (tmp[0] != 0) {
+ mp_add(n, radix, inout, tmp, inout);
+ }
+ return prc;
+}
+
+
+/* -------- mp_io routines -------- */
+
+
+void mp_sprintf(int n, int log10_radix, int in[], char out[])
+{
+ int j, k, x, y, outexp, shift;
+
+ if (in[0] < 0) {
+ *out++ = '-';
+ }
+ x = in[2];
+ shift = log10_radix;
+ for (k = log10_radix; k > 0; k--) {
+ y = x % 10;
+ x /= 10;
+ out[k] = '0' + y;
+ if (y != 0) {
+ shift = k;
+ }
+ }
+ out[0] = out[shift];
+ out[1] = '.';
+ for (k = 1; k <= log10_radix - shift; k++) {
+ out[k + 1] = out[k + shift];
+ }
+ outexp = log10_radix - shift;
+ out += outexp + 2;
+ for (j = 3; j <= n + 1; j++) {
+ x = in[j];
+ for (k = log10_radix - 1; k >= 0; k--) {
+ y = x % 10;
+ x /= 10;
+ out[k] = '0' + y;
+ }
+ out += log10_radix;
+ }
+ *out++ = 'e';
+ outexp += log10_radix * in[1];
+ sprintf(out, "%d", outexp);
+}
+
+
+void mp_sscanf(int n, int log10_radix, char in[], int out[])
+{
+ char *s;
+ int j, x, outexp, outexp_mod;
+
+ while (*in == ' ') {
+ in++;
+ }
+ out[0] = 1;
+ if (*in == '-') {
+ out[0] = -1;
+ in++;
+ } else if (*in == '+') {
+ in++;
+ }
+ while (*in == ' ' || *in == '0') {
+ in++;
+ }
+ outexp = 0;
+ for (s = in; *s != '\0'; s++) {
+ if (*s == 'e' || *s == 'E' || *s == 'd' || *s == 'D') {
+ if (sscanf(++s, "%d", &outexp) != 1) {
+ outexp = 0;
+ }
+ break;
+ }
+ }
+ if (*in == '.') {
+ do {
+ outexp--;
+ while (*++in == ' ');
+ } while (*in == '0' && *in != '\0');
+ } else if (*in != '\0') {
+ s = in;
+ while (*++s == ' ');
+ while (*s >= '0' && *s <= '9' && *s != '\0') {
+ outexp++;
+ while (*++s == ' ');
+ }
+ }
+ x = outexp / log10_radix;
+ outexp_mod = outexp - log10_radix * x;
+ if (outexp_mod < 0) {
+ x--;
+ outexp_mod += log10_radix;
+ }
+ out[1] = x;
+ x = 0;
+ j = 2;
+ for (s = in; *s != '\0'; s++) {
+ if (*s == '.' || *s == ' ') {
+ continue;
+ }
+ if (*s < '0' || *s > '9') {
+ break;
+ }
+ x = 10 * x + (*s - '0');
+ if (--outexp_mod < 0) {
+ if (j > n + 1) {
+ break;
+ }
+ out[j++] = x;
+ x = 0;
+ outexp_mod = log10_radix - 1;
+ }
+ }
+ while (outexp_mod-- >= 0) {
+ x *= 10;
+ }
+ while (j <= n + 1) {
+ out[j++] = x;
+ x = 0;
+ }
+ if (out[2] == 0) {
+ out[0] = 0;
+ out[1] = 0;
+ }
+}
+
+
+void mp_fprintf(int n, int log10_radix, int in[], FILE *fout)
+{
+ int j, k, x, y, outexp, shift;
+ char out[256];
+
+ if (in[0] < 0) {
+ putc('-', fout);
+ }
+ x = in[2];
+ shift = log10_radix;
+ for (k = log10_radix; k > 0; k--) {
+ y = x % 10;
+ x /= 10;
+ out[k] = '0' + y;
+ if (y != 0) {
+ shift = k;
+ }
+ }
+ putc(out[shift], fout);
+ putc('.', fout);
+ for (k = 1; k <= log10_radix - shift; k++) {
+ putc(out[k + shift], fout);
+ }
+ outexp = log10_radix - shift;
+ for (j = 3; j <= n + 1; j++) {
+ x = in[j];
+ for (k = log10_radix - 1; k >= 0; k--) {
+ y = x % 10;
+ x /= 10;
+ out[k] = '0' + y;
+ }
+ for (k = 0; k < log10_radix; k++) {
+ putc(out[k], fout);
+ }
+ }
+ putc('e', fout);
+ outexp += log10_radix * in[1];
+ sprintf(out, "%d", outexp);
+ for (k = 0; out[k] != '\0'; k++) {
+ putc(out[k], fout);
+ }
+}
+
+
diff --git a/plugins/supereq/nsfft-1.00/simd/Makefile b/plugins/supereq/nsfft-1.00/simd/Makefile
new file mode 120000
index 00000000..fc484116
--- /dev/null
+++ b/plugins/supereq/nsfft-1.00/simd/Makefile
@@ -0,0 +1 @@
+Makefile.x86 \ No newline at end of file
diff --git a/plugins/supereq/nsfft-1.00/simd/Makefile.altivec b/plugins/supereq/nsfft-1.00/simd/Makefile.altivec
new file mode 100644
index 00000000..eeaed6a1
--- /dev/null
+++ b/plugins/supereq/nsfft-1.00/simd/Makefile.altivec
@@ -0,0 +1,26 @@
+CC=gcc
+BASEOPT=-Wall -maltivec -mabi=altivec
+OPT=$(BASEOPT) -O3
+
+all : libSIMD.a
+
+SIMDBaseUndiff_purecfloat.o : SIMDBaseUndiff.c SIMDBase.h SIMDBaseUndiff.h
+ $(CC) $(OPT) -DENABLE_PUREC_FLOAT SIMDBaseUndiff.c -c -o SIMDBaseUndiff_purecfloat.o
+
+SIMDBaseUndiff_purecdouble.o : SIMDBaseUndiff.c SIMDBase.h SIMDBaseUndiff.h
+ $(CC) $(OPT) -DENABLE_PUREC_DOUBLE SIMDBaseUndiff.c -c -o SIMDBaseUndiff_purecdouble.o
+
+SIMDBaseUndiff_pureclongdouble.o : SIMDBaseUndiff.c SIMDBase.h SIMDBaseUndiff.h
+ $(CC) $(OPT) -DENABLE_PUREC_LONGDOUBLE SIMDBaseUndiff.c -c -o SIMDBaseUndiff_pureclongdouble.o
+
+SIMDBaseUndiff_altivecfloat.o : SIMDBaseUndiff.c SIMDBase.h SIMDBaseUndiff.h
+ $(CC) $(OPT) -DENABLE_ALTIVEC_FLOAT SIMDBaseUndiff.c -c -o SIMDBaseUndiff_altivecfloat.o
+
+SIMDBase.o : SIMDBase.c SIMDBase.h
+ $(CC) $(BASEOPT) -O -DENABLE_PUREC_FLOAT -DENABLE_PUREC_DOUBLE -DENABLE_PUREC_LONGDOUBLE -DENABLE_ALTIVEC_FLOAT SIMDBase.c -c -o SIMDBase.o
+
+libSIMD.a : SIMDBase.o SIMDBaseUndiff_purecfloat.o SIMDBaseUndiff_purecdouble.o SIMDBaseUndiff_pureclongdouble.o SIMDBaseUndiff_altivecfloat.o
+ rm -f libSIMD.a; ar -cvq libSIMD.a SIMDBase.o SIMDBaseUndiff_purecfloat.o SIMDBaseUndiff_purecdouble.o SIMDBaseUndiff_pureclongdouble.o SIMDBaseUndiff_altivecfloat.o
+
+clean :
+ rm -f *~ *.o *.s *.a
diff --git a/plugins/supereq/nsfft-1.00/simd/Makefile.neon b/plugins/supereq/nsfft-1.00/simd/Makefile.neon
new file mode 100644
index 00000000..ace704f1
--- /dev/null
+++ b/plugins/supereq/nsfft-1.00/simd/Makefile.neon
@@ -0,0 +1,26 @@
+CC=gcc
+BASEOPT=-Wall -mfloat-abi=softfp
+OPT=$(BASEOPT) -O3
+
+all : libSIMD.a
+
+SIMDBaseUndiff_purecfloat.o : SIMDBaseUndiff.c SIMDBase.h SIMDBaseUndiff.h
+ $(CC) $(OPT) -DENABLE_PUREC_FLOAT SIMDBaseUndiff.c -c -o SIMDBaseUndiff_purecfloat.o
+
+SIMDBaseUndiff_purecdouble.o : SIMDBaseUndiff.c SIMDBase.h SIMDBaseUndiff.h
+ $(CC) $(OPT) -DENABLE_PUREC_DOUBLE SIMDBaseUndiff.c -c -o SIMDBaseUndiff_purecdouble.o
+
+SIMDBaseUndiff_pureclongdouble.o : SIMDBaseUndiff.c SIMDBase.h SIMDBaseUndiff.h
+ $(CC) $(OPT) -DENABLE_PUREC_LONGDOUBLE SIMDBaseUndiff.c -c -o SIMDBaseUndiff_pureclongdouble.o
+
+SIMDBaseUndiff_neonfloat.o : SIMDBaseUndiff.c SIMDBase.h SIMDBaseUndiff.h
+ $(CC) $(OPT) -mfpu=neon -DENABLE_NEON_FLOAT SIMDBaseUndiff.c -c -o SIMDBaseUndiff_neonfloat.o
+
+SIMDBase.o : SIMDBase.c SIMDBase.h
+ $(CC) $(BASEOPT) -O -DENABLE_PUREC_FLOAT -DENABLE_PUREC_DOUBLE -DENABLE_PUREC_LONGDOUBLE -DENABLE_NEON_FLOAT SIMDBase.c -c -o SIMDBase.o
+
+libSIMD.a : SIMDBase.o SIMDBaseUndiff_purecfloat.o SIMDBaseUndiff_purecdouble.o SIMDBaseUndiff_pureclongdouble.o SIMDBaseUndiff_neonfloat.o
+ rm -f libSIMD.a; ar -cvq libSIMD.a SIMDBase.o SIMDBaseUndiff_purecfloat.o SIMDBaseUndiff_purecdouble.o SIMDBaseUndiff_pureclongdouble.o SIMDBaseUndiff_neonfloat.o
+
+clean :
+ rm -f *~ *.o *.s *.a
diff --git a/plugins/supereq/nsfft-1.00/simd/Makefile.purec b/plugins/supereq/nsfft-1.00/simd/Makefile.purec
new file mode 100644
index 00000000..2c8b04f1
--- /dev/null
+++ b/plugins/supereq/nsfft-1.00/simd/Makefile.purec
@@ -0,0 +1,35 @@
+CC=gcc
+BASEOPT=-Wall
+OPT=$(BASEOPT) -O3
+
+all : libDFT.a
+
+DFTpurecfloat.o : DFTUndiff.c DFT.h SIMDBase.h
+ $(CC) $(OPT) -DENABLE_PUREC_FLOAT DFTUndiff.c -c -o DFTpurecfloat.o
+
+DFTpurecdouble.o : DFTUndiff.c DFT.h SIMDBase.h
+ $(CC) $(OPT) -DENABLE_PUREC_DOUBLE DFTUndiff.c -c -o DFTpurecdouble.o
+
+DFTpureclongdouble.o : DFTUndiff.c DFT.h SIMDBase.h
+ $(CC) $(OPT) -DENABLE_PUREC_LONGDOUBLE DFTUndiff.c -c -o DFTpureclongdouble.o
+
+SIMDBaseUndiff_purecfloat.o : SIMDBaseUndiff.c SIMDBase.h SIMDBaseUndiff.h
+ $(CC) $(OPT) -DENABLE_PUREC_FLOAT SIMDBaseUndiff.c -c -o SIMDBaseUndiff_purecfloat.o
+
+SIMDBaseUndiff_purecdouble.o : SIMDBaseUndiff.c DFT.h SIMDBase.h SIMDBaseUndiff.h
+ $(CC) $(OPT) -DENABLE_PUREC_DOUBLE SIMDBaseUndiff.c -c -o SIMDBaseUndiff_purecdouble.o
+
+SIMDBaseUndiff_pureclongdouble.o : SIMDBaseUndiff.c SIMDBase.h SIMDBaseUndiff.h
+ $(CC) $(OPT) -DENABLE_PUREC_LONGDOUBLE SIMDBaseUndiff.c -c -o SIMDBaseUndiff_pureclongdouble.o
+
+SIMDBase.o : SIMDBase.c SIMDBase.h
+ $(CC) $(BASEOPT) -O -DENABLE_PUREC_FLOAT -DENABLE_PUREC_DOUBLE -DENABLE_PUREC_LONGDOUBLE SIMDBase.c -c -o SIMDBase.o
+
+DFT.o : DFT.c DFT.h
+ $(CC) $(OPT) -DENABLE_PUREC_FLOAT -DENABLE_PUREC_DOUBLE -DENABLE_PUREC_LONGDOUBLE DFT.c -c -o DFT.o
+
+libDFT.a : DFTpurecfloat.o DFTpurecdouble.o DFTpureclongdouble.o DFT.o SIMDBase.o SIMDBaseUndiff_purecfloat.o SIMDBaseUndiff_purecdouble.o SIMDBaseUndiff_pureclongdouble.o
+ rm -f libDFT.a; ar -cvq libDFT.a DFTpurecfloat.o DFTpurecdouble.o DFTpureclongdouble.o DFT.o SIMDBase.o SIMDBaseUndiff_purecfloat.o SIMDBaseUndiff_purecdouble.o SIMDBaseUndiff_pureclongdouble.o
+
+clean :
+ rm -f *~ *.o *.s *.a
diff --git a/plugins/supereq/nsfft-1.00/simd/Makefile.x86 b/plugins/supereq/nsfft-1.00/simd/Makefile.x86
new file mode 100644
index 00000000..02f49610
--- /dev/null
+++ b/plugins/supereq/nsfft-1.00/simd/Makefile.x86
@@ -0,0 +1,35 @@
+CC=gcc
+BASEOPT=-Wall
+OPT=$(BASEOPT) -O3
+
+all : libSIMD.a
+
+SIMDBaseUndiff_purecfloat.o : SIMDBaseUndiff.c SIMDBase.h SIMDBaseUndiff.h
+ $(CC) $(OPT) -DENABLE_PUREC_FLOAT SIMDBaseUndiff.c -c -o SIMDBaseUndiff_purecfloat.o
+
+SIMDBase_purecdouble.o : SIMDBaseUndiff.c SIMDBase.h SIMDBaseUndiff.h
+ $(CC) $(OPT) -DENABLE_PUREC_DOUBLE SIMDBaseUndiff.c -c -o SIMDBase_purecdouble.o
+
+SIMDBase_pureclongdouble.o : SIMDBaseUndiff.c SIMDBase.h SIMDBaseUndiff.h
+ $(CC) $(OPT) -DENABLE_PUREC_LONGDOUBLE SIMDBaseUndiff.c -c -o SIMDBase_pureclongdouble.o
+
+SIMDBase_ssefloat.o : SIMDBaseUndiff.c SIMDBase.h SIMDBaseUndiff.h
+ $(CC) $(OPT) -msse -DENABLE_SSE_FLOAT SIMDBaseUndiff.c -c -o SIMDBase_ssefloat.o
+
+SIMDBase_sse2double.o : SIMDBaseUndiff.c SIMDBase.h SIMDBaseUndiff.h
+ $(CC) $(OPT) -msse2 -DENABLE_SSE2_DOUBLE SIMDBaseUndiff.c -c -o SIMDBase_sse2double.o
+
+SIMDBase_avxfloat.o : SIMDBaseUndiff.c SIMDBase.h SIMDBaseUndiff.h
+ $(CC) $(OPT) -mavx -DENABLE_AVX_FLOAT SIMDBaseUndiff.c -c -o SIMDBase_avxfloat.o
+
+SIMDBase_avxdouble.o : SIMDBaseUndiff.c SIMDBase.h SIMDBaseUndiff.h
+ $(CC) $(OPT) -mavx -DENABLE_AVX_DOUBLE SIMDBaseUndiff.c -c -o SIMDBase_avxdouble.o
+
+SIMDBase.o : SIMDBase.c SIMDBase.h
+ $(CC) $(BASEOPT) -O -DENABLE_PUREC_FLOAT -DENABLE_PUREC_DOUBLE -DENABLE_PUREC_LONGDOUBLE -DENABLE_SSE_FLOAT -DENABLE_SSE2_DOUBLE SIMDBase.c -c -o SIMDBase.o
+
+libSIMD.a : SIMDBase.o SIMDBaseUndiff_purecfloat.o SIMDBase_purecdouble.o SIMDBase_pureclongdouble.o SIMDBase_ssefloat.o SIMDBase_sse2double.o
+ rm -f libSIMD.a; ar -cvq libSIMD.a SIMDBase.o SIMDBaseUndiff_purecfloat.o SIMDBase_purecdouble.o SIMDBase_pureclongdouble.o SIMDBase_ssefloat.o SIMDBase_sse2double.o
+
+clean :
+ rm -f *~ *.o *.s *.a a.out
diff --git a/plugins/supereq/nsfft-1.00/simd/Makefile.x86avx b/plugins/supereq/nsfft-1.00/simd/Makefile.x86avx
new file mode 100644
index 00000000..d9d27a2e
--- /dev/null
+++ b/plugins/supereq/nsfft-1.00/simd/Makefile.x86avx
@@ -0,0 +1,35 @@
+CC=gcc
+BASEOPT=-Wall
+OPT=$(BASEOPT) -O3
+
+all : libSIMD.a
+
+SIMDBaseUndiff_purecfloat.o : SIMDBaseUndiff.c SIMDBase.h SIMDBaseUndiff.h
+ $(CC) $(OPT) -DENABLE_PUREC_FLOAT SIMDBaseUndiff.c -c -o SIMDBaseUndiff_purecfloat.o
+
+SIMDBaseUndiff_purecdouble.o : SIMDBaseUndiff.c SIMDBase.h SIMDBaseUndiff.h
+ $(CC) $(OPT) -DENABLE_PUREC_DOUBLE SIMDBaseUndiff.c -c -o SIMDBaseUndiff_purecdouble.o
+
+SIMDBaseUndiff_pureclongdouble.o : SIMDBaseUndiff.c SIMDBase.h SIMDBaseUndiff.h
+ $(CC) $(OPT) -DENABLE_PUREC_LONGDOUBLE SIMDBaseUndiff.c -c -o SIMDBaseUndiff_pureclongdouble.o
+
+SIMDBaseUndiff_ssefloat.o : SIMDBaseUndiff.c SIMDBase.h SIMDBaseUndiff.h
+ $(CC) $(OPT) -msse -DENABLE_SSE_FLOAT SIMDBaseUndiff.c -c -o SIMDBaseUndiff_ssefloat.o
+
+SIMDBaseUndiff_sse2double.o : SIMDBaseUndiff.c SIMDBase.h SIMDBaseUndiff.h
+ $(CC) $(OPT) -msse2 -DENABLE_SSE2_DOUBLE SIMDBaseUndiff.c -c -o SIMDBaseUndiff_sse2double.o
+
+SIMDBaseUndiff_avxfloat.o : SIMDBaseUndiff.c SIMDBase.h SIMDBaseUndiff.h
+ $(CC) $(OPT) -mavx -DENABLE_AVX_FLOAT SIMDBaseUndiff.c -c -o SIMDBaseUndiff_avxfloat.o
+
+SIMDBaseUndiff_avxdouble.o : SIMDBaseUndiff.c SIMDBase.h SIMDBaseUndiff.h
+ $(CC) $(OPT) -mavx -DENABLE_AVX_DOUBLE SIMDBaseUndiff.c -c -o SIMDBaseUndiff_avxdouble.o
+
+SIMDBase.o : SIMDBase.c SIMDBase.h
+ $(CC) $(BASEOPT) -O -DENABLE_PUREC_FLOAT -DENABLE_PUREC_DOUBLE -DENABLE_PUREC_LONGDOUBLE -DENABLE_SSE_FLOAT -DENABLE_SSE2_DOUBLE -DENABLE_AVX_FLOAT -DENABLE_AVX_DOUBLE SIMDBase.c -c -o SIMDBase.o
+
+libSIMD.a : SIMDBase.o SIMDBaseUndiff_purecfloat.o SIMDBaseUndiff_purecdouble.o SIMDBaseUndiff_pureclongdouble.o SIMDBaseUndiff_ssefloat.o SIMDBaseUndiff_sse2double.o SIMDBaseUndiff_avxfloat.o SIMDBaseUndiff_avxdouble.o
+ rm -f libSIMD.a; ar -cvq libSIMD.a SIMDBase.o SIMDBaseUndiff_purecfloat.o SIMDBaseUndiff_purecdouble.o SIMDBaseUndiff_pureclongdouble.o SIMDBaseUndiff_ssefloat.o SIMDBaseUndiff_sse2double.o SIMDBaseUndiff_avxfloat.o SIMDBaseUndiff_avxdouble.o
+
+clean :
+ rm -f *~ *.o *.s *.a a.out
diff --git a/plugins/supereq/nsfft-1.00/simd/SIMDBase.c b/plugins/supereq/nsfft-1.00/simd/SIMDBase.c
new file mode 100644
index 00000000..eb51ee10
--- /dev/null
+++ b/plugins/supereq/nsfft-1.00/simd/SIMDBase.c
@@ -0,0 +1,454 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <stdint.h>
+#include <signal.h>
+#include <setjmp.h>
+#include <string.h>
+
+#include "SIMDBase.h"
+
+void detect_purec_float(void);
+void detect_purec_double(void);
+void detect_purec_longdouble(void);
+void detect_sse_float(void);
+void detect_sse2_double(void);
+void detect_neon_float(void);
+void detect_avx_float(void);
+void detect_avx_double(void);
+void detect_altivec_float(void);
+
+int32_t getModeParamInt_purec_float(int32_t paramId);
+int32_t getModeParamInt_purec_double(int32_t paramId);
+int32_t getModeParamInt_purec_longdouble(int32_t paramId);
+int32_t getModeParamInt_sse_float(int32_t paramId);
+int32_t getModeParamInt_sse2_double(int32_t paramId);
+int32_t getModeParamInt_neon_float(int32_t paramId);
+int32_t getModeParamInt_avx_float(int32_t paramId);
+int32_t getModeParamInt_avx_double(int32_t paramId);
+int32_t getModeParamInt_altivec_float(int32_t paramId);
+
+char * getModeParamString_purec_float(int32_t paramId);
+char * getModeParamString_purec_double(int32_t paramId);
+char * getModeParamString_purec_longdouble(int32_t paramId);
+char * getModeParamString_sse_float(int32_t paramId);
+char * getModeParamString_sse2_double(int32_t paramId);
+char * getModeParamString_neon_float(int32_t paramId);
+char * getModeParamString_avx_float(int32_t paramId);
+char * getModeParamString_avx_double(int32_t paramId);
+char * getModeParamString_altivec_float(int32_t paramId);
+
+uint8_t detectBuffer[256];
+char SIMDBase_processorNameString[256];
+
+static char *startsWith(char *str1, char *str2) {
+ if (strncmp(str1, str2, strlen(str2)) == 0) {
+ return str1 + strlen(str2);
+ }
+
+ return NULL;
+}
+
+#if defined(__linux__)
+static char *tryReadingProcCpuinfo(char *entry) {
+ int i;
+
+ FILE *fp = fopen("/proc/cpuinfo", "r");
+ if (fp == NULL) return NULL;
+
+ for(i=0;i<100;i++) {
+ char *q;
+ bzero(SIMDBase_processorNameString, 256);
+ if (fgets(SIMDBase_processorNameString, 255, fp) == NULL) break;
+
+ if ((q = startsWith(SIMDBase_processorNameString, entry)) != NULL) {
+ int j;
+ fclose(fp);
+
+ for(j=0;j<256;j++) {
+ if (SIMDBase_processorNameString[j] == '\n') SIMDBase_processorNameString[j] = ' ';
+ }
+ while(*q != '\0' && *q != ':' && q - SIMDBase_processorNameString < 200) q++;
+ if (q - SIMDBase_processorNameString >= 200) return NULL;
+ if (*q == ':' && *(q+1) == ' ') return q + 2;
+ return NULL;
+ }
+ }
+
+ fclose(fp);
+ return NULL;
+}
+#else
+static char *tryReadingProcCpuinfo(char *entry) { return NULL; }
+#endif
+
+#if defined(__i386__)
+static void SIMDBase_x86cpuid(uint32_t out[4], uint32_t eax, uint32_t ecx) {
+ uint32_t a, b, c, d;
+ __asm__ __volatile__("pushl %%eax; \n\t"
+ "pushl %%ebx; \n\t"
+ "pushl %%ecx; \n\t"
+ "pushl %%edx; \n\t"
+ "cpuid; \n\t"
+ "movl %%eax, %0; \n\t"
+ "movl %%ebx, %1; \n\t"
+ "movl %%ecx, %2; \n\t"
+ "movl %%edx, %3; \n\t"
+ "popl %%edx; \n\t"
+ "popl %%ecx; \n\t"
+ "popl %%ebx; \n\t"
+ "popl %%eax; \n\t"
+ : "=m"(a), "=m"(b), "=m"(c), "=m"(d)
+ : "a"(eax), "c"(ecx)
+ : "cc");
+ out[0] = a; out[1] = b; out[2] = c; out[3] = d;
+}
+#endif
+
+#if defined(__x86_64__)
+static void SIMDBase_x86cpuid(uint32_t out[4], uint32_t eax, uint32_t ecx) {
+ uint32_t a, b, c, d;
+ __asm__ __volatile__ ("cpuid" : "=a" (a), "=b" (b), "=c" (c), "=d" (d) : "a" (eax), "c"(ecx));
+ out[0] = a; out[1] = b; out[2] = c; out[3] = d;
+}
+#endif
+
+#if defined(__i386__) || defined(__x86_64__)
+static void getCacheParam(CacheParam *p) {
+ static int l2assoc[] = {0,1,2,0,4,0,8,0,16,0,32,48,64,96,128,-1};
+ int32_t i;
+ uint32_t out[4];
+
+ for(i=0;i<8;i++) {
+ p->size[i] = p->assoc[i] = 0;
+ }
+
+ SIMDBase_x86cpuid(out, 4, 0);
+
+ if ((out[0] & 0xf) != 0) {
+ p->linesize = ((out[1] >> 0) & 2047)+1;
+ for(i=0;i<8;i++) {
+ SIMDBase_x86cpuid(out, 4, i);
+ if ((out[0] & 0xf) == 0) break;
+ int level = (out[0] >> 5) & 0x7;
+ int type = (out[0] >> 0) & 0xf;
+ int assoc = ((out[1] >> 22) & 1023)+1;
+ int part = ((out[1] >> 12) & 1023)+1;
+ int lsize = ((out[1] >> 0) & 2047)+1;
+ int nsets = ((out[2] >> 0))+1;
+ int nthre = ((out[0] >> 14) & 1023)+1;
+
+ if (type != 1 && type != 3) continue;
+ p->assoc[level-1] = assoc;
+ p->size[level-1] = (uint64_t)assoc * part * lsize * nsets / nthre;
+ }
+ } else {
+ SIMDBase_x86cpuid(out, 0x80000008U, 0);
+ int ncores = (out[2] & 0xff) + 1;
+
+ SIMDBase_x86cpuid(out, 0x80000005U, 0);
+ p->linesize = out[2] & 255;
+ p->size[0] = (out[2] >> 24) * 1024 / ncores;
+ p->assoc[0] = (out[2] >> 16) & 0xff;
+
+ SIMDBase_x86cpuid(out, 0x80000006U, 0);
+ p->size[1] = (out[2] >> 16) * 1024 / ncores;
+ p->assoc[1] = l2assoc[(out[2] >> 12) & 0xf];
+ p->size[2] = (out[3] >> 18) * 512 * 1024 / ncores;
+ p->assoc[2] = l2assoc[(out[3] >> 12) & 0xf];
+ }
+
+ if (p->size[0] == 0) {
+ p->size[0] = 16 * 1024;
+ p->assoc[0] = 4;
+ }
+
+ if (p->size[1] == 0) {
+ p->size[1] = 256 * 1024;
+ p->assoc[1] = 4;
+ }
+}
+
+char *SIMDBase_getProcessorNameString() {
+ union {
+ uint32_t info[4];
+ uint8_t str[16];
+ } u;
+ int i,j;
+ char *p;
+
+ p = SIMDBase_processorNameString;
+
+ SIMDBase_x86cpuid(u.info, 0, 0);
+
+ for(i=0;i<4;i++) *p++ = u.str[i+4];
+ for(i=0;i<4;i++) *p++ = u.str[i+12];
+ for(i=0;i<4;i++) *p++ = u.str[i+8];
+
+ *p++ = ' ';
+
+ for(i=0;i<3;i++) {
+ SIMDBase_x86cpuid(u.info, i + 0x80000002, 0);
+
+ for(j=0;j<16;j++) {
+ *p++ = u.str[j];
+ }
+ }
+
+ *p++ = '\n';
+
+ return SIMDBase_processorNameString;
+}
+#else
+char *SIMDBase_getProcessorNameString() {
+ char *p = "Unknown";
+#if defined(__powerpc__)
+ if ((p = tryReadingProcCpuinfo("cpu")) == NULL) p = "PowerPC";
+#elif defined(__arm__)
+ if ((p = tryReadingProcCpuinfo("Processor")) == NULL) p = "ARM";
+#endif
+
+ return p;
+}
+#endif
+
+int32_t SIMDBase_sizeOfCachelineInByte() {
+#if defined(__i386__) || defined(__x86_64__)
+ CacheParam p;
+ getCacheParam(&p);
+ return p.linesize;
+#else
+ return 64;
+#endif
+}
+
+int32_t SIMDBase_sizeOfDataCacheInByte() {
+#if defined(__i386__) || defined(__x86_64__)
+ CacheParam p;
+ getCacheParam(&p);
+ return p.size[1] + p.size[2]; // L2 + L3
+#else
+ return 256 * 1024;
+#endif
+}
+
+static jmp_buf sigjmp;
+
+static void sighandler(int signum) {
+ longjmp(sigjmp, 1);
+}
+
+int32_t SIMDBase_detect(int32_t paramId) {
+#if defined(__i386__) || defined(__x86_64__)
+ uint32_t reg[4];
+#endif
+
+ switch(paramId) {
+ case SIMDBase_MODE_PUREC_FLOAT:
+#if defined(ENABLE_PUREC_FLOAT)
+ return 1;
+#else
+ return -1;
+#endif
+ case SIMDBase_MODE_PUREC_DOUBLE:
+#if defined(ENABLE_PUREC_DOUBLE)
+ return 1;
+#else
+ return -1;
+#endif
+ case SIMDBase_MODE_PUREC_LONGDOUBLE:
+#if defined(ENABLE_PUREC_LONGDOUBLE)
+ return 1;
+#else
+ return -1;
+#endif
+ case SIMDBase_MODE_SSE_FLOAT:
+#if defined(ENABLE_SSE_FLOAT)
+ SIMDBase_x86cpuid(reg, 1, 0);
+ return (reg[3] & (1 << 25)) != 0;
+#else
+ return -1;
+#endif
+ case SIMDBase_MODE_SSE2_DOUBLE:
+#if defined(ENABLE_SSE2_DOUBLE)
+ SIMDBase_x86cpuid(reg, 1, 0);
+ return (reg[3] & (1 << 26)) != 0;
+#else
+ return -1;
+#endif
+ case SIMDBase_MODE_AVX_FLOAT:
+#if defined(ENABLE_AVX_FLOAT)
+ SIMDBase_x86cpuid(reg, 1, 0);
+ return (reg[2] & (1 << 28)) != 0;
+#else
+ return -1;
+#endif
+ case SIMDBase_MODE_AVX_DOUBLE:
+#if defined(ENABLE_AVX_DOUBLE)
+ SIMDBase_x86cpuid(reg, 1, 0);
+ return (reg[2] & (1 << 28)) != 0;
+#else
+ return -1;
+#endif
+ default:
+ break;
+ }
+
+ signal(SIGILL, sighandler);
+
+ if (setjmp(sigjmp) == 0) {
+ switch(paramId) {
+#if defined(ENABLE_NEON_FLOAT)
+ case SIMDBase_MODE_NEON_FLOAT:
+ detect_neon_float();
+ break;
+#endif
+#if defined(ENABLE_ALTIVEC_FLOAT)
+ case SIMDBase_MODE_ALTIVEC_FLOAT:
+ detect_altivec_float();
+ break;
+#endif
+ default:
+ signal(SIGILL, SIG_DFL);
+ return -1;
+ }
+ signal(SIGILL, SIG_DFL);
+ return 1;
+ } else {
+ signal(SIGILL, SIG_DFL);
+ return 0;
+ }
+}
+
+int32_t SIMDBase_chooseBestMode(int32_t typeId) {
+ switch(typeId) {
+ case SIMDBase_TYPE_HALF:
+ break;
+ case SIMDBase_TYPE_FLOAT:
+ if (SIMDBase_detect(SIMDBase_MODE_AVX_FLOAT) == 1) return SIMDBase_MODE_AVX_FLOAT;
+ if (SIMDBase_detect(SIMDBase_MODE_SSE_FLOAT) == 1) return SIMDBase_MODE_SSE_FLOAT;
+ if (SIMDBase_detect(SIMDBase_MODE_NEON_FLOAT) == 1) return SIMDBase_MODE_NEON_FLOAT;
+ if (SIMDBase_detect(SIMDBase_MODE_ALTIVEC_FLOAT) == 1) return SIMDBase_MODE_ALTIVEC_FLOAT;
+ if (SIMDBase_detect(SIMDBase_MODE_PUREC_FLOAT) == 1) return SIMDBase_MODE_PUREC_FLOAT;
+ break;
+
+ case SIMDBase_TYPE_DOUBLE:
+ if (SIMDBase_detect(SIMDBase_MODE_AVX_DOUBLE) == 1) return SIMDBase_MODE_AVX_DOUBLE;
+ if (SIMDBase_detect(SIMDBase_MODE_SSE2_DOUBLE) == 1) return SIMDBase_MODE_SSE2_DOUBLE;
+ if (SIMDBase_detect(SIMDBase_MODE_PUREC_DOUBLE) == 1) return SIMDBase_MODE_PUREC_DOUBLE;
+ break;
+
+ case SIMDBase_TYPE_LONGDOUBLE:
+ if (SIMDBase_detect(SIMDBase_MODE_PUREC_LONGDOUBLE) == 1) return SIMDBase_MODE_PUREC_LONGDOUBLE;
+ break;
+
+ case SIMDBase_TYPE_EXTENDED:
+ break;
+
+ case SIMDBase_TYPE_QUAD:
+ break;
+ }
+
+ return SIMDBase_MODE_NONE;
+}
+
+int32_t SIMDBase_getModeParamInt(int32_t paramId, int32_t mode) {
+ switch(mode) {
+#if defined(ENABLE_PUREC_FLOAT)
+ case 1: return getModeParamInt_purec_float(paramId); break;
+#endif
+#if defined(ENABLE_PUREC_DOUBLE)
+ case 2: return getModeParamInt_purec_double(paramId); break;
+#endif
+#if defined(ENABLE_PUREC_LONGDOUBLE)
+ case 3: return getModeParamInt_purec_longdouble(paramId); break;
+#endif
+#if defined(ENABLE_SSE_FLOAT)
+ case 4: return getModeParamInt_sse_float(paramId); break;
+#endif
+#if defined(ENABLE_SSE2_DOUBLE)
+ case 5: return getModeParamInt_sse2_double(paramId); break;
+#endif
+#if defined(ENABLE_NEON_FLOAT)
+ case 6: return getModeParamInt_neon_float(paramId); break;
+#endif
+#if defined(ENABLE_AVX_FLOAT)
+ case 7: return getModeParamInt_avx_float(paramId); break;
+#endif
+#if defined(ENABLE_AVX_DOUBLE)
+ case 8: return getModeParamInt_avx_double(paramId); break;
+#endif
+#if defined(ENABLE_ALTIVEC_FLOAT)
+ case 9: return getModeParamInt_altivec_float(paramId); break;
+#endif
+ }
+
+ return -1;
+}
+
+char *SIMDBase_getModeParamString(int32_t paramId, int32_t mode) {
+ switch(mode) {
+#if defined(ENABLE_PUREC_FLOAT)
+ case 1: return getModeParamString_purec_float(paramId); break;
+#endif
+#if defined(ENABLE_PUREC_DOUBLE)
+ case 2: return getModeParamString_purec_double(paramId); break;
+#endif
+#if defined(ENABLE_PUREC_LONGDOUBLE)
+ case 3: return getModeParamString_purec_longdouble(paramId); break;
+#endif
+#if defined(ENABLE_SSE_FLOAT)
+ case 4: return getModeParamString_sse_float(paramId); break;
+#endif
+#if defined(ENABLE_SSE2_DOUBLE)
+ case 5: return getModeParamString_sse2_double(paramId); break;
+#endif
+#if defined(ENABLE_NEON_FLOAT)
+ case 6: return getModeParamString_neon_float(paramId); break;
+#endif
+#if defined(ENABLE_AVX_FLOAT)
+ case 7: return getModeParamString_avx_float(paramId); break;
+#endif
+#if defined(ENABLE_AVX_DOUBLE)
+ case 8: return getModeParamString_avx_double(paramId); break;
+#endif
+#if defined(ENABLE_ALTIVEC_FLOAT)
+ case 9: return getModeParamString_altivec_float(paramId); break;
+#endif
+ }
+
+ return NULL;
+}
+
+#ifdef ANDROID
+int posix_memalign (void **memptr, size_t alignment, size_t size) {
+ *memptr = malloc (size);
+ return *memptr ? 0 : -1;
+}
+#endif
+
+void *SIMDBase_alignedMalloc(uint64_t size) {
+ void *p;
+ if (posix_memalign(&p, SIMDBase_sizeOfCachelineInByte(), size) != 0) abort();
+ return p;
+}
+
+void SIMDBase_alignedFree(void *ptr) {
+ free(ptr);
+}
+
+int32_t SIMDBase_getParamInt(int32_t paramId) {
+ switch(paramId) {
+ case SIMDBase_PARAMID_MODE_MAX:
+ return SIMDBase_LAST_MODE + 1;
+ }
+
+ return -1;
+}
+
+int32_t SIMDBase_getTypeParamInt(int32_t paramId, int32_t typeId) {
+ switch(typeId) {
+ }
+
+ return -1;
+}
diff --git a/plugins/supereq/nsfft-1.00/simd/SIMDBase.h b/plugins/supereq/nsfft-1.00/simd/SIMDBase.h
new file mode 100644
index 00000000..10cdeb81
--- /dev/null
+++ b/plugins/supereq/nsfft-1.00/simd/SIMDBase.h
@@ -0,0 +1,53 @@
+#ifndef _SIMDBase_H_
+#define _SIMDBase_H_
+
+#include <stdint.h>
+
+#define SIMDBase_TYPE_FLOAT ( 1 | ( 1 << 24 ))
+#define SIMDBase_TYPE_DOUBLE ( 2 | ( 1 << 24 ))
+#define SIMDBase_TYPE_LONGDOUBLE ( 3 | ( 1 << 24 ))
+#define SIMDBase_TYPE_EXTENDED ( 4 | ( 1 << 24 ))
+#define SIMDBase_TYPE_QUAD ( 5 | ( 1 << 24 ))
+#define SIMDBase_TYPE_HALF ( 6 | ( 1 << 24 ))
+
+#define SIMDBase_MODE_NONE 0
+#define SIMDBase_MODE_PUREC_FLOAT 1
+#define SIMDBase_MODE_PUREC_DOUBLE 2
+#define SIMDBase_MODE_PUREC_LONGDOUBLE 3
+#define SIMDBase_MODE_SSE_FLOAT 4
+#define SIMDBase_MODE_SSE2_DOUBLE 5
+#define SIMDBase_MODE_NEON_FLOAT 6
+#define SIMDBase_MODE_AVX_FLOAT 7
+#define SIMDBase_MODE_AVX_DOUBLE 8
+#define SIMDBase_MODE_ALTIVEC_FLOAT 9
+
+#define SIMDBase_LAST_MODE SIMDBase_MODE_ALTIVEC_FLOAT
+
+#define SIMDBase_PARAMID_MODE_MAX ( 1 | ( 2 << 24 ))
+#define SIMDBase_PARAMID_TYPE_AVAILABILITY ( 2 | ( 2 << 24 ))
+#define SIMDBase_PARAMID_SIZE_OF_REAL ( 3 | ( 2 << 24 ))
+#define SIMDBase_PARAMID_SIZE_OF_VECT ( 4 | ( 2 << 24 ))
+#define SIMDBase_PARAMID_VECTOR_LEN ( 5 | ( 2 << 24 ))
+#define SIMDBase_PARAMID_MODE_AVAILABILITY ( 6 | ( 2 << 24 ))
+#define SIMDBase_PARAMID_MODE_NAME ( 7 | ( 2 << 24 ))
+
+//
+
+typedef struct {
+ uint32_t linesize;
+ uint32_t size[8], assoc[8];
+} CacheParam;
+
+void *SIMDBase_alignedMalloc(uint64_t size);
+void SIMDBase_alignedFree(void *ptr);
+int32_t SIMDBase_sizeOfCachelineInByte();
+int32_t SIMDBase_sizeOfDataCacheInByte();
+int32_t SIMDBase_chooseBestMode(int32_t typeId);
+char *SIMDBase_getProcessorNameString();
+int32_t SIMDBase_detect(int32_t paramId);
+int32_t SIMDBase_getParamInt(int32_t paramId);
+int32_t SIMDBase_getTypeParamInt(int32_t paramId, int32_t typeId);
+int32_t SIMDBase_getModeParamInt(int32_t paramId, int32_t mode);
+char *SIMDBase_getModeParamString(int32_t paramId, int32_t mode);
+
+#endif
diff --git a/plugins/supereq/nsfft-1.00/simd/SIMDBaseUndiff.c b/plugins/supereq/nsfft-1.00/simd/SIMDBaseUndiff.c
new file mode 100644
index 00000000..257a5ff0
--- /dev/null
+++ b/plugins/supereq/nsfft-1.00/simd/SIMDBaseUndiff.c
@@ -0,0 +1,38 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+#include "SIMDBase.h"
+#include "SIMDBaseUndiff.h"
+
+void SIMDBaseUndiff_DETECT() {
+ extern uint8_t detectBuffer[256];
+ SIMDBase_VECT a = SIMDBase_LOAD((SIMDBase_VECT *)&detectBuffer[0]);
+ SIMDBase_VECT b = SIMDBase_LOAD((SIMDBase_VECT *)&detectBuffer[64]);
+ SIMDBase_VECT c = SIMDBase_ADDi(a, b);
+ SIMDBase_STOR((SIMDBase_VECT *)&detectBuffer[128], c);
+}
+
+int32_t SIMDBaseUndiff_GETMODEPARAMINT(int32_t paramId) {
+ switch(paramId) {
+ case SIMDBase_PARAMID_SIZE_OF_REAL:
+ return sizeof(SIMDBase_REAL);
+ case SIMDBase_PARAMID_SIZE_OF_VECT:
+ return sizeof(SIMDBase_VECT);
+ case SIMDBase_PARAMID_VECTOR_LEN:
+ return SIMDBase_VECTLEN;
+ case SIMDBase_PARAMID_MODE_AVAILABILITY:
+ return SIMDBase_detect(paramId);
+ }
+
+ return -1;
+}
+
+char * SIMDBaseUndiff_GETMODEPARAMSTRING(int32_t paramId) {
+ switch(paramId) {
+ case SIMDBase_PARAMID_MODE_NAME:
+ return SIMDBase_NAME;
+ }
+
+ return NULL;
+}
diff --git a/plugins/supereq/nsfft-1.00/simd/SIMDBaseUndiff.h b/plugins/supereq/nsfft-1.00/simd/SIMDBaseUndiff.h
new file mode 100644
index 00000000..1af849a8
--- /dev/null
+++ b/plugins/supereq/nsfft-1.00/simd/SIMDBaseUndiff.h
@@ -0,0 +1,231 @@
+#ifndef _SIMDBaseUndiff_H_
+#define _SIMDBaseUndiff_H_
+
+#if defined(ENABLE_PUREC_FLOAT) ////////////////////////////////////////////
+
+typedef float SIMDBase_REAL;
+typedef float SIMDBase_VECT;
+
+#define SIMDBase_MODE 1
+#define SIMDBase_TYPE SIMDBase_TYPE_FLOAT
+#define SIMDBase_VECTLEN 1
+#define SIMDBase_NAME "Pure C float"
+#define SIMDBaseUndiff_DETECT detect_purec_float
+#define SIMDBaseUndiff_GETMODEPARAMINT getModeParamInt_purec_float
+#define SIMDBaseUndiff_GETMODEPARAMSTRING getModeParamString_purec_float
+
+static inline SIMDBase_VECT SIMDBase_LOAD(SIMDBase_VECT *p) { return *p; }
+static inline void SIMDBase_STOR(SIMDBase_VECT *p, SIMDBase_VECT u) { *p = u; }
+static inline SIMDBase_VECT SIMDBase_SET1(SIMDBase_REAL f) { return f; }
+static inline SIMDBase_VECT SIMDBase_LOAD1(SIMDBase_REAL *p) { return *p; }
+static inline SIMDBase_VECT SIMDBase_ADDi(SIMDBase_VECT u, SIMDBase_VECT v) { return u + v; }
+static inline SIMDBase_VECT SIMDBase_SUBi(SIMDBase_VECT u, SIMDBase_VECT v) { return u - v; }
+static inline SIMDBase_VECT SIMDBase_MULi(SIMDBase_VECT u, SIMDBase_VECT v) { return u * v; }
+static inline SIMDBase_VECT SIMDBase_NEGi(SIMDBase_VECT u) { return -u; }
+
+#elif defined(ENABLE_PUREC_DOUBLE) ////////////////////////////////////////////
+
+typedef double SIMDBase_REAL;
+typedef double SIMDBase_VECT;
+
+#define SIMDBase_MODE 2
+#define SIMDBase_TYPE SIMDBase_TYPE_DOUBLE
+#define SIMDBase_VECTLEN 1
+#define SIMDBase_NAME "Pure C double"
+#define SIMDBaseUndiff_DETECT detect_purec_double
+#define SIMDBaseUndiff_GETMODEPARAMINT getModeParamInt_purec_double
+#define SIMDBaseUndiff_GETMODEPARAMSTRING getModeParamString_purec_double
+
+static inline SIMDBase_VECT SIMDBase_LOAD(SIMDBase_VECT *p) { return *p; }
+static inline void SIMDBase_STOR(SIMDBase_VECT *p, SIMDBase_VECT u) { *p = u; }
+static inline SIMDBase_VECT SIMDBase_SET1(SIMDBase_REAL f) { return f; }
+static inline SIMDBase_VECT SIMDBase_LOAD1(SIMDBase_REAL *p) { return *p; }
+static inline SIMDBase_VECT SIMDBase_ADDi(SIMDBase_VECT u, SIMDBase_VECT v) { return u + v; }
+static inline SIMDBase_VECT SIMDBase_SUBi(SIMDBase_VECT u, SIMDBase_VECT v) { return u - v; }
+static inline SIMDBase_VECT SIMDBase_MULi(SIMDBase_VECT u, SIMDBase_VECT v) { return u * v; }
+static inline SIMDBase_VECT SIMDBase_NEGi(SIMDBase_VECT u) { return -u; }
+
+#elif defined(ENABLE_PUREC_LONGDOUBLE) ////////////////////////////////////////////
+
+typedef long double SIMDBase_REAL;
+typedef long double SIMDBase_VECT;
+
+#define SIMDBase_MODE 3
+#define SIMDBase_TYPE SIMDBase_TYPE_LONGDOUBLE
+#define SIMDBase_VECTLEN 1
+#define SIMDBase_NAME "Pure C long double"
+#define SIMDBaseUndiff_DETECT detect_purec_longdouble
+#define SIMDBaseUndiff_GETMODEPARAMINT getModeParamInt_purec_longdouble
+#define SIMDBaseUndiff_GETMODEPARAMSTRING getModeParamString_purec_longdouble
+
+static inline SIMDBase_VECT SIMDBase_LOAD(SIMDBase_VECT *p) { return *p; }
+static inline void SIMDBase_STOR(SIMDBase_VECT *p, SIMDBase_VECT u) { *p = u; }
+static inline SIMDBase_VECT SIMDBase_SET1(SIMDBase_REAL f) { return f; }
+static inline SIMDBase_VECT SIMDBase_LOAD1(SIMDBase_REAL *p) { return *p; }
+static inline SIMDBase_VECT SIMDBase_ADDi(SIMDBase_VECT u, SIMDBase_VECT v) { return u + v; }
+static inline SIMDBase_VECT SIMDBase_SUBi(SIMDBase_VECT u, SIMDBase_VECT v) { return u - v; }
+static inline SIMDBase_VECT SIMDBase_MULi(SIMDBase_VECT u, SIMDBase_VECT v) { return u * v; }
+static inline SIMDBase_VECT SIMDBase_NEGi(SIMDBase_VECT u) { return -u; }
+
+#elif defined(ENABLE_SSE_FLOAT) ////////////////////////////////////////////
+
+#include <xmmintrin.h>
+
+typedef float SIMDBase_REAL;
+typedef __m128 SIMDBase_VECT;
+
+#define SIMDBase_MODE 4
+#define SIMDBase_TYPE SIMDBase_TYPE_FLOAT
+#define SIMDBase_VECTLEN 4
+#define SIMDBase_NAME "x86 SSE float"
+#define SIMDBaseUndiff_DETECT detect_sse_float
+#define SIMDBaseUndiff_GETMODEPARAMINT getModeParamInt_sse_float
+#define SIMDBaseUndiff_GETMODEPARAMSTRING getModeParamString_sse_float
+
+static inline SIMDBase_VECT SIMDBase_LOAD(SIMDBase_VECT *p) { return _mm_load_ps((float *)p); }
+static inline void SIMDBase_STOR(SIMDBase_VECT *p, SIMDBase_VECT u) { _mm_store_ps((float *)p, u); }
+static inline SIMDBase_VECT SIMDBase_SET1(SIMDBase_REAL f) { return _mm_set1_ps(f); }
+static inline SIMDBase_VECT SIMDBase_LOAD1(SIMDBase_REAL *p) { return _mm_load1_ps(p); }
+static inline SIMDBase_VECT SIMDBase_ADDi(SIMDBase_VECT u, SIMDBase_VECT v) { return _mm_add_ps(u, v); }
+static inline SIMDBase_VECT SIMDBase_SUBi(SIMDBase_VECT u, SIMDBase_VECT v) { return _mm_sub_ps(u, v); }
+static inline SIMDBase_VECT SIMDBase_MULi(SIMDBase_VECT u, SIMDBase_VECT v) { return _mm_mul_ps(u, v); }
+static inline SIMDBase_VECT SIMDBase_NEGi(SIMDBase_VECT u) { return _mm_xor_ps(u, _mm_set_ps(-0.0f, -0.0f, -0.0f, -0.0f)); }
+
+#elif defined(ENABLE_SSE2_DOUBLE) ////////////////////////////////////////////
+
+#include <emmintrin.h>
+
+typedef double SIMDBase_REAL;
+typedef __m128d SIMDBase_VECT;
+
+#define SIMDBase_MODE 5
+#define SIMDBase_TYPE SIMDBase_TYPE_DOUBLE
+#define SIMDBase_VECTLEN 2
+#define SIMDBase_NAME "x86 SSE2 double"
+#define SIMDBaseUndiff_DETECT detect_sse2_double
+#define SIMDBaseUndiff_GETMODEPARAMINT getModeParamInt_sse2_double
+#define SIMDBaseUndiff_GETMODEPARAMSTRING getModeParamString_sse2_double
+
+static inline SIMDBase_VECT SIMDBase_LOAD(SIMDBase_VECT *p) { return _mm_load_pd((double *)p); }
+static inline void SIMDBase_STOR(SIMDBase_VECT *p, SIMDBase_VECT u) { _mm_store_pd((double *)p, u); }
+static inline SIMDBase_VECT SIMDBase_SET1(SIMDBase_REAL f) { return _mm_set1_pd(f); }
+static inline SIMDBase_VECT SIMDBase_LOAD1(SIMDBase_REAL *p) { return _mm_load1_pd(p); }
+static inline SIMDBase_VECT SIMDBase_ADDi(SIMDBase_VECT u, SIMDBase_VECT v) { return _mm_add_pd(u, v); }
+static inline SIMDBase_VECT SIMDBase_SUBi(SIMDBase_VECT u, SIMDBase_VECT v) { return _mm_sub_pd(u, v); }
+static inline SIMDBase_VECT SIMDBase_MULi(SIMDBase_VECT u, SIMDBase_VECT v) { return _mm_mul_pd(u, v); }
+static inline SIMDBase_VECT SIMDBase_NEGi(SIMDBase_VECT u) { return _mm_xor_pd(u, _mm_set_pd(-0.0, -0.0)); }
+
+#elif defined(ENABLE_NEON_FLOAT) ////////////////////////////////////////////
+
+#include <arm_neon.h>
+
+typedef float32_t SIMDBase_REAL;
+typedef float32x4_t SIMDBase_VECT;
+
+#define SIMDBase_MODE 6
+#define SIMDBase_TYPE SIMDBase_TYPE_FLOAT
+#define SIMDBase_VECTLEN 4
+#define SIMDBase_NAME "ARM NEON float"
+#define SIMDBaseUndiff_DETECT detect_neon_float
+#define SIMDBaseUndiff_GETMODEPARAMINT getModeParamInt_neon_float
+#define SIMDBaseUndiff_GETMODEPARAMSTRING getModeParamString_neon_float
+
+static inline SIMDBase_VECT SIMDBase_LOAD(SIMDBase_VECT *p) { return vld1q_f32((float32_t *)p); }
+static inline void SIMDBase_STOR(SIMDBase_VECT *p, SIMDBase_VECT u) { vst1q_f32((float32_t *)p, u); }
+static inline SIMDBase_VECT SIMDBase_SET1(SIMDBase_REAL f) { return vdupq_n_f32(f); }
+static inline SIMDBase_VECT SIMDBase_LOAD1(SIMDBase_REAL *p) { return vdupq_n_f32(*p); }
+static inline SIMDBase_VECT SIMDBase_ADDi(SIMDBase_VECT u, SIMDBase_VECT v) { return vaddq_f32(u, v); }
+static inline SIMDBase_VECT SIMDBase_SUBi(SIMDBase_VECT u, SIMDBase_VECT v) { return vsubq_f32(u, v); }
+static inline SIMDBase_VECT SIMDBase_MULi(SIMDBase_VECT u, SIMDBase_VECT v) { return vmulq_f32(u, v); }
+static inline SIMDBase_VECT SIMDBase_NEGi(SIMDBase_VECT u) {
+ return vreinterpretq_f32_u32( veorq_u32(vreinterpretq_u32_f32(u), vdupq_n_u32(0x80000000U)));
+}
+
+#define SIMDBase_FMADD_AVAILABLE
+
+static inline SIMDBase_VECT SIMDBase_FMADDi(SIMDBase_VECT u, SIMDBase_VECT v, SIMDBase_VECT w) { return vmlaq_f32(w, u, v); } // w + u * v
+static inline SIMDBase_VECT SIMDBase_FMSUBi(SIMDBase_VECT u, SIMDBase_VECT v, SIMDBase_VECT w) { return vmlsq_f32(w, u, v); } // w - u * v
+
+#elif defined(ENABLE_AVX_FLOAT) ////////////////////////////////////////////
+
+#include <immintrin.h>
+
+typedef float SIMDBase_REAL;
+typedef __m256 SIMDBase_VECT;
+
+#define SIMDBase_MODE 7
+#define SIMDBase_TYPE SIMDBase_TYPE_FLOAT
+#define SIMDBase_VECTLEN 8
+#define SIMDBase_NAME "x86 AVX float"
+#define SIMDBaseUndiff_DETECT detect_avx_float
+#define SIMDBaseUndiff_GETMODEPARAMINT getModeParamInt_avx_float
+#define SIMDBaseUndiff_GETMODEPARAMSTRING getModeParamString_avx_float
+
+static inline SIMDBase_VECT SIMDBase_LOAD(SIMDBase_VECT *p) { return _mm256_load_ps((float *)p); }
+static inline void SIMDBase_STOR(SIMDBase_VECT *p, SIMDBase_VECT u) { _mm256_store_ps((float *)p, u); }
+static inline SIMDBase_VECT SIMDBase_SET1(SIMDBase_REAL f) { return _mm256_set1_ps(f); }
+static inline SIMDBase_VECT SIMDBase_LOAD1(SIMDBase_REAL *p) { return _mm256_set1_ps(*p); }
+static inline SIMDBase_VECT SIMDBase_ADDi(SIMDBase_VECT u, SIMDBase_VECT v) { return _mm256_add_ps(u, v); }
+static inline SIMDBase_VECT SIMDBase_SUBi(SIMDBase_VECT u, SIMDBase_VECT v) { return _mm256_sub_ps(u, v); }
+static inline SIMDBase_VECT SIMDBase_MULi(SIMDBase_VECT u, SIMDBase_VECT v) { return _mm256_mul_ps(u, v); }
+static inline SIMDBase_VECT SIMDBase_NEGi(SIMDBase_VECT u) { return _mm256_xor_ps(u, _mm256_set1_ps(-0.0f)); }
+
+#elif defined(ENABLE_AVX_DOUBLE) ////////////////////////////////////////////
+
+#include <immintrin.h>
+
+typedef double SIMDBase_REAL;
+typedef __m256d SIMDBase_VECT;
+
+#define SIMDBase_MODE 8
+#define SIMDBase_TYPE SIMDBase_TYPE_DOUBLE
+#define SIMDBase_VECTLEN 4
+#define SIMDBase_NAME "x86 AVX double"
+#define SIMDBaseUndiff_DETECT detect_avx_double
+#define SIMDBaseUndiff_GETMODEPARAMINT getModeParamInt_avx_double
+#define SIMDBaseUndiff_GETMODEPARAMSTRING getModeParamString_avx_double
+
+static inline SIMDBase_VECT SIMDBase_LOAD(SIMDBase_VECT *p) { return _mm256_load_pd((double *)p); }
+static inline void SIMDBase_STOR(SIMDBase_VECT *p, SIMDBase_VECT u) { _mm256_store_pd((double *)p, u); }
+static inline SIMDBase_VECT SIMDBase_SET1(SIMDBase_REAL f) { return _mm256_set1_pd(f); }
+static inline SIMDBase_VECT SIMDBase_LOAD1(SIMDBase_REAL *p) { return _mm256_set1_pd(*p); }
+static inline SIMDBase_VECT SIMDBase_ADDi(SIMDBase_VECT u, SIMDBase_VECT v) { return _mm256_add_pd(u, v); }
+static inline SIMDBase_VECT SIMDBase_SUBi(SIMDBase_VECT u, SIMDBase_VECT v) { return _mm256_sub_pd(u, v); }
+static inline SIMDBase_VECT SIMDBase_MULi(SIMDBase_VECT u, SIMDBase_VECT v) { return _mm256_mul_pd(u, v); }
+static inline SIMDBase_VECT SIMDBase_NEGi(SIMDBase_VECT u) { return _mm256_xor_pd(u, _mm256_set1_pd(-0.0)); }
+
+#elif defined(ENABLE_ALTIVEC_FLOAT) ////////////////////////////////////////////
+
+#include <altivec.h>
+
+typedef float SIMDBase_REAL;
+typedef vector float SIMDBase_VECT;
+
+#define SIMDBase_MODE 9
+#define SIMDBase_TYPE SIMDBase_TYPE_FLOAT
+#define SIMDBase_VECTLEN 4
+#define SIMDBase_NAME "PowerPC AltiVec float"
+#define SIMDBaseUndiff_DETECT detect_altivec_float
+#define SIMDBaseUndiff_GETMODEPARAMINT getModeParamInt_altivec_float
+#define SIMDBaseUndiff_GETMODEPARAMSTRING getModeParamString_altivec_float
+
+static inline SIMDBase_VECT SIMDBase_LOAD(SIMDBase_VECT *p) { return vec_ld(0, p); }
+static inline void SIMDBase_STOR(SIMDBase_VECT *p, SIMDBase_VECT u) { vec_st(u, 0, p); }
+static inline SIMDBase_VECT SIMDBase_SET1(SIMDBase_REAL f) { return (vector float){f, f, f, f}; }
+static inline SIMDBase_VECT SIMDBase_LOAD1(SIMDBase_REAL *p) { return (vector float){*p, *p, *p, *p}; }
+static inline SIMDBase_VECT SIMDBase_ADDi(SIMDBase_VECT u, SIMDBase_VECT v) { return vec_add(u, v); }
+static inline SIMDBase_VECT SIMDBase_SUBi(SIMDBase_VECT u, SIMDBase_VECT v) { return vec_sub(u, v); }
+static inline SIMDBase_VECT SIMDBase_MULi(SIMDBase_VECT u, SIMDBase_VECT v) { return vec_madd(u, v, (vector float){0, 0, 0, 0}); }
+static inline SIMDBase_VECT SIMDBase_NEGi(SIMDBase_VECT u) { return vec_xor(u, (vector float){-0.0f, -0.0f, -0.0f, -0.0f}); }
+
+#define SIMDBase_FMADD_AVAILABLE
+
+static inline SIMDBase_VECT SIMDBase_FMADDi(SIMDBase_VECT u, SIMDBase_VECT v, SIMDBase_VECT w) { return vec_madd(u, v, w); } // w + u * v
+static inline SIMDBase_VECT SIMDBase_FMSUBi(SIMDBase_VECT u, SIMDBase_VECT v, SIMDBase_VECT w) { return vec_nmsub(u, v, w); } // w - u * v
+
+#endif ////////////////////////////////////////////////////////////////////
+
+static inline SIMDBase_VECT SIMDBase_ADDm(SIMDBase_VECT *p, SIMDBase_VECT *q) { return SIMDBase_ADDi(SIMDBase_LOAD(p), SIMDBase_LOAD(q)); }
+static inline SIMDBase_VECT SIMDBase_SUBm(SIMDBase_VECT *p, SIMDBase_VECT *q) { return SIMDBase_SUBi(SIMDBase_LOAD(p), SIMDBase_LOAD(q)); }
+
+#endif
diff --git a/plugins/supereq/paramlist.hpp b/plugins/supereq/paramlist.hpp
index 0c513b78..9c5b09c4 100644
--- a/plugins/supereq/paramlist.hpp
+++ b/plugins/supereq/paramlist.hpp
@@ -1,4 +1,22 @@
-//#include <iostream.h>
+/*
+ DeaDBeeF - ultimate music player for GNU/Linux systems with X11
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
+ Original SuperEQ code (C) Naoki Shibata <shibatch@users.sf.net>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -7,12 +25,10 @@ class paramlistelm {
public:
class paramlistelm *next;
- char left,right;
float lower,upper,gain,gain2;
int sortindex;
paramlistelm(void) {
- left = right = 1;
lower = upper = gain = 0;
next = NULL;
};
@@ -21,13 +37,6 @@ public:
delete next;
next = NULL;
};
-
- char *getString(void) {
- static char str[64];
- sprintf(str,"%gHz to %gHz, %gdB %c%c",
- (double)lower,(double)upper,(double)gain,left?'L':' ',right?'R':' ');
- return str;
- }
};
class paramlist {
@@ -52,8 +61,6 @@ public:
for(p=&elm,q=src.elm;q != NULL;q = q->next,p = &(*p)->next)
{
*p = new paramlistelm;
- (*p)->left = q->left;
- (*p)->right = q->right;
(*p)->lower = q->lower;
(*p)->upper = q->upper;
(*p)->gain = q->gain;
diff --git a/plugins/supereq/shibatch_rdft.c b/plugins/supereq/shibatch_rdft.c
new file mode 100644
index 00000000..db453eb8
--- /dev/null
+++ b/plugins/supereq/shibatch_rdft.c
@@ -0,0 +1,71 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <stdint.h>
+
+#include "SIMDBase.h"
+#include "DFT.h"
+
+#define TYPE SIMDBase_TYPE_FLOAT
+
+void rfft(int n,int isign,float *x) {
+ static DFT *p = NULL;
+ static float *buf = NULL;
+ static int ipsize = 0;
+ static int mode = 0;
+ static int veclen = 0;
+ int newipsize;
+ if (n == 0) {
+ if (buf) {
+ SIMDBase_alignedFree (buf);
+ buf = NULL;
+ }
+ if (p) {
+ DFT_dispose(p, mode);
+ p = NULL;
+ }
+ return;
+ }
+ int nn = n;
+ n = 1<<n;
+ newipsize = n;
+ if (newipsize != ipsize) {
+ ipsize = newipsize;
+
+ if (buf) {
+ SIMDBase_alignedFree (buf);
+ buf = NULL;
+ }
+
+ if (p) {
+ DFT_dispose(p, mode);
+ p = NULL;
+ }
+
+ buf = SIMDBase_alignedMalloc (n * sizeof (float));
+
+ mode = SIMDBase_chooseBestMode(TYPE);
+ veclen = SIMDBase_getModeParamInt(SIMDBase_PARAMID_VECTOR_LEN, mode);
+ int sizeOfVect = SIMDBase_getModeParamInt(SIMDBase_PARAMID_SIZE_OF_VECT, mode);
+ printf ("n: %d, veclen: %d, sizeOfVect: %d\n", n, veclen, sizeOfVect);
+ p = DFT_init(mode, n/veclen, DFT_FLAG_REAL);
+ }
+
+ // store in simd order
+ int asize = n / veclen;
+ int i, j;
+ for(j=0;j<veclen;j++) {
+ for (i = 0; i < asize; i++) {
+ buf[i * veclen + j] = x[j * asize + i];
+ }
+ }
+
+ DFT_execute(p, mode, buf, isign);
+
+#define THRES 1e-3
+ for(j=0;j<veclen;j++) {
+ for (i = 0; i < asize; i++) {
+ x[j * asize + i] = buf[i * veclen + j];
+ }
+ }
+}
diff --git a/plugins/supereq/supereq.c b/plugins/supereq/supereq.c
index af4000fd..a773b4ef 100644
--- a/plugins/supereq/supereq.c
+++ b/plugins/supereq/supereq.c
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@@ -18,217 +18,301 @@
*/
#include <stdio.h>
#include <string.h>
+#include <stdlib.h>
+#include <math.h>
#include "../../deadbeef.h"
-#include "supereq.h"
+#include "Equ.h"
static DB_functions_t *deadbeef;
-static DB_supereq_dsp_t plugin;
-
-void *paramlist_alloc (void);
-void paramlist_free (void *);
-void equ_makeTable(float *lbc,float *rbc,void *param,float fs);
-int equ_modifySamples(char *buf,int nsamples,int nch,int bps);
-void equ_clearbuf(int bps,int srate);
-void equ_init(int wb);
-void equ_quit(void);
-
-void supereq_reset (void);
-
-static float last_srate = 0;
-static int last_nch = 0, last_bps = 0;
-static float lbands[18] = {1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0};
-static float rbands[18] = {1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0};
-static float preamp = 1;
-static void *paramsroot;
-
-static int params_changed = 0;
-static intptr_t tid = 0;
-static uintptr_t mutex = 0;
-static int enabled = 0;
-
-static int
-supereq_on_configchanged (DB_event_t *ev, uintptr_t data) {
- int e = deadbeef->conf_get_int ("supereq.enable", 0);
- if (e != enabled) {
- if (e) {
- supereq_reset ();
- }
- enabled = e;
- }
-
- return 0;
-}
+static DB_dsp_t plugin;
+
+typedef struct {
+ ddb_dsp_context_t ctx;
+ float last_srate;
+ int last_nch;
+ float bands[18];
+ float preamp;
+ void *paramsroot;
+ int params_changed;
+ uintptr_t mutex;
+ SuperEqState state;
+ int enabled;
+} ddb_supereq_ctx_t;
+
+void supereq_reset (ddb_dsp_context_t *ctx);
void
-recalc_table (void) {
+recalc_table (ddb_supereq_ctx_t *eq) {
void *params = paramlist_alloc ();
- deadbeef->mutex_lock (mutex);
- float lbands_copy[18];
- float rbands_copy[18];
- float srate = last_srate;
- memcpy (lbands_copy, lbands, sizeof (lbands));
- memcpy (rbands_copy, rbands, sizeof (rbands));
+ deadbeef->mutex_lock (eq->mutex);
+ float bands_copy[18];
+ float srate = eq->last_srate;
+ memcpy (bands_copy, eq->bands, sizeof (eq->bands));
for (int i = 0; i < 18; i++) {
- lbands_copy[i] *= preamp;
- rbands_copy[i] *= preamp;
+ bands_copy[i] *= eq->preamp;
}
- deadbeef->mutex_unlock (mutex);
+ deadbeef->mutex_unlock (eq->mutex);
- equ_makeTable (lbands_copy, rbands_copy, params, srate);
+ equ_makeTable (&eq->state, bands_copy, params, srate);
- deadbeef->mutex_lock (mutex);
- paramlist_free (paramsroot);
- paramsroot = params;
- deadbeef->mutex_unlock (mutex);
+ deadbeef->mutex_lock (eq->mutex);
+ paramlist_free (eq->paramsroot);
+ eq->paramsroot = params;
+ deadbeef->mutex_unlock (eq->mutex);
}
int
supereq_plugin_start (void) {
- enabled = deadbeef->conf_get_int ("supereq.enable", 0);
- // load bands from config
- preamp = deadbeef->conf_get_float ("eq.preamp", 1);
- for (int i = 0; i < 18; i++) {
- char key[100];
- snprintf (key, sizeof (key), "eq.band%d", i);
- lbands[i] = rbands[i] = deadbeef->conf_get_float (key, 1);
- }
-
- equ_init (14);
- paramsroot = paramlist_alloc ();
- last_srate = 44100;
- last_nch = 2;
- last_bps = 16;
- mutex = deadbeef->mutex_create ();
- recalc_table ();
- equ_clearbuf (last_bps,last_srate);
- deadbeef->ev_subscribe (DB_PLUGIN (&plugin), DB_EV_CONFIGCHANGED, DB_CALLBACK (supereq_on_configchanged), 0);
return 0;
}
int
supereq_plugin_stop (void) {
- deadbeef->ev_unsubscribe (DB_PLUGIN (&plugin), DB_EV_CONFIGCHANGED, DB_CALLBACK (supereq_on_configchanged), 0);
- if (tid) {
- deadbeef->thread_join (tid);
- tid = 0;
- }
- if (mutex) {
- deadbeef->mutex_free (mutex);
- mutex = 0;
- }
- equ_quit ();
- paramlist_free (paramsroot);
return 0;
}
-void
-supereq_regen_table_thread (void *param) {
- recalc_table ();
- tid = 0;
-}
-
int
-supereq_process_int16 (int16_t *samples, int nsamples, int nch, int bps, int srate) {
- if ((nch != 1 && nch != 2) || (bps != 8 && bps != 16 && bps != 24)) return nsamples;
- if (params_changed && !tid) {
- tid = deadbeef->thread_start (supereq_regen_table_thread, NULL);
- params_changed = 0;
+supereq_process (ddb_dsp_context_t *ctx, float *samples, int frames, int maxframes, ddb_waveformat_t *fmt, float *r) {
+ ddb_supereq_ctx_t *supereq = (ddb_supereq_ctx_t *)ctx;
+ if (supereq->enabled != ctx->enabled) {
+ if (ctx->enabled && !supereq->enabled) {
+ supereq_reset (ctx);
+ }
+ supereq->enabled = ctx->enabled;
+
+// this causes a glitch on 1st track
+// DB_playItem_t *it = deadbeef->streamer_get_playing_track ();
+// if (it) {
+// float playpos = deadbeef->streamer_get_playpos ();
+// deadbeef->streamer_seek (playpos);
+// deadbeef->pl_item_unref (it);
+// }
}
- if (last_srate != srate) {
- deadbeef->mutex_lock (mutex);
- //equ_makeTable (lbands, rbands, paramsroot, srate);
- last_srate = srate;
- last_nch = nch;
- last_bps = bps;
- recalc_table ();
- deadbeef->mutex_unlock (mutex);
- equ_clearbuf(bps,srate);
+ if (supereq->params_changed) {
+ recalc_table (supereq);
+ supereq->params_changed = 0;
}
- else if (last_nch != nch || last_bps != bps) {
- deadbeef->mutex_lock (mutex);
- last_nch = nch;
- last_bps = bps;
- deadbeef->mutex_unlock (mutex);
- equ_clearbuf(bps,srate);
+ if (supereq->last_srate != fmt->samplerate || supereq->last_nch != fmt->channels) {
+ deadbeef->mutex_lock (supereq->mutex);
+ supereq->last_srate = fmt->samplerate;
+ supereq->last_nch = fmt->channels;
+ equ_init (&supereq->state, 10, fmt->channels);
+ recalc_table (supereq);
+ equ_clearbuf(&supereq->state);
+ deadbeef->mutex_unlock (supereq->mutex);
}
- equ_modifySamples((char *)samples,nsamples,nch,bps);
- return nsamples;
+ equ_modifySamples_float(&supereq->state, (char *)samples,frames,fmt->channels);
+ return frames;
}
float
-supereq_get_band (int band) {
- return lbands[band];
+supereq_get_band (ddb_dsp_context_t *ctx, int band) {
+ ddb_supereq_ctx_t *supereq = (ddb_supereq_ctx_t *)ctx;
+ return supereq->bands[band];
}
void
-supereq_set_band (int band, float value) {
- deadbeef->mutex_lock (mutex);
- lbands[band] = rbands[band] = value;
- deadbeef->mutex_unlock (mutex);
- params_changed = 1;
- char key[100];
- snprintf (key, sizeof (key), "eq.band%d", band);
- deadbeef->conf_set_float (key, value);
+supereq_set_band (ddb_dsp_context_t *ctx, int band, float value) {
+ ddb_supereq_ctx_t *supereq = (ddb_supereq_ctx_t *)ctx;
+ deadbeef->mutex_lock (supereq->mutex);
+ supereq->bands[band] = value;
+ deadbeef->mutex_unlock (supereq->mutex);
+ supereq->params_changed = 1;
}
float
-supereq_get_preamp (void) {
- return preamp;
+supereq_get_preamp (ddb_dsp_context_t *ctx) {
+ ddb_supereq_ctx_t *supereq = (ddb_supereq_ctx_t *)ctx;
+ return supereq->preamp;
}
void
-supereq_set_preamp (float value) {
- deadbeef->mutex_lock (mutex);
- preamp = value;
- deadbeef->mutex_unlock (mutex);
- params_changed = 1;
- deadbeef->conf_set_float ("eq.preamp", value);
+supereq_set_preamp (ddb_dsp_context_t *ctx, float value) {
+ ddb_supereq_ctx_t *supereq = (ddb_supereq_ctx_t *)ctx;
+ deadbeef->mutex_lock (supereq->mutex);
+ supereq->preamp = value;
+ deadbeef->mutex_unlock (supereq->mutex);
+ supereq->params_changed = 1;
}
void
-supereq_reset (void) {
- deadbeef->mutex_lock (mutex);
- equ_clearbuf(last_bps,last_srate);
- deadbeef->mutex_unlock (mutex);
+supereq_reset (ddb_dsp_context_t *ctx) {
+ ddb_supereq_ctx_t *supereq = (ddb_supereq_ctx_t *)ctx;
+ deadbeef->mutex_lock (supereq->mutex);
+ equ_clearbuf(&supereq->state);
+ deadbeef->mutex_unlock (supereq->mutex);
+}
+
+int
+supereq_num_params (void) {
+ return 19;
+}
+
+static const char *bandnames[] = {
+ "Preamp",
+ "55 Hz",
+ "77 Hz",
+ "110 Hz",
+ "156 Hz",
+ "220 Hz",
+ "311 Hz",
+ "440 Hz",
+ "622 Hz",
+ "880 Hz",
+ "1.2 kHz",
+ "1.8 kHz",
+ "2.5 kHz",
+ "3.5 kHz",
+ "5 kHz",
+ "7 kHz",
+ "10 kHz",
+ "14 kHz",
+ "20 kHz"
+};
+
+const char *
+supereq_get_param_name (int p) {
+ return bandnames[p];
+}
+
+
+static inline float
+db_to_amp (float dB) {
+ const float ln10=2.3025850929940002f;
+ return exp(ln10*dB/20.f);
+}
+
+static inline float
+amp_to_db (float amp) {
+ return 20*log10 (amp);
}
void
-supereq_enable (int e) {
- if (e != enabled) {
- deadbeef->conf_set_int ("supereq.enable", e);
- if (e && !enabled) {
- supereq_reset ();
- }
- enabled = e;
+supereq_set_param (ddb_dsp_context_t *ctx, int p, const char *val) {
+ switch (p) {
+ case 0:
+ supereq_set_preamp (ctx, db_to_amp (atof (val)));
+ break;
+ case 1 ... 18:
+ supereq_set_band (ctx, p-1, db_to_amp (atof (val)));
+ break;
+ default:
+ fprintf (stderr, "supereq_set_param: invalid param index (%d)\n", p);
}
}
-int
-supereq_enabled (void) {
- return enabled;
-}
-
-static DB_supereq_dsp_t plugin = {
- .dsp.plugin.api_vmajor = DB_API_VERSION_MAJOR,
- .dsp.plugin.api_vminor = DB_API_VERSION_MINOR,
- .dsp.plugin.type = DB_PLUGIN_DSP,
- .dsp.plugin.id = "supereq",
- .dsp.plugin.name = "SuperEQ",
- .dsp.plugin.descr = "equalizer plugin using SuperEQ library by Naoki Shibata",
- .dsp.plugin.author = "Alexey Yakovenko",
- .dsp.plugin.email = "waker@users.sourceforge.net",
- .dsp.plugin.website = "http://deadbeef.sf.net",
- .dsp.plugin.start = supereq_plugin_start,
- .dsp.plugin.stop = supereq_plugin_stop,
- .dsp.process_int16 = supereq_process_int16,
- .dsp.reset = supereq_reset,
- .dsp.enable = supereq_enable,
- .dsp.enabled = supereq_enabled,
- .get_band = supereq_get_band,
- .set_band = supereq_set_band,
- .get_preamp = supereq_get_preamp,
- .set_preamp = supereq_set_preamp,
+void
+supereq_get_param (ddb_dsp_context_t *ctx, int p, char *v, int sz) {
+ switch (p) {
+ case 0:
+ snprintf (v, sz, "%f", amp_to_db (supereq_get_preamp (ctx)));
+ break;
+ case 1 ... 18:
+ snprintf (v, sz, "%f", amp_to_db (supereq_get_band (ctx, p-1)));
+ break;
+ default:
+ fprintf (stderr, "supereq_get_param: invalid param index (%d)\n", p);
+ }
+}
+
+
+ddb_dsp_context_t*
+supereq_open (void) {
+ ddb_supereq_ctx_t *supereq = malloc (sizeof (ddb_supereq_ctx_t));
+ DDB_INIT_DSP_CONTEXT (supereq,ddb_supereq_ctx_t,&plugin);
+
+ equ_init (&supereq->state, 10, 2);
+ supereq->paramsroot = paramlist_alloc ();
+ supereq->last_srate = 44100;
+ supereq->last_nch = 2;
+ supereq->mutex = deadbeef->mutex_create ();
+ supereq->preamp = 1;
+ for (int i = 0; i < 18; i++) {
+ supereq->bands[i] = 1;
+ }
+ recalc_table (supereq);
+ equ_clearbuf (&supereq->state);
+
+ return (ddb_dsp_context_t*)supereq;
+}
+
+void
+supereq_close (ddb_dsp_context_t *ctx) {
+ ddb_supereq_ctx_t *supereq = (ddb_supereq_ctx_t *)ctx;
+ if (supereq->mutex) {
+ deadbeef->mutex_free (supereq->mutex);
+ supereq->mutex = 0;
+ }
+ equ_quit (&supereq->state);
+ paramlist_free (supereq->paramsroot);
+ free (ctx);
+}
+
+static const char settings_dlg[] =
+ "property \"\" hbox[19] hmg fill expand border=0 spacing=8 height=200;\n"
+ "property \"Preamp\" vscale[20,-20,1] vert 0 0;\n"
+ "property \"55 Hz\" vscale[20,-20,1] vert 1 0;\n"
+ "property \"77 Hz\" vscale[20,-20,1] vert 2 0;\n"
+ "property \"110 Hz\" vscale[20,-20,1] vert 3 0;\n"
+ "property \"156 Hz\" vscale[20,-20,1] vert 4 0;\n"
+ "property \"220 Hz\" vscale[20,-20,1] vert 5 0;\n"
+ "property \"311 Hz\" vscale[20,-20,1] vert 6 0;\n"
+ "property \"440 Hz\" vscale[20,-20,1] vert 7 0;\n"
+ "property \"622 Hz\" vscale[20,-20,1] vert 8 0;\n"
+ "property \"880 Hz\" vscale[20,-20,1] vert 9 0;\n"
+ "property \"1.2 kHz\" vscale[20,-20,1] vert 10 0;\n"
+ "property \"1.8 kHz\" vscale[20,-20,1] vert 11 0;\n"
+ "property \"2.5 kHz\" vscale[20,-20,1] vert 12 0;\n"
+ "property \"3.5 kHz\" vscale[20,-20,1] vert 13 0;\n"
+ "property \"5 kHz\" vscale[20,-20,1] vert 14 0;\n"
+ "property \"7 kHz\" vscale[20,-20,1] vert 15 0;\n"
+ "property \"10 kHz\" vscale[20,-20,1] vert 16 0;\n"
+ "property \"14 kHz\" vscale[20,-20,1] vert 17 0;\n"
+ "property \"20 kHz\" vscale[20,-20,1] vert 18 0;\n"
+;
+
+static DB_dsp_t plugin = {
+ .plugin.api_vmajor = DB_API_VERSION_MAJOR,
+ .plugin.api_vminor = DB_API_VERSION_MINOR,
+ .plugin.version_major = 1,
+ .plugin.version_minor = 0,
+ .plugin.type = DB_PLUGIN_DSP,
+ .plugin.id = "supereq",
+ .plugin.name = "SuperEQ",
+ .plugin.descr = "equalizer plugin using SuperEQ library",
+ .plugin.copyright =
+ "Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>\n"
+ "\n"
+ "Uses supereq library by Naoki Shibata, http://shibatch.sourceforge.net\n"
+ "Uses FFT library by Takuya Ooura, http://www.kurims.kyoto-u.ac.jp/~ooura/\n"
+ "\n"
+ "This program is free software; you can redistribute it and/or\n"
+ "modify it under the terms of the GNU General Public License\n"
+ "as published by the Free Software Foundation; either version 2\n"
+ "of the License, or (at your option) any later version.\n"
+ "\n"
+ "This program is distributed in the hope that it will be useful,\n"
+ "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+ "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+ "GNU General Public License for more details.\n"
+ "\n"
+ "You should have received a copy of the GNU General Public License\n"
+ "along with this program; if not, write to the Free Software\n"
+ "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n"
+ ,
+ .plugin.website = "http://deadbeef.sf.net",
+ .plugin.start = supereq_plugin_start,
+ .plugin.stop = supereq_plugin_stop,
+ .open = supereq_open,
+ .close = supereq_close,
+ .process = supereq_process,
+ .reset = supereq_reset,
+ .num_params = supereq_num_params,
+ .get_param_name = supereq_get_param_name,
+ .set_param = supereq_set_param,
+ .get_param = supereq_get_param,
+ .configdialog = settings_dlg,
};
DB_plugin_t *
diff --git a/plugins/tta/filter.h b/plugins/tta/filter.h
index 6e8b13da..1f86cbb1 100644
--- a/plugins/tta/filter.h
+++ b/plugins/tta/filter.h
@@ -42,7 +42,7 @@
///////// Filter Settings //////////
static int flt_set[3] = {10, 9, 10};
-__inline void
+static __inline void
memshl (register int *pA, register int *pB) {
*pA++ = *pB++;
*pA++ = *pB++;
@@ -54,7 +54,7 @@ memshl (register int *pA, register int *pB) {
*pA = *pB;
}
-__inline void
+static __inline void
hybrid_filter (fltst *fs, int *in) {
register int *pA = fs->dl;
register int *pB = fs->qm;
diff --git a/plugins/tta/ttadec.c b/plugins/tta/ttadec.c
index d5466359..7a33d072 100644
--- a/plugins/tta/ttadec.c
+++ b/plugins/tta/ttadec.c
@@ -267,9 +267,7 @@ int open_tta_file (const char *filename, tta_info *info, unsigned int data_offse
info->HANDLE = infile;
// get file size
- deadbeef->fseek (infile, 0, SEEK_END);
- info->FILESIZE = deadbeef->ftell (infile);
- deadbeef->fseek (infile, 0, SEEK_SET);
+ info->FILESIZE = deadbeef->fgetlength (infile);
// read id3 tags
if (!data_offset) {
diff --git a/plugins/tta/ttaplug.c b/plugins/tta/ttaplug.c
index 196df859..20a0c8a5 100644
--- a/plugins/tta/ttaplug.c
+++ b/plugins/tta/ttaplug.c
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -20,6 +20,7 @@
#include <assert.h>
#include <limits.h>
#include <unistd.h>
+#include <math.h>
#include "ttadec.h"
#ifdef HAVE_CONFIG_H
# include <config.h>
@@ -49,7 +50,7 @@ typedef struct {
} tta_info_t;
static DB_fileinfo_t *
-tta_open (void) {
+tta_open (uint32_t hints) {
DB_fileinfo_t *_info = malloc (sizeof (tta_info_t));
tta_info_t *info = (tta_info_t *)_info;
memset (info, 0, sizeof (tta_info_t));
@@ -60,20 +61,23 @@ static int
tta_init (DB_fileinfo_t *_info, DB_playItem_t *it) {
tta_info_t *info = (tta_info_t *)_info;
- trace ("open_tta_file %s\n", it->fname);
- if (open_tta_file (it->fname, &info->tta, 0) != 0) {
- fprintf (stderr, "tta: failed to open %s\n", it->fname);
+ trace ("open_tta_file %s\n", deadbeef->pl_find_meta (it, ":URI"));
+ if (open_tta_file (deadbeef->pl_find_meta (it, ":URI"), &info->tta, 0) != 0) {
+ fprintf (stderr, "tta: failed to open %s\n", deadbeef->pl_find_meta (it, ":URI"));
return -1;
}
if (player_init (&info->tta) != 0) {
- fprintf (stderr, "tta: failed to init player for %s\n", it->fname);
+ fprintf (stderr, "tta: failed to init player for %s\n", deadbeef->pl_find_meta (it, ":URI"));
return -1;
}
- _info->bps = info->tta.BPS;
- _info->channels = info->tta.NCH;
- _info->samplerate = info->tta.SAMPLERATE;
+ _info->fmt.bps = info->tta.BPS;
+ _info->fmt.channels = info->tta.NCH;
+ _info->fmt.samplerate = info->tta.SAMPLERATE;
+ for (int i = 0; i < _info->fmt.channels; i++) {
+ _info->fmt.channelmask |= 1 << i;
+ }
_info->readpos = 0;
_info->plugin = &plugin;
@@ -86,7 +90,7 @@ tta_init (DB_fileinfo_t *_info, DB_playItem_t *it) {
info->startsample = 0;
info->endsample = (info->tta.DATALENGTH)-1;
}
- trace ("open_tta_file %s success!\n", it->fname);
+ trace ("open_tta_file %s success!\n", deadbeef->pl_find_meta (it, ":URI"));
return 0;
}
@@ -101,65 +105,40 @@ tta_free (DB_fileinfo_t *_info) {
}
static int
-tta_read_int16 (DB_fileinfo_t *_info, char *bytes, int size) {
+tta_read (DB_fileinfo_t *_info, char *bytes, int size) {
tta_info_t *info = (tta_info_t *)_info;
- int out_ch = min (_info->channels, 2);
- if (info->currentsample + size / (2 * out_ch) > info->endsample) {
- size = (info->endsample - info->currentsample + 1) * 2 * out_ch;
+ int samplesize = _info->fmt.channels * _info->fmt.bps / 8;
+ if (info->currentsample + size / samplesize > info->endsample) {
+ size = (info->endsample - info->currentsample + 1) * samplesize;
if (size <= 0) {
return 0;
}
}
int initsize = size;
- int sample_size = 2 * out_ch;
while (size > 0) {
if (info->samples_to_skip > 0 && info->remaining > 0) {
int skip = min (info->remaining, info->samples_to_skip);
if (skip < info->remaining) {
- memmove (info->buffer, info->buffer + skip * info->tta.BSIZE * info->tta.NCH, (info->remaining - skip) * info->tta.BSIZE * info->tta.NCH);
+ memmove (info->buffer, info->buffer + skip * samplesize, (info->remaining - skip) * samplesize);
}
info->remaining -= skip;
info->samples_to_skip -= skip;
}
if (info->remaining > 0) {
- int n = size / sample_size;
+ int n = size / samplesize;
n = min (n, info->remaining);
int nn = n;
char *p = info->buffer;
- if (_info->bps > 8) {
- // hack: shift buffer, so that we always get 2 most significant bytes (24 bit support)
- // same hack kinda works for 8bit, but it's not lossless
- p += (_info->bps >> 3) - 2;
- while (n > 0) {
- *((int16_t*)bytes) = (int16_t)(((uint8_t)p[1]<<8) | (uint8_t)p[0]);
- bytes += 2;
- if (out_ch == 2) {
- *((int16_t*)bytes) = (int16_t)(((uint8_t)(p+info->tta.BSIZE)[1]<<8) | (uint8_t)(p+info->tta.BSIZE)[0]);
- bytes += 2;
- }
- n--;
- size -= sample_size;
- p += info->tta.NCH * info->tta.BSIZE;
- }
- p -= (_info->bps >> 3) - 2;
- }
- else {
- while (n > 0) {
- *((int16_t*)bytes) = ((int16_t)(p[0])) << 8;
- bytes += 2;
- if (out_ch == 2) {
- *((int16_t*)bytes) = ((int16_t)(p[1])) << 8;
- bytes += 2;
- }
- n--;
- size -= sample_size;
- p += info->tta.NCH * info->tta.BSIZE;
- }
- }
+
+ memcpy (bytes, p, n * samplesize);
+ bytes += n * samplesize;
+ size -= n * samplesize;
+ p += n * samplesize;
+
if (info->remaining > nn) {
- memmove (info->buffer, p, (info->remaining - nn) * info->tta.BSIZE * info->tta.NCH);
+ memmove (info->buffer, p, (info->remaining - nn) * samplesize);
}
info->remaining -= nn;
}
@@ -171,7 +150,8 @@ tta_read_int16 (DB_fileinfo_t *_info, char *bytes, int size) {
}
}
}
- info->currentsample += (initsize-size) / sample_size;
+ info->currentsample += (initsize-size) / samplesize;
+ deadbeef->streamer_set_bitrate (info->tta.BITRATE);
return initsize-size;
}
@@ -187,14 +167,14 @@ tta_seek_sample (DB_fileinfo_t *_info, int sample) {
info->currentsample = sample + info->startsample;
info->remaining = 0;
- _info->readpos = sample / _info->samplerate;
+ _info->readpos = sample / _info->fmt.samplerate;
return 0;
}
static int
tta_seek (DB_fileinfo_t *_info, float time) {
tta_info_t *info = (tta_info_t *)_info;
- return tta_seek_sample (_info, time * _info->samplerate);
+ return tta_seek_sample (_info, time * _info->fmt.samplerate);
}
static DB_playItem_t *
@@ -213,15 +193,16 @@ tta_insert (DB_playItem_t *after, const char *fname) {
int totalsamples = tta.DATALENGTH;
double dur = tta.LENGTH;
- DB_playItem_t *it = deadbeef->pl_item_alloc ();
- it->decoder_id = deadbeef->plug_get_decoder_id (plugin.plugin.id);
- it->fname = strdup (fname);
- it->filetype = "TTA";
+ DB_playItem_t *it = deadbeef->pl_item_alloc_init (fname, plugin.plugin.id);
+ deadbeef->pl_add_meta (it, ":FILETYPE", "TTA");
deadbeef->pl_set_item_duration (it, dur);
close_tta_file (&tta);
DB_FILE *fp = deadbeef->fopen (fname);
+
+ int64_t fsize = -1;
if (fp) {
+ fsize = deadbeef->fgetlength (fp);
/*int v2err = */deadbeef->junk_id3v2_read (it, fp);
/*int v1err = */deadbeef->junk_id3v1_read (it, fp);
deadbeef->fclose (fp);
@@ -242,6 +223,18 @@ tta_insert (DB_playItem_t *after, const char *fname) {
}
deadbeef->pl_unlock ();
+ char s[100];
+ snprintf (s, sizeof (s), "%lld", fsize);
+ deadbeef->pl_add_meta (it, ":FILE_SIZE", s);
+ snprintf (s, sizeof (s), "%d", tta.BPS);
+ deadbeef->pl_add_meta (it, ":BPS", s);
+ snprintf (s, sizeof (s), "%d", tta.NCH);
+ deadbeef->pl_add_meta (it, ":CHANNELS", s);
+ snprintf (s, sizeof (s), "%d", tta.SAMPLERATE);
+ deadbeef->pl_add_meta (it, ":SAMPLERATE", s);
+ snprintf (s, sizeof (s), "%d", tta.BITRATE);
+ deadbeef->pl_add_meta (it, ":BITRATE", s);
+
cue = deadbeef->pl_insert_cue (after, it, totalsamples, tta.SAMPLERATE);
if (cue) {
deadbeef->pl_item_unref (it);
@@ -257,7 +250,7 @@ tta_insert (DB_playItem_t *after, const char *fname) {
}
static int tta_read_metadata (DB_playItem_t *it) {
- DB_FILE *fp = deadbeef->fopen (it->fname);
+ DB_FILE *fp = deadbeef->fopen (deadbeef->pl_find_meta (it, ":URI"));
if (!fp) {
return -1;
}
@@ -292,7 +285,8 @@ static int tta_write_metadata (DB_playItem_t *it) {
}
int id3v2_version = 4;
- const char *id3v1_encoding = deadbeef->conf_get_str ("mp3.id3v1_encoding", "iso8859-1");
+ char id3v1_encoding[50];
+ deadbeef->conf_get_str ("mp3.id3v1_encoding", "iso8859-1", id3v1_encoding, sizeof (id3v1_encoding));
return deadbeef->junk_rewrite_tags (it, junk_flags, id3v2_version, id3v1_encoding);
}
@@ -313,22 +307,39 @@ static const char *filetypes[] = { "TTA", NULL };
// define plugin interface
static DB_decoder_t plugin = {
DB_PLUGIN_SET_API_VERSION
- .plugin.version_major = 0,
- .plugin.version_minor = 1,
+ .plugin.version_major = 1,
+ .plugin.version_minor = 0,
.plugin.type = DB_PLUGIN_DECODER,
.plugin.id = "tta",
.plugin.name = "tta decoder",
.plugin.descr = "tta decoder based on TTA Hardware Players Library Version 1.2",
- .plugin.author = "Alexey Yakovenko",
- .plugin.email = "waker@users.sourceforge.net",
+ .plugin.copyright =
+ "Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>\n"
+ "\n"
+ "Uses modified TTA Hardware Players Library Version 1.2,\n"
+ "(c) 2004 Alexander Djourik. All rights reserved.\n"
+ "\n"
+ "This program is free software; you can redistribute it and/or\n"
+ "modify it under the terms of the GNU General Public License\n"
+ "as published by the Free Software Foundation; either version 2\n"
+ "of the License, or (at your option) any later version.\n"
+ "\n"
+ "This program is distributed in the hope that it will be useful,\n"
+ "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+ "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+ "GNU General Public License for more details.\n"
+ "\n"
+ "You should have received a copy of the GNU General Public License\n"
+ "along with this program; if not, write to the Free Software\n"
+ "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n"
+ ,
.plugin.website = "http://deadbeef.sf.net",
.plugin.start = tta_start,
.plugin.stop = tta_stop,
.open = tta_open,
.init = tta_init,
.free = tta_free,
- .read_int16 = tta_read_int16,
-// .read_float32 = tta_read_float32,
+ .read = tta_read,
.seek = tta_seek,
.seek_sample = tta_seek_sample,
.insert = tta_insert,
diff --git a/plugins/uade2/plugin.c b/plugins/uade2/plugin.c
new file mode 100644
index 00000000..a07f82fe
--- /dev/null
+++ b/plugins/uade2/plugin.c
@@ -0,0 +1,692 @@
+/*
+ ddb_input_uade2 - UADE input plugin for DeaDBeeF player
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
+ based on UADE2 plugin for Audacious, Copyright (C) 2005-2006 Heikki Orsila, UADE TEAM
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <signal.h>
+#include "../../deadbeef.h"
+#include "uadeipc.h"
+#include "eagleplayer.h"
+#include "uadeconfig.h"
+#include "uadecontrol.h"
+#include "uadeconstants.h"
+#include "ossupport.h"
+#include "uadeconf.h"
+#include "effects.h"
+#include "sysincludes.h"
+#include "songdb.h"
+#include "songinfo.h"
+
+#define min(x,y) ((x)<(y)?(x):(y))
+#define max(x,y) ((x)>(y)?(x):(y))
+
+#define trace(...) { fprintf(stderr, __VA_ARGS__); }
+//#define trace(fmt,...)
+
+static char configname[PATH_MAX];
+static struct uade_config config_backup;
+static time_t config_load_time;
+static time_t md5_load_time;
+static char md5name[PATH_MAX];
+static char songconfname[PATH_MAX];
+static char gui_filename[PATH_MAX];
+
+static const char *
+get_uade_base_conf_dir (void) {
+ return UADE_CONFIG_BASE_DIR;
+}
+
+static void load_content_db(void)
+{
+ struct stat st;
+ time_t curtime = time(NULL);
+ char name[PATH_MAX];
+
+ if (curtime)
+ md5_load_time = curtime;
+
+ if (md5name[0] == 0) {
+ char *home = uade_open_create_home();
+ if (home)
+ snprintf(md5name, sizeof md5name, "%s/.uade2/contentdb", home);
+ }
+
+ /* User database has priority over global database, so we read it first */
+ if (md5name[0]) {
+ if (stat(md5name, &st) == 0) {
+ if (uade_read_content_db(md5name))
+ return;
+ } else {
+ FILE *f = fopen(md5name, "w");
+ if (f)
+ fclose(f);
+ uade_read_content_db(md5name);
+ }
+ }
+
+ snprintf(name, sizeof name, "%s/contentdb.conf", get_uade_base_conf_dir ());
+ if (stat(name, &st) == 0)
+ uade_read_content_db(name);
+}
+
+/* xmms initializes uade by calling this function */
+static void uade_init(void)
+{
+ static int initialized = 0;
+ if (!initialized) {
+ char *home;
+ int config_loaded;
+
+ config_load_time = time(NULL);
+
+ config_loaded = uade_load_initial_config(configname, sizeof configname,
+ &config_backup, NULL);
+
+ load_content_db();
+
+ uade_load_initial_song_conf(songconfname, sizeof songconfname,
+ &config_backup, NULL);
+
+ home = uade_open_create_home();
+
+ if (home != NULL) {
+ /* If config exists in home, ignore global uade.conf. */
+ snprintf(configname, sizeof configname, "%s/.uade2/uade.conf", home);
+ }
+
+ if (config_loaded == 0) {
+ fprintf(stderr, "No config file found for UADE XMMS plugin. Will try to load config from\n");
+ fprintf(stderr, "$HOME/.uade2/uade.conf in the future.\n");
+ }
+ initialized = 1;
+ }
+}
+
+static void uade_get_song_info(const char *filename, char **title, int *length)
+{
+ char tempname[PATH_MAX];
+ const char *t;
+
+ if (strncmp(filename, "uade://", 7) == 0)
+ filename += 7;
+
+ strlcpy(tempname, filename, sizeof tempname);
+ t = basename(tempname);
+ if (t == NULL)
+ t = filename;
+ if ((*title = strdup(t)) == NULL)
+ trace("Not enough memory for song info.\n");
+ *length = -1;
+}
+
+int uade_get_max_subsong(struct uade_state *state, int def)
+{
+ int subsong;
+ subsong = -1;
+ if (state->song != NULL)
+ subsong = state->song->max_subsong;
+ if (subsong == -1)
+ subsong = def;
+ return subsong;
+}
+
+
+int uade_get_min_subsong(struct uade_state *state, int def)
+{
+ int subsong;
+ subsong = -1;
+ if (state->song != NULL)
+ subsong = state->song->min_subsong;
+ if (subsong == -1)
+ subsong = def;
+ return subsong;
+}
+
+DB_functions_t *deadbeef;
+static DB_decoder_t plugin;
+
+static const char *exts[] = { NULL };
+static const char *prefixes[] = { "mod", NULL };
+static const char *filetypes[] = { "UADE", NULL };
+
+#define UADE_BUFFER_SIZE 100000
+
+typedef struct {
+ DB_fileinfo_t info;
+ struct uade_state state;
+ int controlstate;
+ int record_playtime;
+ int remaining;
+ char buffer[UADE_BUFFER_SIZE];
+ int subsong_end;
+ int song_end_trigger;
+ int64_t skip_bytes;
+ int abort_playing;
+ int uade_seek_forward;
+} uade_info_t;
+
+DB_fileinfo_t *
+uadeplug_open (uint32_t hints) {
+ DB_fileinfo_t *_info = malloc (sizeof (uade_info_t));
+ uade_info_t *info = (uade_info_t *)_info;
+ memset (info, 0, sizeof (uade_info_t));
+ return _info;
+}
+
+static int
+uadeplug_init (DB_fileinfo_t *_info, DB_playItem_t *it) {
+ uade_info_t *info = (uade_info_t *)_info;
+
+ uade_init ();
+ char modulename[PATH_MAX];
+ char playername[PATH_MAX];
+ char scorename[PATH_MAX];
+ char gui_module_filename[PATH_MAX];
+ char gui_player_filename[PATH_MAX];
+
+ info->state.config = config_backup;
+ info->state.validconfig = 1;
+
+ printf ("probing the file\n");
+ int ret = uade_is_our_file(it->fname, 0, &info->state);
+
+ if (!ret) {
+ trace ("not uade file\n");
+ return -1;
+ }
+ strlcpy(modulename, it->fname, sizeof modulename);
+ trace ("modulename: %s\n", modulename);
+ strlcpy(gui_module_filename, it->fname, sizeof gui_module_filename);
+ trace ("gui_module_fname: %s\n", gui_module_filename);
+
+ snprintf(scorename, sizeof scorename, "%s/score", get_uade_base_conf_dir ());
+ trace ("scorename: %s\n", scorename);
+
+ if (strcmp(info->state.ep->playername, "custom") == 0) {
+ strlcpy(playername, modulename, sizeof playername);
+ modulename[0] = 0;
+ gui_module_filename[0] = 0;
+ } else {
+ snprintf(playername, sizeof playername, "%s/players/%s", get_uade_base_conf_dir (), info->state.ep->playername);
+ }
+ trace ("playername: %s\n", playername);
+
+ if (!uade_alloc_song(&info->state, it->fname)) {
+ trace ("uade_alloc_song fail\n");
+ return -1;
+ }
+
+ uade_set_ep_attributes(&info->state);
+
+ uade_set_song_attributes(&info->state, playername, sizeof playername);
+
+ uade_set_effects(&info->state);
+
+ strlcpy(gui_player_filename, playername, sizeof gui_player_filename);
+
+ if (!info->state.pid) {
+ char configname[PATH_MAX];
+ snprintf(configname, sizeof configname, "%s/uaerc", UADE_CONFIG_BASE_DIR);
+ uade_spawn(&info->state, UADE_CONFIG_UADE_CORE, configname);
+ }
+
+ printf ("uade_song_initialization\n");
+ ret = uade_song_initialization(scorename, playername, modulename, &info->state);
+ if (ret) {
+ if (ret != UADECORE_CANT_PLAY && ret != UADECORE_INIT_ERROR) {
+ fprintf(stderr, "Can not initialize song. Unknown error.\n");
+ return -1;
+ }
+ uade_unalloc_song(&info->state);
+ return -1;
+ }
+ printf ("init done\n");
+ int minsong = uade_get_min_subsong (&info->state, 0);
+ int maxsong = uade_get_max_subsong (&info->state, 0);
+ info->state.song->cur_subsong = it->tracknum;
+ uade_change_subsong(&info->state);
+
+ _info->fmt.bps = 16;
+ _info->fmt.channels = UADE_CHANNELS;
+ _info->fmt.samplerate = info->state.config.frequency;
+ for (int i = 0; i < _info->fmt.channels; i++) {
+ _info->fmt.channelmask |= 1 << i;
+ }
+ _info->readpos = 0;
+ _info->plugin = &plugin;
+ info->record_playtime = 1;
+ info->controlstate = UADE_S_STATE;
+
+ return 0;
+}
+
+// free everything allocated in _init
+static void
+uadeplug_free (DB_fileinfo_t *_info) {
+ uade_info_t *info = (uade_info_t *)_info;
+ if (info) {
+ uade_unalloc_song(&info->state);
+ if (info->state.pid) {
+ kill(info->state.pid, SIGTERM);
+ }
+ free (info);
+ }
+}
+
+int
+uadeplug_frame (uade_info_t *info) {
+ uint8_t space[UADE_MAX_MESSAGE_SIZE];
+ struct uade_msg *um = (struct uade_msg *) space;
+ uint16_t *sm;
+ int i;
+ unsigned int play_bytes, tailbytes = 0;
+ uint64_t subsong_bytes = 0;
+ int framesize = UADE_CHANNELS * UADE_BYTES_PER_SAMPLE;
+ int left = 0;
+ char gui_formatname[256];
+ char gui_modulename[256];
+ char gui_playername[256];
+ char *reason;
+ uint32_t *u32ptr;
+ int frame_received = 0;
+
+ while (!frame_received) {
+ if (info->controlstate == UADE_S_STATE) {
+
+ assert(left == 0);
+
+ if (info->abort_playing) {
+ info->record_playtime = 0;
+ break;
+ }
+
+ if (info->uade_seek_forward) {
+ info->skip_bytes += info->uade_seek_forward * (UADE_BYTES_PER_FRAME * info->state.config.frequency);
+ info->uade_seek_forward = 0;
+ }
+
+ left = uade_read_request(&info->state.ipc);
+
+ if (uade_send_short_message(UADE_COMMAND_TOKEN, &info->state.ipc)) {
+ fprintf(stderr, "Can not send token.\n");
+ return -1;
+ }
+ info->controlstate = UADE_R_STATE;
+
+ } else {
+
+ if (uade_receive_message(um, sizeof(space), &info->state.ipc) <= 0) {
+ fprintf(stderr, "Can not receive events from uade\n");
+ exit(-1);
+ }
+
+
+ switch (um->msgtype) {
+
+ case UADE_COMMAND_TOKEN:
+ info->controlstate = UADE_S_STATE;
+ break;
+
+ case UADE_REPLY_DATA:
+ sm = (uint16_t *) um->data;
+ for (i = 0; i < um->size; i += 2) {
+ *sm = ntohs(*sm);
+ sm++;
+ }
+
+ if (info->subsong_end) {
+ play_bytes = tailbytes;
+ tailbytes = 0;
+ } else {
+ play_bytes = um->size;
+ }
+
+ if (info->subsong_end == 0 && info->song_end_trigger == 0 &&
+ uade_test_silence(um->data, play_bytes, &info->state)) {
+ info->subsong_end = 1;
+ }
+
+ subsong_bytes += play_bytes;
+ info->state.song->out_bytes += play_bytes;
+
+ if (info->skip_bytes > 0) {
+ if (play_bytes <= info->skip_bytes) {
+ info->skip_bytes -= play_bytes;
+ play_bytes = 0;
+ } else {
+ play_bytes -= info->skip_bytes;
+ info->skip_bytes = 0;
+ }
+ }
+
+ uade_effect_run(&info->state.effects, (int16_t *) um->data, play_bytes / framesize);
+
+ // ... copy data ...
+ memcpy (info->buffer + info->remaining, um->data, play_bytes);
+ frame_received = 1;
+ info->remaining += play_bytes;
+
+ if (info->state.config.timeout != -1 && info->state.config.use_timeouts) {
+ if (info->song_end_trigger == 0) {
+ if (info->state.song->out_bytes / (UADE_BYTES_PER_FRAME * info->state.config.frequency) >= info->state.config.timeout) {
+ info->song_end_trigger = 1;
+ info->record_playtime = 0;
+ }
+ }
+ }
+
+ if (info->state.config.subsong_timeout != -1 && info->state.config.use_timeouts) {
+ if (info->subsong_end == 0 && info->song_end_trigger == 0) {
+ if (subsong_bytes / (UADE_BYTES_PER_FRAME * info->state.config.frequency) >= info->state.config.subsong_timeout) {
+ info->subsong_end = 1;
+ info->record_playtime = 0;
+ }
+ }
+ }
+
+ assert (left >= um->size);
+ left -= um->size;
+ break;
+
+ case UADE_REPLY_FORMATNAME:
+ uade_check_fix_string(um, 128);
+ strlcpy(gui_formatname, (char *) um->data, sizeof gui_formatname);
+ strlcpy(info->state.song->formatname, (char *) um->data, sizeof info->state.song->formatname);
+ break;
+
+ case UADE_REPLY_MODULENAME:
+ uade_check_fix_string(um, 128);
+ strlcpy(gui_modulename, (char *) um->data, sizeof gui_modulename);
+ strlcpy(info->state.song->modulename, (char *) um->data, sizeof info->state.song->modulename);
+ break;
+
+ case UADE_REPLY_MSG:
+ uade_check_fix_string(um, 128);
+ trace ("Message: %s\n", (char *) um->data);
+ break;
+
+ case UADE_REPLY_PLAYERNAME:
+ uade_check_fix_string(um, 128);
+ strlcpy(gui_playername, (char *) um->data, sizeof gui_playername);
+ strlcpy(info->state.song->playername, (char *) um->data, sizeof info->state.song->playername);
+ break;
+
+ case UADE_REPLY_SONG_END:
+ if (um->size < 9) {
+ fprintf(stderr, "Invalid song end reply\n");
+ exit(-1);
+ }
+ tailbytes = ntohl(((uint32_t *) um->data)[0]);
+ /* next ntohl() is only there for a principle. it is not useful */
+ if (ntohl(((uint32_t *) um->data)[1]) == 0) {
+ /* normal happy song end. go to next subsong if any */
+ info->subsong_end = 1;
+ } else {
+ /* unhappy song end (error in the 68k side). skip to next song
+ ignoring possible subsongs */
+ info->song_end_trigger = 1;
+ }
+ i = 0;
+ reason = (char *) &um->data[8];
+ while (reason[i] && i < (um->size - 8))
+ i++;
+ if (reason[i] != 0 || (i != (um->size - 9))) {
+ fprintf(stderr, "Broken reason string with song end notice\n");
+ exit(-1);
+ }
+ /* fprintf(stderr, "Song end (%s)\n", reason); */
+ break;
+
+ case UADE_REPLY_SUBSONG_INFO:
+ if (um->size != 12) {
+ fprintf(stderr, "subsong info: too short a message\n");
+ exit(-1);
+ }
+ u32ptr = (uint32_t *) um->data;
+ info->state.song->min_subsong = ntohl(u32ptr[0]);
+ info->state.song->max_subsong = ntohl(u32ptr[1]);
+ info->state.song->cur_subsong = ntohl(u32ptr[2]);
+
+ if (!(-1 <= info->state.song->min_subsong && info->state.song->min_subsong <= info->state.song->cur_subsong && info->state.song->cur_subsong <= info->state.song->max_subsong)) {
+ int tempmin = info->state.song->min_subsong, tempmax = info->state.song->max_subsong;
+ fprintf(stderr, "uade: The player is broken. Subsong info does not match with %s.\n", gui_filename);
+ info->state.song->min_subsong = tempmin <= tempmax ? tempmin : tempmax;
+ info->state.song->max_subsong = tempmax >= tempmin ? tempmax : tempmin;
+ if (info->state.song->cur_subsong > info->state.song->max_subsong)
+ info->state.song->max_subsong = info->state.song->cur_subsong;
+ else if (info->state.song->cur_subsong < info->state.song->min_subsong)
+ info->state.song->min_subsong = info->state.song->cur_subsong;
+ }
+ break;
+
+ default:
+ fprintf(stderr, "Expected sound data. got %d.\n", um->msgtype);
+ return -1;
+ }
+ }
+ }
+ return 0;
+}
+
+
+// try decode `size' bytes
+// return number of decoded bytes
+// or 0 on EOF/error
+static int
+uadeplug_read (DB_fileinfo_t *_info, char *bytes, int size) {
+ uade_info_t *info = (uade_info_t *)_info;
+ int samplesize = _info->fmt.channels * _info->fmt.bps / 8;
+ int initsize = size;
+
+ while (size > 0) {
+ if (info->remaining) {
+ int n = min (info->remaining, size);
+ memcpy (bytes, info->buffer, n);
+ bytes += n;
+ size -= n;
+ if (n < info->remaining) {
+ memmove (info->buffer, info->buffer + n, info->remaining-n);
+ info->remaining -= n;
+ break;
+ }
+ info->remaining = 0;
+ }
+
+ if (uadeplug_frame (info) < 0) {
+ return initsize-size;
+ }
+ }
+
+ _info->readpos += ((initsize-size) / samplesize) / (float)(_info->fmt.samplerate);
+ return initsize-size;
+}
+
+// seek to specified sample (frame)
+// return 0 on success
+// return -1 on failure
+static int
+uadeplug_seek_sample (DB_fileinfo_t *_info, int sample) {
+ uade_info_t *info = (uade_info_t *)_info;
+
+ _info->readpos = (float)sample / _info->fmt.samplerate;
+ return 0;
+}
+
+// seek to specified time in seconds
+// return 0 on success
+// return -1 on failure
+static int
+uadeplug_seek (DB_fileinfo_t *_info, float time) {
+ return uadeplug_seek_sample (_info, time * _info->fmt.samplerate);
+}
+
+static DB_playItem_t *
+uadeplug_insert (DB_playItem_t *after, const char *fname) {
+ uade_init ();
+
+ char modulename[PATH_MAX];
+ char playername[PATH_MAX];
+ char scorename[PATH_MAX];
+ char gui_module_filename[PATH_MAX];
+ char gui_player_filename[PATH_MAX];
+
+ struct uade_state state;
+ memset (&state, 0, sizeof (state));
+ state.config = config_backup;
+ state.validconfig = 1;
+
+ printf ("probing the file\n");
+ int ret = uade_is_our_file(fname, 0, &state);
+
+ if (!ret) {
+ trace ("not uade file\n");
+ return NULL;
+ }
+
+ strlcpy(modulename, fname, sizeof modulename);
+ trace ("modulename: %s\n", modulename);
+ strlcpy(gui_module_filename, fname, sizeof gui_module_filename);
+ trace ("gui_module_fname: %s\n", gui_module_filename);
+
+ snprintf(scorename, sizeof scorename, "%s/score", get_uade_base_conf_dir ());
+ trace ("scorename: %s\n", scorename);
+
+ if (strcmp(state.ep->playername, "custom") == 0) {
+ strlcpy(playername, modulename, sizeof playername);
+ modulename[0] = 0;
+ gui_module_filename[0] = 0;
+ } else {
+ snprintf(playername, sizeof playername, "%s/players/%s", get_uade_base_conf_dir (), state.ep->playername);
+ }
+ trace ("playername: %s\n", playername);
+
+ if (!uade_alloc_song(&state, fname)) {
+ trace ("uade_alloc_song fail\n");
+ return NULL;
+ }
+
+ uade_set_ep_attributes(&state);
+
+ uade_set_song_attributes(&state, playername, sizeof playername);
+
+ uade_set_effects(&state);
+
+ strlcpy(gui_player_filename, playername, sizeof gui_player_filename);
+
+ if (!state.pid) {
+ char configname[PATH_MAX];
+ snprintf(configname, sizeof configname, "%s/uaerc", UADE_CONFIG_BASE_DIR);
+ uade_spawn(&state, UADE_CONFIG_UADE_CORE, configname);
+ }
+
+ printf ("uade_song_initialization\n");
+ ret = uade_song_initialization(scorename, playername, modulename, &state);
+ if (ret) {
+ if (ret != UADECORE_CANT_PLAY && ret != UADECORE_INIT_ERROR) {
+ fprintf(stderr, "Can not initialize song. Unknown error.\n");
+ return NULL;
+ }
+ uade_unalloc_song(&state);
+ return NULL;
+ }
+ printf ("init done\n");
+ int minsong = uade_get_min_subsong (&state, 0);
+ int maxsong = uade_get_max_subsong (&state, 0);
+
+ char info[256];
+ int playtime = state.song->playtime;
+
+ /* Hack. Set info text and song length late because we didn't know
+ subsong amounts before this. Pass zero as a length so that the
+ graphical play time counter will run but seek is still enabled.
+ Passing -1 as playtime would disable seeking. */
+ if (playtime <= 0)
+ playtime = 0;
+
+ if (uade_generate_song_title(info, sizeof info, &state))
+ strlcpy(info, gui_filename, sizeof info);
+
+// playhandle->set_params(playhandle, info, playtime,
+// UADE_BYTES_PER_FRAME * state.config.frequency,
+// state.config.frequency, UADE_CHANNELS);
+
+
+ // no cuesheet, prepare track for addition
+ DB_playItem_t *it = deadbeef->pl_item_alloc ();
+ it->decoder_id = deadbeef->plug_get_decoder_id (plugin.plugin.id);
+ it->fname = strdup (fname);
+ it->filetype = filetypes[0];
+ float duration = -1;
+ if (playtime != -1) {
+ duration = playtime / 1000.f;
+ }
+ deadbeef->pl_set_item_duration (it, duration);
+
+ // title is empty, this call will set track title to filename without extension
+ const char *fn = strrchr (fname, '/');
+ if (fn) {
+ fn++;
+ }
+ else {
+ fn = fname;
+ }
+ deadbeef->pl_add_meta (it, "title", info);
+
+ // now the track is ready, insert into playlist
+ after = deadbeef->pl_insert_item (after, it);
+ deadbeef->pl_item_unref (it);
+ uade_unalloc_song(&state);
+ if (state.pid) {
+ kill(state.pid, SIGTERM);
+ }
+ return after;
+}
+
+// define plugin interface
+static DB_decoder_t plugin = {
+ DB_PLUGIN_SET_API_VERSION
+ .plugin.version_major = 1,
+ .plugin.version_minor = 0,
+ .plugin.type = DB_PLUGIN_DECODER,
+ .plugin.id = "uade",
+ .plugin.name = "UADE player",
+ .plugin.descr = "amiga module player based on UADE (http://zakalwe.fi/uade/)",
+ .plugin.author = "Alexey Yakovenko",
+ .plugin.email = "waker@users.sourceforge.net",
+ .plugin.website = "http://deadbeef.sf.net",
+ .open = uadeplug_open,
+ .init = uadeplug_init,
+ .free = uadeplug_free,
+ .read = uadeplug_read,
+ .seek = uadeplug_seek,
+ .seek_sample = uadeplug_seek_sample,
+ .insert = uadeplug_insert,
+ .exts = exts,
+ .prefixes = prefixes,
+ .filetypes = filetypes
+};
+
+DB_plugin_t *
+ddb_uade2_load (DB_functions_t *api) {
+ deadbeef = api;
+ return DB_PLUGIN (&plugin);
+}
diff --git a/plugins/uade2/uade-2.13/AUTHORS b/plugins/uade2/uade-2.13/AUTHORS
new file mode 100644
index 00000000..b1d24130
--- /dev/null
+++ b/plugins/uade2/uade-2.13/AUTHORS
@@ -0,0 +1,59 @@
+Authors of UADE
+---------------
+
+Main authors
+------------
+
+ - Heikki Orsila <heikki.orsila@iki.fi>
+ - Michael Doering <mldoering@gmx.net>
+
+Subsystems
+----------
+
+ - Antti S. Lankila <alankila@bel.fi> for filter emulation and sound effects
+ - Claudio Matsuoka and Hipolito Carraro Jr for module decruncing code in
+ uade 1.xy.
+ jah@fh-zwickau.de for unsqsh
+ Sipos Attila for unsqsh checksum
+ Olivier Lapicque for mmcp
+ Marc Espie (old depack.c)
+ - Harry "Piru" Sintonen <sintonen@iki.fi> for AmigaOS and MorphOS port
+ - Martin Blapp for configure fixes and enhancements from FreeBSD project
+ - Michael S. Baltaks for Mac OS X port
+ - Nicolas A. Mendoza (part of the AmigaOS port)
+ - Stuart 'kyzer' Caie for Mac OS X port and powerpacker decruncher
+ http://www.kyz.uklinux.net
+
+Everyone from UAE project. See doc/UAE-CREDITS.
+
+Eagleplayers
+------------
+
+ - Don Adan / Wanted Team
+ - Eagleeye and Buggs from Defect (Eagleplayer project authors)
+ - Nicolas Frank <gryzor@club-internet.fr> for PTK-Prowiz
+ - Andy Silva <silva@psi5.com> for his replayers
+ - Bartman and Dexter from Abyss for AHX v2 replay routine:
+ http://www.the-leader-of-the-eighties.de
+ - Brian Postma <b.postma@hetnet.nl> for Brian's Soundmonitor player
+ http://www.homepages.hetnet.nl/~brianpostma
+ - Nicolas Pomared <npomarede@kaptech.com> for MYST/YMST replayer
+ - Sean Connolly for EMS V6 replay: http://www.cosine-systems.com/
+ - Stephen Mifsud (Malta) <teknologik@technologist.com> for Darius Zendeh
+ replayer. http://www.marz-kreations.com
+ - Sunbeam/Shelter for his replayers
+ - Paul v.d. Valk for Medley replay routine
+ - Tap & Walt for digibooster source
+ http://www.highantdev2.de/dbpro/index.php
+ - The Welder / Divine for protracker replay routine
+
+ - Everyone else whose Eagleplayer plugins we use. Respective authors of
+ eagleplayer plugins can be found from inside the plugin.
+
+Media
+-----
+
+Manfred Linzner aka Pink/Abyss <linzner@shinen.com> for a great test tune
+(AHX.Cruisin).
+
+
diff --git a/plugins/uade2/uade-2.13/COPYING b/plugins/uade2/uade-2.13/COPYING
new file mode 100644
index 00000000..d8917caa
--- /dev/null
+++ b/plugins/uade2/uade-2.13/COPYING
@@ -0,0 +1,12 @@
+This source distribution contains works with various licenses. Please read
+copyright notices of those works before reuse.
+
+All the code from the UAE (Unix Amiga Emulator) project is licensed
+under the GNU GPL. Read COPYING.GPL for details of the GNU GPL license.
+UAE people work is credited in doc/UAE-* files.
+
+Files under players/ directory are licensed with various different licenses
+and quite a many different copyright holders. See inside the player binaries
+for more details.
+
+Sound core in directory amigasrc/score/ is licensed under the GNU LGPL.
diff --git a/plugins/uade2/uade-2.13/COPYING.GPL b/plugins/uade2/uade-2.13/COPYING.GPL
new file mode 100644
index 00000000..60549be5
--- /dev/null
+++ b/plugins/uade2/uade-2.13/COPYING.GPL
@@ -0,0 +1,340 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) 19yy <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) 19yy name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/plugins/uade2/uade-2.13/COPYING.LGPL b/plugins/uade2/uade-2.13/COPYING.LGPL
new file mode 100644
index 00000000..8add30ad
--- /dev/null
+++ b/plugins/uade2/uade-2.13/COPYING.LGPL
@@ -0,0 +1,504 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
+
+
diff --git a/plugins/uade2/uade-2.13/ChangeLog b/plugins/uade2/uade-2.13/ChangeLog
new file mode 100644
index 00000000..54a2d409
--- /dev/null
+++ b/plugins/uade2/uade-2.13/ChangeLog
@@ -0,0 +1,1907 @@
+
+* ALL THE CHANGE LOG ENTRIES SINCE 2007-05-28 ARE IN THE GIT REPOSITORY. USE
+ "git log" COMMAND
+
+2007-05-28 Heikki Orsila <heikki.orsila@iki.fi>
+ - The development has been moved to a Git repository. Please issue
+ "git-clone git://zakalwe.fi/uade uade.git" to checkout the latest
+ version from the repository.
+
+2007-05-27 Heikki Orsila <heikki.orsila@iki.fi>
+ - Commit messages into version repository should from now on include
+ a short tag explaining the nature of the commit.
+ The tags are:
+ * [ADAPTIVE] - adaptive maintenance: the commit makes software to
+ work better with the surrounding environment (compilers, libraries,
+ path names ...)
+ * [CORRECTVE] - corrective maintenance: fix a defect in the program
+ * [PERFECTIVE] - perfective maintenance: used when adding a feature
+ or improving an existing feature
+ * [PREVENTIVE] - preventive maintenance: used when refactoring,
+ cleaning or asserting the code, or adding self-tests
+
+ See http://www.site.uottawa.ca:4321/oose/index.html#maintenance
+
+ - Fixed Audacious plugin to work for Audacious 1.4/2.x
+ Christian Birchinger <joker@netswarm.net> [ADAPTIVE] [CORRECTIVE]
+
+2007-05-03 Michael Doering <mld@users.sourceforge.net>
+ - Added a new version of Synthdream replayer from Don Adan
+
+2007-04-30 Heikki Orsila <heikki.orsila@iki.fi>
+ * UADE 2.07 (Walpurgis night)
+ - Added Special FX ST replayer from Don Adan
+ - Added a new version of Special FX replayer from Don Adan
+ - Work-arounded libao/alsa so that it drains the audio device for
+ the last few milliseconds of sample data for the last played song.
+ Thanks to Cthulhu for pointing out the problem.
+ - Many fixes in song length database code
+ # Fixed a bug that only the last played subsong time was recorded
+ into the song db
+ # Fixed a file-locking race condition in song db
+ # Fixed a song db corruption bug
+ # Cleaned song db code
+ - Support for full Drag and Drop/Local URL Support in Audacious 1.3
+ plugin
+ - Fixed misdetection and modlen calculation bug of Soundtracker IV
+ mods
+
+2007-04-29 Heikki Orsila <heikki.orsila@iki.fi>
+ - Added Special FX ST replayer from Don Adan
+ - Added a new version of Special FX replayer from Don Adan
+
+2007-04-27 Heikki Orsila <heikki.orsila@iki.fi>
+ - Work-arounded libao/alsa so that it drains the audio device for
+ the last few milliseconds of song data for the last played song.
+ Thanks to Cthulhu for pointing out the problem.
+
+2007-04-15 Michael Doering <mld@users.sourceforge.net>
+ - Bug in songlength database handling fixed (shd)
+
+2007-04-14 Michael Doering <mld@users.sourceforge.net>
+ - Support for full Drag and Drop/Local URL Support in Audacious 1.3
+ plugin. (shd, mld)
+ - Fixed misdetection and modlen calculation bug of Soundtracker IV
+ mods. (shd/mld)
+
+2007-04-09 Heikki Orsila <heikki.orsila@iki.fi>
+ * UADE 2.06 (7 YEARS BIRTHDAY PARTY AT PAULAS!)
+ - UADE project is now exactly 7 years old \o/ PARTY!
+ - Started working for Audacious 1.3 support, at least songs that
+ are added directly through playlist should work if they are
+ regular files. Audacious VFS is not supported in general. Nothing
+ else is guaranteed. Audacious < 1.3 works as in the past.
+ - Infogrames replayer improved, gobliins 2 et al. play with correct
+ tempo
+ - Added new Quartet ST player from Don Adan / Wanted Team
+ (qts.* files)
+ - KRIS aka Chip Tracker replayer (KRIS.* files) from Don Adan /
+ Wanted team. This replaces PTK-Prowiz for Chip Tracker songs, so
+ not a new format.
+ - Quartet PSG replayer (SQT.* files) from Don Adan / Wanted Team
+ - Many small changes, cleanups etc
+
+ - Fixed user installation of Audacious 1.3 plugin...
+
+2007-03-19 Michael Doering <mld@users.sourceforge.net>
+ - Merged Christian Birchingers Audacious 1.3.x API Patches in.
+
+2007-03-03 Heikki Orsila <heikki.orsila@iki.fi>
+ - KRIS aka Chip Tracker replayer (KRIS.* files) from Don Adan /
+ Wanted team. This replaces PTK-Prowiz for Chip Tracker songs, so
+ not a new format.
+ - Quartet PSG replayer (SQT.* files) from Don Adan / Wanted Team
+
+2007-02-13 Heikki Orsila <heikki.orsila@iki.fi>
+ - Updated Inforgrames player to use tempo 0x24ff for Ween songs.
+ Thanks to DrMcCoy of SCUMM VM project.
+ - Reverted Michael's 2007-02-13 patch regarding LC_Numeric and
+ strtod(). Fixed the problem manually by converting x,y values into
+ x.y format and vice versa.
+
+2007-02-13 Michael Doering <mld@users.sourceforge.net>
+ - Fix for German LC_Numeric="," parameters in uadeconfig.c.
+ Thanks for Steffen Wulf for reporting.
+ - Bumped Version to 2.05. :-)
+
+2007-02-08 Michael Doering <mld@users.sourceforge.net>
+ - Added new Quartet ST player from Don Adan / Wanted Team
+ (qts.* files). Great work as ever Don!
+ - Disabled Hippel COSO check in amifilemagic.c to avoid a conflict
+ between Amiga and Atari ST Coso Files.
+ TODO: The file heuristics for Coso in amifilemagic.c has to be fixed,
+ the checkroutine of the Amiga Hippel-Coso replayer isn't HIP-ST Coso
+ aware either.
+
+2007-02-06 Michael Doering <mld@users.sourceforge.net>
+ - Small correction of shd's patch in PTK-Prowiz commited.
+
+2007-02-05 Michael Doering <mld@users.sourceforge.net>
+ - Applied shd's uade_new_get_info patch to PTK-Prowiz.
+
+2007-02-04 Michael Doering <mld@users.sourceforge.net>
+ - Added sanity check to query eagleopts in PTK-Prowiz (needed for
+ score fix)
+ - Added a new uade.library method: UadeNewGetInfo(). It is now used
+ with Infogrames replayer (see
+ amigasrc/players/infogrames/Infogrames.asm). It will be used with
+ PTK-Prowiz soon. Documentation for UadeNewGetInfo() can be read
+ from amigasrc/score/score.s, see function "uade_new_get_info".
+
+2007-02-03 Heikki Orsila <heikki.orsila@iki.fi>
+ - Disassembled Andy Silvas Infogrames replayer, added a work-around
+ list for Gobliins 2 songs to fix tempo. Thanks to Sven Hesse of
+ ScummVM project for letting us know of the tempo problem.
+ The next thing to do is go through all Infogrames games with UAE
+ and record the tempo value for each song? Any volunteers?-)
+
+2007-01-30 Michael Doering <mld@users.sourceforge.net>
+ - Changed Scrollbar policy for audacious modinfo to avoid
+ ugly line breaking in hexmode
+
+2007-01-25 Heikki Orsila <heikki.orsila@iki.fi>
+ * UADE 2.05 (It came from the Paula)
+ - This release workarounds scheduler features of some 2.6.x Linux
+ kernels. IPC method was changed to use sockets instead of pipes,
+ which significantly reduces buffer underruns. This is really the
+ only change affecting scheduling! Weird.
+
+2007-01-24 Heikki Orsila <heikki.orsila@iki.fi>
+ - Fixed compilation for platforms that lack memmem(), such as Mac.
+ The compilation bug was introduced at 2007-01-21 when unixipc
+ and unixsupport were merged.
+
+2007-01-22 Michael Doering <mld@users.sourceforge.net>
+ - Fixed songinfo for mods detected as Protracker compatible
+
+2007-01-21 Heikki Orsila <heikki.orsila@iki.fi>
+ - Merge unixipc.c and unixsupport.c. Modularise uadecore spawn into
+ unixsupport.c.
+ - Move from pipe based IPC communication to UNIX socket based
+ communication. This solves a scheduling problem for some 2.6.x Linux
+ kernels.
+
+2007-01-21 Heikki Orsila <heikki.orsila@iki.fi>
+ * UADE 2.04 (Defective by Design .org)
+ - Added Jochen Hippel ST player (hst.* files)
+ - Added Quartet player from Don Adan / Wanted Team (qpa.* files)
+ - Updated Mark Cookset replayer with a new version from Don Adan of
+ Wanted Team
+ - It's now possible to command an eagleplayer listed in
+ eagleplayer.conf to ignore file type check. This is useful
+ with the CustomMade replayer as it rejects some valid song files.
+ See the change log entry from 2007-01-02 and the man page
+ about song.conf and eagleplayer.conf.
+ - Cygwin work-around (locking on song contents db is broken). Does
+ NOT affect unixes.
+ - Amiga memory size can now be configured properly from ~/.uade2/uaerc.
+ This is useful with big sound files (rare).
+ - Fixed the sinc filter, it had a bug that made it less accurate
+ - Man page updates about filters
+ - GCC 4.x clean ups
+ - Small bug fixes. The default uade.conf had a deprecated option
+ in comments. It was removed.
+ - Updated installation instructions
+
+2007-01-18 Heikki Orsila <heikki.orsila@iki.fi>
+ - Fixed a bug in default uade.conf. "headphone" option for the
+ uade.conf was obsoleted at 2006-05-13, the new option name
+ became "headphones". The backward compatibility is retained
+ again and thus "headphone" option will work to some future.
+ - Fixed several missing cvs sticky bits (-kb) in players/ dir
+
+2007-01-15 Michael Doering <mld@users.sourceforge.net>
+ - Made "detect_format_by_content" parameter for modfiles default.
+ This way only true Amiga 4ch mod files now get played.
+ - Added Quartet player from Don Adan / Wanted Team. It recognizes
+ QPA.* files.
+
+2007-01-12 Heikki Orsila <heikki.orsila@iki.fi>
+ - Added "ignore_player_check" option for eagleplayer.conf and
+ song.conf. It is useful with bad eagleplayers and rips. This
+ feature was requested for use with CustomMade player and therefore
+ this option will also be made default for that player. See the
+ new eagleplayer.conf.
+
+2007-01-11 Antti S. Lankila <alankila@bel.fi>
+ - Correct some ancient mistakes in uade123.1, regarding filter
+ operation. For instance the LED filter center frequency was
+ reported halved due to an earlier mistake in graph drawing
+
+2006-12-22 Heikki Orsila <heikki.orsila@iki.fi>
+ - Added Jochen Hippel ST player from Don Adan / Wanted Team. It
+ recognizes HST.* files
+ - Replaced old Mark Cooksey replayer with a new version from
+ Don Adan / Wanted Team
+
+2006-12-07 Antti S. Lankila <alankila@bel.fi>
+ - Remove uadecore with make clean
+
+2006-12-03 Antti S. Laknila <alankila@bel.fi>
+ - Fixed a strict aliasing warning that occured with GCC 4.1 in
+ newcpu.h
+
+2006-12-01 Heikki Orsila <heikki.orsila@iki.fi>
+ - Memory size of Amiga can now be increased over 2 MiB by editing
+ the uaerc file (e.g. ~/.uade2/uaerc). The variable named chipmem_size
+ should be edited. Allocated memory for the amiga is determined by
+ chipmem_size * 512 KiB
+ By default, chipmem_size = 4 -> 2 MiB of memory. This variable can
+ be set up to 16 (8 MiB of memory).
+
+2006-11-26 Heikki Orsila <heikki.orsila@iki.fi>
+ - Updated instructions about -x option in uade123 and its man page.
+
+2006-10-28 Antti S. Lankila <alankila@bel.fi>
+ - Due to me misunderstanding the Kaiser window beta parameter,
+ the BLEP tables for sinc synthesis were set to attenuate aliasing
+ only for 40 dB instead of the target 80 dB.
+
+2006-10-24 Heikki Orsila <heikki.orsila@iki.fi>
+ - No locking with Cygwin -> uade is dangerous with songdb.
+
+2006-10-02 Heikki Orsila <heikki.orsila@iki.fi>
+ - Updated INSTALL.readme to include more dependencies (pkg-config
+ and sed) and tips for Mac OS X compiling (workarounds)
+
+2006-08-27 Heikki Orsila <heikki.orsila@iki.fi>
+ * UADE 2.03 (Microsoft punishment)
+ - Added song.conf support to set song specific attributes for
+ playback, such as ntsc, blank, filtering etc. See the man
+ page. An example, one may add following line to ~/.uade2/song.conf
+ to make fred.hybris_light always timeout on 200 seconds:
+ md5=60f3bb11cc1bacaf77d7c16d13361844 broken_song_end timeout=200 comment FRED.Hybris_Light
+ This need not be added manually, one can just issue:
+ uade123 --set=broken_song_end --set=timeout=200 FRED.Hybris_Light
+ and afterwards uade will always play the song correctly.
+ Similarly, one can fix volume gain for some songs:
+ uade123 --set=gain=2 foo
+ To reset all options for a given song, do:
+ uade123 --set= foo
+ - Fixed PAL audio synthesis frequency (inaudible)
+ - --interpolator=x is now --resampler=x because the function of
+ interpolators was actually resampling.
+ - Only A500 and A1200 filters are now supported and A500 is the
+ default.
+ - Added Play time database support for uade123
+ - Compatibility fixes
+ - Lots of bug fixes
+ - Improvements in uade123 UI (press i or I for info on song)
+ - Improved file magic support for some formats (P61A, Fuzzac, ...)
+ - Hacky NTSC mode support available now. Use --ntsc or ntsc
+ directive in uade123. Also works per-song with song.conf.
+ One can now make specific songs be played in NTSC mode by
+ programming song.conf with proper values. One can issue:
+ uade123 --set=ntsc dw.FooBar
+ or put a line to ~/.uade2/song.conf:
+ md5=225bbb405433c7c05fe10b99b8e088ff ntsc comment dw.AlfredChicken
+ - One can force protracker replayer to use VBlank timing with many
+ ways, see the man page on section EAGLEPLAYER OPTIONS. For example,
+ do:
+ uade123 -x vblank mod.FooBar
+ - Enhancements in PTK-Prowiz. Protracker version is now selectable
+ between 3.0b, 2.3a and 1.0c. See the man page section EAGLEPLAYERS
+ OPTIONS. This option is not yet guaranteed to be 100% but may
+ fix some immediate problems with some songs.. These settings
+ may also be recorded to song.conf so that one only has to give
+ these parameters once. Example:
+ uade123 -x type:pt10c mod.TheClassicProtrackerVersionedSong
+ btw. uade is probably the first mod player for non-amigas that
+ has a direct version support for protrackers.
+ - Improved some players
+ - Titles in audacious and xmms plugins on the playlist are now
+ programmable with uade.conf. The default is
+ song_title %F %X [%P]
+ This displays filename, subsong (if more than one) and player.
+ See SONG TITLE SPECIFICATION section in the man page. There's a
+ small help in the uade.conf too.
+ - Significant code refactorizations
+ - Fixed a memory leak issue (see Change log on 2006-04-15)
+ - Added Dirk Bialluch format support by Don Adan/Wanted Team
+
+2006-07-27 Heikki Orsila <heikki.orsila@iki.fi>
+ - Removed -fno-strength-reduce from src/Makefile.in. Some old
+ GCC 2.x versions had bugged strength reduce, but it shouldn't
+ matter anymore. Maybe the compiler will produce better code
+ without this. AHX.cruisin showed approx 3% speedup :) Thanks
+ to alankila for pointing out use of this flag.
+
+2006-07-17 Heikki Orsila <heikki.orsila@iki.fi>
+ - Fixed a segfault bug in songdb caused by recent changes to add
+ subsong volume normalisation info to contentdb. Segfaults were
+ catched in several places due to uninitialized vplist in
+ struct uade_content.
+
+2006-07-02 Heikki Orsila <heikki.orsila@iki.fi>
+ - Merged an initial version of volume normalization effect from
+ alankila.
+ - Split song.conf and contentdb related functionality away from
+ eagleplayer.c to songdb.c.
+
+2006-06-30 Heikki Orsila <heikki.orsila@iki.fi>
+ - Work-arounded signedness warnings with GCC4 in src/frontends/common/
+
+2006-06-23 Heikki Orsila <heikki.orsila@iki.fi>
+ - Fix sinc resampler to support --filter=none (alankila)
+ - Optimize sinc_handler() inner-loop by avoiding unnecessary
+ indexing (alankila)
+
+2006-06-22 Heikki Orsila <heikki.orsila@iki.fi>
+ - Separated accumulator and sinc resamplers into separate functions
+ in src/audio.c.
+ - Removed "anti" name from resampler list. "anti" has been the
+ "default" for a long time already.
+ - Change FIR convolution of sinc into bandlimited step synthesis.
+ Filters are applied directly by the BLEPs. Warning, sinc and
+ filtering are now integrated together so they can not be
+ changed separately (breaking modular development idea). The
+ default resampler does not suffer from this modularity problem
+ and it is still the recommended resampler. (alankila)
+
+2006-06-18 Heikki Orsila <heikki.orsila@iki.fi>
+ - Added play time database saving support into uade123.
+
+2006-05-22 Heikki Orsila <heikki.orsila@iki.fi>
+ - Changed --magic to --detect-format-by-content and changed
+ corresponding "content_detection" directive in eagleplayer.conf and
+ uade.conf to "detect_format_by_content". Changed --no-song-end to
+ "--no-ep-end-detect".
+
+2006-05-20 Heikki Orsila <heikki.orsila@iki.fi>
+ - Changed default input file to be /dev/tty instead of stdin for
+ uade123. Also, failing terminal setup (input file is not a tty)
+ is not a fatal error.
+ - Added a warning to eagleplayer.conf parsing for the situation
+ that user has removed all prefixes from an eagleplayer. It makes
+ all kind of detection (including content detection) unusable.
+ If you don't want to detect a particular file type by name
+ extensions, add "content_detection" option for the line in
+ eagleplayer.conf. But note that there isn't content detection
+ for all formats. For example, adding "content_detection" for
+ Thomas Hermann player will make all Thomas Hermann songs
+ unplayable because there is no content detection for it.
+
+2006-05-19 Heikki Orsila <heikki.orsila@iki.fi>
+ - Added Gryzors (Nicholas Franck <gryzor@club-internet.fr>)
+ Protracker converter source code into CVS. See
+ amigasrc/players/tracker/converter/README.txt for copyright and
+ licensing information. Thanks to Stuart Caie for leading us
+ to the distribution terms (we did have the source before :-)
+
+2006-05-18 Heikki Orsila <heikki.orsila@iki.fi>
+ - Added p5x and p6x file extensions for The Player 5.x/6.x to
+ eagleplayer.conf (Stuart Caie requested it)
+ - Added "P50A" four letter magic detection to amifilemagic.c
+
+2006-05-17 Michael Doering <mld@users.sourceforge.net>
+ - Removed deprecated <audacious/configfile.h> from audacious
+ plugin. Thanks to Joker for the report.
+
+2006-05-16 Michael Doering <mld@users.sourceforge.net>
+ - Raised length of extension[] in uade_analyze_file from 11 to 16,
+ which caused the xmms and audacious plugin to segfault on
+ very long prefixes (such as mod15_st-iv) in eagleplayer.conf.
+
+2006-06-15 Heikki Orsila <heikki.orsila@iki.fi>
+ - Added "-x y" to set eagleplayer options more conveniently. It's
+ now possible to do: uade123 -x type:pt11b mod.foo. -x can be
+ used multiple times on the same command line.
+
+2006-05-15 Michael Doering <mld@users.sourceforge.net>
+ - PTK-Prowiz now uses the epopt config system. You can set options
+ such as "vblank" and/or "type:" on a song base with the uade123
+ "--set=xyz" command line parameter or edit uade.conf or song.conf
+ manually. For valid protracker types: check the uade123 man page.
+ Please test. I hope I didn't break anything.
+ - Changed Protracker and compatible tag in amifilemagic. It seems
+ it was too long for xmms/audacious and crashed. Odd.
+
+2006-05-13 Heikki Orsila <heikki.orsila@iki.fi>
+ - Merged man page update from alankila, explaining filter and
+ resampling features
+ - Merged headphones 2 effect patch from alankila, making it sample
+ rate independent
+ - Added --version to uade123
+ - Cleaned up frontends with respect to configuration management.
+ Initial configuration loading is made in uade_load_initial_config()
+ in all frontends.
+ - Fixed song.conf locking
+ - Fixed recursive mode song.conf option setting. Try:
+ uade123 -r --set=gain=2 songdir
+
+2006-05-12 Michael Doering <mld@users.sourceforge.net>
+ - Audacious modinfo GTK-2.8's assertion error fixed by "porting"
+ the legacy gdk_font_load/gtk_text to gtk2's tag, viewport,
+ buffer system.
+ - Worked around gtk2's assumption any text has to be clean UTF-8
+ which obviously will break when displaying binaryhexdumps or
+ Amiga locale strings.
+
+2006-05-11 Heikki Orsila <heikki.orsila@iki.fi>
+ - Updated documentation to reflect implementation.
+ - Added support for eagleplayer/song specific eagleplayer options.
+ Use epopt=x in eagleplayer.conf and song.conf. Look at the
+ man page section "EAGLEPLAYER OPTIONS" for valid options.
+
+2006-05-09 Heikki Orsila <heikki.orsila@iki.fi>
+ - Added information about sample rate into effects API.
+ - Fixed a race condition for Audacious and XMMS plugins.
+ A shared static buffer was not locked for file magic detection
+ in eagleplayer.c:analyze_file_format().
+ - Fixed a bug in eagleplayer.c:analyze_file_format() that might
+ have caused a partial read for file to be detected.
+ - Fixed a buffer overrun bug in uade.c:uade_get_amiga_message().
+ With AMIGAMSG_GET_INFO request, the eagleplayer could
+ cause a slight overrun of the amiga memory to uade data memory.
+ The attacker could not however choose the string to be written
+ over the bounds.
+
+2006-05-07 Heikki Orsila <heikki.orsila@iki.fi>
+ - Improved filters to work on arbitrary frequency (alankila)
+ - Removed A500S and A1200S filters. For compatibility, they're now
+ aliased to A500 and A1200.
+ - Moved computation of audio emulation parameters away from
+ init_sound() to audio_set_rate(). init_sound() calls
+ audio_set_rate().
+ - It's now possible to use frequency directive in uade.conf to
+ set playback frequency. But watch out, it can cause bugs
+ and sound quality degradation.
+ - Now only two models (FILTER_MODEL_(A500|A1200)) exist in
+ amigafilter.h.
+ - Code cleanups
+ - Renamed interpolator to be resampler in command line options
+ and configuration files. Use --resampler=x instead of
+ --interpolator=x.
+ - Fixed IIR filter not to waste CPU time with denormal numbers.
+ This idea was presented to us by Antti Huovilainen, thanks.
+ Try playing BD.Mickey_mouse with an older version and see how
+ much cpu it takes with A500 filter. The new version is one
+ quarter CPU time on an AMD64 machine (alankila)
+ - Optimized event handling in include/events.h by removing
+ redundant vsynctime check that relied upon processor/OS
+ specific timers (that we've removed long ago).
+
+2006-05-06 Heikki Orsila <heikki.orsila@iki.fi>
+ - Added two util functions into uadeipc.c. They are uade_send_u32()
+ and uade_send_two_u32s().
+ - Started changes towards changeable output frequency. You can
+ experiment with --freq=x but filter emulation only works for
+ 44,1 kHz at the moment. Note that filter emulation always has an
+ effect on sound.
+
+2006-05-05 Heikki Orsila <heikki.orsila@iki.fi>
+ - Fixed --filter=x and --force-led=y to work again.
+
+2006-05-02 Michael Doering <mld@users.sourceforge.net>
+ - Fixed crash due to uninitialized pointer to subsong scale in seek
+ window for xmms and auda plugin.
+ Seems the UI got into a race condition when trying to update the
+ scale belonging to the seek window and the pointer for the seek
+ window was there, while the scale wasn't ready. This happend for
+ very short subsongs only...
+ - Added NTK/STK detection to modinfo
+ - Check for Dirk Bialluch songs in amifilemagic.
+
+2006-05-02 Heikki Orsila <heikki.orsila@iki.fi>
+ - Fixed a small bug that allows resetting song.conf options from
+ the command line. Use 'uade123 --set= foo' to reset options.
+
+2006-05-01 Heikki Orsila <heikki.orsila@iki.fi>
+ - Changing to a previous song is now possible in uade123. Try
+ pressing '<'. -z option now means randomizing the playlist
+ order before playing, but random play mode (press 's') does
+ randomizing on the fly. Both alternatives support seeking to
+ previous song in the same way, but seeking to next song will
+ always be random in random play mode (not with -z).
+ - Added --repeat option into uade123 to play playlist over and
+ over again.
+
+2006-04-30 Heikki Orsila <heikki.orsila@iki.fi>
+ - It's now possible to set options into song.conf by using uade123
+ directly. This is not the final feature, only a step towards
+ a more usable feature. Try:
+ # uade123 --set="gain=2" foo
+ It should add the associated entry into ~/.uade2/song.conf.
+ Eventually uade123 should be used like:
+ # uade123 --set --gain=2 foo
+
+2006-04-29 Heikki Orsila <heikki.orsila@iki.fi>
+ - Changed hexdump of module/player to show 2 KiBs of text.
+ - Fixed some memory leaks in eagleplayer.c and songinfo.c.
+ - Removed doc/eagleplayer.conf and doc/song.conf. doc/uade123.1 is
+ the authorative documentation for all configuration files.
+ - Many uade song attribute and configuration management changes.
+ - Added broken song end directive for eagleplayers and songs.
+ To work-around a defective timeout logics in song.conf you could
+ add a following line to your song.conf:
+ md5=60f3bb11cc1bacaf77d7c16d13361844 broken_song_end timeout=200 comment FRED.Hybris_Light
+ - Marked song end detection of FRED format as defective in
+ eagleplayer.conf:
+ Fred prefixes=fred broken_song_end
+ - Unified eagleplayer.conf and song.conf settings. See uade123
+ man page for those options.
+
+2006-04-28 Heikki Orsila <heikki.orsila@iki.fi>
+ - Fixed another config bug introduced by last config refactorization.
+ Filter type could not be set from config file in uade123. The bug
+ did not happen on Audacious/XMMS plugins.
+ - uade123 -v now prints the uade.conf and song.conf files that were
+ loaded.
+
+2006-04-28 Michael Doering <mld@users.sourceforge.net>
+ - Fixed bug in Soundtracker 31 instruments check introduced
+ by fixing the misdetection of a digibooster as protracker mod which
+ was introduced by easing accepting mods with bad length...
+ See a pattern there, folks?!?
+ - Along the way, added a distinction between Soundtracker 2.5/
+ Noisetracker1.0 and Soundtracker 2.4. ST2.5/NT1.0 obviously shared
+ the same replay by Kaktus & Mahoney, while ST2.4 was still based on
+ the old 2.3 replay by Unknown and Mnemotron (using repeat offset in
+ bytes).
+
+2006-04-27 Michael Doering <mld@users.sourceforge.net>
+ - Fixed misdetection of a digibooster mod as protracker in
+ amifilemagic.
+ - Fortified modplayer checks against amifilemagic's new policy
+ to accept modfiles with trailing garbage...
+
+2006-04-26 Heikki Orsila <heikki.orsila@iki.fi>
+ - Fixed panning, gain and recursive mode to work again. The problem
+ was the new configuration management system. Command line options
+ were not merged into used options. Also, even if they were merged,
+ they would happen before effects were set ;) Sorry. Fixed now.
+ - Improved gain effect. It can now clip samples if an overflow
+ happens.
+ - Improved song.conf settings. It now supports all but two
+ options. See doc/song.conf.
+
+2006-04-21 Michael Doering <mld@users.sourceforge.net>
+ - Fixed detection bug triptodestroy.mod in PTK-Prowiz. Thanks to
+ Joker for the report.
+ The mod uses very large instruments with loops which rolled over
+ to negative checking instrument sizes in words and when large
+ enough. Stupid bug. Stupid me. :-)
+ - Replaced \t with white spaces. This might fix Joker's bug report
+ about garbled output in modinfo for audacious.
+ - Fixed audacious crash, when trying to access fileinfo while not
+ playing a song... Bug was simple we did't have uadesong struct.
+ get_cur_subsong, get_max_subsong and get_min_ subsong was trying
+ read from that struct even when idle and uade went up in a blaze...
+ Now checking towards uadsong struct exists and all is nice
+ - Fixed the Audacious crash fix. It contained a race condition with
+ respect to the NULL pointer. Also fixed the XMMS plugin. (shd)
+
+2006-04-19 Michael Doering <mld@users.sourceforge.net>
+ - Added new replayer for the Dirk Bialluch format by
+ Don Adan/Wanted Team.
+ - Amended Startrekker/Audiosculpture detection in amifilemagic again.
+
+2006-04-18 Heikki Orsila <heikki.orsila@iki.fi>
+ - Fixed a bug in memmem() replacement. If needle length was zero,
+ it returned NULL, but glibc would return pointer to haystack.
+
+2006-04-15 Michael Doering <mld@users.sourceforge.net>
+ - Fixed bug in sanity check in pt_karplusstrong effect (e8x) in
+ mod player. (thanks Heikki)
+ - Disabled Effect E8x for Protracker 2.3a, 1.1b and 1.0c compatibility
+ mode in PTK-Prowiz.
+ E.g. Playing mod.cyberlogik as PTK3.0 will result in timing bugs,
+ playing it as PTK2.3a will play ok.
+ - Fixed a very serious memory leak issue. Each played song that was
+ read into memory was leaked. My chip collection is 230 MiB and
+ after running
+ valgrind -zr -t1 --enable-timeouts -f /dev/null /chips
+ I noticed a huge chunk of mem leaked :( Now it's fixed. (shd)
+
+2006-04-14 Heikki Orsila <heikki.orsila@iki.fi>
+ - Refactored and changed amifilemagic.c. Changed tracker type magic
+ values into enums. A warning about differing file size and
+ calculated file size for protracker modules is given if one of
+ two conditions happen:
+ - uade123 is run in verbose mode (-v)
+ - xmms or audacious plugin starts to play file
+ - Refactored configuration code
+ - Fixed a subsong/total timeout bug in xmms and audacious plugins.
+ Always ends directive was not obeyed.
+
+2006-04-13 Heikki Orsila <heikki.orsila@iki.fi>
+ - Committed a programmable option for displaying song titles on
+ playlist. Try setting
+ song_title %F %X [%P]
+ to uade.conf.
+ - Reverted xmms buffer underrun fix that was ported to audacious
+ plugin. With produce_audio() one does not need to wait for
+ buffer_free(). (shd)
+ [Comment: it still locks up here :-\] (mld)
+ - Added songtitle feature to audacious plugin and uade.conf (mld)
+ - Added #include <songinfo.h> to audacious plugin and removed some
+ unused variables.
+ - Added a work-around against ALSA output plugin into XMMS plugin
+ which avoids to old subsong change blocking bug. Now sleeping is
+ hardlimited to 5 secs. If work-around is activated, you will see:
+ UADE: blocking work-around activated.
+ on stderr. It seems like snd_pcm_state(pcm) in ALSA output plugin
+ never comes out of SND_PCM_STATE_RUNNING.
+ - Set song_title default to %F %X [%P]
+ - Fixed all xmms and audacious plugin symbols to be non-exportable
+ symbols. The get_iplugin_info() remains the only exportable
+ symbol. 'objcopy -G get_iplugin_info foo.so' should do it, right?
+
+2006-04-12 Heikki Orsila <heikki.orsila@iki.fi>
+ - Fixed configure script to handle uade.pc file correctly in the
+ situation of '--user'.
+ - Added a user warning to amifilemagic.c about truncated protracker
+ modules.
+ - Reverted Michaels change partially. Audacious and XMMS plugins will
+ not show song name that is obtained from the module because it
+ is unreliable. This will be made configurable in the future.
+ - Fixed a potential bug in XMMS plugin. If maximum free audio buffers
+ was less than 4088 bytes, uade plugin would refuse to write
+ anything. This was noticed because XMMS wouldn't recover from
+ a buffer underrun in ALSA mmap mode. The output plugin would
+ not increase the amount of free buffers even if time passes.
+ XMMS 1.2.10 ALSA output plugin (or alsa library) is still buggy.
+ - Ported shd's xmms buffer underrun fix to audacious (mld)
+ - Changed user warning about truncated protracker modules in
+ amifilemagic to produce less false positives. (mld)
+
+2006-04-11 Michael Doering <mld@users.sourceforge.net>
+ - Fixed my crap indentation in audacious plugin
+ - Sync'd xmms and audacious playlist display
+ - Fixed possible changing current subsong > maximal subsong
+ in audacious plugin.
+
+2006-04-10 Heikki Orsila <heikki.orsila@iki.fi>
+ - --no-song-end is now aliased to -n in uade123
+ - Fixed bug in ArtOfNoise8 replayer end routine. (mld)
+ - Added Songtitle to ArtOfNoise 4V/8V players (mld)
+ - Display "Guru Meditation" error in audacious playlist for a song
+ that crashed uadecore. :-) (mld).
+ - Fixed bug updating the playtime in audacious playlist (mld)
+
+2006-04-09 Heikki Orsila <heikki.orsila@iki.fi>
+ - Code refactorization to unify configuration, effect and song
+ attribute handling among all frontends.
+ - Added memmem() replacement for operating systems not having it.
+ - Added uade.pc for pkg-config.
+ - Upgraded MED/OctaMED replay to v7.0, using Fastmem replay if
+ available and needed by the song (long samples :-) (mld)
+ - DigiBooster player now reports songname. (mld)
+ - Fixed ommited pointer in MED/Octamed fastmem replay detection.
+ (mld)
+
+2006-04-06 Heikki Orsila <heikki.orsila@iki.fi>
+ - Added a small README file
+ - Moved some effect related configuration issues to
+ src/frontends/common/ so that they're not reimplemented in all
+ frontends. See src/frontends/common/uadeconf.c function
+ uade_enable_conf_effects().
+ - Use of uade_enable_conf_effects() in audacious plugin (mld)
+ - Disabled debug messages in Audacious and XMMS plugins
+ - Removed debug message about song.conf not found. It's perfectly
+ valid that song.conf does not exist anywhere.
+ - Cleaned songinfo.c. Added a common implementation of read_be_u16/u32
+ to src/include/uadeutils.h, which is now used from songinfo.c and
+ amifilemagic.c. Changed length types to size_t. Made find_tag()
+ more generic and made it use memmem() function.
+ - Added Heikki's dpiutil to songinfo for CUST.* songs. (mld)
+
+2006-04-05 Michael Doering <mld@users.sourceforge.net>
+ - PTK-Prowiz: changed opcodes beq, sf to seq on Heikkis advice.
+ - Tiny Protracker player compatibility change when calling
+ playvoice.
+ - Nicer playlist entries for Audcious plugin:
+ title (cur/max) - [Format]
+
+2006-04-03 Heikki Orsila <heikki.orsila@iki.fi>
+ - Implemented NTSC mode support. It can be buggy and it will not
+ affect some players at all (those which set CIA tempo by
+ themselves). NTSC mode can detected in eagleplayers by reading
+ $212(execbase) aka VBlankFrequency(execbase). It's a byte
+ with value 50 (PAL) or 60 (NTSC):
+ move.l 4.w,a6
+ cmp.b #60,$212(a6)
+ beq is_an_ntsc_system
+ * pal system
+ - Changed Timing configuration in players/env/PTK-Prowiz.cfg
+ from CIA <-> VBI/NTSC to CIA <-> VBI. (mld)
+ - Mod player now honours pal/ntsc setting automatically. (mld)
+ - Fixed stupid *oops* in mod player reading cia timing from config
+ file.
+ - Added ntsc option uade.conf. (mld)
+
+2006-04-02 Heikki Orsila <heikki.orsila@iki.fi>
+ - Fixed P61A detection (introduced by mlds change sometime ago).
+ src/frontends/common/amifilemagic.c had "P60A" as the pattern
+ for Player 6.1, but obviously it should be "P61A".
+ - Improved the man page.
+
+2006-03-31 Michael Doering <mld@users.sourceforge.net>
+ - Changed DMAWait to dtg_DMAWait and add dtg_Timer support
+ to DIGI-Booster
+ - DIGI-booster songinfo now matches modfiles songinfo.
+
+2006-03-30 Michael Doering <mld@users.sourceforge.net>
+ - Small check for Fuzzac Packer in amifilemagic.
+
+2006-03-27 Michael Doering <mld@users.sourceforge.net>
+ - Renamed XANN-Packer to XANN-Player, following Sylvain 'Asle'
+ Chipeaux' suggestion.
+ - Merged Funkok saftey check from EP2.04 to protracker player...
+
+2006-03-25 Heikki Orsila <heikki.orsila@iki.fi>
+ - Added a new action key into uade123. 'i' will print module info
+ and 'I' will print a hex dump of a head of the module.
+
+2006-03-23 Michael Doering <mld@users.sourceforge.net>
+ - Sync'd songinfo for modfiles with the more verbose appearance of
+ Asle's ModInfo v2.31 appearance... It displays now sample sizes,
+ volume, finetune, loop start and loop size, too.
+ - Added yet some more tiny differences between Protracker 2.3 and 3.0
+ compatibility mode for completeness... (set sample_num in pt_plvskip,
+ and n_period in pt_doretrig).
+ These changes might have no effect on the replay quality like e.g.
+ earlier mentioned Updatefunk calling difference or volume setting,
+ though.
+
+2006-03-21 Michael Doering <mld@users.sourceforge.net>
+ - Small protacker replayer config file parsing fix...
+
+2006-03-20 Heikki Orsila <heikki.orsila@iki.fi>
+ - Fixed slight bugs in build system. Architecture specific CFLAGS
+ were missing from xmms and audacious frontends. Also, those flags
+ will be the last flags always so that they can be used for
+ overriding other options.
+ - Made debug flags really optional. They can be turned off with
+ --no-debug (for configure).
+
+2006-03-20 Michael Doering <mld@users.sourceforge.net>
+ - Figured out the period multiplier issue. It was a bug in my
+ brain. *g*
+ - Forgot to add notecut volume setting for protracker 2.3 and below.
+ This is now fixed.
+ - Set the default playback style to Protracker 3.0b.
+ - Added an experimental hybrid protracker setup: 9.
+ Effects are done ptk2.3a style, volume setting like 3.0.
+ This fixes some pops and clicks which even the original
+ protacker 2.3a replay and below had.
+
+2006-03-17 Michael Doering <mld@users.sourceforge.net>
+ - Enhanced compatibilty concerning protracker 2.3a/1.1b(fixed),
+ 2.1a/1.1b, 1.0c and Prottracker 3.0b concerning access of
+ the periodtable while using the effects.
+ It's astonishing in how many ways the protracker replays
+ differ... :-)
+ E.g. Protracker 3.0b (like Noisetracker) uses a multiplication of
+ 37*2 for all effects to get the right period. Protracker 2.3a and
+ the socalled bugfixed 1.1b replay use a value of 36*2 (like the
+ old Soundtracker)
+ Last but least ptk 1.0c, the original ptk1.1b and ptk2.1a use
+ one or the other value for some effects...
+ All in all, it's a mess and we have 4 different setups in our
+ protracker config file :-)
+ - Temporarily disabled the period multiplier hack mentioned above
+ because it borked on some tunes.
+ - Added "update volume when skip/hold note" for protracker 2.3 and
+ below. Protracker 3.0 doesn't do it.
+
+2006-03-16 Heikki Orsila <heikki.orsila@iki.fi>
+ - Changed PAL audio synthesis frequency to be exactly 3546895 Hz. It
+ was 3541200 Hz before. The old value was totally synchronous with
+ video hw. Changing this does not affect anything else than audio.
+ The new value is from the hardware reference manual.
+
+2006-03-16 Michael Doering <mld@users.sourceforge.net>
+ - Compatibility for PTK-Prowiz can now be set to play files like
+ Protracker 3.0b, 2.3a or 1.0c.
+ INFO: Files being played as PT1.0c will have a different vibrato
+ depth, and use funk_repeat effect instead of the invert loop effect
+ which might break all mods composed with later protrackers.
+ - Added support for the different ways Protrackers 1.0, 2.3 and 3.0
+ updated periods.
+
+2006-03-14 Heikki Orsila <heikki.orsila@iki.fi>
+ * UADE 2.02 (Muhammad pictures)
+ - Fixed a bug in xmms plugin that cut off sound data from the end of
+ a song.
+ - New Sierra AGI player by Don Adan / Wanted Team
+ - Better support for old sonic arranger files.
+ - Improved file type detection on many formats.
+ - Debugger improvements (see 'c' and 'i' commands)
+ - Added --buffer-time=x option for uade123 to set audio buffer
+ length in milliseconds.
+ - A configuration file was added for PTK-Prowiz (that plays protracker
+ and clones) to set compatibility to either protracker v3.0b or
+ v2.3a. Please edit file: players/ENV/EaglePlayer/EP-PTK-Prowiz.cfg.
+ - More KDE integration: support for kfmexec wrapper.
+ - Fixed many bugs.
+ - Many other changes :-)
+
+2006-03-12 Heikki Orsila <heikki.orsila@iki.fi>
+ - Changed various uade123 parameters. -k and -K have been changed
+ to one option:
+ -k x or --keys=x, where x is 0 or 1 (disabling and enabling action
+ keys).
+ --no-filter has been removed. Use --filter=none instead.
+
+2006-03-10 Heikki Orsila <heikki.orsila@iki.fi>
+ - Fixed some compiler warnings. Using %u to print unsigned ints :)
+
+2006-03-01 Heikki Orsila <heikki.orsila@iki.fi>
+ - Reverted mlds work-around to avoid subsong change lockups.
+ - Did a potential fix for the XMMS plugin lockup bug. However, I
+ do not have a test case for this. The problem was, I think, that
+ play_loop() called uade_lock(), then called
+ uade_gui_subsong_changed(), then gtk called some function,
+ which would eventually call get_next_subsong() which would
+ try to re-take the mutex by uade_lock() -> deadlock.
+ * THIS THEORY WAS WRONG.
+ - Merged a patch from Martin Jeppensen to rename some eagleplayers
+ to better names.
+
+2006-02-28 Heikki Orsila <heikki.orsila@iki.fi>
+ - Fixed -m option for uade123. "uade123 -m file" would only print help
+ but not play the file.
+
+2006-02-17 Michael Doering <mld@users.sourceforge.net>
+ - Added some missing file extensions for the KDE mimelnk.
+ - Use of kfmexec wrapper in KDE mimelnk for easy ftp:// http://,
+ smb://, zip:// etc. support under KDE/Konqueror.
+ - Added install script for KDE users in /src/frontents/uade123/KDE.
+ Now playing Amiga music is just one click away from you ;-)
+
+2006-02-15 Michael Doering <mld@users.sourceforge.net>
+ - NTSC Flag in config file ENV:eagleplayer/ for PTK-Prowiz affecting
+ Sound, Noisetracker, Startrekker and Protracker (vblank) added.
+ Normal Pro- and Fastracker are not affected.
+ Info: it's not a real ntsc mode in emulation but just calculating
+ the CIAA timer to use a value ~ 7.15Mhz, 60khz, 125bpm on PAL
+ machines...
+ It's a cludge I know :)
+
+2006-02-14 Heikki Orsila <heikki.orsila@iki.fi>
+ - Fixed /dev/urandom detection. Using test -c rather than test -e.
+ Test -c is more compatible and more exact too.
+ - Worked around random lock ups when switching very short subsongs
+ with the xmms subsong changer (mld)
+ - Config file for PTK-Prowiz' Protracker engine added to set the
+ way _Protracker_ mods are played. There's currently two values: 0
+ for Protracker 3.0b like, 1 for Protracker 2.3A like (for anyone
+ interested: funkrepeat is updated before parsing the extended fx :)
+ Differences are probl. not audible but Latter is currently the
+ default. If it breaks a mod file, you can savely turn back to
+ "0" (mld)
+
+2006-02-13 Heikki Orsila <heikki.orsila@iki.fi>
+ - Fixed uade123 to accept -k and -K switches. Their meaning is now
+ changed. '-k' disables action keys and '-K' enables.
+
+2006-02-10 Michael Doering <mld@users.sourceforge.net>
+ - A new email alias. ;)
+ - Cosmetical change in name from 32 to 31 instr. for Soundtracker II
+ in PTK-Prowiz.
+
+2006-02-08 Michael Doering <mldoering@gmx.net>
+ - Updated mod2ogg.sh to set encoding quality (Giulio Canevari).
+
+2006-02-07 Michael Doering <mldoering@gmx.net>
+ - Put new Sierra AGI player by Don Adan/Wanted Team into players dir.
+
+2006-02-02 Heikki Orsila <heikki.orsila@iki.fi>
+ - Cleaned up gensound.h. It contained unuseful external variables
+ such as sample16s_handler and sample_handler.
+ - Improved mod detection in amifilemagic and Protracker replayer for
+ Protracker compatible mods using effects 5,6,7 and 9. (mld)
+ - Quick "work around" of a lock up with the subsong seek popup and very
+ short subsongs in audacious plugin. Needs further investigation
+ though. Some kind of race condition, I think. (mld)
+ - Reintroduced produce_audio(); to audacious plugin for the freshly
+ released Audacious 0.2 at http://audacious-media-player.org (mld)
+
+2006-02-01 Michael Doering <mldoering@gmx.net>
+ - Changed association of jp file extension to Jason Page New.
+ - Added simple detection for Jason Page old in amifilemagic.
+ - Added alternative Jason Page Player for one file Jason Page New
+ files (Thanks dom from the legacy.de for the report).
+ - Changed HIP, HIPC and HIP7 to SOG, SOC and S7G prefix in
+ amifilemagic.
+
+2006-01-31 Heikki Orsila <heikki.orsila@iki.fi>
+ - Fixed song length database bug in the XMMS plugin. The XMMS plugin
+ didn't use the correct md5sum in struct uade_song, instead it used
+ the old and useless array called curmd5[] which was an empty
+ string.
+ - Continued to move common variables in frontends to struct uade_song.
+ - Fixed instrument name len in songinfo for mods. (mld)
+
+2006-01-25 Michael Doering <mldoering@gmx.net>
+ - Added Turbo/Infect's SonicArranger Player for "old" sa.* files
+ - Added experimental filedetection for two different
+ Sonicarranger_pc types...
+
+2006-01-24 Michael Doering <mldoering@gmx.net>
+ - Synced audacious plugin with xmms plugin and changed back
+ to support the current stable audacious 0.1.2.
+ The audacious supporting "produce_audio()" will be supported as
+ soon as there's a stable release... (mld)
+ - Ported songinfo for Wanted Team song formats [e.g BSS, DL, FP...]
+ - Fixed mod title display in songinfo
+
+2006-01-22 Heikki Orsila <heikki.orsila@iki.fi>
+ - Added a new option to uade.conf: buffer_time x. buffer_time x in
+ uade.conf sets audio buffer length to x milliseconds. This can
+ be used to avoid buffer underruns on some systems. Beware that
+ Alsa support in libao is buggy in versions 0.8.6 and earlier so
+ that the actual buffer time must be given in microseconds. At
+ this time it is not fixed in any official libao releases.
+ - uade123 option --buffer-time=x can be used to set audio buffer
+ length to x milliseconds.
+
+2006-01-21 Heikki Orsila <heikki.orsila@iki.fi>
+ - Imported the LGPL'ed Max Trax source to amigasrc/players/max_trax.
+ Then applied a patch from alankila. It is not yet an eagleplayer
+ but a work-in-progress. (alankila)
+ - Added a command 'i' to the debugger that traces till next hw
+ interrupt.
+ - 'c' command in debugger will now also print cycle count.
+
+2006-01-20 Heikki Orsila <heikki.orsila@iki.fi>
+ - Continued frontend modularization and code sharing effort. Created
+ struct uade_song in eagleplayer.h to store relevant properties
+ of songs that are played. Modified uade123 and XMMS plugin to use
+ it. The transition is not completed yet. Many fields are still
+ unused and those fields unnecessarily duplicated in frontends.
+ Notice that audacious plugin is broken because of this, but it's
+ also in a transition phase.
+ - Fixed merging conflicts between latest frontend modularization
+ effort and mlds mod/fileinfo changes.
+ - Fixed bugs in songinfo.c. Some file checking could have read over
+ over memory boundary causing a segfault (but nothing else).
+ - Backported fileinfo for DIGI-Booster mods. (mld)
+ - Fixed a bug in XMMS plugin that it stopped a subsong too early
+ if there was another subsong to play. The sound data that was
+ buffered in audio output plugin was discarded. Thanks to Cthulhu
+ (the old one) for the bug report.
+
+
+2006-01-19 Michael Doering <mldoering@gmx.net>
+ - Improved vblank detection in Protracker replay for mod.slow_motion
+ by Jogeir Liljedahl. (mld)
+ - Started work on backporting modinfo from uade 1. Ideally all
+ frontends should be able to use it. (mld)
+ - Experimental "update fileinfo window on songchange" feature...
+
+2006-01-18 Heikki Orsila <heikki.orsila@iki.fi>
+ - Added a simple and broken XMMS file info window. Module info
+ displays a hexdump of the first 1024 bytes of the module.
+ - Fixed #include issues with FreeBSD in unixatomic.c.
+ - Optimized sinc interpolator (alankila)
+ - Changed fileinfo.c to allow many different types of infos for
+ modules. Hexdump is the current default since nothing else has
+ been implemented.
+
+2006-01-17 Michael Doering <mldoering@gmx.net>
+ - (hopefully) Fixed broken subsong detection for Digital Illusion
+ mods.
+ - Fixed unallocating timer resources when changing subsong in
+ MED/Octamed replayer. As a consequence, changing subsongs works
+ again.
+ - Removed sinc table from audio.c and put it into a separate file
+ named sinctable.c. (alankila)
+ - audacious plugin: changed legacy uade_ip audio output from xmms
+ to audacious 0.2 produce_audio(); Seems to work here, but I'm not
+ sure if it's 100% ok... So give it a test and report back.
+ - Fixed strlrep.h to #include <strings.h> to have size_t type (shd)
+
+2006-01-15 Heikki Orsila <heikki.orsila@iki.fi>
+ - Added more debug messages into the interface between emulator and
+ sound core. Now Amiga file loading events will give informative
+ message to the frontend. Use uade123 with -v to see all the spam.
+
+2006-01-14 Heikki Orsila <heikki.orsila@iki.fi>
+ - Merged sinc interpolator patch (alankila)
+ - Changed RK to CM prefix in amifilemagic. This affects custom made
+ format. Old RK and RKB prefixes are still supported but they may
+ be removed in the future.
+ - Added contrib/sinc-integral.py which computes the sinc antialiasing
+ window for audio.c synthesis. (alankila)
+ - Made huge changes into sound cores subsong restart and interrupt
+ logic. Some formats were fixed with respect to subsong changing.
+ Try Monkey Island now. The tempo should be correct after subsong
+ change. 4ch MED/OctaMED is still broken. Try changing to subsong
+ 9 in DaveNinja.med (some channels do not get re-initialized and
+ a disturbing sound plays on the background). The changes are:
+ 1. Earlier we didn't call StopInt and EndSound in subsong change,
+ but now we do. The old procedure just called InitSound and
+ StartInt because our allocators in sound core were robust
+ against double allocation.
+ 2. Implemented unallocation for CIA resources. See
+ rem_cia[ab]_interrupt functions.
+ 3. StopInt unallocates the CIA resource used for the player
+ interrupt. Set_player_interrupt allocates the player interrupt
+ and calls StartInt.
+ 4. EndSound has a default code now which turns off audio DMA and
+ sets volumes to zero.
+ 5. exec.library/SetIntVector() does not enable interrupts anymore.
+ If interrupts are disabled they stay disabled.
+
+2006-01-12 Heikki Orsila <heikki.orsila@iki.fi>
+ - Made anti (accumulator) interpolator to be the default.
+
+2006-01-08 Michael Doering <mldoering@gmx.net>
+ - Commited audacious input plugin based on the XMMS plugin
+ (http://audacious.nenoload.net).
+
+2006-01-08 Heikki Orsila <heikki.orsila@iki.fi>
+ - Fixed XMMS plugin installation which didn't obey package prefix
+ (Michal Januszewski <spock@gentoo.org>).
+ - Added some more b-flags for fopen(). This time in code in
+ src/frontends/common.
+ - Cleaned up sound data buffering code in uadeipc.c, uade.c and
+ audio.c. Removed uademsg.h as being useless.
+ - Changed uadecontrol.c to uadeipc.c in src/Makefile.in because
+ uadecontrol.c is long gone.
+ - Optimized uade123 to issue next song data request for the uadecore
+ before passing sample data to libao. This way the uadecore may
+ do useful work while libao is blocked on sound device. This didn't
+ solve the underrun problem completely but effect of improving
+ behavior is clearly observable with 'top'. Before this change, top
+ showed only 0.4% CPU usage for uadecore, but after the change it
+ shows 3.3% CPU usage, and the latter reflects reality much better.
+
+2006-01-07 Heikki Orsila <heikki.orsila@iki.fi>
+ - Changed fopen() to use "b" flag for porting to Windows environment.
+ - Thanks to sasq <jonas@nightmode.org> for help with cross-compiling.
+
+2006-01-06 Heikki Orsila <heikki.orsila@iki.fi>
+ - Made uadeipc() re-entrant so that uadecore and a frontend could in
+ theory be run in the same process but different threads.
+ - Replaced poll() with select() in unixatomic.c to be compatible with
+ weak systems.
+
+2006-01-05 Heikki Orsila <heikki.orsila@iki.fi>
+ - Continued cleaning up run-time configuration issues. uade123 and
+ XMMS plugin do not duplicate settings anymore. Most configuration
+ and command line options are stored inside 'struct uade_config'
+ which is defined in src/frontends/common/uadeconf.h.
+
+2006-01-04 Heikki Orsila <heikki.orsila@iki.fi>
+ - Changed -I./include/ to be -I./include in src/Makefile.in to make
+ it compatible with mingw.
+ - PTK-Prowiz now accepts mods with max 1KiB trailing garbage...
+ Nevertheless use 100% good rips, people! (mld)
+ - Fixed spelling mistake in PTK-Prowiz *g* (mld)
+ - Updated uade123 man page with apologies about bad file detection
+ heuristic :(
+
+2006-01-04 Heikki Orsila <heikki.orsila@iki.fi>
+ * UADE 2.01
+ - Compatibility fixes for OpenLSD and Mac OS X to make UADE compile
+ - Added 'cm.' prefix for CustomMade format (Ron Klaren)
+ - PTK-Prowiz subsong scanning was improved (mld)
+
+2006-01-03 Heikki Orsila <heikki.orsila@iki.fi>
+ - Cleaned up post-processing of sound data. Removed postprocessing.[ch]
+ because it was redundant functionality and added necessary
+ functionality into effects.[ch]. Also, moved effect state out of
+ effects.c by creating 'struct uade_effect'. This allows easy
+ loading and storing of state.
+ The goal is to have a unified mechanism for handling information
+ from command line options, uade.conf, eagleplayer.conf and
+ song.conf that is easy. All the setting must be storable and
+ restorable through that mechanism. Currently that is broken,
+ incomplete and messy. The functionality is even duplicated between
+ frontends :( It will probably take many cleanup steps to achieve
+ the goal.
+ - Fixed Mac OS X compatibility issue. poll() was replaced with
+ select(). Thanks to Juuso Raitala.
+ - Improved (hopefully) subsong detection for mods and similar. Now
+ there should be less false positives in PTK-Prowiz than there
+ used to be. (mld)
+ - Removed 255 BPM SetTempo fix in PTK-Prowiz for mod.loader from
+ Coolspot to fix mod.alkupala by jorma... *sigh* (mld)
+ - Fixed broken Prorunner support introduced by reorganization
+ PTK-Prowiz (mld)
+
+2006-01-02 Heikki Orsila <heikki.orsila@iki.fi>
+ - Fixed a configure bug that occured when --with-xmms was specified.
+ (Michal Januszewski <spock@gentoo.org>)
+ - Made contrib/uadexmmsadd script to be installed if XMMS plugin is
+ installed
+ - Added a work-around for OpenBSD 3.8 which lacks portable types from
+ stdint.h. inttypes.h is used instead. Possibly this avoids type
+ problems on some other OSes too. Note that we require some C99
+ features from standard C libraries. Thanks to ave@silokki.org.
+ - Made OpenBSD use 'gmake'. Thanks to ave@silokki.org.
+ - Fixed execlp() call in src/frontends/common/uadecontrol.c by
+ casting NULL as (char *). Thanks to ave@silokki.org.
+
+2006-01-01 Heikki Orsila <heikki.orsila@iki.fi>
+ * UADE 2.00 (Mental hangover)
+ - Finally the first stable release of UADE 2 series. The work began
+ 6 months ago. There are still rough edges and deficiencies but
+ it is superior to UADE 1 in many respects.
+ - UADE 2 series has following improvements over UADE 1 series:
+ * Superior audio quality due to excellent Amiga 500 and 1200
+ filter models. The default sound model is now the Amiga 500
+ model. This affects all songs whether or not they use filtering.
+ (Antti S. Lankila)
+ * A component architecture which makes creating new frontends
+ easier
+ * Unified configuration files to set defaults for all frontends
+ * Improved command line tool, uade123, supports run-time control
+ of song playback for switching subsong, skipping to next song,
+ skipping fast forward, pausing and altering post-processing
+ effects
+ * Post-processing effect for headphone users (Antti S. Lankila)
+ * Skip fast forward feature in uade123 and XMMS plugin
+ * Many core subsystems have been rewritten or heavily altered
+ * New supported formats
+ * UADE 1 produces snaps in audio output because of a bug in
+ audio DMA engine, but is fixed in UADE 2
+
+2006-01-01 Heikki Orsila <heikki.orsila@iki.fi>
+ - Added contrib/uadexmmsadd script to add uade:// prefixed songs into
+ XMMS playlist. This is useful to avoid conflicts with protracker
+ songs with modplug and other XMMS plugins. Any other plugin will not
+ accept uade:// prefixed entries from the playlist.
+ - Changed forward seeking button in XMMS plugin from ">>" to "10s fwd".
+ - Allow gain values greater than 1.0.
+ - Improved uade123 man page.
+ - Fixed a NULL pointer derefecence in eagleplayer.conf loading. If
+ eagleplayer.conf couldn't be loaded it would crash.
+ - Fixed a directory creation problem with 'make feinstall'.
+
+2005-12-30 Heikki Orsila <heikki.orsila@iki.fi>
+ - Merged an altered sample accumulation patch from alankila. The
+ patch has an effect only if anti interpolator is used.
+ - Removed crux, linear and rh interpolators because they're broken
+ by design. Only default and anti are now supported.
+
+2005-12-22 Heikki Orsila <heikki.orsila@iki.fi>
+ - Fixed shared library compilation for Mac OS X. Thanks to
+ Michael Baltaks <mbaltaks@mac.com> for information.
+
+2005-12-21 Michael Doering <mldoering@gmx.net>
+ - PTK-Prowiz: Commited various changes to cvs.
+ o Almost finished reorganizing and redoing the mod checks.
+ o Fixed bug in Soundtracker with repeat in bytes handling.
+ o Fixed some bugs in handling empty instruments.
+ o Added hack for vblank mod detection.
+ o Hopefully working, support for Karplusstrong fx.
+ - Amifilemagic: backported a small bugfix in mod detection.
+
+2005-12-20 Heikki Orsila <heikki.orsila@iki.fi>
+ - Added a short note for Max OS X users to address a compilation
+ problem.
+ - Renamed INSTALL to be INSTALL.readme to avoid makefile problems with
+ Mac OS X.
+
+2005-12-19 Heikki Orsila <heikki.orsila@iki.fi>
+ - Merged accurate audio output patch from Antti S. Lankila. The patch
+ solves the problem that Paula's 3.5 MHz output was sampled at
+ regular integer valued intervals that caused inaccuracy. The old
+ interval was round_down(3541200 / 44100) = 80 paula cycles, but
+ the real interval is ~80.299 paula cycles. This means 0.4% relative
+ error in outputted sampling rate that is not audible, but it is
+ harming filter accuracy analysis.
+
+2005-12-17 Heikki Orsila <heikki.orsila@iki.fi>
+ * UADE 1.50-pre10
+ - Cleaned up src/include/events.h. Removed unnecessary event
+ scheduler.
+ - Reworked audio subsystem to be more debuggable and added comments.
+ - Fixed a bug in audio state engine that caused DMA engine to play
+ one word too much of sample data. How could this bug have gone
+ unnoticed for so long? The same bug exists in UAE too.
+ - Reverted back to not using interpolation with A500E and A1200E
+ filters. The anti interpolator caused problems with many songs.
+ It will be fixed at some point and changed back, but at the
+ moment there's doubt how to fix the problem.
+
+2005-12-16 Heikki Orsila <heikki.orsila@iki.fi>
+ - Applied filter improvement and optimization to audio.c. The
+ filter should be slightly better than the old. Affects only
+ A500E and A1200E filters. (alankila)
+ - Cleaned up audio.c
+ - Reworked configuration loading system to avoid conflicts with
+ uade123 command line parameters. Command line parameters have
+ priority over uade.conf.
+
+2005-12-15 Michael Doering <mldoering@gmx.net>
+ - Some progress on porting the mod detection to m68k asm.
+
+2005-12-15 Heikki Orsila <heikki.orsila@iki.fi>
+ - Fixed a bug that forced filter to be A500E type when --force-led
+ was uade with uade123. (alankila)
+
+2005-12-14 Heikki Orsila <heikki.orsila@iki.fi>
+ - Added displaying total playtime based on content database into
+ uade123
+
+2005-12-12 Michael Doering <mldoering@gmx.net>
+ - replaced Grouleff replayer with Wanted Team's EarAche.
+ - added new EMS replayer by Wanted Team.
+
+2005-12-12 Heikki Orsila <heikki.orsila@iki.fi>
+ - Added INSTALL file to document build process.
+
+2005-12-11 Heikki Orsila <heikki.orsila@iki.fi>
+ * UADE 1.50-pre9
+ - An XMMS plugin has been added. New features compared to UADE1 XMMS
+ plugin are seek fast forward and correct subsong seeking bar. The
+ plugin still lacks GUI for configuration, but uade.conf can be
+ edited directly.
+ - Filtering settings are audibly different compared to last release.
+ A500E filter model is now the default. It was A1200 in the last
+ release. This affects all songs, even those which do not use the
+ filter.
+ - New players for 15 instrument soundtracker variants have been added.
+ - uade123 man page has been updated.
+ - Most subsystems have gone through changes. Some important changes
+ have been left out. See log entries for further details.
+
+2005-12-11 Heikki Orsila <heikki.orsila@iki.fi>
+ - Significant changes in filter default values. Current default filter
+ is A500E, which is audibly different on every song compared to the
+ old default (A1200). To restore the old behavior, set "filter a1200"
+ in uade.conf. If you want to advocate another default value, please
+ post to the forum or send email. The forum is preferred.
+
+2005-12-10 Heikki Orsila <heikki.orsila@iki.fi>
+ - Added notices to documentation that setting filter model has an
+ audible effect even if a song doesn't use filtering at all.
+ - Cleaned up configure script (that is originated from uade1)
+
+2005-12-07 Heikki Orsila <heikki.orsila@iki.fi>
+ - Added unrecognizable type "packed" into amifilemagic. It is
+ used to inform user about files that are packed with an amiga
+ packer.
+ - some work on m68k mod checking and replay routine (mld)
+
+2005-12-06 Michael Doering <mldoering@gmx.net>
+ - XMMS plugin now automagically advances the subsong seek slider, if
+ the replay rolls over to the next subsong.
+ - Soundtracker15 name check that was added yesterday was removed. (shd)
+ - Fixed a bug in uade_filemagic() that char *pre was not initialized
+ to be an empty string by default. This caused
+ uade_analyze_file_format() to receive garbage data when file format
+ was not recognized. (shd)
+ - Valgrinded a memory allocation bug in two places of eagleplayer.c
+ (the same error actually due to replicating same lines of code),
+ where space for (n + 1) pointers should have been allocated, but
+ only ((n * sizeof ptr) + 1) bytes was allocated. (shd)
+ - Added gain effect into uade.conf. You can use variable named
+ 'gain' to set scaling value for each outputted sample. For
+ example, add a following line to uade.conf:
+ gain 0.25 (shd)
+ - Made length test of mods with 32 instruments less strict. Due to
+ popular demand *g* now "oversize mods" get accepted.
+ - Added check for sane finetune and volume values in modchecks.
+
+2005-12-05 Heikki Orsila <heikki.orsila@iki.fi>
+ - Added initial version of song length database into XMMS plugin. It
+ is compatible with uade1 db-content, but named differently:
+ ~/.uade2/contentdb. You can just copy the old db:
+ cp ~/.uade/db-content ~/.uade2/contentdb
+ - Content db is loaded during play_file if it has changed
+ on the disk. If it has not changed on the disk, then it is
+ saved if an hour has passed and the db has been changed.
+ - Added a requirement for Soundtracker15 song content detection that
+ the name must have prefix or postix being: "mod", "mod15", or
+ "mod15_". This change could be reverted at some point but now it's
+ the safest choice.
+
+2005-12-04 Heikki Orsila <heikki.orsila@iki.fi>
+ - Added missing #include for uadecontrol.h (sys/types.h for pid_t).
+
+2005-12-03 Heikki Orsila <heikki.orsila@iki.fi>
+ - Made XMMS plugin display play time correctly in the play list
+ after a song ends. If song ended volutarily, tell XMMS the
+ play time. If song ended involuntarily by user intervention,
+ error, or timeout, tell XMMS that the song doesn't have a length
+ leaving the play list time empty.
+
+2005-12-02 Heikki Orsila <heikki.orsila@iki.fi>
+ - Fixed a latency and time bug in the XMMS plugin that affected
+ fast forward seeking. When forward seeking happened the XMMS time
+ display was not updated and the seeking happened with a delay.
+ - Made XMMS plugin report the play time for XMMS after a song
+ ends.
+ - Added comments about variable locking in XMMS plugin.
+
+2005-12-01 Michael Doering <mldoering@gmx.net>
+ - eagleplayer.conf: Amended the different MarkCooksey prefixes.
+ - amifilemagic: fixed TFMX 1.5 detection bug introduced by the recent
+ clean-up.
+ - amifilemagic: fixed another TFMX detection bug. Should be alright
+ again now.
+
+2005-11-30 Heikki Orsila <heikki.orsila@iki.fi>
+ - Make XMMS plugin auto detectable in configure script. The plugin is
+ still very experimental and incomplete in features, but it can
+ already play songs, or at least it should.
+ - GCC4 gave warnings of problems I had not noticed: Fixed a bug in
+ md5.h. uint32_t was accidently redefined (that is #included
+ originally from stdint.h). XMMS plugin's uade_ip structure was
+ declared static but later as external. Fixed signedness warnings
+ from various modules.
+ - Added seek-forward button into XMMS plugin. (mld)
+ - New replayer for Soundtracker v2-v5 mods with 15 instruments and
+ a lot of different effects added. (mld)
+ - fixed WaitAudioDMA for all old mod15 replayers. (thanks heikki!)
+ - changed mod15 (again) for stricter st-iv detection (mld)
+ - changed to a stricter tracker module length policy...
+ If uade doesn't play your modfiles anymore, it's a bad rip.
+ Get a good one! :)
+ - Since Master-Soundtracker files seem to use a subset of the normal
+ Soundtracker fx, they now get played with the mod15 replay
+ This makes Master-ST replayer kind of obsolete atm. (mld)
+
+2005-11-29 Heikki Orsila <heikki.orsila@iki.fi>
+ - Partial and buggy implementation of song.conf. It is used for uade
+ specific work-arounds for broken or bad songs. Look at doc/song.conf
+ and src/frontends/common/eagleplayer.c. Please do not use this yet.
+ - Fixed some compiler warnings that surprisingly came with gcc 4.0.2.
+ - Fixed Makefile.in to not report error on 'make install' when XMMS
+ plugin is not installed.
+
+2005-11-28 Heikki Orsila <heikki.orsila@iki.fi>
+ - Modularized loading and parsing on uade.conf options. See
+ src/frontends/common/uadeconf.[ch].
+ - It is possible that config parsing for uade123 breaks now.
+ - Added partial config loading support for XMMS plugin. Doesn't
+ support setting filter type or interpolation mode yet. You must
+ edit uade.conf by hand if you want configuration changes. No GUI
+ for setting options yet.
+ - Added cleaning rule for XMMS plugin
+ - New make rule: 'make feclean' will clean all frontend objects
+ - The XMMS plugin determines configuration file path for uade.conf
+ once during XMMS plugin initialization, and it will not change
+ afterwards. If no global or user configuration is found, then
+ the plugin chooses the file under HOME ($HOME/.uade2/uade.conf).
+ It will try to load the configuration each time a new song is
+ selected from the XMMS.
+ - Optimization: XMMS will re-read configuration when a new song is
+ selected if the file timestamp of uade.conf has changed.
+ - Fixed synchronization problem in XMMS plugin's play loop. The audio
+ device is drained of written sound data before actually stopping
+ the device. The earlier version cut of audible data from the end
+ of the song :( However, draining can be interrupted if the user
+ requests something urgent, such as wanting an immediate song change.
+ Draining takes time as long as audio
+ device has buffered data. Buffering settings can be found from
+ output plugin settings, as usual.
+
+2005-11-28 Heikki Orsila <heikki.orsila@iki.fi>
+ - Added hardcoded timeouts for the XMMS plugin. They are the same
+ as uade123 defaults. 20 seconds for silence and 512 seconds for
+ subsong. Reading uade.conf variables is not supported yet.
+
+2005-11-27 Heikki Orsila <heikki.orsila@iki.fi>
+ - Continuing modularization of uade frontends. Various commands,
+ such as set subsong, change subsong, set filter type, and set
+ interpolation mode, were moved to src/frontends/common/uadecontrol.c.
+ The idea is that all the non-trivial commands have a wrapper in
+ uadecontrol.c, but trivial commands that don't require parameters
+ can be used through uadeipc.c (uade_send_short_message()).
+ - Added src/include/uadeconstants.h that should contain constants that
+ are common with uadecore and frontends.
+ - Subsong seeking works in XMMS plugin :-)
+ - Made XMMS plugin globally installable as it should be
+
+2005-11-26 Heikki Orsila <heikki.orsila@iki.fi>
+ - Continuing modularization of uade frontends. Renamed
+ src/uadecontrol.c to be src/uadeipc.c, and added
+ src/frontends/common/uadecontrol.c which contains a set of
+ helper functions to control and spawn uadecore.
+ - Added --with-xmms to configure script for developing the XMMS
+ plugin. It does not work yet!
+
+2005-11-25 Heikki Orsila <heikki.orsila@iki.fi>
+ - Cleaned up and fixed tronictest check in amifilemagic. Added
+ read_be_u16() and read_be_u32() to help parsing amiga formats.
+ - Cleaned up tfmxtest in amifilemagic.
+ - Cleaned up modparsing in amifilemagic.
+
+2005-11-24 Michael Doering <mldoering@gmx.net>
+ - amifilemagic: improved mod32 and mod15 checks a bit
+ - ha! found pitchbend incompatibility bewteen
+ Master-ST and DOC Soundtracker II in amifilemagic. Now
+ Mods using the pitchbends bigger than 0xf are played as
+ DOC Soundtracker II:)
+
+2005-11-23 Michael Doering <mldoering@gmx.net>
+ - Master-ST and Ultimate-ST replayers now check for a valid file
+ length, thus badly ripped mod15 songs won't get played anymore with
+ UADE. No exceptions.
+ FYI this will also be future for all other Sound and Protracker
+ derivates, so for anyone having bad rips - get some valid files! :)
+
+2005-11-22 Michael Doering <mldoering@gmx.net>
+ - Improved amifilemagic: mod32 check now tries to distinguish
+ 10 different mod types. (BTW. 4ch Fastracker mods and similar
+ now default to mod_pc and get played by the Multichannel PS3M player)
+ - Some more work on the mod15 check in amifilemagic again.
+ - Started to update the amiga mod15 replayers (Ultimate-ST and
+ Master-ST with better checks, resulting in breaking support for other
+ players like EP or DT atm.
+
+2005-11-18 Michael Doering <mldoering@gmx.net>
+ - Lowered the file buffer size to 8192 bytes to reduce overhead with
+ xmms plugin scans. Unfortunately mods with a header and pattern data
+ beyond that buffer size can't be detected properly and get played
+ as plain mod15.
+ - Improved mod15 check. It should produce now less false positives.
+ - Added a smarter(?) way of the mod check for larger files that
+ don't fit into the check buffer completely.
+ - Renamed filemagic() to uade_filemagic() (shd)
+ - Filemagic buffer size (8192) is now passed as an argument to
+ uade_filemagic(). Previously both the caller and callee knew the
+ size.
+ - Made amifilemagic tables static (only visible inside the module)
+ (shd)
+ - Name prefix conflict between Future Player and PTK-Prowiz was
+ resolved in favor of Future Player. The name prefix/extension is
+ 'fp'. (shd)
+
+2005-11-16 Heikki Orsila <heikki.orsila@iki.fi>
+ - Made install to a standard path by default. That is /usr/local.
+ Use ./configure --prefix to override. configure --user will install
+ to users home directory as in the past.
+ - Committed initial version of man page for uade123.
+ - added a first uade-only mod15_Mastertracker player (mld)
+ - improved (?) mod15 type checks in amifilemagic (mld)
+ - started to work on more complete mod type check in amifilemagic
+ (mld)
+
+2005-11-13 Heikki Orsila <heikki.orsila@iki.fi>
+ - Cleaned up src/frontends/common/eagleplayer.c. Removed skip_ws(),
+ skip_nws(), and loops that used them, and replaced those with
+ shorted loops that use strsep(). Changed index variables to use
+ size_t instead of int to be more robust against bad input.
+ - Fixed a bug that if eagleplayers.conf specifies always_ends for
+ an eagleplayer then forcing timeout from command line with -t
+ didn't work.
+ - Fixed a dirty bug in score that made score crash if an eagleplayer
+ gave a NULL pointer as module name. This happened with Frontier
+ custom. Closer inspection revealed that Frontier custom is also
+ buggy because it sets module name in InitSound() but the
+ specification says module name is evaluated after InitPlayer()
+ which is before InitSound(). This looks like a design bug in
+ the interface, or a typo in the documentation, because setting
+ module separately for each subsong is useful, and that is what
+ Frontier actually does.
+
+2005-11-12 Heikki Orsila <heikki.orsila@iki.fi>
+ - Add new antialiasing interpolation mode, which corrects for noisy
+ treble especially audible in the A1200 filter model. It does its
+ work by computing the average value of Paula's output pins between
+ samples.
+
+2005-11-09 Michael Doering <mldoering@gmx.net>
+ - Fixed missing hipc and soc prefixes in eagleplayer.conf.
+ - Associated #chn, ##ch mods to PS3M again. (note: s3m, xm or mtm
+ are still omitted by uade)
+
+2005-11-08 Heikki Orsila <heikki.orsila@iki.fi>
+ - Added slight noise reduction into CSpline code to reduce
+ noise due to interpolation errors, and snapping sounds from
+ sudden volume changes. (alankila)
+ - Updated headphone filtering parameters to place virtual
+ sound sources closer to head and reduced the associated treble
+ filtering to make the sound at the same time brighter and more
+ forward placed. The sources still appear slightly behind and
+ perhaps elevated, so the illusion will be further improved.
+ (alankila)
+ - fixed AON8 timing now for real *grin* (mld)
+ - added Musicline Editor to be detected by amifilemagic (mld)
+
+2005-11-07 Michael Doering <mldoering@gmx.net>
+ - Removed dupes from new eagleplayer.conf (mld)
+ - Added new player: Musicline Editor (mld)
+ - Broke ArtOfNoise8 timing, and added song end detection. (mld)
+
+2005-11-06 Heikki Orsila <heikki.orsila@iki.fi>
+ - Added an experimental support for eagleplayer.conf, which is
+ specified at doc/eagleplayer.conf. The new system allows eagleplayer
+ specific settings. uadeformats is no longer used, so it has been
+ removed. Here's a list of currently possible eagleplayer options:
+ a500 (A500 type filter emulation is used.)
+ a1200 (A1200 type filter emulation is used.)
+ always_ends (A song always ends, so timeouts are not used.)
+ content_detection (File name prefix or postfix heuristics are not
+ used for determining format.)
+ speed_hack (Speed hack is enabled.)
+ Tips:
+ Speed hack can be turned on for a specific format by editing
+ eagleplayer.conf. A format can be marked as ending always, which
+ means that timeout values are not used (except silence timeout).
+ There are other options too, and all of them are specified in
+ doc/eagleplayer.conf.
+
+
+2005-11-05 Heikki Orsila <heikki.orsila@iki.fi>
+ - Player interrupt is now a CIA A interrupt by default. As a
+ consequence CUST.Loom works (it requires that player interrupt
+ runs at a lower priority level than audio interrupts).
+ THM.BlueAngel69 might play better now - a good comparison is needed.
+ There are still a few things to do in the sound core's interrupt
+ system, see amigasrc/score/todo.txt.
+ - Headphones effect clipping fix (alankila)
+ - Added improved (but currently experimental) LED filtering code.
+ The old code was based on assumption that A500 and A1200 have same
+ output filtering circuitry, but this was not correct. After
+ analysing hi-fi measurements by pyksy, I designed new filters
+ by tweaking a couple of equalizers on top of a RC filter that
+ provided basic treble attenuation. Use --filter=a500e or a1200e to
+ test the new filters. (alankila)
+
+2005-11-04 Heikki Orsila <heikki.orsila@iki.fi>
+ - Separated CIA B timer A and timer B interrupts finally. Some
+ Forgotten World songs started to work, but not all. Thomas
+ Herman BlueAngel69 swent back to its earlier buggy state. Our
+ recent interrupt handler change broke Thomas Hermann completely.
+ This change fixes our original design fault that only one CIA
+ timer interrupt may be used, but not both. This patch takes us
+ much closer to full CIA interrupt handler support.
+ - Heikki's CIAB-A and CIAB-B separation in soundcore gave us full
+ support of the MusiclineEditor player from Eagleplayer 2.02.
+ You still have to use --speedhack to give it enough
+ cpu cycles, though. (mld)
+ - forgot to add detection bug fix of the two different MCMD formats
+ in amifilemagic to changelog *grin* (mld)
+
+2005-11-03 Heikki Orsila <heikki.orsila@iki.fi>
+ * UADE 1.50-pre8
+ - Many bug fixes and cleanups.
+ - Headphones postprocessing effect.
+ - Improved A1200 filter emulation.
+ - Added A500 filter emulation. Use --filter=a500.
+ - Cleaned up sound cores timer code.
+ - Fixed CIA timer initialization.
+ - Improved uade123 user interface. Press 'h' in uade123 or list
+ action keys with uade123 --help.
+ - New sample interpolation code (--interpolator=cspline).
+ - --stderr can be used to pipe sound data to stdout.
+
+2005-11-02 Heikki Orsila <heikki.orsila@iki.fi>
+ - Fixed a very stupid bug I introduced yesterday to src/uade.c.
+ if (curs > maxs)
+ foo();
+ bar();
+ Duh. Why did I forgot {}??
+ - Network byte orderized, or big endianized, subsong info transmission
+ between uadecore and frontend. This wasn't a bug. Just a change for
+ consistency.
+
+2005-11-01 Heikki Orsila <heikki.orsila@iki.fi>
+ - Removed src/effects.c. It was accidently left there from uade 1
+ (alankila)
+ - Removed unnecessary functionality from src/players.c. Black listing
+ Protracker modules to be VBI timed should be in frontend logic
+ rather than emulator logic.
+ - Cleaned up text messages all over the place.
+
+2005-10-31 Heikki Orsila <heikki.orsila@iki.fi>
+ - Did highly experimental changes to sound core's timing interrupt
+ system. I tested the change with all known players, and only the
+ Thomas Hermann broke out, but it was broken already, so no big
+ loss there. Of course I only tested each format with a few songs,
+ so it's very possible that if the new system doesn't work,
+ then I couldn't catch the problems. Nevertheless, I spent over an
+ hour listening to different samples. Testing this change would be
+ appreciated. One should especially pay attention to tempo, because
+ that may have gone wrong. The changes I technically made were:
+ - Made default interrupt timer to be CIA B timer A. Took away all
+ the hacks to use VBI when ever possible to be the default timer.
+ - While turning on any CIA B timer (A or B), it does not turn off
+ the other CIA B timer.
+ - Fixed CIA B timer initialization. Setting a timer (A or B) gets
+ the timer value from dtg_Timer(eaglebase).
+ - Cleaned up audio interrupt server.
+ - Fixed tiny bug in uade123 file extension detection (mld)
+ - Moved amifilemagic, uadeformats, and unixwalkdir modules to
+ frontends/common/ where they belong.
+
+2005-10-30 Heikki Orsila <heikki.orsila@iki.fi>
+ - Modified headphones effect. (alankila)
+ - Added 'H' action key to toggle headphones effect, and 'P' to toggle
+ panning effect. Default panning value is 0.7, unless specified
+ otherwise with command line option or in uade.conf.
+ - Added forgotten -O2 optimization flag to uade123 Makefile
+ - Cleaned audio.c. Removed some debug #defines.
+ - Imported amiga player sources from uade1 project to amigasrc/players/
+
+2005-10-29 Heikki Orsila <heikki.orsila@iki.fi>
+ - Antti S. Lankila <alankila@bel.fi> will be referred to as 'alankila'
+ in ChangeLog from now.
+ - Beautified and cleaned up audio.c and sd-sound-generic.h.
+ - Fixed a bug that caused 1 bit precision loss in audio output.
+ Sample data was multiplied after filtering, but it should have been
+ multiplied before. (alankila)
+ - cust.Bubble_Bobble gives wrong subsong information. Added a logic
+ into uade123 that determines subsong ranges if default subsong
+ is outside the reported range.
+ - Changed score's CIA setup so that both CIA-A and CIA-B time of day
+ counters run continously. Some players, such as Oktalyzer and
+ sean connolly depend on this. As a consequence it was possible to
+ remove a work around from score that patched the sean connolly
+ player not to use CIA TOD. However, any player using CIA TOD is at
+ risk of not functioning properly, but I have only seen two cases
+ so far (those which I mentioned).
+ - Removed score from uade source root, now it's only located at
+ amigasrc/score/ directory.
+ - Fixed a bug in uade123/playloop.c. If one subsong ended because of
+ silence, all the rest subsongs would end because of silence too.
+ I forgot to reset the silence counter to zero..
+ - Added a headphone postprocessing effect, and an effect framework for
+ different uade frontends. Try --headphone. (alankila)
+ - Try pressing 'p' on uade123 to toggle postprocessing effects on
+ and off.
+ - New filter code (alankila)
+
+2005-10-28 Heikki Orsila <heikki.orsila@iki.fi>
+ - Radical cleaned up in audio.c.
+ - Fixed rh and crux interpolators. Thanks to Antti S. Lankila.
+ <alankila@bel.fi>
+ - Removed lots of unnecessary macros, variables and functions.
+ - rh interpolator is now names as linear.
+ - Removed src/config.h. It is unnecessary.
+ - uade123 help will now print usable action keys too. Also, one may
+ press 'h' at run-time to see usable keys. It will print currently
+ as follows:
+ Action keys for interactive mode:
+ '.' Skip 10 seconds forward.
+ SPACE, 'b' Go to next subsong.
+ 'c' Pause.
+ 'f' Toggle filter (takes filter control away from eagleplayer).
+ 'h' Print this list.
+ RETURN, 'n' Next song.
+ 'q' Quit.
+ 's' Toggle between shuffle mode and normal play.
+ 'x' Restart current subsong.
+ 'z' Previous subsong.
+ - To verify whether a song uses filter or not, enable verbose mode
+ for uade123 by -v. You'll see messages like:
+ Message: Filter ON
+ - Added two different types of filters: A500 and A1200. Thanks to
+ Antti S. Lankila, again. Use --filter=a500 or --filter=a1200,
+ the A1200 case is the default. Both types of filter are
+ but A1200 filter is better tested. We need feedback on A500 filter.
+ - --force-filter was changed to --force-led.
+ - Fixed a bug with getopts. The long options list was not zero
+ terminated, and it had worked by luck so long..
+ - Added good ol' speed hack feature into uade123. Use --speedhack
+ to increase CPU speed for players that extra virtual power. It
+ is useful for players that require more cpu than 68k can give,
+ multichannel oktalyzer for example.
+
+2005-10-27 Heikki Orsila <heikki.orsila@iki.fi>
+ - Made interpolation mode selectable from command line. Use
+ --interpolator=x to choose the interpolation mode, where
+ x = default (no interpolation),
+ rh = rh interpolator (broken atm),
+ crux = crux interpolator (broken atm),
+ cspline = Antti S. Lankila's spline interpolator
+ (This is not recommended for chip songs! The spline
+ spline interpolator is good for natural instruments,
+ but may produce bad sounds with chips.)
+ - Interpolator is selectable from uade.conf file by adding line:
+ interpolator foo
+ Note that using anything else but default is not recommended
+ at the moment.
+ - As per Michael Doering's needs, I added --stderr option to uade123.
+ It will force all terminal output printed onto the stderr, and thus
+ allows piping pure sound data. Example:
+ uade123 --stderr -e raw -f /dev/stdout DW.Platoon |postprocessing
+
+2005-10-27 Heikki Orsila <heikki.orsila@iki.fi>
+ * UADE 1.50-pre7
+ - Antti S. Lankila <alankila@bel.fi> fixed and improved filter
+ behavior. The filter state must be updated even when filtering
+ is not outputted. Output scaling was fixed to the right place
+ so that it does not distort filter state. Unnecessary range
+ scaling of input samples was removed. Some documentation was
+ added about technical properties of the IIR filter.
+ - Filtering by default was not enabled for those people who had an
+ earlier uade2 version installed to their home directory, because
+ make install does not overwrite ~/.uade2/uade.conf. Now the default
+ is hard coded into the source code.
+
+2005-10-27 Heikki Orsila <heikki.orsila@iki.fi>
+ * UADE 1.50-pre6 (tester pre)
+ - Uade core now supports only 16-bits stereo. If 8-bits or mono is
+ needed the sample data can be postprocessed.
+ - Added experimental filtering support. It should be better than the
+ one found from uade1. Thanks to Antti S. Lankila <alankila@bel.fi>
+ for IIR filter coefficients and advice.
+ - New uade.conf options:
+ filter - enable filter emulation
+ no_filter - disable filter emulation
+ filter_off - turn filter always off
+ - New command line options:
+ --filter Enable filter emulation
+ --force-filter=x, where x = 0, or x = 1. Set filter state either
+ off (0) or on (1).
+
+2005-10-16 Heikki Orsila <heikki.orsila@iki.fi>
+ - Added a fuzzy state diagram on client-server interaction from client
+ perspective.
+
+2005-10-08 Heikki Orsila <heikki.orsila@iki.fi>
+ - Unknown keywords in uade.conf are ignored. Old behavior was to
+ terminate uade123 on an unknown keyword.
+ - First try to load uade.conf from ~/.uade2/uade.conf, and then
+ try the global config file ($PREFIX/etc/uade.conf)
+ - Simplify playloop in uade123.
+ - Beautify directory hierarchy scanning by avoiding unnecessary
+ '/' characters.
+ - Started specifying uade client-server protocol. See
+ doc/play_loop_state_diagram.dia.
+ - Removed S3M support. It's not an Amiga format, and thus it doesn't
+ belong to UADE. It might also interfere with other players when
+ UADE is used as an XMMS plugin. Use XMP, modplug or something
+ else for these formats.
+ - 'make check' is now 'make soundcheck' because it's more a sound
+ check than a good test set.
+
+2005-10-03 Heikki Orsila <heikki.orsila@iki.fi>
+ - Action keys made into default behavior for uade123.
+
+2005-09-08 Heikki Orsila <heikki.orsila@iki.fi>
+ - Giulio Canevari pointed out that --panning doesn't work. For
+ some reason I didn't notice that (perhaps didn't test ;-). The
+ problem was false parameters for GNU getopt.
+ - mod2ogg2.sh from Giulio Canevari
+
+2005-09-04 Heikki Orsila <heikki.orsila@iki.fi>
+ - Added -g option to uade123 to only print information about songs.
+ Songs are not played in this mode. All relevant output goes into
+ stdout. This should be useful for scripting people. An example:
+
+ $ uade123 -g /svu/chip/mod/mod.Unit-a-remix 2>/dev/null
+ playername: Protracker & relatives
+ modulename: unit-a-remix
+ formatname: type: Protracker
+ subsong_info: 1 1 1 (cur, min, max)
+ <uade123 quits fast>
+
+2005-09-01 Heikki Orsila <heikki.orsila@iki.fi>
+ - Cygwin fixes. Add cygwin detection to configure script. Makefile
+ should be aware that uade123 is named uade123.exe on cygwin.
+
+2005-08-27 Heikki Orsila <heikki.orsila@iki.fi>
+ - Fixed a memory copying bug which could cause sound data
+ corruption when skipping 10 seconds forward with uade123. The bug
+ was at playloop.c:273. memmove should be used instead of memcpy (shd)
+ - A patch from Jarno Paananen <jpaana@s2.org>. It fixes use of C99
+ anonymous initializers with sigaction (2) on Cygwin.
+
+2005-07-28 Heikki Orsila <heikki.orsila@iki.fi>
+ * UADE 1.50-pre5 (developer release)
+ - Nothing better to do. Let's release the new version for users to
+ test.
+
+2005-07-25 Heikki Orsila <heikki.orsila@iki.fi>
+ - It seems ALSA lib could fork and consequently terminate a process
+ when used through libao, and we must not consider it an error in
+ our signal handler that catches all dead children. The signal
+ handler assumed that the only child that could die is uade. (shd)
+
+2005-07-24 Heikki Orsila <heikki.orsila@iki.fi>
+ - New keys for interactive mode:
+ [0-9] - Select subsong in range [0, 9]
+ q - Quit player
+ s - Switch between normal and shuffle mode
+ x - Restart current subsong
+ - Added - or --no-song-end switches. Song just keeps playing even if
+ the amiga player says it has ended. Dude! You can get pretty weird
+ sounds with this, and sometimes the sound core crashes, and should
+ crash. Fortunately that doesn't kill the simulator :)
+ - Made help print (-h) prettier by aligning tex columns
+ - Added -K or --no-keys to disable action keys (this can be used to
+ override the uade.conf if it enables actions by default).
+
+2005-07-23 Heikki Orsila <heikki.orsila@iki.fi>
+ * UADE 1.50-pre4 (developer release)
+ - Added shell interaction keys into UADE123. The keys can be enabled
+ with -k switch, or adding line "action_keys" into uade.conf.
+ The keys are (mimiking XMMS):
+ z - Previous subsong
+ c - Pause
+ b - Next subsong
+ n - Next song
+ . - Skip 10 seconds forward
+ ENTER - Next song
+ SPACE - Next subsong
+ Does someone want these configurable into uade.conf? Please email
+ me.
+
+2005-07-22 Heikki Orsila <heikki.orsila@iki.fi>
+ * UADE 1.50-pre3 (developer release)
+ - Added a -j to skip x seconds of audio from the beginning. Note that
+ this does not affect timeout parameters in any way. If timeout is
+ 1 minute and skip is 2 minutes, the song will just end before
+ anything is played.
+
+2005-07-21 Heikki Orsila <heikki.orsila@iki.fi>
+ - Added silence timeout
+ - Wrote a config file parser for uade123. Look at uade.conf file
+ for instructions. uade123 tries to load following files in order on
+ startup: BASEDIR/uade.conf and $(HOME)/.uade2/uade.conf. Command
+ line options can override config file parameters. Users of uade123
+ might want to configure timeout, panning and such values as
+ personal defaults. This is a very important feature important over
+ uade 1.0x command line tool.
+ - Restructured uade123 code into different code modules to make
+ maintaining and code reuse easier.
+
+2005-07-18 Heikki Orsila <heikki.orsila@iki.fi>
+ - Fixed a bug in uade123 that prevented it from playing the last
+ subsong of a song.
+
+2005-07-18 Heikki Orsila <heikki.orsila@iki.fi>
+ * UADE 1.50-pre2 (developer release)
+ - uade123 now has eagleplayer fileformat check ignoring feature (-i),
+ panning (-p), song timeout (-t), and subsong timeouts (-w)
+
+2005-07-17 Heikki Orsila <heikki.orsila@iki.fi>
+ - uade123 now uses GNU getopt
+ - uade123 can now output both raw and wav formats by using libao
+ file output mechanism. Wav format is the default. Example:
+ uade123 -e wav -f foo.wav songfile
+ - The sound core now reports to the simulator when audio output should
+ start. Traditionally the simulator has produced audio output from
+ the reboot of the amiga even if it is only useful to output audio
+ after all the lengthy player initializations have been made in
+ the sound core. For example, AHX.Cruisin now has 0.96 seconds less
+ zero samples in the beginning.
+ - Cleaned up sound core a bit. Removed some unused definitions
+ of messages between sound core and the simulator. Removed unused
+ code that was designed to be used when running sound core under a
+ _real_ AmigaOS.
+ - Made uade123 less verbose. Use -v option to get more details.
+ - Renamed uade-trivial.c to 'uade123.c' in src/frontends/uade123
+ - Renamed directory 'trivial' to 'uade123' in src/frontends/
+
+2005-07-15 Heikki Orsila <heikki.orsila@iki.fi>
+ * UADE 1.50-pre1 (developer release)
+ - Lots of changes into uade123
+ - This is just a preview of the new system. There are no interesting
+ features over uade 1.0x versions. This release doesn't even have
+ xmms / beepmp plugins.
+ - Short instructions for testing:
+ $ ./configure && make
+ $ make test
+ $ make install
+ Will install everything to $(HOME)/.uade2/. Then
+ $(HOME)/.uade2/uade123 is the player you can use. This version
+ uses libao for audio output.
+
+2005-07-12 Heikki Orsila <heikki.orsila@iki.fi>
+ - Code in src/amifilemagic.c does amiga fileformats detection. If it's
+ useful for any other project out there, it is now dual licensed
+ under the GNU GPL _and_ Public Domain. By public domain we mean
+ that you can do anything you like with the code, including
+ relicensing arbitrarily for your projects.
+
+2005-07-11 Heikki Orsila <heikki.orsila@iki.fi>
+ - Improved the command line frontend in src/frontends/trivial/,
+ and now it is called uade123. It can now do fileformat detection by
+ content, and load proper players from their installation place.
+ Also, it can play multiple songs in a sequence if one switches to
+ next song with ctrl-c before the song actually ends. If the song
+ ends by itself, the system will crash ;)
+ - Found a bug in amifilemagic by accident. chk_id_offset() function
+ tested patterns of length sizeof(patterns[i]) which is totally
+ wrong. It was corrected to strlen(patterns[i]).
+
+2005-07-09 Heikki Orsila <heikki.orsila@iki.fi>
+ - Started hacking uade. The goal is to release uade 2.00 someday
+ http://board.kohina.com/viewtopic.php?p=3499#3499
+ - These changes start a series. Version 1.50 will be the first public
+ release in this series.
+ - src/frontends/trivial/ can now play single file songs.
+ - Debugging is broken because libao can't handle signals well.
+ - Tons of things missing from the system.
diff --git a/plugins/uade2/uade-2.13/README b/plugins/uade2/uade-2.13/README
new file mode 100644
index 00000000..9ada771a
--- /dev/null
+++ b/plugins/uade2/uade-2.13/README
@@ -0,0 +1,53 @@
+UADE - Unix Amiga Delitracker Emulator
+======================================
+
+UADE is a music player for UNIX platforms that plays music formats used on
+the Amiga computer.
+
+Very short instructions for installing UADE
+===========================================
+
+1. Read INSTALL.readme
+2. Install the program globally or directly to your home directory. Do either
+ ./configure
+ or
+ ./configure --user (makes uade to be installed under ~/.uade2)
+3. make
+4. make install (as root if installed globally, but as the user if configure
+ was given --user)
+
+The program is ready now.
+
+Now you can edit uade.conf, if you want. uade.conf is located at
+$PREFIX/share/uade2/uade.conf or ~/.uade2/uade.conf. If you installed
+globally, you can make a copy of uade.conf to ~/.uade2/.
+
+Fire up xmms, audacious or use the command line tool.
+
+$ uade123 -zr /my/chips
+
+Credits
+=======
+
+See AUTHORS file for credits.
+
+Information sources
+===================
+
+Web site:
+
+ http://zakalwe.fi/uade
+
+Public web forum (most issues should go here):
+
+ http://board.kohina.net/index.php?c=5
+
+Public IRC channel:
+
+ #amigaexotic at IRCNet
+
+Subscribe to new releases at: http://freshmeat.net/projects/uade
+
+Project maintainer:
+ Heikki Orsila
+ heikki.orsila@iki.fi
diff --git a/plugins/uade2/uade-2.13/src/frontends/common/amifilemagic.c b/plugins/uade2/uade-2.13/src/frontends/common/amifilemagic.c
new file mode 100644
index 00000000..9365436c
--- /dev/null
+++ b/plugins/uade2/uade-2.13/src/frontends/common/amifilemagic.c
@@ -0,0 +1,1168 @@
+/*
+ Copyright (C) 2000-2005 Heikki Orsila
+ Copyright (C) 2000-2005 Michael Doering
+
+ This module is dual licensed under the GNU GPL and the Public Domain.
+ Hence you may use _this_ module (not another code module) in any way you
+ want in your projects.
+
+ About security:
+
+ This module tries to avoid any buffer overruns by not copying anything but
+ hard coded strings (such as "FC13"). This doesn't
+ copy any data from modules to program memory. Any memory writing with
+ non-hard-coded data is an error by assumption. This module will only
+ determine the format of a given module.
+
+ Occasional memory reads over buffer ranges can occur, but they will of course
+ be fixed when spotted :P The worst that can happen with reading over the
+ buffer range is a core dump :)
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+
+#include <uadeutils.h>
+#include <amifilemagic.h>
+
+#define FILEMAGIC_DEBUG 0
+
+#if FILEMAGIC_DEBUG
+#define amifiledebug(fmt, args...) do { fprintf(stderr, "%s:%d: %s: " fmt, __FILE__, __LINE__, __func__, ## args); } while(0)
+#else
+#define amifiledebug(fmt, args...)
+#endif
+
+#define WAV_HEADER_LEN 44
+
+enum {
+ MOD_UNDEFINED = 0,
+ MOD_SOUNDTRACKER25_NOISETRACKER10,
+ MOD_NOISETRACKER12,
+ MOD_NOISETRACKER20,
+ MOD_STARTREKKER4,
+ MOD_STARTREKKER8,
+ MOD_AUDIOSCULPTURE4,
+ MOD_AUDIOSCULPTURE8,
+ MOD_PROTRACKER,
+ MOD_FASTTRACKER,
+ MOD_NOISETRACKER,
+ MOD_PTK_COMPATIBLE,
+ MOD_SOUNDTRACKER24
+};
+
+
+#define S15_HEADER_LENGTH 600
+#define S31_HEADER_LENGTH 1084
+
+
+static int chk_id_offset(unsigned char *buf, int bufsize,
+ const char *patterns[], int offset, char *pre);
+
+
+/* Do not use '\0'. They won't work in patterns */
+static const char *offset_0000_patterns[] = {
+ /* ID: Prefix: Desc: */
+ "DIGI Booster", "DIGI", /* Digibooster */
+ "OKTASONG", "OKT", /* Oktalyzer */
+ "SYNTRACKER", "SYNMOD", /* Syntracker */
+ "OBISYNTHPACK", "OSP", /* Synthpack */
+ "SOARV1.0", "SA", /* Sonic Arranger */
+ "AON4", "AON4", /* Art Of Noise (4ch) */
+ "AON8", "AON8", /* Art Of Noise (8ch) */
+ "ARP.", "MTP2", /* HolyNoise / Major Tom */
+ "AmBk", "ABK", /* Amos ABK */
+ "FUCO", "BSI", /* FutureComposer BSI */
+ "MMU2", "DSS", /* DSS */
+ "GLUE", "GLUE", /* GlueMon */
+ "ISM!", "IS", /* In Stereo */
+ "IS20", "IS20", /* In Stereo 2 */
+ "SMOD", "FC13", /* FC 1.3 */
+ "FC14", "FC14", /* FC 1.4 */
+ "MMDC", "MMDC", /* Med packer */
+ "MSOB", "MSO", /* Medley */
+ "MODU", "NTP", /* Novotrade */
+/* HIPPEL-ST CONFLICT: "COSO", "SOC",*/ /* Hippel Coso */
+ "BeEp", "JAM", /* Jamcracker */
+ "ALL ", "DM1", /* Deltamusic 1 */
+ "YMST", "YM", /* MYST ST-YM */
+ "AMC ", "AMC", /* AM-Composer */
+ "P40A", "P40A", /* The Player 4.0a */
+ "P40B", "P40B", /* The Player 4.0b */
+ "P41A", "P41A", /* The Player 4.1a */
+ "P50A", "P50A", /* The Player 5.0a */
+ "P60A", "P60A", /* The Player 6.0a */
+ "P61A", "P61A", /* The Player 6.1a */
+ "SNT!", "PRU2", /* Prorunner 2 */
+ "MEXX_TP2", "TP2", /* Tracker Packer 2 */
+ "CPLX_TP3", "TP3", /* Tracker Packer 3 */
+ "MEXX", "TP1", /* Tracker Packer 2 */
+ "PM40", "PM40", /* Promizer 4.0 */
+ "FC-M", "FC-M", /* FC-M */
+ "E.M.S. V6.", "EMSV6", /* EMS version 6 */
+ "MCMD", "MCMD_org", /* 0x00 MCMD format */
+ "STP3", "STP3", /* Soundtracker Pro 2 */
+ "MTM", "MTM", /* Multitracker */
+ "Extended Module:", "XM", /* Fasttracker2 */
+ "MLEDMODL", "ML", /* Musicline Editor */
+ "FTM", "FTM", /* Face The Music */
+ "MXTX", "MXTX", /* Maxtrax*/
+ "M1.0", "FUZZ", /* Fuzzac*/
+ "MSNG", "TPU", /* Dirk Bialluch*/
+ "YM!", "", /* stplay -- intentionally sabotaged */
+ "ST1.2 ModuleINFO", "", /* Startrekker AM .NT -- intentionally sabotaged */
+ "AudioSculpture10", "", /* Audiosculpture .AS -- intentionally sabotaged */
+ NULL, NULL
+};
+
+static const char *offset_0024_patterns[] = {
+ /* ID: Prefix: Desc: */
+ "UNCLEART", "DL", /* Dave Lowe WT */
+ "DAVELOWE", "DL_deli", /* Dave Lowe Deli */
+ "J.FLOGEL", "JMF", /* Janko Mrsic-Flogel */
+ "BEATHOVEN", "BSS", /* BSS */
+ "FREDGRAY", "GRAY", /* Fred Gray */
+ "H.DAVIES", "HD", /* Howie Davies */
+ "RIFFRAFF", "RIFF", /* Riff Raff */
+ "!SOPROL!", "SPL", /* Soprol */
+ "F.PLAYER", "FP", /* F.Player */
+ "S.PHIPPS", "CORE", /* Core Design */
+ "DAGLISH!", "BDS", /* Benn Daglish */
+ NULL, NULL
+};
+
+
+/* check for 'pattern' in 'buf'.
+ the 'pattern' must lie inside range [0, maxlen) in the buffer.
+ returns true if pattern is at buf[offset], otherwrise false
+ */
+static int patterntest(const unsigned char *buf, const char *pattern,
+ int offset, int bytes, int maxlen)
+{
+ if ((offset + bytes) <= maxlen)
+ return (memcmp(buf + offset, pattern, bytes) == 0) ? 1 : 0;
+ return 0;
+}
+
+
+static int tronictest(unsigned char *buf, size_t bufsize)
+{
+ size_t a = read_be_u16(&buf[0x02]) + read_be_u16(&buf[0x06]) +
+ read_be_u16(&buf[0x0a]) + read_be_u16(&buf[0x0e]) + 0x10;
+
+ if (((a + 2) >= bufsize) || (a & 1))
+ return 0; /* size & btst #0, d1; */
+
+ a = read_be_u16(&buf[a]) + a;
+ if (((a + 8) >= bufsize) || (a & 1))
+ return 0; /*size & btst #0,d1 */
+
+ if (read_be_u32(&buf[a + 4]) != 0x5800b0)
+ return 0;
+
+ amifiledebug("tronic recognized\n");
+
+ return 1;
+}
+
+static int tfmxtest(unsigned char *buf, size_t bufsize, char *pre)
+{
+ if (bufsize <= 0x208)
+ return 0;
+
+ if (strncmp((char *) buf, "TFHD", 4) == 0) {
+ if (buf[0x8] == 0x01) {
+ strcpy(pre, "TFHD1.5"); /* One File TFMX format by Alexis NASR */
+ return 1;
+ } else if (buf[0x8] == 0x02) {
+ strcpy(pre, "TFHDPro");
+ return 1;
+ } else if (buf[0x8] == 0x03) {
+ strcpy(pre, "TFHD7V");
+ return 1;
+ }
+ }
+
+ if (strncasecmp((char *) buf, "TFMX", 4) == 0) {
+ if (strncmp((char *) &buf[4], "-SONG", 5) == 0 ||
+ strncmp((char *) &buf[4], "_SONG ", 6) == 0 ||
+ strncasecmp((char *) &buf[4], "SONG", 4) == 0 ||
+ buf[4] == 0x20) {
+ strcpy(pre, "MDAT"); /*default TFMX: TFMX Pro */
+
+ if (strncmp((char *) &buf[10], "by", 2) == 0 ||
+ strncmp((char *) &buf[16], " ", 2) == 0 ||
+ strncmp((char *) &buf[16], "(Empty)", 7) == 0 ||
+ /* Lethal Zone */
+ (buf[16] == 0x30 && buf[17] == 0x3d) ||
+ (buf[4] == 0x20)){
+
+ if (read_be_u32(&buf[464]) == 0x00000000) {
+ uint16_t x = read_be_u16(&buf[14]);
+ if ((x != 0x0e60) || /* z-out title */
+ (x == 0x0860 && bufsize > 4645 && read_be_u16(&buf[4644]) != 0x090c) || /* metal law */
+ (x == 0x0b20 && bufsize > 5121 && read_be_u16(&buf[5120]) != 0x8c26) || /* bug bomber */
+ (x == 0x0920 && bufsize > 3977 && read_be_u16(&buf[3876]) != 0x9305)) { /* metal preview */
+ strcpy(pre, "TFMX1.5"); /*TFMX 1.0 - 1.6 */
+ }
+ }
+ return 1;
+
+ } else if (((buf[0x0e] == 0x08 && buf[0x0f] == 0xb0) && /* BMWi */
+ (buf[0x140] == 0x00 && buf[0x141] == 0x0b) && /*End tackstep 1st subsong */
+ (buf[0x1d2] == 0x02 && buf[0x1d3] == 0x00) && /*Trackstep datas */
+ (buf[0x200] == 0xff && buf[0x201] == 0x00 && /*First effect */
+ buf[0x202] == 0x00 && buf[0x203] == 0x00 &&
+ buf[0x204] == 0x01 && buf[0x205] == 0xf4 &&
+ buf[0x206] == 0xff && buf[0x207] == 0x00)) ||
+ ((buf[0x0e] == 0x0A && buf[0x0f] == 0xb0) && /* B.C Kid */
+ (buf[0x140] == 0x00 && buf[0x141] == 0x15) && /*End tackstep 1st subsong */
+ (buf[0x1d2] == 0x02 && buf[0x1d3] == 0x00) && /*Trackstep datas */
+ (buf[0x200] == 0xef && buf[0x201] == 0xfe && /*First effect */
+ buf[0x202] == 0x00 && buf[0x203] == 0x03 &&
+ buf[0x204] == 0x00 && buf[0x205] == 0x0d &&
+ buf[0x206] == 0x00 && buf[0x207] == 0x00))) {
+ strcpy(pre, "TFMX7V"); /* "special cases TFMX 7V */
+ return 1;
+
+ } else {
+ int e, i, s, t;
+
+ /* Trackstep datas offset */
+ s = read_be_u32(&buf[0x1d0]);
+ if (s == 0x00000000) {
+ /* unpacked */
+ s = 0x00000800;
+ }
+
+ for (i = 0; i < 0x3d; i += 2) {
+ if (read_be_u16(&buf[0x140 + i]) != 0x0000) { /* subsong */
+ /* Start of subsongs Trackstep data :) */
+ t = read_be_u16(&buf[0x100 + i]) * 16 + s;
+ /* End of subsongs Trackstep data :) */
+ e = read_be_u16(&buf[0x140 + i]) * 16 + s;
+ if (e < bufsize) {
+ for (; t < e && (t + 6) < bufsize; t += 2) {
+ if (read_be_u16(&buf[t]) == 0xeffe &&
+ read_be_u32(&buf[t + 2]) == 0x0003ff00 &&
+ buf[t + 6] == 0x00) {
+ strcpy(pre, "TFMX7V"); /*TFMX 7V */
+ return 1;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+/* Calculate Module length: Just need at max 1084 */
+/* data in buf for a */
+/* succesful calculation */
+/* returns: */
+/* -1 for no mod */
+/* 1 for a mod with good length */
+static size_t modlentest(unsigned char *buf, size_t bufsize, size_t filesize,
+ int header)
+{
+ int i;
+ int no_of_instr;
+ int smpl = 0;
+ int plist;
+ int maxpattern = 0;
+
+ if (header > bufsize)
+ return -1; /* no mod */
+
+ if (header == S15_HEADER_LENGTH) {
+ no_of_instr = 15;
+ plist = header - 128;
+ } else if (header == S31_HEADER_LENGTH) {
+ no_of_instr = 31;
+ plist = header - 4 - 128;
+ } else {
+ return -1;
+ }
+
+ for (i = 0; i < 128; i++) {
+ if (buf[plist + i] > maxpattern)
+ maxpattern = buf[plist + i];
+ }
+
+ if (maxpattern > 100)
+ return -1;
+
+ for (i = 0; i < no_of_instr; i++)
+ smpl += 2 * read_be_u16(&buf[42 + i * 30]); /* add sample length in bytes*/
+
+ return header + (maxpattern + 1) * 1024 + smpl;
+}
+
+
+static void modparsing(unsigned char *buf, size_t bufsize, size_t header, int max_pattern, int pfx[], int pfxarg[])
+{
+ int offset;
+ int i, j, fx;
+ unsigned char fxarg;
+
+ for (i = 0; i < max_pattern; i++) {
+ for (j = 0; j < 256; j++) {
+ offset = header + i * 1024 + j * 4;
+
+ if ((offset + 4) > bufsize)
+ return;
+
+ fx = buf[offset + 2] & 0x0f;
+ fxarg = buf[offset + 3];
+
+ if (fx == 0) {
+ if (fxarg != 0 )
+ pfx[fx] += 1;
+ pfxarg[fx] = (pfxarg[fx] > fxarg) ? pfxarg[fx] : fxarg;
+
+ } else if (1 <= fx && fx <= 13) {
+ pfx[fx] +=1;
+ pfxarg[fx] = (pfxarg[fx] > fxarg) ? pfxarg[fx] : fxarg;
+
+ } else if (fx == 14) {
+ pfx[((fxarg >> 4) & 0x0f) + 16] +=1;
+
+ } else if (fx == 15) {
+ if (fxarg > 0x1f)
+ pfx[14] +=1;
+ else
+ pfx[15] +=1;
+ pfxarg[15] = (pfxarg[15] > fxarg) ? pfxarg[15] : fxarg;
+ }
+ }
+ }
+
+}
+
+
+static int mod32check(unsigned char *buf, size_t bufsize, size_t realfilesize,
+ const char *path, int verbose)
+{
+ /* mod patterns at file offset 0x438 */
+ char *mod_patterns[] = { "M.K.", ".M.K", NULL};
+ /* startrekker patterns at file offset 0x438 */
+ char *startrekker_patterns[] = { "FLT4", "FLT8", "EXO4", "EXO8", NULL};
+
+ int max_pattern = 0;
+ int i, j, t, ret;
+ int pfx[32];
+ int pfxarg[32];
+
+ /* instrument var */
+ int vol, slen, srep, sreplen;
+
+ int has_slen_sreplen_zero = 0; /* sreplen empty of non looping instrument */
+ int no_slen_sreplen_zero = 0; /* sreplen */
+
+ int has_slen_sreplen_one = 0;
+ int no_slen_sreplen_one = 0;
+
+ int no_slen_has_volume = 0;
+ int finetune_used = 0;
+
+ size_t calculated_size;
+
+ /* returns: 0 for undefined */
+ /* 1 for a Soundtracker2.5/Noisetracker 1.0 */
+ /* 2 for a Noisetracker 1.2 */
+ /* 3 for a Noisetracker 2.0 */
+ /* 4 for a Startrekker 4ch */
+ /* 5 for a Startrekker 8ch */
+ /* 6 for Audiosculpture 4 ch/fm */
+ /* 7 for Audiosculpture 8 ch/fm */
+ /* 8 for a Protracker */
+ /* 9 for a Fasttracker */
+ /* 10 for a Noisetracker (M&K!) */
+ /* 11 for a PTK Compatible */
+ /* 12 for a Soundtracker 31instr. with repl in bytes */
+
+ /* Special cases first */
+ if (patterntest(buf, "M&K!", (S31_HEADER_LENGTH - 4), 4, bufsize))
+ return MOD_NOISETRACKER; /* Noisetracker (M&K!) */
+
+ if (patterntest(buf, "M!K!", (S31_HEADER_LENGTH - 4), 4, bufsize))
+ return MOD_PROTRACKER; /* Protracker (100 patterns) */
+
+ if (patterntest(buf, "N.T.", (S31_HEADER_LENGTH - 4), 4, bufsize))
+ return MOD_NOISETRACKER20; /* Noisetracker2.x */
+
+ for (i = 0; startrekker_patterns[i]; i++) {
+ if (patterntest(buf, startrekker_patterns[i], (S31_HEADER_LENGTH - 4), 4, bufsize)) {
+ t = 0;
+ for (j = 0; j < 30 * 0x1e; j = j + 0x1e) {
+ if (buf[0x2a + j] == 0 && buf[0x2b + j] == 0 && buf[0x2d + j] != 0) {
+ t = t + 1; /* no of AM instr. */
+ }
+ }
+ if (t > 0) {
+ if (buf[0x43b] == '4'){
+ ret = MOD_AUDIOSCULPTURE4; /* Startrekker 4 AM / ADSC */
+ } else {
+ ret = MOD_AUDIOSCULPTURE8; /* Startrekker 8 AM / ADSC */
+ }
+ } else {
+ if (buf[0x43b] == '4'){
+ ret = MOD_STARTREKKER4; /* Startrekker 4ch */
+ } else {
+ ret = MOD_STARTREKKER8; /* Startrekker 8ch */
+ }
+ }
+ return ret;
+ }
+ }
+
+ calculated_size = modlentest(buf, bufsize, realfilesize, S31_HEADER_LENGTH);
+
+ if (calculated_size == -1)
+ return MOD_UNDEFINED;
+
+
+ for (i = 0; mod_patterns[i]; i++) {
+ if (patterntest(buf, mod_patterns[i], S31_HEADER_LENGTH - 4, 4, bufsize)) {
+ /* seems to be a generic M.K. MOD */
+ /* only spam filesize message when it's a tracker module */
+
+ if (calculated_size != realfilesize) {
+ fprintf(stderr, "uade: file size is %zd but calculated size for a mod file is %zd (%s).\n", realfilesize, calculated_size, path);
+ }
+
+ if (calculated_size > realfilesize) {
+ fprintf(stderr, "uade: file is truncated and won't get played (%s)\n", path);
+ return MOD_UNDEFINED;
+ }
+
+ if (calculated_size < realfilesize) {
+ fprintf(stderr, "uade: file has trailing garbage behind the actual module data. Please fix it. (%s)\n", path);
+ }
+
+ /* parse instruments */
+ for (i = 0; i < 31; i++) {
+ vol = buf[45 + i * 30];
+ slen = ((buf[42 + i * 30] << 8) + buf[43 + i * 30]) * 2;
+ srep = ((buf[46 + i * 30] << 8) + buf[47 + i * 30]) *2;
+ sreplen = ((buf[48 + i * 30] << 8) + buf[49 + i * 30]) * 2;
+ /* fprintf (stderr, "%d, slen: %d, %d (srep %d, sreplen %d), vol: %d\n",i, slen, srep+sreplen,srep, sreplen, vol); */
+
+ if (vol > 64)
+ return MOD_UNDEFINED;
+
+ if (buf[44 + i * 30] != 0) {
+ if (buf[44+i*30] > 15) {
+ return MOD_UNDEFINED;
+ } else {
+ finetune_used++;
+ }
+ }
+
+ if (slen > 0 && (srep + sreplen) > slen) {
+ /* Old Noisetracker /Soundtracker with repeat offset in bytes */
+ return MOD_SOUNDTRACKER24;
+ }
+
+ if (srep == 0) {
+ if (slen > 0) {
+ if (sreplen == 2){
+ has_slen_sreplen_one++;
+ }
+ if (sreplen == 0){
+ has_slen_sreplen_zero++;
+ }
+ } else {
+ if (sreplen > 0){
+ no_slen_sreplen_one++;
+ } else {
+ no_slen_sreplen_zero++;
+ }
+ if (vol > 0)
+ no_slen_has_volume++;
+ }
+ }
+ }
+
+ for (i = 0; i < 128; i++) {
+ if (buf[1080 - 130 + 2 + i] > max_pattern)
+ max_pattern = buf[1080 - 130 + 2 + i];
+ }
+
+ if (max_pattern > 100) {
+ /* pattern number can only be 0 <-> 100 for mod*/
+ return MOD_UNDEFINED;
+ }
+
+ memset (pfx, 0, sizeof (pfx));
+ memset (pfxarg, 0, sizeof (pfxarg));
+ modparsing(buf, bufsize, S31_HEADER_LENGTH-4, max_pattern, pfx, pfxarg);
+
+ /* and now for let's see if we can spot the mod */
+
+ /* FX used: */
+ /* DOC Soundtracker 2.x(2.5): 0,1,2(3,4) a,b,c,d,e,f */
+ /* Noisetracker 1.x: 0,1,2,3,4 a,b,c,d,e,f */
+ /* Noisetracker 2.x: 0,1,2,3,4 a,b,c,d,e,f */
+ /* Protracker: 0,1,2,3,4,5,6,7 9,a,b,c,d,e,f +e## */
+ /* PC tracker: 0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f +e## */
+
+ for (j = 17; j <= 31; j++) {
+ if (pfx[j] != 0 || finetune_used >0) /* Extended fx used */ {
+ if (buf[0x3b7] != 0x7f && buf[0x3b7] != 0x78) {
+ return MOD_FASTTRACKER; /* Definetely Fasttracker*/
+ } else {
+ return MOD_PROTRACKER; /* Protracker*/
+ }
+ }
+ }
+
+ if ((buf[0x3b7] == 0x7f) &&
+ (has_slen_sreplen_zero <= has_slen_sreplen_one) &&
+ (no_slen_sreplen_zero <=no_slen_sreplen_one))
+ return MOD_PROTRACKER; /* Protracker */
+
+ if (buf[0x3b7] >0x7f)
+ return MOD_PTK_COMPATIBLE; /* Protracker compatible */
+
+ if ((buf[0x3b7] == 0) &&
+ (has_slen_sreplen_zero > has_slen_sreplen_one) &&
+ (no_slen_sreplen_zero > no_slen_sreplen_one)){
+ if (pfx[0x10] == 0) {
+ /* probl. Fastracker or Protracker compatible */
+ return MOD_PTK_COMPATIBLE;
+ }
+ /* FIXME: Investigate
+ else {
+ return MOD_PROTRACKER; // probl. Protracker
+ } */
+ }
+
+ if (pfx[0x05] != 0 || pfx[0x06] != 0 || pfx[0x07] != 0 ||
+ pfx[0x09] != 0) {
+ /* Protracker compatible */
+ return MOD_PTK_COMPATIBLE;
+ }
+
+ if ((buf[0x3b7] >0 && buf[0x3b7] <= buf[0x3b6]) &&
+ (has_slen_sreplen_zero <= has_slen_sreplen_one) &&
+ (no_slen_sreplen_zero == 1) &&
+ (no_slen_sreplen_zero <= no_slen_sreplen_one))
+ return MOD_NOISETRACKER12; // Noisetracker 1.2
+
+ if ((buf[0x3b7] <0x80) &&
+ (has_slen_sreplen_zero <= has_slen_sreplen_one) &&
+ (no_slen_sreplen_zero <=no_slen_sreplen_one))
+ return MOD_NOISETRACKER20; // Noisetracker 2.x
+
+ if ((buf[0x3b7] <0x80) &&
+ (pfx[0x0e] ==0) &&
+ (has_slen_sreplen_zero <= has_slen_sreplen_one) &&
+ (no_slen_sreplen_zero >=no_slen_sreplen_one))
+ return MOD_SOUNDTRACKER25_NOISETRACKER10; // Noisetracker 1.x
+
+ return MOD_PTK_COMPATIBLE; // Protracker compatible
+ }
+ }
+
+ return MOD_UNDEFINED;
+}
+
+
+static int mod15check(unsigned char *buf, size_t bufsize, size_t realfilesize,
+ const char *path)
+/* pattern parsing based on Sylvain 'Asle' Chipaux' */
+/* Modinfo-V2 */
+/* */
+/* returns: 0 for an undefined mod */
+/* 1 for a DOC Soundtracker mod */
+/* 2 for a Ultimate ST mod */
+/* 3 for a Mastersoundtracker */
+/* 4 for a SoundtrackerV2.0 -V4.0 */
+{
+ int i = 0, j = 0;
+ int slen = 0;
+ int srep = 0;
+ int sreplen = 0;
+ int vol = 0;
+
+ int noof_slen_zero_sreplen_zero = 0;
+ int noof_slen_zero_vol_zero = 0;
+ int srep_bigger_slen = 0;
+ int srep_bigger_ffff = 0;
+ int st_xy = 0;
+
+ int max_pattern = 1;
+ int pfx[32];
+ int pfxarg[32];
+
+ size_t calculated_size;
+
+ /* sanity checks */
+ if (bufsize < 0x1f3)
+ return 0; /* file too small */
+
+ if (bufsize < 2648+4 || realfilesize <2648+4) /* size 1 pattern + 1x 4 bytes Instrument :) */
+ return 0;
+
+ calculated_size = modlentest(buf, bufsize, realfilesize, S15_HEADER_LENGTH);
+ if (calculated_size == -1)
+ return 0; /* modlentest failed */
+
+ if (calculated_size != realfilesize) {
+ return 0 ;
+ }
+
+ if (calculated_size > realfilesize) {
+ fprintf(stderr, "uade: file is truncated and won't get played (%s)\n", path);
+ return 0 ;
+ }
+
+
+
+ /* check for 15 instruments */
+ if (buf[0x1d6] != 0x00 && buf[0x1d6] < 0x81 && buf[0x1f3] !=1) {
+ for (i = 0; i < 128; i++) { /* pattern list table: 128 posbl. entries */
+ max_pattern=(buf[600 - 130 + 2 + i] > max_pattern) ? buf[600 - 130 + 2 + i] : max_pattern;
+ }
+ if (max_pattern > 63)
+ return 0; /* pattern number can only be 0 <-> 63 for mod15 */
+ } else {
+ return 0;
+ }
+
+ /* parse instruments */
+ for (i = 0; i < 15; i++) {
+ vol = buf[45 + i * 30];
+ slen = ((buf[42 + i * 30] << 8) + buf[43 + i * 30]) * 2;
+ srep = ((buf[46 + i * 30] << 8) + buf[47 + i * 30]);
+ sreplen = ((buf[48 + i * 30] << 8) + buf[49 + i * 30]) * 2;
+ /* fprintf (stderr, "%d, slen: %d, %d (srep %d, sreplen %d), vol: %d\n",i, slen, srep+sreplen,srep, sreplen, vol); */
+
+ if (vol > 64 && buf[44+i*30] != 0) return 0; /* vol and finetune */
+
+ if (slen == 0) {
+
+ if (vol == 0)
+ noof_slen_zero_vol_zero++;
+
+ if (sreplen == 0 )
+ noof_slen_zero_sreplen_zero++;
+
+ } else {
+ if ((srep+sreplen) > slen)
+ srep_bigger_slen++;
+ }
+
+ /* slen < 9999 */
+ slen = (buf[42 + i * 30] << 8) + buf[43 + i * 30];
+ if (slen <= 9999) {
+ /* repeat offset + repeat size*2 < word size */
+ srep = ((buf[48 + i * 30] << 8) + buf[49 + i * 30]) * 2 +
+ ((buf[46 + i * 30] << 8) + buf[47 + i * 30]);
+ if (srep > 0xffff) srep_bigger_ffff++;
+ }
+
+ if (buf[25+i*30] ==':' && buf [22+i*30] == '-' &&
+ ((buf[20+i*30] =='S' && buf [21+i*30] == 'T') ||
+ (buf[20+i*30] =='s' && buf [21+i*30] == 't'))) st_xy++;
+ }
+
+ /* parse pattern data -> fill pfx[] with number of times fx being used*/
+ memset (pfx, 0, sizeof (pfx));
+ memset (pfxarg, 0, sizeof (pfxarg));
+
+ modparsing(buf, bufsize, S15_HEADER_LENGTH, max_pattern, pfx, pfxarg);
+
+ /* and now for let's see if we can spot the mod */
+
+/* FX used: */
+/* Ultimate ST: 0,1,2 */
+/* MasterSoundtracker: 0,1,2, c, e,f */
+/* DOC-Soundtracker V2.2: 0,1,2,a,b,c,d,e,f */
+/* Soundtracker I-VI 0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f*/
+
+
+ /* Check for fx used between 0x3 <-> 0xb for some weird ST II-IV mods */
+ for (j = 0x5; j < 0xa; j++) {
+ if (pfx[j] != 0)
+ return 4; /* ST II-IV */
+ }
+
+ for (j = 0x0c; j < 0x11; j++) {
+ if (pfx[j] != 0) {
+
+ if (pfx[0x0d] != 0 && pfxarg[0x0d] != 0)
+ return 4; /* ST II-IV */
+
+ if (pfx[0x0b] != 0 || pfx[0x0d] != 0 || pfx[0x0a]!= 0 ) {
+ return 1; /* DOC ST */
+ } else {
+ if (pfxarg[1] > 0xe || pfxarg[2] > 0xe)
+ return 1; /* DOC ST */
+
+ return 3; /* Master ST */
+ }
+ }
+ }
+
+ /* pitchbend out of range ? */
+ if ((pfxarg[1] > 0 && pfxarg[1] <0x1f) ||
+ (pfxarg[2] > 0 && pfxarg [2] <0x1f) ||
+ pfx [0] >2) return 1; // ST style Arpeggio, Pitchbends ???
+
+ if (pfx[1] > 0 || pfx[2] > 0)
+ return 2; /* nope UST like fx */
+
+ /* the rest of the files has no fx. so check instruments */
+ if (st_xy!=0 && noof_slen_zero_vol_zero == 0 &&
+ noof_slen_zero_sreplen_zero == 0 && buf[0x1d7] == 120) {
+ return 3;
+ }
+
+ /* no fx, no loops... let's simply guess :)*/
+ if (srep_bigger_slen == 0 && srep_bigger_ffff == 0 &&
+ ((st_xy != 0 && buf[0x1d7] != 120 ) || st_xy==0))
+ return 2;
+
+ return 3; /* anything is played as normal soundtracker */
+}
+
+/* Reject WAV files so that uadefs doesn't cause bad behaviour */
+static int is_wav_file(unsigned char *buf, size_t size)
+{
+ if (size < WAV_HEADER_LEN)
+ return 0;
+
+ if (memcmp(buf, "RIFF", 4))
+ return 0;
+
+ if (memcmp(buf + 8, "WAVEfmt ", 8))
+ return 0;
+
+ if (memcmp(buf + 36, "data", 4))
+ return 0;
+
+ return 1;
+}
+
+void uade_filemagic(unsigned char *buf, size_t bufsize, char *pre,
+ size_t realfilesize, const char *path, int verbose)
+{
+ /* char filemagic():
+ detects formats like e.g.: tfmx1.5, hip, hipc, fc13, fc1.4
+ - tfmx 1.5 checking based on both tfmx DT and tfmxplay by jhp,
+ and the EP by Don Adan/WT.
+ - tfmx 7v checking based on info by don adan, the amore file
+ ripping description and jhp's desc of the tfmx format.
+ - other checks based on e.g. various player sources from Exotica
+ or by checking bytes with a hexeditor
+ by far not complete...
+
+ NOTE: Those Magic ID checks are quite lame compared to the checks the
+ amiga replayer do... well, after all we are not ripping. so they
+ have to do at the moment :)
+ */
+
+ int i, modtype, t;
+
+ struct modtype {
+ int e;
+ char *str;
+ };
+
+ struct modtype mod32types[] = {
+ {.e = MOD_SOUNDTRACKER25_NOISETRACKER10, .str = "MOD_NTK"},
+ {.e = MOD_NOISETRACKER12, .str = "MOD_NTK1"},
+ {.e = MOD_NOISETRACKER20, .str = "MOD_NTK2"},
+ {.e = MOD_STARTREKKER4, .str = "MOD_FLT4"},
+ {.e = MOD_STARTREKKER8, .str = "MOD_FLT8"},
+ {.e = MOD_AUDIOSCULPTURE4, .str = "MOD_ADSC4"},
+ {.e = MOD_AUDIOSCULPTURE8, .str = "MOD_ADSC8"},
+ {.e = MOD_PROTRACKER, .str = "MOD"},
+ {.e = MOD_FASTTRACKER, .str = "MOD_COMP"},
+ {.e = MOD_NOISETRACKER, .str = "MOD_NTKAMP"},
+ {.e = MOD_PTK_COMPATIBLE, .str = "MOD_COMP"},
+ {.e = MOD_SOUNDTRACKER24, .str = "MOD_DOC"},
+ {.str = NULL}
+ };
+
+ struct modtype mod15types[] = {
+ {.e = 1, .str = "MOD15"},
+ {.e = 2, .str = "MOD15_UST"},
+ {.e = 3, .str = "MOD15_MST"},
+ {.e = 4, .str = "MOD15_ST-IV"},
+ {.str = NULL}
+ };
+
+ /* Mark format unknown by default */
+ pre[0] = 0;
+
+ if (is_wav_file(buf, bufsize)) {
+ strcpy(pre, "reject");
+ return;
+ }
+
+ modtype = mod32check(buf, bufsize, realfilesize, path, verbose);
+ if (modtype != MOD_UNDEFINED) {
+ for (t = 0; mod32types[t].str != NULL; t++) {
+ if (modtype == mod32types[t].e) {
+ strcpy(pre, mod32types[t].str);
+ return;
+ }
+ }
+ }
+
+ /* 0x438 == S31_HEADER_LENGTH - 4 */
+ if (((buf[0x438] >= '1' && buf[0x438] <= '3')
+ && (buf[0x439] >= '0' && buf[0x439] <= '9') && buf[0x43a] == 'C'
+ && buf[0x43b] == 'H') || ((buf[0x438] >= '2' && buf[0x438] <= '8')
+ && buf[0x439] == 'C' && buf[0x43a] == 'H'
+ && buf[0x43b] == 'N')
+ || (buf[0x438] == 'T' && buf[0x439] == 'D' && buf[0x43a] == 'Z')
+ || (buf[0x438] == 'O' && buf[0x439] == 'C' && buf[0x43a] == 'T'
+ && buf[0x43b] == 'A') || (buf[0x438] == 'C' && buf[0x439] == 'D'
+ && buf[0x43a] == '8'
+ && buf[0x43b] == '1')) {
+ strcpy(pre, "MOD_PC"); /*Multichannel Tracker */
+
+ } else if (buf[0x2c] == 'S' && buf[0x2d] == 'C' && buf[0x2e] == 'R'
+ && buf[0x2f] == 'M') {
+ strcpy(pre, "S3M"); /*Scream Tracker */
+
+ } else if ((buf[0] == 0x60 && buf[2] == 0x60 && buf[4] == 0x48
+ && buf[5] == 0xe7) || (buf[0] == 0x60 && buf[2] == 0x60
+ && buf[4] == 0x41 && buf[5] == 0xfa)
+ || (buf[0] == 0x60 && buf[1] == 0x00 && buf[4] == 0x60
+ && buf[5] == 0x00 && buf[8] == 0x48 && buf[9] == 0xe7)
+ || (buf[0] == 0x60 && buf[1] == 0x00 && buf[4] == 0x60
+ && buf[5] == 0x00 && buf[8] == 0x60 && buf[9] == 0x00
+ && buf[12] == 0x60 && buf[13] == 0x00 && buf[16] == 0x48
+ && buf[17] == 0xe7)) {
+ strcpy(pre, "SOG"); /* Hippel */
+
+ } else if (buf[0x348] == '.' && buf[0x349] == 'Z' && buf[0x34A] == 'A'
+ && buf[0x34B] == 'D' && buf[0x34c] == 'S' && buf[0x34d] == '8'
+ && buf[0x34e] == '9' && buf[0x34f] == '.') {
+ strcpy(pre, "MKII"); /* Mark II */
+
+ } else if (read_be_u16(&buf[0x00]) == 0x2b7c &&
+ read_be_u16(&buf[0x08]) == 0x2b7c &&
+ read_be_u16(&buf[0x10]) == 0x2b7c &&
+ read_be_u16(&buf[0x18]) == 0x2b7c &&
+ read_be_u32(&buf[0x20]) == 0x303c00ff &&
+ read_be_u32(&buf[0x24]) == 0x32004eb9 &&
+ read_be_u16(&buf[0x2c]) == 0x4e75) {
+ strcpy(pre, "JPO"); /* Steve Turner*/
+
+ } else if (((buf[0] == 0x08 && buf[1] == 0xf9 && buf[2] == 0x00
+ && buf[3] == 0x01) && (buf[4] == 0x00 && buf[5] == 0xbb
+ && buf[6] == 0x41 && buf[7] == 0xfa)
+ && ((buf[0x25c] == 0x4e && buf[0x25d] == 0x75)
+ || (buf[0x25c] == 0x4e && buf[0x25d] == 0xf9)))
+ || ((buf[0] == 0x41 && buf[1] == 0xfa)
+ && (buf[4] == 0xd1 && buf[5] == 0xe8)
+ && (((buf[0x230] == 0x4e && buf[0x231] == 0x75)
+ || (buf[0x230] == 0x4e && buf[0x231] == 0xf9))
+ || ((buf[0x29c] == 0x4e && buf[0x29d] == 0x75)
+ || (buf[0x29c] == 0x4e && buf[0x29d] == 0xf9))
+ ))) {
+ strcpy(pre, "SID1"); /* SidMon1 */
+
+ } else if (buf[0] == 0x4e && buf[1] == 0xfa &&
+ buf[4] == 0x4e && buf[5] == 0xfa &&
+ buf[8] == 0x4e && buf[9] == 0xfa &&
+ buf[2] == 0x00 && buf[6] == 0x06 && buf[10] == 0x07) {
+ if (buf[3] == 0x2a && buf[7] == 0xfc && buf[11] == 0x7c) {
+ strcpy(pre, "SA_old");
+ } else if (buf[3] == 0x1a && buf[7] == 0xc6 && buf[11] == 0x3a) {
+ strcpy(pre, "SA");
+ }
+
+ } else if (buf[0] == 0x4e && buf[1] == 0xfa &&
+ buf[4] == 0x4e && buf[5] == 0xfa &&
+ buf[8] == 0x4e && buf[9] == 0xfa &&
+ buf[0xc] == 0x4e && buf[0xd] == 0xfa) {
+ for (i = 0x10; i < 256; i = i + 2) {
+ if (buf[i + 0] == 0x4e && buf[i + 1] == 0x75 && buf[i + 2] == 0x47
+ && buf[i + 3] == 0xfa && buf[i + 12] == 0x4e && buf[i + 13] == 0x75) {
+ strcpy(pre, "FRED"); /* FRED */
+ break;
+ }
+ }
+
+ } else if (buf[0] == 0x60 && buf[1] == 0x00 &&
+ buf[4] == 0x60 && buf[5] == 0x00 &&
+ buf[8] == 0x60 && buf[9] == 0x00 &&
+ buf[12] == 0x48 && buf[13] == 0xe7) {
+ strcpy(pre, "MA"); /*Music Assembler */
+
+ } else if (buf[0] == 0x00 && buf[1] == 0x00 &&
+ buf[2] == 0x00 && buf[3] == 0x28 &&
+ (buf[7] >= 0x34 && buf[7] <= 0x64) &&
+ buf[0x20] == 0x21 && (buf[0x21] == 0x54 || buf[0x21] == 0x44)
+ && buf[0x22] == 0xff && buf[0x23] == 0xff) {
+ strcpy(pre, "SA-P"); /*SonicArranger Packed */
+
+
+ } else if (buf[0] == 0x4e && buf[1] == 0xfa &&
+ buf[4] == 0x4e && buf[5] == 0xfa &&
+ buf[8] == 0x4e && buf[9] == 0xfa) {
+ t = ((buf[2] * 256) + buf[3]);
+ if (t < bufsize - 9) {
+ if (buf[2 + t] == 0x4b && buf[3 + t] == 0xfa &&
+ buf[6 + t] == 0x08 && buf[7 + t] == 0xad && buf[8 + t] == 0x00
+ && buf[9 + t] == 0x00) {
+ strcpy(pre, "MON"); /*M.O.N */
+ }
+ }
+
+ } else if (buf[0] == 0x02 && buf[1] == 0x39 &&
+ buf[2] == 0x00 && buf[3] == 0x01 &&
+ buf[8] == 0x66 && buf[9] == 0x02 &&
+ buf[10] == 0x4e && buf[11] == 0x75 &&
+ buf[12] == 0x78 && buf[13] == 0x00 &&
+ buf[14] == 0x18 && buf[15] == 0x39) {
+ strcpy(pre, "MON_old"); /*M.O.N_old */
+
+ } else if (buf[0] == 0x48 && buf[1] == 0xe7 && buf[2] == 0xf1
+ && buf[3] == 0xfe && buf[4] == 0x61 && buf[5] == 0x00) {
+ t = ((buf[6] * 256) + buf[7]);
+ if (t < (bufsize - 17)) {
+ for (i = 0; i < 10; i = i + 2) {
+ if (buf[6 + t + i] == 0x47 && buf[7 + t + i] == 0xfa) {
+ strcpy(pre, "DW"); /*Whittaker Type1... FIXME: incomplete */
+ }
+ }
+ }
+
+ } else if (buf[0] == 0x13 && buf[1] == 0xfc &&
+ buf[2] == 0x00 && buf[3] == 0x40 &&
+ buf[8] == 0x4e && buf[9] == 0x71 &&
+ buf[10] == 0x04 && buf[11] == 0x39 &&
+ buf[12] == 0x00 && buf[13] == 0x01 &&
+ buf[18] == 0x66 && buf[19] == 0xf4 &&
+ buf[20] == 0x4e && buf[21] == 0x75 &&
+ buf[22] == 0x48 && buf[23] == 0xe7 &&
+ buf[24] == 0xff && buf[25] == 0xfe) {
+ strcpy(pre, "EX"); /*Fashion Tracker */
+
+/* Magic ID */
+ } else if (buf[0x3a] == 'S' && buf[0x3b] == 'I' && buf[0x3c] == 'D' &&
+ buf[0x3d] == 'M' && buf[0x3e] == 'O' && buf[0x3f] == 'N' &&
+ buf[0x40] == ' ' && buf[0x41] == 'I' && buf[0x42] == 'I') {
+ strcpy(pre, "SID2"); /* SidMon II */
+
+ } else if (buf[0x28] == 'R' && buf[0x29] == 'O' && buf[0x2a] == 'N' &&
+ buf[0x2b] == '_' && buf[0x2c] == 'K' && buf[0x2d] == 'L' &&
+ buf[0x2e] == 'A' && buf[0x2f] == 'R' && buf[0x30] == 'E' &&
+ buf[0x31] == 'N') {
+ strcpy(pre, "CM"); /* Ron Klaren (CustomMade) */
+
+ } else if (buf[0x3e] == 'A' && buf[0x3f] == 'C' && buf[0x40] == 'T'
+ && buf[0x41] == 'I' && buf[0x42] == 'O' && buf[0x43] == 'N'
+ && buf[0x44] == 'A' && buf[0x45] == 'M') {
+ strcpy(pre, "AST"); /*Actionanamics */
+
+ } else if (buf[26] == 'V' && buf[27] == '.' && buf[28] == '2') {
+ strcpy(pre, "BP"); /* Soundmon V2 */
+
+ } else if (buf[26] == 'V' && buf[27] == '.' && buf[28] == '3') {
+ strcpy(pre, "BP3"); /* Soundmon V2.2 */
+
+ } else if (buf[60] == 'S' && buf[61] == 'O' && buf[62] == 'N'
+ && buf[63] == 'G') {
+ strcpy(pre, "SFX13"); /* Sfx 1.3-1.8 */
+
+ } else if (buf[124] == 'S' && buf[125] == 'O' && buf[126] == '3'
+ && buf[127] == '1') {
+ strcpy(pre, "SFX20"); /* Sfx 2.0 */
+
+ } else if (buf[0x1a] == 'E' && buf[0x1b] == 'X' && buf[0x1c] == 'I'
+ && buf[0x1d] == 'T') {
+ strcpy(pre, "AAM"); /*Audio Arts & Magic */
+ } else if (buf[8] == 'E' && buf[9] == 'M' && buf[10] == 'O'
+ && buf[11] == 'D' && buf[12] == 'E' && buf[13] == 'M'
+ && buf[14] == 'I' && buf[15] == 'C') {
+ strcpy(pre, "EMOD"); /* EMOD */
+
+ /* generic ID Check at offset 0x24 */
+
+ } else if (chk_id_offset(buf, bufsize, offset_0024_patterns, 0x24, pre)) {
+
+ /* HIP7 ID Check at offset 0x04 */
+ } else if (patterntest(buf, " **** Player by Jochen Hippel 1990 **** ",
+ 0x04, 40, bufsize)) {
+ strcpy(pre, "S7G"); /* HIP7 */
+
+ /* Magic ID at Offset 0x00 */
+ } else if (buf[0] == 'M' && buf[1] == 'M' && buf[2] == 'D') {
+ if (buf[0x3] >= '0' && buf[0x3] < '3') {
+ /*move.l mmd_songinfo(a0),a1 */
+ int s = (buf[8] << 24) + (buf[9] << 16) + (buf[0xa] << 8) + buf[0xb];
+ if (((int) buf[s + 767]) & (1 << 6)) { /* btst #6, msng_flags(a1); */
+ strcpy(pre, "OCTAMED");
+ /*OCTAMED*/} else {
+ strcpy(pre, "MED");
+ /*MED*/}
+ } else if (buf[0x3] != 'C') {
+ strcpy(pre, "MMD3"); /* mmd3 and above */
+ }
+
+ /* all TFMX format tests here */
+ } else if (tfmxtest(buf, bufsize, pre)) {
+ /* is TFMX, nothing to do here ('pre' set in tfmxtest() */
+
+ } else if (buf[0] == 'T' && buf[1] == 'H' && buf[2] == 'X') {
+ if ((buf[3] == 0x00) || (buf[3] == 0x01)) {
+ strcpy(pre, "AHX"); /* AHX */
+ }
+
+ } else if (buf[1] == 'M' && buf[2] == 'U' && buf[3] == 'G'
+ && buf[4] == 'I' && buf[5] == 'C' && buf[6] == 'I'
+ && buf[7] == 'A' && buf[8] == 'N') {
+ if (buf[9] == '2') {
+ strcpy(pre, "MUG2"); /* Digimugi2 */
+ } else {
+ strcpy(pre, "MUG"); /* Digimugi */
+ }
+
+ } else if (buf[0] == 'L' && buf[1] == 'M' && buf[2] == 'E' && buf[3] == 0x00) {
+ strcpy(pre, "LME"); /* LegLess */
+
+ } else if (buf[0] == 'P' && buf[1] == 'S' && buf[2] == 'A' && buf[3] == 0x00) {
+ strcpy(pre, "PSA"); /* PSA */
+
+ } else if ((buf[0] == 'S' && buf[1] == 'y' && buf[2] == 'n' && buf[3] == 't'
+ && buf[4] == 'h' && buf[6] == '.' && buf[8] == 0x00)
+ && (buf[5] > '1' && buf[5] < '4')) {
+ strcpy(pre, "SYN"); /* Synthesis */
+
+ } else if (buf[0xbc6] == '.' && buf[0xbc7] == 'F' && buf[0xbc8] == 'N'
+ && buf[0xbc9] == 'L') {
+ strcpy(pre, "DM2"); /* Delta 2.0 */
+
+ } else if (buf[0] == 'R' && buf[1] == 'J' && buf[2] == 'P') {
+
+ if (buf[4] == 'S' && buf[5] == 'M' && buf[6] == 'O' && buf[7] == 'D') {
+ strcpy(pre, "RJP"); /* Vectordean (Richard Joseph Player) */
+ } else {
+ strcpy(pre, ""); /* but don't play .ins files */
+ }
+ } else if (buf[0] == 'F' && buf[1] == 'O' && buf[2] == 'R' && buf[3] == 'M') {
+ if (buf[8] == 'S' && buf[9] == 'M' && buf[10] == 'U' && buf[11] == 'S') {
+ strcpy(pre, "SMUS"); /* Sonix */
+ }
+ // } else if (buf[0x00] == 0x00 && buf[0x01] == 0xfe &&
+ // buf[0x30] == 0x00 && buf[0x31] ==0x00 && buf[0x32] ==0x01 && buf[0x33] ==0x40 &&
+ // realfilesize > 332 ){
+ // }
+ // strcpy (pre, "SMUS"); /* Tiny Sonix*/
+
+ } else if (tronictest(buf, bufsize)) {
+ strcpy(pre, "TRONIC"); /* Tronic */
+
+ /* generic ID Check at offset 0x00 */
+ } else if (chk_id_offset(buf, bufsize, offset_0000_patterns, 0x00, pre)) {
+
+ /*magic ids of some modpackers */
+ } else if (buf[0x438] == 'P' && buf[0x439] == 'W' && buf[0x43a] == 'R'
+ && buf[0x43b] == 0x2e) {
+ strcpy(pre, "PPK"); /*Polkapacker */
+
+ } else if (buf[0x100] == 'S' && buf[0x101] == 'K' && buf[0x102] == 'Y'
+ && buf[0x103] == 'T') {
+ strcpy(pre, "SKT"); /*Skytpacker */
+
+ } else if ((buf[0x5b8] == 'I' && buf[0x5b9] == 'T' && buf[0x5ba] == '1'
+ && buf[0x5bb] == '0') || (buf[0x5b8] == 'M' && buf[0x5b9] == 'T'
+ && buf[0x5ba] == 'N'
+ && buf[0x5bb] == 0x00)) {
+ strcpy(pre, "ICE"); /*Ice/Soundtracker 2.6 */
+
+ } else if (buf[0x3b8] == 'K' && buf[0x3b9] == 'R' && buf[0x3ba] == 'I'
+ && buf[0x3bb] == 'S') {
+ strcpy(pre, "KRIS"); /*Kristracker */
+
+ } else if (buf[0] == 'X' && buf[1] == 'P' && buf[2] == 'K' && buf[3] == 'F'&&
+ read_be_u32(&buf[4]) + 8 == realfilesize &&
+ buf[8] == 'S' && buf[9] == 'Q' && buf[10] == 'S' && buf[11] == 'H') {
+ fprintf(stderr, "uade: The file is SQSH packed. Please depack first.\n");
+ strcpy(pre, "packed");
+
+ } else if ((modtype = mod15check(buf, bufsize, realfilesize, path)) != 0) {
+ for (t = 0; mod15types[t].str != NULL; t++) {
+ if (modtype == mod15types[t].e) {
+ strcpy(pre, mod15types[t].str);
+ return;
+ }
+ }
+
+ /* Custom file check */
+ } else if (buf[0] == 0x00 && buf[1] == 0x00 && buf[2] == 0x03
+ && buf[3] == 0xf3) {
+ /*CUSTOM*/ i = (buf[0x0b] * 4) + 0x1c; /* beginning of first chunk */
+
+ if (i < bufsize - 0x42) {
+
+ t = 0;
+ /* unfort. we can't always assume: moveq #-1,d0 rts before "delirium" */
+ /* search 0x40 bytes from here, (enough?) */
+ while ((buf[i + t + 0] != 'D' && buf[i + t + 1] != 'E'
+ && buf[i + t + 2] != 'L' && buf[i + t + 3] != 'I')
+ && (t < 0x40)) {
+ t++;
+ }
+
+ if (t < 0x40) {
+ /* longword after Delirium is rel. offset from first chunk
+ where "hopefully" the delitags are */
+ int s = (buf[i + t + 10] * 256) + buf[i + t + 11] + i; /* 64K */
+ if (s < bufsize - 0x33) {
+ for (i = 0; i < 0x30; i = i + 4) {
+ if (buf[i + s + 0] == 0x80 && buf[i + s + 1] == 0x00 &&
+ buf[i + s + 2] == 0x44 && buf[i + s + 3] == 0x55) {
+ strcpy(pre, "CUST"); /* CUSTOM */
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ } else if (buf[12] == 0x00) {
+ int s = (buf[12] * 256 + buf[13] + 1) * 14;
+ if (s < (bufsize - 91)) {
+ if (buf[80 + s] == 'p' && buf[81 + s] == 'a' && buf[82 + s] == 't'
+ && buf[83 + s] == 't' && buf[87 + s] == 32 && buf[88 + s] == 'p'
+ && buf[89 + s] == 'a' && buf[90 + s] == 't' && buf[91 + s] == 't') {
+ strcpy(pre, "PUMA"); /* Pumatracker */
+ }
+ }
+ }
+}
+
+
+/* We are currently stupid and check only for a few magic IDs at the offsets
+ * chk_id_offset returns 1 on success and sets the right prefix/extension
+ * in pre
+ * TODO: more and less easy check for the rest of the 52 trackerclones
+ */
+static int chk_id_offset(unsigned char *buf, int bufsize,
+ const char *patterns[], int offset, char *pre)
+{
+ int i;
+ for (i = 0; patterns[i]; i = i + 2) {
+ if (patterntest(buf, patterns[i], offset, strlen(patterns[i]), bufsize)) {
+ /* match found */
+ strcpy(pre, patterns[i + 1]);
+ return 1;
+ }
+ }
+ return 0;
+}
diff --git a/plugins/uade2/uade-2.13/src/frontends/common/amifilemagic.h b/plugins/uade2/uade-2.13/src/frontends/common/amifilemagic.h
new file mode 100644
index 00000000..45e5cd48
--- /dev/null
+++ b/plugins/uade2/uade-2.13/src/frontends/common/amifilemagic.h
@@ -0,0 +1,9 @@
+#ifndef _UADE_AMIFILEMAGIC_H_
+#define _UADE_AMIFILEMAGIC_H_
+
+#include <stdio.h>
+
+void uade_filemagic(unsigned char *buf, size_t bufsize, char *pre,
+ size_t realfilesize, const char *path, int verbose);
+
+#endif
diff --git a/plugins/uade2/uade-2.13/src/frontends/common/eagleplayer.c b/plugins/uade2/uade-2.13/src/frontends/common/eagleplayer.c
new file mode 100644
index 00000000..7c8dfce2
--- /dev/null
+++ b/plugins/uade2/uade-2.13/src/frontends/common/eagleplayer.c
@@ -0,0 +1,502 @@
+/*
+ * Loads contents of 'eagleplayer.conf'. The file formats are
+ * specified in doc/uade123.1.
+ *
+ * Copyright 2005-2007 Heikki Orsila <heikki.orsila@iki.fi>
+ *
+ * This source code module is dual licensed under GPL and Public Domain.
+ * Hence you may use _this_ module (not another code module) in any you
+ * want in your projects.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <assert.h>
+#include <stdint.h>
+
+#include <errno.h>
+#include <limits.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "eagleplayer.h"
+#include "ossupport.h"
+#include "amifilemagic.h"
+#include "uadeconf.h"
+#include "unixatomic.h"
+#include "songdb.h"
+#include "support.h"
+#include "uadestate.h"
+
+
+#define OPTION_DELIMITER ","
+
+#define MAX_SUFFIX_LENGTH 16
+
+#define eperror(fmt, args...) do { uadeerror("Eagleplayer.conf error on line %zd: " fmt, lineno, ## args); } while (0)
+
+
+/* Table for associating eagleplayer.conf, song.conf and uade.conf options
+ * together.
+ */
+const struct epconfattr epconf[] = {
+ {.s = "a500", .e = ES_A500, .o = UC_FILTER_TYPE, .c = "a500"},
+ {.s = "a1200", .e = ES_A1200, .o = UC_FILTER_TYPE, .c = "a1200"},
+ {.s = "always_ends", .e = ES_ALWAYS_ENDS, .o = UC_DISABLE_TIMEOUTS},
+ {.s = "broken_song_end", .e = ES_BROKEN_SONG_END, .o = UC_NO_EP_END},
+ {.s = "detect_format_by_content", .e = ES_CONTENT_DETECTION, .o = UC_CONTENT_DETECTION},
+ {.s = "detect_format_by_name", .e = ES_NAME_DETECTION, .o = 0},
+ {.s = "ignore_player_check",.e = ES_IGNORE_PLAYER_CHECK, .o = UC_IGNORE_PLAYER_CHECK},
+ {.s = "led_off", .e = ES_LED_OFF, .o = UC_FORCE_LED_OFF},
+ {.s = "led_on", .e = ES_LED_ON, .o = UC_FORCE_LED_ON},
+ {.s = "never_ends", .e = ES_NEVER_ENDS, .o = 0},
+ {.s = "no_ep_end_detect", .e = ES_BROKEN_SONG_END, .o = UC_NO_EP_END},
+ {.s = "no_filter", .e = ES_NO_FILTER, .o = UC_NO_FILTER},
+ {.s = "no_headphones", .e = ES_NO_HEADPHONES, .o = UC_NO_HEADPHONES},
+ {.s = "no_panning", .e = ES_NO_PANNING, .o = UC_NO_PANNING},
+ {.s = "no_postprocessing", .e = ES_NO_POSTPROCESSING, .o = UC_NO_POSTPROCESSING},
+ {.s = "ntsc", .e = ES_NTSC, .o = UC_NTSC},
+ {.s = "one_subsong", .e = ES_ONE_SUBSONG, .o = UC_ONE_SUBSONG},
+ {.s = "pal", .e = ES_PAL, .o = UC_PAL},
+ {.s = "reject", .e = ES_REJECT, .o = 0},
+ {.s = "speed_hack", .e = ES_SPEED_HACK, .o = UC_SPEED_HACK},
+ {.s = NULL}
+};
+
+
+/* Variables for eagleplayer.conf and song.conf */
+static const struct epconfattr epconf_variables[] = {
+ {.s = "epopt", .t = UA_STRING, .e = ES_EP_OPTION},
+ {.s = "gain", .t = UA_STRING, .e = ES_GAIN},
+ {.s = "interpolator", .t = UA_STRING, .e = ES_RESAMPLER},
+ {.s = "panning", .t = UA_STRING, .e = ES_PANNING},
+ {.s = "player", .t = UA_STRING, .e = ES_PLAYER},
+ {.s = "resampler", .t = UA_STRING, .e = ES_RESAMPLER},
+ {.s = "silence_timeout", .t = UA_STRING, .e = ES_SILENCE_TIMEOUT},
+ {.s = "subsong_timeout", .t = UA_STRING, .e = ES_SUBSONG_TIMEOUT},
+ {.s = "subsongs", .t = UA_STRING, .e = ES_SUBSONGS},
+ {.s = "timeout", .t = UA_STRING, .e = ES_TIMEOUT},
+ {.s = NULL}
+};
+
+
+static int ufcompare(const void *a, const void *b);
+static struct eagleplayerstore *read_eagleplayer_conf(const char *filename);
+
+
+static struct eagleplayer *get_eagleplayer(const char *extension,
+ struct eagleplayerstore *playerstore);
+
+
+static int load_playerstore(struct uade_state *state)
+{
+ static int warnings = 1;
+ char formatsfile[PATH_MAX];
+
+ if (state->playerstore == NULL) {
+ snprintf(formatsfile, sizeof(formatsfile),
+ "%s/eagleplayer.conf", state->config.basedir.name);
+
+ state->playerstore = read_eagleplayer_conf(formatsfile);
+ if (state->playerstore == NULL) {
+ if (warnings) {
+ fprintf(stderr, "Tried to load eagleplayer.conf from %s, but failed\n", formatsfile);
+ }
+ warnings = 0;
+ return 0;
+ }
+
+ if (state->config.verbose)
+ fprintf(stderr, "Loaded eagleplayer.conf: %s\n",
+ formatsfile);
+ }
+
+ return 1;
+}
+
+
+static struct eagleplayer *analyze_file_format(int *content,
+ const char *modulename,
+ struct uade_state *state)
+{
+ struct stat st;
+ char ext[MAX_SUFFIX_LENGTH];
+ FILE *f;
+ struct eagleplayer *contentcandidate = NULL;
+ struct eagleplayer *namecandidate = NULL;
+ char *prefix, *postfix, *t;
+ size_t bufsize, bytesread;
+ uint8_t buf[8192];
+
+ *content = 0;
+
+ if ((f = fopen(modulename, "rb")) == NULL)
+ return NULL;
+
+ if (fstat(fileno(f), &st))
+ uadeerror("Very weird stat error: %s (%s)\n", modulename, strerror(errno));
+
+ bufsize = sizeof buf;
+ bytesread = atomic_fread(buf, 1, bufsize, f);
+ fclose(f);
+ if (bytesread == 0)
+ return NULL;
+ memset(&buf[bytesread], 0, bufsize - bytesread);
+
+ uade_filemagic(buf, bytesread, ext, st.st_size, modulename, state->config.verbose);
+
+ if (strcmp(ext, "reject") == 0)
+ return NULL;
+
+ if (ext[0] != 0 && state->config.verbose)
+ fprintf(stderr, "Content recognized: %s (%s)\n", ext, modulename);
+
+ if (strcmp(ext, "packed") == 0)
+ return NULL;
+
+ if (!load_playerstore(state))
+ return NULL;
+
+ /* First do filename detection (we'll later do content detection) */
+ t = xbasename(modulename);
+
+ if (strlcpy((char *) buf, t, sizeof buf) >= sizeof buf)
+ return NULL;
+
+ t = strchr((char *) buf, '.');
+ if (t == NULL)
+ return NULL;
+
+ *t = 0;
+ prefix = (char *) buf;
+
+ if (strlen(prefix) < MAX_SUFFIX_LENGTH)
+ namecandidate = get_eagleplayer(prefix, state->playerstore);
+
+ if (namecandidate == NULL) {
+ /* Try postfix */
+ t = xbasename(modulename);
+ strlcpy((char *) buf, t, sizeof buf);
+ postfix = strrchr((char *) buf, '.') + 1; /* postfix != NULL */
+
+ if (strlen(postfix) < MAX_SUFFIX_LENGTH)
+ namecandidate = get_eagleplayer(postfix, state->playerstore);
+ }
+
+ /* If filemagic found a match, we'll use player plugins associated with
+ that extension */
+ if (ext[0]) {
+ contentcandidate = get_eagleplayer(ext, state->playerstore);
+ if (contentcandidate != NULL) {
+ /* Do not recognize name detectable eagleplayers by
+ content */
+ if (namecandidate == NULL ||
+ (namecandidate->flags & ES_NAME_DETECTION) == 0) {
+ *content = 1;
+ return contentcandidate;
+ }
+ } else {
+ if (state->config.verbose)
+ fprintf(stderr, "%s not in eagleplayer.conf\n", ext);
+ }
+ }
+
+ if (state->config.verbose)
+ fprintf(stderr, "Format detection by filename\n");
+
+ return namecandidate;
+}
+
+
+static void handle_attribute(struct uade_attribute **attributelist,
+ const struct epconfattr *attr,
+ char *item, size_t len, size_t lineno)
+{
+ struct uade_attribute *a;
+ char *str, *endptr;
+ int success = 0;
+
+ if (item[len] != '=') {
+ fprintf(stderr, "Invalid song item: %s\n", item);
+ return;
+ }
+ str = item + len + 1;
+
+ if ((a = calloc(1, sizeof *a)) == NULL)
+ eperror("No memory for song attribute.\n");
+
+ switch (attr->t) {
+ case UA_DOUBLE:
+ a->d = strtod(str, &endptr);
+ if (*endptr == 0)
+ success = 1;
+ break;
+ case UA_INT:
+ a->i = strtol(str, &endptr, 10);
+ if (*endptr == 0)
+ success = 1;
+ break;
+ case UA_STRING:
+ a->s = strdup(str);
+ if (a->s == NULL)
+ eperror("Out of memory allocating string option for song\n");
+ success = 1;
+ break;
+ default:
+ fprintf(stderr, "Unknown song option: %s\n",
+ item);
+ break;
+ }
+
+ if (success) {
+ a->type = attr->e;
+ a->next = *attributelist;
+ *attributelist = a;
+ } else {
+ fprintf(stderr, "Invalid song option: %s\n", item);
+ free(a);
+ }
+}
+
+
+int uade_song_and_player_attribute(struct uade_attribute **attributelist,
+ int *flags, char *item, size_t lineno)
+{
+ size_t i, len;
+
+ for (i = 0; epconf[i].s != NULL; i++) {
+ if (strcasecmp(item, epconf[i].s) == 0) {
+ *flags |= epconf[i].e;
+ return 1;
+ }
+ }
+
+ for (i = 0; epconf_variables[i].s != NULL; i++) {
+ len = strlen(epconf_variables[i].s);
+ if (strncasecmp(item, epconf_variables[i].s, len) != 0)
+ continue;
+
+ handle_attribute(attributelist, &epconf_variables[i],
+ item, len, lineno);
+ return 1;
+ }
+
+ return 0;
+}
+
+/* Compare function for bsearch() and qsort() to sort eagleplayers with
+ respect to name extension. */
+static int ufcompare(const void *a, const void *b)
+{
+ const struct eagleplayermap *ua = a;
+ const struct eagleplayermap *ub = b;
+
+ return strcasecmp(ua->extension, ub->extension);
+}
+
+int uade_is_our_file(const char *modulename, int scanmode,
+ struct uade_state *state)
+{
+ int content;
+ struct eagleplayer *ep;
+
+ ep = analyze_file_format(&content, modulename, state);
+
+ if (!scanmode)
+ state->ep = ep;
+
+ if (ep == NULL)
+ return 0;
+
+ if (content)
+ return 1;
+
+ if (state->config.content_detection && content == 0)
+ return 0;
+
+ if ((ep->flags & ES_CONTENT_DETECTION) != 0)
+ return 0;
+
+ return 1;
+}
+
+static struct eagleplayer *get_eagleplayer(const char *extension,
+ struct eagleplayerstore *ps)
+{
+ struct eagleplayermap *uf = ps->map;
+ struct eagleplayermap *f;
+ struct eagleplayermap key = {.extension = (char *)extension };
+
+ f = bsearch(&key, uf, ps->nextensions, sizeof(uf[0]), ufcompare);
+ if (f == NULL)
+ return NULL;
+
+ return f->player;
+}
+
+/* Read eagleplayer.conf. */
+static struct eagleplayerstore *read_eagleplayer_conf(const char *filename)
+{
+ FILE *f;
+ struct eagleplayer *p;
+ size_t allocated;
+ size_t lineno = 0;
+ struct eagleplayerstore *ps = NULL;
+ size_t exti;
+ size_t i, j;
+ int epwarning;
+
+ f = fopen(filename, "r");
+ if (f == NULL)
+ goto error;
+
+ ps = calloc(1, sizeof ps[0]);
+ if (ps == NULL)
+ eperror("No memory for ps.");
+
+ allocated = 16;
+ if ((ps->players = malloc(allocated * sizeof(ps->players[0]))) == NULL)
+ eperror("No memory for eagleplayer.conf file.\n");
+
+ while (1) {
+ char **items;
+ size_t nitems;
+
+ items = read_and_split_lines(&nitems, &lineno, f, UADE_WS_DELIMITERS);
+ if (items == NULL)
+ break;
+
+ assert(nitems > 0);
+
+ if (ps->nplayers == allocated) {
+ allocated *= 2;
+ ps->players = realloc(ps->players, allocated * sizeof(ps->players[0]));
+ if (ps->players == NULL)
+ eperror("No memory for players.");
+ }
+
+ p = &ps->players[ps->nplayers];
+ ps->nplayers++;
+
+ memset(p, 0, sizeof p[0]);
+
+ p->playername = strdup(items[0]);
+ if (p->playername == NULL)
+ uadeerror("No memory for playername.\n");
+
+ for (i = 1; i < nitems; i++) {
+
+ if (strncasecmp(items[i], "prefixes=", 9) == 0) {
+ char prefixes[UADE_LINESIZE];
+ char *prefixstart = items[i] + 9;
+ char *sp, *s;
+ size_t pos;
+
+ assert(p->nextensions == 0 && p->extensions == NULL);
+
+ p->nextensions = 0;
+ strlcpy(prefixes, prefixstart,
+ sizeof(prefixes));
+ sp = prefixes;
+ while ((s = strsep(&sp, OPTION_DELIMITER)) != NULL) {
+ if (*s == 0)
+ continue;
+ p->nextensions++;
+ }
+
+ p->extensions =
+ malloc((p->nextensions +
+ 1) * sizeof(p->extensions[0]));
+ if (p->extensions == NULL)
+ eperror("No memory for extensions.");
+
+ pos = 0;
+ sp = prefixstart;
+ while ((s = strsep(&sp, OPTION_DELIMITER)) != NULL) {
+ if (*s == 0)
+ continue;
+
+ p->extensions[pos] = strdup(s);
+ if (s == NULL)
+ eperror("No memory for prefix.");
+ pos++;
+ }
+ p->extensions[pos] = NULL;
+ assert(pos == p->nextensions);
+
+ continue;
+ }
+
+ if (strncasecmp(items[i], "comment:", 7) == 0)
+ break;
+
+ if (uade_song_and_player_attribute(&p->attributelist, &p->flags, items[i], lineno))
+ continue;
+
+ fprintf(stderr, "Unrecognized option: %s\n", items[i]);
+ }
+
+ for (i = 0; items[i] != NULL; i++)
+ free(items[i]);
+
+ free(items);
+ }
+
+ fclose(f);
+
+ if (ps->nplayers == 0) {
+ free(ps->players);
+ free(ps);
+ return NULL;
+ }
+
+ for (i = 0; i < ps->nplayers; i++)
+ ps->nextensions += ps->players[i].nextensions;
+
+ ps->map = malloc(sizeof(ps->map[0]) * ps->nextensions);
+ if (ps->map == NULL)
+ eperror("No memory for extension map.");
+
+ exti = 0;
+ epwarning = 0;
+ for (i = 0; i < ps->nplayers; i++) {
+ p = &ps->players[i];
+ if (p->nextensions == 0) {
+ if (epwarning == 0) {
+ fprintf(stderr,
+ "uade warning: %s eagleplayer lacks prefixes in "
+ "eagleplayer.conf, which makes it unusable for any kind of "
+ "file type detection. If you don't want name based file type "
+ "detection for a particular format, use content_detection "
+ "option for the line in eagleplayer.conf.\n",
+ ps->players[i].playername);
+ epwarning = 1;
+ }
+ continue;
+ }
+ for (j = 0; j < p->nextensions; j++) {
+ assert(exti < ps->nextensions);
+ ps->map[exti].player = p;
+ ps->map[exti].extension = p->extensions[j];
+ exti++;
+ }
+ }
+
+ assert(exti == ps->nextensions);
+
+ /* Make the extension map bsearch() ready */
+ qsort(ps->map, ps->nextensions, sizeof(ps->map[0]), ufcompare);
+
+ return ps;
+
+ error:
+ if (ps)
+ free(ps->players);
+ free(ps);
+ if (f != NULL)
+ fclose(f);
+ return NULL;
+}
diff --git a/plugins/uade2/uade-2.13/src/frontends/common/eagleplayer.h b/plugins/uade2/uade-2.13/src/frontends/common/eagleplayer.h
new file mode 100644
index 00000000..fc3497b5
--- /dev/null
+++ b/plugins/uade2/uade-2.13/src/frontends/common/eagleplayer.h
@@ -0,0 +1,127 @@
+#ifndef _UADE_EAGLEPLAYER_H_
+#define _UADE_EAGLEPLAYER_H_
+
+#include <stdio.h>
+#include <stdint.h>
+#include <limits.h>
+
+#include "uadeconfstructure.h"
+
+/* We maintain alphabetical order even if that forces us to renumber bits
+ when a new option is added */
+#define ES_A1200 (1 << 0)
+#define ES_A500 (1 << 1)
+#define ES_ALWAYS_ENDS (1 << 2)
+#define ES_BROKEN_SONG_END (1 << 3)
+#define ES_CONTENT_DETECTION (1 << 4)
+#define ES_EP_OPTION (1 << 5)
+#define ES_GAIN (1 << 6)
+#define ES_IGNORE_PLAYER_CHECK (1 << 7)
+#define ES_LED_OFF (1 << 8)
+#define ES_LED_ON (1 << 9)
+#define ES_NAME_DETECTION (1 << 10)
+#define ES_NEVER_ENDS (1 << 11)
+#define ES_NO_FILTER (1 << 12)
+#define ES_NO_HEADPHONES (1 << 13)
+#define ES_NO_PANNING (1 << 14)
+#define ES_NO_POSTPROCESSING (1 << 15)
+#define ES_NTSC (1 << 16)
+#define ES_ONE_SUBSONG (1 << 17)
+#define ES_PAL (1 << 18)
+#define ES_PANNING (1 << 19)
+#define ES_PLAYER (1 << 20)
+#define ES_REJECT (1 << 21)
+#define ES_RESAMPLER (1 << 22)
+#define ES_SILENCE_TIMEOUT (1 << 23)
+#define ES_SPEED_HACK (1 << 24)
+#define ES_SUBSONGS (1 << 25)
+#define ES_SUBSONG_TIMEOUT (1 << 26)
+#define ES_TIMEOUT (1 << 27)
+
+#define UADE_WS_DELIMITERS " \t\n"
+
+struct eagleplayer {
+ char *playername;
+ size_t nextensions;
+ char **extensions;
+ int flags;
+ struct uade_attribute *attributelist;
+};
+
+struct eagleplayermap {
+ char *extension;
+ struct eagleplayer *player;
+};
+
+struct eagleplayerstore {
+ size_t nplayers;
+ struct eagleplayer *players;
+ size_t nextensions;
+ struct eagleplayermap *map;
+};
+
+enum uade_attribute_type {
+ UA_STRING = 1,
+ UA_INT,
+ UA_DOUBLE
+};
+
+struct uade_attribute;
+
+struct uade_attribute {
+ struct uade_attribute *next;
+ enum uade_attribute_type type;
+ char *s;
+ int i;
+ double d;
+};
+
+struct uade_song {
+ char md5[33];
+
+ char module_filename[PATH_MAX];
+
+ char playername[256]; /* Eagleplayer name in players directory */
+ char modulename[256]; /* From score */
+ char formatname[256];
+
+ uint8_t *buf;
+ size_t bufsize;
+
+ int min_subsong;
+ int max_subsong;
+ int cur_subsong;
+
+ int playtime;
+ int flags;
+ int nsubsongs;
+ uint8_t *subsongs;
+ struct uade_attribute *songattributes;
+ struct uade_ep_options ep_options;
+ char *normalisation;
+
+ int64_t out_bytes;
+
+ int64_t silence_count;
+};
+
+struct epconfattr {
+ char *s; /* config file directive/variable name */
+ int e; /* ES_* flags for eagleplayers and songs */
+ int o; /* UC_* flag for uade.conf option */
+ char *c; /* constant for an UC_* flag */
+ enum uade_attribute_type t; /* if variable, its special type */
+};
+
+
+extern const struct epconfattr epconf[];
+
+
+/* FIX: A forward declaration to avoid circular dependency */
+struct uade_state;
+
+int uade_is_our_file(const char *modulename, int scanmode, struct uade_state *state);
+int uade_song_and_player_attribute(struct uade_attribute **attributelist,
+ int *flags, char *item, size_t lineno);
+
+#endif
diff --git a/plugins/uade2/uade-2.13/src/frontends/common/effects.c b/plugins/uade2/uade-2.13/src/frontends/common/effects.c
new file mode 100644
index 00000000..c75c859d
--- /dev/null
+++ b/plugins/uade2/uade-2.13/src/frontends/common/effects.c
@@ -0,0 +1,490 @@
+/* Effect module for UADE2 frontends.
+
+ Copyright 2005 (C) Antti S. Lankila <alankila@bel.fi>
+
+ This module is licensed under the GNU LGPL.
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+#include <string.h>
+#include <math.h>
+
+#include <compilersupport.h>
+
+#include "effects.h"
+
+/*** old headphone effect ***/
+#define UADE_EFFECT_HEADPHONES_DELAY_LENGTH 22
+#define UADE_EFFECT_HEADPHONES_DELAY_DIRECT 0.3
+#define UADE_EFFECT_HEADPHONES_CROSSMIX_VOL 0.80
+
+static float headphones_ap_l[UADE_EFFECT_HEADPHONES_DELAY_LENGTH];
+static float headphones_ap_r[UADE_EFFECT_HEADPHONES_DELAY_LENGTH];
+static float headphones_rc_l[4];
+static float headphones_rc_r[4];
+
+/*** new headphone effect ***/
+
+/* delay time defines the width of the head. 0.5 ms gives us 15 cm virtual distance
+ * between sound arriving to either ear. */
+#define HEADPHONE2_DELAY_TIME 0.49e-3
+#define HEADPHONE2_DELAY_K 0.15
+/* head shadow frequency cutoff */
+#define HEADPHONE2_SHADOW_FREQ 8000.0
+/* high shelve keeps frequencies below cutoff intact and attenuates
+ * the rest in an uniform way. The effect is to make bass more "mono" than "stereo". */
+#define HEADPHONE2_SHELVE_FREQ 100.0
+#define HEADPHONE2_SHELVE_LEVEL -2.0
+
+#define MAXIMUM_SAMPLING_RATE 96000
+#define HEADPHONE2_DELAY_MAX_LENGTH ((int)(MAXIMUM_SAMPLING_RATE*HEADPHONE2_DELAY_TIME+1))
+#define DENORMAL_OFFSET 1E-10
+
+#define NORMALISE_RESOLUTION 10 /* in bits */
+#define NORMALISE_DEFAULT_GAIN 8.0
+#define NORMALISE_MAXIMUM_GAIN 8.0
+
+/* Headphone variables */
+typedef struct {
+ float b0, b1, b2, a1, a2, x[2], y[2];
+} biquad_t;
+
+static float headphone2_ap_l[HEADPHONE2_DELAY_MAX_LENGTH];
+static float headphone2_ap_r[HEADPHONE2_DELAY_MAX_LENGTH];
+static int headphone2_delay_length;
+static biquad_t headphone2_shelve_l;
+static biquad_t headphone2_shelve_r;
+static biquad_t headphone2_rc_l;
+static biquad_t headphone2_rc_r;
+
+/* Normalise variables */
+static int normalise_peak_level;
+static int normalise_historic_maximum_peak;
+static int normalise_oldlevel;
+
+static void gain(int gain_amount, int16_t * sm, int frames);
+static void pan(int pan_amount, int16_t * sm, int frames);
+static void headphones(int16_t * sm, int frames);
+static void headphones2(int16_t * sm, int frames);
+static void normalise(int change_level, int16_t * sm, int frames);
+static int normalise_compute_gain(int peak);
+
+static inline int sampleclip(int x)
+{
+ if (unlikely(x > 32767 || x < -32768)) {
+ if (x > 32767)
+ x = 32767;
+ else
+ x = -32768;
+ }
+ return x;
+}
+
+/* calculate a high shelve filter */
+static void calculate_shelve(double fs, double fc, double g, biquad_t * bq)
+{
+ float A, omega, sn, cs, beta, b0, b1, b2, a0, a1, a2;
+
+ A = powf(10, g / 40);
+ omega = 2 * M_PI * fc / fs;
+ omega = tan(omega / 2) * 2;
+ sn = sin(omega);
+ cs = cos(omega);
+ beta = sqrt(A + A);
+
+ b0 = A * ((A + 1) + (A - 1) * cs + beta * sn);
+ b1 = -2 * A * ((A - 1) + (A + 1) * cs);
+ b2 = A * ((A + 1) + (A - 1) * cs - beta * sn);
+ a0 = (A + 1) - (A - 1) * cs + beta * sn;
+ a1 = 2 * ((A - 1) - (A + 1) * cs);
+ a2 = (A + 1) - (A - 1) * cs - beta * sn;
+
+ bq->b0 = b0 / a0;
+ bq->b1 = b1 / a0;
+ bq->b2 = b2 / a0;
+ bq->a1 = a1 / a0;
+ bq->a2 = a2 / a0;
+}
+
+/* calculate 1st order lowpass filter */
+static void calculate_rc(double fs, double fc, biquad_t * bq)
+{
+ float omega;
+
+ if (fc >= fs / 2) {
+ bq->b0 = 1.0;
+ bq->b1 = 0.0;
+ bq->b2 = 0.0;
+ bq->a1 = 0.0;
+ bq->a2 = 0.0;
+ return;
+ }
+ omega = 2 * M_PI * fc / fs;
+ omega = tan(omega / 2) * 2;
+
+ bq->b0 = 1 / (1 + 1 / omega);
+ bq->b1 = 0;
+ bq->b2 = 0;
+ bq->a1 = -1 + bq->b0;
+ bq->a2 = 0;
+}
+
+static inline float evaluate_biquad(float input, biquad_t * bq)
+{
+ float output = DENORMAL_OFFSET;
+
+ output += input * bq->b0 + bq->x[0] * bq->b1 + bq->x[1] * bq->b2;
+ output -= bq->y[0] * bq->a1 + bq->y[1] * bq->a2;
+
+ bq->x[1] = bq->x[0];
+ bq->x[0] = input;
+
+ bq->y[1] = bq->y[0];
+ bq->y[0] = output;
+
+ return output;
+}
+
+static void reset_biquad(biquad_t * bq)
+{
+ bq->x[0] = bq->x[1] = bq->y[0] = bq->y[1] = 0;
+}
+
+/* Reset effects' state variables.
+ * Call this method between before starting playback */
+void uade_effect_reset_internals(void)
+{
+ /* old headphones */
+ memset(headphones_ap_l, 0, sizeof(headphones_ap_l));
+ memset(headphones_ap_r, 0, sizeof(headphones_ap_r));
+ memset(headphones_rc_l, 0, sizeof(headphones_rc_l));
+ memset(headphones_rc_r, 0, sizeof(headphones_rc_r));
+
+ /* new headphones */
+ memset(headphone2_ap_l, 0, sizeof(headphone2_ap_l));
+ memset(headphone2_ap_r, 0, sizeof(headphone2_ap_r));
+ reset_biquad(&headphone2_shelve_l);
+ reset_biquad(&headphone2_shelve_r);
+ reset_biquad(&headphone2_rc_l);
+ reset_biquad(&headphone2_rc_r);
+
+ normalise_peak_level = 0;
+ normalise_historic_maximum_peak = 0;
+ normalise_oldlevel = 1 << NORMALISE_RESOLUTION;
+}
+
+void uade_effect_disable_all(struct uade_effect *ue)
+{
+ ue->enabled = 0;
+}
+
+void uade_effect_disable(struct uade_effect *ue, uade_effect_t effect)
+{
+ ue->enabled &= ~(1 << effect);
+}
+
+void uade_effect_enable(struct uade_effect *ue, uade_effect_t effect)
+{
+ ue->enabled |= 1 << effect;
+}
+
+/* Returns 1 if effect is enabled, and zero otherwise. Ignores
+ UADE_EFFECT_ALLOW. */
+int uade_effect_is_enabled(struct uade_effect *ue, uade_effect_t effect)
+{
+ return (ue->enabled & (1 << effect)) != 0;
+}
+
+void uade_effect_run(struct uade_effect *ue, int16_t * samples, int frames)
+{
+ if (ue->enabled & (1 << UADE_EFFECT_ALLOW)) {
+ normalise(ue->enabled & (1 << UADE_EFFECT_NORMALISE), samples,
+ frames);
+ if (ue->enabled & (1 << UADE_EFFECT_PAN))
+ pan(ue->pan, samples, frames);
+ if (ue->enabled & (1 << UADE_EFFECT_HEADPHONES))
+ headphones(samples, frames);
+ if (ue->enabled & (1 << UADE_EFFECT_HEADPHONES2) && ue->rate)
+ headphones2(samples, frames);
+ if (ue->enabled & (1 << UADE_EFFECT_GAIN))
+ gain(ue->gain, samples, frames);
+ }
+}
+
+void uade_effect_toggle(struct uade_effect *ue, uade_effect_t effect)
+{
+ ue->enabled ^= 1 << effect;
+}
+
+void uade_effect_set_defaults(struct uade_effect *ue)
+{
+ memset(ue, 0, sizeof(*ue));
+ uade_effect_disable_all(ue);
+ uade_effect_enable(ue, UADE_EFFECT_ALLOW);
+ uade_effect_gain_set_amount(ue, 1.0);
+ uade_effect_pan_set_amount(ue, 0.7);
+}
+
+/* Rate of 0 means undefined. Effects that depend on sample rate must
+ self-check against this because they can not implemented properly */
+void uade_effect_set_sample_rate(struct uade_effect *ue, int rate)
+{
+ assert(rate >= 0);
+ ue->rate = rate;
+
+ if (rate == 0)
+ return;
+
+ calculate_shelve(rate, HEADPHONE2_SHELVE_FREQ, HEADPHONE2_SHELVE_LEVEL,
+ &headphone2_shelve_l);
+ calculate_shelve(rate, HEADPHONE2_SHELVE_FREQ, HEADPHONE2_SHELVE_LEVEL,
+ &headphone2_shelve_r);
+ calculate_rc(rate, HEADPHONE2_SHADOW_FREQ, &headphone2_rc_l);
+ calculate_rc(rate, HEADPHONE2_SHADOW_FREQ, &headphone2_rc_r);
+ headphone2_delay_length = HEADPHONE2_DELAY_TIME * rate + 0.5;
+ if (headphone2_delay_length > HEADPHONE2_DELAY_MAX_LENGTH) {
+ fprintf(stderr, "effects.c: truncating headphone delay line due to samplerate exceeding 96 kHz.\n");
+ headphone2_delay_length = HEADPHONE2_DELAY_MAX_LENGTH;
+ }
+}
+
+void uade_effect_gain_set_amount(struct uade_effect *ue, float amount)
+{
+ assert(amount >= 0.0 && amount <= 128.0);
+ ue->gain = amount * 256.0;
+}
+
+void uade_effect_pan_set_amount(struct uade_effect *ue, float amount)
+{
+ assert(amount >= 0.0 && amount <= 2.0);
+ ue->pan = amount * 256.0 / 2.0;
+}
+
+static int normalise_compute_gain(int peak)
+{
+ if (normalise_historic_maximum_peak == 0) {
+ /* if the peak is not known, we cap gain in an attempt to avoid
+ * boosting silent intros too much. */
+ if (peak < 32768 / NORMALISE_DEFAULT_GAIN)
+ return NORMALISE_DEFAULT_GAIN *
+ (1 << NORMALISE_RESOLUTION);
+ else
+ return (32768 << NORMALISE_RESOLUTION) / peak;
+ } else {
+ int largerpeak;
+ if (peak < normalise_historic_maximum_peak)
+ largerpeak = normalise_historic_maximum_peak;
+ else
+ largerpeak = peak;
+ /* if the peak is known, we use the recorded value but adapt
+ if this rendition comes out louder for some reason (for
+ instance, updated UADE) */
+ if (largerpeak < 32768 / NORMALISE_MAXIMUM_GAIN)
+ return NORMALISE_MAXIMUM_GAIN *
+ (1 << NORMALISE_RESOLUTION);
+ else
+ return (32768 << NORMALISE_RESOLUTION) / largerpeak;
+ }
+}
+
+/* We save gain from maximum known level. This is an one-way street,
+ the gain can * only decrease with time. If the historic level is
+ known and larger, we prefer it. */
+void uade_effect_normalise_serialise(char *buf, size_t len)
+{
+ int peak = normalise_peak_level;
+
+ assert(len > 0);
+
+ if (normalise_historic_maximum_peak > normalise_peak_level)
+ peak = normalise_historic_maximum_peak;
+
+ if (snprintf(buf, len, "v=1,p=%d", peak) >= len) {
+ fprintf(stderr, "normalise effect: buffer too short, gain would be truncated. This is a bug in UADE.\n");
+ exit(-1);
+ }
+}
+
+/* similarly, this should only be called if gain has a positive value,
+ * but we try to recover from misuse. */
+void uade_effect_normalise_unserialise(const char *buf)
+{
+ int version, readcount;
+ float peak;
+
+ normalise_historic_maximum_peak = 0;
+
+ if (buf == NULL)
+ return;
+
+ readcount = sscanf(buf, "v=%d,p=%f", &version, &peak);
+
+ if (readcount == 0) {
+ fprintf(stderr, "normalise effect: gain string invalid: '%s'\n", buf);
+ exit(-1);
+ }
+
+ if (version != 1) {
+ fprintf(stderr, "normalise effect: unrecognized gain version: '%s'\n", buf);
+ exit(-1);
+ }
+
+ if (readcount != 2) {
+ fprintf(stderr, "Could not read peak value for version 1: '%s'\n", buf);
+ exit(-1);
+ }
+
+ if (peak >= 0.0 && peak <= 1.0) {
+ normalise_oldlevel = normalise_historic_maximum_peak =
+ 32768 * peak;
+ } else {
+ fprintf(stderr, "normalise effect: invalid peak level: '%s'\n", buf);
+ }
+}
+
+static void normalise(int change_level, int16_t * sm, int frames)
+{
+ int i;
+
+ /* Negative side is mirrored. but positive side gains by 1.
+ * This is to make both semiwaves have same max. */
+ for (i = 0; i < 2 * frames; i += 1) {
+ int tmp = sm[i];
+ tmp = (tmp >= 0) ? tmp + 1 : -tmp;
+ if (tmp > normalise_peak_level)
+ normalise_peak_level = tmp;
+ }
+
+ /* Slight clipping may result in first playback while the system
+ * adjusts. With a bit of "advance warning" of clipping about to
+ * occur, the level begins to adjust as soon as the buffer
+ * begins. Typical adjustment times are not large -- a few hundred
+ * samples are to be expected -- and the clipping should only
+ * occur on the first rendition of the song, if at all. */
+ if (change_level) {
+ int newlevel = normalise_compute_gain(normalise_peak_level);
+
+ for (i = 0; i < 2 * frames; i += 1) {
+ /* same gain for the frame */
+ if ((i & 1) == 0) {
+ if (normalise_oldlevel < newlevel)
+ normalise_oldlevel += 1;
+ if (normalise_oldlevel > newlevel)
+ normalise_oldlevel -= 1;
+ }
+ sm[i] =
+ sampleclip((sm[i] *
+ normalise_oldlevel) >>
+ NORMALISE_RESOLUTION);
+ }
+ }
+}
+
+static void gain(int gain_amount, int16_t * sm, int frames)
+{
+ int i;
+ for (i = 0; i < 2 * frames; i += 1)
+ sm[i] = sampleclip((sm[i] * gain_amount) >> 8);
+}
+
+/* Panning effect. Turns stereo into mono in a specific degree */
+static void pan(int pan_amount, int16_t * sm, int frames)
+{
+ int i, l, r, m;
+ for (i = 0; i < frames; i += 1) {
+ l = sm[0];
+ r = sm[1];
+ m = (r - l) * pan_amount;
+ sm[0] = ((l << 8) + m) >> 8;
+ sm[1] = ((r << 8) - m) >> 8;
+ sm += 2;
+ }
+}
+
+/* All-pass delay. Its purpose is to confuse the phase of the sound a bit
+ * and also provide some delay to locate the source outside the head. This
+ * seems to work better than a pure delay line. */
+static float headphones_allpass_delay(float in, float *state)
+{
+ int i;
+ float tmp, output;
+
+ tmp = in - UADE_EFFECT_HEADPHONES_DELAY_DIRECT * state[0];
+ output = state[0] + UADE_EFFECT_HEADPHONES_DELAY_DIRECT * tmp;
+
+ /* FIXME: use modulo and index */
+ for (i = 1; i < UADE_EFFECT_HEADPHONES_DELAY_LENGTH; i += 1)
+ state[i - 1] = state[i];
+ state[UADE_EFFECT_HEADPHONES_DELAY_LENGTH - 1] = tmp;
+
+ return output;
+}
+
+static float headphones_lpf(float in, float *state)
+{
+ float out = in * 0.53;
+ out += 0.47 * state[0];
+ state[0] = out;
+
+ return out;
+}
+
+/* A real implementation would simply perform FIR with recorded HRTF data. */
+static void headphones(int16_t * sm, int frames)
+{
+ int i;
+ float ld, rd;
+ int l_final, r_final;
+ for (i = 0; i < frames; i += 1) {
+ ld = headphones_allpass_delay(sm[0], headphones_ap_l);
+ rd = headphones_allpass_delay(sm[1], headphones_ap_r);
+ ld = headphones_lpf(ld, headphones_rc_l);
+ rd = headphones_lpf(rd, headphones_rc_r);
+
+ l_final =
+ (sm[0] + rd * UADE_EFFECT_HEADPHONES_CROSSMIX_VOL) / 2;
+ r_final =
+ (sm[1] + ld * UADE_EFFECT_HEADPHONES_CROSSMIX_VOL) / 2;
+ sm[0] = sampleclip(l_final);
+ sm[1] = sampleclip(r_final);
+
+ sm += 2;
+ }
+}
+
+static float headphone2_allpass_delay(float in, float *state)
+{
+ int i;
+ float tmp, output;
+
+ tmp = in - HEADPHONE2_DELAY_K * state[0];
+ output = state[0] + HEADPHONE2_DELAY_K * tmp;
+
+ /* FIXME: use modulo and index */
+ for (i = 1; i < headphone2_delay_length; i += 1)
+ state[i - 1] = state[i];
+ state[headphone2_delay_length - 1] = tmp;
+
+ return output;
+}
+
+static void headphones2(int16_t * sm, int frames)
+{
+ int i;
+ for (i = 0; i < frames; i += 1) {
+ float ld, rd;
+
+ ld = headphone2_allpass_delay(sm[0], headphone2_ap_l);
+ rd = headphone2_allpass_delay(sm[1], headphone2_ap_r);
+ ld = evaluate_biquad(ld, &headphone2_rc_l);
+ rd = evaluate_biquad(rd, &headphone2_rc_r);
+ ld = evaluate_biquad(ld, &headphone2_shelve_l);
+ rd = evaluate_biquad(rd, &headphone2_shelve_r);
+
+ sm[0] = sampleclip((sm[0] + rd) / 2);
+ sm[1] = sampleclip((sm[1] + ld) / 2);
+ sm += 2;
+ }
+}
diff --git a/plugins/uade2/uade-2.13/src/frontends/common/effects.h b/plugins/uade2/uade-2.13/src/frontends/common/effects.h
new file mode 100644
index 00000000..57a779df
--- /dev/null
+++ b/plugins/uade2/uade-2.13/src/frontends/common/effects.h
@@ -0,0 +1,42 @@
+#ifndef _UADE2_EFFECTS_H_
+#define _UADE2_EFFECTS_H_
+
+#include <stdint.h>
+
+typedef enum {
+ UADE_EFFECT_ALLOW,
+ UADE_EFFECT_GAIN,
+ UADE_EFFECT_HEADPHONES,
+ UADE_EFFECT_HEADPHONES2,
+ UADE_EFFECT_PAN,
+ UADE_EFFECT_NORMALISE,
+} uade_effect_t;
+
+struct uade_effect {
+ uade_effect_t enabled;
+ int gain;
+ int pan;
+ int rate;
+};
+
+void uade_effect_disable(struct uade_effect *ue, uade_effect_t effect);
+void uade_effect_disable_all(struct uade_effect *ue);
+void uade_effect_enable(struct uade_effect *ue, uade_effect_t effect);
+int uade_effect_is_enabled(struct uade_effect *ue, uade_effect_t effect);
+void uade_effect_set_defaults(struct uade_effect *ue);
+void uade_effect_set_sample_rate(struct uade_effect *ue, int rate);
+void uade_effect_toggle(struct uade_effect *ue, uade_effect_t effect);
+
+/* effect-specific knobs */
+void uade_effect_gain_set_amount(struct uade_effect *ue, float amount);
+void uade_effect_normalise_unserialise(const char *buf);
+void uade_effect_normalise_serialise(char *buf, size_t len);
+void uade_effect_pan_set_amount(struct uade_effect *ue, float amount);
+
+/* reset state at start of song */
+void uade_effect_reset_internals(void);
+
+/* process n frames of sample buffer */
+void uade_effect_run(struct uade_effect *ue, int16_t * sample, int frames);
+
+#endif
diff --git a/plugins/uade2/uade-2.13/src/frontends/common/md5.c b/plugins/uade2/uade-2.13/src/frontends/common/md5.c
new file mode 100644
index 00000000..7614ea48
--- /dev/null
+++ b/plugins/uade2/uade-2.13/src/frontends/common/md5.c
@@ -0,0 +1,247 @@
+/*
+ * This code implements the MD5 message-digest algorithm.
+ * The algorithm is due to Ron Rivest. This code was
+ * written by Colin Plumb in 1993, no copyright is claimed.
+ * This code is in the public domain; do with it what you wish.
+ *
+ * Equivalent code is available from RSA Data Security, Inc.
+ * This code has been tested against that, and is equivalent,
+ * except that you don't need to include two pages of legalese
+ * with every copy.
+ *
+ * To compute the message digest of a chunk of bytes, declare an
+ * MD5Context structure, pass it to MD5Init, call MD5Update as
+ * needed on buffers full of bytes, and then call MD5Final, which
+ * will fill a supplied 16-byte array with the digest.
+ */
+
+#include <string.h> /* for memcpy() */
+#include "md5.h"
+
+#if __BYTE_ORDER == 1234
+#define byteReverse(buf, len) /* Nothing */
+#else
+static void byteReverse(unsigned char *buf, unsigned longs);
+
+/*
+ * Note: this code is harmless on little-endian machines.
+ */
+static void byteReverse(unsigned char *buf, unsigned longs)
+{
+ uint32_t t;
+ do {
+ t = (uint32_t) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
+ ((unsigned) buf[1] << 8 | buf[0]);
+ *(uint32_t *) buf = t;
+ buf += 4;
+ } while (--longs);
+}
+#endif
+
+/*
+ * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
+ * initialization constants.
+ */
+void MD5Init(MD5_CTX *ctx)
+{
+ ctx->buf[0] = 0x67452301;
+ ctx->buf[1] = 0xefcdab89;
+ ctx->buf[2] = 0x98badcfe;
+ ctx->buf[3] = 0x10325476;
+
+ ctx->bits[0] = 0;
+ ctx->bits[1] = 0;
+}
+
+/*
+ * Update context to reflect the concatenation of another buffer full
+ * of bytes.
+ */
+void MD5Update(MD5_CTX *ctx, unsigned char const *buf, unsigned len)
+{
+ uint32_t t;
+
+ /* Update bitcount */
+
+ t = ctx->bits[0];
+ if ((ctx->bits[0] = t + ((uint32_t) len << 3)) < t)
+ ctx->bits[1]++; /* Carry from low to high */
+ ctx->bits[1] += len >> 29;
+
+ t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */
+
+ /* Handle any leading odd-sized chunks */
+
+ if (t) {
+ unsigned char *p = (unsigned char *) ctx->in + t;
+
+ t = 64 - t;
+ if (len < t) {
+ memcpy(p, buf, len);
+ return;
+ }
+ memcpy(p, buf, t);
+ byteReverse(ctx->in, 16);
+ MD5Transform(ctx->buf, (uint32_t *) ctx->in);
+ buf += t;
+ len -= t;
+ }
+ /* Process data in 64-byte chunks */
+
+ while (len >= 64) {
+ memcpy(ctx->in, buf, 64);
+ byteReverse(ctx->in, 16);
+ MD5Transform(ctx->buf, (uint32_t *) ctx->in);
+ buf += 64;
+ len -= 64;
+ }
+
+ /* Handle any remaining bytes of data. */
+
+ memcpy(ctx->in, buf, len);
+}
+
+/*
+ * Final wrapup - pad to 64-byte boundary with the bit pattern
+ * 1 0* (64-bit count of bits processed, MSB-first)
+ */
+void MD5Final(unsigned char digest[16], MD5_CTX *ctx)
+{
+ unsigned count;
+ unsigned char *p;
+
+ /* Compute number of bytes mod 64 */
+ count = (ctx->bits[0] >> 3) & 0x3F;
+
+ /* Set the first char of padding to 0x80. This is safe since there is
+ always at least one byte free */
+ p = ctx->in + count;
+ *p++ = 0x80;
+
+ /* Bytes of padding needed to make 64 bytes */
+ count = 64 - 1 - count;
+
+ /* Pad out to 56 mod 64 */
+ if (count < 8) {
+ /* Two lots of padding: Pad the first block to 64 bytes */
+ memset(p, 0, count);
+ byteReverse(ctx->in, 16);
+ MD5Transform(ctx->buf, (uint32_t *) ctx->in);
+
+ /* Now fill the next block with 56 bytes */
+ memset(ctx->in, 0, 56);
+ } else {
+ /* Pad block to 56 bytes */
+ memset(p, 0, count - 8);
+ }
+ byteReverse(ctx->in, 14);
+
+ /* Append length in bits and transform */
+ ((uint32_t *) ctx->in)[14] = ctx->bits[0];
+ ((uint32_t *) ctx->in)[15] = ctx->bits[1];
+
+ MD5Transform(ctx->buf, (uint32_t *) ctx->in);
+ byteReverse((unsigned char *) ctx->buf, 4);
+ memcpy(digest, ctx->buf, 16);
+ memset((char *) ctx, 0, sizeof(ctx)); /* In case it's sensitive */
+}
+
+/* The four core functions - F1 is optimized somewhat */
+
+/* #define F1(x, y, z) (x & y | ~x & z) */
+#define F1(x, y, z) (z ^ (x & (y ^ z)))
+#define F2(x, y, z) F1(z, x, y)
+#define F3(x, y, z) (x ^ y ^ z)
+#define F4(x, y, z) (y ^ (x | ~z))
+
+/* This is the central step in the MD5 algorithm. */
+#define MD5STEP(f, w, x, y, z, data, s) \
+ ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
+
+/*
+ * The core of the MD5 algorithm, this alters an existing MD5 hash to
+ * reflect the addition of 16 longwords of new data. MD5Update blocks
+ * the data and converts bytes into longwords for this routine.
+ */
+void MD5Transform(uint32_t buf[4], uint32_t const in[16])
+{
+ uint32_t a, b, c, d;
+
+ a = buf[0];
+ b = buf[1];
+ c = buf[2];
+ d = buf[3];
+
+ MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
+ MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
+ MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
+ MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
+ MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
+ MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
+ MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
+ MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
+ MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
+ MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
+ MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
+ MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
+ MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
+ MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
+ MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
+ MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
+
+ MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
+ MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
+ MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
+ MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
+ MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
+ MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
+ MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
+ MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
+ MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
+ MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
+ MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
+ MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
+ MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
+ MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
+ MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
+ MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
+
+ MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
+ MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
+ MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
+ MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
+ MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
+ MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
+ MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
+ MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
+ MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
+ MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
+ MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
+ MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
+ MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
+ MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
+ MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
+ MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
+
+ MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
+ MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
+ MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
+ MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
+ MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
+ MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
+ MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
+ MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
+ MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
+ MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
+ MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
+ MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
+ MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
+ MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
+ MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
+ MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
+
+ buf[0] += a;
+ buf[1] += b;
+ buf[2] += c;
+ buf[3] += d;
+}
diff --git a/plugins/uade2/uade-2.13/src/frontends/common/md5.copyright b/plugins/uade2/uade-2.13/src/frontends/common/md5.copyright
new file mode 100644
index 00000000..72b040b3
--- /dev/null
+++ b/plugins/uade2/uade-2.13/src/frontends/common/md5.copyright
@@ -0,0 +1,8 @@
+The algorithm is due to Ron Rivest. This code was written by Colin
+Plumb in 1993, no copyright is claimed. This code is in the public
+domain; do with it what you wish.
+.Pp
+Equivalent code is available from RSA Data Security, Inc.
+This code has been tested against that, and is equivalent,
+except that you don't need to include two pages of legalese
+with every copy.
diff --git a/plugins/uade2/uade-2.13/src/frontends/common/md5.h b/plugins/uade2/uade-2.13/src/frontends/common/md5.h
new file mode 100644
index 00000000..6f471e3b
--- /dev/null
+++ b/plugins/uade2/uade-2.13/src/frontends/common/md5.h
@@ -0,0 +1,21 @@
+#ifndef _UADE_MD5_H_
+#define _UADE_MD5_H_
+
+#include <sys/types.h>
+#include <stdint.h>
+
+#define MD5_HASHBYTES 16
+
+typedef struct MD5Context {
+ uint32_t buf[4];
+ uint32_t bits[2];
+ unsigned char in[64];
+} MD5_CTX;
+
+void MD5Init(MD5_CTX *context);
+void MD5Update(MD5_CTX *context, unsigned char const *buf,
+ unsigned len);
+void MD5Final(unsigned char digest[MD5_HASHBYTES], MD5_CTX *context);
+void MD5Transform(uint32_t buf[4], uint32_t const in[16]);
+
+#endif /* !_UADE_MD5_H_ */
diff --git a/plugins/uade2/uade-2.13/src/frontends/common/songdb.c b/plugins/uade2/uade-2.13/src/frontends/common/songdb.c
new file mode 100644
index 00000000..b7d79165
--- /dev/null
+++ b/plugins/uade2/uade-2.13/src/frontends/common/songdb.c
@@ -0,0 +1,798 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <assert.h>
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include "songdb.h"
+#include "uadeconf.h"
+#include "md5.h"
+#include "unixatomic.h"
+#include "ossupport.h"
+#include "uadeconfig.h"
+#include "support.h"
+#include "uadeconstants.h"
+
+#define NORM_ID "n="
+#define NORM_ID_LENGTH 2
+
+#define eserror(fmt, args...) do { fprintf(stderr, "song.conf error on line %zd: " fmt "\n", lineno, ## args); exit(-1); } while (0)
+
+
+struct eaglesong {
+ int flags;
+ char md5[33];
+ struct uade_attribute *attributes;
+};
+
+struct persub {
+ int sub;
+ char *normalisation;
+};
+
+static struct uade_content *contentchecksums;
+static size_t nccused; /* number of valid entries in content db */
+static size_t nccalloc; /* number of allocated entries for content db */
+static int ccmodified;
+static int cccorrupted;
+
+static int nsongs;
+static struct eaglesong *songstore;
+
+static int escompare(const void *a, const void *b);
+static struct uade_content *get_content(const char *md5);
+
+
+static void add_sub_normalisation(struct uade_content *n, char *normalisation)
+{
+ struct persub *subinfo;
+ char *endptr;
+
+ subinfo = malloc(sizeof(*subinfo));
+ if (subinfo == NULL)
+ uadeerror("Can't allocate memory for normalisation entry\n");
+
+ subinfo->sub = strtol(normalisation, &endptr, 10);
+ if (*endptr != ',' || subinfo->sub < 0) {
+ fprintf(stderr, "Invalid normalisation entry: %s\n", normalisation);
+ return;
+ }
+
+ subinfo->normalisation = strdup(endptr + 1);
+ if (subinfo->normalisation == NULL)
+ uadeerror("Can't allocate memory for normalisation string\n");
+
+ vplist_append(n->subs, subinfo);
+}
+
+/* Compare function for bsearch() and qsort() to sort songs with respect
+ to their md5sums */
+static int contentcompare(const void *a, const void *b)
+{
+ return strcasecmp(((struct uade_content *)a)->md5,
+ ((struct uade_content *)b)->md5);
+}
+
+static int escompare(const void *a, const void *b)
+{
+ return strcasecmp(((struct eaglesong *)a)->md5,
+ ((struct eaglesong *)b)->md5);
+}
+
+static struct uade_content *get_content(const char *md5)
+{
+ struct uade_content key;
+
+ if (contentchecksums == NULL)
+ return NULL;
+
+ memset(&key, 0, sizeof key);
+ strlcpy(key.md5, md5, sizeof key.md5);
+
+ return bsearch(&key, contentchecksums, nccused,
+ sizeof contentchecksums[0], contentcompare);
+}
+
+static struct uade_content *create_content_checksum(const char *md5,
+ uint32_t playtime)
+{
+ struct uade_content *n;
+
+ if (nccused == nccalloc) {
+ nccalloc = MAX(nccalloc * 2, 16);
+ n = realloc(contentchecksums,
+ nccalloc * sizeof(struct uade_content));
+ if (n == NULL) {
+ fprintf(stderr,
+ "uade: No memory for new content checksums.\n");
+ return NULL;
+ }
+ contentchecksums = n;
+ }
+
+ n = &contentchecksums[nccused];
+
+ if (md5 == NULL)
+ return n;
+
+ nccused++;
+
+ ccmodified = 1;
+
+ memset(n, 0, sizeof(*n));
+ strlcpy(n->md5, md5, sizeof(n->md5));
+ n->playtime = playtime;
+
+ n->subs = vplist_create(1);
+
+ return n;
+}
+
+static void md5_from_buffer(char *dest, size_t destlen,
+ uint8_t * buf, size_t bufsize)
+{
+ uint8_t md5[16];
+ int ret;
+ MD5_CTX ctx;
+ MD5Init(&ctx);
+ MD5Update(&ctx, buf, bufsize);
+ MD5Final(md5, &ctx);
+ ret =
+ snprintf(dest, destlen,
+ "%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x",
+ md5[0], md5[1], md5[2], md5[3], md5[4], md5[5], md5[6],
+ md5[7], md5[8], md5[9], md5[10], md5[11], md5[12], md5[13],
+ md5[14], md5[15]);
+ if (ret >= destlen || ret != 32) {
+ fprintf(stderr, "md5 buffer error (%d/%zd)\n", ret, destlen);
+ exit(1);
+ }
+}
+
+static void update_playtime(struct uade_content *n, uint32_t playtime)
+{
+ if (n->playtime != playtime) {
+ ccmodified = 1;
+ n->playtime = playtime;
+ }
+}
+
+static void sort_content_checksums(void)
+{
+ if (contentchecksums == NULL)
+ return;
+
+ qsort(contentchecksums, nccused, sizeof contentchecksums[0],
+ contentcompare);
+}
+
+/* replace must be zero if content db is unsorted */
+struct uade_content *uade_add_playtime(const char *md5, uint32_t playtime)
+{
+ struct uade_content *n;
+
+ /* If content db hasn't been read into memory already, it is not used */
+ if (contentchecksums == NULL)
+ return NULL;
+
+ /* Do not record song shorter than 3 secs */
+ if (playtime < 3000)
+ return NULL;
+
+ if (strlen(md5) != 32)
+ return NULL;
+
+ n = get_content(md5);
+ if (n != NULL) {
+ update_playtime(n, playtime);
+ return n;
+ }
+
+ n = create_content_checksum(md5, playtime);
+
+ sort_content_checksums();
+
+ return n;
+}
+
+void uade_lookup_volume_normalisation(struct uade_state *state)
+{
+ size_t i, nsubs;
+ struct uade_effect *ue = &state->effects;
+ struct uade_config *uc = &state->config;
+ struct uade_song *us = state->song;
+ struct uade_content *content = get_content(us->md5);
+
+ if (content != NULL) {
+
+ nsubs = vplist_len(content->subs);
+
+ for (i = 0; i < nsubs; i++) {
+
+ struct persub *subinfo = vplist_get(content->subs, i);
+
+ if (subinfo->sub == us->cur_subsong) {
+ uade_set_config_option(uc, UC_NORMALISE,
+ subinfo->normalisation);
+ uade_effect_normalise_unserialise(uc->
+ normalise_parameter);
+ uade_effect_enable(ue, UADE_EFFECT_NORMALISE);
+ break;
+ }
+ }
+ }
+}
+
+static void get_song_flags_and_attributes_from_songstore(struct uade_song *us)
+{
+ struct eaglesong key;
+ struct eaglesong *es;
+
+ if (songstore != NULL) {
+ /* Lookup md5 from the songdb */
+ strlcpy(key.md5, us->md5, sizeof key.md5);
+ es = bsearch(&key, songstore, nsongs, sizeof songstore[0], escompare);
+
+ if (es != NULL) {
+ /* Found -> copy flags and attributes from database */
+ us->flags |= es->flags;
+ us->songattributes = es->attributes;
+ }
+ }
+}
+
+int uade_alloc_song(struct uade_state *state, const char *filename)
+{
+ struct uade_song *us;
+ struct uade_content *content;
+
+ state->song = NULL;
+
+ us = calloc(1, sizeof *us);
+ if (us == NULL)
+ goto error;
+
+ strlcpy(us->module_filename, filename, sizeof us->module_filename);
+
+ us->buf = atomic_read_file(&us->bufsize, filename);
+ if (us->buf == NULL)
+ goto error;
+
+ /* Compute an md5sum of the song */
+ md5_from_buffer(us->md5, sizeof us->md5, us->buf, us->bufsize);
+
+ /* Needs us->md5 sum */
+ get_song_flags_and_attributes_from_songstore(us);
+
+ /* Lookup playtime from content database */
+ us->playtime = -1;
+ content = get_content(us->md5);
+ if (content != NULL && content->playtime > 0)
+ us->playtime = content->playtime;
+
+ /* We can't know subsong numbers yet. The eagleplayer will report them
+ * in the playback state */
+ us->min_subsong = us->max_subsong = us->cur_subsong = -1;
+
+ state->song = us;
+ return 1;
+
+ error:
+ if (us != NULL) {
+ free(us->buf);
+ free(us);
+ }
+ return 0;
+}
+
+static int uade_open_and_lock(const char *filename, int create)
+{
+ int fd, ret;
+ fd = open(filename, O_RDWR);
+ if (fd < 0) {
+ if (errno == ENOENT && create) {
+ fd = open(filename, O_RDWR | O_CREAT,
+ S_IRUSR | S_IWUSR);
+ if (fd < 0)
+ return -1;
+ } else {
+ return -1;
+ }
+ }
+#ifndef UADE_HAVE_CYGWIN
+ ret = lockf(fd, F_LOCK, 0);
+ if (ret) {
+ fprintf(stderr, "uade: Unable to lock song.conf: %s (%s)\n",
+ filename, strerror(errno));
+ atomic_close(fd);
+ return -1;
+ }
+#endif
+
+ return fd;
+}
+
+
+static struct uade_content *store_playtime(const char *md5, long playtime,
+ int *newccmodified,
+ size_t oldnccused)
+{
+ struct uade_content *n = NULL;
+
+ if (oldnccused > 0) {
+ struct uade_content key;
+ memset(&key, 0, sizeof key);
+ strlcpy(key.md5, md5, sizeof key.md5);
+
+ /* We use "oldnccused" here as the length, while new entries
+ are added in unsorted manner to the end of the array */
+ n = bsearch(&key, contentchecksums, oldnccused,
+ sizeof contentchecksums[0], contentcompare);
+ if (n == NULL)
+ /* new songs on disk db -> merge -> need saving */
+ *newccmodified = 1;
+ }
+
+ /* We value a playtime determined during run-time over
+ a database value */
+ if (n == NULL) {
+ /* Note, create_content_checksum() makes "ccmodified"
+ true, which we work-around later with the "newccmodified" */
+ n = create_content_checksum(md5, (uint32_t) playtime);
+ }
+
+ if (n == NULL) {
+ /* No memory, fuck. We shouldn't save anything to
+ avoid losing data. */
+ fprintf(stderr,
+ "uade: Warning, no memory for the song database\n");
+ cccorrupted = 1;
+ }
+
+ return n;
+}
+
+
+
+int uade_read_content_db(const char *filename)
+{
+ char line[1024];
+ FILE *f;
+ size_t lineno = 0;
+ long playtime;
+ int i, j, nexti;
+ char *id, *eptr;
+ char numberstr[1024];
+ char *md5;
+
+ /* We make backups of some variables because following loop will
+ make it always true, which is not what we want. The end result should
+ be that ccmodified is true in following cases only:
+ 1. the in-memory db is already dirty
+ 2. the in-memory db gets new data from disk db (merge operation)
+ Otherwise ccmodified should be false. */
+ int newccmodified = ccmodified;
+ size_t oldnccused = nccused;
+ int fd;
+ struct uade_content *n;
+
+ /* Try to create a database if it doesn't exist */
+ if (contentchecksums == NULL
+ && create_content_checksum(NULL, 0) == NULL)
+ return 0;
+
+ fd = uade_open_and_lock(filename, 0);
+ if (fd < 0) {
+ fprintf(stderr, "uade: Can not find %s\n", filename);
+ return 0;
+ }
+
+ f = fdopen(fd, "r");
+ if (f == NULL) {
+ fprintf(stderr, "uade: Can not create FILE structure for %s\n",
+ filename);
+ close(fd);
+ return 0;
+ }
+
+ while (xfgets(line, sizeof line, f) != NULL) {
+ lineno++;
+
+ if (line[0] == '#')
+ continue;
+
+ md5 = line;
+ i = skip_and_terminate_word(line, 0);
+ if (i < 0)
+ continue; /* playtime doesn't exist */
+
+ for (j = 0; isxdigit(line[j]); j++);
+
+ if (j != 32)
+ continue; /* is not a valid md5sum */
+
+ /* Grab and validate playtime (in milliseconds) */
+ nexti = skip_and_terminate_word(line, i);
+
+ playtime = strtol(&line[i], &eptr, 10);
+ if (*eptr != 0 || playtime < 0) {
+ fprintf(stderr, "Invalid playtime for md5 %s on contentdb line %zd: %s\n", md5, lineno, numberstr);
+ continue;
+ }
+
+ n = store_playtime(md5, playtime, &newccmodified, oldnccused);
+ if (n == NULL)
+ continue;
+
+ i = nexti; /* Note, it could be that i < 0 */
+
+ /* Get rest of the directives in a loop */
+ while (i >= 0) {
+ id = &line[i];
+ i = skip_and_terminate_word(line, i);
+
+ /* Subsong volume normalisation: n=sub1,XXX */
+ if (strncmp(id, NORM_ID, NORM_ID_LENGTH) == 0) {
+ id += NORM_ID_LENGTH;
+ add_sub_normalisation(n, id);
+ } else {
+ fprintf(stderr, "Unknown contentdb directive on line %zd: %s\n", lineno, id);
+ }
+ }
+ }
+ fclose(f);
+
+ ccmodified = newccmodified;
+
+ sort_content_checksums();
+
+ return 1;
+}
+
+int uade_read_song_conf(const char *filename)
+{
+ FILE *f = NULL;
+ struct eaglesong *s;
+ size_t allocated;
+ size_t lineno = 0;
+ size_t i;
+ int fd;
+
+ fd = uade_open_and_lock(filename, 1);
+ /* open_and_lock() may fail without harm (it's actually supposed to
+ fail if the process does not have lock (write) permissions to
+ the song.conf file */
+
+ f = fopen(filename, "r");
+ if (f == NULL)
+ goto error;
+
+ nsongs = 0;
+ allocated = 16;
+ songstore = calloc(allocated, sizeof songstore[0]);
+ if (songstore == NULL)
+ eserror("No memory for song store.");
+
+ while (1) {
+ char **items;
+ size_t nitems;
+
+ items = read_and_split_lines(&nitems, &lineno, f,
+ UADE_WS_DELIMITERS);
+ if (items == NULL)
+ break;
+
+ assert(nitems > 0);
+
+ if (nsongs == allocated) {
+ allocated *= 2;
+ songstore = realloc(songstore, allocated * sizeof(songstore[0]));
+ if (songstore == NULL)
+ eserror("No memory for players.");
+ }
+
+ s = &songstore[nsongs];
+ nsongs++;
+
+ memset(s, 0, sizeof s[0]);
+
+ if (strncasecmp(items[0], "md5=", 4) != 0) {
+ fprintf(stderr, "Line %zd must begin with md5= in %s\n",
+ lineno, filename);
+ free(items);
+ continue;
+ }
+ if (strlcpy(s->md5, items[0] + 4, sizeof s->md5) !=
+ ((sizeof s->md5) - 1)) {
+ fprintf(stderr,
+ "Line %zd in %s has too long an md5sum.\n",
+ lineno, filename);
+ free(items);
+ continue;
+ }
+
+ for (i = 1; i < nitems; i++) {
+ if (strncasecmp(items[i], "comment:", 7) == 0)
+ break;
+ if (uade_song_and_player_attribute(&s->attributes, &s->flags, items[i], lineno))
+ continue;
+ fprintf(stderr, "song option %s is invalid\n", items[i]);
+ }
+
+ for (i = 0; items[i] != NULL; i++)
+ free(items[i]);
+
+ free(items);
+ }
+
+ fclose(f);
+
+ /* we may not have the file locked */
+ if (fd >= 0)
+ atomic_close(fd); /* lock is closed too */
+
+ /* Sort MD5 sums for binary searching songs */
+ qsort(songstore, nsongs, sizeof songstore[0], escompare);
+ return 1;
+
+ error:
+ if (f)
+ fclose(f);
+ if (fd >= 0)
+ atomic_close(fd);
+ return 0;
+}
+
+void uade_save_content_db(const char *filename)
+{
+ int fd;
+ FILE *f;
+ size_t i;
+
+ if (ccmodified == 0 || cccorrupted)
+ return;
+
+ fd = uade_open_and_lock(filename, 1);
+ if (fd < 0) {
+ fprintf(stderr, "uade: Can not write content db: %s\n",
+ filename);
+ return;
+ }
+
+ f = fdopen(fd, "w");
+ if (f == NULL) {
+ fprintf(stderr,
+ "uade: Can not create a FILE structure for content db: %s\n",
+ filename);
+ close(fd);
+ return;
+ }
+
+ for (i = 0; i < nccused; i++) {
+ char str[1024];
+ size_t subi, nsubs;
+ size_t bindex, bleft;
+ struct uade_content *n = &contentchecksums[i];
+
+ str[0] = 0;
+
+ bindex = 0;
+ bleft = sizeof(str);
+
+ nsubs = vplist_len(n->subs);
+
+ for (subi = 0; subi < nsubs; subi++) {
+ struct persub *sub = vplist_get(n->subs, subi);
+ int ret;
+ ret =
+ snprintf(&str[bindex], bleft, NORM_ID "%s ",
+ sub->normalisation);
+ if (ret >= bleft) {
+ fprintf(stderr,
+ "Too much subsong infos for %s\n",
+ n->md5);
+ break;
+ }
+ bleft -= ret;
+ bindex += ret;
+ }
+
+ fprintf(f, "%s %u %s\n", n->md5, (unsigned int)n->playtime,
+ str);
+ }
+
+ ccmodified = 0;
+
+ fclose(f);
+ fprintf(stderr, "uade: Saved %zd entries into content db.\n", nccused);
+}
+
+int uade_test_silence(void *buf, size_t size, struct uade_state *state)
+{
+ int i, s, exceptioncount;
+ int16_t *sm;
+ int nsamples;
+ int64_t count = state->song->silence_count;
+ int end = 0;
+
+ if (state->config.silence_timeout < 0)
+ return 0;
+
+ exceptioncount = 0;
+ sm = buf;
+ nsamples = size / 2;
+
+ for (i = 0; i < nsamples; i++) {
+ s = (sm[i] >= 0) ? sm[i] : -sm[i];
+ if (s >= (32767 * 1 / 100)) {
+ exceptioncount++;
+ if (exceptioncount >= (size * 2 / 100)) {
+ count = 0;
+ break;
+ }
+ }
+ }
+
+ if (i == nsamples) {
+ count += size;
+ if (count / (UADE_BYTES_PER_FRAME * state->config.frequency) >= state->config.silence_timeout) {
+ count = 0;
+ end = 1;
+ }
+ }
+
+ state->song->silence_count = count;
+
+ return end;
+}
+
+void uade_unalloc_song(struct uade_state *state)
+{
+ free(state->song->buf);
+ state->song->buf = NULL;
+
+ free(state->song);
+ state->song = NULL;
+}
+
+int uade_update_song_conf(const char *songconfin, const char *songconfout,
+ const char *songname, const char *options)
+{
+ int ret;
+ int fd;
+ char md5[33];
+ void *mem = NULL;
+ size_t filesize, newsize;
+ int found = 0;
+ size_t inputsize;
+ char *input, *inputptr, *outputptr;
+ size_t inputoffs;
+ char newline[256];
+ size_t i;
+ int need_newline = 0;
+
+ if (strlen(options) > 128) {
+ fprintf(stderr, "Too long song.conf options.\n");
+ return 0;
+ }
+
+ fd = uade_open_and_lock(songconfout, 1);
+
+ input = atomic_read_file(&inputsize, songconfin);
+ if (input == NULL) {
+ fprintf(stderr, "Can not read song.conf: %s\n", songconfin);
+ atomic_close(fd); /* closes the lock too */
+ return 0;
+ }
+
+ newsize = inputsize + strlen(options) + strlen(songname) + 64;
+ mem = realloc(input, newsize);
+ if (mem == NULL) {
+ fprintf(stderr,
+ "Can not realloc the input file buffer for song.conf.\n");
+ free(input);
+ atomic_close(fd); /* closes the lock too */
+ return 0;
+ }
+ input = mem;
+
+ mem = atomic_read_file(&filesize, songname);
+ if (mem == NULL)
+ goto error;
+
+ md5_from_buffer(md5, sizeof md5, mem, filesize);
+
+ inputptr = outputptr = input;
+ inputoffs = 0;
+
+ while (inputoffs < inputsize) {
+ if (inputptr[0] == '#')
+ goto copyline;
+
+ if ((inputoffs + 37) >= inputsize)
+ goto copyline;
+
+ if (strncasecmp(inputptr, "md5=", 4) != 0)
+ goto copyline;
+
+ if (strncasecmp(inputptr + 4, md5, 32) == 0) {
+ if (found) {
+ fprintf(stderr,
+ "Warning: dupe entry in song.conf: %s (%s)\n"
+ "Need manual resolving.\n", songname,
+ md5);
+ goto copyline;
+ }
+ found = 1;
+ snprintf(newline, sizeof newline, "md5=%s\t%s\n", md5,
+ options);
+
+ /* Skip this line. It will be appended later to the end of the buffer */
+ for (i = inputoffs; i < inputsize; i++) {
+ if (input[i] == '\n') {
+ i = i + 1 - inputoffs;
+ break;
+ }
+ }
+ if (i == inputsize) {
+ i = inputsize - inputoffs;
+ found = 0;
+ need_newline = 1;
+ }
+ inputoffs += i;
+ inputptr += i;
+ continue;
+ }
+
+ copyline:
+ /* Copy the line */
+ for (i = inputoffs; i < inputsize; i++) {
+ if (input[i] == '\n') {
+ i = i + 1 - inputoffs;
+ break;
+ }
+ }
+ if (i == inputsize) {
+ i = inputsize - inputoffs;
+ need_newline = 1;
+ }
+ memmove(outputptr, inputptr, i);
+ inputoffs += i;
+ inputptr += i;
+ outputptr += i;
+ }
+
+ if (need_newline) {
+ snprintf(outputptr, 2, "\n");
+ outputptr += 1;
+ }
+
+ /* there is enough space */
+ ret = snprintf(outputptr, PATH_MAX + 256, "md5=%s\t%s\tcomment %s\n",
+ md5, options, songname);
+ outputptr += ret;
+
+ if (ftruncate(fd, 0)) {
+ fprintf(stderr, "Can not truncate the file.\n");
+ goto error;
+ }
+
+ /* Final file size */
+ i = (size_t) (outputptr - input);
+
+ if (atomic_write(fd, input, i) < i)
+ fprintf(stderr,
+ "Unable to write file contents back. Data loss happened. CRAP!\n");
+
+ error:
+ atomic_close(fd); /* Closes the lock too */
+ free(input);
+ free(mem);
+ return 1;
+}
diff --git a/plugins/uade2/uade-2.13/src/frontends/common/songdb.h b/plugins/uade2/uade-2.13/src/frontends/common/songdb.h
new file mode 100644
index 00000000..8cbba160
--- /dev/null
+++ b/plugins/uade2/uade-2.13/src/frontends/common/songdb.h
@@ -0,0 +1,24 @@
+#ifndef _UADE_SONGDB_H_
+#define _UADE_SONGDB_H_
+
+#include "uadestate.h"
+#include "vplist.h"
+
+struct uade_content {
+ char md5[33];
+ uint32_t playtime; /* in milliseconds */
+ struct vplist *subs;
+};
+
+struct uade_content *uade_add_playtime(const char *md5, uint32_t playtime);
+int uade_alloc_song(struct uade_state *state, const char *filename);
+void uade_lookup_volume_normalisation(struct uade_state *state);
+int uade_read_content_db(const char *filename);
+int uade_read_song_conf(const char *filename);
+void uade_save_content_db(const char *filename);
+int uade_test_silence(void *buf, size_t size, struct uade_state *state);
+void uade_unalloc_song(struct uade_state *state);
+int uade_update_song_conf(const char *songconfin, const char *songconfout,
+ const char *songname, const char *options);
+
+#endif
diff --git a/plugins/uade2/uade-2.13/src/frontends/common/songinfo.c b/plugins/uade2/uade-2.13/src/frontends/common/songinfo.c
new file mode 100644
index 00000000..5997b183
--- /dev/null
+++ b/plugins/uade2/uade-2.13/src/frontends/common/songinfo.c
@@ -0,0 +1,721 @@
+#define _GNU_SOURCE
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+#include <stdint.h>
+#include <ctype.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "songinfo.h"
+#include "uadeutils.h"
+#include "ossupport.h"
+#include "amifilemagic.h"
+#include "support.h"
+
+
+static void asciiline(char *dst, unsigned char *buf)
+{
+ int i, c;
+ for (i = 0; i < 16; i++) {
+ c = buf[i];
+ if (isgraph(c) || c == ' ') {
+ dst[i] = c;
+ } else {
+ dst[i] = '.';
+ }
+ }
+ dst[i] = 0;
+}
+
+static int hexdump(char *info, size_t maxlen, char *filename, size_t toread)
+{
+ FILE *f;
+ size_t rb, ret;
+ uint8_t *buf;
+
+ assert(maxlen >= 8192);
+
+ f = fopen(filename, "rb");
+ if (f == NULL)
+ return 0;
+
+ buf = malloc(toread);
+ if (buf == NULL)
+ return 0;
+
+ rb = 0;
+ while (rb < toread) {
+ ret = fread(&buf[rb], 1, toread - rb, f);
+ if (ret == 0)
+ break;
+ rb += ret;
+ }
+
+ if (rb > 0) {
+ size_t roff = 0;
+ size_t woff = 0;
+
+ while (roff < rb) {
+ int iret;
+
+ if (woff >= maxlen)
+ break;
+
+ if (woff + 32 >= maxlen) {
+ strcpy(&info[woff], "\nbuffer overflow...\n");
+ woff += strlen(&info[woff]);
+ break;
+ }
+
+ iret = snprintf(&info[woff], maxlen - woff, "%.3zx: ",
+ roff);
+ assert(iret > 0);
+ woff += iret;
+
+ if (woff >= maxlen)
+ break;
+
+ if (roff + 16 > rb) {
+ iret = snprintf(&info[woff], maxlen - woff,
+ "Aligned line ");
+ assert(iret > 0);
+ woff += iret;
+
+ } else {
+ char dbuf[17];
+ asciiline(dbuf, &buf[roff]);
+ iret = snprintf(&info[woff], maxlen - woff,
+ "%.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x |%s|",
+ buf[roff + 0], buf[roff + 1],
+ buf[roff + 2], buf[roff + 3],
+ buf[roff + 4], buf[roff + 5],
+ buf[roff + 6], buf[roff + 7],
+ buf[roff + 8], buf[roff + 9],
+ buf[roff + 10], buf[roff + 11],
+ buf[roff + 12], buf[roff + 13],
+ buf[roff + 14], buf[roff + 15],
+ dbuf);
+ assert(iret > 0);
+ woff += iret;
+ }
+
+ if (woff >= maxlen)
+ break;
+
+ iret = snprintf(&info[woff], maxlen - woff, "\n");
+ woff += iret;
+
+ roff += 16;
+ }
+
+ if (woff >= maxlen)
+ woff = maxlen - 1;
+ info[woff] = 0;
+ }
+
+ fclose(f);
+ free(buf);
+ return rb == 0;
+}
+
+static size_t find_tag(uint8_t * buf, size_t startoffset, size_t buflen,
+ uint8_t * tag, size_t taglen)
+{
+ uint8_t *treasure;
+
+ if (startoffset >= buflen)
+ return -1;
+
+ treasure = memmem(buf + startoffset, buflen - startoffset, tag, taglen);
+ if (treasure == NULL)
+ return -1;
+
+ return (size_t) (treasure - buf);
+}
+
+static int string_checker(unsigned char *str, size_t off, size_t maxoff)
+{
+ assert(maxoff > 0);
+ while (off < maxoff) {
+ if (*str == 0)
+ return 1;
+ off++;
+ str++;
+ }
+ return 0;
+}
+
+/* Wanted Team's loadseg modules */
+static void process_WTWT_mod(char *credits, size_t credits_len,
+ unsigned char *buf, size_t len, char *lo,
+ char *hi, int rel)
+{
+ int offset, txt_offset, chunk;
+ char tmpstr[256];
+
+ /* check for Magic ID */
+ offset = find_tag((uint8_t *) buf, 0, len, (uint8_t *) lo, 4);
+ if (offset == -1)
+ return;
+
+ offset =
+ find_tag((uint8_t *) buf, offset + 4, offset + 8, (uint8_t *) hi,
+ 4);
+ if (offset == -1)
+ return;
+
+ chunk = offset - 8; /* here's where our first chunk should be */
+ offset = offset + rel; /* offset to our info pointers */
+
+ if (chunk < len && offset < len) {
+ txt_offset = read_be_u32(buf + offset) + chunk;
+ if (txt_offset < len && txt_offset != chunk) {
+ if (!string_checker(buf, txt_offset, len))
+ return;
+ snprintf(tmpstr, sizeof tmpstr, "\nMODULENAME:\n %s\n",
+ buf + txt_offset);
+ strlcat(credits, tmpstr, credits_len);
+
+ }
+ txt_offset = read_be_u32(buf + offset + 4) + chunk;
+ if (txt_offset < len && txt_offset != chunk) {
+ if (!string_checker(buf, txt_offset, len))
+ return;
+ snprintf(tmpstr, sizeof tmpstr, "\nAUTHORNAME:\n %s\n",
+ buf + txt_offset);
+ strlcat(credits, tmpstr, credits_len);
+ }
+
+ txt_offset = read_be_u32(buf + offset + 8) + chunk;
+ if (txt_offset < len && txt_offset != chunk) {
+ if (!string_checker(buf, txt_offset, len))
+ return;
+ snprintf(tmpstr, sizeof tmpstr, "\nSPECIALINFO:\n %s",
+ buf + txt_offset);
+ strlcat(credits, tmpstr, credits_len);
+ }
+ }
+}
+
+/* Get the info out of the AHX module data*/
+static void process_ahx_mod(char *credits, size_t credits_len,
+ unsigned char *buf, size_t len)
+{
+ int i;
+ size_t offset;
+ char tmpstr[256];
+
+ if (len < 13)
+ return;
+
+ offset = read_be_u16(buf + 4);
+
+ if (offset >= len)
+ return;
+
+ if (!string_checker(buf, offset, len))
+ return;
+
+ snprintf(tmpstr, sizeof tmpstr, "\nSong title: %s\n", buf + offset);
+ strlcat(credits, tmpstr, credits_len);
+
+ for (i = 0; i < buf[12]; i++) {
+ if (!string_checker(buf, offset, len))
+ break;
+ offset = offset + 1 + strlen((char *)buf + offset);
+ if (offset < len) {
+ snprintf(tmpstr, 256, "\n %s", buf + offset);
+ strlcat(credits, tmpstr, credits_len);
+ }
+ }
+}
+
+/* Get the info out of the protracker module data*/
+static void process_ptk_mod(char *credits, size_t credits_len, int inst,
+ uint8_t * buf, size_t len)
+{
+ int i;
+ char tmpstr[256];
+
+ if (!string_checker(buf, 0, len))
+ return;
+
+ snprintf(tmpstr, 35, "\nSong title: %s", buf);
+ strlcat(credits, tmpstr, credits_len);
+
+ if (inst == 31) {
+ if (len >= 0x43c) {
+ snprintf(tmpstr, sizeof tmpstr,
+ "\nmax positions: %d\n", buf[0x3b6]);
+ strlcat(credits, tmpstr, credits_len);
+ }
+ } else {
+ if (len >= 0x1da) {
+ snprintf(tmpstr, sizeof tmpstr,
+ "\nmax positions: %d\n", buf[0x1d6]);
+ strlcat(credits, tmpstr, credits_len);
+ }
+ }
+
+ snprintf(tmpstr, sizeof tmpstr, "\nINST - NAME SIZE VOL FINE LSTART LSIZE\n");
+ strlcat(credits, tmpstr, credits_len);
+ if (len >= (0x14 + inst * 0x1e)) {
+ for (i = 0; i < inst; i++) {
+ if (!string_checker(buf, 0x14 + i * 0x1e, len))
+ break;
+ snprintf(tmpstr, sizeof tmpstr, "[%2d] - ", i + 1);
+ strlcat(credits, tmpstr, credits_len);
+ snprintf(tmpstr, 23, "%-23s", buf + 0x14 + (i * 0x1e));
+ strlcat(credits, tmpstr, credits_len);
+ snprintf(tmpstr, sizeof tmpstr,
+ " %6d %2d %2d %6d %6d\n",
+ read_be_u16(buf + 42 + i * 0x1e) * 2,
+ buf[45 + i * 0x1e], buf[44 + i * 0x1e],
+ read_be_u16(buf + 46 + i * 0x1e) * 2,
+ read_be_u16(buf + 48 + i * 0x1e) * 2);
+ strlcat(credits, tmpstr, credits_len);
+ }
+ }
+}
+
+/* Get the info out of the digibooster module data*/
+static void process_digi_mod(char *credits, size_t credits_len,
+ uint8_t * buf, size_t len)
+{
+ int i;
+ char tmpstr[256];
+
+ if (len < (642 + 0x30 * 0x1e))
+ return;
+
+ if (!string_checker(buf, 610, len))
+ return;
+
+ snprintf(tmpstr, 0x2f, "\nSong title: %s \n", buf + 610);
+ strlcat(credits, tmpstr, credits_len);
+
+ snprintf(tmpstr, sizeof tmpstr, "max positions: %d\n", buf[47]);
+ strlcat(credits, tmpstr, credits_len);
+
+ snprintf(tmpstr, sizeof tmpstr, "\nINST - NAME SIZE VOL FINE LSTART LSIZE\n");
+ strlcat(credits, tmpstr, credits_len);
+ if (len >= (642 + 0x1f * 0x1e)) {
+ for (i = 0; i < 0x1f; i++) {
+ if (!string_checker(buf, 642 + i * 0x1e, len))
+ break;
+ snprintf(tmpstr, sizeof tmpstr, "[%2d] - ", i + 1);
+ strlcat(credits, tmpstr, credits_len);
+ snprintf(tmpstr, 30, "%-30s", buf + 642 + (i * 0x1e));
+ strlcat(credits, tmpstr, credits_len);
+ snprintf(tmpstr, sizeof tmpstr,
+ " %11d %2d %3d %11d %11d\n",
+ read_be_u32(buf + 176 + i * 4), buf[548 + i],
+ buf[579 + i], read_be_u32(buf + 300 + i * 4),
+ read_be_u32(buf + 424 + i * 4));
+ strlcat(credits, tmpstr, credits_len);
+ }
+ }
+}
+
+/* Get the info out of custom song. FIX ME, clean this function. */
+static void process_custom(char *credits, size_t credits_len,
+ unsigned char *buf, size_t len)
+{
+ char tmpstr[1024];
+ unsigned char *hunk;
+ unsigned char *tag_table;
+ int hunk_size;
+ int table_size;
+
+ int i;
+ int offset;
+ unsigned int x, y;
+ unsigned char startpattern[4] = { 0x70, 0xff, 0x4e, 0x75 };
+
+ if (len < 4)
+ return;
+
+ if (read_be_u32(buf) != 0x000003f3)
+ return;
+
+ i = find_tag(buf, 0, len, startpattern, sizeof startpattern);
+ if (i == -1 || (i + 12) >= len)
+ return;
+
+ if (strncmp((char *)buf + i + 4, "DELIRIUM", 8) != 0 &&
+ strncmp((char *)buf + i + 4, "EPPLAYER", 8) != 0) {
+ return;
+ }
+
+ /* Hunk found */
+ hunk = buf + i;
+ hunk_size = len - i;
+
+ if (16 + i + 5 >= hunk_size)
+ return;
+
+ /* Check if $VER is available */
+ if (!memcmp(&hunk[16], "$VER:", 5)) {
+ offset = 16 + 5;
+ while (offset < hunk_size) {
+ if (memcmp(&hunk[offset], " ", 1))
+ break;
+ offset++;
+ }
+ if (offset >= hunk_size)
+ return;
+
+ if ((offset + strlen((char *)hunk + offset) + 1) >
+ ((size_t) hunk_size))
+ return;
+
+ snprintf(tmpstr, sizeof tmpstr, "\nVERSION:\n%s\n\n",
+ hunk + offset);
+ strlcat(credits, tmpstr, credits_len);
+ }
+
+ offset = read_be_u32(hunk + 12);
+ if (offset < 0) {
+ return;
+ }
+
+ tag_table = hunk + offset;
+
+ if (tag_table >= &buf[len])
+ return;
+
+ table_size = ((int)(&buf[len] - tag_table)) / 8;
+
+ if (table_size <= 0)
+ return;
+
+ /* check all tags in this loop */
+ for (i = 0; i < table_size; i += 2) {
+ x = read_be_u32(tag_table + 4 * i);
+ y = read_be_u32(tag_table + 4 * (i + 1));
+
+ if (!x)
+ break;
+
+ switch (x) {
+ case 0x8000445a:
+ if (y >= ((unsigned int)hunk_size))
+ return;
+ if ((y + strlen((char *)hunk + y) + 1) >
+ ((size_t) hunk_size))
+ return;
+ snprintf(tmpstr, sizeof tmpstr, "\nCREDITS:\n%s\n\n",
+ hunk + y);
+ strlcat(credits, tmpstr, credits_len);
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+/*
+ * Get the info out of the Deltamusic 2 module data
+ */
+static void process_dm2_mod(char *credits, size_t credits_len,
+ unsigned char *buf, size_t len)
+{
+ char tmpstr[256];
+ if (!string_checker(buf, 0x148, len))
+ return;
+ snprintf(tmpstr, sizeof tmpstr, "\nRemarks:\n%s", buf + 0x148);
+ strlcat(credits, tmpstr, credits_len);
+}
+
+static int process_module(char *credits, size_t credits_len, char *filename)
+{
+ FILE *modfile;
+ struct stat st;
+ size_t modfilelen;
+ unsigned char *buf;
+ char pre[11];
+ char tmpstr[256];
+ size_t rb;
+
+ if (!(modfile = fopen(filename, "rb")))
+ return 0;
+
+ if (fstat(fileno(modfile), &st))
+ return 0;
+
+ modfilelen = st.st_size;
+
+ if ((buf = malloc(modfilelen)) == NULL) {
+ fprintf(stderr, "uade: can't allocate mem in process_module()");
+ fclose(modfile);
+ return 0;
+ }
+
+ rb = 0;
+ while (rb < modfilelen) {
+ size_t ret = fread(&buf[rb], 1, modfilelen - rb, modfile);
+ if (ret == 0)
+ break;
+ rb += ret;
+ }
+
+ fclose(modfile);
+
+ if (rb < modfilelen) {
+ fprintf(stderr, "uade: song info could not read %s fully\n",
+ filename);
+ free(buf);
+ return 0;
+ }
+
+ snprintf(tmpstr, sizeof tmpstr, "UADE2 MODINFO:\n\nFile name: %s\nFile length: %zd bytes\n", filename, modfilelen);
+ strlcpy(credits, tmpstr, credits_len);
+
+ /* Get filetype in pre */
+ uade_filemagic(buf, modfilelen, pre, modfilelen, filename, 0);
+
+ snprintf(tmpstr, sizeof tmpstr, "File prefix: %s.*\n", pre);
+ strlcat(credits, tmpstr, credits_len);
+
+ if (strcasecmp(pre, "CUST") == 0) {
+ /* CUST */
+ process_custom(credits, credits_len, buf, modfilelen);
+
+ } else if (strcasecmp(pre, "DM2") == 0) {
+ /* DM2 */
+ process_dm2_mod(credits, credits_len, buf, modfilelen);
+
+ } else if (strcasecmp(pre, "DIGI") == 0) {
+ /* DIGIBooster */
+ process_digi_mod(credits, credits_len, buf, modfilelen);
+
+ } else if ((strcasecmp(pre, "AHX") == 0) ||
+ (strcasecmp(pre, "THX") == 0)) {
+ /* AHX */
+ process_ahx_mod(credits, credits_len, buf, modfilelen);
+
+ } else if ((strcasecmp(pre, "MOD15") == 0) ||
+ (strcasecmp(pre, "MOD15_UST") == 0) ||
+ (strcasecmp(pre, "MOD15_MST") == 0) ||
+ (strcasecmp(pre, "MOD15_ST-IV") == 0)) {
+ /*MOD15 */
+ process_ptk_mod(credits, credits_len, 15, buf, modfilelen);
+
+ } else if ((strcasecmp(pre, "MOD") == 0) ||
+ (strcasecmp(pre, "MOD_DOC") == 0) ||
+ (strcasecmp(pre, "MOD_NTK") == 0) ||
+ (strcasecmp(pre, "MOD_NTK1") == 0) ||
+ (strcasecmp(pre, "MOD_NTK2") == 0) ||
+ (strcasecmp(pre, "MOD_FLT4") == 0) ||
+ (strcasecmp(pre, "MOD_FLT8") == 0) ||
+ (strcasecmp(pre, "MOD_ADSC4") == 0) ||
+ (strcasecmp(pre, "MOD_ADSC8") == 0) ||
+ (strcasecmp(pre, "MOD_COMP") == 0) ||
+ (strcasecmp(pre, "MOD_NTKAMP") == 0) ||
+ (strcasecmp(pre, "PPK") == 0) ||
+ (strcasecmp(pre, "MOD_PC") == 0) ||
+ (strcasecmp(pre, "ICE") == 0) ||
+ (strcasecmp(pre, "ADSC") == 0)) {
+ /*MOD*/
+ process_ptk_mod(credits, credits_len, 31, buf, modfilelen);
+ } else if (strcasecmp(pre, "DL") == 0) {
+ process_WTWT_mod(credits, credits_len, buf, modfilelen, "UNCL",
+ "EART", 0x28);
+ } else if (strcasecmp(pre, "BSS") == 0) {
+ process_WTWT_mod(credits, credits_len, buf, modfilelen, "BEAT",
+ "HOVE", 0x1c);
+ } else if (strcasecmp(pre, "GRAY") == 0) {
+ process_WTWT_mod(credits, credits_len, buf, modfilelen, "FRED",
+ "GRAY", 0x10);
+ } else if (strcasecmp(pre, "JMF") == 0) {
+ process_WTWT_mod(credits, credits_len, buf, modfilelen, "J.FL",
+ "OGEL", 0x14);
+ } else if (strcasecmp(pre, "SPL") == 0) {
+ process_WTWT_mod(credits, credits_len, buf, modfilelen, "!SOP",
+ "ROL!", 0x10);
+ } else if (strcasecmp(pre, "HD") == 0) {
+ process_WTWT_mod(credits, credits_len, buf, modfilelen, "H.DA",
+ "VIES", 24);
+ } else if (strcasecmp(pre, "RIFF") == 0) {
+ process_WTWT_mod(credits, credits_len, buf, modfilelen, "RIFF",
+ "RAFF", 0x14);
+ } else if (strcasecmp(pre, "FP") == 0) {
+ process_WTWT_mod(credits, credits_len, buf, modfilelen, "F.PL",
+ "AYER", 0x8);
+ } else if (strcasecmp(pre, "CORE") == 0) {
+ process_WTWT_mod(credits, credits_len, buf, modfilelen, "S.PH",
+ "IPPS", 0x20);
+ } else if (strcasecmp(pre, "BDS") == 0) {
+ process_WTWT_mod(credits, credits_len, buf, modfilelen, "DAGL",
+ "ISH!", 0x14);
+ }
+
+ free(buf);
+
+ return 0;
+}
+
+int uade_generate_song_title(char *title, size_t dstlen,
+ struct uade_state *state)
+{
+ size_t srcoffs;
+ size_t dstoffs;
+ size_t srclen;
+ char *format;
+ char *bname;
+ char p[64];
+ char *default_format = "%F %X [%P]";
+ struct uade_song *us = state->song;
+ struct uade_config *uc = &state->config;
+
+ /* %A min subsong
+ %B cur subsong
+ %C max subsong
+ %F file base name (us->module_filename)
+ %P player name
+ %T title
+ %X print subsong info if more than one subsong exist
+ */
+
+ format = uc->song_title;
+
+ if (format == NULL)
+ format = default_format;
+
+ if (strcmp("default", format) == 0)
+ format = default_format;
+
+ if ((srclen = strlen(format)) == 0) {
+ fprintf(stderr, "Warning: empty song_title format string.\n");
+ return 1;
+ }
+
+ if (dstlen == 0)
+ return 1;
+
+ if (strlen(us->module_filename) == 0)
+ return 1;
+
+ bname = xbasename(us->module_filename);
+
+ p[0] = 0;
+ if (us->formatname[0] == 0) {
+ if (us->playername[0] == 0) {
+ strlcpy(p, "Custom", sizeof p);
+ } else {
+ strlcpy(p, us->playername, sizeof p);
+ }
+ } else {
+ if (strncmp(us->formatname, "type: ", 6) == 0) {
+ strlcpy(p, us->formatname + 6, sizeof p);
+ } else {
+ strlcpy(p, us->formatname, sizeof p);
+ }
+ }
+
+ srcoffs = dstoffs = 0;
+
+ title[0] = 0;
+
+ while (dstoffs < dstlen) {
+ char c;
+ if (srcoffs >= srclen)
+ break;
+
+ if ((c = format[srcoffs]) == 0)
+ break;
+
+ if (c != '%') {
+ title[dstoffs++] = format[srcoffs++];
+ } else {
+ size_t inc;
+ char *dat = NULL;
+ char tmp[32];
+
+ if ((srcoffs + 1) >= srclen) {
+ fprintf(stderr, "Error: no identifier given in song title format: %s\n", format);
+ title[dstoffs] = 0;
+ return 1;
+ }
+
+ c = format[srcoffs + 1];
+
+ switch (c) {
+ case 'A':
+ snprintf(tmp, sizeof tmp, "%d",
+ us->min_subsong);
+ dat = tmp;
+ break;
+ case 'B':
+ snprintf(tmp, sizeof tmp, "%d",
+ us->cur_subsong);
+ dat = tmp;
+ break;
+ case 'C':
+ snprintf(tmp, sizeof tmp, "%d",
+ us->max_subsong);
+ dat = tmp;
+ break;
+ case 'F':
+ dat = bname;
+ break;
+ case 'P':
+ dat = p;
+ break;
+ case 'T':
+ dat = us->modulename;
+ if (strcmp("<no songtitle>", dat) == 0)
+ dat[0] = 0;
+ if (dat[0] == 0)
+ dat = bname;
+ break;
+ case 'X':
+ if (us->min_subsong == us->max_subsong) {
+ tmp[0] = 0;
+ } else {
+ snprintf(tmp, sizeof tmp, "(%d/%d)",
+ us->cur_subsong,
+ us->max_subsong);
+ }
+ dat = tmp;
+ break;
+ default:
+ fprintf(stderr,
+ "Unknown identifier %%%c in song_title format: %s\n",
+ c, format);
+ title[dstoffs] = 0;
+ return 1;
+ }
+ inc = strlcpy(&title[dstoffs], dat, dstlen - dstoffs);
+ srcoffs += 2;
+ dstoffs += inc;
+ }
+ }
+
+ if (dstoffs < dstlen)
+ title[dstoffs] = 0;
+ else
+ title[dstlen - 1] = 0;
+
+ return 0;
+}
+
+/* Returns zero on success, non-zero otherwise. */
+int uade_song_info(char *info, size_t maxlen, char *filename,
+ enum song_info_type type)
+{
+ switch (type) {
+ case UADE_MODULE_INFO:
+ return process_module(info, maxlen, filename);
+ case UADE_HEX_DUMP_INFO:
+ return hexdump(info, maxlen, filename, 2048);
+ default:
+ fprintf(stderr, "Illegal info requested.\n");
+ exit(-1);
+ }
+ return 0;
+}
diff --git a/plugins/uade2/uade-2.13/src/frontends/common/songinfo.h b/plugins/uade2/uade-2.13/src/frontends/common/songinfo.h
new file mode 100644
index 00000000..e0abd059
--- /dev/null
+++ b/plugins/uade2/uade-2.13/src/frontends/common/songinfo.h
@@ -0,0 +1,19 @@
+#ifndef _UADE_SONG_INFO_
+#define _UADE_SONG_INFO_
+
+#include <stdio.h>
+
+#include "uadestate.h"
+
+enum song_info_type {
+ UADE_MODULE_INFO = 0,
+ UADE_HEX_DUMP_INFO,
+ UADE_NUMBER_OF_INFOS
+};
+
+int uade_generate_song_title(char *title, size_t dstlen,
+ struct uade_state *state);
+int uade_song_info(char *info, size_t maxlen, char *filename,
+ enum song_info_type type);
+
+#endif
diff --git a/plugins/uade2/uade-2.13/src/frontends/common/support.c b/plugins/uade2/uade-2.13/src/frontends/common/support.c
new file mode 100644
index 00000000..852d4c0e
--- /dev/null
+++ b/plugins/uade2/uade-2.13/src/frontends/common/support.c
@@ -0,0 +1,183 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "support.h"
+#include "ossupport.h"
+
+/* Zero terminate the current word. Returns -1 is *s == 0 or the next word
+ does not exist. Otherwise returns offset to the beginning of next word. */
+int skip_and_terminate_word(char *s, int i)
+{
+ i = skipnws(s, i);
+ if (i < 0)
+ return -1;
+
+ /* Zero terminate word */
+ s[i] = 0;
+
+ i = skipws(s, i + 1);
+ if (i < 0)
+ return -1;
+
+ return i;
+}
+
+char *xbasename(const char *s)
+{
+ char *t = strrchr(s, (int) '/');
+ if (t == NULL) {
+ t = (char *) s;
+ } else {
+ t++;
+ }
+ return t;
+}
+
+/*
+ * Split a string into 2 whitespace separated fields returned in "key" and
+ * "value". If more than 2 fields are found, they are cut off by zero
+ * terminating "key" and "value" inside the string. If "value" is not found,
+ * *value is set to NULL. If "key" is not found, *key is set to NULL.
+ * If something is found, both *key and *value become pointers inside the
+ * string s.
+ *
+ * Return values:
+ * - 0 if neither "key" nor "value" is found
+ * - 1 if only "key" is found
+ * - 2 if both "key" and "value" are found
+ */
+int get_two_ws_separated_fields(char **key, char **value, char *s)
+{
+ int i;
+
+ *key = NULL;
+ *value = NULL;
+
+ i = skipws(s, 0); /* Skip initial whitespace */
+
+ if (i < 0)
+ return 0; /* We got nothing */
+
+ *key = s + i;
+
+ i = skip_and_terminate_word(s, i);
+
+ if (i < 0)
+ return 1; /* We got a "key", but not a "value" */
+
+ *value = s + i;
+
+ skip_and_terminate_word(s, i);
+
+ return 2; /* We got both a "key" and a "value" */
+}
+
+/*
+ * Skip whitespace characters in string starting from offset i. Returns offset
+ * j >= i as the next non-whitespace character offset, or -1 if non-whitespace
+ * are not found.
+ */
+int skipws(const char *s, int i)
+{
+ while (isspace(s[i]))
+ i++;
+
+ if (s[i] == 0)
+ return -1;
+
+ return i;
+}
+
+/*
+ * Skip non-whitespace characters in string starting from offset i. Returns
+ * offset j >= i as the next whitespace character offset, or -1 if no
+ * whitespace if found.
+ */
+int skipnws(const char *s, int i)
+{
+ while (!isspace(s[i]) && s[i] != 0)
+ i++;
+
+ if (s[i] == 0)
+ return -1;
+
+ return i;
+}
+
+
+/* Split line with respect to white space. */
+char **read_and_split_lines(size_t *nitems, size_t *lineno, FILE *f,
+ const char *delim)
+{
+ char line[UADE_LINESIZE], templine[UADE_LINESIZE];
+ char **items = NULL;
+ size_t pos;
+ char *sp, *s;
+
+ *nitems = 0;
+
+ while (xfgets(line, sizeof line, f) != NULL) {
+
+ if (lineno != NULL)
+ (*lineno)++;
+
+ /* Skip, if a comment line */
+ if (line[0] == '#')
+ continue;
+
+ /* strsep() modifies line that it touches, so we make a copy
+ of it, and then count the number of items on the line */
+ strlcpy(templine, line, sizeof(templine));
+ sp = templine;
+ while ((s = strsep(&sp, delim)) != NULL) {
+ if (*s == 0)
+ continue;
+ (*nitems)++;
+ }
+
+ if (*nitems > 0)
+ break;
+ }
+
+ if (*nitems == 0)
+ return NULL;
+
+ if ((items = malloc(sizeof(items[0]) * (*nitems + 1))) == NULL)
+ uadeerror("No memory for nws items.\n");
+
+ sp = line;
+ pos = 0;
+ while ((s = strsep(&sp, delim)) != NULL) {
+ if (*s == 0)
+ continue;
+
+ if ((items[pos] = strdup(s)) == NULL)
+ uadeerror("No memory for an nws item.\n");
+
+ pos++;
+ }
+ items[pos] = NULL;
+ assert(pos == *nitems);
+
+ return items;
+}
+
+
+char *xfgets(char *s, int size, FILE *stream)
+{
+ char *ret;
+
+ while (1) {
+ ret = fgets(s, size, stream);
+ if (ret != NULL)
+ break;
+
+ if (feof(stream))
+ break;
+ }
+
+ return ret;
+}
diff --git a/plugins/uade2/uade-2.13/src/frontends/common/support.h b/plugins/uade2/uade-2.13/src/frontends/common/support.h
new file mode 100644
index 00000000..1b32fe92
--- /dev/null
+++ b/plugins/uade2/uade-2.13/src/frontends/common/support.h
@@ -0,0 +1,31 @@
+#ifndef _UADE_SUPPORT_H_
+#define _UADE_SUPPORT_H_
+
+#include <stdio.h>
+
+#define UADE_LINESIZE 1024
+
+#define uadeerror(fmt, args...) do { fprintf(stderr, "uade: " fmt, ## args); exit(1); } while (0)
+
+#define MAX(x, y) ((x) >= (y) ? (x) : (y))
+#define MIN(x, y) ((x) < (y) ? (x) : (y))
+
+
+char *xbasename(const char *path);
+
+int get_two_ws_separated_fields(char **key, char **value, char *s);
+
+int skipnws(const char *s, int i);
+
+int skip_and_terminate_word(char *s, int i);
+
+int skipws(const char *s, int i);
+
+char **read_and_split_lines(size_t *nitems, size_t *lineno, FILE *f,
+ const char *delim);
+
+/* Same as fgets(), but guarantees that feof() or ferror() have happened
+ when xfgets() returns NULL */
+char *xfgets(char *s, int size, FILE *stream);
+
+#endif
diff --git a/plugins/uade2/uade-2.13/src/frontends/common/uadeconf.c b/plugins/uade2/uade-2.13/src/frontends/common/uadeconf.c
new file mode 100644
index 00000000..17300340
--- /dev/null
+++ b/plugins/uade2/uade-2.13/src/frontends/common/uadeconf.c
@@ -0,0 +1,888 @@
+/* Handle uade.conf file
+
+ Copyright (C) 2005 Heikki Orsila <heikki.orsila@iki.fi>
+
+ This source code module is dual licensed under GPL and Public Domain.
+ Hence you may use _this_ module (not another code module) in any way you
+ want in your projects.
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+#include <assert.h>
+#include <limits.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "ossupport.h"
+#include "uadeconf.h"
+#include "uadeconfig.h"
+#include "amigafilter.h"
+#include "uadeconstants.h"
+#include "songdb.h"
+#include "uadeutils.h"
+#include "support.h"
+
+static int uade_set_silence_timeout(struct uade_config *uc, const char *value);
+static int uade_set_subsong_timeout(struct uade_config *uc, const char *value);
+static int uade_set_timeout(struct uade_config *uc, const char *value);
+
+
+struct uade_conf_opts {
+ char *str;
+ int l;
+ enum uade_option e;
+};
+
+/* List of uade.conf options. The list includes option name, minimum
+ string match length for the option name and its enum code. */
+static const struct uade_conf_opts uadeconfopts[] = {
+ {.str = "action_keys", .l = 2, .e = UC_ACTION_KEYS},
+ {.str = "ao_option", .l = 2, .e = UC_AO_OPTION},
+ {.str = "buffer_time", .l = 1, .e = UC_BUFFER_TIME},
+ {.str = "cygwin", .l = 1, .e = UC_CYGWIN_DRIVE_WORKAROUND},
+ {.str = "detect_format_by_detection", .l = 18, .e = UC_CONTENT_DETECTION},
+ {.str = "disable_timeout", .l = 1, .e = UC_DISABLE_TIMEOUTS},
+ {.str = "enable_timeout", .l = 2, .e = UC_ENABLE_TIMEOUTS},
+ {.str = "ep_option", .l = 2, .e = UC_EAGLEPLAYER_OPTION},
+ {.str = "filter_type", .l = 2, .e = UC_FILTER_TYPE},
+ {.str = "force_led_off", .l = 12, .e = UC_FORCE_LED_OFF},
+ {.str = "force_led_on", .l = 12, .e = UC_FORCE_LED_ON},
+ {.str = "force_led", .l = 9, .e = UC_FORCE_LED},
+ {.str = "frequency", .l = 2, .e = UC_FREQUENCY},
+ {.str = "gain", .l = 1, .e = UC_GAIN},
+ {.str = "headphones", .l = 11, .e = UC_HEADPHONES},
+ {.str = "headphones2", .l = 11, .e = UC_HEADPHONES2},
+ {.str = "headphone", .l = 11, .e = UC_HEADPHONES},
+ {.str = "ignore_player_check", .l = 2, .e = UC_IGNORE_PLAYER_CHECK},
+ {.str = "interpolator", .l = 2, .e = UC_RESAMPLER},
+ {.str = "magic_detection", .l = 1, .e = UC_CONTENT_DETECTION},
+ {.str = "no_ep_end_detect", .l = 4, .e = UC_NO_EP_END},
+ {.str = "no_filter", .l = 4, .e = UC_NO_FILTER},
+ {.str = "no_song_end", .l = 4, .e = UC_NO_EP_END},
+ {.str = "normalise", .l = 1, .e = UC_NORMALISE},
+ {.str = "ntsc", .l = 2, .e = UC_NTSC},
+ {.str = "one_subsong", .l = 1, .e = UC_ONE_SUBSONG},
+ {.str = "pal", .l = 3, .e = UC_PAL},
+ {.str = "panning_value", .l = 3, .e = UC_PANNING_VALUE},
+ {.str = "random_play", .l = 3, .e = UC_RANDOM_PLAY},
+ {.str = "recursive_mode", .l = 3, .e = UC_RECURSIVE_MODE},
+ {.str = "resampler", .l = 3, .e = UC_RESAMPLER},
+ {.str = "silence_timeout_value", .l = 2, .e = UC_SILENCE_TIMEOUT_VALUE},
+ {.str = "song_title", .l = 2, .e = UC_SONG_TITLE},
+ {.str = "speed_hack", .l = 2, .e = UC_SPEED_HACK},
+ {.str = "subsong_timeout_value", .l = 2, .e = UC_SUBSONG_TIMEOUT_VALUE},
+ {.str = "timeout_value", .l = 1, .e = UC_TIMEOUT_VALUE},
+ {.str = "verbose", .l = 1, .e = UC_VERBOSE},
+ {.str = NULL} /* END OF LIST */
+};
+
+
+/* Map an uade.conf option to an enum */
+static enum uade_option map_str_to_option(const char *key)
+{
+ size_t i;
+
+ for (i = 0; uadeconfopts[i].str != NULL; i++) {
+ if (strncmp(key, uadeconfopts[i].str, uadeconfopts[i].l) == 0)
+ return uadeconfopts[i].e;
+ }
+
+ return 0;
+}
+
+/* The function sets the default options. No *_set variables are set because
+ we don't want any option to become mergeable by default. See
+ uade_merge_configs(). */
+void uade_config_set_defaults(struct uade_config *uc)
+{
+ memset(uc, 0, sizeof(*uc));
+ uc->action_keys = 1;
+ strlcpy(uc->basedir.name, UADE_CONFIG_BASE_DIR, sizeof uc->basedir.name);
+ uade_set_filter_type(uc, NULL);
+ uc->frequency = UADE_DEFAULT_FREQUENCY;
+ uc->gain = 1.0;
+ uc->panning = 0.7;
+ uc->silence_timeout = 20;
+ uc->subsong_timeout = 512;
+ uc->timeout = -1;
+ uc->use_timeouts = 1;
+}
+
+double uade_convert_to_double(const char *value, double def, double low,
+ double high, const char *type)
+{
+ char *endptr, *newvalue;
+ char newseparator;
+ double v;
+
+ if (value == NULL)
+ return def;
+
+ v = strtod(value, &endptr);
+
+ /* Decimal separator conversion, if needed */
+ if (*endptr == ',' || *endptr == '.') {
+ newvalue = strdup(value);
+ if (newvalue == NULL)
+ uade_error("Out of memory\n");
+
+ newseparator = (*endptr == ',') ? '.' : ',';
+
+ newvalue[(intptr_t) endptr - (intptr_t) value] = newseparator;
+
+ v = strtod(newvalue, &endptr);
+ free(newvalue);
+ }
+
+ if (*endptr != 0 || v < low || v > high) {
+ fprintf(stderr, "Invalid %s value: %s\n", type, value);
+ v = def;
+ }
+
+ return v;
+}
+
+static void uade_add_ep_option(struct uade_ep_options *opts, const char *s)
+{
+ size_t freespace = sizeof(opts->o) - opts->s;
+
+ if (strlcpy(&opts->o[opts->s], s, freespace) >= freespace) {
+ fprintf(stderr, "Warning: uade eagleplayer option overflow: %s\n", s);
+ return;
+ }
+
+ opts->s += strlen(s) + 1;
+}
+
+static int handle_attributes(struct uade_config *uc, struct uade_song *us,
+ char *playername, size_t playernamelen,
+ int flags, struct uade_attribute *attributelist)
+{
+ struct uade_attribute *a;
+ size_t i;
+
+ for (i = 0; epconf[i].s != NULL; i++) {
+
+ if (epconf[i].o == 0)
+ continue;
+
+ if ((flags & epconf[i].e) == 0)
+ continue;
+
+ uade_set_config_option(uc, epconf[i].o, epconf[i].c);
+ }
+
+ if (flags & ES_NEVER_ENDS)
+ fprintf(stderr, "uade: ES_NEVER_ENDS is not implemented. What should it do?\n");
+
+ if (flags & ES_REJECT)
+ return -1;
+
+ a = attributelist;
+
+ while (a != NULL) {
+
+ switch (a->type) {
+ case ES_EP_OPTION:
+ if (uc->verbose)
+ fprintf(stderr, "Using eagleplayer option %s\n", a->s);
+ uade_add_ep_option(&us->ep_options, a->s);
+ break;
+
+ case ES_GAIN:
+ uade_set_config_option(uc, UC_GAIN, a->s);
+ break;
+
+ case ES_RESAMPLER:
+ uade_set_config_option(uc, UC_RESAMPLER, a->s);
+ break;
+
+ case ES_PANNING:
+ uade_set_config_option(uc, UC_PANNING_VALUE, a->s);
+ break;
+
+ case ES_PLAYER:
+ if (playername) {
+ snprintf(playername, playernamelen, "%s/players/%s", uc->basedir.name, a->s);
+ } else {
+ fprintf(stderr, "Error: attribute handling was given playername == NULL.\n");
+ }
+ break;
+
+ case ES_SILENCE_TIMEOUT:
+ uade_set_config_option(uc, UC_SILENCE_TIMEOUT_VALUE, a->s);
+ break;
+
+ case ES_SUBSONGS:
+ fprintf(stderr, "Subsongs not implemented.\n");
+ break;
+
+ case ES_SUBSONG_TIMEOUT:
+ uade_set_config_option(uc, UC_SUBSONG_TIMEOUT_VALUE, a->s);
+ break;
+
+ case ES_TIMEOUT:
+ uade_set_config_option(uc, UC_TIMEOUT_VALUE, a->s);
+ break;
+
+ default:
+ fprintf(stderr, "Unknown song attribute integer: 0x%x\n", a->type);
+ break;
+ }
+
+ a = a->next;
+ }
+
+ return 0;
+}
+
+int uade_set_song_attributes(struct uade_state *state,
+ char *playername, size_t playernamelen)
+{
+ struct uade_song *us = state->song;
+ struct uade_config *uc = &state->config;
+
+ if (us->normalisation)
+ uade_set_config_option(uc, UC_NORMALISE, us->normalisation);
+
+ return handle_attributes(uc, us, playername, playernamelen,
+ us->flags, us->songattributes);
+}
+
+int uade_load_config(struct uade_config *uc, const char *filename)
+{
+ char line[256];
+ FILE *f;
+ char *key, *value;
+ int linenumber = 0;
+ enum uade_option opt;
+
+ if ((f = fopen(filename, "r")) == NULL)
+ return 0;
+
+ uade_config_set_defaults(uc);
+
+ while (xfgets(line, sizeof(line), f) != NULL) {
+ linenumber++;
+
+ /* Skip comment lines */
+ if (line[0] == '#')
+ continue;
+
+ if (!get_two_ws_separated_fields(&key, &value, line))
+ continue; /* Skip an empty line */
+
+ opt = map_str_to_option(key);
+
+ if (opt) {
+ uade_set_config_option(uc, opt, value);
+ } else {
+ fprintf(stderr, "Unknown config key in %s on line %d: %s\n", filename, linenumber, key);
+ }
+ }
+
+ fclose(f);
+ return 1;
+}
+
+int uade_load_initial_config(char *uadeconfname, size_t maxlen,
+ struct uade_config *uc, struct uade_config *ucbase)
+{
+ int loaded;
+ char *home;
+
+ assert(maxlen > 0);
+ uadeconfname[0] = 0;
+
+ uade_config_set_defaults(uc);
+
+ loaded = 0;
+
+ /* First try to load from forced base dir (testing mode) */
+ if (ucbase != NULL && ucbase->basedir_set) {
+ snprintf(uadeconfname, maxlen, "%s/uade.conf",
+ ucbase->basedir.name);
+ loaded = uade_load_config(uc, uadeconfname);
+ }
+
+ home = uade_open_create_home();
+
+ /* Second, try to load config from ~/.uade2/uade.conf */
+ if (loaded == 0 && home != NULL) {
+ snprintf(uadeconfname, maxlen, "%s/.uade2/uade.conf", home);
+ loaded = uade_load_config(uc, uadeconfname);
+ }
+
+ /* Third, try to load from install path */
+ if (loaded == 0) {
+ snprintf(uadeconfname, maxlen, "%s/uade.conf",
+ uc->basedir.name);
+ loaded = uade_load_config(uc, uadeconfname);
+ }
+
+ return loaded;
+}
+
+int uade_load_initial_song_conf(char *songconfname, size_t maxlen,
+ struct uade_config *uc,
+ struct uade_config *ucbase)
+{
+ int loaded = 0;
+ char *home;
+
+ assert(maxlen > 0);
+ songconfname[0] = 0;
+
+ /* Used for testing */
+ if (ucbase != NULL && ucbase->basedir_set) {
+ snprintf(songconfname, maxlen, "%s/song.conf",
+ ucbase->basedir.name);
+ loaded = uade_read_song_conf(songconfname);
+ }
+
+ /* Avoid unwanted home directory creation for test mode */
+ if (loaded)
+ return loaded;
+
+ home = uade_open_create_home();
+
+ /* Try to load from home dir */
+ if (loaded == 0 && home != NULL) {
+ snprintf(songconfname, maxlen, "%s/.uade2/song.conf", home);
+ loaded = uade_read_song_conf(songconfname);
+ }
+
+ /* No? Try install path */
+ if (loaded == 0) {
+ snprintf(songconfname, maxlen, "%s/song.conf",
+ uc->basedir.name);
+ loaded = uade_read_song_conf(songconfname);
+ }
+
+ return loaded;
+}
+
+void uade_merge_configs(struct uade_config *ucd, const struct uade_config *ucs)
+{
+#define MERGE_OPTION(y) do { if (ucs->y##_set) ucd->y = ucs->y; } while (0)
+
+ MERGE_OPTION(action_keys);
+ MERGE_OPTION(ao_options);
+ MERGE_OPTION(basedir);
+ MERGE_OPTION(buffer_time);
+ MERGE_OPTION(content_detection);
+ MERGE_OPTION(cygwin_drive_workaround);
+ MERGE_OPTION(ep_options);
+ MERGE_OPTION(filter_type);
+ MERGE_OPTION(frequency);
+ MERGE_OPTION(gain);
+ MERGE_OPTION(gain_enable);
+ MERGE_OPTION(headphones);
+ MERGE_OPTION(headphones2);
+ MERGE_OPTION(ignore_player_check);
+ MERGE_OPTION(led_forced);
+ MERGE_OPTION(led_state);
+ MERGE_OPTION(no_ep_end);
+ MERGE_OPTION(no_filter);
+ MERGE_OPTION(no_postprocessing);
+
+ /* Special merge -> don't use MERGE_OPTION macro */
+ if (ucs->normalise_set && ucs->normalise) {
+ ucd->normalise = 1;
+ if (ucs->normalise_parameter != NULL)
+ ucd->normalise_parameter = ucs->normalise_parameter;
+ }
+
+ MERGE_OPTION(one_subsong);
+ MERGE_OPTION(panning);
+ MERGE_OPTION(panning_enable);
+ MERGE_OPTION(random_play);
+ MERGE_OPTION(recursive_mode);
+ MERGE_OPTION(resampler);
+ MERGE_OPTION(silence_timeout);
+ MERGE_OPTION(song_title);
+ MERGE_OPTION(speed_hack);
+ MERGE_OPTION(subsong_timeout);
+
+ MERGE_OPTION(timeout);
+ MERGE_OPTION(use_timeouts);
+ if (ucs->timeout_set) {
+ ucd->use_timeouts = 1;
+ ucd->use_timeouts_set = 1;
+ }
+
+ MERGE_OPTION(use_text_scope);
+ MERGE_OPTION(use_ntsc);
+ MERGE_OPTION(verbose);
+}
+
+char *uade_open_create_home(void)
+{
+ /* Create ~/.uade2 directory if it does not exist */
+ char *home = getenv("HOME");
+ if (home) {
+ char name[PATH_MAX];
+ struct stat st;
+ snprintf(name, sizeof name, "%s/.uade2", home);
+ if (stat(name, &st) != 0)
+ mkdir(name, S_IRUSR | S_IWUSR | S_IXUSR);
+ }
+
+ return home;
+}
+
+int uade_parse_subsongs(int **subsongs, char *option)
+{
+ char substr[256];
+ char *sp, *str;
+ size_t pos;
+ int nsubsongs;
+
+ nsubsongs = 0;
+ *subsongs = NULL;
+
+ if (strlcpy(substr, option, sizeof subsongs) >= sizeof subsongs) {
+ fprintf(stderr, "Too long a subsong option: %s\n", option);
+ return -1;
+ }
+
+ sp = substr;
+ while ((str = strsep(&sp, ",")) != NULL) {
+ if (*str == 0)
+ continue;
+ nsubsongs++;
+ }
+
+ *subsongs = malloc((nsubsongs + 1) * sizeof((*subsongs)[0]));
+ if (*subsongs == NULL) {
+ fprintf(stderr, "No memory for subsongs.\n");
+ return -1;
+ }
+
+ strlcpy(substr, option, sizeof subsongs);
+
+ pos = 0;
+ sp = substr;
+ while ((str = strsep(&sp, ",")) != NULL) {
+ if (*str == 0)
+ continue;
+ (*subsongs)[pos] = atoi(str);
+ pos++;
+ }
+
+ (*subsongs)[pos] = -1;
+ assert(pos == nsubsongs);
+
+ return nsubsongs;
+}
+
+void uade_set_effects(struct uade_state *state)
+{
+ struct uade_effect *effects = &state->effects;
+ struct uade_config *uc = &state->config;
+
+ uade_effect_set_defaults(effects);
+
+ if (uc->no_postprocessing)
+ uade_effect_disable(effects, UADE_EFFECT_ALLOW);
+
+ if (uc->gain_enable) {
+ uade_effect_gain_set_amount(effects, uc->gain);
+ uade_effect_enable(effects, UADE_EFFECT_GAIN);
+ }
+
+ if (uc->headphones)
+ uade_effect_enable(effects, UADE_EFFECT_HEADPHONES);
+
+ if (uc->headphones2)
+ uade_effect_enable(effects, UADE_EFFECT_HEADPHONES2);
+
+ if (uc->normalise) {
+ uade_effect_normalise_unserialise(uc->normalise_parameter);
+ uade_effect_enable(effects, UADE_EFFECT_NORMALISE);
+ }
+
+ if (uc->panning_enable) {
+ uade_effect_pan_set_amount(effects, uc->panning);
+ uade_effect_enable(effects, UADE_EFFECT_PAN);
+ }
+
+ uade_effect_set_sample_rate(effects, uc->frequency);
+}
+
+void uade_set_config_option(struct uade_config *uc, enum uade_option opt,
+ const char *value)
+{
+ char *endptr;
+ long x;
+
+#define SET_OPTION(opt, value) do { uc->opt = (value); uc->opt##_set = 1; } while (0)
+
+ switch (opt) {
+ case UC_ACTION_KEYS:
+ if (value != NULL) {
+ uc->action_keys_set = 1;
+ if (!strcasecmp(value, "on") || !strcmp(value, "1")) {
+ uc->action_keys = 1;
+ } else if (!strcasecmp(value, "off") ||
+ !strcmp(value, "0")) {
+ uc->action_keys = 0;
+ } else {
+ fprintf(stderr,
+ "uade.conf: Unknown setting for action keys: %s\n",
+ value);
+ }
+ }
+ break;
+
+ case UC_AO_OPTION:
+ strlcat(uc->ao_options.o, value, sizeof uc->ao_options.o);
+ strlcat(uc->ao_options.o, "\n", sizeof uc->ao_options.o);
+ uc->ao_options_set = 1;
+ break;
+
+ case UC_BASE_DIR:
+ if (value != NULL) {
+ strlcpy(uc->basedir.name, value,
+ sizeof uc->basedir.name);
+ uc->basedir_set = 1;
+ } else {
+ fprintf(stderr, "uade: Passed NULL to UC_BASE_DIR.\n");
+ }
+ break;
+
+ case UC_BUFFER_TIME:
+ if (value != NULL) {
+ uc->buffer_time_set = 1;
+ uc->buffer_time = strtol(value, &endptr, 10);
+ if (uc->buffer_time <= 0 || *endptr != 0) {
+ fprintf(stderr, "Invalid buffer_time: %s\n",
+ value);
+ uc->buffer_time = 0;
+ }
+ } else {
+ fprintf(stderr,
+ "uade: Passed NULL to UC_BUFFER_TIME.\n");
+ }
+ break;
+
+ case UC_CONTENT_DETECTION:
+ SET_OPTION(content_detection, 1);
+ break;
+
+ case UC_CYGWIN_DRIVE_WORKAROUND:
+ SET_OPTION(cygwin_drive_workaround, 1);
+ break;
+
+ case UC_DISABLE_TIMEOUTS:
+ SET_OPTION(use_timeouts, 0);
+ break;
+
+ case UC_ENABLE_TIMEOUTS:
+ SET_OPTION(use_timeouts, 1);
+ break;
+
+ case UC_EAGLEPLAYER_OPTION:
+ if (value != NULL) {
+ uade_add_ep_option(&uc->ep_options, value);
+ uc->ep_options_set = 1;
+ } else {
+ fprintf(stderr,
+ "uade: Passed NULL to UC_EAGLEPLAYER_OPTION.\n");
+ }
+ break;
+
+ case UC_FILTER_TYPE:
+ SET_OPTION(no_filter, 0);
+
+ if (value != NULL) {
+ if (strcasecmp(value, "none") != 0) {
+ /* Filter != NONE */
+ uade_set_filter_type(uc, value);
+ uc->filter_type_set = 1;
+ } else {
+ /* Filter == NONE */
+ uc->no_filter = 1;
+ }
+ }
+ break;
+
+ case UC_FORCE_LED:
+ if (value == NULL) {
+ fprintf(stderr, "uade: UC_FORCE_LED value is NULL\n");
+ break;
+ }
+ if (strcasecmp(value, "off") == 0 || strcmp(value, "0") == 0) {
+ uc->led_state = 0;
+ } else if (strcasecmp(value, "on") == 0
+ || strcmp(value, "1") == 0) {
+ uc->led_state = 1;
+ } else {
+ fprintf(stderr, "Unknown force led argument: %s\n",
+ value);
+ break;
+ }
+ uc->led_state_set = 1;
+
+ SET_OPTION(led_forced, 1);
+ break;
+
+ case UC_FORCE_LED_OFF:
+ SET_OPTION(led_forced, 1);
+ SET_OPTION(led_state, 0);
+ break;
+
+ case UC_FORCE_LED_ON:
+ SET_OPTION(led_forced, 1);
+ SET_OPTION(led_state, 1);
+ break;
+
+ case UC_FREQUENCY:
+ if (value == NULL) {
+ fprintf(stderr, "uade: UC_FREQUENCY value is NULL\n");
+ break;
+ }
+ x = strtol(value, &endptr, 10);
+ if (*endptr != 0) {
+ fprintf(stderr, "Invalid frequency number: %s\n",
+ value);
+ break;
+ }
+ /* The upper bound is NTSC Amigas bus freq */
+ if (x < 1 || x > 3579545) {
+ fprintf(stderr, "Frequency out of bounds: %ld\n", x);
+ x = UADE_DEFAULT_FREQUENCY;
+ }
+ SET_OPTION(frequency, x);
+ break;
+
+ case UC_GAIN:
+ if (value == NULL) {
+ fprintf(stderr, "uade: UC_GAIN value is NULL\n");
+ break;
+ }
+ SET_OPTION(gain_enable, 1);
+ SET_OPTION(gain, uade_convert_to_double(value, 1.0, 0.0, 128.0, "gain"));
+ break;
+
+ case UC_HEADPHONES:
+ SET_OPTION(headphones, 1);
+ break;
+
+ case UC_HEADPHONES2:
+ SET_OPTION(headphones2, 1);
+ break;
+
+ case UC_IGNORE_PLAYER_CHECK:
+ SET_OPTION(ignore_player_check, 1);
+ break;
+
+ case UC_RESAMPLER:
+ if (value == NULL) {
+ fprintf(stderr, "uade.conf: No resampler given.\n");
+ break;
+ }
+ uc->resampler = strdup(value);
+ if (uc->resampler != NULL) {
+ uc->resampler_set = 1;
+ } else {
+ fprintf(stderr, "uade.conf: no memory for resampler.\n");
+ }
+ break;
+
+ case UC_NO_EP_END:
+ SET_OPTION(no_ep_end, 1);
+ break;
+
+ case UC_NO_FILTER:
+ SET_OPTION(no_filter, 1);
+ break;
+
+ case UC_NO_HEADPHONES:
+ SET_OPTION(headphones, 0);
+ SET_OPTION(headphones2, 0);
+ break;
+
+ case UC_NO_PANNING:
+ SET_OPTION(panning_enable, 0);
+ break;
+
+ case UC_NO_POSTPROCESSING:
+ SET_OPTION(no_postprocessing, 1);
+ break;
+
+ case UC_NORMALISE:
+ if (value == NULL) {
+ fprintf(stderr, "uade: UC_NORMALISE is NULL\n");
+ break;
+ }
+ SET_OPTION(normalise, 1);
+ uc->normalise_parameter = (char *) value;
+ break;
+
+ case UC_NTSC:
+ SET_OPTION(use_ntsc, 1);
+ break;
+
+ case UC_ONE_SUBSONG:
+ SET_OPTION(one_subsong, 1);
+ break;
+
+ case UC_PAL:
+ SET_OPTION(use_ntsc, 0);
+ break;
+
+ case UC_PANNING_VALUE:
+ if (value == NULL) {
+ fprintf(stderr, "uade: UC_PANNING_VALUE is NULL\n");
+ break;
+ }
+ SET_OPTION(panning_enable, 1);
+ SET_OPTION(panning, uade_convert_to_double(value, 0.0, 0.0, 2.0, "panning"));
+ break;
+
+ case UC_RANDOM_PLAY:
+ SET_OPTION(random_play, 1);
+ break;
+
+ case UC_RECURSIVE_MODE:
+ SET_OPTION(recursive_mode, 1);
+ break;
+
+ case UC_SILENCE_TIMEOUT_VALUE:
+ if (value == NULL) {
+ fprintf(stderr,
+ "uade: UC_SILENCE_TIMEOUT_VALUE is NULL\n");
+ break;
+ }
+ uade_set_silence_timeout(uc, value);
+ break;
+
+ case UC_SONG_TITLE:
+ if (value == NULL) {
+ fprintf(stderr, "uade: No song_title format given.\n");
+ break;
+ }
+ if ((uc->song_title = strdup(value)) == NULL) {
+ fprintf(stderr, "No memory for song title format\n");
+ } else {
+ uc->song_title_set = 1;
+ }
+ break;
+
+ case UC_SPEED_HACK:
+ SET_OPTION(speed_hack, 1);
+ break;
+
+ case UC_SUBSONG_TIMEOUT_VALUE:
+ if (value == NULL) {
+ fprintf(stderr,
+ "uade: UC_SUBSONG_TIMEOUT_VALUE is NULL\n");
+ break;
+ }
+ uade_set_subsong_timeout(uc, value);
+ break;
+
+ case UC_TIMEOUT_VALUE:
+ if (value == NULL) {
+ fprintf(stderr, "uade: UC_TIMEOUT_VALUE is NULL\n");
+ break;
+ }
+ uade_set_timeout(uc, value);
+ break;
+
+ case UC_USE_TEXT_SCOPE:
+ SET_OPTION(use_text_scope, 1);
+ break;
+
+ case UC_VERBOSE:
+ SET_OPTION(verbose, 1);
+ break;
+
+ default:
+ fprintf(stderr, "uade_set_config_option(): unknown enum: %d\n",
+ opt);
+ exit(1);
+ }
+}
+
+void uade_set_ep_attributes(struct uade_state *state)
+{
+ handle_attributes(&state->config, state->song, NULL, 0, state->ep->flags, state->ep->attributelist);
+}
+
+void uade_set_filter_type(struct uade_config *uc, const char *model)
+{
+ uc->filter_type = FILTER_MODEL_A500;
+
+ if (model == NULL)
+ return;
+
+ /* a500 and a500e are the same */
+ if (strncasecmp(model, "a500", 4) == 0) {
+ uc->filter_type = FILTER_MODEL_A500;
+
+ /* a1200 and a1200e are the same */
+ } else if (strncasecmp(model, "a1200", 5) == 0) {
+ uc->filter_type = FILTER_MODEL_A1200;
+
+ } else {
+ fprintf(stderr, "Unknown filter model: %s\n", model);
+ }
+}
+
+static int uade_set_silence_timeout(struct uade_config *uc, const char *value)
+{
+ char *endptr;
+ int t;
+ if (value == NULL) {
+ return -1;
+ }
+ t = strtol(value, &endptr, 10);
+ if (*endptr != 0 || t < -1) {
+ fprintf(stderr, "Invalid silence timeout value: %s\n", value);
+ return -1;
+ }
+ uc->silence_timeout = t;
+ uc->silence_timeout_set = 1;
+ return 0;
+}
+
+static int uade_set_subsong_timeout(struct uade_config *uc, const char *value)
+{
+ char *endptr;
+ int t;
+ if (value == NULL) {
+ return -1;
+ }
+ t = strtol(value, &endptr, 10);
+ if (*endptr != 0 || t < -1) {
+ fprintf(stderr, "Invalid subsong timeout value: %s\n", value);
+ return -1;
+ }
+ uc->subsong_timeout = t;
+ uc->subsong_timeout_set = 1;
+ return 0;
+}
+
+static int uade_set_timeout(struct uade_config *uc, const char *value)
+{
+ char *endptr;
+ int t;
+ if (value == NULL) {
+ return -1;
+ }
+ t = strtol(value, &endptr, 10);
+ if (*endptr != 0 || t < -1) {
+ fprintf(stderr, "Invalid timeout value: %s\n", value);
+ return -1;
+ }
+ uc->timeout = t;
+ uc->timeout_set = 1;
+ return 0;
+}
diff --git a/plugins/uade2/uade-2.13/src/frontends/common/uadeconf.h b/plugins/uade2/uade-2.13/src/frontends/common/uadeconf.h
new file mode 100644
index 00000000..62b11ef9
--- /dev/null
+++ b/plugins/uade2/uade-2.13/src/frontends/common/uadeconf.h
@@ -0,0 +1,27 @@
+#ifndef _UADE_FRONTEND_CONFIG_H_
+#define _UADE_FRONTEND_CONFIG_H_
+
+#include <uadestate.h>
+
+void uade_config_set_defaults(struct uade_config *uc);
+double uade_convert_to_double(const char *value, double def,
+ double low, double high, const char *type);
+int uade_load_config(struct uade_config *uc, const char *filename);
+int uade_load_initial_config(char *uadeconfname, size_t maxlen,
+ struct uade_config *uc,
+ struct uade_config *ucbase);
+int uade_load_initial_song_conf(char *songconfname, size_t maxlen,
+ struct uade_config *uc,
+ struct uade_config *ucbase);
+void uade_merge_configs(struct uade_config *ucd, const struct uade_config *ucs);
+char *uade_open_create_home(void);
+int uade_parse_subsongs(int **subsongs, char *option);
+void uade_set_config_option(struct uade_config *uc, enum uade_option opt,
+ const char *value);
+void uade_set_effects(struct uade_state *state);
+void uade_set_ep_attributes(struct uade_state *state);
+int uade_set_song_attributes(struct uade_state *state, char *playername,
+ size_t playernamelen);
+void uade_set_filter_type(struct uade_config *uc, const char *value);
+
+#endif
diff --git a/plugins/uade2/uade-2.13/src/frontends/common/uadeconfstructure.h b/plugins/uade2/uade-2.13/src/frontends/common/uadeconfstructure.h
new file mode 100644
index 00000000..d6cff1e0
--- /dev/null
+++ b/plugins/uade2/uade-2.13/src/frontends/common/uadeconfstructure.h
@@ -0,0 +1,139 @@
+#ifndef _UADECONF_STRUCTURE_H_
+#define _UADECONF_STRUCTURE_H_
+
+#include <limits.h>
+
+enum uade_option {
+ UC_ACTION_KEYS = 0x1000,
+ UC_AO_OPTION,
+ UC_BASE_DIR,
+ UC_BUFFER_TIME,
+ UC_CONTENT_DETECTION,
+ UC_CYGWIN_DRIVE_WORKAROUND,
+ UC_DISABLE_TIMEOUTS,
+ UC_ENABLE_TIMEOUTS,
+ UC_EAGLEPLAYER_OPTION,
+ UC_FILTER_TYPE,
+ UC_FORCE_LED_OFF,
+ UC_FORCE_LED_ON,
+ UC_FORCE_LED,
+ UC_FREQUENCY,
+ UC_GAIN,
+ UC_HEADPHONES,
+ UC_HEADPHONES2,
+ UC_IGNORE_PLAYER_CHECK,
+ UC_NO_FILTER,
+ UC_NO_HEADPHONES,
+ UC_NO_PANNING,
+ UC_NO_POSTPROCESSING,
+ UC_NO_EP_END,
+ UC_NORMALISE,
+ UC_NTSC,
+ UC_ONE_SUBSONG,
+ UC_PAL,
+ UC_PANNING_VALUE,
+ UC_RANDOM_PLAY,
+ UC_RECURSIVE_MODE,
+ UC_RESAMPLER,
+ UC_SILENCE_TIMEOUT_VALUE,
+ UC_SONG_TITLE,
+ UC_SPEED_HACK,
+ UC_SUBSONG_TIMEOUT_VALUE,
+ UC_TIMEOUT_VALUE,
+ UC_USE_TEXT_SCOPE,
+ UC_VERBOSE
+};
+
+struct uade_dir {
+ char name[PATH_MAX];
+};
+
+struct uade_ep_options {
+ char o[256];
+ size_t s;
+};
+
+struct uade_ao_options {
+ char o[256];
+};
+
+#define UADE_CHAR_CONFIG(x) char x; char x##_set;
+#define UADE_FLOAT_CONFIG(x) float x; char x##_set;
+#define UADE_INT_CONFIG(x) int x; char x##_set;
+
+/* All the options are put into an instance of this structure.
+ * There can be many structures, one for uade.conf and the other for
+ * command line options. Then these structures are then merged together
+ * to know the complete behavior for each case. Note, these structures
+ * can be conflicting, so the options are merged in following order
+ * so that the last merge will determine true behavior:
+ *
+ * 1. set uade.conf options
+ * 2. set eagleplayer attributes
+ * 3. set song attributes
+ * 4. set command line options
+ *
+ * Merging works by looking at X_set members of this structure. X_set
+ * member indicates that feature X has explicitly been set, so the
+ * merge will notice the change in value.
+ */
+struct uade_config {
+ UADE_CHAR_CONFIG(action_keys);
+
+ struct uade_ao_options ao_options;
+ char ao_options_set;
+
+ struct uade_dir basedir;
+ char basedir_set;
+
+ UADE_INT_CONFIG(buffer_time);
+ UADE_CHAR_CONFIG(content_detection);
+ UADE_CHAR_CONFIG(cygwin_drive_workaround);
+
+ struct uade_ep_options ep_options;
+ char ep_options_set;
+
+ UADE_CHAR_CONFIG(filter_type);
+ UADE_INT_CONFIG(frequency);
+ UADE_CHAR_CONFIG(led_forced);
+ UADE_CHAR_CONFIG(led_state);
+
+ UADE_CHAR_CONFIG(gain_enable);
+ /* should be removed of uade_effect integrated */
+ UADE_FLOAT_CONFIG(gain);
+
+ UADE_CHAR_CONFIG(headphones);
+ UADE_CHAR_CONFIG(headphones2);
+ UADE_CHAR_CONFIG(ignore_player_check);
+
+ char *resampler;
+ char resampler_set;
+
+ UADE_CHAR_CONFIG(no_ep_end);
+ UADE_CHAR_CONFIG(no_filter);
+ UADE_CHAR_CONFIG(no_postprocessing);
+
+ UADE_CHAR_CONFIG(normalise);
+ /* no normalise_parameter_set entry, use manual merging code */
+ char *normalise_parameter;
+
+ UADE_CHAR_CONFIG(one_subsong);
+ UADE_FLOAT_CONFIG(panning); /* should be removed */
+ UADE_CHAR_CONFIG(panning_enable);
+ UADE_CHAR_CONFIG(random_play);
+ UADE_CHAR_CONFIG(recursive_mode);
+ UADE_INT_CONFIG(silence_timeout);
+
+ char *song_title;
+ char song_title_set;
+
+ UADE_CHAR_CONFIG(speed_hack);
+ UADE_INT_CONFIG(subsong_timeout);
+ UADE_INT_CONFIG(timeout);
+ UADE_CHAR_CONFIG(use_text_scope);
+ UADE_CHAR_CONFIG(use_timeouts);
+ UADE_CHAR_CONFIG(use_ntsc);
+ UADE_CHAR_CONFIG(verbose);
+};
+
+#endif
diff --git a/plugins/uade2/uade-2.13/src/frontends/common/uadecontrol.c b/plugins/uade2/uade-2.13/src/frontends/common/uadecontrol.c
new file mode 100644
index 00000000..66e3eac8
--- /dev/null
+++ b/plugins/uade2/uade-2.13/src/frontends/common/uadecontrol.c
@@ -0,0 +1,249 @@
+/* uadecontrol.c is a helper module to control uade core through IPC:
+
+ Copyright (C) 2005 Heikki Orsila <heikki.orsila@iki.fi>
+
+ This source code module is dual licensed under GPL and Public Domain.
+ Hence you may use _this_ module (not another code module) in any way you
+ want in your projects.
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#include <errno.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/socket.h>
+
+#include "uadecontrol.h"
+#include "ossupport.h"
+#include "sysincludes.h"
+#include "uadeconstants.h"
+#include "songdb.h"
+
+static void subsong_control(int subsong, int command, struct uade_ipc *ipc);
+
+void uade_change_subsong(struct uade_state *state)
+{
+ state->song->silence_count = 0;
+
+ uade_lookup_volume_normalisation(state);
+
+ subsong_control(state->song->cur_subsong, UADE_COMMAND_CHANGE_SUBSONG, &state->ipc);
+}
+
+int uade_read_request(struct uade_ipc *ipc)
+{
+ uint32_t left = UADE_MAX_MESSAGE_SIZE - sizeof(struct uade_msg);
+ if (uade_send_u32(UADE_COMMAND_READ, left, ipc)) {
+ fprintf(stderr, "\ncan not send read command\n");
+ return 0;
+ }
+ return left;
+}
+
+static int send_ep_options(struct uade_ep_options *eo, struct uade_ipc *ipc)
+{
+ if (eo->s > 0) {
+ size_t i = 0;
+ while (i < eo->s) {
+ char *s = &eo->o[i];
+ size_t l = strlen(s) + 1;
+ assert((i + l) <= eo->s);
+ if (uade_send_string
+ (UADE_COMMAND_SET_PLAYER_OPTION, s, ipc)) {
+ fprintf(stderr,
+ "Can not send eagleplayer option.\n");
+ return -1;
+ }
+ i += l;
+ }
+ }
+ return 0;
+}
+
+void uade_send_filter_command(struct uade_state *state)
+{
+ struct uade_config *uadeconf = &state->config;
+ struct uade_ipc *ipc = &state->ipc;
+
+ int filter_type = uadeconf->filter_type;
+ int filter_state = uadeconf->led_state;
+ int force_filter = uadeconf->led_forced;
+
+ if (uadeconf->no_filter)
+ filter_type = 0;
+
+ /* Note that filter state is not normally forced */
+ filter_state = force_filter ? (2 + (filter_state & 1)) : 0;
+
+ if (uade_send_two_u32s
+ (UADE_COMMAND_FILTER, filter_type, filter_state, ipc)) {
+ fprintf(stderr, "Can not setup filters.\n");
+ exit(-1);
+ }
+}
+
+static void send_resampling_command(struct uade_ipc *ipc,
+ struct uade_config *uadeconf)
+{
+ char *mode = uadeconf->resampler;
+ if (mode != NULL) {
+ if (strlen(mode) == 0) {
+ fprintf(stderr, "Resampling mode may not be empty.\n");
+ exit(-1);
+ }
+ if (uade_send_string
+ (UADE_COMMAND_SET_RESAMPLING_MODE, mode, ipc)) {
+ fprintf(stderr, "Can not set resampling mode.\n");
+ exit(-1);
+ }
+ }
+}
+
+static void subsong_control(int subsong, int command, struct uade_ipc *ipc)
+{
+ assert(subsong >= 0 && subsong < 256);
+ if (uade_send_u32(command, (uint32_t) subsong, ipc) < 0) {
+ fprintf(stderr, "Could not changet subsong\n");
+ exit(-1);
+ }
+}
+
+void uade_set_subsong(int subsong, struct uade_ipc *ipc)
+{
+ subsong_control(subsong, UADE_COMMAND_SET_SUBSONG, ipc);
+}
+
+int uade_song_initialization(const char *scorename,
+ const char *playername,
+ const char *modulename,
+ struct uade_state *state)
+{
+ uint8_t space[UADE_MAX_MESSAGE_SIZE];
+ struct uade_msg *um = (struct uade_msg *)space;
+ struct uade_ipc *ipc = &state->ipc;
+ struct uade_config *uc = &state->config;
+ struct uade_song *us = state->song;
+
+ if (uade_send_string(UADE_COMMAND_SCORE, scorename, ipc)) {
+ fprintf(stderr, "Can not send score name.\n");
+ goto cleanup;
+ }
+
+ if (uade_send_string(UADE_COMMAND_PLAYER, playername, ipc)) {
+ fprintf(stderr, "Can not send player name.\n");
+ goto cleanup;
+ }
+
+ if (uade_send_string(UADE_COMMAND_MODULE, modulename, ipc)) {
+ fprintf(stderr, "Can not send module name.\n");
+ goto cleanup;
+ }
+
+ if (uade_send_short_message(UADE_COMMAND_TOKEN, ipc)) {
+ fprintf(stderr, "Can not send token after module.\n");
+ goto cleanup;
+ }
+
+ printf ("uade_song_initialization: receive message\n");
+ if (uade_receive_message(um, sizeof(space), ipc) <= 0) {
+ fprintf(stderr, "Can not receive acknowledgement.\n");
+ goto cleanup;
+ }
+
+ if (um->msgtype == UADE_REPLY_CANT_PLAY) {
+ if (uade_receive_short_message(UADE_COMMAND_TOKEN, ipc)) {
+ fprintf(stderr,
+ "Can not receive token in main loop.\n");
+ exit(-1);
+ }
+ return UADECORE_CANT_PLAY;
+ }
+
+ if (um->msgtype != UADE_REPLY_CAN_PLAY) {
+ fprintf(stderr, "Unexpected reply from uade: %u\n",
+ (unsigned int)um->msgtype);
+ goto cleanup;
+ }
+
+ if (uade_receive_short_message(UADE_COMMAND_TOKEN, ipc) < 0) {
+ fprintf(stderr, "Can not receive token after play ack.\n");
+ goto cleanup;
+ }
+
+ if (uc->ignore_player_check) {
+ if (uade_send_short_message(UADE_COMMAND_IGNORE_CHECK, ipc) < 0) {
+ fprintf(stderr, "Can not send ignore check message.\n");
+ goto cleanup;
+ }
+ }
+
+ if (uc->no_ep_end) {
+ if (uade_send_short_message
+ (UADE_COMMAND_SONG_END_NOT_POSSIBLE, ipc) < 0) {
+ fprintf(stderr,
+ "Can not send 'song end not possible'.\n");
+ goto cleanup;
+ }
+ }
+
+ uade_send_filter_command(state);
+
+ send_resampling_command(ipc, uc);
+
+ if (uc->speed_hack) {
+ if (uade_send_short_message(UADE_COMMAND_SPEED_HACK, ipc)) {
+ fprintf(stderr, "Can not send speed hack command.\n");
+ goto cleanup;
+ }
+ }
+
+ if (uc->use_ntsc) {
+ if (uade_send_short_message(UADE_COMMAND_SET_NTSC, ipc)) {
+ fprintf(stderr, "Can not send ntsc command.\n");
+ goto cleanup;
+ }
+ }
+
+ if (uc->frequency != UADE_DEFAULT_FREQUENCY) {
+ if (uade_send_u32
+ (UADE_COMMAND_SET_FREQUENCY, uc->frequency, ipc)) {
+ fprintf(stderr, "Can not send frequency.\n");
+ goto cleanup;
+ }
+ }
+
+ if (uc->use_text_scope) {
+ if (uade_send_short_message(UADE_COMMAND_USE_TEXT_SCOPE, ipc)) {
+ fprintf(stderr, "Can not send use text scope command.\n");
+ goto cleanup;
+ }
+ }
+
+ if (send_ep_options(&us->ep_options, ipc) ||
+ send_ep_options(&uc->ep_options, ipc))
+ goto cleanup;
+
+ printf ("uade_song_initialization: success\n");
+
+ return 0;
+
+ cleanup:
+ return UADECORE_INIT_ERROR;
+}
+
+void uade_spawn(struct uade_state *state, const char *uadename,
+ const char *configname)
+{
+ uade_arch_spawn(&state->ipc, &state->pid, uadename);
+
+ if (uade_send_string(UADE_COMMAND_CONFIG, configname, &state->ipc)) {
+ fprintf(stderr, "Can not send config name: %s\n",
+ strerror(errno));
+ kill(state->pid, SIGTERM);
+ state->pid = 0;
+ abort();
+ }
+}
diff --git a/plugins/uade2/uade-2.13/src/frontends/common/uadecontrol.h b/plugins/uade2/uade-2.13/src/frontends/common/uadecontrol.h
new file mode 100644
index 00000000..769521a9
--- /dev/null
+++ b/plugins/uade2/uade-2.13/src/frontends/common/uadecontrol.h
@@ -0,0 +1,24 @@
+#ifndef _UADE_CONTROL_
+#define _UADE_CONTROL_
+
+#include <sys/types.h>
+
+#include <uadestate.h>
+
+enum {
+ UADECORE_INIT_OK = 0,
+ UADECORE_INIT_ERROR,
+ UADECORE_CANT_PLAY
+};
+
+void uade_change_subsong(struct uade_state *state);
+int uade_read_request(struct uade_ipc *ipc);
+void uade_send_filter_command(struct uade_state *state);
+void uade_set_subsong(int subsong, struct uade_ipc *ipc);
+int uade_song_initialization(const char *scorename, const char *playername,
+ const char *modulename,
+ struct uade_state *state);
+void uade_spawn(struct uade_state *state, const char *uadename,
+ const char *configname);
+
+#endif
diff --git a/plugins/uade2/uade-2.13/src/frontends/common/uadestate.h b/plugins/uade2/uade-2.13/src/frontends/common/uadestate.h
new file mode 100644
index 00000000..7014a30a
--- /dev/null
+++ b/plugins/uade2/uade-2.13/src/frontends/common/uadestate.h
@@ -0,0 +1,25 @@
+#ifndef _UADE_STATE_H_
+#define _UADE_STATE_H_
+
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <eagleplayer.h>
+#include <effects.h>
+#include <uadeipc.h>
+
+struct uade_state {
+ /* Per song members */
+ struct uade_config config;
+ struct uade_song *song;
+ struct uade_effect effects;
+ struct eagleplayer *ep;
+
+ /* Permanent members */
+ int validconfig;
+ struct eagleplayerstore *playerstore;
+ struct uade_ipc ipc;
+ pid_t pid;
+};
+
+#endif
diff --git a/plugins/uade2/uade-2.13/src/frontends/common/unixwalkdir.c b/plugins/uade2/uade-2.13/src/frontends/common/unixwalkdir.c
new file mode 100644
index 00000000..292976d7
--- /dev/null
+++ b/plugins/uade2/uade-2.13/src/frontends/common/unixwalkdir.c
@@ -0,0 +1,69 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <string.h>
+
+#include <unixwalkdir.h>
+
+void *uade_walk_directories(const char *dirname,
+ void *(*fn) (const char *file,
+ enum uade_wtype wtype, void *opaque),
+ void *opaque)
+{
+ char *dename;
+ DIR *dir;
+ size_t namelen;
+ struct dirent *de;
+ void *ret = NULL;
+ struct stat st;
+ enum uade_wtype wtype;
+
+ namelen = strlen(dirname) + 256 + 2;
+ if ((dename = malloc(namelen)) == NULL)
+ return NULL;
+
+ if ((dir = opendir(dirname)) == NULL)
+ return NULL;
+
+ while ((de = readdir(dir)) != NULL) {
+
+ if (strcmp(de->d_name, ".") == 0
+ || strcmp(de->d_name, "..") == 0)
+ continue;
+
+ if (snprintf(dename, namelen, "%s/%s", dirname, de->d_name) >=
+ namelen) {
+ fprintf(stderr, "interesting: too long a filename\n");
+ continue;
+ }
+
+ if (lstat(dename, &st))
+ continue;
+
+ if (S_ISREG(st.st_mode))
+ wtype = UADE_WALK_REGULAR_FILE;
+ else if (S_ISDIR(st.st_mode))
+ wtype = UADE_WALK_DIRECTORY;
+ else if (S_ISLNK(st.st_mode))
+ wtype = UADE_WALK_SYMLINK;
+ else
+ wtype = UADE_WALK_SPECIAL;
+
+ if ((ret = fn(dename, wtype, opaque)) != NULL)
+ break;
+
+ if (wtype == UADE_WALK_DIRECTORY) {
+ if ((ret =
+ uade_walk_directories(dename, fn, opaque)) != NULL)
+ break;
+ }
+ }
+
+ closedir(dir);
+ free(dename);
+
+ return ret;
+}
diff --git a/plugins/uade2/uade-2.13/src/frontends/common/unixwalkdir.h b/plugins/uade2/uade-2.13/src/frontends/common/unixwalkdir.h
new file mode 100644
index 00000000..69844f47
--- /dev/null
+++ b/plugins/uade2/uade-2.13/src/frontends/common/unixwalkdir.h
@@ -0,0 +1,16 @@
+#ifndef _UADE_UNIXWALKDIR_H_
+#define _UADE_UNIXWALKDIR_H_
+
+enum uade_wtype {
+ UADE_WALK_REGULAR_FILE = 1,
+ UADE_WALK_DIRECTORY,
+ UADE_WALK_SYMLINK,
+ UADE_WALK_SPECIAL
+};
+
+void *uade_walk_directories(const char *dirname,
+ void *(*fn) (const char *file,
+ enum uade_wtype wtype, void *opaque),
+ void *opaque);
+
+#endif
diff --git a/plugins/uade2/uade-2.13/src/frontends/common/vplist.c b/plugins/uade2/uade-2.13/src/frontends/common/vplist.c
new file mode 100644
index 00000000..5546f54d
--- /dev/null
+++ b/plugins/uade2/uade-2.13/src/frontends/common/vplist.c
@@ -0,0 +1,115 @@
+#include <stdlib.h>
+#include <string.h>
+
+#include "vplist.h"
+
+
+#define VPLIST_BASIC_LENGTH 5
+
+
+static void shrink_vplist(struct vplist *v, size_t newsize)
+{
+ size_t ncopied = v->tail - v->head;
+ void **newl;
+ if (newsize >= v->allocated) {
+ fprintf(stderr, "vplist not shrinked.\n");
+ return;
+ }
+ memmove(v->l, &v->l[v->head], ncopied * sizeof(v->l[0]));
+ v->head = 0;
+ v->tail = ncopied;
+ v->allocated = newsize;
+ if ((newl = realloc(v->l, v->allocated * sizeof(v->l[0]))) == NULL) {
+ fprintf(stderr, "Not enough memory for shrinking vplist.\n");
+ exit(-1);
+ }
+ v->l = newl;
+}
+
+
+void vplist_grow(struct vplist *v)
+{
+ size_t newsize = v->allocated * 2;
+ void **newl;
+ if (newsize == 0)
+ newsize = VPLIST_BASIC_LENGTH;
+ newl = realloc(v->l, newsize * sizeof(v->l[0]));
+ if (newl == NULL) {
+ fprintf(stderr, "Not enough memory for growing vplist.\n");
+ exit(-1);
+ }
+ v->l = newl;
+ v->allocated = newsize;
+}
+
+
+struct vplist *vplist_create(size_t initial_length)
+{
+ struct vplist *v;
+ if ((v = calloc(1, sizeof(*v))) == NULL) {
+ fprintf(stderr, "No memory for vplist.\n");
+ exit(-1);
+ }
+ if (initial_length == 0)
+ initial_length = VPLIST_BASIC_LENGTH;
+ v->allocated = initial_length;
+ if ((v->l = malloc(v->allocated * sizeof(v->l[0]))) == NULL) {
+ fprintf(stderr, "Can not create a vplist.\n");
+ exit(-1);
+ }
+ return v;
+}
+
+
+void vplist_flush(struct vplist *v)
+{
+ v->head = v->tail = 0;
+ if (v->allocated >= (2 * VPLIST_BASIC_LENGTH))
+ shrink_vplist(v, VPLIST_BASIC_LENGTH);
+}
+
+
+void vplist_free(struct vplist *v)
+{
+ free(v->l);
+ memset(v, 0, sizeof(*v));
+ free(v);
+}
+
+
+void *vplist_pop_head(struct vplist *v)
+{
+ void *item;
+
+ if (v->head == v->tail) {
+ fprintf(stderr, "Error: can not pop head from an empty vplist.\n");
+ exit(-1);
+ }
+
+ item = v->l[v->head++];
+
+ /* If 3/4 of a list is unused, free half the list */
+ if (v->allocated >= VPLIST_BASIC_LENGTH && v->head >= ((v->allocated / 4) * 3))
+ shrink_vplist(v, v->allocated / 2);
+
+ return item;
+}
+
+
+void *vplist_pop_tail(struct vplist *v)
+{
+ void *item;
+
+ if (v->head == v->tail) {
+ fprintf(stderr, "Error: can not pop tail from an empty vplist.\n");
+ exit(-1);
+ }
+
+ item = v->l[v->tail--];
+
+ /* If 3/4 of a list is unused, free half the list */
+ if (v->allocated >= VPLIST_BASIC_LENGTH && v->tail < (v->allocated / 4))
+ shrink_vplist(v, v->allocated / 2);
+
+ return item;
+}
diff --git a/plugins/uade2/uade-2.13/src/frontends/common/vplist.h b/plugins/uade2/uade-2.13/src/frontends/common/vplist.h
new file mode 100644
index 00000000..ef79f5bd
--- /dev/null
+++ b/plugins/uade2/uade-2.13/src/frontends/common/vplist.h
@@ -0,0 +1,44 @@
+#ifndef _SHD_VPLIST_H_
+#define _SHD_VPLIST_H_
+
+#include <stdio.h>
+#include <assert.h>
+
+
+struct vplist {
+ size_t head;
+ size_t tail;
+ size_t allocated;
+ void **l;
+};
+
+
+struct vplist *vplist_create(size_t initial_length);
+void vplist_flush(struct vplist *v);
+void vplist_free(struct vplist *v);
+void vplist_grow(struct vplist *v);
+void *vplist_pop_head(struct vplist *v);
+void *vplist_pop_tail(struct vplist *v);
+
+
+static inline void vplist_append(struct vplist *v, void *item)
+{
+ if (v->tail == v->allocated)
+ vplist_grow(v);
+ v->l[v->tail++] = item;
+}
+
+
+static inline void *vplist_get(struct vplist *v, size_t i)
+{
+ assert(i < (v->tail - v->head));
+ return v->l[v->head + i];
+}
+
+
+static inline size_t vplist_len(struct vplist *v)
+{
+ return v->tail - v->head;
+}
+
+#endif
diff --git a/plugins/uade2/uade-2.13/src/include/.gitignore b/plugins/uade2/uade-2.13/src/include/.gitignore
new file mode 100644
index 00000000..c74efa80
--- /dev/null
+++ b/plugins/uade2/uade-2.13/src/include/.gitignore
@@ -0,0 +1,4 @@
+compilersupport.h
+ossupport.h
+sysincludes.h
+uadeconfig.h
diff --git a/plugins/uade2/uade-2.13/src/include/amigafilter.h b/plugins/uade2/uade-2.13/src/include/amigafilter.h
new file mode 100644
index 00000000..761fd33f
--- /dev/null
+++ b/plugins/uade2/uade-2.13/src/include/amigafilter.h
@@ -0,0 +1,10 @@
+#ifndef _UADE_AMIGA_FILTER_H_
+#define _UADE_AMIGA_FILTER_H_
+
+enum {
+ FILTER_MODEL_A500 = 1,
+ FILTER_MODEL_A1200,
+ FILTER_MODEL_UPPER_BOUND
+};
+
+#endif
diff --git a/plugins/uade2/uade-2.13/src/include/amigamsg.h b/plugins/uade2/uade-2.13/src/include/amigamsg.h
new file mode 100644
index 00000000..457529c3
--- /dev/null
+++ b/plugins/uade2/uade-2.13/src/include/amigamsg.h
@@ -0,0 +1,24 @@
+#ifndef _AMIGAMSG_H_
+#define _AMIGAMSG_H_
+
+enum amigamsg {
+ AMIGAMSG_SETSUBSONG = 1,
+ AMIGAMSG_SONG_END,
+ AMIGAMSG_PLAYERNAME,
+ AMIGAMSG_MODULENAME,
+ AMIGAMSG_SUBSINFO,
+ AMIGAMSG_CHECKERROR,
+ AMIGAMSG_SCORECRASH,
+ AMIGAMSG_SCOREDEAD,
+ AMIGAMSG_GENERALMSG,
+ AMIGAMSG_NTSC,
+ AMIGAMSG_FORMATNAME,
+ AMIGAMSG_LOADFILE,
+ AMIGAMSG_READ,
+ AMIGAMSG_FILESIZE,
+ AMIGAMSG_TIME_CRITICAL,
+ AMIGAMSG_GET_INFO,
+ AMIGAMSG_START_OUTPUT
+};
+
+#endif
diff --git a/plugins/uade2/uade-2.13/src/include/audio.h b/plugins/uade2/uade-2.13/src/include/audio.h
new file mode 100644
index 00000000..5716f5f9
--- /dev/null
+++ b/plugins/uade2/uade-2.13/src/include/audio.h
@@ -0,0 +1,57 @@
+ /*
+ * UAE - The Un*x Amiga Emulator
+ *
+ * Sound emulation stuff
+ *
+ * Copyright 1995, 1996, 1997 Bernd Schmidt
+ */
+
+#ifndef _UADE_AUDIO_H_
+#define _UADE_AUDIO_H_
+
+#include "sinctable.h"
+
+#define AUDIO_DEBUG 0
+/* Queue length 256 implies minimum emulated period of 8. This should be
+ * sufficient for all imaginable purposes. This must be power of two. */
+#define SINC_QUEUE_LENGTH 256
+
+typedef struct {
+ int time, output;
+} sinc_queue_t;
+
+extern struct audio_channel_data {
+ unsigned long adk_mask;
+ unsigned long evtime;
+ unsigned char dmaen, intreq2, data_written;
+ uaecptr lc, pt;
+
+ int state, wper, wlen;
+ int current_sample;
+ int sample_accum, sample_accum_time;
+ int output_state;
+ sinc_queue_t sinc_queue[SINC_QUEUE_LENGTH];
+ int sinc_queue_time;
+ int sinc_queue_head;
+ int vol;
+ uae_u16 dat, nextdat, per, len;
+
+ /* Debug variables */
+ uaecptr ptend, nextdatpt, nextdatptend, datpt, datptend;
+} audio_channel[4];
+
+extern void AUDxDAT (int nr, uae_u16 value);
+extern void AUDxVOL (int nr, uae_u16 value);
+extern void AUDxPER (int nr, uae_u16 value);
+extern void AUDxLCH (int nr, uae_u16 value);
+extern void AUDxLCL (int nr, uae_u16 value);
+extern void AUDxLEN (int nr, uae_u16 value);
+
+void audio_reset (void);
+void audio_set_filter(int filter_type, int filter_force);
+void audio_set_rate (int rate);
+void audio_set_resampler(char *name);
+void audio_use_text_scope(void);
+void update_audio (void);
+
+#endif
diff --git a/plugins/uade2/uade-2.13/src/include/cia.h b/plugins/uade2/uade-2.13/src/include/cia.h
new file mode 100644
index 00000000..558b11c0
--- /dev/null
+++ b/plugins/uade2/uade-2.13/src/include/cia.h
@@ -0,0 +1,26 @@
+ /*
+ * UAE - The Un*x Amiga Emulator
+ *
+ * CIA chip support
+ *
+ * (c) 1995 Bernd Schmidt
+ */
+
+extern void CIA_reset(void);
+extern void CIA_vsync_handler(void);
+extern void CIA_hsync_handler(void);
+extern void CIA_handler(void);
+
+extern void diskindex_handler(void);
+
+extern void dumpcia(void);
+
+extern unsigned int ciaaicr,ciaaimask,ciabicr,ciabimask;
+extern unsigned int ciaacra,ciaacrb,ciabcra,ciabcrb;
+extern unsigned int ciaapra, ciabpra;
+extern unsigned long ciaata,ciaatb,ciabta,ciabtb;
+extern unsigned long ciaatod,ciabtod,ciaatol,ciabtol,ciaaalarm,ciabalarm;
+extern int ciaatlatch,ciabtlatch;
+
+extern unsigned int gui_ledstate;
+extern int gui_ledstate_forced;
diff --git a/plugins/uade2/uade-2.13/src/include/commpipe.h b/plugins/uade2/uade-2.13/src/include/commpipe.h
new file mode 100644
index 00000000..c7f4d814
--- /dev/null
+++ b/plugins/uade2/uade-2.13/src/include/commpipe.h
@@ -0,0 +1,155 @@
+ /*
+ * UAE - The Un*x Amiga Emulator
+ *
+ * Communication between threads
+ *
+ * Copyright 1997, 2001 Bernd Schmidt
+ */
+
+typedef union {
+ int i;
+ uae_u32 u32;
+ void *pv;
+} uae_pt;
+
+/* These currently require the maximum size to be known at initialization
+ * time, but it wouldn't be hard to use a "normal" pipe as an extension once the
+ * user-level one gets full.
+ * We queue up to chunks pieces of data before signalling the other thread to
+ * avoid overhead. */
+
+typedef struct {
+ uae_sem_t lock;
+ uae_sem_t reader_wait;
+ uae_sem_t writer_wait;
+ uae_pt *data;
+ int size, chunks;
+ volatile int rdp, wrp;
+ volatile int writer_waiting;
+ volatile int reader_waiting;
+} smp_comm_pipe;
+
+static inline void init_comm_pipe (smp_comm_pipe *p, int size, int chunks)
+{
+ p->data = (uae_pt *)malloc (size*sizeof (uae_pt));
+ p->size = size;
+ p->chunks = chunks;
+ p->rdp = p->wrp = 0;
+ p->reader_waiting = 0;
+ p->writer_waiting = 0;
+ uae_sem_init (&p->lock, 0, 1);
+ uae_sem_init (&p->reader_wait, 0, 0);
+ uae_sem_init (&p->writer_wait, 0, 0);
+}
+
+static inline void destroy_comm_pipe (smp_comm_pipe *p)
+{
+ uae_sem_destroy (&p->lock);
+ uae_sem_destroy (&p->reader_wait);
+ uae_sem_destroy (&p->writer_wait);
+}
+
+static inline void maybe_wake_reader (smp_comm_pipe *p, int no_buffer)
+{
+ if (p->reader_waiting
+ && (no_buffer || ((p->wrp - p->rdp + p->size) % p->size) >= p->chunks))
+ {
+ p->reader_waiting = 0;
+ uae_sem_post (&p->reader_wait);
+ }
+}
+
+static inline void write_comm_pipe_pt (smp_comm_pipe *p, uae_pt data, int no_buffer)
+{
+ int nxwrp = (p->wrp + 1) % p->size;
+
+ if (p->reader_waiting) {
+ /* No need to do all the locking */
+ p->data[p->wrp] = data;
+ p->wrp = nxwrp;
+ maybe_wake_reader (p, no_buffer);
+ return;
+ }
+
+ uae_sem_wait (&p->lock);
+ if (nxwrp == p->rdp) {
+ /* Pipe full! */
+ p->writer_waiting = 1;
+ uae_sem_post (&p->lock);
+ /* Note that the reader could get in between here and do a
+ * sem_post on writer_wait before we wait on it. That's harmless.
+ * There's a similar case in read_comm_pipe_int_blocking. */
+ uae_sem_wait (&p->writer_wait);
+ uae_sem_wait (&p->lock);
+ }
+ p->data[p->wrp] = data;
+ p->wrp = nxwrp;
+ maybe_wake_reader (p, no_buffer);
+ uae_sem_post (&p->lock);
+}
+
+static inline uae_pt read_comm_pipe_pt_blocking (smp_comm_pipe *p)
+{
+ uae_pt data;
+
+ uae_sem_wait (&p->lock);
+ if (p->rdp == p->wrp) {
+ p->reader_waiting = 1;
+ uae_sem_post (&p->lock);
+ uae_sem_wait (&p->reader_wait);
+ uae_sem_wait (&p->lock);
+ }
+ data = p->data[p->rdp];
+ p->rdp = (p->rdp + 1) % p->size;
+
+ /* We ignore chunks here. If this is a problem, make the size bigger in the init call. */
+ if (p->writer_waiting) {
+ p->writer_waiting = 0;
+ uae_sem_post (&p->writer_wait);
+ }
+ uae_sem_post (&p->lock);
+ return data;
+}
+
+static inline int comm_pipe_has_data (smp_comm_pipe *p)
+{
+ return p->rdp != p->wrp;
+}
+
+static inline int read_comm_pipe_int_blocking (smp_comm_pipe *p)
+{
+ uae_pt foo = read_comm_pipe_pt_blocking (p);
+ return foo.i;
+}
+static inline uae_u32 read_comm_pipe_u32_blocking (smp_comm_pipe *p)
+{
+ uae_pt foo = read_comm_pipe_pt_blocking (p);
+ return foo.u32;
+}
+
+static inline void *read_comm_pipe_pvoid_blocking (smp_comm_pipe *p)
+{
+ uae_pt foo = read_comm_pipe_pt_blocking (p);
+ return foo.pv;
+}
+
+static inline void write_comm_pipe_int (smp_comm_pipe *p, int data, int no_buffer)
+{
+ uae_pt foo;
+ foo.i = data;
+ write_comm_pipe_pt (p, foo, no_buffer);
+}
+
+static inline void write_comm_pipe_u32 (smp_comm_pipe *p, int data, int no_buffer)
+{
+ uae_pt foo;
+ foo.u32 = data;
+ write_comm_pipe_pt (p, foo, no_buffer);
+}
+
+static inline void write_comm_pipe_pvoid (smp_comm_pipe *p, void *data, int no_buffer)
+{
+ uae_pt foo;
+ foo.pv = data;
+ write_comm_pipe_pt (p, foo, no_buffer);
+}
diff --git a/plugins/uade2/uade-2.13/src/include/compiler.h b/plugins/uade2/uade-2.13/src/include/compiler.h
new file mode 100644
index 00000000..545dd6a4
--- /dev/null
+++ b/plugins/uade2/uade-2.13/src/include/compiler.h
@@ -0,0 +1,111 @@
+ /*
+ * UAE - The Un*x Amiga Emulator
+ *
+ * m68k -> i386 compiler
+ *
+ * (c) 1995 Bernd Schmidt
+ */
+
+typedef uaecptr (*code_execfunc)(void);
+
+struct code_page {
+ struct code_page *next;
+ uae_u32 allocmask;
+};
+
+struct hash_block {
+ struct hash_block *lru_next, *lru_prev;
+ struct hash_entry *he_first;
+
+ struct code_page *cpage;
+ int alloclen;
+ uae_u32 page_allocmask;
+ char *compile_start;
+
+ int nrefs;
+
+ int translated:1;
+ int untranslatable:1;
+ int allocfailed:1;
+};
+
+struct hash_entry {
+ code_execfunc execute; /* For the sake of the stubs in X86.S */
+ struct hash_entry *next,*prev;
+ struct hash_entry *next_same_block, *lru_next, *lru_prev;
+ struct hash_block *block;
+
+ uaecptr addr;
+ uae_u32 matchword;
+ int ncalls:8;
+ int locked:1;
+ int cacheflush:1;
+};
+
+extern int nr_bbs_start;
+extern uae_u8 nr_bbs_to_run;
+extern code_execfunc exec_me;
+
+#ifdef USE_COMPILER
+static inline void run_compiled_code(void)
+{
+
+ /*if (regs.spcflags == SPCFLAG_EXEC && may_run_compiled) {*/
+ while (regs.spcflags == SPCFLAG_EXEC) {
+ uaecptr newpc;
+ regs.spcflags = 0;
+ /* newpc = (*exec_me)();*/
+ __asm__ __volatile__ ("pushl %%ebp; call *%1; popl %%ebp" : "=a" (newpc) : "r" (exec_me) :
+ "%eax", "%edx", "%ecx", "%ebx",
+ "%edi", "%esi", "memory", "cc");
+ if (nr_bbs_to_run == 0) {
+ struct hash_entry *h = (struct hash_entry *)newpc;
+ regs.spcflags = SPCFLAG_EXEC;
+ exec_me = h->execute;
+ regs.pc = h->addr;
+ regs.pc_p = regs.pc_oldp = get_real_address(h->addr);
+ nr_bbs_to_run = nr_bbs_start;
+ } else
+ m68k_setpc_fast(newpc);
+ do_cycles();
+ }
+/*} else */
+ regs.spcflags &= ~SPCFLAG_EXEC;
+}
+
+extern void compiler_init(void);
+extern void possible_loadseg(void);
+
+extern void m68k_do_rts(void);
+extern void m68k_do_bsr(uaecptr, uae_s32);
+extern void m68k_do_jsr(uaecptr, uaecptr);
+extern void compiler_flush_jsr_stack(void);
+
+#else
+
+#define run_compiled_code() do { ; } while (0)
+#define compiler_init() do { ; } while (0)
+#define possible_loadseg() do { ; } while (0)
+#define compiler_flush_jsr_stack() do { ; } while (0)
+
+static inline void m68k_do_rts(void)
+{
+ m68k_setpc(get_long(m68k_areg(regs, 7)));
+ m68k_areg(regs, 7) += 4;
+}
+
+static inline void m68k_do_bsr(uaecptr oldpc, uae_s32 offset)
+{
+ m68k_areg(regs, 7) -= 4;
+ put_long(m68k_areg(regs, 7), oldpc);
+ m68k_incpc(offset);
+}
+
+static inline void m68k_do_jsr(uaecptr oldpc, uaecptr dest)
+{
+ m68k_areg(regs, 7) -= 4;
+ put_long(m68k_areg(regs, 7), oldpc);
+ m68k_setpc(dest);
+}
+
+#endif
diff --git a/plugins/uade2/uade-2.13/src/include/custom.h b/plugins/uade2/uade-2.13/src/include/custom.h
new file mode 100644
index 00000000..15e3d689
--- /dev/null
+++ b/plugins/uade2/uade-2.13/src/include/custom.h
@@ -0,0 +1,115 @@
+ /*
+ * UAE - The Un*x Amiga Emulator
+ *
+ * custom chip support
+ *
+ * (c) 1995 Bernd Schmidt
+ */
+
+/* These are the masks that are ORed together in the chipset_mask option.
+ * If CSMASK_AGA is set, the ECS bits are guaranteed to be set as well. */
+#define CSMASK_ECS_AGNUS 1
+#define CSMASK_ECS_DENISE 2
+#define CSMASK_AGA 4
+
+extern void custom_init (void);
+extern void customreset (void);
+extern int intlev (void);
+extern void dumpcustom (void);
+
+extern void do_disk (void);
+
+extern void notice_new_xcolors (void);
+extern void notice_screen_contents_lost (void);
+extern void init_row_map (void);
+
+extern int picasso_requested_on;
+extern int picasso_on;
+
+/* Set to 1 to leave out the current frame in average frame time calculation.
+ * Useful if the debugger was active. */
+extern int bogusframe;
+
+extern uae_u16 dmacon;
+extern uae_u16 intena,intreq;
+
+extern int current_hpos (void);
+
+static inline int dmaen (unsigned int dmamask)
+{
+ return (dmamask & dmacon) && (dmacon & 0x200);
+}
+
+#define SPCFLAG_STOP 2
+#define SPCFLAG_DISK 4
+#define SPCFLAG_INT 8
+#define SPCFLAG_BRK 16
+#define SPCFLAG_EXTRA_CYCLES 32
+#define SPCFLAG_TRACE 64
+#define SPCFLAG_DOTRACE 128
+#define SPCFLAG_DOINT 256
+#define SPCFLAG_BLTNASTY 512
+#define SPCFLAG_EXEC 1024
+#define SPCFLAG_MODE_CHANGE 8192
+
+extern int dskdmaen;
+extern uae_u16 adkcon;
+
+extern unsigned int joy0dir, joy1dir;
+extern int joy0button, joy1button;
+
+extern void INTREQ (uae_u16);
+extern uae_u16 INTREQR (void);
+
+/* maximums for statically allocated tables */
+
+/* PAL/NTSC values */
+
+/* The HRM says: The vertical blanking area (PAL) ranges from line 0 to line 29,
+ * and no data can be displayed there. Nevertheless, we lose some overscan data
+ * if minfirstline is set to 29. */
+
+#define MAXHPOS_PAL 227
+#define MAXHPOS_NTSC 227
+#define MAXVPOS_PAL 312
+#define MAXVPOS_NTSC 262
+#define MINFIRSTLINE_PAL 21
+#define MINFIRSTLINE_NTSC 18
+#define VBLANK_ENDLINE_PAL 29
+#define VBLANK_ENDLINE_NTSC 24
+#define VBLANK_HZ_PAL 50
+#define VBLANK_HZ_NTSC 60
+
+#define SOUNDTICKS_PAL 3546895
+#define SOUNDTICKS_NTSC 3579545
+
+#define MAXHPOS (MAXHPOS_PAL)
+#define MAXVPOS (MAXVPOS_PAL)
+#define SOUNDTICKS (SOUNDTICKS_PAL)
+
+extern int maxhpos, maxvpos, minfirstline, vblank_endline, numscrlines, vblank_hz;
+extern unsigned long syncbase;
+#define NUMSCRLINES (maxvpos+1-minfirstline+1)
+
+#define DMA_AUD0 0x0001
+#define DMA_AUD1 0x0002
+#define DMA_AUD2 0x0004
+#define DMA_AUD3 0x0008
+#define DMA_DISK 0x0010
+#define DMA_SPRITE 0x0020
+#define DMA_BLITTER 0x0040
+#define DMA_COPPER 0x0080
+#define DMA_BITPLANE 0x0100
+#define DMA_BLITPRI 0x0400
+
+extern unsigned long frametime, timeframes;
+
+/* 50 words give you 800 horizontal pixels. An A500 can't do that, so it ought
+ * to be enough. Don't forget to update the definition in genp2c.c as well. */
+#define MAX_WORDS_PER_LINE 50
+
+extern uae_u32 hirestab_h[256][2];
+extern uae_u32 lorestab_h[256][4];
+
+extern uae_u32 hirestab_l[256][1];
+extern uae_u32 lorestab_l[256][2];
diff --git a/plugins/uade2/uade-2.13/src/include/debug.h b/plugins/uade2/uade-2.13/src/include/debug.h
new file mode 100644
index 00000000..8ca10ab5
--- /dev/null
+++ b/plugins/uade2/uade-2.13/src/include/debug.h
@@ -0,0 +1,25 @@
+ /*
+ * UAE - The Un*x Amiga Emulator
+ *
+ * Debugger
+ *
+ * (c) 1995 Bernd Schmidt
+ *
+ */
+
+#define MAX_HIST 10000
+
+extern int firsthist;
+extern int lasthist;
+extern int debugging;
+extern int debug_interrupt_happened;
+
+#ifdef NEED_TO_DEBUG_BADLY
+extern struct regstruct history[MAX_HIST];
+extern union flagu historyf[MAX_HIST];
+#else
+extern uaecptr history[MAX_HIST];
+#endif
+
+extern void debug(void);
+extern void activate_debugger(void);
diff --git a/plugins/uade2/uade-2.13/src/include/events.h b/plugins/uade2/uade-2.13/src/include/events.h
new file mode 100644
index 00000000..4b692650
--- /dev/null
+++ b/plugins/uade2/uade-2.13/src/include/events.h
@@ -0,0 +1,83 @@
+ /*
+ * UAE - The Un*x Amiga Emulator
+ *
+ * Events
+ * These are best for low-frequency events. Having too many of them,
+ * or using them for events that occur too frequently, can cause massive
+ * slowdown.
+ *
+ * Copyright 1995-1998 Bernd Schmidt
+ */
+
+extern void reset_frame_rate_hack (void);
+extern int rpt_available;
+
+extern unsigned long int cycles, nextevent, is_lastline;
+extern unsigned long int sample_evtime;
+typedef void (*evfunc)(void);
+
+struct ev
+{
+ int active;
+ unsigned long int evtime, oldcycles;
+ evfunc handler;
+};
+
+enum {
+ ev_hsync, ev_copper, ev_cia,
+ ev_blitter, ev_diskblk, ev_diskindex,
+ ev_max
+};
+
+extern struct ev eventtab[ev_max];
+
+static void events_schedule (void)
+{
+ unsigned long int mintime = ~0L;
+ unsigned long int eventtime;
+ /* HSYNC */
+ if(eventtab[ev_hsync].active) {
+ eventtime = eventtab[ev_hsync].evtime - cycles;
+ if (eventtime < mintime) mintime = eventtime;
+ }
+ /* AUDIO */
+#if 0
+ if(eventtab[ev_audio].active) {
+ eventtime = eventtab[ev_audio].evtime - cycles;
+ if (eventtime < mintime) mintime = eventtime;
+ }
+#endif
+ /* CIA */
+ if(eventtab[ev_cia].active) {
+ eventtime = eventtab[ev_cia].evtime - cycles;
+ if (eventtime < mintime) mintime = eventtime;
+ }
+ nextevent = cycles + mintime;
+}
+
+static void do_cycles_slow (unsigned long cycles_to_add) {
+ if ((nextevent - cycles) <= cycles_to_add) {
+ for (; cycles_to_add != 0; cycles_to_add--) {
+ if (++cycles == nextevent) {
+ /* HSYNC */
+ if(eventtab[ev_hsync].active && eventtab[ev_hsync].evtime == cycles) {
+ (*eventtab[ev_hsync].handler)();
+ }
+ /* AUDIO */
+#if 0
+ if(eventtab[ev_audio].active && eventtab[ev_audio].evtime == cycles) {
+ (*eventtab[ev_audio].handler)();
+ }
+#endif
+ /* CIA */
+ if(eventtab[ev_cia].active && eventtab[ev_cia].evtime == cycles) {
+ (*eventtab[ev_cia].handler)();
+ }
+ events_schedule();
+ }
+ }
+ }
+ cycles += cycles_to_add;
+}
+
+#define do_cycles do_cycles_slow
diff --git a/plugins/uade2/uade-2.13/src/include/execlib.h b/plugins/uade2/uade-2.13/src/include/execlib.h
new file mode 100644
index 00000000..c0777221
--- /dev/null
+++ b/plugins/uade2/uade-2.13/src/include/execlib.h
@@ -0,0 +1,40 @@
+ /*
+ * UAE - The Un*x Amiga Emulator
+ *
+ * Miscellaneous bits for exec emulation
+ *
+ * Copyright 1996 Bernd Schmidt
+ */
+
+#define CMD_INVALID 0
+#define CMD_RESET 1
+#define CMD_READ 2
+#define CMD_WRITE 3
+#define CMD_UPDATE 4
+#define CMD_CLEAR 5
+#define CMD_STOP 6
+#define CMD_START 7
+#define CMD_FLUSH 8
+#define CMD_NONSTD 9
+
+#define NT_TASK 1
+#define NT_DEVICE 3
+#define NT_MSGPORT 4
+#define NT_MESSAGE 5
+#define NT_FREEMSG 6
+#define NT_REPLYMSG 7
+#define NT_RESOURCE 8
+#define NT_LIBRARY 9
+#define NT_SIGNALSEM 15
+
+#ifndef MEMF_PUBLIC /* protection for AmigaDOS */
+#define MEMF_PUBLIC 1
+#define MEMF_CHIP 2
+#define MEMF_FAST 4
+#define MEMF_LOCAL 256
+#define MEMF_24BITDMA 512
+#define MEMF_CLEAR (1<<16)
+#define MEMF_LARGEST (1<<17)
+#define MEMF_REVERSE (1<<18)
+#define MEMF_TOTAL (1<<19)
+#endif
diff --git a/plugins/uade2/uade-2.13/src/include/gensound.h b/plugins/uade2/uade-2.13/src/include/gensound.h
new file mode 100644
index 00000000..63daeb04
--- /dev/null
+++ b/plugins/uade2/uade-2.13/src/include/gensound.h
@@ -0,0 +1,19 @@
+ /*
+ * UAE - The Un*x Amiga Emulator
+ *
+ * Prototypes for general sound related functions
+ * This use to be called sound.h, but that causes confusion
+ *
+ * Copyright 1997 Bernd Schmidt
+ */
+
+extern int sound_available;
+
+/* Determine if we can produce any sound at all. This can be only a guess;
+ * if unsure, say yes. Any call to init_sound may change the value. */
+extern int setup_sound (void);
+
+extern void set_sound_freq (int x);
+extern void init_sound (void);
+extern void flush_sound (void);
+extern void close_sound (void);
diff --git a/plugins/uade2/uade-2.13/src/include/memory.h b/plugins/uade2/uade-2.13/src/include/memory.h
new file mode 100644
index 00000000..96a967b5
--- /dev/null
+++ b/plugins/uade2/uade-2.13/src/include/memory.h
@@ -0,0 +1,181 @@
+ /*
+ * UAE - The Un*x Amiga Emulator
+ *
+ * memory management
+ *
+ * Copyright 1995 Bernd Schmidt
+ */
+
+/* Enabling this adds one additional native memory reference per 68k memory
+ * access, but saves one shift (on the x86). Enabling this is probably
+ * better for the cache. My favourite benchmark (PP2) doesn't show a
+ * difference, so I leave this enabled. */
+
+#if 1 || defined SAVE_MEMORY
+#define SAVE_MEMORY_BANKS
+#endif
+
+#ifndef REGPARAM
+#define REGPARAM
+#endif
+
+typedef uae_u32 (*mem_get_func)(uaecptr) REGPARAM;
+typedef void (*mem_put_func)(uaecptr, uae_u32) REGPARAM;
+typedef uae_u8 *(*xlate_func)(uaecptr) REGPARAM;
+typedef int (*check_func)(uaecptr, uae_u32) REGPARAM;
+
+extern char *address_space, *good_address_map;
+extern uae_u8 *chipmemory;
+
+extern uae_u32 allocated_chipmem;
+extern uae_u32 allocated_fastmem;
+extern uae_u32 allocated_bogomem;
+extern uae_u32 allocated_gfxmem;
+extern uae_u32 allocated_z3fastmem;
+extern uae_u32 allocated_a3000mem;
+
+#undef DIRECT_MEMFUNCS_SUCCESSFUL
+#include "machdep/maccess.h"
+
+#ifndef CAN_MAP_MEMORY
+#undef USE_COMPILER
+#endif
+
+#if defined(USE_COMPILER) && !defined(USE_MAPPED_MEMORY)
+#define USE_MAPPED_MEMORY
+#endif
+
+#define kickmem_size 0x080000
+
+#define chipmem_start 0x00000000
+#define bogomem_start 0x00C00000
+#define a3000mem_start 0x07000000
+#define kickmem_start 0x00F80000
+
+extern int ersatzkickfile;
+
+typedef struct {
+ /* These ones should be self-explanatory... */
+ mem_get_func lget, wget, bget;
+ mem_put_func lput, wput, bput;
+ /* Use xlateaddr to translate an Amiga address to a uae_u8 * that can
+ * be used to address memory without calling the wget/wput functions.
+ * This doesn't work for all memory banks, so this function may call
+ * abort(). */
+ xlate_func xlateaddr;
+ /* To prevent calls to abort(), use check before calling xlateaddr.
+ * It checks not only that the memory bank can do xlateaddr, but also
+ * that the pointer points to an area of at least the specified size.
+ * This is used for example to translate bitplane pointers in custom.c */
+ check_func check;
+} addrbank;
+
+extern uae_u8 filesysory[65536];
+
+extern addrbank chipmem_bank;
+extern addrbank kickmem_bank;
+extern addrbank custom_bank;
+extern addrbank clock_bank;
+extern addrbank cia_bank;
+extern addrbank rtarea_bank;
+extern addrbank expamem_bank;
+extern addrbank fastmem_bank;
+extern addrbank gfxmem_bank;
+
+extern void rtarea_init (void);
+extern void rtarea_setup (void);
+extern void expamem_init (void);
+extern void expamem_reset (void);
+
+extern uae_u32 gfxmem_start;
+extern uae_u8 *gfxmemory;
+extern uae_u32 gfxmem_mask;
+extern int address_space_24;
+
+/* Default memory access functions */
+
+extern int default_check(uaecptr addr, uae_u32 size) REGPARAM;
+extern uae_u8 *default_xlate(uaecptr addr) REGPARAM;
+
+#define bankindex(addr) (((uaecptr)(addr)) >> 16)
+
+#ifdef SAVE_MEMORY_BANKS
+extern addrbank *mem_banks[65536];
+#define get_mem_bank(addr) (*mem_banks[bankindex(addr)])
+#define put_mem_bank(addr, b) (mem_banks[bankindex(addr)] = (b))
+#else
+extern addrbank mem_banks[65536];
+#define get_mem_bank(addr) (mem_banks[bankindex(addr)])
+#define put_mem_bank(addr, b) (mem_banks[bankindex(addr)] = *(b))
+#endif
+
+extern void memory_init(void);
+extern void map_banks(addrbank *bank, int first, int count);
+
+#ifndef NO_INLINE_MEMORY_ACCESS
+
+#define longget(addr) (call_mem_get_func(get_mem_bank(addr).lget, addr))
+#define wordget(addr) (call_mem_get_func(get_mem_bank(addr).wget, addr))
+#define byteget(addr) (call_mem_get_func(get_mem_bank(addr).bget, addr))
+#define longput(addr,l) (call_mem_put_func(get_mem_bank(addr).lput, addr, l))
+#define wordput(addr,w) (call_mem_put_func(get_mem_bank(addr).wput, addr, w))
+#define byteput(addr,b) (call_mem_put_func(get_mem_bank(addr).bput, addr, b))
+
+#else
+
+extern uae_u32 alongget(uaecptr addr);
+extern uae_u32 awordget(uaecptr addr);
+extern uae_u32 longget(uaecptr addr);
+extern uae_u32 wordget(uaecptr addr);
+extern uae_u32 byteget(uaecptr addr);
+extern void longput(uaecptr addr, uae_u32 l);
+extern void wordput(uaecptr addr, uae_u32 w);
+extern void byteput(uaecptr addr, uae_u32 b);
+
+#endif
+
+#ifndef MD_HAVE_MEM_1_FUNCS
+
+#define longget_1 longget
+#define wordget_1 wordget
+#define byteget_1 byteget
+#define longput_1 longput
+#define wordput_1 wordput
+#define byteput_1 byteput
+
+#endif
+
+static inline uae_u32 get_long(uaecptr addr)
+{
+ return longget_1(addr);
+}
+static inline uae_u32 get_word(uaecptr addr)
+{
+ return wordget_1(addr);
+}
+static inline uae_u32 get_byte(uaecptr addr)
+{
+ return byteget_1(addr);
+}
+static inline void put_long(uaecptr addr, uae_u32 l)
+{
+ longput_1(addr, l);
+}
+static inline void put_word(uaecptr addr, uae_u32 w)
+{
+ wordput_1(addr, w);
+}
+static inline void put_byte(uaecptr addr, uae_u32 b)
+{
+ byteput_1(addr, b);
+}
+
+static inline uae_u8 *get_real_address(uaecptr addr)
+{
+ return get_mem_bank(addr).xlateaddr(addr);
+}
+
+static inline int valid_address(uaecptr addr, uae_u32 size)
+{
+ return get_mem_bank(addr).check(addr, size);
+}
diff --git a/plugins/uade2/uade-2.13/src/include/newcpu.h b/plugins/uade2/uade-2.13/src/include/newcpu.h
new file mode 100644
index 00000000..84732f10
--- /dev/null
+++ b/plugins/uade2/uade-2.13/src/include/newcpu.h
@@ -0,0 +1,275 @@
+ /*
+ * UAE - The Un*x Amiga Emulator
+ *
+ * MC68000 emulation
+ *
+ * Copyright 1995 Bernd Schmidt
+ */
+
+#include <machdep/m68k.h>
+
+void m68k_run_1 (void);
+
+#ifndef SET_CFLG
+
+#define SET_CFLG(x) (CFLG = (x))
+#define SET_NFLG(x) (NFLG = (x))
+#define SET_VFLG(x) (VFLG = (x))
+#define SET_ZFLG(x) (ZFLG = (x))
+#define SET_XFLG(x) (XFLG = (x))
+
+#define GET_CFLG CFLG
+#define GET_NFLG NFLG
+#define GET_VFLG VFLG
+#define GET_ZFLG ZFLG
+#define GET_XFLG XFLG
+
+#define CLEAR_CZNV do { \
+ SET_CFLG (0); \
+ SET_ZFLG (0); \
+ SET_NFLG (0); \
+ SET_VFLG (0); \
+while (0)
+
+#define COPY_CARRY (SET_XFLG (GET_CFLG))
+#endif
+
+extern int areg_byteinc[];
+extern int imm8_table[];
+
+extern int movem_index1[256];
+extern int movem_index2[256];
+extern int movem_next[256];
+
+extern int fpp_movem_index1[256];
+extern int fpp_movem_index2[256];
+extern int fpp_movem_next[256];
+
+extern int broken_in;
+
+typedef unsigned long cpuop_func (uae_u32) REGPARAM;
+
+struct cputbl {
+ cpuop_func *handler;
+ int specific;
+ uae_u16 opcode;
+};
+
+extern unsigned long op_illg (uae_u32) REGPARAM;
+
+typedef char flagtype;
+
+extern struct regstruct
+{
+ uae_u32 regs[16];
+ uaecptr usp,isp,msp;
+ uae_u16 sr;
+ flagtype t1;
+ flagtype t0;
+ flagtype s;
+ flagtype m;
+ flagtype x;
+ flagtype stopped;
+ int intmask;
+
+ uae_u32 pc;
+ uae_u8 *pc_p;
+ uae_u8 *pc_oldp;
+
+ uae_u32 vbr,sfc,dfc;
+
+ double fp[8];
+ uae_u32 fpcr,fpsr,fpiar;
+
+ uae_u32 spcflags;
+ uae_u32 kick_mask;
+
+ /* Fellow sources say this is 4 longwords. That's impossible. It needs
+ * to be at least a longword. The HRM has some cryptic comment about two
+ * instructions being on the same longword boundary.
+ * The way this is implemented now seems like a good compromise.
+ */
+ uae_u32 prefetch;
+} regs, lastint_regs;
+
+#define m68k_dreg(r,num) ((r).regs[(num)])
+#define m68k_areg(r,num) (((r).regs + 8)[(num)])
+
+#define get_ibyte(o) do_get_mem_byte((uae_u8 *)(regs.pc_p + (o) + 1))
+#define get_iword(o) do_get_mem_word((uae_u16 *)(regs.pc_p + (o)))
+#define get_ilong(o) do_get_mem_long((uae_u32 *)(regs.pc_p + (o)))
+
+#ifdef HAVE_GET_WORD_UNSWAPPED
+#define GET_OPCODE (do_get_mem_word_unswapped (regs.pc_p))
+#else
+#define GET_OPCODE (get_iword (0))
+#endif
+
+static inline uae_u32 get_ibyte_prefetch (uae_s32 o)
+{
+ if (o > 3 || o < 0)
+ return do_get_mem_byte((uae_u8 *)(regs.pc_p + o + 1));
+
+ return do_get_mem_byte((uae_u8 *)(((uae_u8 *)&regs.prefetch) + o + 1));
+}
+static inline uae_u32 get_iword_prefetch (uae_s32 o)
+{
+ if (o > 3 || o < 0)
+ return do_get_mem_word((uae_u16 *)(regs.pc_p + o));
+
+ return do_get_mem_word((uae_u16 *)(((uae_u8 *)&regs.prefetch) + o));
+}
+static inline uae_u32 get_ilong_prefetch (uae_s32 o)
+{
+ union {
+ uae_u32 *u32;
+ uae_u16 *u16;
+ } prefetch_u;
+
+ if (o > 3 || o < 0)
+ return do_get_mem_long((uae_u32 *)(regs.pc_p + o));
+ if (o == 0)
+ return do_get_mem_long(&regs.prefetch);
+
+ prefetch_u.u32 = &regs.prefetch;
+
+ return (do_get_mem_word (prefetch_u.u16 + 1) << 16) | do_get_mem_word ((uae_u16 *)(regs.pc_p + 4));
+}
+
+#define m68k_incpc(o) (regs.pc_p += (o))
+
+static inline void fill_prefetch_0 (void)
+{
+ uae_u32 r;
+#ifdef UNALIGNED_PROFITABLE
+ r = *(uae_u32 *)regs.pc_p;
+ regs.prefetch = r;
+#else
+ r = do_get_mem_long ((uae_u32 *)regs.pc_p);
+ do_put_mem_long (&regs.prefetch, r);
+#endif
+}
+
+#if 0
+static inline void fill_prefetch_2 (void)
+{
+ uae_u32 r = do_get_mem_long (&regs.prefetch) << 16;
+ uae_u32 r2 = do_get_mem_word (((uae_u16 *)regs.pc_p) + 1);
+ r |= r2;
+ do_put_mem_long (&regs.prefetch, r);
+}
+#else
+#define fill_prefetch_2 fill_prefetch_0
+#endif
+
+/* These are only used by the 68020/68881 code, and therefore don't
+ * need to handle prefetch. */
+static inline uae_u32 next_ibyte (void)
+{
+ uae_u32 r = get_ibyte (0);
+ m68k_incpc (2);
+ return r;
+}
+
+static inline uae_u32 next_iword (void)
+{
+ uae_u32 r = get_iword (0);
+ m68k_incpc (2);
+ return r;
+}
+
+static inline uae_u32 next_ilong (void)
+{
+ uae_u32 r = get_ilong (0);
+ m68k_incpc (4);
+ return r;
+}
+
+#if !defined USE_COMPILER
+static inline void m68k_setpc (uaecptr newpc)
+{
+ regs.pc_p = regs.pc_oldp = get_real_address(newpc);
+ regs.pc = newpc;
+}
+#else
+extern void m68k_setpc (uaecptr newpc);
+#endif
+
+static inline uaecptr m68k_getpc (void)
+{
+ return regs.pc + ((char *)regs.pc_p - (char *)regs.pc_oldp);
+}
+
+static inline uaecptr m68k_getpc_p (uae_u8 *p)
+{
+ return regs.pc + ((char *)p - (char *)regs.pc_oldp);
+}
+
+#ifdef USE_COMPILER
+extern void m68k_setpc_fast (uaecptr newpc);
+extern void m68k_setpc_bcc (uaecptr newpc);
+extern void m68k_setpc_rte (uaecptr newpc);
+#else
+#define m68k_setpc_fast m68k_setpc
+#define m68k_setpc_bcc m68k_setpc
+#define m68k_setpc_rte m68k_setpc
+#endif
+
+static inline void m68k_setstopped (int stop)
+{
+ regs.stopped = stop;
+ if (stop)
+ regs.spcflags |= SPCFLAG_STOP;
+}
+
+extern uae_u32 get_disp_ea_020 (uae_u32 base, uae_u32 dp);
+extern uae_u32 get_disp_ea_000 (uae_u32 base, uae_u32 dp);
+
+extern uae_s32 ShowEA (int reg, amodes mode, wordsizes size, char *buf);
+
+extern void MakeSR (void);
+extern void MakeFromSR (void);
+extern void Exception (int, uaecptr);
+extern void dump_counts (void);
+extern void m68k_move2c (int, uae_u32 *);
+extern void m68k_movec2 (int, uae_u32 *);
+extern void m68k_divl (uae_u32, uae_u32, uae_u16, uaecptr);
+extern void m68k_mull (uae_u32, uae_u32, uae_u16);
+extern void init_m68k (void);
+extern void m68k_go (void);
+extern void m68k_dumpstate (uaecptr *);
+extern void m68k_disasm (uaecptr, uaecptr *, int);
+extern void m68k_reset (void);
+
+extern void mmu_op (uae_u32, uae_u16);
+
+extern void fpp_opp (uae_u32, uae_u16);
+extern void fdbcc_opp (uae_u32, uae_u16);
+extern void fscc_opp (uae_u32, uae_u16);
+extern void ftrapcc_opp (uae_u32,uaecptr);
+extern void fbcc_opp (uae_u32, uaecptr, uae_u32);
+extern void fsave_opp (uae_u32);
+extern void frestore_opp (uae_u32);
+
+/* Opcode of faulting instruction */
+extern uae_u16 last_op_for_exception_3;
+/* PC at fault time */
+extern uaecptr last_addr_for_exception_3;
+/* Address that generated the exception */
+extern uaecptr last_fault_for_exception_3;
+
+#define CPU_OP_NAME(a) op ## a
+
+/* 68020 + 68881 */
+extern struct cputbl op_smalltbl_0[];
+/* 68020 */
+extern struct cputbl op_smalltbl_1[];
+/* 68010 */
+extern struct cputbl op_smalltbl_2[];
+/* 68000 */
+extern struct cputbl op_smalltbl_3[];
+/* 68000 slow but compatible. */
+extern struct cputbl op_smalltbl_4[];
+
+extern cpuop_func *cpufunctbl[65536];
+
diff --git a/plugins/uade2/uade-2.13/src/include/options.h b/plugins/uade2/uade-2.13/src/include/options.h
new file mode 100644
index 00000000..2ec4befc
--- /dev/null
+++ b/plugins/uade2/uade-2.13/src/include/options.h
@@ -0,0 +1,262 @@
+ /*
+ * UAE - The Un*x Amiga Emulator
+ *
+ * Stuff
+ *
+ * Copyright 1995, 1996 Ed Hanway
+ * Copyright 1995-98 Bernd Schmidt
+ */
+
+#define UAEMAJOR 0
+#define UAEMINOR 8
+#define UAESUBREV 9
+
+typedef enum { KBD_LANG_US, KBD_LANG_DE, KBD_LANG_SE, KBD_LANG_FR, KBD_LANG_IT, KBD_LANG_ES } KbdLang;
+
+extern long int version;
+
+struct uaedev_mount_info;
+
+struct strlist {
+ struct strlist *next;
+ char *str;
+};
+
+struct uae_prefs {
+ struct strlist *unknown_lines;
+
+ char description[256];
+
+ int illegal_mem;
+ int no_xhair;
+ int use_serial;
+ int serial_demand;
+ int parallel_demand;
+ int automount_uaedev;
+ int use_gfxlib;
+ int socket_emu;
+
+ int start_debugger;
+ int start_gui;
+
+ int jport0;
+ int jport1;
+ KbdLang keyboard_lang;
+ int allow_save;
+ int emul_accuracy;
+ int test_drawing_speed;
+
+ int produce_sound;
+ int stereo;
+ int sound_bits;
+ int sound_freq;
+ int sound_minbsiz;
+ int sound_maxbsiz;
+ int sound_pri_time;
+ int sound_pri_cutoff;
+ int sound_interpol;
+
+ int gfx_framerate;
+ int gfx_width;
+ int gfx_height;
+ int gfx_lores;
+ int gfx_linedbl;
+ int gfx_correct_aspect;
+ int gfx_afullscreen;
+ int gfx_pfullscreen;
+ int gfx_xcenter;
+ int gfx_ycenter;
+ int color_mode;
+
+ int blits_32bit_enabled;
+ int immediate_blits;
+ unsigned int chipset_mask;
+ int ntscmode;
+
+ char df[4][256];
+ char romfile[256];
+ char keyfile[256];
+ char prtname[256];
+
+ char path_floppy[256];
+ char path_hardfile[256];
+ char path_rom[256];
+
+ int m68k_speed;
+ int cpu_level;
+ int cpu_compatible;
+ int address_space_24;
+
+ uae_u32 z3fastmem_size;
+ uae_u32 fastmem_size;
+ uae_u32 chipmem_size;
+ uae_u32 bogomem_size;
+ uae_u32 a3000mem_size;
+ uae_u32 gfxmem_size;
+
+ struct uaedev_mount_info *mountinfo;
+
+ /* Target specific options */
+ int x11_use_low_bandwidth;
+ int x11_use_mitshm;
+ int x11_use_dgamode;
+ int x11_hide_cursor;
+ int svga_no_linear;
+ int win32_middle_mouse;
+ int win32_sound_style;
+ int win32_sound_tweak;
+ int win32_logfile;
+ int win32_iconified_nospeed;
+ int win32_iconified_nosound;
+};
+
+extern void save_options (FILE *, struct uae_prefs *);
+
+extern void default_prefs (struct uae_prefs *);
+extern void discard_prefs (struct uae_prefs *);
+
+extern int cfgfile_yesno (char *option, char *value, char *name, int *location);
+extern int cfgfile_intval (char *option, char *value, char *name, int *location, int scale);
+extern int cfgfile_strval (char *option, char *value, char *name, int *location, const char *table[], int more);
+extern int cfgfile_string (char *option, char *value, char *name, char *location, int maxsz);
+extern char *cfgfile_subst_path (const char *path, const char *subst, const char *file);
+
+extern int target_parse_option (struct uae_prefs *, char *option, char *value);
+extern void target_save_options (FILE *, struct uae_prefs *);
+
+extern int cfgfile_load (struct uae_prefs *, const char *filename);
+extern int cfgfile_save (struct uae_prefs *, const char *filename);
+extern void cfgfile_parse_line (struct uae_prefs *p, char *);
+extern int cfgfile_parse_option (struct uae_prefs *p, char *option, char *value);
+extern int cfgfile_get_description (const char *filename, char *description);
+extern void cfgfile_show_usage (void);
+
+extern void fixup_prefs_dimensions (struct uae_prefs *prefs);
+
+extern void check_prefs_changed_custom (void);
+extern void check_prefs_changed_cpu (void);
+extern int check_prefs_changed_gfx (void);
+
+#define JSEM_DECODEVAL(n,v) ((n) == 0 ? (v)->jport0 : (v)->jport1)
+/* Determine how port n is configured */
+#define JSEM_ISJOY0(n,v) (JSEM_DECODEVAL(n,v) == 0)
+#define JSEM_ISJOY1(n,v) (JSEM_DECODEVAL(n,v) == 1)
+#define JSEM_ISMOUSE(n,v) (JSEM_DECODEVAL(n,v) == 2)
+#define JSEM_ISNUMPAD(n,v) (JSEM_DECODEVAL(n,v) == 3)
+#define JSEM_ISCURSOR(n,v) (JSEM_DECODEVAL(n,v) == 4)
+#define JSEM_ISSOMEWHEREELSE(n,v) (JSEM_DECODEVAL(n,v) == 5)
+extern const char *gameport_state (int n);
+
+extern struct uae_prefs currprefs, changed_prefs;
+
+#if __GNUC__ - 1 > 1 || __GNUC_MINOR__ - 1 > 6
+extern void write_log (const char *, ...) __attribute__ ((format (printf, 1, 2)));
+#else
+extern void write_log (const char *, ...);
+#endif
+
+extern void machdep_init (void);
+
+/* AIX doesn't think it is Unix. Neither do I. */
+#if defined(_ALL_SOURCE) || defined(_AIX)
+#undef __unix
+#define __unix
+#endif
+
+extern char romfile[], keyfile[], prtname[], sername[];
+
+extern int cloanto_rom;
+
+#define MAX_COLOR_MODES 5
+
+extern int fast_memcmp(const void *foo, const void *bar, int len);
+extern int memcmpy(void *foo, const void *bar, int len);
+
+/*
+ * You can specify numbers from 0 to 5 here. It is possible that higher
+ * numbers will make the CPU emulation slightly faster, but if the setting
+ * is too high, you will run out of memory while compiling.
+ * Best to leave this as it is.
+ */
+#define CPU_EMU_SIZE 0
+
+/* #define NEED_TO_DEBUG_BADLY */
+
+#if !defined(USER_PROGRAMS_BEHAVE)
+#define USER_PROGRAMS_BEHAVE 0
+#endif
+
+/* Some memsets which know that they can safely overwrite some more memory
+ * at both ends and use that knowledge to align the pointers. */
+
+#define QUADRUPLIFY(c) (((c) | ((c) << 8)) | (((c) | ((c) << 8)) << 16))
+
+/* When you call this routine, bear in mind that it rounds the bounds and
+ * may need some padding for the array. */
+
+#define fuzzy_memset(p, c, o, l) fuzzy_memset_1 ((p), QUADRUPLIFY (c), (o) & ~3, ((l) + 4) >> 2)
+static inline void fuzzy_memset_1 (void *p, uae_u32 c, int offset, int len)
+{
+ uae_u32 *p2 = (uae_u32 *)((char *)p + offset);
+ int a = len & 7;
+ len >>= 3;
+ switch (a) {
+ case 7: p2--; goto l1;
+ case 6: p2-=2; goto l2;
+ case 5: p2-=3; goto l3;
+ case 4: p2-=4; goto l4;
+ case 3: p2-=5; goto l5;
+ case 2: p2-=6; goto l6;
+ case 1: p2-=7; goto l7;
+ case 0: if (!--len) return; break;
+ }
+
+ for (;;) {
+ p2[0] = c;
+ l1:
+ p2[1] = c;
+ l2:
+ p2[2] = c;
+ l3:
+ p2[3] = c;
+ l4:
+ p2[4] = c;
+ l5:
+ p2[5] = c;
+ l6:
+ p2[6] = c;
+ l7:
+ p2[7] = c;
+
+ if (!len)
+ break;
+ len--;
+ p2 += 8;
+ }
+}
+
+/* This one knows it will never be asked to clear more than 32 bytes. Make sure you call this with a
+ constant for the length. */
+#define fuzzy_memset_le32(p, c, o, l) fuzzy_memset_le32_1 ((p), QUADRUPLIFY (c), (o) & ~3, ((l) + 7) >> 2)
+static inline void fuzzy_memset_le32_1 (void *p, uae_u32 c, int offset, int len)
+{
+ uae_u32 *p2 = (uae_u32 *)((char *)p + offset);
+
+ switch (len) {
+ case 9: p2[0] = c; p2[1] = c; p2[2] = c; p2[3] = c; p2[4] = c; p2[5] = c; p2[6] = c; p2[7] = c; p2[8] = c; break;
+ case 8: p2[0] = c; p2[1] = c; p2[2] = c; p2[3] = c; p2[4] = c; p2[5] = c; p2[6] = c; p2[7] = c; break;
+ case 7: p2[0] = c; p2[1] = c; p2[2] = c; p2[3] = c; p2[4] = c; p2[5] = c; p2[6] = c; break;
+ case 6: p2[0] = c; p2[1] = c; p2[2] = c; p2[3] = c; p2[4] = c; p2[5] = c; break;
+ case 5: p2[0] = c; p2[1] = c; p2[2] = c; p2[3] = c; p2[4] = c; break;
+ case 4: p2[0] = c; p2[1] = c; p2[2] = c; p2[3] = c; break;
+ case 3: p2[0] = c; p2[1] = c; p2[2] = c; break;
+ case 2: p2[0] = c; p2[1] = c; break;
+ case 1: p2[0] = c; break;
+ case 0: break;
+ default: printf("Hit the programmer.\n"); break;
+ }
+}
+
+#if defined(AMIGA) && defined(__GNUC__)
+/* #include "od-amiga/amiga-kludges.h" */
+#endif
diff --git a/plugins/uade2/uade-2.13/src/include/osemu.h b/plugins/uade2/uade-2.13/src/include/osemu.h
new file mode 100644
index 00000000..817c5c9b
--- /dev/null
+++ b/plugins/uade2/uade-2.13/src/include/osemu.h
@@ -0,0 +1,19 @@
+ /*
+ * UAE - The Un*x Amiga Emulator
+ *
+ * OS emulation prototypes
+ *
+ * Copyright 1996 Bernd Schmidt
+ */
+
+static inline char *raddr(uaecptr p)
+{
+ return p == 0 ? NULL : (char *)get_real_address(p);
+}
+
+extern void gfxlib_install(void);
+
+/* graphics.library */
+
+extern int GFX_WritePixel(uaecptr rp, int x, int y);
+
diff --git a/plugins/uade2/uade-2.13/src/include/readcpu.h b/plugins/uade2/uade-2.13/src/include/readcpu.h
new file mode 100644
index 00000000..62a81c6a
--- /dev/null
+++ b/plugins/uade2/uade-2.13/src/include/readcpu.h
@@ -0,0 +1,99 @@
+ENUMDECL {
+ Dreg, Areg, Aind, Aipi, Apdi, Ad16, Ad8r,
+ absw, absl, PC16, PC8r, imm, imm0, imm1, imm2, immi, am_unknown, am_illg
+} ENUMNAME (amodes);
+
+ENUMDECL {
+ i_ILLG,
+
+ i_OR, i_AND, i_EOR, i_ORSR, i_ANDSR, i_EORSR,
+ i_SUB, i_SUBA, i_SUBX, i_SBCD,
+ i_ADD, i_ADDA, i_ADDX, i_ABCD,
+ i_NEG, i_NEGX, i_NBCD, i_CLR, i_NOT, i_TST,
+ i_BTST, i_BCHG, i_BCLR, i_BSET,
+ i_CMP, i_CMPM, i_CMPA,
+ i_MVPRM, i_MVPMR, i_MOVE, i_MOVEA, i_MVSR2, i_MV2SR,
+ i_SWAP, i_EXG, i_EXT, i_MVMEL, i_MVMLE,
+ i_TRAP, i_MVR2USP, i_MVUSP2R, i_RESET, i_NOP, i_STOP, i_RTE, i_RTD,
+ i_LINK, i_UNLK,
+ i_RTS, i_TRAPV, i_RTR,
+ i_JSR, i_JMP, i_BSR, i_Bcc,
+ i_LEA, i_PEA, i_DBcc, i_Scc,
+ i_DIVU, i_DIVS, i_MULU, i_MULS,
+ i_ASR, i_ASL, i_LSR, i_LSL, i_ROL, i_ROR, i_ROXL, i_ROXR,
+ i_ASRW, i_ASLW, i_LSRW, i_LSLW, i_ROLW, i_RORW, i_ROXLW, i_ROXRW,
+ i_CHK,i_CHK2,
+ i_MOVEC2, i_MOVE2C, i_CAS, i_CAS2, i_DIVL, i_MULL,
+ i_BFTST,i_BFEXTU,i_BFCHG,i_BFEXTS,i_BFCLR,i_BFFFO,i_BFSET,i_BFINS,
+ i_PACK, i_UNPK, i_TAS, i_BKPT, i_CALLM, i_RTM, i_TRAPcc, i_MOVES,
+ i_FPP, i_FDBcc, i_FScc, i_FTRAPcc, i_FBcc, i_FSAVE, i_FRESTORE,
+ i_MMUOP
+} ENUMNAME (instrmnem);
+
+extern struct mnemolookup {
+ instrmnem mnemo;
+ const char *name;
+} lookuptab[];
+
+ENUMDECL {
+ sz_byte, sz_word, sz_long
+} ENUMNAME (wordsizes);
+
+ENUMDECL {
+ fa_set, fa_unset, fa_zero, fa_one, fa_dontcare, fa_unknown, fa_isjmp
+} ENUMNAME (flagaffect);
+
+ENUMDECL {
+ fu_used, fu_unused, fu_maybecc, fu_unknown, fu_isjmp
+} ENUMNAME (flaguse);
+
+ENUMDECL {
+ bit0, bit1, bitc, bitC, bitf, biti, bitI, bitj, bitJ, bitk, bitK,
+ bits, bitS, bitd, bitD, bitr, bitR, bitz, lastbit
+} ENUMNAME (bitvals);
+
+struct instr_def {
+ unsigned int bits;
+ int n_variable;
+ char bitpos[16];
+ unsigned int mask;
+ int cpulevel;
+ int plevel;
+ struct {
+ unsigned int flaguse:3;
+ unsigned int flagset:3;
+ } flaginfo[5];
+ unsigned char sduse;
+ const char *opcstr;
+};
+
+extern struct instr_def defs68k[];
+extern int n_defs68k;
+
+extern struct instr {
+ long int handler;
+ unsigned char dreg;
+ unsigned char sreg;
+ signed char dpos;
+ signed char spos;
+ unsigned char sduse;
+ int flagdead:8, flaglive:8;
+ unsigned int mnemo:8;
+ unsigned int cc:4;
+ unsigned int plev:2;
+ unsigned int size:2;
+ unsigned int smode:5;
+ unsigned int stype:3;
+ unsigned int dmode:5;
+ unsigned int suse:1;
+ unsigned int duse:1;
+ unsigned int unused1:1;
+ unsigned int clev:3;
+ unsigned int unused2:5;
+} *table68k;
+
+extern void read_table68k (void);
+extern void do_merges (void);
+extern int get_no_mismatches (void);
+extern int nr_cpuop_funcs;
+
diff --git a/plugins/uade2/uade-2.13/src/include/sinctable.h b/plugins/uade2/uade-2.13/src/include/sinctable.h
new file mode 100644
index 00000000..56fb62d7
--- /dev/null
+++ b/plugins/uade2/uade-2.13/src/include/sinctable.h
@@ -0,0 +1,7 @@
+#ifndef _SINCTABLE_H_
+#define _SINCTABLE_H_
+
+#define SINC_QUEUE_MAX_AGE 2048
+extern const int winsinc_integral[5][SINC_QUEUE_MAX_AGE];
+
+#endif
diff --git a/plugins/uade2/uade-2.13/src/include/sysdeps.h b/plugins/uade2/uade-2.13/src/include/sysdeps.h
new file mode 100644
index 00000000..5d407b2d
--- /dev/null
+++ b/plugins/uade2/uade-2.13/src/include/sysdeps.h
@@ -0,0 +1,347 @@
+ /*
+ * UAE - The Un*x Amiga Emulator
+ *
+ * Try to include the right system headers and get other system-specific
+ * stuff right & other collected kludges.
+ *
+ * If you think about modifying this, think twice. Some systems rely on
+ * the exact order of the #include statements. That's also the reason
+ * why everything gets included unconditionally regardless of whether
+ * it's actually needed by the .c file.
+ *
+ * Copyright 1996, 1997 Bernd Schmidt
+ */
+
+/* MODIF PMO */
+#ifndef _H_SYSDEPS
+#define _H_SYSDEPS
+/* ENDOF MODIF PMO */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <assert.h>
+#include <limits.h>
+
+#ifndef __STDC__
+#error "Your compiler is not ANSI. Get a real one."
+#endif
+
+#include <stdarg.h>
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#ifdef HAVE_VALUES_H
+#include <values.h>
+#endif
+
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+#ifdef HAVE_UTIME_H
+#include <utime.h>
+#endif
+
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else
+# if HAVE_SYS_TIME_H
+# include <sys/time.h>
+# else
+# include <time.h>
+# endif
+#endif
+
+#if HAVE_DIRENT_H
+# include <dirent.h>
+#else
+# define dirent direct
+# if HAVE_SYS_NDIR_H
+# include <sys/ndir.h>
+# endif
+# if HAVE_SYS_DIR_H
+# include <sys/dir.h>
+# endif
+# if HAVE_NDIR_H
+# include <ndir.h>
+# endif
+#endif
+
+#ifdef HAVE_SYS_UTIME_H
+# include <sys/utime.h>
+#endif
+
+#include <errno.h>
+#include <assert.h>
+
+#if EEXIST == ENOTEMPTY
+#define BROKEN_OS_PROBABLY_AIX
+#endif
+
+#ifdef __NeXT__
+#define S_IRUSR S_IREAD
+#define S_IWUSR S_IWRITE
+#define S_IXUSR S_IEXEC
+#define S_ISDIR(val) (S_IFDIR & val)
+struct utimbuf
+{
+ time_t actime;
+ time_t modtime;
+};
+#endif
+
+#define REGPARAM2
+
+#ifdef __DOS__
+#include <pc.h>
+#include <io.h>
+#endif
+
+/* MODIF PMO */
+/* WIN32/UNIX compatibility */
+#ifdef WINDOWS_VCPP
+ #define COMP_SEPARATOR '\\'
+ #define COMP_S_SEPARATOR "\\"
+#else
+ #define COMP_SEPARATOR '/'
+ #define COMP_S_SEPARATOR "/"
+#endif
+/* ENDOF MODIF PMO */
+
+/* Acorn specific stuff */
+#ifdef ACORN
+
+#define S_IRUSR S_IREAD
+#define S_IWUSR S_IWRITE
+#define S_IXUSR S_IEXEC
+
+#define strcasecmp stricmp
+
+#endif
+
+#ifndef L_tmpnam
+#define L_tmpnam 128 /* ought to be safe */
+#endif
+
+/* If char has more then 8 bits, good night. */
+typedef unsigned char uae_u8;
+typedef signed char uae_s8;
+
+typedef struct { uae_u8 RGB[3]; } RGB;
+
+#if SIZEOF_SHORT == 2
+typedef unsigned short uae_u16;
+typedef short uae_s16;
+#elif SIZEOF_INT == 2
+typedef unsigned int uae_u16;
+typedef int uae_s16;
+#else
+#error No 2 byte type, you lose.
+#endif
+
+#if SIZEOF_INT == 4
+typedef unsigned int uae_u32;
+typedef int uae_s32;
+#elif SIZEOF_LONG == 4
+typedef unsigned long uae_u32;
+typedef long uae_s32;
+#else
+#error No 4 byte type, you lose.
+#endif
+
+typedef uae_u32 uaecptr;
+
+#undef uae_s64
+#undef uae_u64
+
+#if SIZEOF_LONG_LONG == 8
+#define uae_s64 long long
+#define uae_u64 long long
+#define VAL64(a) (a ## LL)
+#define UVAL64(a) (a ## uLL)
+#elif SIZEOF___INT64 == 8
+#define uae_s64 __int64
+#define uae_u64 unsigned __int64
+#define VAL64(a) (a)
+#define UVAL64(a) (a)
+#elif SIZEOF_LONG == 8
+#define uae_s64 long;
+#define uae_u64 unsigned long;
+#define VAL64(a) (a ## l)
+#define UVAL64(a) (a ## ul)
+#endif
+
+#ifdef HAVE_STRDUP
+#define my_strdup strdup
+#else
+extern char *my_strdup (const char*s);
+#endif
+extern void *xmalloc(size_t);
+
+/* We can only rely on GNU C getting enums right. Mickeysoft VSC++ is known
+ * to have problems, and it's likely that other compilers choke too. */
+#ifdef __GNUC__
+#define ENUMDECL typedef enum
+#define ENUMNAME(name) name
+#else
+#define ENUMDECL enum
+#define ENUMNAME(name) ; typedef int name
+#endif
+
+/*
+ * Porters to weird systems, look! This is the preferred way to get
+ * filesys.c (and other stuff) running on your system. Define the
+ * appropriate macros and implement wrappers in a machine-specific file.
+ *
+ * I guess the Mac port could use this (Ernesto?)
+ */
+
+#undef DONT_HAVE_POSIX
+#undef DONT_HAVE_REAL_POSIX /* define if open+delete doesn't do what it should */
+#undef DONT_HAVE_STDIO
+#undef DONT_HAVE_MALLOC
+
+#if defined _WIN32
+
+#if defined __WATCOMC__
+
+#define O_NDELAY 0
+#include <direct.h>
+#define dirent direct
+#define mkdir(a,b) mkdir(a)
+#define strcasecmp stricmp
+
+#elif defined __MINGW32__
+
+#define O_NDELAY 0
+#define mkdir(a,b) mkdir(a)
+
+#endif
+
+#endif /* _WIN32 */
+
+#ifdef DONT_HAVE_POSIX
+
+#define access posixemu_access
+extern int posixemu_access (const char *, int);
+#define open posixemu_open
+extern int posixemu_open (const char *, int, int);
+#define close posixemu_close
+extern void posixemu_close (int);
+#define read posixemu_read
+extern int posixemu_read (int, char *, int);
+#define write posixemu_write
+extern int posixemu_write (int, const char *, int);
+#undef lseek
+#define lseek posixemu_seek
+extern int posixemu_seek (int, int, int);
+#define stat(a,b) posixemu_stat ((a), (b))
+extern int posixemu_stat (const char *, STAT *);
+#define mkdir posixemu_mkdir
+extern int mkdir (const char *, int);
+#define rmdir posixemu_rmdir
+extern int posixemu_rmdir (const char *);
+#define unlink posixemu_unlink
+extern int posixemu_unlink (const char *);
+#define truncate posixemu_truncate
+extern int posixemu_truncate (const char *, long int);
+#define rename posixemu_rename
+extern int posixemu_rename (const char *, const char *);
+#define chmod posixemu_chmod
+extern int posixemu_chmod (const char *, int);
+#define tmpnam posixemu_tmpnam
+extern void posixemu_tmpnam (char *);
+#define utime posixemu_utime
+extern int posixemu_utime (const char *, struct utimbuf *);
+#define opendir posixemu_opendir
+extern DIR * posixemu_opendir (const char *);
+#define readdir posixemu_readdir
+extern struct dirent* readdir (DIR *);
+#define closedir posixemu_closedir
+extern void closedir (DIR *);
+
+/* This isn't the best place for this, but it fits reasonably well. The logic
+ * is that you probably don't have POSIX errnos if you don't have the above
+ * functions. */
+extern long dos_errno (void);
+
+#endif
+
+#ifdef DONT_HAVE_STDIO
+
+extern FILE *stdioemu_fopen (const char *, const char *);
+#define fopen(a,b) stdioemu_fopen(a, b)
+extern int stdioemu_fseek (FILE *, int, int);
+#define fseek(a,b,c) stdioemu_fseek(a, b, c)
+extern int stdioemu_fread (char *, int, int, FILE *);
+#define fread(a,b,c,d) stdioemu_fread(a, b, c, d)
+extern int stdioemu_fwrite (const char *, int, int, FILE *);
+#define fwrite(a,b,c,d) stdioemu_fwrite(a, b, c, d)
+extern int stdioemu_ftell (FILE *);
+#define ftell(a) stdioemu_ftell(a)
+extern int stdioemu_fclose (FILE *);
+#define fclose(a) stdioemu_fclose(a)
+
+#endif
+
+#ifdef DONT_HAVE_MALLOC
+
+#define malloc(a) mallocemu_malloc(a)
+extern void *mallocemu_malloc (int size);
+#define free(a) mallocemu_free(a)
+extern void mallocemu_free (void *ptr);
+
+#endif
+
+#ifdef X86_ASSEMBLY
+#define ASM_SYM_FOR_FUNC(a) __asm__(a)
+#else
+#define ASM_SYM_FOR_FUNC(a)
+#endif
+
+#if defined USE_COMPILER
+#undef NO_PREFETCH_BUFFER
+#undef NO_EXCEPTION_3
+#define NO_EXCEPTION_3
+#define NO_PREFETCH_BUFFER
+#endif
+
+#include "target.h"
+
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
+/* Every Amiga hardware clock cycle takes this many "virtual" cycles. This
+ used to be hardcoded as 1, but using higher values allows us to time some
+ stuff more precisely.
+ 512 is the official value from now on - it can't change, unless we want
+ _another_ config option "finegrain2_m68k_speed".
+
+ We define this value here rather than in events.h so that gencpu.c sees
+ it. */
+#define CYCLE_UNIT 512
+
+/* MODIF PMO */
+#endif
+
+/* ENDOF MODIF PMO */
+
diff --git a/plugins/uade2/uade-2.13/src/include/text_scope.h b/plugins/uade2/uade-2.13/src/include/text_scope.h
new file mode 100644
index 00000000..7bc9d206
--- /dev/null
+++ b/plugins/uade2/uade-2.13/src/include/text_scope.h
@@ -0,0 +1,21 @@
+#ifndef _TEXT_SCOPE_H_
+#define _TEXT_SCOPE_H_
+
+#include "uadeconfig.h"
+
+#ifdef UADE_CONFIG_TEXT_SCOPE
+#define TEXT_SCOPE(cycles, voice, e, value) \
+ do { \
+ if (use_text_scope) \
+ text_scope(cycles, voice, e, value); \
+ } while (0)
+#else
+#define TEXT_SCOPE(cycles, voice, e, value) do {} while (0)
+#endif
+
+enum PaulaEventType {PET_VOL, PET_PER, PET_DAT, PET_LEN, PET_LCH, PET_LCL};
+
+void text_scope(unsigned long cycles, int voice, enum PaulaEventType e,
+ int value);
+
+#endif
diff --git a/plugins/uade2/uade-2.13/src/include/uade.h b/plugins/uade2/uade-2.13/src/include/uade.h
new file mode 100644
index 00000000..91f590fe
--- /dev/null
+++ b/plugins/uade2/uade-2.13/src/include/uade.h
@@ -0,0 +1,43 @@
+#ifndef _UADE_MAIN_H_
+#define _UADE_MAIN_H_
+
+#include <limits.h>
+#include <stdlib.h>
+
+#include "uadeipc.h"
+
+struct uade_song {
+ char playername[PATH_MAX]; /* filename of eagleplayer */
+ char modulename[PATH_MAX]; /* filename of song */
+ char scorename[PATH_MAX]; /* filename of score file */
+
+ int min_subsong;
+ int max_subsong;
+ int cur_subsong;
+};
+
+
+void uade_change_subsong(int subs);
+void uade_check_sound_buffers(int bytes);
+void uade_send_debug(const char *fmt, ...);
+void uade_get_amiga_message(void);
+void uade_handle_r_state(void);
+void uade_option(int, char**); /* handles command line parameters */
+void uade_reset(void);
+void uade_send_amiga_message(int msgtype);
+void uade_set_automatic_song_end(int song_end_possible);
+void uade_set_ntsc(int usentsc);
+void uade_song_end(char *reason, int kill_it);
+void uade_swap_buffer_bytes(void *data, int bytes);
+
+extern int uade_audio_output;
+extern int uade_audio_skip;
+extern int uade_debug;
+extern int uade_local_sound;
+extern int uade_read_size;
+extern int uade_reboot;
+extern int uade_time_critical;
+
+extern struct uade_ipc uadeipc;
+
+#endif
diff --git a/plugins/uade2/uade-2.13/src/include/uadeconstants.h b/plugins/uade2/uade-2.13/src/include/uadeconstants.h
new file mode 100644
index 00000000..5a69953a
--- /dev/null
+++ b/plugins/uade2/uade-2.13/src/include/uadeconstants.h
@@ -0,0 +1,10 @@
+#ifndef _UADE_CONSTANTS_H_
+#define _UADE_CONSTANTS_H_
+
+/* You must not change anything */
+#define UADE_CHANNELS (2)
+#define UADE_DEFAULT_FREQUENCY (44100)
+#define UADE_BYTES_PER_SAMPLE (2)
+#define UADE_BYTES_PER_FRAME (UADE_CHANNELS * UADE_BYTES_PER_SAMPLE)
+
+#endif
diff --git a/plugins/uade2/uade-2.13/src/include/uadeipc.h b/plugins/uade2/uade-2.13/src/include/uadeipc.h
new file mode 100644
index 00000000..3bad980b
--- /dev/null
+++ b/plugins/uade2/uade-2.13/src/include/uadeipc.h
@@ -0,0 +1,77 @@
+#ifndef _UADEIPC_H_
+#define _UADEIPC_H_
+
+#include <stdlib.h>
+#include <stdint.h>
+
+#include "uadeutils.h"
+
+#define UADE_MAX_MESSAGE_SIZE (4096)
+
+enum uade_msgtype {
+ UADE_MSG_FIRST = 0,
+ UADE_COMMAND_ACTIVATE_DEBUGGER,
+ UADE_COMMAND_CHANGE_SUBSONG,
+ UADE_COMMAND_CONFIG,
+ UADE_COMMAND_SCORE,
+ UADE_COMMAND_PLAYER,
+ UADE_COMMAND_MODULE,
+ UADE_COMMAND_READ,
+ UADE_COMMAND_REBOOT,
+ UADE_COMMAND_SET_SUBSONG,
+ UADE_COMMAND_IGNORE_CHECK,
+ UADE_COMMAND_SONG_END_NOT_POSSIBLE,
+ UADE_COMMAND_SET_NTSC,
+ UADE_COMMAND_FILTER,
+ UADE_COMMAND_SET_FREQUENCY,
+ UADE_COMMAND_SET_PLAYER_OPTION,
+ UADE_COMMAND_SET_RESAMPLING_MODE,
+ UADE_COMMAND_SPEED_HACK,
+ UADE_COMMAND_TOKEN,
+ UADE_COMMAND_USE_TEXT_SCOPE,
+ UADE_REPLY_MSG,
+ UADE_REPLY_CANT_PLAY,
+ UADE_REPLY_CAN_PLAY,
+ UADE_REPLY_SONG_END,
+ UADE_REPLY_SUBSONG_INFO,
+ UADE_REPLY_PLAYERNAME,
+ UADE_REPLY_MODULENAME,
+ UADE_REPLY_FORMATNAME,
+ UADE_REPLY_DATA,
+ UADE_MSG_LAST
+};
+
+struct uade_msg {
+ uint32_t msgtype;
+ uint32_t size;
+ uint8_t data[0];
+} __attribute__((packed));
+
+enum uade_control_state {
+ UADE_INITIAL_STATE = 0,
+ UADE_R_STATE,
+ UADE_S_STATE
+};
+
+struct uade_ipc {
+ void *input;
+ void *output;
+ unsigned int inputbytes;
+ char inputbuffer[UADE_MAX_MESSAGE_SIZE];
+ enum uade_control_state state;
+};
+
+void uade_check_fix_string(struct uade_msg *um, size_t maxlen);
+int uade_parse_u32_message(uint32_t *u1, struct uade_msg *um);
+int uade_parse_two_u32s_message(uint32_t *u1, uint32_t *u2, struct uade_msg *um);
+int uade_receive_message(struct uade_msg *um, size_t maxbytes, struct uade_ipc *ipc);
+int uade_receive_short_message(enum uade_msgtype msgtype, struct uade_ipc *ipc);
+int uade_receive_string(char *s, enum uade_msgtype msgtype, size_t maxlen, struct uade_ipc *ipc);
+int uade_send_message(struct uade_msg *um, struct uade_ipc *ipc);
+int uade_send_short_message(enum uade_msgtype msgtype, struct uade_ipc *ipc);
+int uade_send_string(enum uade_msgtype msgtype, const char *str, struct uade_ipc *ipc);
+int uade_send_u32(enum uade_msgtype com, uint32_t u, struct uade_ipc *ipc);
+int uade_send_two_u32s(enum uade_msgtype com, uint32_t u1, uint32_t u2, struct uade_ipc *ipc);
+void uade_set_peer(struct uade_ipc *ipc, int peer_is_client, const char *input, const char *output);
+
+#endif
diff --git a/plugins/uade2/uade-2.13/src/include/uadeutils.h b/plugins/uade2/uade-2.13/src/include/uadeutils.h
new file mode 100644
index 00000000..fcd24233
--- /dev/null
+++ b/plugins/uade2/uade-2.13/src/include/uadeutils.h
@@ -0,0 +1,27 @@
+#ifndef _UADE_UTILS_H_
+#define _UADE_UTILS_H_
+
+#include <stdint.h>
+
+#define uade_error(fmt, args...) do { \
+ fprintf(stderr, "%s:%d: %s: " fmt, __FILE__, __LINE__, __func__, ## args); \
+ abort(); \
+ } while (0)
+
+static inline uint16_t read_be_u16(void *s)
+{
+ uint16_t x;
+ uint8_t *ptr = (uint8_t *) s;
+ x = ptr[1] + (ptr[0] << 8);
+ return x;
+}
+
+static inline uint32_t read_be_u32(void *s)
+{
+ uint32_t x;
+ uint8_t *ptr = (uint8_t *) s;
+ x = (ptr[0] << 24) + (ptr[1] << 16) + (ptr[2] << 8) + ptr[3];
+ return x;
+}
+
+#endif
diff --git a/plugins/uade2/uade-2.13/src/include/uae.h b/plugins/uade2/uade-2.13/src/include/uae.h
new file mode 100644
index 00000000..1ab9d75f
--- /dev/null
+++ b/plugins/uade2/uade-2.13/src/include/uae.h
@@ -0,0 +1,30 @@
+ /*
+ * UAE - The Un*x Amiga Emulator
+ *
+ * Prototypes for main.c
+ *
+ * Copyright 1996 Bernd Schmidt
+ */
+
+extern int uade_main (int argc, char **argv);
+extern void uae_quit (void);
+
+extern int quit_program;
+
+extern char warning_buffer[256];
+
+/* This structure is used to define menus. The val field can hold key
+ * shortcuts, or one of these special codes:
+ * -4: deleted entry, not displayed, not selectable, but does count in
+ * select value
+ * -3: end of table
+ * -2: line that is displayed, but not selectable
+ * -1: line that is selectable, but has no keyboard shortcut
+ * 0: Menu title
+ */
+struct bstring {
+ const char *data;
+ int val;
+};
+
+extern char *colormodes[];
diff --git a/plugins/uade2/uade-2.13/src/include/unixatomic.h b/plugins/uade2/uade-2.13/src/include/unixatomic.h
new file mode 100644
index 00000000..565cf864
--- /dev/null
+++ b/plugins/uade2/uade-2.13/src/include/unixatomic.h
@@ -0,0 +1,15 @@
+#ifndef _UNIXATOMIC_H_
+#define _UNIXATOMIC_H_
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+
+int atomic_close(int fd);
+int atomic_dup2(int oldfd, int newfd);
+size_t atomic_fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
+ssize_t atomic_read(int fd, const void *buf, size_t count);
+void *atomic_read_file(size_t *fs, const char *filename);
+ssize_t atomic_write(int fd, const void *buf, size_t count);
+
+#endif
diff --git a/plugins/uade2/uade-2.13/src/include/unixsupport.h b/plugins/uade2/uade-2.13/src/include/unixsupport.h
new file mode 100644
index 00000000..dc7d545e
--- /dev/null
+++ b/plugins/uade2/uade-2.13/src/include/unixsupport.h
@@ -0,0 +1,32 @@
+#ifndef _UADE_UNIXSUPPORT_H_
+#define _UADE_UNIXSUPPORT_H_
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <string.h>
+#include <errno.h>
+
+#include "uadeipc.h"
+
+
+#define die(fmt, args...) do { fprintf(stderr, "uade: " fmt, ## args); exit(1); } while(0)
+
+#define dieerror(fmt, args...) do { fprintf(stderr, "uade: " fmt ": %s\n", ## args, strerror(errno)); exit(1); } while(0)
+
+
+char *uade_dirname(char *dst, char *src, size_t maxlen);
+FILE *uade_open_amiga_file(char *aname, const char *playerdir);
+void uade_portable_initializations(void);
+void uade_arch_spawn(struct uade_ipc *ipc, pid_t *uadepid, const char *uadename);
+
+/* These read and write functions MUST read and write the full size_t amount
+ if they are able to. */
+ssize_t uade_ipc_read(void *f, const void *buf, size_t count);
+ssize_t uade_ipc_write(void *f, const void *buf, size_t count);
+void *uade_ipc_set_input(const char *input);
+void *uade_ipc_set_output(const char *output);
+
+char *windows_to_cygwin_path(const char *path);
+
+#endif
diff --git a/plugins/uade2/uade-2.13/src/ossupport.c b/plugins/uade2/uade-2.13/src/ossupport.c
new file mode 100644
index 00000000..6ecfb53e
--- /dev/null
+++ b/plugins/uade2/uade-2.13/src/ossupport.c
@@ -0,0 +1,48 @@
+#include "ossupport.h"
+
+#include "unixsupport.c"
+/* This module was written by Heikki Orsila <heikki.orsila@iki.fi> 2000-2005.
+ * No copyrights claimed, so this module is in Public Domain (only this
+ * code module). See OpenBSD man pages for strlcat and strlcpy
+ */
+
+#include <string.h>
+
+size_t strlcpy(char *dst, const char *src, size_t size)
+{
+ size_t slen = strlen(src);
+ if(slen < size)
+ strcpy(dst, src);
+ else if (size > 0) {
+ strncpy(dst, src, size-1);
+ dst[size-1] = 0;
+ }
+ return slen;
+}
+
+
+size_t strlcat(char *dst, const char *src, size_t size)
+{
+ size_t slen = strlen(src);
+ size_t dlen = 0;
+ while(dlen < size) {
+ if(dst[dlen] == 0)
+ break;
+ dlen++;
+ }
+
+ if(dlen == size) {
+ return slen + dlen;
+ }
+
+ if((dlen + slen) < size)
+ strcat(dst, src);
+ else {
+ int left = size - dlen - 1;
+ if(left > 0) {
+ strncat(dst, src, left);
+ }
+ dst[size-1] = 0;
+ }
+ return slen + dlen;
+}
diff --git a/plugins/uade2/uade-2.13/src/uadeipc.c b/plugins/uade2/uade-2.13/src/uadeipc.c
new file mode 100644
index 00000000..cba45ce0
--- /dev/null
+++ b/plugins/uade2/uade-2.13/src/uadeipc.c
@@ -0,0 +1,291 @@
+/* UADE
+ *
+ * Copyright 2005 Heikki Orsila <heikki.orsila@iki.fi>
+ *
+ * This source code module is dual licensed under GPL and Public Domain.
+ * Hence you may use _this_ module (not another code module) in any way you
+ * want in your projects.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+#include <assert.h>
+#include <string.h>
+
+#include "uadeipc.h"
+#include "ossupport.h"
+#include "sysincludes.h"
+
+
+static int valid_message(struct uade_msg *uc);
+
+
+void uade_check_fix_string(struct uade_msg *um, size_t maxlen)
+{
+ uint8_t *s = (uint8_t *) um->data;
+ size_t safelen;
+ if (um->size == 0) {
+ s[0] = 0;
+ fprintf(stderr, "zero string detected\n");
+ }
+ safelen = 0;
+ while (s[safelen] != 0 && safelen < maxlen)
+ safelen++;
+ if (safelen == maxlen) {
+ safelen--;
+ fprintf(stderr, "too long a string\n");
+ s[safelen] = 0;
+ }
+ if (um->size != (safelen + 1)) {
+ fprintf(stderr, "string size does not match\n");
+ um->size = safelen + 1;
+ s[safelen] = 0;
+ }
+}
+
+
+static ssize_t get_more(size_t bytes, struct uade_ipc *ipc)
+{
+ if (ipc->inputbytes < bytes) {
+ ssize_t s = uade_ipc_read(ipc->input, &ipc->inputbuffer[ipc->inputbytes], bytes - ipc->inputbytes);
+ if (s <= 0)
+ return -1;
+ ipc->inputbytes += s;
+ }
+ return 0;
+}
+
+
+static void copy_from_inputbuffer(void *dst, int bytes, struct uade_ipc *ipc)
+{
+ if (ipc->inputbytes < bytes) {
+ fprintf(stderr, "not enough bytes in input buffer\n");
+ exit(-1);
+ }
+ memcpy(dst, ipc->inputbuffer, bytes);
+ memmove(ipc->inputbuffer, &ipc->inputbuffer[bytes], ipc->inputbytes - bytes);
+ ipc->inputbytes -= bytes;
+}
+
+
+int uade_parse_u32_message(uint32_t *u1, struct uade_msg *um)
+{
+ if (um->size != 4)
+ return -1;
+ *u1 = ntohl(* (uint32_t *) um->data);
+ return 0;
+}
+
+
+int uade_parse_two_u32s_message(uint32_t *u1, uint32_t *u2,
+ struct uade_msg *um)
+{
+ if (um->size != 8)
+ return -1;
+ *u1 = ntohl(((uint32_t *) um->data)[0]);
+ *u2 = ntohl(((uint32_t *) um->data)[1]);
+ return 0;
+}
+
+
+int uade_receive_message(struct uade_msg *um, size_t maxbytes,
+ struct uade_ipc *ipc)
+{
+ size_t fullsize;
+
+ if (ipc->state == UADE_INITIAL_STATE) {
+ ipc->state = UADE_R_STATE;
+ } else if (ipc->state == UADE_S_STATE) {
+ fprintf(stderr, "protocol error: receiving in S state is forbidden\n");
+ return -1;
+ }
+
+ if (ipc->inputbytes < sizeof(*um)) {
+ if (get_more(sizeof(*um), ipc))
+ return 0;
+ }
+
+ copy_from_inputbuffer(um, sizeof(*um), ipc);
+
+ um->msgtype = ntohl(um->msgtype);
+ um->size = ntohl(um->size);
+
+ if (!valid_message(um))
+ return -1;
+
+ fullsize = um->size + sizeof(*um);
+ if (fullsize > maxbytes) {
+ fprintf(stderr, "too big a command: %zu\n", fullsize);
+ return -1;
+ }
+ if (ipc->inputbytes < um->size) {
+ if (get_more(um->size, ipc))
+ return -1;
+ }
+ copy_from_inputbuffer(&um->data, um->size, ipc);
+
+ if (um->msgtype == UADE_COMMAND_TOKEN)
+ ipc->state = UADE_S_STATE;
+
+ return 1;
+}
+
+
+int uade_receive_short_message(enum uade_msgtype msgtype, struct uade_ipc *ipc)
+{
+ struct uade_msg um;
+
+ if (ipc->state == UADE_INITIAL_STATE) {
+ ipc->state = UADE_R_STATE;
+ } else if (ipc->state == UADE_S_STATE) {
+ fprintf(stderr, "protocol error: receiving (%d) in S state is forbidden\n", msgtype);
+ return -1;
+ }
+
+ if (uade_receive_message(&um, sizeof(um), ipc) <= 0) {
+ fprintf(stderr, "can not receive short message: %d\n", msgtype);
+ return -1;
+ }
+ return (um.msgtype == msgtype) ? 0 : -1;
+}
+
+
+int uade_receive_string(char *s, enum uade_msgtype com,
+ size_t maxlen, struct uade_ipc *ipc)
+{
+ uint8_t commandbuf[UADE_MAX_MESSAGE_SIZE];
+ struct uade_msg *um = (struct uade_msg *) commandbuf;
+ int ret;
+
+ if (ipc->state == UADE_INITIAL_STATE) {
+ ipc->state = UADE_R_STATE;
+ } else if (ipc->state == UADE_S_STATE) {
+ fprintf(stderr, "protocol error: receiving in S state is forbidden\n");
+ return -1;
+ }
+
+ ret = uade_receive_message(um, UADE_MAX_MESSAGE_SIZE, ipc);
+ if (ret <= 0)
+ return ret;
+ if (um->msgtype != com)
+ return -1;
+ if (um->size == 0)
+ return -1;
+ if (um->size != (strlen((char *) um->data) + 1))
+ return -1;
+ strlcpy(s, (char *) um->data, maxlen);
+ return 1;
+}
+
+
+int uade_send_message(struct uade_msg *um, struct uade_ipc *ipc)
+{
+ uint32_t size = um->size;
+
+ if (ipc->state == UADE_INITIAL_STATE) {
+ ipc->state = UADE_S_STATE;
+ } else if (ipc->state == UADE_R_STATE) {
+ fprintf(stderr, "protocol error: sending in R state is forbidden\n");
+ return -1;
+ }
+
+ if (!valid_message(um))
+ return -1;
+ if (um->msgtype == UADE_COMMAND_TOKEN)
+ ipc->state = UADE_R_STATE;
+ um->msgtype = htonl(um->msgtype);
+ um->size = htonl(um->size);
+ if (uade_ipc_write(ipc->output, um, sizeof(*um) + size) < 0)
+ return -1;
+
+ return 0;
+}
+
+
+int uade_send_short_message(enum uade_msgtype msgtype, struct uade_ipc *ipc)
+{
+ struct uade_msg msg = {.msgtype = msgtype};
+
+ if (uade_send_message(&msg, ipc)) {
+ fprintf(stderr, "can not send short message: %d\n", msgtype);
+ return -1;
+ }
+ return 0;
+}
+
+
+int uade_send_string(enum uade_msgtype com, const char *str, struct uade_ipc *ipc)
+{
+ uint32_t size = strlen(str) + 1;
+ struct uade_msg um = {.msgtype = ntohl(com), .size = ntohl(size)};
+
+ if (ipc->state == UADE_INITIAL_STATE) {
+ ipc->state = UADE_S_STATE;
+ } else if (ipc->state == UADE_R_STATE) {
+ fprintf(stderr, "protocol error: sending in R state is forbidden\n");
+ return -1;
+ }
+
+ if ((sizeof(um) + size) > UADE_MAX_MESSAGE_SIZE)
+ return -1;
+ if (uade_ipc_write(ipc->output, &um, sizeof(um)) < 0)
+ return -1;
+ if (uade_ipc_write(ipc->output, str, size) < 0)
+ return -1;
+
+ return 0;
+}
+
+
+int uade_send_u32(enum uade_msgtype com, uint32_t u, struct uade_ipc *ipc)
+{
+ uint8_t space[UADE_MAX_MESSAGE_SIZE];
+ struct uade_msg *um = (struct uade_msg *) space;
+ um->msgtype = com;
+ um->size = 4;
+ * (uint32_t *) um->data = htonl(u);
+ return uade_send_message(um, ipc);
+}
+
+
+int uade_send_two_u32s(enum uade_msgtype com, uint32_t u1, uint32_t u2,
+ struct uade_ipc *ipc)
+{
+ uint8_t space[UADE_MAX_MESSAGE_SIZE];
+ struct uade_msg *um = (struct uade_msg *) space;
+ um->msgtype = com;
+ um->size = 8;
+ ((uint32_t *) um->data)[0] = htonl(u1);
+ ((uint32_t *) um->data)[1] = htonl(u2);
+ return uade_send_message(um, ipc);
+}
+
+
+void uade_set_peer(struct uade_ipc *ipc, int peer_is_client, const char *input, const char *output)
+{
+ assert(peer_is_client == 0 || peer_is_client == 1);
+ assert(input != NULL);
+ assert(output != NULL);
+
+ *ipc = (struct uade_ipc) {.state = UADE_INITIAL_STATE,
+ .input= uade_ipc_set_input(input),
+ .output = uade_ipc_set_output(output)};
+}
+
+
+static int valid_message(struct uade_msg *um)
+{
+ size_t len;
+ if (um->msgtype <= UADE_MSG_FIRST || um->msgtype >= UADE_MSG_LAST) {
+ fprintf(stderr, "unknown command: %u\n", (unsigned int) um->msgtype);
+ return 0;
+ }
+ len = sizeof(*um) + um->size;
+ if (len > UADE_MAX_MESSAGE_SIZE) {
+ fprintf(stderr, "too long a message: %zu\n", len);
+ return 0;
+ }
+ return 1;
+}
diff --git a/plugins/uade2/uade-2.13/src/unixatomic.c b/plugins/uade2/uade-2.13/src/unixatomic.c
new file mode 100644
index 00000000..1adbe27a
--- /dev/null
+++ b/plugins/uade2/uade-2.13/src/unixatomic.c
@@ -0,0 +1,149 @@
+#include <errno.h>
+#include <stdint.h>
+#include <assert.h>
+
+#include "unixatomic.h"
+#include "sysincludes.h"
+
+int atomic_close(int fd)
+{
+ while (1) {
+ if (close(fd) < 0) {
+ if (errno == EINTR)
+ continue;
+ return -1;
+ }
+ break;
+ }
+ return 0;
+}
+
+
+int atomic_dup2(int oldfd, int newfd)
+{
+ while (1) {
+ if (dup2(oldfd, newfd) < 0) {
+ if (errno == EINTR)
+ continue;
+ return -1;
+ }
+ break;
+ }
+ return newfd;
+}
+
+
+size_t atomic_fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
+{
+ uint8_t *dest = ptr;
+ size_t readmembers = 0;
+ size_t ret;
+
+ while (readmembers < nmemb) {
+ ret = fread(dest + size * readmembers, size, nmemb - readmembers, stream);
+ if (ret == 0)
+ break;
+ readmembers += ret;
+ }
+
+ assert(readmembers <= nmemb);
+
+ return readmembers;
+}
+
+
+ssize_t atomic_read(int fd, const void *buf, size_t count)
+{
+ char *b = (char *) buf;
+ ssize_t bytes_read = 0;
+ ssize_t ret;
+ while (bytes_read < count) {
+ ret = read(fd, &b[bytes_read], count - bytes_read);
+ if (ret < 0) {
+ if (errno == EINTR)
+ continue;
+ if (errno == EAGAIN) {
+ fd_set s;
+ FD_ZERO(&s);
+ FD_SET(fd, &s);
+ if (select(fd + 1, &s, NULL, NULL, NULL) == 0)
+ fprintf(stderr, "atomic_read: very strange. infinite select() returned 0. report this!\n");
+ continue;
+ }
+ return -1;
+ } else if (ret == 0) {
+ return 0;
+ }
+ bytes_read += ret;
+ }
+ return bytes_read;
+}
+
+
+void *atomic_read_file(size_t *fs, const char *filename)
+{
+ FILE *f;
+ size_t off;
+ void *mem = NULL;
+ size_t msize;
+ long pos;
+
+ if ((f = fopen(filename, "rb")) == NULL)
+ goto error;
+
+ if (fseek(f, 0, SEEK_END))
+ goto error;
+ pos = ftell(f);
+ if (pos < 0)
+ goto error;
+ if (fseek(f, 0, SEEK_SET))
+ goto error;
+
+ *fs = pos;
+ msize = (pos > 0) ? pos : 1;
+
+ if ((mem = malloc(msize)) == NULL)
+ goto error;
+
+ off = atomic_fread(mem, 1, *fs, f);
+ if (off < *fs) {
+ fprintf(stderr, "Not able to read the whole file %s\n", filename);
+ goto error;
+ }
+
+ fclose(f);
+ return mem;
+
+ error:
+ if (f)
+ fclose(f);
+ free(mem);
+ *fs = 0;
+ return NULL;
+}
+
+
+ssize_t atomic_write(int fd, const void *buf, size_t count)
+{
+ char *b = (char *) buf;
+ ssize_t bytes_written = 0;
+ ssize_t ret;
+ while (bytes_written < count) {
+ ret = write(fd, &b[bytes_written], count - bytes_written);
+ if (ret < 0) {
+ if (errno == EINTR)
+ continue;
+ if (errno == EAGAIN) {
+ fd_set s;
+ FD_ZERO(&s);
+ FD_SET(fd, &s);
+ if (select(fd + 1, NULL, &s, NULL, NULL) == 0)
+ fprintf(stderr, "atomic_write: very strange. infinite select() returned 0. report this!\n");
+ continue;
+ }
+ return -1;
+ }
+ bytes_written += ret;
+ }
+ return bytes_written;
+}
diff --git a/plugins/uade2/uade-2.13/src/unixsupport.c b/plugins/uade2/uade-2.13/src/unixsupport.c
new file mode 100644
index 00000000..d6131bc2
--- /dev/null
+++ b/plugins/uade2/uade-2.13/src/unixsupport.c
@@ -0,0 +1,350 @@
+/* UNIX support tools for uadecore.
+
+ Copyright 2000 - 2005 (C) Heikki Orsila <heikki.orsila@iki.fi>
+
+ This module is licensed under the GNU GPL.
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <signal.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <libgen.h>
+#include <sys/socket.h>
+#include <unistd.h>
+#include <limits.h>
+#include <ctype.h>
+
+#include "uade.h"
+#include "unixatomic.h"
+
+
+static int url_to_fd(const char *url, int flags, mode_t mode)
+{
+ int fd;
+ if (strncmp(url, "fd://", 5) == 0) {
+ char *endptr;
+ if (url[5] == 0)
+ return -1;
+ fd = strtol(&url[5], &endptr, 10);
+ if (*endptr != 0)
+ return -1;
+ } else {
+ if (flags & O_WRONLY) {
+ fd = open(url, flags, mode);
+ } else {
+ fd = open(url, flags);
+ }
+ }
+ if (fd < 0)
+ fd = -1;
+ return fd;
+}
+
+
+/* This must read the full size_t count if it can, and therefore we use
+ atomic_read() */
+ssize_t uade_ipc_read(void *f, const void *buf, size_t count)
+{
+ int fd = (intptr_t) f;
+ return atomic_read(fd, buf, count);
+}
+
+
+/* This must write the full size_t count if it can, and therefore we use
+ atomic_write() */
+ssize_t uade_ipc_write(void *f, const void *buf, size_t count)
+{
+ int fd = (intptr_t) f;
+ return atomic_write(fd, buf, count);
+}
+
+
+void *uade_ipc_set_input(const char *input)
+{
+ int fd;
+ if ((fd = url_to_fd(input, O_RDONLY, 0)) < 0) {
+ fprintf(stderr, "can not open input file %s: %s\n", input, strerror(errno));
+ exit(-1);
+ }
+ return (void *) ((intptr_t) fd);
+}
+
+
+void *uade_ipc_set_output(const char *output)
+{
+ int fd;
+ if ((fd = url_to_fd(output, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) < 0) {
+ fprintf(stderr, "can not open output file %s: %s\n", output, strerror(errno));
+ exit(-1);
+ }
+ return (void *) ((intptr_t) fd);
+}
+
+
+static int uade_amiga_scandir(char *real, char *dirname, char *fake, int ml)
+{
+ DIR *dir;
+ struct dirent *direntry;
+ if (!(dir = opendir(dirname))) {
+ fprintf(stderr, "uade: can't open dir (%s) (amiga scandir)\n", dirname);
+ return 0;
+ }
+ while ((direntry = readdir(dir))) {
+ if (!strcmp(fake, direntry->d_name)) {
+ if (((int) strlcpy(real, direntry->d_name, ml)) >= ml) {
+ fprintf(stderr, "uade: %s does not fit real", direntry->d_name);
+ closedir(dir);
+ return 0;
+ }
+ break;
+ }
+ }
+ if (direntry) {
+ closedir(dir);
+ return 1;
+ }
+ rewinddir(dir);
+ while ((direntry = readdir(dir))) {
+ if (!strcasecmp(fake, direntry->d_name)) {
+ if (((int) strlcpy(real, direntry->d_name, ml)) >= ml) {
+ fprintf(stderr, "uade: %s does not fit real", direntry->d_name);
+ closedir(dir);
+ return 0;
+ }
+ break;
+ }
+ }
+ closedir(dir);
+ return direntry ? 1 : 0;
+}
+
+
+char *uade_dirname(char *dst, char *src, size_t maxlen)
+{
+ char *srctemp = strdup(src);
+ if (srctemp == NULL)
+ return NULL;
+ strlcpy(dst, dirname(srctemp), maxlen);
+ free(srctemp);
+ return dst;
+}
+
+
+/* opens file in amiga namespace */
+FILE *uade_open_amiga_file(char *aname, const char *playerdir)
+{
+ char *separator;
+ char *ptr;
+ char copy[PATH_MAX];
+ char dirname[PATH_MAX];
+ char fake[PATH_MAX];
+ char real[PATH_MAX];
+ int len;
+ DIR *dir;
+ FILE *file;
+
+ if (strlcpy(copy, aname, sizeof(copy)) >= sizeof(copy)) {
+ fprintf(stderr, "uade: error: amiga tried to open a very long filename\nplease REPORT THIS!\n");
+ return NULL;
+ }
+ ptr = copy;
+ /* fprintf(stderr, "uade: opening %s\n", ptr); */
+ if ((separator = strchr(ptr, (int) ':'))) {
+ len = (int) (separator - ptr);
+ memcpy(dirname, ptr, len);
+ dirname[len] = 0;
+ if (!strcasecmp(dirname, "ENV")) {
+ snprintf(dirname, sizeof(dirname), "%s/ENV/", playerdir);
+ } else if (!strcasecmp(dirname, "S")) {
+ snprintf(dirname, sizeof(dirname), "%s/S/", playerdir);
+ } else {
+ fprintf(stderr, "uade: open_amiga_file: unknown amiga volume (%s)\n", aname);
+ return NULL;
+ }
+ if (!(dir = opendir(dirname))) {
+ fprintf(stderr, "uade: can't open dir (%s) (volume parsing)\n", dirname);
+ return NULL;
+ }
+ closedir(dir);
+ /* fprintf(stderr, "uade: opening from dir %s\n", dirname); */
+ ptr = separator + 1;
+ } else {
+ if (*ptr == '/') {
+ /* absolute path */
+ strlcpy(dirname, "/", sizeof(dirname));
+ ptr++;
+ } else {
+ /* relative path */
+ strlcpy(dirname, "./", sizeof(dirname));
+ }
+ }
+
+ while ((separator = strchr(ptr, (int) '/'))) {
+ len = (int) (separator - ptr);
+ if (!len) {
+ ptr++;
+ continue;
+ }
+ memcpy(fake, ptr, len);
+ fake[len] = 0;
+ if (uade_amiga_scandir(real, dirname, fake, sizeof(real))) {
+ /* found matching entry */
+ if (strlcat(dirname, real, sizeof(dirname)) >= sizeof(dirname)) {
+ fprintf(stderr, "uade: too long dir path (%s + %s)\n", dirname, real);
+ return NULL;
+ }
+ if (strlcat(dirname, "/", sizeof(dirname)) >= sizeof(dirname)) {
+ fprintf(stderr, "uade: too long dir path (%s + %s)\n", dirname, "/");
+ return NULL;
+ }
+ } else {
+ /* didn't find entry */
+ /* fprintf (stderr, "uade: %s not found from (%s) (dir scanning)\n", fake, dirname); */
+ return NULL;
+ }
+ ptr = separator + 1;
+ }
+ /* fprintf(stderr, "uade: pass 3: (%s) (%s)\n", dirname, ptr); */
+
+ if (!(dir = opendir(dirname))) {
+ fprintf(stderr, "can't open dir (%s) (after dir scanning)\n", dirname);
+ return NULL;
+ }
+ closedir(dir);
+
+ if (uade_amiga_scandir(real, dirname, ptr, sizeof(real))) {
+ /* found matching entry */
+ if (strlcat(dirname, real, sizeof(dirname)) >= sizeof(dirname)) {
+ fprintf(stderr, "uade: too long dir path (%s + %s)\n", dirname, real);
+ return NULL;
+ }
+ } else {
+ /* didn't find entry */
+ /* fprintf (stderr, "uade: %s not found from %s\n", ptr, dirname); */
+ return NULL;
+ }
+ if (!(file = fopen(dirname, "r"))) {
+ fprintf (stderr, "uade: couldn't open file (%s) induced by (%s)\n", dirname, aname);
+ }
+ return file;
+}
+
+
+void uade_portable_initializations(void)
+{
+ int signals[] = {SIGINT, -1};
+ int *signum = signals;
+ struct sigaction act;
+ memset(&act, 0, sizeof act);
+ act.sa_handler = SIG_IGN;
+
+ while (*signum != -1) {
+ while (1) {
+ if ((sigaction(*signum, &act, NULL)) < 0) {
+ if (errno == EINTR)
+ continue;
+ fprintf(stderr, "can not ignore signal %d: %s\n", *signum, strerror(errno));
+ exit(-1);
+ }
+ break;
+ }
+ signum++;
+ }
+}
+
+
+void uade_arch_spawn(struct uade_ipc *ipc, pid_t *uadepid,
+ const char *uadename)
+{
+ int fds[2];
+ char input[32], output[32];
+
+ if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds)) {
+ fprintf(stderr, "Can not create socketpair: %s\n", strerror(errno));
+ abort();
+ }
+
+ *uadepid = fork();
+ if (*uadepid < 0) {
+ fprintf(stderr, "Fork failed: %s\n", strerror(errno));
+ abort();
+ }
+
+ /* The child (*uadepid == 0) will execute uadecore */
+ if (*uadepid == 0) {
+ int fd;
+ int maxfds;
+
+ if ((maxfds = sysconf(_SC_OPEN_MAX)) < 0) {
+ maxfds = 1024;
+ fprintf(stderr, "Getting max fds failed. Using %d.\n", maxfds);
+ }
+
+ /* close everything else but stdin, stdout, stderr, and in/out fds */
+ for (fd = 3; fd < maxfds; fd++) {
+ if (fd != fds[1])
+ atomic_close(fd);
+ }
+
+ /* give in/out fds as command line parameters to the uade process */
+ snprintf(input, sizeof(input), "fd://%d", fds[1]);
+ snprintf(output, sizeof(output), "fd://%d", fds[1]);
+
+ execlp(uadename, uadename, "-i", input, "-o", output, (char *) NULL);
+ fprintf(stderr, "uade execlp failed: %s\n", strerror(errno));
+ abort();
+ }
+
+ /* Close fds that the uadecore uses */
+ if (atomic_close(fds[1]) < 0) {
+ fprintf(stderr, "Could not close uadecore fds: %s\n", strerror(errno));
+ kill (*uadepid, SIGTERM);
+ abort();
+ }
+
+ do {
+ snprintf(output, sizeof output, "fd://%d", fds[0]);
+ snprintf(input, sizeof input, "fd://%d", fds[0]);
+ uade_set_peer(ipc, 1, input, output);
+ } while (0);
+}
+
+/*
+ * A hack that converts X:\something style windows names into cygwin style name
+ * /cygdrive/X/something. All '\\' characters are converted into '/'
+ * characters.
+ */
+char *windows_to_cygwin_path(const char *path)
+{
+ size_t i;
+ char *s;
+ size_t len = strlen(path);
+
+ if (len == 0)
+ return calloc(1, 1);
+
+ if (len >= 2 && isalpha(path[0]) && path[1] == ':') {
+ /* uses windows drive names */
+ size_t newlen = len + 32;
+ s = malloc(newlen);
+ if (s != NULL)
+ snprintf(s, newlen, "/cygdrive/%c/%s", path[0], &path[2]);
+ } else {
+ s = strdup(path);
+ }
+ if (s == NULL)
+ return NULL;
+
+ for (i = 0; s[i] != 0; i++) {
+ if (s[i] == '\\')
+ s[i] = '/';
+ }
+
+ return s;
+}
diff --git a/plugins/vfs_curl/Makefile.am b/plugins/vfs_curl/Makefile.am
index 95794831..4c69c51f 100644
--- a/plugins/vfs_curl/Makefile.am
+++ b/plugins/vfs_curl/Makefile.am
@@ -4,6 +4,6 @@ pkglib_LTLIBRARIES = vfs_curl.la
vfs_curl_la_SOURCES = vfs_curl.c
vfs_curl_la_LDFLAGS = -module
-vfs_curl_la_LIBADD = $(LDADD) $(CURL_LIBS)
+vfs_curl_la_LIBADD = $(LDADD) $(VFS_CURL_LIBS)
AM_CFLAGS = $(CFLAGS) -std=c99
endif
diff --git a/plugins/vfs_curl/vfs_curl.c b/plugins/vfs_curl/vfs_curl.c
index 048f964e..528b3809 100644
--- a/plugins/vfs_curl/vfs_curl.c
+++ b/plugins/vfs_curl/vfs_curl.c
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@@ -46,6 +46,7 @@ enum {
STATUS_FINISHED = 2,
STATUS_ABORTED = 3,
STATUS_SEEK = 4,
+ STATUS_DESTROY = 5,
};
typedef struct {
@@ -72,6 +73,8 @@ typedef struct {
int metadata_size; // size of metadata in stream
int metadata_have_size; // amount which is already in metadata buffer
+ char http_err[CURL_ERROR_SIZE];
+
// flags (bitfields to save some space)
unsigned seektoend : 1; // indicates that next tell must return length
unsigned gotheader : 1; // tells that all headers (including ICY) were processed (to start reading body)
@@ -81,13 +84,34 @@ typedef struct {
static DB_vfs_t plugin;
-static char http_err[CURL_ERROR_SIZE];
-
static int allow_new_streams;
static size_t
http_content_header_handler (void *ptr, size_t size, size_t nmemb, void *stream);
+static int64_t biglock;
+
+#define MAX_ABORT_FILES 100
+static DB_FILE *open_files[MAX_ABORT_FILES];
+static int num_open_files = 0;
+static DB_FILE *abort_files[MAX_ABORT_FILES];
+static int num_abort_files = 0;
+
+static int
+http_need_abort (DB_FILE *fp);
+
+static void
+http_cancel_abort (DB_FILE *fp);
+
+static void
+http_abort (DB_FILE *fp);
+
+static void
+http_reg_open_file (DB_FILE *fp);
+
+static void
+http_unreg_open_file (DB_FILE *fp);
+
static size_t
http_curl_write_wrapper (HTTP_FILE *fp, void *ptr, size_t size) {
size_t avail = size;
@@ -98,7 +122,8 @@ http_curl_write_wrapper (HTTP_FILE *fp, void *ptr, size_t size) {
deadbeef->mutex_unlock (fp->mutex);
return 0;
}
- if (fp->status == STATUS_ABORTED) {
+ if (http_need_abort ((DB_FILE*)fp)) {
+ fp->status = STATUS_ABORTED;
trace ("vfs_curl STATUS_ABORTED in the middle of packet\n");
deadbeef->mutex_unlock (fp->mutex);
break;
@@ -217,13 +242,14 @@ http_curl_write (void *ptr, size_t size, size_t nmemb, void *stream) {
// trace ("http_curl_write %d bytes, wait_meta=%d\n", size * nmemb, fp->wait_meta);
gettimeofday (&fp->last_read_time, NULL);
- if (fp->status == STATUS_ABORTED) {
+ if (http_need_abort (stream)) {
+ fp->status = STATUS_ABORTED;
trace ("vfs_curl STATUS_ABORTED at start of packet\n");
return 0;
}
- if (fp->gotsomeheader) {
- fp->gotheader = 1;
- }
+// if (fp->gotsomeheader) {
+// fp->gotheader = 1;
+// }
if (!fp->gotheader) {
// check if that's ICY
if (!fp->icyheader && avail >= 10 && !memcmp (ptr, "ICY 200 OK", 10)) {
@@ -467,7 +493,8 @@ http_curl_control (void *stream, double dltotal, double dlnow, double ultotal, d
deadbeef->mutex_unlock (fp->mutex);
return -1;
}
- if (fp->status == STATUS_ABORTED) {
+ if (http_need_abort ((DB_FILE *)fp)) {
+ fp->status = STATUS_ABORTED;
trace ("vfs_curl STATUS_ABORTED in progress callback\n");
deadbeef->mutex_unlock (fp->mutex);
return -1;
@@ -477,6 +504,23 @@ http_curl_control (void *stream, double dltotal, double dlnow, double ultotal, d
}
static void
+http_destroy (HTTP_FILE *fp) {
+ if (fp->content_type) {
+ free (fp->content_type);
+ }
+ if (fp->track) {
+ deadbeef->pl_item_unref (fp->track);
+ }
+ if (fp->url) {
+ free (fp->url);
+ }
+ if (fp->mutex) {
+ deadbeef->mutex_free (fp->mutex);
+ }
+ free (fp);
+}
+
+static void
http_thread_func (void *ctx) {
HTTP_FILE *fp = (HTTP_FILE *)ctx;
CURL *curl;
@@ -492,10 +536,11 @@ http_thread_func (void *ctx) {
struct curl_slist *headers = NULL;
curl_easy_reset (curl);
curl_easy_setopt (curl, CURLOPT_URL, fp->url);
+ curl_easy_setopt (curl, CURLOPT_USERAGENT, "deadbeef");
curl_easy_setopt (curl, CURLOPT_NOPROGRESS, 1);
curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, http_curl_write);
curl_easy_setopt (curl, CURLOPT_WRITEDATA, ctx);
- curl_easy_setopt (curl, CURLOPT_ERRORBUFFER, http_err);
+ curl_easy_setopt (curl, CURLOPT_ERRORBUFFER, fp->http_err);
curl_easy_setopt (curl, CURLOPT_BUFFERSIZE, BUFFER_SIZE/2);
curl_easy_setopt (curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_easy_setopt (curl, CURLOPT_HEADERFUNCTION, http_content_header_handler);
@@ -513,9 +558,10 @@ http_thread_func (void *ctx) {
curl_easy_setopt (curl, CURLOPT_RESUME_FROM, fp->pos);
}
if (deadbeef->conf_get_int ("network.proxy", 0)) {
- curl_easy_setopt (curl, CURLOPT_PROXY, deadbeef->conf_get_str ("network.proxy.address", ""));
+ deadbeef->conf_lock ();
+ curl_easy_setopt (curl, CURLOPT_PROXY, deadbeef->conf_get_str_fast ("network.proxy.address", ""));
curl_easy_setopt (curl, CURLOPT_PROXYPORT, deadbeef->conf_get_int ("network.proxy.port", 8080));
- const char *type = deadbeef->conf_get_str ("network.proxy.type", "HTTP");
+ const char *type = deadbeef->conf_get_str_fast ("network.proxy.type", "HTTP");
int curlproxytype = CURLPROXY_HTTP;
if (!strcasecmp (type, "HTTP")) {
curlproxytype = CURLPROXY_HTTP;
@@ -543,8 +589,8 @@ http_thread_func (void *ctx) {
#endif
curl_easy_setopt (curl, CURLOPT_PROXYTYPE, curlproxytype);
- const char *proxyuser = deadbeef->conf_get_str ("network.proxy.username", "");
- const char *proxypass = deadbeef->conf_get_str ("network.proxy.password", "");
+ const char *proxyuser = deadbeef->conf_get_str_fast ("network.proxy.username", "");
+ const char *proxypass = deadbeef->conf_get_str_fast ("network.proxy.password", "");
if (*proxyuser || *proxypass) {
#if LIBCURL_VERSION_MINOR >= 19 && LIBCURL_VERSION_PATCH >= 1
curl_easy_setopt (curl, CURLOPT_PROXYUSERNAME, proxyuser);
@@ -555,6 +601,7 @@ http_thread_func (void *ctx) {
curl_easy_setopt (curl, CURLOPT_PROXYUSERPWD, pwd);
#endif
}
+ deadbeef->conf_unlock ();
}
// fp->status = STATUS_INITIAL;
trace ("vfs_curl: calling curl_easy_perform (status=%d)...\n", fp->status);
@@ -562,7 +609,7 @@ http_thread_func (void *ctx) {
status = curl_easy_perform (curl);
trace ("vfs_curl: curl_easy_perform retval=%d\n", status);
if (status != 0) {
- trace ("curl error:\n%s\n", http_err);
+ trace ("curl error:\n%s\n", fp->http_err);
}
deadbeef->mutex_lock (fp->mutex);
if (status == 0 && fp->length < 0 && fp->status != STATUS_ABORTED && fp->status != STATUS_SEEK) {
@@ -583,10 +630,12 @@ http_thread_func (void *ctx) {
continue;
}
if (fp->status != STATUS_SEEK) {
+ trace ("vfs_curl: break loop\n");
deadbeef->mutex_unlock (fp->mutex);
break;
}
else {
+ trace ("vfs_curl: restart loop\n");
fp->skipbytes = 0;
fp->status = STATUS_INITIAL;
trace ("seeking to %d\n", fp->pos);
@@ -612,15 +661,22 @@ http_thread_func (void *ctx) {
curl_easy_cleanup (curl);
deadbeef->mutex_lock (fp->mutex);
+
+ if (fp->status == STATUS_ABORTED) {
+ trace ("vfs_curl: thread ended due to abort signal\n");
+ }
+ else {
+ trace ("vfs_curl: thread ended normally\n");
+ }
fp->status = STATUS_FINISHED;
deadbeef->mutex_unlock (fp->mutex);
- fp->tid = 0;
}
static void
http_start_streamer (HTTP_FILE *fp) {
fp->mutex = deadbeef->mutex_create ();
fp->tid = deadbeef->thread_start (http_thread_func, fp);
+// deadbeef->thread_detach (fp->tid);
}
static DB_FILE *
@@ -630,6 +686,7 @@ http_open (const char *fname) {
}
trace ("http_open\n");
HTTP_FILE *fp = malloc (sizeof (HTTP_FILE));
+ http_reg_open_file ((DB_FILE *)fp);
memset (fp, 0, sizeof (HTTP_FILE));
fp->vfs = &plugin;
fp->url = strdup (fname);
@@ -651,24 +708,13 @@ http_close (DB_FILE *stream) {
assert (stream);
HTTP_FILE *fp = (HTTP_FILE *)stream;
- deadbeef->mutex_lock (fp->mutex);
+ http_abort (stream);
if (fp->tid) {
- fp->status = STATUS_ABORTED;
- trace ("http_close thread_join\n");
- deadbeef->mutex_unlock (fp->mutex);
deadbeef->thread_join (fp->tid);
}
- if (fp->content_type) {
- free (fp->content_type);
- }
- if (fp->track) {
- deadbeef->pl_item_unref (fp->track);
- }
- if (fp->url) {
- free (fp->url);
- }
- deadbeef->mutex_free (fp->mutex);
- free (stream);
+ http_cancel_abort ((DB_FILE *)fp);
+ http_destroy (fp);
+ http_unreg_open_file ((DB_FILE *)fp);
trace ("http_close done\n");
}
@@ -690,7 +736,7 @@ http_read (void *ptr, size_t size, size_t nmemb, DB_FILE *stream) {
{
// wait until data is available
while ((fp->remaining == 0 || fp->skipbytes > 0) && fp->status != STATUS_FINISHED) {
-// trace ("vfs_curl: readwait..\n");
+ trace ("vfs_curl: readwait, status: %d..\n", fp->status);
deadbeef->mutex_lock (fp->mutex);
if (fp->status == STATUS_READING) {
struct timeval tm;
@@ -867,43 +913,163 @@ http_get_content_type (DB_FILE *stream) {
return fp->content_type;
}
-void
+static void
http_abort (DB_FILE *fp) {
- trace ("http_abort %p\n", fp);
- HTTP_FILE *f = (HTTP_FILE *)fp;
- if (f->tid) {
- deadbeef->mutex_lock (f->mutex);
- f->status = STATUS_ABORTED;
- deadbeef->mutex_unlock (f->mutex);
- }
- trace ("http_abort done\n");
+ trace ("abort file: %p\n", fp);
+ deadbeef->mutex_lock (biglock);
+ int i;
+ for (i = 0; i < num_abort_files; i++) {
+ if (abort_files[i] == fp) {
+ break;
+ }
+ }
+ if (i == num_abort_files) {
+ if (num_abort_files == MAX_ABORT_FILES) {
+ trace ("vfs_curl: abort_files list overflow\n");
+ }
+ else {
+ trace ("added file to abort list: %p\n", fp);
+ abort_files[num_abort_files++] = fp;
+ }
+ }
+ deadbeef->mutex_unlock (biglock);
+}
+
+static int
+http_need_abort (DB_FILE *fp) {
+ deadbeef->mutex_lock (biglock);
+ for (int i = 0; i < num_abort_files; i++) {
+ if (abort_files[i] == fp) {
+ trace ("need to abort: %p\n", fp);
+ deadbeef->mutex_unlock (biglock);
+ return 1;
+ }
+ }
+ deadbeef->mutex_unlock (biglock);
+ return 0;
+}
+
+static void
+http_cancel_abort (DB_FILE *fp) {
+ deadbeef->mutex_lock (biglock);
+ for (int i = 0; i < num_abort_files; i++) {
+ if (abort_files[i] == fp) {
+ if (i != num_abort_files-1) {
+ abort_files[i] = abort_files[num_abort_files-1];
+ }
+ num_abort_files--;
+ break;
+ }
+ }
+ deadbeef->mutex_unlock (biglock);
+}
+
+static void
+http_reg_open_file (DB_FILE *fp) {
+ deadbeef->mutex_lock (biglock);
+ for (int i = 0; i < num_open_files; i++) {
+ if (open_files[i] == fp) {
+ deadbeef->mutex_unlock (biglock);
+ return;
+ }
+ }
+ if (num_open_files == MAX_ABORT_FILES) {
+ fprintf (stderr, "vfs_curl: open files overflow\n");
+ deadbeef->mutex_unlock (biglock);
+ return;
+ }
+ open_files[num_open_files++] = fp;
+ deadbeef->mutex_unlock (biglock);
+}
+
+static void
+http_unreg_open_file (DB_FILE *fp) {
+ deadbeef->mutex_lock (biglock);
+ int i;
+ for (i = 0; i < num_open_files; i++) {
+ if (open_files[i] == fp) {
+ if (i != num_open_files-1) {
+ open_files[i] = open_files[num_open_files-1];
+ }
+ num_open_files--;
+ trace ("remove from open list: %p\n", fp);
+ break;
+ }
+ }
+
+ // gc abort_files
+ int j = 0;
+ while (j < num_abort_files) {
+ for (i = 0; i < num_open_files; i++) {
+ if (abort_files[j] == open_files[i]) {
+ break;
+ }
+ }
+ if (i == num_open_files) {
+ // remove abort
+ http_cancel_abort (abort_files[j]);
+ continue;
+ }
+ j++;
+ }
+ deadbeef->mutex_unlock (biglock);
}
static int
vfs_curl_start (void) {
allow_new_streams = 1;
+ biglock = deadbeef->mutex_create ();
return 0;
}
static int
vfs_curl_stop (void) {
allow_new_streams = 0;
+ if (biglock) {
+ deadbeef->mutex_free (biglock);
+ biglock = 0;
+ }
return 0;
}
static const char *scheme_names[] = { "http://", "ftp://", NULL };
+const char **
+http_get_schemes (void) {
+ return scheme_names;
+}
+
+int
+http_is_streaming (void) {
+ return 1;
+}
+
// standard stdio vfs
static DB_vfs_t plugin = {
DB_PLUGIN_SET_API_VERSION
- .plugin.version_major = 0,
- .plugin.version_minor = 1,
+ .plugin.version_major = 1,
+ .plugin.version_minor = 0,
.plugin.type = DB_PLUGIN_VFS,
.plugin.id = "vfs_curl",
.plugin.name = "cURL vfs",
.plugin.descr = "http and ftp streaming module using libcurl, with ICY protocol support",
- .plugin.author = "Alexey Yakovenko",
- .plugin.email = "waker@users.sourceforge.net",
+ .plugin.copyright =
+ "Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>\n"
+ "\n"
+ "This program is free software; you can redistribute it and/or\n"
+ "modify it under the terms of the GNU General Public License\n"
+ "as published by the Free Software Foundation; either version 2\n"
+ "of the License, or (at your option) any later version.\n"
+ "\n"
+ "This program is distributed in the hope that it will be useful,\n"
+ "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+ "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+ "GNU General Public License for more details.\n"
+ "\n"
+ "You should have received a copy of the GNU General Public License\n"
+ "along with this program; if not, write to the Free Software\n"
+ "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n"
+ ,
.plugin.website = "http://deadbeef.sf.net",
.plugin.start = vfs_curl_start,
.plugin.stop = vfs_curl_stop,
@@ -917,8 +1083,8 @@ static DB_vfs_t plugin = {
.rewind = http_rewind,
.getlength = http_getlength,
.get_content_type = http_get_content_type,
- .scheme_names = scheme_names,
- .streaming = 1
+ .get_schemes = http_get_schemes,
+ .is_streaming = http_is_streaming,
};
DB_plugin_t *
diff --git a/plugins/vfs_zip/Makefile.am b/plugins/vfs_zip/Makefile.am
new file mode 100644
index 00000000..8a03b68d
--- /dev/null
+++ b/plugins/vfs_zip/Makefile.am
@@ -0,0 +1,9 @@
+if HAVE_VFS_ZIP
+pkglib_LTLIBRARIES = vfs_zip.la
+vfs_zip_la_SOURCES = vfs_zip.c
+
+vfs_zip_la_LDFLAGS = -module
+
+vfs_zip_la_LIBADD = $(LDADD) $(ZLIB_LIBS) $(ZIP_LIBS)
+AM_CFLAGS = $(CFLAGS) -std=c99
+endif
diff --git a/plugins/vfs_zip/vfs_zip.c b/plugins/vfs_zip/vfs_zip.c
new file mode 100644
index 00000000..5e77b740
--- /dev/null
+++ b/plugins/vfs_zip/vfs_zip.c
@@ -0,0 +1,255 @@
+/*
+ DeaDBeeF - ultimate music player for GNU/Linux systems with X11
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+#include <string.h>
+#include <zip.h>
+#include <stdlib.h>
+#include <assert.h>
+#include "../../deadbeef.h"
+
+#define trace(...) { fprintf(stderr, __VA_ARGS__); }
+//#define trace(fmt,...)
+
+#define min(x,y) ((x)<(y)?(x):(y))
+
+static DB_functions_t *deadbeef;
+static DB_vfs_t plugin;
+
+typedef struct {
+ DB_FILE file;
+ struct zip* z;
+ struct zip_file *zf;
+ int64_t offset;
+ int index;
+ int64_t size;
+} zip_file_t;
+
+static const char *scheme_names[] = { "zip://", NULL };
+
+const char **
+vfs_zip_get_schemes (void) {
+ return scheme_names;
+}
+
+int
+vfs_zip_is_streaming (void) {
+ return 0;
+}
+
+// fname must have form of zip://full_filepath.zip:full_filepath_in_zip
+DB_FILE*
+vfs_zip_open (const char *fname) {
+ if (strncasecmp (fname, "zip://", 6)) {
+ return NULL;
+ }
+
+ fname += 6;
+ const char *colon = strchr (fname, ':');
+ if (!colon) {
+ return NULL;
+ }
+
+
+ char zipname[colon-fname+1];
+ memcpy (zipname, fname, colon-fname);
+ zipname[colon-fname] = 0;
+
+ fname = colon+1;
+
+ struct zip *z = zip_open (zipname, 0, NULL);
+ if (!z) {
+ return NULL;
+ }
+ struct zip_stat st;
+ memset (&st, 0, sizeof (st));
+
+ int res = zip_stat(z, fname, 0, &st);
+ if (res != 0) {
+ zip_close (z);
+ return NULL;
+ }
+
+ struct zip_file *zf = zip_fopen_index (z, st.index, 0);
+ if (!zf) {
+ zip_close (z);
+ return NULL;
+ }
+
+ zip_file_t *f = malloc (sizeof (zip_file_t));
+ memset (f, 0, sizeof (zip_file_t));
+ f->file.vfs = &plugin;
+ f->z = z;
+ f->zf = zf;
+ f->index = st.index;
+ f->size = st.size;
+ return (DB_FILE*)f;
+}
+
+void
+vfs_zip_close (DB_FILE *f) {
+ zip_file_t *zf = (zip_file_t *)f;
+ if (zf->zf) {
+ zip_fclose (zf->zf);
+ }
+ if (zf->z) {
+ zip_close (zf->z);
+ }
+ free (zf);
+}
+
+size_t
+vfs_zip_read (void *ptr, size_t size, size_t nmemb, DB_FILE *f) {
+ zip_file_t *zf = (zip_file_t *)f;
+ ssize_t rb = zip_fread (zf->zf, ptr, size * nmemb);
+ zf->offset += rb;
+ return rb / size;
+}
+
+int
+vfs_zip_seek (DB_FILE *f, int64_t offset, int whence) {
+ zip_file_t *zf = (zip_file_t *)f;
+
+ if (whence == SEEK_CUR) {
+ offset = zf->offset + offset;
+ }
+ else if (whence == SEEK_END) {
+ offset = zf->size + offset;
+ }
+
+ if (offset < zf->offset) {
+ // reopen
+ zip_fclose (zf->zf);
+ zf->zf = zip_fopen_index (zf->z, zf->index, 0);
+ if (!zf->zf) {
+ return -1;
+ }
+ zf->offset = 0;
+ }
+ char buf[4096];
+ int64_t n = offset - zf->offset;
+ while (n > 0) {
+ int sz = min (n, sizeof (buf));
+ ssize_t rb = zip_fread (zf->zf, buf, sz);
+ n -= rb;
+ assert (n >= 0);
+ zf->offset += rb;
+ if (rb != sz) {
+ break;
+ }
+ }
+ if (n > 0) {
+ return -1;
+ }
+ return 0;
+}
+
+int64_t
+vfs_zip_tell (DB_FILE *f) {
+ zip_file_t *zf = (zip_file_t *)f;
+ return zf->offset;
+}
+
+void
+vfs_zip_rewind (DB_FILE *f) {
+ zip_file_t *zf = (zip_file_t *)f;
+ zip_fclose (zf->zf);
+ zf->zf = zip_fopen_index (zf->z, zf->index, 0);
+ assert (zf->zf); // FIXME: better error handling?
+ zf->offset = 0;
+}
+
+int64_t
+vfs_zip_getlength (DB_FILE *f) {
+ zip_file_t *zf = (zip_file_t *)f;
+ return zf->size;
+}
+
+int
+vfs_zip_scandir (const char *dir, struct dirent ***namelist, int (*selector) (const struct dirent *), int (*cmp) (const struct dirent **, const struct dirent **)) {
+ struct zip *z = zip_open (dir, ZIP_CHECKCONS, NULL);
+ if (!z) {
+ return -1;
+ }
+
+ int n = zip_get_num_files (z);
+ *namelist = malloc (sizeof (void *) * n);
+ for (int i = 0; i < n; i++) {
+ (*namelist)[i] = malloc (sizeof (struct dirent));
+ memset ((*namelist)[i], 0, sizeof (struct dirent));
+ const char *nm = zip_get_name (z, i, 0);
+ snprintf ((*namelist)[i]->d_name, sizeof ((*namelist)[i]->d_name), "zip://%s:%s", dir, nm);
+ }
+
+ zip_close (z);
+ return n;
+}
+
+int
+vfs_zip_is_container (const char *fname) {
+ const char *ext = strrchr (fname, '.');
+ if (ext && !strcasecmp (ext, ".zip")) {
+ return 1;
+ }
+ return 0;
+}
+
+static DB_vfs_t plugin = {
+ DB_PLUGIN_SET_API_VERSION
+ .plugin.version_major = 1,
+ .plugin.version_minor = 0,
+ .plugin.type = DB_PLUGIN_VFS,
+ .plugin.id = "vfs_zip",
+ .plugin.name = "ZIP vfs",
+ .plugin.descr = "play files directly from zip files",
+ .plugin.copyright =
+ "Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>\n"
+ "\n"
+ "This program is free software; you can redistribute it and/or\n"
+ "modify it under the terms of the GNU General Public License\n"
+ "as published by the Free Software Foundation; either version 2\n"
+ "of the License, or (at your option) any later version.\n"
+ "\n"
+ "This program is distributed in the hope that it will be useful,\n"
+ "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+ "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+ "GNU General Public License for more details.\n"
+ "\n"
+ "You should have received a copy of the GNU General Public License\n"
+ "along with this program; if not, write to the Free Software\n"
+ "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n"
+ ,
+ .plugin.website = "http://deadbeef.sf.net",
+ .open = vfs_zip_open,
+ .close = vfs_zip_close,
+ .read = vfs_zip_read,
+ .seek = vfs_zip_seek,
+ .tell = vfs_zip_tell,
+ .rewind = vfs_zip_rewind,
+ .getlength = vfs_zip_getlength,
+ .get_schemes = vfs_zip_get_schemes,
+ .is_streaming = vfs_zip_is_streaming,
+ .is_container = vfs_zip_is_container,
+ .scandir = vfs_zip_scandir,
+};
+
+DB_plugin_t *
+vfs_zip_load (DB_functions_t *api) {
+ deadbeef = api;
+ return DB_PLUGIN (&plugin);
+}
diff --git a/plugins/vorbis/vorbis.c b/plugins/vorbis/vorbis.c
index fc0afe9e..691e40f3 100644
--- a/plugins/vorbis/vorbis.c
+++ b/plugins/vorbis/vorbis.c
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -22,6 +22,7 @@
#include <assert.h>
#include <limits.h>
#include <unistd.h>
+#include <math.h>
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
@@ -88,6 +89,7 @@ static const char *metainfo[] = {
"DISCNUMBER", "disc",
"COPYRIGHT", "copyright",
"TOTALTRACKS", "numtracks",
+ "TRACKTOTAL", "numtracks",
"ALBUM ARTIST", "band",
NULL
};
@@ -112,7 +114,6 @@ update_vorbis_comments (DB_playItem_t *it, vorbis_comment *vc, int refresh_playl
for (m = 0; metainfo[m]; m += 2) {
int l = strlen (metainfo[m]);
if (vc->comment_lengths[i] > l && !strncasecmp (metainfo[m], s, l) && s[l] == '=') {
- trace ("ogg adding %s\n", s);
if (refresh_playlist == 2) {
const char *val = deadbeef->pl_find_meta (it, metainfo[m+1]);
if (!val || strcmp (val, s+l+1)) {
@@ -121,6 +122,7 @@ update_vorbis_comments (DB_playItem_t *it, vorbis_comment *vc, int refresh_playl
}
else {
deadbeef->pl_append_meta (it, metainfo[m+1], s + l + 1);
+ break;
}
}
}
@@ -129,16 +131,28 @@ update_vorbis_comments (DB_playItem_t *it, vorbis_comment *vc, int refresh_playl
deadbeef->pl_add_meta (it, "cuesheet", s + 9);
}
else if (!strncasecmp (s, "replaygain_album_gain=", 22)) {
- it->replaygain_album_gain = atof (s + 22);
+ deadbeef->pl_set_item_replaygain (it, DDB_REPLAYGAIN_ALBUMGAIN, atof (s+22));
}
else if (!strncasecmp (s, "replaygain_album_peak=", 22)) {
- it->replaygain_album_peak = atof (s + 22);
+ deadbeef->pl_set_item_replaygain (it, DDB_REPLAYGAIN_ALBUMPEAK, atof (s+22));
}
else if (!strncasecmp (s, "replaygain_track_gain=", 22)) {
- it->replaygain_track_gain = atof (s + 22);
+ deadbeef->pl_set_item_replaygain (it, DDB_REPLAYGAIN_TRACKGAIN, atof (s+22));
}
else if (!strncasecmp (s, "replaygain_track_peak=", 22)) {
- it->replaygain_track_peak = atof (s + 22);
+ deadbeef->pl_set_item_replaygain (it, DDB_REPLAYGAIN_TRACKPEAK, atof (s+22));
+ }
+ else {
+ const char *p = s;
+ while (*p && *p != '=') {
+ p++;
+ }
+ if (*p == '=') {
+ char key[p-s+1];
+ memcpy (key, s, p-s);
+ key[p-s] = 0;
+ deadbeef->pl_add_meta (it, key, p+1);
+ }
}
}
}
@@ -154,10 +168,11 @@ update_vorbis_comments (DB_playItem_t *it, vorbis_comment *vc, int refresh_playl
if (refresh_playlist) {
deadbeef->plug_trigger_event_playlistchanged ();
}
+ return 0;
}
static DB_fileinfo_t *
-cvorbis_open (void) {
+cvorbis_open (uint32_t hints) {
DB_fileinfo_t *_info = malloc (sizeof (ogg_info_t));
ogg_info_t *info = (ogg_info_t *)_info;
memset (info, 0, sizeof (ogg_info_t));
@@ -173,18 +188,19 @@ cvorbis_init (DB_fileinfo_t *_info, DB_playItem_t *it) {
info->cur_bit_stream = -1;
}
else {
- info->cur_bit_stream = it->tracknum;
+ int tracknum = deadbeef->pl_find_meta_int (it, ":TRACKNUM", -1);
+ info->cur_bit_stream = tracknum;
}
info->ptrack = it;
deadbeef->pl_item_ref (it);
- info->info.file = deadbeef->fopen (it->fname);
+ info->info.file = deadbeef->fopen (deadbeef->pl_find_meta (it, ":URI"));
if (!info->info.file) {
trace ("ogg: failed to open file %s\n", it->fname);
return -1;
}
int ln = deadbeef->fgetlength (info->info.file);
- if (info->info.file->vfs->streaming && ln == -1) {
+ if (info->info.file->vfs->is_streaming () && ln == -1) {
ov_callbacks ovcb = {
.read_func = cvorbis_fread,
.seek_func = NULL,
@@ -227,13 +243,18 @@ cvorbis_init (DB_fileinfo_t *_info, DB_playItem_t *it) {
return -1;
}
_info->plugin = &plugin;
- _info->bps = 16;
+ _info->fmt.bps = 16;
//_info->dataSize = ov_pcm_total (&vorbis_file, -1) * vi->channels * 2;
- _info->channels = info->vi->channels;
- _info->samplerate = info->vi->rate;
+ _info->fmt.channels = info->vi->channels;
+ _info->fmt.samplerate = info->vi->rate;
+
+ for (int i = 0; i < _info->fmt.channels; i++) {
+ _info->fmt.channelmask |= 1 << i;
+ }
+
_info->readpos = 0;
info->currentsample = 0;
- if (!info->info.file->vfs->streaming) {
+ if (!info->info.file->vfs->is_streaming ()) {
if (it->endsample > 0) {
info->startsample = it->startsample;
info->endsample = it->endsample;
@@ -266,8 +287,12 @@ cvorbis_free (DB_fileinfo_t *_info) {
deadbeef->pl_item_unref (info->ptrack);
}
if (info->info.file) {
- ov_clear (&info->vorbis_file);
- //fclose (file); //-- ov_clear closes it
+ if (info->vorbis_file.datasource) {
+ ov_clear (&info->vorbis_file);
+ }
+ else {
+ deadbeef->fclose (info->info.file);
+ }
}
free (info);
}
@@ -277,10 +302,12 @@ static int
cvorbis_read (DB_fileinfo_t *_info, char *bytes, int size) {
ogg_info_t *info = (ogg_info_t *)_info;
// trace ("cvorbis_read %d bytes\n", size);
- int out_ch = min (_info->channels, 2);
- if (!info->info.file->vfs->streaming) {
- if (info->currentsample + size / (2 * out_ch) > info->endsample) {
- size = (info->endsample - info->currentsample + 1) * 2 * out_ch;
+
+ int samplesize = _info->fmt.channels * _info->fmt.bps / 8;
+
+ if (!info->info.file->vfs->is_streaming ()) {
+ if (info->currentsample + size / samplesize > info->endsample) {
+ size = (info->endsample - info->currentsample + 1) * samplesize;
trace ("size truncated to %d bytes, cursample=%d, info->endsample=%d, totalsamples=%d\n", size, info->currentsample, info->endsample, ov_pcm_total (&info->vorbis_file, -1));
if (size <= 0) {
return 0;
@@ -288,7 +315,7 @@ cvorbis_read (DB_fileinfo_t *_info, char *bytes, int size) {
}
}
else {
- if (info->ptrack && info->currentsample - info->last_comment_update > 5 * _info->samplerate) {
+ if (info->ptrack && info->currentsample - info->last_comment_update > 5 * _info->fmt.samplerate) {
if (info->ptrack) {
info->last_comment_update = info->currentsample;
vorbis_comment *vc = ov_comment (&info->vorbis_file, -1);
@@ -311,23 +338,33 @@ cvorbis_read (DB_fileinfo_t *_info, char *bytes, int size) {
endianess = 1;
#endif
- if (out_ch != _info->channels) {
- int nframes = size / out_ch / 2;
- int16_t buf[nframes * _info->channels];
- ret=ov_read (&info->vorbis_file, (char*)buf, sizeof(buf), endianess, 2, 1, &info->cur_bit_stream);
+ if (_info->fmt.channels <= 2 || _info->fmt.channels == 4) {
+ ret=ov_read (&info->vorbis_file, bytes, size, endianess, 2, 1, &info->cur_bit_stream);
+ }
+ else {
+ int16_t temp[size/2];
+ ret=ov_read (&info->vorbis_file, (char *)temp, size, endianess, 2, 1, &info->cur_bit_stream);
if (ret > 0) {
- int n = ret / _info->channels / 2;
- for (int i = 0; i < n; i++) {
- for (int j = 0; j < out_ch; j++) {
- ((int16_t *)bytes)[i * out_ch + j] = buf[i * _info->channels + j];
+ // remap channels to wav format
+ int idx = _info->fmt.channels - 3;
+ static int remap[4][6] = {
+ {0,2,1},
+ {0,1,2,3}, // should not be used
+ {0,2,1,3,4},
+ {0,2,1,4,5,3}
+ };
+
+ int i, j;
+ int16_t *src = temp;
+ int n = ret / samplesize;
+ for (i = 0; i < n; i++) {
+ for (j = 0; j < _info->fmt.channels; j++) {
+ ((int16_t *)(bytes + samplesize * i))[remap[idx][j]] = src[j];
}
+ src += _info->fmt.channels;
}
- ret = n * out_ch * 2;
}
}
- else {
- ret=ov_read (&info->vorbis_file, bytes, size, endianess, 2, 1, &info->cur_bit_stream);
- }
if (ret <= 0)
{
if (ret < 0) {
@@ -352,12 +389,12 @@ cvorbis_read (DB_fileinfo_t *_info, char *bytes, int size) {
}
else if (ret < size)
{
- info->currentsample += ret / (out_ch * 2);
+ info->currentsample += ret / samplesize;
size -= ret;
bytes += ret;
}
else {
- info->currentsample += ret / (out_ch * 2);
+ info->currentsample += ret / samplesize;
size = 0;
break;
}
@@ -410,10 +447,10 @@ cvorbis_insert (DB_playItem_t *after, const char *fname) {
trace ("vorbis: failed to fopen %s\n", fname);
return NULL;
}
- if (fp->vfs->streaming) {
- DB_playItem_t *it = deadbeef->pl_item_alloc ();
- it->fname = strdup (fname);
- it->filetype = "OggVorbis";
+ int64_t fsize = deadbeef->fgetlength (fp);
+ if (fp->vfs->is_streaming ()) {
+ DB_playItem_t *it = deadbeef->pl_item_alloc_init (fname, plugin.plugin.id);
+ deadbeef->pl_add_meta (it, ":FILETYPE", "OggVorbis");
deadbeef->pl_set_item_duration (it, -1);
deadbeef->pl_add_meta (it, "title", NULL);
after = deadbeef->pl_insert_item (after, it);
@@ -448,11 +485,9 @@ cvorbis_insert (DB_playItem_t *after, const char *fname) {
float duration = ov_time_total (&vorbis_file, stream);
int totalsamples = ov_pcm_total (&vorbis_file, stream);
- DB_playItem_t *it = deadbeef->pl_item_alloc ();
- it->decoder_id = deadbeef->plug_get_decoder_id (plugin.plugin.id);
- it->fname = strdup (fname);
- it->filetype = "OggVorbis";
- it->tracknum = stream;
+ DB_playItem_t *it = deadbeef->pl_item_alloc_init (fname, plugin.plugin.id);
+ deadbeef->pl_add_meta (it, ":FILETYPE", "OggVorbis");
+ deadbeef->pl_set_meta_int (it, ":TRACKNUM", stream);
deadbeef->pl_set_item_duration (it, duration);
if (nstreams > 1) {
it->startsample = currentsample;
@@ -465,6 +500,19 @@ cvorbis_insert (DB_playItem_t *after, const char *fname) {
update_vorbis_comments (it, vc, 0);
int samplerate = vi->rate;
+ char s[100];
+ snprintf (s, sizeof (s), "%lld", fsize);
+ deadbeef->pl_add_meta (it, ":FILE_SIZE", s);
+ deadbeef->pl_add_meta (it, ":BPS", "16");
+ snprintf (s, sizeof (s), "%d", vi->channels);
+ deadbeef->pl_add_meta (it, ":CHANNELS", s);
+ snprintf (s, sizeof (s), "%d", samplerate);
+ deadbeef->pl_add_meta (it, ":SAMPLERATE", s);
+ int br = (int)roundf(fsize / duration * 8 / 1000);
+ snprintf (s, sizeof (s), "%d", br);
+ deadbeef->pl_add_meta (it, ":BITRATE", s);
+
+
if (nstreams == 1) {
DB_playItem_t *cue = deadbeef->pl_insert_cue (after, it, totalsamples, samplerate);
if (cue) {
@@ -513,12 +561,12 @@ cvorbis_read_metadata (DB_playItem_t *it) {
OggVorbis_File vorbis_file;
vorbis_info *vi = NULL;
- fp = deadbeef->fopen (it->fname);
+ fp = deadbeef->fopen (deadbeef->pl_find_meta (it, ":URI"));
if (!fp) {
trace ("cvorbis_read_metadata: failed to fopen %s\n", it->fname);
return -1;
}
- if (fp->vfs->streaming) {
+ if (fp->vfs->is_streaming ()) {
trace ("cvorbis_read_metadata: failed to fopen %s\n", it->fname);
goto error;
}
@@ -533,14 +581,15 @@ cvorbis_read_metadata (DB_playItem_t *it) {
trace ("cvorbis_read_metadata: ov_open_callbacks returned %d\n", res);
goto error;
}
- vi = ov_info (&vorbis_file, it->tracknum);
+ int tracknum = deadbeef->pl_find_meta_int (it, ":TRACKNUM", -1);
+ vi = ov_info (&vorbis_file, tracknum);
if (!vi) { // not a vorbis stream
trace ("cvorbis_read_metadata: failed to ov_open %s\n", it->fname);
goto error;
}
// metainfo
- vorbis_comment *vc = ov_comment (&vorbis_file, it->tracknum);
+ vorbis_comment *vc = ov_comment (&vorbis_file, tracknum);
if (vc) {
update_vorbis_comments (it, vc, 0);
}
@@ -576,7 +625,7 @@ cvorbis_write_metadata (DB_playItem_t *it) {
trace ("cvorbis_write_metadata: vcedit_new_state failed\n");
return -1;
}
- fp = fopen (it->fname, "rb");
+ fp = fopen (deadbeef->pl_find_meta (it, ":URI"), "rb");
if (!fp) {
trace ("cvorbis_write_metadata: failed to read metadata from %s\n", it->fname);
goto error;
@@ -592,6 +641,7 @@ cvorbis_write_metadata (DB_playItem_t *it) {
goto error;
}
+#if 0
// copy all unknown fields to separate buffer
for (int i = 0; i < vc->comments; i++) {
int m;
@@ -612,42 +662,55 @@ cvorbis_write_metadata (DB_playItem_t *it) {
preserved_fields = f;
}
}
+#endif
vorbis_comment_clear(vc);
vorbis_comment_init(vc);
- // add known fields
- for (int m = 0; metainfo[m]; m += 2) {
- const char *val = deadbeef->pl_find_meta (it, metainfo[m+1]);
- if (val && *val) {
- while (val) {
- const char *next = strchr (val, '\n');
- int l;
- if (next) {
- l = next - val;
- next++;
- }
- else {
- l = strlen (val);
+ // add unknown/custom fields
+ deadbeef->pl_lock ();
+ DB_metaInfo_t *m = deadbeef->pl_get_metadata_head (it);
+ while (m) {
+ if (m->key[0] != ':') {
+ int i;
+ for (i = 0; metainfo[i]; i += 2) {
+ if (!strcasecmp (metainfo[i+1], m->key)) {
+ break;
}
- if (l > 0) {
- char s[100+l+1];
- int n = snprintf (s, sizeof (s), "%s=", metainfo[m]);
- strncpy (s+n, val, l);
- *(s+n+l) = 0;
- vorbis_comment_add (vc, s);
+ }
+ const char *val = m->value;
+ if (val && *val) {
+ while (val) {
+ const char *next = strchr (val, '\n');
+ int l;
+ if (next) {
+ l = next - val;
+ next++;
+ }
+ else {
+ l = strlen (val);
+ }
+ if (l > 0) {
+ char s[100+l+1];
+ int n = snprintf (s, sizeof (s), "%s=", metainfo[i] ? metainfo[i] : m->key);
+ strncpy (s+n, val, l);
+ *(s+n+l) = 0;
+ vorbis_comment_add (vc, s);
+ }
+ val = next;
}
- val = next;
}
}
+ m = m->next;
}
+ deadbeef->pl_unlock ();
// add preserved fields
for (struct field *f = preserved_fields; f; f = f->next) {
vorbis_comment_add (vc, f->data);
}
- snprintf (outname, sizeof (outname), "%s.temp.ogg", it->fname);
+ snprintf (outname, sizeof (outname), "%s.temp.ogg", deadbeef->pl_find_meta (it, ":URI"));
out = fopen (outname, "w+b");
if (!out) {
@@ -678,7 +741,7 @@ error:
}
if (!err) {
- rename (outname, it->fname);
+ rename (outname, deadbeef->pl_find_meta (it, ":URI"));
}
else if (out) {
unlink (outname);
@@ -694,21 +757,36 @@ static const char *filetypes[] = { "OggVorbis", NULL };
// define plugin interface
static DB_decoder_t plugin = {
DB_PLUGIN_SET_API_VERSION
- .plugin.version_major = 0,
- .plugin.version_minor = 1,
+ .plugin.version_major = 1,
+ .plugin.version_minor = 0,
.plugin.type = DB_PLUGIN_DECODER,
.plugin.id = "stdogg",
.plugin.name = "OggVorbis decoder",
.plugin.descr = "OggVorbis decoder using standard xiph.org libraries",
- .plugin.author = "Alexey Yakovenko",
- .plugin.email = "waker@users.sourceforge.net",
+ .plugin.copyright =
+ "Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>\n"
+ "\n"
+ "This program is free software; you can redistribute it and/or\n"
+ "modify it under the terms of the GNU General Public License\n"
+ "as published by the Free Software Foundation; either version 2\n"
+ "of the License, or (at your option) any later version.\n"
+ "\n"
+ "This program is distributed in the hope that it will be useful,\n"
+ "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+ "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+ "GNU General Public License for more details.\n"
+ "\n"
+ "You should have received a copy of the GNU General Public License\n"
+ "along with this program; if not, write to the Free Software\n"
+ "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n"
+ ,
.plugin.website = "http://deadbeef.sf.net",
.plugin.start = vorbis_start,
.plugin.stop = vorbis_stop,
.open = cvorbis_open,
.init = cvorbis_init,
.free = cvorbis_free,
- .read_int16 = cvorbis_read,
+ .read = cvorbis_read,
// vorbisfile can't output float32
// .read_float32 = cvorbis_read_float32,
.seek = cvorbis_seek,
diff --git a/plugins/vtx/vtx.c b/plugins/vtx/vtx.c
index 3e4ed6b9..aa62422e 100644
--- a/plugins/vtx/vtx.c
+++ b/plugins/vtx/vtx.c
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@@ -47,7 +47,7 @@ typedef struct {
} vtx_info_t;
static DB_fileinfo_t *
-vtx_open (void) {
+vtx_open (uint32_t hints) {
DB_fileinfo_t *_info = malloc (sizeof (vtx_info_t));
memset (_info, 0, sizeof (vtx_info_t));
return _info;
@@ -62,9 +62,9 @@ vtx_init (DB_fileinfo_t *_info, DB_playItem_t *it) {
size_t sz = 0;
char *buf = NULL;
- DB_FILE *fp = deadbeef->fopen (it->fname);
+ DB_FILE *fp = deadbeef->fopen (deadbeef->pl_find_meta (it, ":URI"));
if (!fp) {
- trace ("vtx: failed to open file %s\n", it->fname);
+ trace ("vtx: failed to open file %s\n", deadbeef->pl_find_meta (it, ":URI"));
return -1;
}
@@ -102,16 +102,21 @@ vtx_init (DB_fileinfo_t *_info, DB_playItem_t *it) {
int samplerate = deadbeef->conf_get_int ("synth.samplerate", 44100);
- ayemu_set_sound_format (&info->ay, samplerate, deadbeef->get_output ()->channels (), deadbeef->get_output ()->bitspersample ());
-
info->left = 0;
- info->rate = deadbeef->get_output ()->channels () * deadbeef->get_output ()->bitspersample () / 8;
info->vtx_pos = 0;
_info->plugin = &plugin;
- _info->bps = deadbeef->get_output ()->bitspersample ();
- _info->channels = deadbeef->get_output ()->channels ();
- _info->samplerate = samplerate;
+ _info->fmt.bps = deadbeef->conf_get_int ("vtx.bps", 16);;
+ if (_info->fmt.bps != 16 && _info->fmt.bps != 8) {
+ _info->fmt.bps = 16;
+ }
+ _info->fmt.channels = 2;
+ _info->fmt.samplerate = samplerate;
+ _info->fmt.channelmask = _info->fmt.channels == 1 ? DDB_SPEAKER_FRONT_LEFT : (DDB_SPEAKER_FRONT_LEFT | DDB_SPEAKER_FRONT_RIGHT);
_info->readpos = 0;
+
+ ayemu_set_sound_format (&info->ay, samplerate, _info->fmt.channels, _info->fmt.bps);
+
+ info->rate = _info->fmt.channels * _info->fmt.bps / 8;
return 0;
}
@@ -149,7 +154,7 @@ ayemu_vtx_get_next_frame (vtx_info_t *info)
}
static int
-vtx_read_int16 (DB_fileinfo_t *_info, char *bytes, int size) {
+vtx_read (DB_fileinfo_t *_info, char *bytes, int size) {
// try decode `size' bytes
// return number of decoded bytes
// return 0 on EOF
@@ -170,7 +175,7 @@ vtx_read_int16 (DB_fileinfo_t *_info, char *bytes, int size) {
}
else {
// number of samples it current frame
- info->left = _info->samplerate / info->decoder->playerFreq;
+ info->left = _info->fmt.samplerate / info->decoder->playerFreq;
// mul by rate to get number of bytes;
info->left *= info->rate;
ayemu_set_regs (&info->ay, info->regs);
@@ -179,7 +184,7 @@ vtx_read_int16 (DB_fileinfo_t *_info, char *bytes, int size) {
}
}
info->currentsample += (initsize - size) / 4;
- _info->readpos = (float)info->currentsample / _info->samplerate;
+ _info->readpos = (float)info->currentsample / _info->fmt.samplerate;
return initsize - size;
}
@@ -192,7 +197,7 @@ vtx_seek_sample (DB_fileinfo_t *_info, int sample) {
// get frame
int num_frames = info->decoder->regdata_size / AY_FRAME_SIZE;
- int samples_per_frame = _info->samplerate / info->decoder->playerFreq;
+ int samples_per_frame = _info->fmt.samplerate / info->decoder->playerFreq;
// start of frame
info->vtx_pos = sample / samples_per_frame;
@@ -206,11 +211,11 @@ vtx_seek_sample (DB_fileinfo_t *_info, int sample) {
info->regs[n] = *p;
}
// set number of bytes left in frame
- info->left = _info->samplerate / info->decoder->playerFreq - (sample % samples_per_frame);
+ info->left = _info->fmt.samplerate / info->decoder->playerFreq - (sample % samples_per_frame);
// mul by rate to get number of bytes
info->left *= info->rate;
info->currentsample = sample;
- _info->readpos = (float)info->currentsample / _info->samplerate;
+ _info->readpos = (float)info->currentsample / _info->fmt.samplerate;
return 0;
}
@@ -220,7 +225,7 @@ vtx_seek (DB_fileinfo_t *_info, float time) {
// seek to specified time in seconds
// return 0 on success
// return -1 on failure
- return vtx_seek_sample (_info, time * _info->samplerate);
+ return vtx_seek_sample (_info, time * _info->fmt.samplerate);
}
static DB_playItem_t *
@@ -253,11 +258,8 @@ vtx_insert (DB_playItem_t *after, const char *fname) {
}
trace ("vtx: datasize: %d\n", hdr->regdata_size);
- DB_playItem_t *it = deadbeef->pl_item_alloc ();
-
- it->decoder_id = deadbeef->plug_get_decoder_id (plugin.plugin.id);
- it->fname = strdup (fname);
- it->filetype = filetypes[0];
+ DB_playItem_t *it = deadbeef->pl_item_alloc_init (fname, plugin.plugin.id);
+ deadbeef->pl_add_meta (it, ":FILETYPE", filetypes[0]);
int numframes = hdr->regdata_size / AY_FRAME_SIZE;
// int totalsamples = numframes * hdr->playerFreq;
@@ -290,25 +292,48 @@ vtx_stop (void) {
// return -1 on failure
return 0;
}
+
+static const char settings_dlg[] =
+ "property \"Bits Per Sample (8 or 16)\" entry vtx.bps 16;\n"
+;
+
// define plugin interface
static DB_decoder_t plugin = {
DB_PLUGIN_SET_API_VERSION
- .plugin.version_major = 0,
- .plugin.version_minor = 1,
+ .plugin.version_major = 1,
+ .plugin.version_minor = 0,
.plugin.type = DB_PLUGIN_DECODER,
.plugin.id = "vtx",
.plugin.name = "VTX decoder",
.plugin.descr = "AY8910/12 chip emulator and vtx file player",
- .plugin.author = "Alexey Yakovenko",
- .plugin.email = "waker@users.sourceforge.net",
+ .plugin.copyright =
+ "Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>\n"
+ "\n"
+ "Uses libayemu - AY/YM sound chip emulator and music file loader\n"
+ "Copyright (C) 2003-2004 Sashnov Alexander\n"
+ "\n"
+ "This program is free software; you can redistribute it and/or\n"
+ "modify it under the terms of the GNU General Public License\n"
+ "as published by the Free Software Foundation; either version 2\n"
+ "of the License, or (at your option) any later version.\n"
+ "\n"
+ "This program is distributed in the hope that it will be useful,\n"
+ "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+ "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+ "GNU General Public License for more details.\n"
+ "\n"
+ "You should have received a copy of the GNU General Public License\n"
+ "along with this program; if not, write to the Free Software\n"
+ "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n"
+ ,
.plugin.website = "http://deadbeef.sf.net",
.plugin.start = vtx_start,
.plugin.stop = vtx_stop,
+ .plugin.configdialog = settings_dlg,
.open = vtx_open,
.init = vtx_init,
.free = vtx_free,
- .read_int16 = vtx_read_int16,
-// .read_float32 = vtx_read_float32,
+ .read = vtx_read,
.seek = vtx_seek,
.seek_sample = vtx_seek_sample,
.insert = vtx_insert,
diff --git a/plugins/wavpack/COPYING b/plugins/wavpack/COPYING
new file mode 100644
index 00000000..f1cf0011
--- /dev/null
+++ b/plugins/wavpack/COPYING
@@ -0,0 +1,26 @@
+WavPack plugin for DeaDBeeF Player
+Copyright (C) 2009-2011, Alexey Yakovenko <waker@users.sourceforge.net>
+With contributions from David Bryant <david@wavpack.com>
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of the <organization> nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/plugins/wavpack/wavpack.c b/plugins/wavpack/wavpack.c
index e1eb4787..15973421 100644
--- a/plugins/wavpack/wavpack.c
+++ b/plugins/wavpack/wavpack.c
@@ -1,20 +1,30 @@
/*
- DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+WavPack plugin for DeaDBeeF Player
+Copyright (C) 2009-2011, Alexey Yakovenko <waker@users.sourceforge.net>
+Copyright (C) 2010-2011, David Bryant <david@wavpack.com>
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of the <organization> nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <string.h>
@@ -106,7 +116,7 @@ static WavpackStreamReader wsr = {
#endif
static DB_fileinfo_t *
-wv_open (void) {
+wv_open (uint32_t hints) {
DB_fileinfo_t *_info = malloc (sizeof (wvctx_t));
memset (_info, 0, sizeof (wvctx_t));
return _info;
@@ -115,15 +125,15 @@ wv_open (void) {
static int
wv_init (DB_fileinfo_t *_info, DB_playItem_t *it) {
wvctx_t *info = (wvctx_t *)_info;
- info->file = deadbeef->fopen (it->fname);
+ info->file = deadbeef->fopen (deadbeef->pl_find_meta (it, ":URI"));
if (!info->file) {
return -1;
}
#ifndef TINYWV
- char *c_fname = alloca (strlen (it->fname) + 2);
+ char *c_fname = alloca (strlen (deadbeef->pl_find_meta (it, ":URI")) + 2);
if (c_fname) {
- strcpy (c_fname, it->fname);
+ strcpy (c_fname, deadbeef->pl_find_meta (it, ":URI"));
strcat (c_fname, "c");
info->c_file = deadbeef->fopen (c_fname);
}
@@ -136,16 +146,18 @@ wv_init (DB_fileinfo_t *_info, DB_playItem_t *it) {
#ifdef TINYWV
info->ctx = WavpackOpenFileInput (wv_read_stream, info->file, error);
#else
- info->ctx = WavpackOpenFileInputEx (&wsr, info->file, info->c_file, error, OPEN_2CH_MAX | OPEN_NORMALIZE, 0);
+ info->ctx = WavpackOpenFileInputEx (&wsr, info->file, info->c_file, error, OPEN_NORMALIZE, 0);
#endif
if (!info->ctx) {
fprintf (stderr, "wavpack error: %s\n", error);
return -1;
}
_info->plugin = &plugin;
- _info->bps = WavpackGetBytesPerSample (info->ctx) * 8;
- _info->channels = WavpackGetNumChannels (info->ctx);
- _info->samplerate = WavpackGetSampleRate (info->ctx);
+ _info->fmt.bps = WavpackGetBytesPerSample (info->ctx) * 8;
+ _info->fmt.channels = WavpackGetNumChannels (info->ctx);
+ _info->fmt.samplerate = WavpackGetSampleRate (info->ctx);
+ _info->fmt.is_float = (WavpackGetMode (info->ctx) & MODE_FLOAT) ? 1 : 0;
+ _info->fmt.channelmask = WavpackGetChannelMask (info->ctx);
_info->readpos = 0;
if (it->endsample > 0) {
info->startsample = it->startsample;
@@ -184,49 +196,57 @@ wv_free (DB_fileinfo_t *_info) {
}
static int
-wv_read_int16 (DB_fileinfo_t *_info, char *bytes, int size) {
+wv_read (DB_fileinfo_t *_info, char *bytes, int size) {
wvctx_t *info = (wvctx_t *)_info;
int currentsample = WavpackGetSampleIndex (info->ctx);
- int nchannels = WavpackGetReducedChannels (info->ctx);
- if (size / (2 * nchannels) + currentsample > info->endsample) {
- size = (info->endsample - currentsample + 1) * 2 * nchannels;
- trace ("wv: size truncated to %d bytes, cursample=%d, endsample=%d\n", size, currentsample, info->endsample);
+ int samplesize = _info->fmt.channels * _info->fmt.bps / 8;
+ if (size / samplesize + currentsample > info->endsample) {
+ size = (info->endsample - currentsample + 1) * samplesize;
+ trace ("wv: size truncated to %d bytes (%d samples), cursample=%d, endsample=%d\n", size, info->endsample - currentsample + 1, currentsample, info->endsample);
if (size <= 0) {
return 0;
}
}
- int32_t buffer[size/2];
- int n = WavpackUnpackSamples (info->ctx, buffer, size/(2*nchannels));
- size = n * 2 * nchannels;
- // convert to int16
- int32_t *p = buffer;
- n *= nchannels;
-
+ int initsize = size;
+ int n;
if (WavpackGetMode (info->ctx) & MODE_FLOAT) {
- while (n > 0) {
- float val = *(float*)p;
- if (val >= 1.0)
- *((int16_t *)bytes) = 32767;
- else if (val <= -1.0)
- *((int16_t *)bytes) = -32768;
- else
- *((int16_t *)bytes) = floor (val * 32768.f);
- bytes += sizeof (int16_t);
- p++;
- n--;
- }
+ _info->fmt.is_float = 1;
+ }
+ if (_info->fmt.is_float || _info->fmt.bps == 32) {
+ n = WavpackUnpackSamples (info->ctx, (int32_t *)bytes, size / samplesize);
+ size -= n * samplesize;
}
else {
- while (n > 0) {
- if (_info->bps >= 16) {
- *((int16_t *)bytes) = (int16_t)((*p) >> (_info->bps-16));
+ int32_t buffer[size/(_info->fmt.bps / 8)];
+ n = WavpackUnpackSamples (info->ctx, (int32_t *)buffer, size / samplesize);
+ size -= n * samplesize;
+ n *= _info->fmt.channels;
+
+ // convert from int32 to input (what???)
+ int32_t *p = buffer;
+ if (_info->fmt.bps == 16) {
+ while (n > 0) {
+ *((int16_t *)bytes) = (int16_t)(*p);
+ bytes += sizeof (int16_t);
+ p++;
+ n--;
}
- else {
- *((int16_t *)bytes) = (int16_t)((*p) << (16-_info->bps));
+ }
+ else if (_info->fmt.bps == 8) {
+ while (n > 0) {
+ *bytes++ = (char)(*p);
+ p++;
+ n--;
+ }
+ }
+ else if (_info->fmt.bps == 24) {
+ while (n > 0) {
+ *bytes++ = (*p)&0xff;
+ *bytes++ = ((*p)&0xff00)>>8;
+ *bytes++ = ((*p)&0xff0000)>>16;
+ p++;
+ n--;
}
- bytes += sizeof (int16_t);
- p++;
- n--;
}
}
_info->readpos = (float)(WavpackGetSampleIndex (info->ctx)-info->startsample)/WavpackGetSampleRate (info->ctx);
@@ -235,45 +255,7 @@ wv_read_int16 (DB_fileinfo_t *_info, char *bytes, int size) {
deadbeef->streamer_set_bitrate (WavpackGetInstantBitrate (info->ctx) / 1000);
#endif
- return size;
-}
-
-static int
-wv_read_float32 (DB_fileinfo_t *_info, char *bytes, int size) {
- wvctx_t *info = (wvctx_t *)_info;
- int nchannels = WavpackGetReducedChannels (info->ctx);
- int currentsample = WavpackGetSampleIndex (info->ctx);
- if (size / (4 * nchannels) + currentsample > info->endsample) {
- size = (info->endsample - currentsample + 1) * 4 * nchannels;
- trace ("wv: size truncated to %d bytes, cursample=%d, endsample=%d\n", size, currentsample, info->endsample);
- if (size <= 0) {
- return 0;
- }
- }
- int32_t buffer[size/4];
- int n = WavpackUnpackSamples (info->ctx, buffer, size/(4*nchannels));
- size = n * 4 * nchannels;
- // convert to float32
- n *= nchannels;
-
- if (WavpackGetMode (info->ctx) & MODE_FLOAT) {
- memcpy (bytes, buffer, size);
- }
- else {
- float mul = 1.f/ (1UL << (_info->bps-1));
- int32_t *p = buffer;
- while (n > 0) {
- *((float *)bytes) = (*p) * mul;
- bytes += sizeof (float);
- p++;
- n--;
- }
- }
- _info->readpos = (float)(WavpackGetSampleIndex (info->ctx)-info->startsample)/WavpackGetSampleRate (info->ctx);
-#ifndef TINYWV
- deadbeef->streamer_set_bitrate (WavpackGetInstantBitrate (info->ctx) / 1000);
-#endif
- return size;
+ return initsize-size;
}
static int
@@ -294,7 +276,6 @@ wv_seek (DB_fileinfo_t *_info, float sec) {
static DB_playItem_t *
wv_insert (DB_playItem_t *after, const char *fname) {
-
DB_FILE *fp = deadbeef->fopen (fname);
if (!fp) {
return NULL;
@@ -314,10 +295,8 @@ wv_insert (DB_playItem_t *after, const char *fname) {
int samplerate = WavpackGetSampleRate (ctx);
float duration = (float)totalsamples / samplerate;
- DB_playItem_t *it = deadbeef->pl_item_alloc ();
- it->decoder_id = deadbeef->plug_get_decoder_id (plugin.plugin.id);
- it->fname = strdup (fname);
- it->filetype = "wv";
+ DB_playItem_t *it = deadbeef->pl_item_alloc_init (fname, plugin.plugin.id);
+ deadbeef->pl_add_meta (it, ":FILETYPE", "wv");
deadbeef->pl_set_item_duration (it, duration);
trace ("wv: totalsamples=%d, samplerate=%d, duration=%f\n", totalsamples, samplerate, duration);
@@ -340,28 +319,21 @@ wv_insert (DB_playItem_t *after, const char *fname) {
if (!v1err) {
trace ("wv: id3v1 tag found\n");
}
-
-#if 0
- // embedded cue
- char *emb_cuesheet;
- int len = WavpackGetTagItem (ctx, "cuesheet", NULL, 0);
- if (len) {
- emb_cuesheet = malloc (len);
- if (emb_cuesheet) {
- WavpackGetTagItem (ctx, "Cuesheet", emb_cuesheet, len);
- trace ("got cuesheet\n%s\n", emb_cuesheet);
- DB_playItem_t *last = deadbeef->pl_insert_cue_from_buffer (after, it, emb_cuesheet, strlen (emb_cuesheet), totalsamples, samplerate);
- free (emb_cuesheet);
- if (last) {
- deadbeef->pl_item_unref (it);
- deadbeef->fclose (fp);
- WavpackCloseFile (ctx);
- return last;
- }
- trace ("pl_insert_cue_from_buffer failed!\n");
- }
- }
-#endif
+ deadbeef->pl_add_meta (it, "title", NULL);
+
+ char s[100];
+ snprintf (s, sizeof (s), "%lld", deadbeef->fgetlength (fp));
+ deadbeef->pl_add_meta (it, ":FILE_SIZE", s);
+ snprintf (s, sizeof (s), "%d", WavpackGetBytesPerSample (ctx) * 8);
+ deadbeef->pl_add_meta (it, ":BPS", s);
+ snprintf (s, sizeof (s), "%d", WavpackGetNumChannels (ctx));
+ deadbeef->pl_add_meta (it, ":CHANNELS", s);
+ snprintf (s, sizeof (s), "%d", WavpackGetSampleRate (ctx));
+ deadbeef->pl_add_meta (it, ":SAMPLERATE", s);
+ snprintf (s, sizeof (s), "%d", (int)(WavpackGetAverageBitrate (ctx, 1) / 1000));
+ deadbeef->pl_add_meta (it, ":BITRATE", s);
+ snprintf (s, sizeof (s), "%s", (WavpackGetMode (ctx) & MODE_FLOAT) ? "FLOAT" : "INTEGER");
+ deadbeef->pl_add_meta (it, ":WAVPACK_MODE", s);
// embedded cue
const char *cuesheet = deadbeef->pl_find_meta (it, "cuesheet");
@@ -396,7 +368,7 @@ wv_insert (DB_playItem_t *after, const char *fname) {
int
wv_read_metadata (DB_playItem_t *it) {
- DB_FILE *fp = deadbeef->fopen (it->fname);
+ DB_FILE *fp = deadbeef->fopen (deadbeef->pl_find_meta (it, ":URI"));
if (!fp) {
return -1;
}
@@ -442,20 +414,45 @@ static const char *filetypes[] = { "wv", NULL };
// define plugin interface
static DB_decoder_t plugin = {
DB_PLUGIN_SET_API_VERSION
- .plugin.version_major = 0,
- .plugin.version_minor = 1,
+ .plugin.version_major = 1,
+ .plugin.version_minor = 0,
.plugin.type = DB_PLUGIN_DECODER,
.plugin.id = "wv",
.plugin.name = "WavPack decoder",
- .plugin.descr = ".wv player using libwavpack",
- .plugin.author = "Alexey Yakovenko",
- .plugin.email = "waker@users.sourceforge.net",
+ .plugin.descr = "WavPack (.wv, .iso.wv) player",
+ .plugin.copyright =
+ "WavPack plugin for DeaDBeeF Player\n"
+ "Copyright (C) 2009-2011, Alexey Yakovenko <waker@users.sourceforge.net>\n"
+ "Copyright (C) 2010-2011, David Bryant <david@wavpack.com>\n"
+ "All rights reserved.\n"
+ "\n"
+ "Redistribution and use in source and binary forms, with or without\n"
+ "modification, are permitted provided that the following conditions are met:\n"
+ " * Redistributions of source code must retain the above copyright\n"
+ " notice, this list of conditions and the following disclaimer.\n"
+ " * Redistributions in binary form must reproduce the above copyright\n"
+ " notice, this list of conditions and the following disclaimer in the\n"
+ " documentation and/or other materials provided with the distribution.\n"
+ " * Neither the name of the <organization> nor the\n"
+ " names of its contributors may be used to endorse or promote products\n"
+ " derived from this software without specific prior written permission.\n"
+ "\n"
+ "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n"
+ "ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n"
+ "WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n"
+ "DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY\n"
+ "DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n"
+ "(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n"
+ "LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n"
+ "ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n"
+ "(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n"
+ "SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
+ ,
.plugin.website = "http://deadbeef.sf.net",
.open = wv_open,
.init = wv_init,
.free = wv_free,
- .read_int16 = wv_read_int16,
- .read_float32 = wv_read_float32,
+ .read = wv_read,
.seek = wv_seek,
.seek_sample = wv_seek_sample,
.insert = wv_insert,
diff --git a/plugins/wildmidi/wildmidiplug.c b/plugins/wildmidi/wildmidiplug.c
index e9c976b3..87aee260 100644
--- a/plugins/wildmidi/wildmidiplug.c
+++ b/plugins/wildmidi/wildmidiplug.c
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@@ -42,7 +42,7 @@ typedef struct {
} wmidi_info_t;
DB_fileinfo_t *
-wmidi_open (void) {
+wmidi_open (uint32_t hints) {
DB_fileinfo_t *_info = (DB_fileinfo_t *)malloc (sizeof (wmidi_info_t));
memset (_info, 0, sizeof (wmidi_info_t));
return _info;
@@ -52,16 +52,17 @@ int
wmidi_init (DB_fileinfo_t *_info, DB_playItem_t *it) {
wmidi_info_t *info = (wmidi_info_t *)_info;
- info->m = WildMidi_Open (it->fname);
+ info->m = WildMidi_Open (deadbeef->pl_find_meta (it, ":URI"));
if (!info->m) {
- trace ("wmidi: failed to open %s\n", it->fname);
+ trace ("wmidi: failed to open %s\n", deadbeef->pl_find_meta (it, ":URI"));
return -1;
}
_info->plugin = &wmidi_plugin;
- _info->channels = 2;
- _info->bps = 16;
- _info->samplerate = 44100;
+ _info->fmt.channels = 2;
+ _info->fmt.bps = 16;
+ _info->fmt.samplerate = 44100;
+ _info->fmt.channelmask = _info->fmt.channels == 1 ? DDB_SPEAKER_FRONT_LEFT : (DDB_SPEAKER_FRONT_LEFT | DDB_SPEAKER_FRONT_RIGHT);
_info->readpos = 0;
return 0;
@@ -96,13 +97,13 @@ wmidi_seek_sample (DB_fileinfo_t *_info, int sample) {
wmidi_info_t *info = (wmidi_info_t *)_info;
unsigned long int s = sample;
WildMidi_SampledSeek (info->m, &s);
- _info->readpos = s/44100.0f;
+ _info->readpos = s/(float)_info->fmt.samplerate;
return 0;
}
int
wmidi_seek (DB_fileinfo_t *_info, float time) {
- return wmidi_seek_sample (_info, time * 44100);
+ return wmidi_seek_sample (_info, time * _info->fmt.samplerate);
}
DB_playItem_t *
@@ -116,12 +117,10 @@ wmidi_insert (DB_playItem_t *after, const char *fname) {
}
struct _WM_Info *inf = WildMidi_GetInfo (m);
- it = deadbeef->pl_item_alloc ();
- it->decoder_id = deadbeef->plug_get_decoder_id (wmidi_plugin.plugin.id);
- it->fname = strdup (fname);
+ it = deadbeef->pl_item_alloc_init (fname, wmidi_plugin.plugin.id);
deadbeef->pl_add_meta (it, "title", NULL);
deadbeef->pl_set_item_duration (it, inf->approx_total_samples / 44100.f);
- it->filetype = "MID";
+ deadbeef->pl_add_meta (it, ":FILETYPE", "MID");
after = deadbeef->pl_insert_item (after, it);
deadbeef->pl_item_unref (it);
WildMidi_Close (m);
@@ -132,7 +131,8 @@ wmidi_insert (DB_playItem_t *after, const char *fname) {
int
wmidi_start (void) {
- const char *config_files = deadbeef->conf_get_str ("wildmidi.config", DEFAULT_TIMIDITY_CONFIG);
+ char config_files[1000];
+ deadbeef->conf_get_str ("wildmidi.config", DEFAULT_TIMIDITY_CONFIG, config_files, sizeof (config_files));
char config[1024] = "";
const char *p = config_files;
while (p) {
@@ -186,12 +186,30 @@ static const char settings_dlg[] =
DB_decoder_t wmidi_plugin = {
DB_PLUGIN_SET_API_VERSION
.plugin.type = DB_PLUGIN_DECODER,
- .plugin.version_major = 0,
- .plugin.version_minor = 1,
+ .plugin.version_major = 1,
+ .plugin.version_minor = 0,
.plugin.name = "WildMidi player",
- .plugin.descr = "MIDI player based on WildMidi library",
- .plugin.author = "Alexey Yakovenko",
- .plugin.email = "waker@users.sourceforge.net",
+ .plugin.descr = "MIDI player based on WildMidi library\n\nRequires freepats package to be installed\nSee http://freepats.zenvoid.org/\nMake sure to set correct freepats.cfg path in plugin settings.",
+ .plugin.copyright =
+ "Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>\n"
+ "\n"
+ "Uses modified WildMidi v0.2.2\n"
+ "(C) 2001-2004 Chris Ison\n"
+ "\n"
+ "This program is free software; you can redistribute it and/or\n"
+ "modify it under the terms of the GNU General Public License\n"
+ "as published by the Free Software Foundation; either version 2\n"
+ "of the License, or (at your option) any later version.\n"
+ "\n"
+ "This program is distributed in the hope that it will be useful,\n"
+ "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+ "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+ "GNU General Public License for more details.\n"
+ "\n"
+ "You should have received a copy of the GNU General Public License\n"
+ "along with this program; if not, write to the Free Software\n"
+ "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n"
+ ,
.plugin.website = "http://deadbeef.sf.net",
.plugin.start = wmidi_start,
.plugin.stop = wmidi_stop,
@@ -200,7 +218,7 @@ DB_decoder_t wmidi_plugin = {
.open = wmidi_open,
.init = wmidi_init,
.free = wmidi_free,
- .read_int16 = wmidi_read,
+ .read = wmidi_read,
.seek = wmidi_seek,
.seek_sample = wmidi_seek_sample,
.insert = wmidi_insert,
diff --git a/po/LINGUAS b/po/LINGUAS
index 91638f0f..87d75b1a 100644
--- a/po/LINGUAS
+++ b/po/LINGUAS
@@ -1,4 +1,7 @@
+be
+bg
bn
+ca
da
de
el
@@ -9,11 +12,13 @@ fr
gl
he
hr
+hu
id
it
ja
kk
km
+lg
nl
pl
pt
@@ -23,6 +28,8 @@ sk
sr
sr@latin
sv
+tr
uk
vi
+zh_CN
zh_TW
diff --git a/po/be.po b/po/be.po
new file mode 100644
index 00000000..7c212a99
--- /dev/null
+++ b/po/be.po
@@ -0,0 +1,1457 @@
+# Deadbeef Audio Player
+# Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+# This file is distributed under the same license as the Deadbeef package.
+# Максім Томкавіч <quendimax@tut.by>, 2011.
+# Максім Тамковіч <quendimax@tut.by>, 2011.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: 0.4.2\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2010-10-01 22:33+0300\n"
+"PO-Revision-Date: 2011-02-15 00:37+0200\n"
+"Last-Translator: Максім Тамковіч <quendimax@tut.by>\n"
+"Language-Team: Belarusian <>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: \n"
+"Language: be\n"
+"Plural-Forms: \n"
+"X-Generator: Pootle 2.0.5\n"
+
+#: ../plugins/gtkui/callbacks.c:97
+msgid "Supported sound formats"
+msgstr "Падтрымліваемыя фарматы"
+
+#: ../plugins/gtkui/callbacks.c:108
+msgid "Other files (*)"
+msgstr "Іншыя файлы (*)"
+
+#: ../plugins/gtkui/callbacks.c:118
+msgid "Open file(s)..."
+msgstr "Адкрыць файл(ы)..."
+
+#: ../plugins/gtkui/callbacks.c:151
+msgid "Add file(s) to playlist..."
+msgstr "Дадаць файл(ы) у плэйліст..."
+
+#: ../plugins/gtkui/callbacks.c:190
+msgid "Add folder(s) to playlist..."
+msgstr "Дадаць каталог(і) у плэйліст..."
+
+#: ../plugins/gtkui/callbacks.c:192
+msgid "Follow symlinks"
+msgstr "Ісці па сімвалічных спасылках"
+
+#: ../plugins/gtkui/callbacks.c:667
+msgid "Failed while reading help file"
+msgstr "Не атрымалася прачытаць файл даведкі"
+
+#: ../plugins/gtkui/callbacks.c:677
+msgid "Failed to load help file"
+msgstr "Не атрымалася загрузіць файл даведкі"
+
+#: ../plugins/gtkui/callbacks.c:692
+msgid "help.txt"
+msgstr "help.ru.txt"
+
+#: ../plugins/gtkui/callbacks.c:693 ../plugins/gtkui/interface.c:1125
+#: ../plugins/gtkui/deadbeef.glade.h:52
+msgid "Help"
+msgstr "Даведка"
+
+#: ../plugins/gtkui/callbacks.c:703
+#, c-format
+msgid "About DeaDBeeF %s"
+msgstr "Аб праграме DeaDBeeF %s"
+
+#: ../plugins/gtkui/callbacks.c:705
+msgid "about.txt"
+msgstr "about.txt"
+
+#: ../plugins/gtkui/callbacks.c:716
+#, c-format
+msgid "DeaDBeeF %s ChangeLog"
+msgstr "Змены ў DeaDBeeF %s"
+
+#: ../plugins/gtkui/callbacks.c:718
+msgid "ChangeLog"
+msgstr "Змены"
+
+#: ../plugins/gtkui/callbacks.c:729
+msgid "COPYING.GPLv2"
+msgstr "COPYING.GPLv2"
+
+#: ../plugins/gtkui/callbacks.c:740
+msgid "COPYING.LGPLv2.1"
+msgstr "COPYING.LGPLv2.1"
+
+#: ../plugins/gtkui/callbacks.c:1080
+#, c-format
+msgid "DeaDBeeF Translators"
+msgstr "Перакладчыкі DeaDBeeF "
+
+#: ../plugins/gtkui/callbacks.c:1082
+msgid "translators.txt"
+msgstr "translators.txt"
+
+#: ../plugins/gtkui/ddbtabstrip.c:626
+msgid "Edit playlist"
+msgstr "Рэдагаваць плэйліст"
+
+#: ../plugins/gtkui/ddbtabstrip.c:701
+msgid "Rename Playlist"
+msgstr "Перайменаваць плэйліст"
+
+#: ../plugins/gtkui/ddbtabstrip.c:705
+msgid "Remove Playlist"
+msgstr "Выдаліць плэйліст"
+
+#: ../plugins/gtkui/ddbtabstrip.c:709
+msgid "Add New Playlist"
+msgstr "Дадаць новы плэйліст"
+
+#: ../plugins/gtkui/eq.c:113
+msgid "Save DeaDBeeF EQ Preset"
+msgstr "Захаваць перадусталёўкі эквалайзера DeaDBeeF"
+
+#: ../plugins/gtkui/eq.c:120
+msgid "DeaDBeeF EQ preset files (*.ddbeq)"
+msgstr "Файлы перадусталёвак DeaDBeeF (*.ddbeq)"
+
+#: ../plugins/gtkui/eq.c:151
+msgid "Load DeaDBeeF EQ Preset..."
+msgstr "Загрузіць перадусталёўкі эквалайзера DeaDBeeF..."
+
+#: ../plugins/gtkui/eq.c:155
+msgid "DeaDBeeF EQ presets (*.ddbeq)"
+msgstr "Перадусталёўкі эквалайзера DeaDBeeF (*.ddbeq)"
+
+#: ../plugins/gtkui/eq.c:214
+msgid "Import Foobar2000 EQ Preset..."
+msgstr "Імпартаваць перадусталёўку эквалайзера Foobar2000..."
+
+#: ../plugins/gtkui/eq.c:218
+msgid "Foobar2000 EQ presets (*.feq)"
+msgstr "Перадусталёўкі эквалайзера Foobar2000 (*.feq)"
+
+#: ../plugins/gtkui/eq.c:292
+msgid "Enable"
+msgstr "Уключыць"
+
+#: ../plugins/gtkui/eq.c:300
+msgid "Zero All"
+msgstr "Абнуліць усё"
+
+#: ../plugins/gtkui/eq.c:307
+msgid "Zero Preamp"
+msgstr "Абнуліць перадузмацненне"
+
+#: ../plugins/gtkui/eq.c:314
+msgid "Zero Bands"
+msgstr "Абнуліць частоты"
+
+#: ../plugins/gtkui/eq.c:321
+msgid "Save Preset"
+msgstr "Захаваць"
+
+#: ../plugins/gtkui/eq.c:328
+msgid "Load Preset"
+msgstr "Загрузіць"
+
+#: ../plugins/gtkui/eq.c:335
+msgid "Import Foobar2000 Preset"
+msgstr "Імпартаваць перадусталёўку Foobar2000"
+
+#: ../plugins/gtkui/gtkui.c:133
+#, c-format
+msgid "1 day %d:%02d:%02d"
+msgstr "1 дзень %d:%02d:%02d"
+
+#: ../plugins/gtkui/gtkui.c:136
+#, c-format
+msgid "%d days %d:%02d:%02d"
+msgstr "%d дзён %d:%02d:%02d"
+
+#: ../plugins/gtkui/gtkui.c:145
+#, c-format
+msgid "Stopped | %d tracks | %s total playtime"
+msgstr "Стоп | %d трэкаў | %s агульны час"
+
+#: ../plugins/gtkui/gtkui.c:158
+msgid "Mono"
+msgstr "Мона"
+
+#: ../plugins/gtkui/gtkui.c:158
+msgid "Stereo"
+msgstr "Стэрэа"
+
+#: ../plugins/gtkui/gtkui.c:183
+#, c-format
+msgid "| %4d kbps "
+msgstr "| %4d кбіт/с "
+
+#: ../plugins/gtkui/gtkui.c:189
+msgid "Paused | "
+msgstr "Паўза | "
+
+#: ../plugins/gtkui/gtkui.c:190
+#, c-format
+msgid ""
+"%s%s %s| %dHz | %d bit | %s | %d:%02d / %s | %d tracks | %s total playtime"
+msgstr ""
+"%s%s %s| %dГц | %d біт | %s | %d:%02d / %s | %d трэкаў | %s агульны час"
+
+#: ../plugins/gtkui/gtkui.c:661
+msgid "Save Playlist As"
+msgstr "Захаваць плэйліст як"
+
+#: ../plugins/gtkui/gtkui.c:670 ../plugins/gtkui/gtkui.c:731
+msgid "DeaDBeeF playlist files (*.dbpl)"
+msgstr "Файлы плэйлістоў DeaDBeeF (*.dbpl)"
+
+#: ../plugins/gtkui/gtkui.c:724
+msgid "Load Playlist"
+msgstr "Загрузіць плэйліст"
+
+#: ../plugins/gtkui/gtkui.c:864
+msgid "New Playlist"
+msgstr "Новы плэйліст"
+
+#: ../plugins/gtkui/gtkui.c:867
+#, c-format
+msgid "New Playlist (%d)"
+msgstr "Новы плэйліст (%d)"
+
+#: ../plugins/gtkui/interface.c:142 ../plugins/gtkui/deadbeef.glade.h:152
+msgid "_File"
+msgstr "_Файл"
+
+#: ../plugins/gtkui/interface.c:149 ../plugins/gtkui/deadbeef.glade.h:158
+msgid "_Open file(s)"
+msgstr "_Адкрыць файл(ы)"
+
+#: ../plugins/gtkui/interface.c:165 ../plugins/gtkui/deadbeef.glade.h:4
+msgid "Add file(s)"
+msgstr "Дадаць файл(ы)"
+
+#: ../plugins/gtkui/interface.c:173 ../plugins/gtkui/deadbeef.glade.h:6
+msgid "Add folder(s)"
+msgstr "Дадаць каталог(і)"
+
+#: ../plugins/gtkui/interface.c:181 ../plugins/gtkui/interface.c:2997
+#: ../plugins/gtkui/deadbeef.glade.h:7
+msgid "Add location"
+msgstr "Дадаць месцазнаходжанне"
+
+#: ../plugins/gtkui/interface.c:190 ../plugins/gtkui/deadbeef.glade.h:82
+msgid "New playlist"
+msgstr "Новы плэйліст"
+
+#: ../plugins/gtkui/interface.c:197 ../plugins/gtkui/deadbeef.glade.h:74
+msgid "Load playlist"
+msgstr "Загрузіць плэйліст"
+
+#: ../plugins/gtkui/interface.c:201 ../plugins/gtkui/deadbeef.glade.h:111
+msgid "Save playlist"
+msgstr "Захаваць плэйліст"
+
+#: ../plugins/gtkui/interface.c:205 ../plugins/gtkui/deadbeef.glade.h:112
+msgid "Save playlist as"
+msgstr "Захаваць плэйліст як"
+
+#: ../plugins/gtkui/interface.c:214 ../plugins/gtkui/deadbeef.glade.h:160
+msgid "_Quit"
+msgstr "_Выйсцi"
+
+#: ../plugins/gtkui/interface.c:225 ../plugins/gtkui/deadbeef.glade.h:151
+msgid "_Edit"
+msgstr "_Праўка"
+
+#: ../plugins/gtkui/interface.c:232 ../plugins/gtkui/deadbeef.glade.h:149
+msgid "_Clear"
+msgstr "_Ачысціць"
+
+#: ../plugins/gtkui/interface.c:240 ../plugins/gtkui/deadbeef.glade.h:116
+msgid "Select all"
+msgstr "Вылучыць усё"
+
+#: ../plugins/gtkui/interface.c:247 ../plugins/gtkui/deadbeef.glade.h:23
+msgid "Deselect all"
+msgstr "Зняць вылучэнне"
+
+#: ../plugins/gtkui/interface.c:254 ../plugins/gtkui/deadbeef.glade.h:57
+msgid "Invert selection"
+msgstr "Звярнуць вылучэнне"
+
+#: ../plugins/gtkui/interface.c:258 ../plugins/gtkui/deadbeef.glade.h:119
+msgid "Selection"
+msgstr "Вылучанае"
+
+#: ../plugins/gtkui/interface.c:265 ../plugins/gtkui/plcommon.c:426
+#: ../plugins/gtkui/prefwin.c:334 ../plugins/gtkui/deadbeef.glade.h:106
+msgid "Remove"
+msgstr "Выдаліць"
+
+#: ../plugins/gtkui/interface.c:273 ../plugins/gtkui/deadbeef.glade.h:18
+msgid "Crop"
+msgstr "Пакінуць вылучанае"
+
+#: ../plugins/gtkui/interface.c:277 ../plugins/gtkui/deadbeef.glade.h:153
+msgid "_Find"
+msgstr "_Знайсці"
+
+#: ../plugins/gtkui/interface.c:289 ../plugins/gtkui/interface.c:1733
+#: ../plugins/gtkui/deadbeef.glade.h:96
+msgid "Preferences"
+msgstr "Наладкі"
+
+#: ../plugins/gtkui/interface.c:293 ../plugins/gtkui/deadbeef.glade.h:162
+msgid "_View"
+msgstr "_Выгляд"
+
+#: ../plugins/gtkui/interface.c:300 ../plugins/gtkui/deadbeef.glade.h:122
+msgid "Status bar"
+msgstr "Радок стану"
+
+#: ../plugins/gtkui/interface.c:304 ../plugins/gtkui/deadbeef.glade.h:16
+msgid "Column headers"
+msgstr "Загалоўкі слупкоў"
+
+#: ../plugins/gtkui/interface.c:308 ../plugins/gtkui/deadbeef.glade.h:129
+msgid "Tabs"
+msgstr "Устаўкі"
+
+#: ../plugins/gtkui/interface.c:312 ../plugins/gtkui/deadbeef.glade.h:31
+msgid "Equalizer"
+msgstr "Эквалайзер"
+
+#: ../plugins/gtkui/interface.c:316 ../plugins/gtkui/deadbeef.glade.h:159
+msgid "_Playback"
+msgstr "Прай_граванне"
+
+#: ../plugins/gtkui/interface.c:323 ../plugins/gtkui/deadbeef.glade.h:85
+msgid "Order"
+msgstr "Чарга"
+
+#: ../plugins/gtkui/interface.c:330 ../plugins/gtkui/deadbeef.glade.h:73
+msgid "Linear"
+msgstr "Па чарзе"
+
+#: ../plugins/gtkui/interface.c:336 ../plugins/gtkui/deadbeef.glade.h:120
+msgid "Shuffle"
+msgstr "Уперамешку"
+
+#: ../plugins/gtkui/interface.c:342 ../plugins/gtkui/deadbeef.glade.h:105
+msgid "Random"
+msgstr "Выпадкова"
+
+#: ../plugins/gtkui/interface.c:348 ../plugins/gtkui/deadbeef.glade.h:77
+msgid "Looping"
+msgstr "Паўтараць"
+
+#: ../plugins/gtkui/interface.c:355 ../plugins/gtkui/deadbeef.glade.h:75
+msgid "Loop All"
+msgstr "Паўтараць усё"
+
+#: ../plugins/gtkui/interface.c:361 ../plugins/gtkui/deadbeef.glade.h:76
+msgid "Loop Single Song"
+msgstr "Паўтараць адзін трэк"
+
+#: ../plugins/gtkui/interface.c:367 ../plugins/gtkui/deadbeef.glade.h:27
+msgid "Don't Loop"
+msgstr "Не паўтараць"
+
+#: ../plugins/gtkui/interface.c:373 ../plugins/gtkui/deadbeef.glade.h:113
+msgid "Scroll follows playback"
+msgstr "Пракручваць плэйліст аўтаматычна"
+
+#: ../plugins/gtkui/interface.c:378 ../plugins/gtkui/deadbeef.glade.h:20
+msgid "Cursor follows playback"
+msgstr "Вылучаць бягучы трэк"
+
+#: ../plugins/gtkui/interface.c:382 ../plugins/gtkui/deadbeef.glade.h:124
+msgid "Stop after current"
+msgstr "Спыніць пасля бягучага"
+
+#: ../plugins/gtkui/interface.c:394 ../plugins/gtkui/deadbeef.glade.h:69
+msgid "Jump to current track"
+msgstr "Перайсці на бягучы трэк"
+
+#: ../plugins/gtkui/interface.c:401 ../plugins/gtkui/interface.c:408
+#: ../plugins/gtkui/deadbeef.glade.h:155
+msgid "_Help"
+msgstr "_Даведка"
+
+#: ../plugins/gtkui/interface.c:416 ../plugins/gtkui/deadbeef.glade.h:148
+msgid "_ChangeLog"
+msgstr "_Змены"
+
+#: ../plugins/gtkui/interface.c:425 ../plugins/gtkui/deadbeef.glade.h:154
+msgid "_GPLv2"
+msgstr "_GPLv2"
+
+#: ../plugins/gtkui/interface.c:429 ../plugins/gtkui/deadbeef.glade.h:156
+msgid "_LGPLv2.1"
+msgstr "_LGPLv2.1"
+
+#: ../plugins/gtkui/interface.c:438 ../plugins/gtkui/deadbeef.glade.h:145
+msgid "_About"
+msgstr "_Аб праграме"
+
+#: ../plugins/gtkui/interface.c:446 ../plugins/gtkui/deadbeef.glade.h:161
+msgid "_Translators"
+msgstr "_Перакладчыкі"
+
+#: ../plugins/gtkui/interface.c:836 ../plugins/gtkui/deadbeef.glade.h:114
+msgid "Search"
+msgstr "Пошук"
+
+#: ../plugins/gtkui/interface.c:911 ../plugins/gtkui/deadbeef.glade.h:123
+msgid "Stop"
+msgstr "Стоп"
+
+#: ../plugins/gtkui/interface.c:919 ../plugins/gtkui/deadbeef.glade.h:91
+msgid "Play"
+msgstr "Прайграць"
+
+#: ../plugins/gtkui/interface.c:927 ../plugins/gtkui/deadbeef.glade.h:90
+msgid "Pause"
+msgstr "Паўза"
+
+#: ../plugins/gtkui/interface.c:935 ../plugins/gtkui/deadbeef.glade.h:97
+msgid "Previous"
+msgstr "Папярэдняя"
+
+#: ../plugins/gtkui/interface.c:943 ../plugins/gtkui/deadbeef.glade.h:83
+msgid "Next"
+msgstr "Наступная"
+
+#: ../plugins/gtkui/interface.c:951 ../plugins/gtkui/deadbeef.glade.h:92
+msgid "Play Random"
+msgstr "Граць выпадкова"
+
+#: ../plugins/gtkui/interface.c:960 ../plugins/gtkui/deadbeef.glade.h:3
+msgid "About"
+msgstr "Аб праграме"
+
+#: ../plugins/gtkui/interface.c:973 ../plugins/gtkui/deadbeef.glade.h:104
+msgid "Quit"
+msgstr "Выйсце"
+
+#: ../plugins/gtkui/interface.c:1045 ../plugins/gtkui/deadbeef.glade.h:8
+msgid "Adding files..."
+msgstr "Даданне файлаў..."
+
+#: ../plugins/gtkui/interface.c:1089 ../plugins/gtkui/deadbeef.glade.h:144
+msgid "_Abort"
+msgstr "_Скасаваць"
+
+#: ../plugins/gtkui/interface.c:1189 ../plugins/gtkui/deadbeef.glade.h:135
+msgid "Track Properties"
+msgstr "Уласцівасці трэка"
+
+#: ../plugins/gtkui/interface.c:1235 ../plugins/gtkui/deadbeef.glade.h:146
+msgid "_Apply"
+msgstr "_Ужыць"
+
+#: ../plugins/gtkui/interface.c:1256 ../plugins/gtkui/interface.c:1302
+#: ../plugins/gtkui/interface.c:2525 ../plugins/gtkui/deadbeef.glade.h:150
+msgid "_Close"
+msgstr "_Зачыніць"
+
+#: ../plugins/gtkui/interface.c:1260 ../plugins/gtkui/deadbeef.glade.h:78
+msgid "Metadata"
+msgstr "Метададзеныя"
+
+#: ../plugins/gtkui/interface.c:1306 ../plugins/gtkui/plcommon.c:504
+#: ../plugins/gtkui/deadbeef.glade.h:98
+msgid "Properties"
+msgstr "Уласцівасці"
+
+#: ../plugins/gtkui/interface.c:1391 ../plugins/gtkui/deadbeef.glade.h:163
+msgid "editcolumndlg"
+msgstr "Рэдагаваць слупок"
+
+#: ../plugins/gtkui/interface.c:1406 ../plugins/gtkui/interface.c:2897
+#: ../plugins/gtkui/deadbeef.glade.h:132
+msgid "Title:"
+msgstr "Назва:"
+
+#: ../plugins/gtkui/interface.c:1414 ../plugins/gtkui/deadbeef.glade.h:30
+msgid "Enter new column title here"
+msgstr "Увядзіце назву новага слупка"
+
+#: ../plugins/gtkui/interface.c:1422 ../plugins/gtkui/deadbeef.glade.h:136
+msgid "Type:"
+msgstr "Тып:"
+
+#: ../plugins/gtkui/interface.c:1430
+msgid "Item Index"
+msgstr "Нумар"
+
+#. create default set of columns
+#: ../plugins/gtkui/interface.c:1431 ../plugins/gtkui/mainplaylist.c:305
+msgid "Playing"
+msgstr "Прайграецца"
+
+#: ../plugins/gtkui/interface.c:1432
+msgid "Album Art"
+msgstr "Вокладка альбому"
+
+#: ../plugins/gtkui/interface.c:1433
+msgid "Artist - Album"
+msgstr "Выканаўца - Альбом"
+
+#. Track properties dialog
+#: ../plugins/gtkui/interface.c:1434 ../plugins/gtkui/plcommon.c:878
+#: ../translation/extra.c:55
+msgid "Artist"
+msgstr "Выканаўца"
+
+#: ../plugins/gtkui/interface.c:1435 ../plugins/gtkui/interface.c:1822
+#: ../translation/extra.c:59
+msgid "Album"
+msgstr "Альбом"
+
+#: ../plugins/gtkui/interface.c:1436 ../plugins/gtkui/prefwin.c:612
+msgid "Title"
+msgstr "Назва"
+
+#: ../plugins/gtkui/interface.c:1437
+msgid "Length"
+msgstr "Даўжыня"
+
+#: ../plugins/gtkui/interface.c:1438 ../plugins/gtkui/interface.c:1821
+msgid "Track"
+msgstr "Трэк"
+
+#: ../plugins/gtkui/interface.c:1439 ../translation/extra.c:58
+msgid "Band / Album Artist"
+msgstr "Гурт / Выканаўца альбому"
+
+#: ../plugins/gtkui/interface.c:1440 ../plugins/gtkui/plcommon.c:882
+msgid "Custom"
+msgstr "Карыстальніцкі"
+
+#: ../plugins/gtkui/interface.c:1446 ../plugins/gtkui/interface.c:3124
+#: ../plugins/gtkui/deadbeef.glade.h:49
+msgid "Format:"
+msgstr "Фармат:"
+
+#: ../plugins/gtkui/interface.c:1461 ../plugins/gtkui/deadbeef.glade.h:9
+msgid "Alignment:"
+msgstr "Выраўніванне:"
+
+#: ../plugins/gtkui/interface.c:1469
+msgid "Left"
+msgstr "Па леваму краю"
+
+#: ../plugins/gtkui/interface.c:1470
+msgid "Right"
+msgstr "Па праваму краю"
+
+#: ../plugins/gtkui/interface.c:1472 ../plugins/gtkui/deadbeef.glade.h:35
+#, no-c-format
+msgid ""
+"Format conversions (start with %):\n"
+" [a]rtist, [t]itle, al[b]um, [B]and, [C]omposer\n"
+" track[n]umber, [N]totaltracks,\n"
+" [l]ength, [y]ear, [g]enre, [c]omment,\n"
+" copy[r]ight, [f]ilename, [F]ullPathname, [T]ags,\n"
+" [d]irectory, [D]irectoryWithPath\n"
+"Example: %a - %t [%l]"
+msgstr ""
+"Пераўтварэнне фармата (пачынаецца з %):\n"
+" %a-выканаўца, %t-назва, %b-альбом, %B-гурт,\n"
+" %C-кампазітар, %n-нумар трэка, %N-усяго трэкаў,\n"
+" %l-даўжыня, %y-год, %g-жанр, %c-каментар,\n"
+" %r-аўтарскія правы, %f-імя файла, %F-шлях да файла\n"
+" %T-тэгі, %d-дырэкторыя, %D-поўны шлях да дырэкторыі\n"
+"Прыклад: %a - %t [%l]"
+
+#: ../plugins/gtkui/interface.c:1501 ../plugins/gtkui/interface.c:2928
+#: ../plugins/gtkui/interface.c:3040 ../plugins/gtkui/interface.c:3163
+#: ../plugins/gtkui/deadbeef.glade.h:147
+msgid "_Cancel"
+msgstr "_Скасаваць"
+
+#: ../plugins/gtkui/interface.c:1522 ../plugins/gtkui/interface.c:2949
+#: ../plugins/gtkui/interface.c:3061 ../plugins/gtkui/interface.c:3184
+#: ../plugins/gtkui/deadbeef.glade.h:157
+msgid "_OK"
+msgstr "_ОК"
+
+#: ../plugins/gtkui/interface.c:1753 ../plugins/gtkui/deadbeef.glade.h:87
+msgid "Output plugin:"
+msgstr "Модуль вывада:"
+
+#: ../plugins/gtkui/interface.c:1766 ../plugins/gtkui/deadbeef.glade.h:86
+msgid "Output device:"
+msgstr "Прылада вывада:"
+
+#: ../plugins/gtkui/interface.c:1775 ../plugins/gtkui/deadbeef.glade.h:121
+msgid "Sound"
+msgstr "Гук"
+
+#: ../plugins/gtkui/interface.c:1784 ../plugins/gtkui/deadbeef.glade.h:10
+msgid "Allow dynamic samplerate switching"
+msgstr "Дазволіць дынамічную змену частаты дыскрэтызацыі"
+
+#: ../plugins/gtkui/interface.c:1792 ../plugins/gtkui/deadbeef.glade.h:110
+msgid "Samplerate conversion quality:"
+msgstr "Алгарытм інтэрпаляцыі:"
+
+#: ../plugins/gtkui/interface.c:1811 ../plugins/gtkui/deadbeef.glade.h:107
+msgid "Replaygain mode:"
+msgstr "Рэжым аўтаўстаноўкі гучнасці:"
+
+#: ../plugins/gtkui/interface.c:1820
+msgid "Disable"
+msgstr "Адключаны"
+
+#: ../plugins/gtkui/interface.c:1824 ../plugins/gtkui/deadbeef.glade.h:108
+msgid "Replaygain peak scale"
+msgstr "Выкарыстоўваць пікавае значэнне"
+
+#: ../plugins/gtkui/interface.c:1832 ../plugins/gtkui/deadbeef.glade.h:5
+msgid "Add files from command line (or file manager) to this playlist:"
+msgstr ""
+"Дадаваць файлы з каманднага радка\n"
+"(ці файлавага кіраўніка) у гэты плэйліст:"
+
+#: ../plugins/gtkui/interface.c:1841 ../plugins/gtkui/deadbeef.glade.h:109
+msgid "Resume previous session on startup"
+msgstr "Аднаўляць папярэднюю сесію пры запуску"
+
+#: ../plugins/gtkui/interface.c:1845 ../plugins/gtkui/deadbeef.glade.h:93
+msgid "Playback"
+msgstr "Прайграванне"
+
+#: ../plugins/gtkui/interface.c:1854 ../plugins/gtkui/deadbeef.glade.h:14
+msgid "Close minimizes to tray"
+msgstr "Згортваць у трэй паводле зачынення"
+
+#: ../plugins/gtkui/interface.c:1858 ../plugins/gtkui/deadbeef.glade.h:80
+msgid "Middle mouse button closes playlist"
+msgstr "Сярэдняя кнопка мышы зачыняе плэйліст"
+
+#: ../plugins/gtkui/interface.c:1862 ../plugins/gtkui/deadbeef.glade.h:54
+msgid "Hide system tray icon"
+msgstr "Не адлюстроўваць іконку у трэі"
+
+#: ../plugins/gtkui/interface.c:1866 ../plugins/gtkui/deadbeef.glade.h:138
+msgid "Use bold font for currently playing track"
+msgstr "Выкарыстоўваць тлусты шрыфт для бягучага трэка"
+
+#: ../plugins/gtkui/interface.c:1870 ../plugins/gtkui/deadbeef.glade.h:53
+msgid "Hide \"Delete from disk\" context menu item"
+msgstr "Прыбраць пункт \"Выдаліць з дыска\" з кантэкстнага меню"
+
+#: ../plugins/gtkui/interface.c:1878 ../plugins/gtkui/deadbeef.glade.h:133
+msgid "Titlebar text while playing:"
+msgstr "Тэкст загалоўка пры прайграванні:"
+
+#: ../plugins/gtkui/interface.c:1892 ../plugins/gtkui/deadbeef.glade.h:134
+msgid "Titlebar text while stopped:"
+msgstr "Тэкст загалоўка пры спыненні:"
+
+#: ../plugins/gtkui/interface.c:1902 ../plugins/gtkui/deadbeef.glade.h:50
+msgid "GUI"
+msgstr "Інтэрфейс"
+
+#: ../plugins/gtkui/interface.c:1916 ../plugins/gtkui/interface.c:1960
+#: ../plugins/gtkui/deadbeef.glade.h:88
+msgid "Override"
+msgstr "Замяніць"
+
+#: ../plugins/gtkui/interface.c:1925 ../plugins/gtkui/deadbeef.glade.h:33
+msgid "Foreground"
+msgstr "Пярэдні план"
+
+#: ../plugins/gtkui/interface.c:1932 ../plugins/gtkui/deadbeef.glade.h:12
+msgid "Background"
+msgstr "Фон"
+
+#: ../plugins/gtkui/interface.c:1951 ../plugins/gtkui/deadbeef.glade.h:115
+msgid "Seekbar/Volumebar colors"
+msgstr "Асноўныя колеры"
+
+#: ../plugins/gtkui/interface.c:1969 ../plugins/gtkui/deadbeef.glade.h:79
+msgid "Middle"
+msgstr "Сярэдні"
+
+#: ../plugins/gtkui/interface.c:1976 ../plugins/gtkui/deadbeef.glade.h:72
+msgid "Light"
+msgstr "Светлы"
+
+#: ../plugins/gtkui/interface.c:1983 ../plugins/gtkui/deadbeef.glade.h:21
+msgid "Dark"
+msgstr "Цёмны"
+
+#: ../plugins/gtkui/interface.c:2014 ../plugins/gtkui/deadbeef.glade.h:13
+msgid "Base"
+msgstr "Грунтоўны"
+
+#: ../plugins/gtkui/interface.c:2021 ../plugins/gtkui/deadbeef.glade.h:128
+msgid "Tab strip colors"
+msgstr "Колеры ўставак"
+
+#: ../plugins/gtkui/interface.c:2030 ../plugins/gtkui/deadbeef.glade.h:89
+msgid "Override (looses GTK treeview theming, but speeds up rendering)"
+msgstr ""
+"Замяніць (губляюцца наладкі тэмы GTK, але павялічваецца\n"
+"хуткасць адлюстроўвання"
+
+#: ../plugins/gtkui/interface.c:2039 ../plugins/gtkui/deadbeef.glade.h:32
+msgid "Even row"
+msgstr ""
+"Цотны\n"
+"радок"
+
+#: ../plugins/gtkui/interface.c:2046 ../plugins/gtkui/deadbeef.glade.h:84
+msgid "Odd row"
+msgstr ""
+"Няцотны\n"
+"радок"
+
+#: ../plugins/gtkui/interface.c:2065 ../plugins/gtkui/deadbeef.glade.h:131
+msgid "Text"
+msgstr "Тэкст"
+
+#: ../plugins/gtkui/interface.c:2072 ../plugins/gtkui/deadbeef.glade.h:117
+msgid "Selected row"
+msgstr ""
+"Вылучаны\n"
+"радок"
+
+#: ../plugins/gtkui/interface.c:2091 ../plugins/gtkui/deadbeef.glade.h:118
+msgid "Selected text"
+msgstr "Вылучаны радок"
+
+#: ../plugins/gtkui/interface.c:2104 ../plugins/gtkui/deadbeef.glade.h:19
+msgid "Cursor"
+msgstr "Курсор"
+
+#: ../plugins/gtkui/interface.c:2117 ../plugins/gtkui/deadbeef.glade.h:94
+msgid "Playlist colors"
+msgstr "Колеры плэйліста"
+
+#: ../plugins/gtkui/interface.c:2121 ../plugins/gtkui/deadbeef.glade.h:15
+msgid "Colors"
+msgstr "Колеры"
+
+#: ../plugins/gtkui/interface.c:2130 ../plugins/gtkui/deadbeef.glade.h:29
+msgid "Enable Proxy Server"
+msgstr "Уключыць проксі-сервер"
+
+#: ../plugins/gtkui/interface.c:2138 ../plugins/gtkui/deadbeef.glade.h:100
+msgid "Proxy Server Address:"
+msgstr "Адрас:"
+
+#: ../plugins/gtkui/interface.c:2152 ../plugins/gtkui/deadbeef.glade.h:101
+msgid "Proxy Server Port:"
+msgstr "Порт:"
+
+#: ../plugins/gtkui/interface.c:2166 ../plugins/gtkui/deadbeef.glade.h:102
+msgid "Proxy Type:"
+msgstr "Тып проксі:"
+
+#: ../plugins/gtkui/interface.c:2185 ../plugins/gtkui/deadbeef.glade.h:103
+msgid "Proxy Username:"
+msgstr "Імя карыстальніка:"
+
+#: ../plugins/gtkui/interface.c:2198 ../plugins/gtkui/deadbeef.glade.h:99
+msgid "Proxy Password:"
+msgstr "Пароль:"
+
+#: ../plugins/gtkui/interface.c:2208 ../plugins/gtkui/deadbeef.glade.h:81
+msgid "Network"
+msgstr "Сетка"
+
+#: ../plugins/gtkui/interface.c:2236 ../plugins/gtkui/deadbeef.glade.h:142
+msgid "Write ID3v2"
+msgstr "Пісаць ID3v2"
+
+#: ../plugins/gtkui/interface.c:2240 ../plugins/gtkui/interface.c:2367
+#: ../plugins/gtkui/deadbeef.glade.h:141
+msgid "Write ID3v1"
+msgstr "Пісаць ID3v1"
+
+#: ../plugins/gtkui/interface.c:2244 ../plugins/gtkui/interface.c:2323
+#: ../plugins/gtkui/interface.c:2363 ../plugins/gtkui/deadbeef.glade.h:140
+msgid "Write APEv2"
+msgstr "Пісаць APEv2"
+
+#: ../plugins/gtkui/interface.c:2252 ../plugins/gtkui/interface.c:2331
+#: ../plugins/gtkui/deadbeef.glade.h:127
+msgid "Strip ID3v2"
+msgstr "Выразаць ID3v2"
+
+#: ../plugins/gtkui/interface.c:2256 ../plugins/gtkui/interface.c:2379
+#: ../plugins/gtkui/deadbeef.glade.h:126
+msgid "Strip ID3v1"
+msgstr "Выразаць ID3v1"
+
+#: ../plugins/gtkui/interface.c:2260 ../plugins/gtkui/interface.c:2335
+#: ../plugins/gtkui/interface.c:2375 ../plugins/gtkui/deadbeef.glade.h:125
+msgid "Strip APEv2"
+msgstr "Выразаць APEv2"
+
+#: ../plugins/gtkui/interface.c:2268 ../plugins/gtkui/deadbeef.glade.h:56
+msgid "ID3v2 version"
+msgstr "Версія ID3v2"
+
+#: ../plugins/gtkui/interface.c:2275
+msgid "2.3 (Recommended)"
+msgstr "2.3 (Параіная)"
+
+#: ../plugins/gtkui/interface.c:2276
+msgid "2.4"
+msgstr "2.4"
+
+#: ../plugins/gtkui/interface.c:2282 ../plugins/gtkui/deadbeef.glade.h:55
+msgid "ID3v1 character encoding (default is iso8859-1)"
+msgstr "Кадыроўка ID3v1 (па змаўчанні iso8859-1)"
+
+#: ../plugins/gtkui/interface.c:2319 ../plugins/gtkui/deadbeef.glade.h:143
+msgid "Write ID3v2.4"
+msgstr "Пісать ID3v2.4"
+
+#: ../plugins/gtkui/interface.c:2388 ../plugins/gtkui/deadbeef.glade.h:130
+msgid "Tag writer"
+msgstr "Рэдактар тэгаў"
+
+#: ../plugins/gtkui/interface.c:2419 ../plugins/gtkui/deadbeef.glade.h:22
+msgid "Description:"
+msgstr "Апісанне:"
+
+#: ../plugins/gtkui/interface.c:2434 ../plugins/gtkui/deadbeef.glade.h:11
+msgid "Author(s):"
+msgstr "Аўтар(ы):"
+
+#: ../plugins/gtkui/interface.c:2449 ../plugins/gtkui/deadbeef.glade.h:28
+msgid "Email:"
+msgstr "Электронны адрас:"
+
+#: ../plugins/gtkui/interface.c:2464 ../plugins/gtkui/deadbeef.glade.h:139
+msgid "Website:"
+msgstr "Вэб-сайт:"
+
+#: ../plugins/gtkui/interface.c:2495 ../plugins/gtkui/deadbeef.glade.h:17
+msgid "Configure"
+msgstr "Наладзіць"
+
+#: ../plugins/gtkui/interface.c:2499 ../plugins/gtkui/deadbeef.glade.h:95
+msgid "Plugins"
+msgstr "Дадаткі"
+
+#: ../plugins/gtkui/interface.c:2881 ../plugins/gtkui/deadbeef.glade.h:164
+msgid "editplaylistdlg"
+msgstr "Рэдактаваць плэйліст"
+
+#: ../plugins/gtkui/interface.c:3008 ../plugins/gtkui/deadbeef.glade.h:137
+msgid "URL:"
+msgstr "URL:"
+
+#: ../plugins/gtkui/interface.c:3109 ../plugins/gtkui/deadbeef.glade.h:51
+msgid "Group By"
+msgstr "Гуртаваць па"
+
+#: ../plugins/gtkui/interface.c:3134 ../plugins/gtkui/deadbeef.glade.h:43
+#, no-c-format
+msgid ""
+"Format conversions (start with %):\n"
+" [a]rtist, [t]itle, al[b]um, [B]and, [C]omposer\n"
+" track[n]umber, [N]totaltracks,\n"
+" [l]ength, [y]ear, [g]enre, [c]omment,\n"
+" copy[r]ight, [f]ilename, [T]ags\n"
+"Example: %a - %t [%l]"
+msgstr ""
+"Пераўтварэнне фармату (пачыная з %):\n"
+" %a-выканаўца, %t-назва, %b-альбом, %B-гурт,\n"
+" %C-кампазітар, %n-нумар трэка, %N-усяго трэкаў,\n"
+" %l-даўжыня, %y-год, %g-жанр, %c-каментар,\n"
+" %r-аўтарскія правы, %f-імя файла, %T-тэгі\n"
+"Прыклад: %a - %t [%l]"
+
+#: ../plugins/gtkui/mainplaylist.c:306 ../plugins/gtkui/search.c:439
+msgid "Artist / Album"
+msgstr "Выканаўца / Альбом"
+
+#: ../plugins/gtkui/mainplaylist.c:307 ../plugins/gtkui/search.c:440
+msgid "Track No"
+msgstr "Трэк №"
+
+#: ../plugins/gtkui/mainplaylist.c:308 ../plugins/gtkui/search.c:441
+msgid "Title / Track Artist"
+msgstr "Загаловак / Выканаўца"
+
+#: ../plugins/gtkui/mainplaylist.c:309 ../plugins/gtkui/search.c:442
+#: ../plugins/gtkui/trkproperties.c:175
+msgid "Duration"
+msgstr "Працягласць"
+
+#: ../plugins/gtkui/plcommon.c:324
+msgid "Delete files from disk"
+msgstr "Выдаліць файлы з жорсткага дыска"
+
+#: ../plugins/gtkui/plcommon.c:325
+msgid ""
+"Files will be lost. Proceed?\n"
+"(This dialog can be turned off in GTKUI plugin settings)"
+msgstr ""
+"Файлы будуць выдалены. Працягваць?\n"
+"(Гэты дыялог можы быць адключаны ў наладках GTKUI)"
+
+#: ../plugins/gtkui/plcommon.c:326 ../plugins/gtkui/trkproperties.c:56
+msgid "Warning"
+msgstr "Увага"
+
+#: ../plugins/gtkui/plcommon.c:402
+msgid "Add to playback queue"
+msgstr "Дадаць у чаргу"
+
+#: ../plugins/gtkui/plcommon.c:407
+msgid "Remove from playback queue"
+msgstr "Выдаліць з чаргі"
+
+#: ../plugins/gtkui/plcommon.c:415
+msgid "Reload metadata"
+msgstr "Аднавіць метададзеныя"
+
+#: ../plugins/gtkui/plcommon.c:434
+msgid "Remove from disk"
+msgstr "Выдаліць з жорсткага дыска"
+
+#: ../plugins/gtkui/plcommon.c:720 ../plugins/gtkui/plcommon.c:845
+msgid "Add column"
+msgstr "Дадаць слупок"
+
+#: ../plugins/gtkui/plcommon.c:750 ../plugins/gtkui/plcommon.c:849
+msgid "Edit column"
+msgstr "Рэдактаваць слупок"
+
+#: ../plugins/gtkui/plcommon.c:853
+msgid "Remove column"
+msgstr "Выдаліць слупок"
+
+#: ../plugins/gtkui/plcommon.c:863
+msgid "Group by"
+msgstr "Гуртаваць па"
+
+#: ../plugins/gtkui/plcommon.c:870
+msgid "None"
+msgstr "Адсутнічае"
+
+#: ../plugins/gtkui/plcommon.c:874
+msgid "Artist/Date/Album"
+msgstr "Выканаўца/Дата/Альбом"
+
+#: ../plugins/gtkui/pluginconf.c:41
+msgid "Open file..."
+msgstr "Адкрыць файл..."
+
+#: ../plugins/gtkui/pluginconf.c:142
+#, c-format
+msgid "Setup %s"
+msgstr "Усталёўкі %s"
+
+#: ../plugins/gtkui/prefwin.c:99
+msgid "Default Audio Device"
+msgstr "Аўдыё прыстасаванне па змаўчанні"
+
+#: ../plugins/gtkui/prefwin.c:329
+msgid "Add"
+msgstr "Дадаць"
+
+#: ../plugins/gtkui/prefwin.c:339
+msgid "Global Hotkeys"
+msgstr "Гарачыя клавішы"
+
+#: ../plugins/gtkui/prefwin.c:401
+msgid "Slot"
+msgstr "Слот"
+
+#: ../plugins/gtkui/prefwin.c:402
+msgid "Key combination"
+msgstr "Камбінацыя клавіш"
+
+#. output plugin selection
+#: ../plugins/gtkui/prefwin.c:481 ../plugins/gtkui/prefwin.c:693
+#: ../plugins.c:873
+msgid "ALSA output plugin"
+msgstr "Модуль вывада ALSA"
+
+#: ../plugins/gtkui/progress.c:64
+msgid "Initializing..."
+msgstr "Ініцыялізацыя..."
+
+#: ../plugins/gtkui/trkproperties.c:53
+msgid "You've modified data for this track."
+msgstr "Дадзеныя для гэтага трэка былі зменены."
+
+#: ../plugins/gtkui/trkproperties.c:55
+msgid "Really close the window?"
+msgstr "Зачыніць вакно?"
+
+#: ../plugins/gtkui/trkproperties.c:169
+msgid "Location"
+msgstr "Месцазнаходжанне"
+
+#: ../plugins/gtkui/trkproperties.c:172
+msgid "Subtrack Index"
+msgstr "Нумар укладзенага трэка"
+
+#: ../plugins/gtkui/trkproperties.c:178
+msgid "Tag Type(s)"
+msgstr "Тып(ы) тэгаў"
+
+#: ../plugins/gtkui/trkproperties.c:180
+msgid "Embedded Cuesheet"
+msgstr "Укладзены файл cue"
+
+#: ../plugins/gtkui/trkproperties.c:180
+msgid "Yes"
+msgstr "Да"
+
+#: ../plugins/gtkui/trkproperties.c:180
+msgid "No"
+msgstr "Не"
+
+#: ../plugins/gtkui/trkproperties.c:182
+msgid "Codec"
+msgstr "Кодек"
+
+#: ../plugins/gtkui/trkproperties.c:250 ../plugins/gtkui/trkproperties.c:262
+msgid "Key"
+msgstr "Ключ"
+
+#: ../plugins/gtkui/trkproperties.c:251 ../plugins/gtkui/trkproperties.c:263
+msgid "Value"
+msgstr "Значэнне"
+
+#: ../plugins/notify/notify.c:138
+msgid "DeaDBeeF now playing"
+msgstr "DeaDBeeF зараз грае"
+
+#: ../main.c:89
+#, c-format
+msgid "Usage: deadbeef [options] [file(s)]\n"
+msgstr "Выкарыстоўванне: deadbeef [опцыі] [файл(ы)]\n"
+
+#: ../main.c:90
+#, c-format
+msgid "Options:\n"
+msgstr "Опцыі:\n"
+
+#: ../main.c:91
+#, c-format
+msgid " --help or -h Print help (this message) and exit\n"
+msgstr " --help ці -h Адлюстраваць даведку (гэты тэкст) і выйсці\n"
+
+#: ../main.c:92
+#, c-format
+msgid " --quit Quit player\n"
+msgstr " --quit Выйсці з плэера\n"
+
+#: ../main.c:93
+#, c-format
+msgid " --version Print version info and exit\n"
+msgstr ""
+" --version Адлюстраваць інфармацыю аб версіі праграмы і выйсці\n"
+
+#: ../main.c:94
+#, c-format
+msgid " --play Start playback\n"
+msgstr " --play Пачаць граць\n"
+
+#: ../main.c:95
+#, c-format
+msgid " --stop Stop playback\n"
+msgstr " --stop Спыніць прайграванне\n"
+
+#: ../main.c:96
+#, c-format
+msgid " --pause Pause playback\n"
+msgstr " --pause Прыпыніць прайграванне\n"
+
+#: ../main.c:97
+#, c-format
+msgid " --next Next song in playlist\n"
+msgstr " --next Настуная песня ў плэйлісце\n"
+
+#: ../main.c:98
+#, c-format
+msgid " --prev Previous song in playlist\n"
+msgstr " --prev Папярэдняя песня ў плэйлісце\n"
+
+#: ../main.c:99
+#, c-format
+msgid " --random Random song in playlist\n"
+msgstr " --random Выпадковая песня ў плэлісце\n"
+
+#: ../main.c:100
+#, c-format
+msgid " --queue Append file(s) to existing playlist\n"
+msgstr " --queue Дадаць файл(ы) у існуючы плэйліст\n"
+
+#: ../main.c:101
+#, c-format
+msgid " --nowplaying FMT Print formatted track name to stdout\n"
+msgstr " --nowplaying FMT Адлюстраваць адфарматыраваную назву трэка\n"
+
+#: ../main.c:102
+#, c-format
+msgid ""
+" FMT %%-syntax: [a]rtist, [t]itle, al[b]um,\n"
+" [l]ength, track[n]umber, [y]ear, [c]omment,\n"
+" copy[r]ight, [e]lapsed\n"
+msgstr ""
+" FMT %%-сінтаксіс: %%a-выканаўца, %%t-назва, %%b-"
+"альбом,\n"
+" %%l-даўжыня, %%n-нумар трэка, %%y-год, %%c-каментар,\n"
+" %%r-аўтарскія правы, %%e-пройдзены час \n"
+
+#: ../main.c:105
+#, c-format
+msgid ""
+" e.g.: --nowplaying \"%%a - %%t\" should print \"artist "
+"- title\"\n"
+msgstr ""
+" Напрыклад: --nowplaying \"%%a - %%t\" павінна вывесці "
+"на экран \"artist - title\"\n"
+
+#: ../playlist.c:377 ../playlist.c:2289
+msgid "Default"
+msgstr "Плэйліст"
+
+#: ../plugins/gtkui/deadbeef.glade.h:1
+msgid ""
+"2.3 (Recommended)\n"
+"2.4"
+msgstr ""
+"2.3 (Параіная)\n"
+"2.4"
+
+#: ../plugins/gtkui/deadbeef.glade.h:24
+msgid ""
+"Disable\n"
+"Track\n"
+"Album"
+msgstr ""
+"Адключыць\n"
+"Трэк\n"
+"Альбом"
+
+#: ../plugins/gtkui/deadbeef.glade.h:58
+msgid ""
+"Item Index\n"
+"Playing\n"
+"Album Art\n"
+"Artist - Album\n"
+"Artist\n"
+"Album\n"
+"Title\n"
+"Length\n"
+"Track\n"
+"Band / Album Artist\n"
+"Custom"
+msgstr ""
+"Нумар\n"
+"Прайграваецца\n"
+"Вокладка альбома\n"
+"Выканаўца - Альбом\n"
+"Выканаўца\n"
+"Альбом\n"
+"Назва\n"
+"Даўжыня\n"
+"Трэк\n"
+"Гурт / Выканаўца альбому\n"
+"Рознае"
+
+#: ../plugins/gtkui/deadbeef.glade.h:70
+msgid ""
+"Left\n"
+"Right"
+msgstr ""
+"Левы\n"
+"Правы"
+
+#: ../plugins/gtkui/support.c:90 ../plugins/gtkui/support.c:114
+#, c-format
+msgid "Couldn't find pixmap file: %s"
+msgstr "Не атрымалася знайсці файл выявы: %s"
+
+#: ../plugins/wildmidi/wildmidiplug.c:162
+#, c-format
+msgid ""
+"wildmidi: freepats config file not found. Please install timidity-freepats "
+"package, or specify path to freepats.cfg in the plugin settings."
+msgstr ""
+"wildmidi: канфігурацыйны файл freepats не знойдзены. Усталюйце пакетtimidity-"
+"freepats, ці вызначце шлях да файла freepats.cfg у наладкахпашырэння."
+
+#. this file should list extra translatable strings that are not referenced
+#. directly in source code, e.g. scripted plugin configuration strings
+#: ../translation/extra.c:3
+msgid "Add Audio CD"
+msgstr "Дадаць аўдыё CD"
+
+#: ../translation/extra.c:4
+msgid "Lookup on Last.fm"
+msgstr "Паказаць на Last.fm"
+
+#. ALSA output plugin
+#: ../translation/extra.c:6
+msgid "Use ALSA resampling"
+msgstr "Выкарыстоўваць перадыскрэтызацыю з дапамогай ALSA"
+
+#: ../translation/extra.c:7
+msgid "Release device while stopped"
+msgstr "Вызваляць прыстасаванне ў час спынення"
+
+#: ../translation/extra.c:8 ../translation/extra.c:43
+msgid "Preferred buffer size"
+msgstr "Упадабаны памер буферу"
+
+#: ../translation/extra.c:9
+msgid "Preferred period size"
+msgstr "Упадабаны памер перыяду"
+
+#. Last.fm plugin
+#: ../translation/extra.c:11
+msgid "Enable scrobbler"
+msgstr "Уключыць скроблер"
+
+#: ../translation/extra.c:12
+msgid "Disable nowplaying"
+msgstr "Не выкарыстоўваць інфармацыю аб бягучым трэку"
+
+#: ../translation/extra.c:13
+msgid "Username"
+msgstr "Імя карыстальніка"
+
+#: ../translation/extra.c:14
+msgid "Password"
+msgstr "Пароль"
+
+#: ../translation/extra.c:15
+msgid "Scrobble URL"
+msgstr "Адрас для скроблінга"
+
+#. Album Artwork plugin
+#: ../translation/extra.c:17
+msgid "Cache update period (hr)"
+msgstr "Перыяд аднаўлення кэша (гадзіны)"
+
+#: ../translation/extra.c:18
+msgid "Fetch from embedded tags"
+msgstr "Атрымліваць з унутраных тэгаў"
+
+#: ../translation/extra.c:19
+msgid "Fetch from local folder"
+msgstr "Атрымліваць з лакальнай тэчкі"
+
+#: ../translation/extra.c:20
+msgid "Local cover file mask"
+msgstr "Файлавая маска для лакальных вокладак"
+
+#: ../translation/extra.c:21
+msgid "Fetch from last.fm"
+msgstr "Атрымліваць з last.fm"
+
+#: ../translation/extra.c:22
+msgid "Fetch from albumart.org"
+msgstr "Атрымліваць з albumart.org"
+
+#. Audio CD player
+#: ../translation/extra.c:24
+msgid "Use CDDB/FreeDB"
+msgstr "Выкарыстоўваць CDDB/FreeDB"
+
+#: ../translation/extra.c:25
+msgid "Prefer CD-Text over CDDB"
+msgstr "Выкарытоўваць CD-Text замест CDDB"
+
+#: ../translation/extra.c:26
+msgid "CDDB url (e.g. 'freedb.org')"
+msgstr "CDDB url (напрыклад, 'freedb.org')"
+
+#: ../translation/extra.c:27
+msgid "CDDB port number (e.g. '888')"
+msgstr "Нумар парта CDDB (напрыклад, '888')"
+
+#: ../translation/extra.c:28
+msgid "Prefer CDDB protocol over HTTP"
+msgstr "Выкарыстоўваць пратакол CDDB замест HTTP"
+
+#: ../translation/extra.c:29
+msgid "Enable NRG image support"
+msgstr "Уключыць падтрымку NRG вобразаў"
+
+#. DUMB module player plugin
+#: ../translation/extra.c:31
+msgid "Resampling quality (0..2, higher is better)"
+msgstr "Якасць перадысрэтызацыі (0..2, вышэй - лепш)"
+
+#. Game_Music_Emu decoder plugin
+#: ../translation/extra.c:33
+msgid "Max song length (in minutes)"
+msgstr "Максімальная даўжыня трэка (у хвілінах)"
+
+#. Standard GTK2 user interface plugin
+#: ../translation/extra.c:35
+msgid "Ask confirmation to delete files from disk"
+msgstr "Запытваць пацверджанне на выдаленне файлаў з жорсткага дыска"
+
+#: ../translation/extra.c:36
+msgid "Status icon volume control sensitivity"
+msgstr "Адчувальнасць рэгулятара гучнасці ў значку статусу"
+
+#: ../translation/extra.c:37
+msgid "Custom status icon"
+msgstr "Карстальніцкі значок статусу"
+
+#: ../translation/extra.c:38
+msgid "Run gtk_init with --sync (debug mode)"
+msgstr "Запускаць gtk_init з ключом --sync (рэжым адладкі)"
+
+#. OSD Notify plugin
+#: ../translation/extra.c:40
+msgid "Notification format"
+msgstr "Фармат паведамлення"
+
+#. PulseAudio output plugin
+#: ../translation/extra.c:42
+msgid "PulseAudio server"
+msgstr "Сервер PulseAudio"
+
+#: ../translation/extra.c:44
+msgid "Samplerate"
+msgstr "Частата дыскрэтызацыі"
+
+#. SHN player plugin
+#: ../translation/extra.c:46
+msgid "Relative seek table path"
+msgstr "Адносны шлях табліцы пошуку"
+
+#: ../translation/extra.c:47
+msgid "Absolute seek table path"
+msgstr "Абсолютный путь таблицы поиска"
+
+#: ../translation/extra.c:48
+msgid "Swap audio bytes (toggle if all you hear is static)"
+msgstr "Пераставіць месцамі аўдыё байты"
+
+#. SID decoder plugin
+#: ../translation/extra.c:50
+msgid "Enable HVSC"
+msgstr "Уключыць падтрымку HVSC"
+
+#: ../translation/extra.c:51
+msgid "HVSC path"
+msgstr "Шлях да HVSC"
+
+#. WildMidi player plugin
+#: ../translation/extra.c:53
+msgid "Timidity++ bank configuration file"
+msgstr "Файл канфігурацыі для банка Timidity++"
+
+#: ../translation/extra.c:56
+msgid "Track Title"
+msgstr "Назва трэка"
+
+#: ../translation/extra.c:57
+msgid "Performer"
+msgstr "Выканаўца"
+
+#: ../translation/extra.c:60
+msgid "Date"
+msgstr "Дата"
+
+#: ../translation/extra.c:61
+msgid "Track Number"
+msgstr "Нумар трэка"
+
+#: ../translation/extra.c:62
+msgid "Total Tracks"
+msgstr "Усяго трэкаў"
+
+#: ../translation/extra.c:63
+msgid "Genre"
+msgstr "Жанр"
+
+#: ../translation/extra.c:64
+msgid "Composer"
+msgstr "Кампазітар"
+
+#: ../translation/extra.c:65
+msgid "Disc Number"
+msgstr "Нумар дыска"
+
+#: ../translation/extra.c:66
+msgid "Comment"
+msgstr "Каментар"
+
+#: ../translation/extra.c:67
+msgid "Encoder / Vendor"
+msgstr "Кодер / Продавец"
+
+#: ../translation/extra.c:68
+msgid "Copyright"
+msgstr "Аўтарскія правы"
+
+#~ msgid "Couldn't get enough memory for input buffering."
+#~ msgstr ""
+#~ "Не атрымалася вылучыць дастатковую колькасць памяці для ўваходнага буфера."
+
+#~ msgid "Error reading first page of Ogg bitstream."
+#~ msgstr "Памылка чытання загалоўка патока Ogg."
+
+#~ msgid "Couldn't get enough memory to register new stream serial number."
+#~ msgstr ""
+#~ "Не атрымалася вылучыць дастатковую колькасць памяці для рэгістрацыі "
+#~ "новага серыйнага нумару патоку."
+
+#~ msgid "Input truncated or empty."
+#~ msgstr "Уваходны паток абрэзаны ці пусты."
+
+#~ msgid "Input is not an Ogg bitstream."
+#~ msgstr "Увод не з'яўляецца патокам Ogg."
+
+#~ msgid "Ogg bitstream does not contain Vorbis data."
+#~ msgstr "Паток Ogg не ўтрымлівае Vorbis."
+
+#~ msgid "Ogg bitstream does not contain a supported data-type."
+#~ msgstr "Паток Ogg не ўтрымлівае падтрымліваемы тып дадзеных."
+
+#~ msgid "Corrupt secondary header."
+#~ msgstr "Пашкоджаны другасны загаловак."
+
+#~ msgid "EOF before end of Vorbis headers."
+#~ msgstr "Паток перапынені да заканчэння перадачы загалоўкаў Vorbis."
+
+#~ msgid "Corrupt or missing data, continuing..."
+#~ msgstr "Пашкоджанныя ці адсутныя дадзеныя, працягваем..."
+
+#~ msgid ""
+#~ "Error writing stream to output. Output stream may be corrupted or "
+#~ "truncated."
+#~ msgstr ""
+#~ "Памылка запісу выхаднога патоку. Выхадны паток можа быць пашкоджаны ці "
+#~ "абрэзаны."
+
+#~ msgid "Apply"
+#~ msgstr "Ужыць"
+
+#~ msgid ""
+#~ "<b>WARNING</b>: tag writing feature is still in development.\n"
+#~ "<b>Make backup copies</b> before using."
+#~ msgstr ""
+#~ "<b>Увага</b>: магчымасць рэдагавання тэгаў знаходзіцца\n"
+#~ "ў распрацоўцы.\n"
+#~ "<b>Стварайце рэзэрвовые копіі</b> перад выкарстаннем."
+
+#~ msgid "Sound (adv.)"
+#~ msgstr "Гук"
diff --git a/premix.c b/premix.c
new file mode 100644
index 00000000..c7a3324b
--- /dev/null
+++ b/premix.c
@@ -0,0 +1,438 @@
+/*
+ DeaDBeeF - ultimate music player for GNU/Linux systems with X11
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+#include <assert.h>
+#include <string.h>
+#include <stdlib.h>
+#include "deadbeef.h"
+#include "premix.h"
+#include "optmath.h"
+
+#define trace(...) { fprintf(stderr, __VA_ARGS__); }
+//#define trace(fmt,...)
+
+
+static inline void
+pcm_write_samples_8_to_8 (const ddb_waveformat_t * restrict inputfmt, const char * restrict input, const ddb_waveformat_t * restrict outputfmt, char * restrict output, int nsamples, int * restrict channelmap, int outputsamplesize) {
+ for (int s = 0; s < nsamples; s++) {
+ for (int c = 0; c < inputfmt->channels; c++) {
+ *(output + channelmap[c]) = *input;
+ input++;
+ }
+ output += outputsamplesize;
+ }
+}
+
+static inline void
+pcm_write_samples_8_to_16 (const ddb_waveformat_t * restrict inputfmt, const char * restrict input, const ddb_waveformat_t * restrict outputfmt, char * restrict output, int nsamples, int * restrict channelmap, int outputsamplesize) {
+ for (int s = 0; s < nsamples; s++) {
+ for (int c = 0; c < inputfmt->channels; c++) {
+ *((int16_t*)(output + 2 * channelmap[c])) = (int16_t)(*input) << 8;
+ input++;
+ }
+ output += outputsamplesize;
+ }
+}
+
+static inline void
+pcm_write_samples_8_to_24 (const ddb_waveformat_t * restrict inputfmt, const char * restrict input, const ddb_waveformat_t * restrict outputfmt, char * restrict output, int nsamples, int * restrict channelmap, int outputsamplesize) {
+ for (int s = 0; s < nsamples; s++) {
+ for (int c = 0; c < inputfmt->channels; c++) {
+ char *out = output + 3 * channelmap[c];
+ out[0] = 0;
+ out[1] = 0;
+ out[2] = input[0];
+ input += 1;
+ }
+ output += outputsamplesize;
+ }
+}
+
+static inline void
+pcm_write_samples_8_to_32 (const ddb_waveformat_t * restrict inputfmt, const char * restrict input, const ddb_waveformat_t * restrict outputfmt, char * restrict output, int nsamples, int * restrict channelmap, int outputsamplesize) {
+ for (int s = 0; s < nsamples; s++) {
+ for (int c = 0; c < inputfmt->channels; c++) {
+ char *out = output + 4 * channelmap[c];
+ out[0] = 0;
+ out[1] = 0;
+ out[2] = 0;
+ out[3] = input[0];
+ input += 1;
+ }
+ output += outputsamplesize;
+ }
+}
+
+static inline void
+pcm_write_samples_8_to_float (const ddb_waveformat_t * restrict inputfmt, const char * restrict input, const ddb_waveformat_t * restrict outputfmt, char * restrict output, int nsamples, int * restrict channelmap, int outputsamplesize) {
+ for (int s = 0; s < nsamples; s++) {
+ for (int c = 0; c < inputfmt->channels; c++) {
+ float sample = (*input) / (float)0x7f;
+ *((float *)(output + 4 * channelmap[c])) = sample;
+ input++;
+ }
+ output += outputsamplesize;
+ }
+}
+
+static inline void
+pcm_write_samples_16_to_16 (const ddb_waveformat_t * restrict inputfmt, const char * restrict input, const ddb_waveformat_t * restrict outputfmt, char * restrict output, int nsamples, int * restrict channelmap, int outputsamplesize) {
+ for (int s = 0; s < nsamples; s++) {
+ for (int c = 0; c < inputfmt->channels; c++) {
+ *((int16_t*)(output + 2 * channelmap[c])) = *((int16_t*)input);
+ input += 2;
+ }
+ output += outputsamplesize;
+ }
+}
+
+static inline void
+pcm_write_samples_16_to_8 (const ddb_waveformat_t * restrict inputfmt, const char * restrict input, const ddb_waveformat_t * restrict outputfmt, char * restrict output, int nsamples, int * restrict channelmap, int outputsamplesize) {
+ for (int s = 0; s < nsamples; s++) {
+ for (int c = 0; c < inputfmt->channels; c++) {
+ *((int8_t*)(output + channelmap[c])) = *((int16_t*)input) >> 8;
+ input += 2;
+ }
+ output += outputsamplesize;
+ }
+}
+
+static inline void
+pcm_write_samples_16_to_24 (const ddb_waveformat_t * restrict inputfmt, const char * restrict input, const ddb_waveformat_t * restrict outputfmt, char * restrict output, int nsamples, int * restrict channelmap, int outputsamplesize) {
+ for (int s = 0; s < nsamples; s++) {
+ for (int c = 0; c < inputfmt->channels; c++) {
+ char *out = output + 3 * channelmap[c];
+ out[0] = 0;
+ out[1] = input[0];
+ out[2] = input[1];
+ input += 2;
+ }
+ output += outputsamplesize;
+ }
+}
+
+static inline void
+pcm_write_samples_16_to_32 (const ddb_waveformat_t * restrict inputfmt, const char * restrict input, const ddb_waveformat_t * restrict outputfmt, char * restrict output, int nsamples, int * restrict channelmap, int outputsamplesize) {
+ for (int s = 0; s < nsamples; s++) {
+ for (int c = 0; c < inputfmt->channels; c++) {
+ char *out = output + 4 * channelmap[c];
+ out[0] = 0;
+ out[1] = 0;
+ out[2] = input[0];
+ out[3] = input[1];
+ input += 2;
+ }
+ output += outputsamplesize;
+ }
+}
+
+static inline void
+pcm_write_samples_16_to_float (const ddb_waveformat_t * restrict inputfmt, const char * restrict input, const ddb_waveformat_t * restrict outputfmt, char * restrict output, int nsamples, int * restrict channelmap, int outputsamplesize) {
+ for (int s = 0; s < nsamples; s++) {
+ for (int c = 0; c < inputfmt->channels; c++) {
+ float sample = (*((int16_t*)input)) / (float)0x7fff;
+ *((float *)(output + 4 * channelmap[c])) = sample;
+ input += 2;
+ }
+ output += outputsamplesize;
+ }
+}
+
+static inline void
+pcm_write_samples_24_to_8 (const ddb_waveformat_t * restrict inputfmt, const char * restrict input, const ddb_waveformat_t * restrict outputfmt, char * restrict output, int nsamples, int * restrict channelmap, int outputsamplesize) {
+ for (int s = 0; s < nsamples; s++) {
+ for (int c = 0; c < inputfmt->channels; c++) {
+ char *out = output + channelmap[c];
+ *out = input[2];
+ input += 3;
+ }
+ output += outputsamplesize;
+ }
+}
+
+static inline void
+pcm_write_samples_24_to_24 (const ddb_waveformat_t * restrict inputfmt, const char * restrict input, const ddb_waveformat_t * restrict outputfmt, char * restrict output, int nsamples, int * restrict channelmap, int outputsamplesize) {
+ for (int s = 0; s < nsamples; s++) {
+ for (int c = 0; c < inputfmt->channels; c++) {
+ char *out = output + 3 * channelmap[c];
+ out[0] = input[0];
+ out[1] = input[1];
+ out[2] = input[2];
+ input += 3;
+ }
+ output += outputsamplesize;
+ }
+}
+
+static inline void
+pcm_write_samples_24_to_32 (const ddb_waveformat_t * restrict inputfmt, const char * restrict input, const ddb_waveformat_t * restrict outputfmt, char * restrict output, int nsamples, int * restrict channelmap, int outputsamplesize) {
+ for (int s = 0; s < nsamples; s++) {
+ for (int c = 0; c < inputfmt->channels; c++) {
+ char *out = output + 4 * channelmap[c];
+ out[0] = 0;
+ out[1] = input[0];
+ out[2] = input[1];
+ out[3] = input[2];
+ input += 3;
+ }
+ output += outputsamplesize;
+ }
+}
+
+static inline void
+pcm_write_samples_24_to_16 (const ddb_waveformat_t * restrict inputfmt, const char * restrict input, const ddb_waveformat_t * restrict outputfmt, char * restrict output, int nsamples, int * restrict channelmap, int outputsamplesize) {
+ for (int s = 0; s < nsamples; s++) {
+ for (int c = 0; c < inputfmt->channels; c++) {
+ char *out = output + 2 * channelmap[c];
+ out[0] = input[1];
+ out[1] = input[2];
+ input += 3;
+ }
+ output += outputsamplesize;
+ }
+}
+
+static inline void
+pcm_write_samples_24_to_float (const ddb_waveformat_t * restrict inputfmt, const char * restrict input, const ddb_waveformat_t * restrict outputfmt, char * restrict output, int nsamples, int * restrict channelmap, int outputsamplesize) {
+ for (int s = 0; s < nsamples; s++) {
+ for (int c = 0; c < inputfmt->channels; c++) {
+ float *out = (float *)(output + 4 * channelmap[c]);
+ int32_t sample = ((unsigned char)input[0]) | ((unsigned char)input[1]<<8) | (input[2]<<16);
+ *out = sample / (float)0x7fffff;
+ input += 3;
+ }
+ output += outputsamplesize;
+ }
+}
+
+static inline void
+pcm_write_samples_32_to_32 (const ddb_waveformat_t * restrict inputfmt, const char * restrict input, const ddb_waveformat_t * restrict outputfmt, char * restrict output, int nsamples, int * restrict channelmap, int outputsamplesize) {
+ for (int s = 0; s < nsamples; s++) {
+ for (int c = 0; c < inputfmt->channels; c++) {
+ *((int32_t*)(output + 4 * channelmap[c])) = *((int32_t*)input);
+ input += 4;
+ }
+ output += outputsamplesize;
+ }
+}
+
+static inline void
+pcm_write_samples_float_to_8 (const ddb_waveformat_t * restrict inputfmt, const char * restrict input, const ddb_waveformat_t * restrict outputfmt, char * restrict output, int nsamples, int * restrict channelmap, int outputsamplesize) {
+ fpu_control ctl;
+ fpu_setround (&ctl);
+ for (int s = 0; s < nsamples; s++) {
+ for (int c = 0; c < inputfmt->channels; c++) {
+ int8_t *out = (int8_t*)(output + channelmap[c]);
+ float sample = *((float*)input);
+ // FIXME: sse optimize
+ if (sample > 1) {
+ sample = 1;
+ }
+ if (sample < -1) {
+ sample = -1;
+ }
+ *out = (int8_t)ftoi (sample*0x7f);
+ input += 4;
+ }
+ output += outputsamplesize;
+ }
+ fpu_restore (ctl);
+}
+
+static inline void
+pcm_write_samples_float_to_16 (const ddb_waveformat_t * restrict inputfmt, const char * restrict input, const ddb_waveformat_t * restrict outputfmt, char * restrict output, int nsamples, int * restrict channelmap, int outputsamplesize) {
+ fpu_control ctl;
+ fpu_setround (&ctl);
+ for (int s = 0; s < nsamples; s++) {
+ for (int c = 0; c < inputfmt->channels; c++) {
+ int16_t *out = (int16_t*)(output + 2 * channelmap[c]);
+ float sample = *((float*)input);
+ // FIXME: sse optimize
+ if (sample > 1) {
+ sample = 1;
+ }
+ if (sample < -1) {
+ sample = -1;
+ }
+ *out = (int16_t)ftoi (sample*0x7fff);
+ input += 4;
+ }
+ output += outputsamplesize;
+ }
+ fpu_restore (ctl);
+}
+
+static inline void
+pcm_write_samples_float_to_24 (const ddb_waveformat_t * restrict inputfmt, const char * restrict input, const ddb_waveformat_t * restrict outputfmt, char * restrict output, int nsamples, int * restrict channelmap, int outputsamplesize) {
+ fpu_control ctl;
+ fpu_setround (&ctl);
+ for (int s = 0; s < nsamples; s++) {
+ for (int c = 0; c < inputfmt->channels; c++) {
+ char *out = output + 3 * channelmap[c];
+ float sample = *((float*)input);
+ // FIXME: sse optimize
+ if (sample > 1) {
+ sample = 1;
+ }
+ if (sample < -1) {
+ sample = -1;
+ }
+ int32_t outsample = (int32_t)ftoi (sample * 0x7fffff);
+ out[0] = (outsample&0x0000ff);
+ out[1] = (outsample&0x00ff00)>>8;
+ out[2] = (outsample&0xff0000)>>16;
+ input += 4;
+ }
+ output += outputsamplesize;
+ }
+ fpu_restore (ctl);
+}
+
+
+static inline void
+pcm_write_samples_float_to_32 (const ddb_waveformat_t * restrict inputfmt, const char * restrict input, const ddb_waveformat_t * restrict outputfmt, char * restrict output, int nsamples, int * restrict channelmap, int outputsamplesize) {
+ for (int s = 0; s < nsamples; s++) {
+ for (int c = 0; c < inputfmt->channels; c++) {
+ int sample = (*((float*)input)) * (float)0x7fffffff;
+ *((int32_t *)(output + 4 * channelmap[c])) = sample;
+ input += 4;
+ }
+ output += outputsamplesize;
+ }
+}
+
+typedef void (*remap_fn_t) (const ddb_waveformat_t * restrict inputfmt, const char * restrict input, const ddb_waveformat_t * restrict outputfmt, char * restrict output, int nsamples, int * restrict channelmap, int outputsamplesize);
+
+
+remap_fn_t remappers[8][8] = {
+ {
+ pcm_write_samples_8_to_8,
+ pcm_write_samples_8_to_16,
+ pcm_write_samples_8_to_24,
+ pcm_write_samples_8_to_32,
+ NULL,
+ NULL,
+ NULL,
+ pcm_write_samples_8_to_float,
+ },
+ {
+ pcm_write_samples_16_to_8,
+ pcm_write_samples_16_to_16,
+ pcm_write_samples_16_to_24,
+ pcm_write_samples_16_to_32,
+ NULL,
+ NULL,
+ NULL,
+ pcm_write_samples_16_to_float,
+ },
+ {
+ pcm_write_samples_24_to_8,
+ pcm_write_samples_24_to_16,
+ pcm_write_samples_24_to_24,
+ pcm_write_samples_24_to_32,
+ NULL,
+ NULL,
+ NULL,
+ pcm_write_samples_24_to_float,
+ },
+ {
+ NULL, // FIXME: add 32_to_8
+ NULL, // FIXME: add 32_to_16
+ NULL, // FIXME: add 32_to_24
+ pcm_write_samples_32_to_32,
+ NULL,
+ NULL,
+ NULL,
+ NULL, // FIXME: add 32_to_float
+ },
+ {
+ },
+ {
+ },
+ {
+ },
+ {
+ pcm_write_samples_float_to_8,
+ pcm_write_samples_float_to_16,
+ pcm_write_samples_float_to_24,
+ pcm_write_samples_float_to_32,
+ NULL,
+ NULL,
+ NULL,
+ pcm_write_samples_32_to_32,
+ }
+};
+
+int
+pcm_convert (const ddb_waveformat_t * restrict inputfmt, const char * restrict input, const ddb_waveformat_t * restrict outputfmt, char * restrict output, int inputsize) {
+ // calculate output size
+ int inputsamplesize = (inputfmt->bps >> 3) * inputfmt->channels;
+ int outputsamplesize = (outputfmt->bps >> 3) * outputfmt->channels;
+ int nsamples = inputsize / inputsamplesize;
+
+ uint32_t outchannels = 0;
+
+ if (output) {
+ // build channelmap
+ int channelmap[32] = {0};
+ uint32_t inputbitmask = 1;
+ for (int i = 0; i < inputfmt->channels; i++) {
+ // find next input channel
+ while (inputbitmask < 0x80000000 && !(inputfmt->channelmask & inputbitmask)) {
+ inputbitmask <<= 1;
+ }
+ if (!(inputfmt->channelmask & inputbitmask)) {
+ trace ("pcm_convert: channelmask doesn't correspond inputfmt (channels=%d, channelmask=%X)!\n", inputfmt->channels, inputfmt->channelmask);
+ break;
+ }
+ if (outputfmt->channelmask & inputbitmask) {
+ int o = 0;
+ uint32_t outputbitmask = 1;
+ while (outputbitmask < 0x80000000 && (outputfmt->channelmask & outputbitmask) != inputbitmask) {
+ outputbitmask <<= 1;
+ o++;
+ }
+ if (!(inputfmt->channelmask & outputbitmask)) {
+ // no corresponding output channel -- ignore
+ continue;
+ }
+ outchannels |= outputbitmask;
+ channelmap[i] = o; // input channel i going to output channel o
+ //trace ("channelmap[%d]=%d\n", i, o);
+ }
+ inputbitmask <<= 1;
+ }
+
+ if (outchannels != outputfmt->channelmask) {
+ // some of the channels are not used
+ memset (output, 0, nsamples * outputsamplesize);
+ }
+
+ int outidx = ((outputfmt->bps >> 3) - 1) | (outputfmt->is_float << 2);
+ int inidx = ((inputfmt->bps >> 3) - 1) | (inputfmt->is_float << 2);
+ if (remappers[inidx][outidx]) {
+ remappers[inidx][outidx] (inputfmt, input, outputfmt, output, nsamples, channelmap, outputsamplesize);
+ }
+ else {
+ trace ("no converter from %d %s to %d %s ([%d][%d])\n", inputfmt->bps, inputfmt->is_float ? "float" : "", outputfmt->bps, outputfmt->is_float ? "float" : "", inidx, outidx);
+ }
+ }
+ return nsamples * outputsamplesize;
+}
+
diff --git a/premix.h b/premix.h
new file mode 100644
index 00000000..39d1700d
--- /dev/null
+++ b/premix.h
@@ -0,0 +1,27 @@
+/*
+ DeaDBeeF - ultimate music player for GNU/Linux systems with X11
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+#ifndef __PREMIX_H
+#define __PREMIX_H
+
+// @returns number of output bytes
+int
+pcm_convert (const ddb_waveformat_t * restrict inputfmt, const char * restrict input, const ddb_waveformat_t * restrict outputfmt, char * restrict output, int inputsize);
+
+#endif
diff --git a/replaygain.c b/replaygain.c
new file mode 100644
index 00000000..50f88535
--- /dev/null
+++ b/replaygain.c
@@ -0,0 +1,237 @@
+
+/*
+ DeaDBeeF - ultimate music player for GNU/Linux systems with X11
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+#include "playlist.h"
+#include "volume.h"
+#include "replaygain.h"
+
+static int conf_replaygain_mode = 0;
+static int conf_replaygain_scale = 1;
+static float conf_replaygain_preamp = 0;
+
+static float rg_albumgain = 1;
+static float rg_albumpeak = 1;
+static float rg_trackgain = 1;
+static float rg_trackpeak = 1;
+static float rg_albumgain_preamp = 1;
+static float rg_trackgain_preamp = 1;
+
+void
+replaygain_apply (ddb_waveformat_t *fmt, playItem_t *it, char *bytes, int bytesread) {
+ // FIXME: separate replaygain DSP plugin?
+ if (fmt->bps == 16) {
+ apply_replay_gain_int16 (it, bytes, bytesread);
+ }
+ else if (fmt->bps == 24) {
+ apply_replay_gain_int24 (it, bytes, bytesread);
+ }
+ else if (fmt->bps == 8) {
+ apply_replay_gain_int16 (it, bytes, bytesread);
+ }
+ else if (fmt->bps == 32 && !fmt->is_float) {
+ apply_replay_gain_int32 (it, bytes, bytesread);
+ }
+ else if (fmt->bps == 32 && fmt->is_float) {
+ apply_replay_gain_float32 (it, bytes, bytesread);
+ }
+}
+
+void
+replaygain_set (int mode, int scale, float preamp) {
+ conf_replaygain_mode = mode;
+ conf_replaygain_scale = scale;
+ conf_replaygain_preamp = db_to_amp (preamp);
+ rg_albumgain_preamp = rg_albumgain * conf_replaygain_preamp;
+ rg_trackgain_preamp = rg_trackgain * conf_replaygain_preamp;
+}
+
+void
+replaygain_set_values (float albumgain, float albumpeak, float trackgain, float trackpeak) {
+ rg_albumgain = db_to_amp (albumgain);
+ rg_trackgain = db_to_amp (trackgain);
+ rg_albumgain_preamp = rg_albumgain * conf_replaygain_preamp;
+ rg_trackgain_preamp = rg_trackgain * conf_replaygain_preamp;
+ rg_albumpeak = albumpeak;
+ rg_trackpeak = trackpeak;
+}
+
+static inline int
+get_int_volume (void) {
+ int vol = 1000;
+ if (conf_replaygain_mode == 1) {
+ if (rg_trackgain == 1) {
+ return -1;
+ }
+ vol = rg_trackgain_preamp * 1000;
+ if (conf_replaygain_scale) {
+ if (vol * rg_trackpeak > 1000) {
+ vol = 1000 / rg_trackpeak;
+ }
+ }
+ }
+ else if (conf_replaygain_mode == 2) {
+ if (rg_albumgain == 1) {
+ return -1;
+ }
+ vol = rg_albumgain_preamp * 1000;
+ if (conf_replaygain_scale) {
+ if (vol * rg_albumpeak > 1000) {
+ vol = 1000 / rg_albumpeak;
+ }
+ }
+ }
+ return vol;
+}
+
+void
+apply_replay_gain_int8 (playItem_t *it, char *bytes, int size) {
+ if (!conf_replaygain_mode) {
+ return;
+ }
+ int vol = get_int_volume ();
+ if (vol < 0) {
+ return;
+ }
+ int8_t *s = (int8_t*)bytes;
+ for (int j = 0; j < size; j++) {
+ int32_t sample = ((int8_t)(*s)) * vol / 1000;
+ if (sample > 0x7f) {
+ sample = 0x7f;
+ }
+ else if (sample < -0x80) {
+ sample = -0x80;
+ }
+ *s = (int8_t)sample;
+ s++;
+ }
+}
+
+void
+apply_replay_gain_int16 (playItem_t *it, char *bytes, int size) {
+ if (!conf_replaygain_mode) {
+ return;
+ }
+ int vol = get_int_volume ();
+ if (vol < 0) {
+ return;
+ }
+ int16_t *s = (int16_t*)bytes;
+ for (int j = 0; j < size/2; j++) {
+ int32_t sample = ((int32_t)(*s)) * vol / 1000;
+ if (sample > 0x7fff) {
+ sample = 0x7fff;
+ }
+ else if (sample < -0x8000) {
+ sample = -0x8000;
+ }
+ *s = (int16_t)sample;
+ s++;
+ }
+}
+
+void
+apply_replay_gain_int24 (playItem_t *it, char *bytes, int size) {
+ if (!conf_replaygain_mode) {
+ return;
+ }
+ int64_t vol = get_int_volume ();
+ if (vol < 0) {
+ return;
+ }
+ char *s = (char*)bytes;
+ for (int j = 0; j < size/3; j++) {
+ int32_t sample = ((unsigned char)s[0]) | ((unsigned char)s[1]<<8) | (s[2]<<16);
+ sample = sample * vol / 1000;
+ if (sample > 0x7fffff) {
+ sample = 0x7fffff;
+ }
+ else if (sample < -0x800000) {
+ sample = -0x800000;
+ }
+ s[0] = (sample&0x0000ff);
+ s[1] = (sample&0x00ff00)>>8;
+ s[2] = (sample&0xff0000)>>16;
+ s += 3;
+ }
+}
+
+void
+apply_replay_gain_int32 (playItem_t *it, char *bytes, int size) {
+ if (!conf_replaygain_mode) {
+ return;
+ }
+ int64_t vol = get_int_volume ();
+ if (vol < 0) {
+ return;
+ }
+ int32_t *s = (int32_t*)bytes;
+ for (int j = 0; j < size/4; j++) {
+ int64_t sample = ((int32_t)(*s)) * vol / 1000;
+ if (sample > 0x7fffffff) {
+ sample = 0x7fffffff;
+ }
+ else if (sample < -0x80000000) {
+ sample = -0x80000000;
+ }
+ *s = (int32_t)sample;
+ s++;
+ }
+}
+
+void
+apply_replay_gain_float32 (playItem_t *it, char *bytes, int size) {
+ if (!conf_replaygain_mode) {
+ return;
+ }
+ float vol = 1.f;
+ if (conf_replaygain_mode == 1) {
+ if (rg_trackgain == 1) {
+ return;
+ }
+ vol = rg_trackgain_preamp;
+ if (conf_replaygain_scale) {
+ if (vol * rg_trackpeak > 1.f) {
+ vol = 1.f / rg_trackpeak;
+ }
+ }
+ }
+ else if (conf_replaygain_mode == 2) {
+ if (rg_albumgain == 1) {
+ return;
+ }
+ vol = rg_albumgain_preamp;
+ if (conf_replaygain_scale) {
+ if (vol * rg_albumpeak > 1.f) {
+ vol = 1.f / rg_albumpeak;
+ }
+ }
+ }
+ float *s = (float*)bytes;
+ for (int j = 0; j < size/4; j++) {
+ float sample = ((float)*s) * vol;
+ if (sample > 1.f) {
+ sample = 1.f;
+ }
+ else if (sample < -1.f) {
+ sample = -1.f;
+ }
+ *s = sample;
+ s++;
+ }
+}
diff --git a/replaygain.h b/replaygain.h
new file mode 100644
index 00000000..cee57782
--- /dev/null
+++ b/replaygain.h
@@ -0,0 +1,48 @@
+/*
+ DeaDBeeF - ultimate music player for GNU/Linux systems with X11
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+#ifndef __REPLAYGAIN_H
+#define __REPLAYGAIN_H
+
+#include "deadbeef.h"
+
+void
+replaygain_apply (ddb_waveformat_t *fmt, playItem_t *it, char *bytes, int bytesread);
+
+void
+replaygain_set (int mode, int scale, float preamp);
+
+void
+replaygain_set_values (float albumgain, float albumpeak, float trackgain, float trackpeak);
+
+void
+apply_replay_gain_int8 (playItem_t *it, char *bytes, int size);
+
+void
+apply_replay_gain_int16 (playItem_t *it, char *bytes, int size);
+
+void
+apply_replay_gain_int24 (playItem_t *it, char *bytes, int size);
+
+void
+apply_replay_gain_int32 (playItem_t *it, char *bytes, int size);
+
+void
+apply_replay_gain_float32 (playItem_t *it, char *bytes, int size);
+
+#endif
diff --git a/ringbuf.c b/ringbuf.c
new file mode 100644
index 00000000..be82945e
--- /dev/null
+++ b/ringbuf.c
@@ -0,0 +1,85 @@
+/*
+ DeaDBeeF - ultimate music player for GNU/Linux systems with X11
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+#include <string.h>
+#include "ringbuf.h"
+
+void
+ringbuf_init (ringbuf_t *p, char *buffer, size_t size) {
+ memset (p, 0, sizeof (ringbuf_t));
+ p->bytes = buffer;
+ p->cursor = 0;
+ p->size = size;
+ p->remaining = 0;
+}
+
+int
+ringbuf_write (ringbuf_t *p, char *bytes, size_t size) {
+ if (p->size - p->remaining < size) {
+ return -1;
+ }
+
+ size_t cursor = p->cursor + p->remaining;
+ cursor %= p->size;
+
+ if (p->size - cursor >= size) { // split
+ memcpy (p->bytes + cursor, bytes, size);
+ p->remaining += size;
+ }
+ else {
+ size_t n = p->size - cursor;
+ if (n > 0) {
+ memcpy (p->bytes + cursor, bytes, n);
+ p->remaining += n;
+ size -= n;
+ bytes += n;
+ }
+ memcpy (p->bytes, bytes, size);
+ p->remaining += size;
+ }
+ return 0;
+}
+
+int
+ringbuf_read (ringbuf_t *p, char *bytes, size_t size) {
+ if (p->remaining < size) {
+ size = p->remaining;
+ }
+ int rb = size;
+
+ if (p->size - p->cursor >= size) {
+ memcpy (bytes, p->bytes + p->cursor, size);
+ p->cursor += size;
+ p->remaining -= size;
+ }
+ else {
+ size_t n = p->size - p->cursor;
+ if (n > 0) {
+ memcpy (bytes, p->bytes + p->cursor, n);
+ p->cursor += n;
+ p->remaining -= n;
+ bytes += n;
+ size -= n;
+ }
+ memcpy (bytes, p->bytes, size);
+ p->cursor = size;
+ p->remaining -= size;
+ }
+ return rb;
+}
diff --git a/ringbuf.h b/ringbuf.h
new file mode 100644
index 00000000..e7008bf8
--- /dev/null
+++ b/ringbuf.h
@@ -0,0 +1,40 @@
+/*
+ DeaDBeeF - ultimate music player for GNU/Linux systems with X11
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+#ifndef __RINGBUF_H
+#define __RINGBUF_H
+
+#include <sys/types.h>
+
+typedef struct {
+ char *bytes;
+ size_t size;
+ size_t cursor;
+ size_t remaining;
+} ringbuf_t;
+
+void
+ringbuf_init (ringbuf_t *p, char *buffer, size_t size);
+
+int
+ringbuf_write (ringbuf_t *p, char *bytes, size_t size);
+
+int
+ringbuf_read (ringbuf_t *p, char *bytes, size_t size);
+
+#endif
diff --git a/scripts/configure_minimal.sh b/scripts/configure_minimal.sh
new file mode 100755
index 00000000..4044a03c
--- /dev/null
+++ b/scripts/configure_minimal.sh
@@ -0,0 +1 @@
+./configure --enable-maintainer-mode --disable-nullout --disable-oss --disable-sid --disable-ffap --disable-vtx --disable-adplug --disable-vorbis --disable-ffmpeg --disable-flac --disable-sndfile --disable-wavpack --disable-cdda --disable-gme --disable-dumb --disable-musepack --disable-wildmidi --disable-tta --disable-dca --disable-aac --disable-mms --disable-shn --disable-ao --disable-supereq --disable-artwork --disable-lfm --disable-vfs-curl --disable-hotkeys --disable-notify --disable-shellexec
diff --git a/extract_translators.pl b/scripts/extract_translators.pl
index a3ad02a2..a3ad02a2 100755
--- a/extract_translators.pl
+++ b/scripts/extract_translators.pl
diff --git a/scripts/pluginstall.sh b/scripts/pluginstall.sh
new file mode 100644
index 00000000..433a5d8d
--- /dev/null
+++ b/scripts/pluginstall.sh
@@ -0,0 +1,3 @@
+#./scripts/portable_postbuild.sh
+sudo ./scripts/quickinstall.sh
+
diff --git a/scripts/portable_build.sh b/scripts/portable_build.sh
new file mode 100755
index 00000000..35ee48a1
--- /dev/null
+++ b/scripts/portable_build.sh
@@ -0,0 +1,17 @@
+#!/bin/sh
+VERSION=`cat PORTABLE_VERSION | perl -ne 'chomp and print'`
+ORIGIN=`pwd | perl -ne 'chomp and print'`
+export APBUILD_STATIC_LIBGCC=1
+
+CC=$ORIGIN/tools/apbuild/apgcc CXX=$ORIGIN/tools/apbuild/apgcc ./configure --enable-staticlink --enable-portable=yes --disable-pulse --disable-mpris --disable-nls
+sed -i 's/-lstdc++ -lm -lgcc_s -lc -lgcc_s/-lm -lc/g' libtool
+make clean
+make -j9
+
+echo "building pluginfo tool..."
+cd tools/pluginfo
+make
+cd ../../
+
+./scripts/portable_postbuild.sh
+
diff --git a/scripts/portable_package.sh b/scripts/portable_package.sh
new file mode 100755
index 00000000..fc6e09b6
--- /dev/null
+++ b/scripts/portable_package.sh
@@ -0,0 +1,74 @@
+#!/bin/sh
+
+# package for distribution
+VERSION=`cat PORTABLE_VERSION | perl -ne 'chomp and print'`
+BUILD=`cat PORTABLE_BUILD | perl -ne 'chomp and print'`
+
+# main distro
+SRCDIR=deadbeef-$VERSION-portable
+PLUGDIR=$SRCDIR/plugins
+DOCDIR=$SRCDIR/doc
+PIXMAPDIR=$SRCDIR/pixmaps
+
+mkdir -p portable_out/build 2>/dev/null
+rm portable_out/* 2>/dev/null
+rm portable_out/build/* 2>/dev/null
+
+tar jcvf portable_out/build/deadbeef-$VERSION-portable-r$BUILD.tar.bz2\
+ $SRCDIR/deadbeef\
+ $SRCDIR/deadbeef.png\
+ $DOCDIR\
+ $PLUGDIR/alsa.so\
+ $PLUGDIR/oss.so\
+ $PLUGDIR/vfs_curl.so\
+ $PLUGDIR/artwork.so\
+ $PLUGDIR/gtkui.so\
+ $PLUGDIR/gtkui.fallback.so\
+ $PLUGDIR/hotkeys.so\
+ $PLUGDIR/cdda.so\
+ $PLUGDIR/mpgmad.so\
+ $PLUGDIR/vorbis.so\
+ $PLUGDIR/wavpack.so\
+ $PLUGDIR/flac.so\
+ $PLUGDIR/ffap.so\
+ $PLUGDIR/musepack.so\
+ $PLUGDIR/notify.so\
+ $PLUGDIR/sndfile.so\
+ $PLUGDIR/supereq.so\
+ $PLUGDIR/tta.so\
+ $PIXMAPDIR
+
+# plugins
+cd $PLUGDIR
+
+plugtable=../../../deadbeef-web/web/plugins-autogen.mkd
+echo "<table><tr><th>Name</th><th>Version</th><th>Size</th><th>For Deadbeef</th><th>Description</th><th>Author(s)</th></tr>" >$plugtable
+
+PLUGINFO=../../tools/pluginfo/pluginfo
+
+for i in *.so ; do
+ plugname=`basename $i .so`
+ echo $plugname
+
+ version=""
+ $PLUGINFO ./$i >./temp.sh
+ RET=$?
+ if [ "$RET" = "0" ]; then
+ source ./temp.sh
+ rm ./temp.sh
+ if [[ -n $version ]]; then
+ echo "$plugname version $version"
+ else
+ echo "$plugname version not found"
+ fi
+ fname=../../portable_out/deadbeef-$VERSION-portable-$plugname-$version.tar.bz2
+ tar jcvf $fname $i
+ fsize=$(stat -c%s "$fname")
+
+ # add some markdown
+ echo "<tr><td><a href="http://sourceforge.net/projects/deadbeef/files/portable/$VERSION/deadbeef-$VERSION-portable-$plugname-$version.tar.bz2/download">$name ($plugname)</a></td><td>$version</td><td>$fsize</td><td>$VERSION</td><td>$descr</td><td>$author ($email, $website)</td></tr>" >>$plugtable
+ fi
+done
+echo "</table>" >>$plugtable
+cd ../../
+
diff --git a/scripts/portable_package_partial.sh b/scripts/portable_package_partial.sh
new file mode 100755
index 00000000..d3d63396
--- /dev/null
+++ b/scripts/portable_package_partial.sh
@@ -0,0 +1,36 @@
+#!/bin/sh
+
+# package for distribution
+VERSION=`cat PORTABLE_VERSION | perl -ne 'chomp and print'`
+BUILD=`cat PORTABLE_BUILD | perl -ne 'chomp and print'`
+
+# main distro
+SRCDIR=deadbeef-$VERSION-portable
+PLUGDIR=$SRCDIR/plugins
+DOCDIR=$SRCDIR/doc
+PIXMAPDIR=$SRCDIR/pixmaps
+
+tar jcvf portable_out/build/deadbeef-$VERSION-portable-partial-r$BUILD.tar.bz2\
+ $SRCDIR/deadbeef\
+ $SRCDIR/deadbeef.png\
+ $DOCDIR\
+ $PLUGDIR/alsa.so\
+ $PLUGDIR/oss.so\
+ $PLUGDIR/vfs_curl.so\
+ $PLUGDIR/artwork.so\
+ $PLUGDIR/gtkui.so\
+ $PLUGDIR/gtkui.fallback.so\
+ $PLUGDIR/hotkeys.so\
+ $PLUGDIR/cdda.so\
+ $PLUGDIR/mpgmad.so\
+ $PLUGDIR/vorbis.so\
+ $PLUGDIR/wavpack.so\
+ $PLUGDIR/flac.so\
+ $PLUGDIR/ffap.so\
+ $PLUGDIR/musepack.so\
+ $PLUGDIR/notify.so\
+ $PLUGDIR/sndfile.so\
+ $PLUGDIR/supereq.so\
+ $PLUGDIR/tta.so\
+ $PIXMAPDIR
+
diff --git a/scripts/portable_postbuild.sh b/scripts/portable_postbuild.sh
new file mode 100755
index 00000000..41c573dd
--- /dev/null
+++ b/scripts/portable_postbuild.sh
@@ -0,0 +1,52 @@
+#!/bin/sh
+VERSION=`cat PORTABLE_VERSION | perl -ne 'chomp and print'`
+OSTYPE=`uname -s`
+OUTDIR=deadbeef-$VERSION-portable
+PLUGDIR=$OUTDIR/plugins
+DOCDIR=$OUTDIR/doc
+PIXMAPDIR=$OUTDIR/pixmaps
+mkdir -p $PLUGDIR
+mkdir -p $DOCDIR
+mkdir -p $PIXMAPDIR
+
+cp ./deadbeef ./deadbeef-$VERSION-portable/
+
+for i in nullout cdda flac alsa mpgmad hotkeys vtx \
+ ffap ffmpeg wavpack vorbis oss vfs_curl \
+ lastfm sid adplug sndfile artwork \
+ supereq gme dumb notify musepack wildmidi \
+ tta dca aac mms shn ao shellexec; do
+ if [ -f ./plugins/$i/.libs/$i.so ]; then
+ cp ./plugins/$i/.libs/$i.so $PLUGDIR/
+ else
+ echo $i not found
+ fi
+done
+
+for i in gtkui gtkui.fallback;do
+ if [ -f ./plugins/$i/.libs/$i.so ]; then
+ cp ./plugins/$i/.libs/$i.so $PLUGDIR/
+ else
+ echo $i not found
+ fi
+done
+
+#pixmaps
+
+for i in pause_16.png play_16.png noartwork.jpg buffering_16.png; do
+ cp ./pixmaps/$i $PIXMAPDIR/
+done
+
+# docs
+for i in ChangeLog help.txt COPYING.GPLv2 about.txt translators.txt; do
+ cp ./$i $DOCDIR/
+done
+
+# icon
+cp ./icons/32x32/deadbeef.png $OUTDIR/
+
+# strip
+if [ $OSTYPE != 'Darwin' ];then
+ strip --strip-unneeded ./deadbeef-$VERSION-portable/deadbeef
+ for i in $PLUGDIR/*.so ; do strip --strip-unneeded $i ; done
+fi
diff --git a/scripts/portable_upload.sh b/scripts/portable_upload.sh
new file mode 100755
index 00000000..482e66ea
--- /dev/null
+++ b/scripts/portable_upload.sh
@@ -0,0 +1,9 @@
+#!/bin/sh
+
+VERSION=`cat PORTABLE_VERSION | perl -ne 'chomp and print'`
+BUILD=`cat PORTABLE_BUILD | perl -ne 'chomp and print'`
+
+UPLOAD_URI=waker,deadbeef@frs.sourceforge.net:/home/frs/project/d/de/deadbeef/portable/$VERSION/
+
+scp portable_out/* $UPLOAD_URI/
+scp portable_out/build/* $UPLOAD_URI/
diff --git a/scripts/quickinstall.sh b/scripts/quickinstall.sh
new file mode 100755
index 00000000..59d270cf
--- /dev/null
+++ b/scripts/quickinstall.sh
@@ -0,0 +1,43 @@
+#!/bin/sh
+rm /usr/local/lib/deadbeef/*.so
+cp ./deadbeef /usr/local/bin/
+cp ./plugins/nullout/.libs/nullout.so /usr/local/lib/deadbeef/
+cp ./plugins/cdda/.libs/cdda.so /usr/local/lib/deadbeef/
+cp ./plugins/flac/.libs/flac.so /usr/local/lib/deadbeef/
+cp ./plugins/alsa/.libs/alsa.so /usr/local/lib/deadbeef/
+cp ./plugins/mpgmad/.libs/mpgmad.so /usr/local/lib/deadbeef/
+cp ./plugins/hotkeys/.libs/hotkeys.so /usr/local/lib/deadbeef/
+cp ./plugins/vtx/.libs/vtx.so /usr/local/lib/deadbeef/
+cp ./plugins/ffap/.libs/ffap.so /usr/local/lib/deadbeef/
+cp ./plugins/wavpack/.libs/wavpack.so /usr/local/lib/deadbeef/
+cp ./plugins/vorbis/.libs/vorbis.so /usr/local/lib/deadbeef/
+cp ./plugins/oss/.libs/oss.so /usr/local/lib/deadbeef/
+cp ./plugins/vfs_curl/.libs/vfs_curl.so /usr/local/lib/deadbeef/
+cp ./plugins/ffmpeg/.libs/ffmpeg.so /usr/local/lib/deadbeef/
+cp ./plugins/lastfm/.libs/lastfm.so /usr/local/lib/deadbeef/
+cp ./plugins/sid/.libs/sid.so /usr/local/lib/deadbeef/
+cp ./plugins/adplug/.libs/adplug.so /usr/local/lib/deadbeef/
+cp ./plugins/gtkui/.libs/ddb_gui_GTK2.so /usr/local/lib/deadbeef/
+cp ./plugins/sndfile/.libs/sndfile.so /usr/local/lib/deadbeef/
+cp ./plugins/pulse/.libs/pulse.so /usr/local/lib/deadbeef/
+cp ./plugins/artwork/.libs/artwork.so /usr/local/lib/deadbeef/
+cp ./plugins/supereq/.libs/supereq.so /usr/local/lib/deadbeef/
+cp ./plugins/gme/.libs/gme.so /usr/local/lib/deadbeef/
+cp ./plugins/dumb/dumb.so /usr/local/lib/deadbeef/
+cp ./plugins/notify/.libs/notify.so /usr/local/lib/deadbeef/
+cp ./plugins/musepack/.libs/musepack.so /usr/local/lib/deadbeef/
+cp ./plugins/wildmidi/.libs/wildmidi.so /usr/local/lib/deadbeef/
+cp ./plugins/tta/.libs/tta.so /usr/local/lib/deadbeef/
+cp ./plugins/dca/.libs/dca.so /usr/local/lib/deadbeef/
+cp ./plugins/aac/.libs/aac.so /usr/local/lib/deadbeef/
+cp ./plugins/mms/.libs/mms.so /usr/local/lib/deadbeef/
+cp ./plugins/shn/shn.so /usr/local/lib/deadbeef/
+cp ./plugins/ao/ao.so /usr/local/lib/deadbeef/
+cp ./plugins/shellexec/.libs/shellexec.so /usr/local/lib/deadbeef/
+cp ./plugins/dsp_libsrc/.libs/dsp_libsrc.so /usr/local/lib/deadbeef/
+cp ./plugins/m3u/.libs/m3u.so /usr/local/lib/deadbeef/
+cp ./plugins/ddb_input_uade2/ddb_input_uade2.so /usr/local/lib/deadbeef/
+cp ./plugins/converter/converter.so /usr/local/lib/deadbeef/
+cp ./plugins/converter/converter_gtkui.so /usr/local/lib/deadbeef/
+cp ./plugins/soundtouch/ddb_soundtouch.so /usr/local/lib/deadbeef/
+cp ./plugins/vfs_zip/.libs/vfs_zip.so /usr/local/lib/deadbeef/
diff --git a/scripts/u8_casemap/UnicodeData.txt b/scripts/u8_casemap/UnicodeData.txt
new file mode 100644
index 00000000..8d7222b1
--- /dev/null
+++ b/scripts/u8_casemap/UnicodeData.txt
@@ -0,0 +1,23697 @@
+0000;<control>;Cc;0;BN;;;;;N;NULL;;;;
+0001;<control>;Cc;0;BN;;;;;N;START OF HEADING;;;;
+0002;<control>;Cc;0;BN;;;;;N;START OF TEXT;;;;
+0003;<control>;Cc;0;BN;;;;;N;END OF TEXT;;;;
+0004;<control>;Cc;0;BN;;;;;N;END OF TRANSMISSION;;;;
+0005;<control>;Cc;0;BN;;;;;N;ENQUIRY;;;;
+0006;<control>;Cc;0;BN;;;;;N;ACKNOWLEDGE;;;;
+0007;<control>;Cc;0;BN;;;;;N;BELL;;;;
+0008;<control>;Cc;0;BN;;;;;N;BACKSPACE;;;;
+0009;<control>;Cc;0;S;;;;;N;CHARACTER TABULATION;;;;
+000A;<control>;Cc;0;B;;;;;N;LINE FEED (LF);;;;
+000B;<control>;Cc;0;S;;;;;N;LINE TABULATION;;;;
+000C;<control>;Cc;0;WS;;;;;N;FORM FEED (FF);;;;
+000D;<control>;Cc;0;B;;;;;N;CARRIAGE RETURN (CR);;;;
+000E;<control>;Cc;0;BN;;;;;N;SHIFT OUT;;;;
+000F;<control>;Cc;0;BN;;;;;N;SHIFT IN;;;;
+0010;<control>;Cc;0;BN;;;;;N;DATA LINK ESCAPE;;;;
+0011;<control>;Cc;0;BN;;;;;N;DEVICE CONTROL ONE;;;;
+0012;<control>;Cc;0;BN;;;;;N;DEVICE CONTROL TWO;;;;
+0013;<control>;Cc;0;BN;;;;;N;DEVICE CONTROL THREE;;;;
+0014;<control>;Cc;0;BN;;;;;N;DEVICE CONTROL FOUR;;;;
+0015;<control>;Cc;0;BN;;;;;N;NEGATIVE ACKNOWLEDGE;;;;
+0016;<control>;Cc;0;BN;;;;;N;SYNCHRONOUS IDLE;;;;
+0017;<control>;Cc;0;BN;;;;;N;END OF TRANSMISSION BLOCK;;;;
+0018;<control>;Cc;0;BN;;;;;N;CANCEL;;;;
+0019;<control>;Cc;0;BN;;;;;N;END OF MEDIUM;;;;
+001A;<control>;Cc;0;BN;;;;;N;SUBSTITUTE;;;;
+001B;<control>;Cc;0;BN;;;;;N;ESCAPE;;;;
+001C;<control>;Cc;0;B;;;;;N;INFORMATION SEPARATOR FOUR;;;;
+001D;<control>;Cc;0;B;;;;;N;INFORMATION SEPARATOR THREE;;;;
+001E;<control>;Cc;0;B;;;;;N;INFORMATION SEPARATOR TWO;;;;
+001F;<control>;Cc;0;S;;;;;N;INFORMATION SEPARATOR ONE;;;;
+0020;SPACE;Zs;0;WS;;;;;N;;;;;
+0021;EXCLAMATION MARK;Po;0;ON;;;;;N;;;;;
+0022;QUOTATION MARK;Po;0;ON;;;;;N;;;;;
+0023;NUMBER SIGN;Po;0;ET;;;;;N;;;;;
+0024;DOLLAR SIGN;Sc;0;ET;;;;;N;;;;;
+0025;PERCENT SIGN;Po;0;ET;;;;;N;;;;;
+0026;AMPERSAND;Po;0;ON;;;;;N;;;;;
+0027;APOSTROPHE;Po;0;ON;;;;;N;APOSTROPHE-QUOTE;;;;
+0028;LEFT PARENTHESIS;Ps;0;ON;;;;;Y;OPENING PARENTHESIS;;;;
+0029;RIGHT PARENTHESIS;Pe;0;ON;;;;;Y;CLOSING PARENTHESIS;;;;
+002A;ASTERISK;Po;0;ON;;;;;N;;;;;
+002B;PLUS SIGN;Sm;0;ES;;;;;N;;;;;
+002C;COMMA;Po;0;CS;;;;;N;;;;;
+002D;HYPHEN-MINUS;Pd;0;ES;;;;;N;;;;;
+002E;FULL STOP;Po;0;CS;;;;;N;PERIOD;;;;
+002F;SOLIDUS;Po;0;CS;;;;;N;SLASH;;;;
+0030;DIGIT ZERO;Nd;0;EN;;0;0;0;N;;;;;
+0031;DIGIT ONE;Nd;0;EN;;1;1;1;N;;;;;
+0032;DIGIT TWO;Nd;0;EN;;2;2;2;N;;;;;
+0033;DIGIT THREE;Nd;0;EN;;3;3;3;N;;;;;
+0034;DIGIT FOUR;Nd;0;EN;;4;4;4;N;;;;;
+0035;DIGIT FIVE;Nd;0;EN;;5;5;5;N;;;;;
+0036;DIGIT SIX;Nd;0;EN;;6;6;6;N;;;;;
+0037;DIGIT SEVEN;Nd;0;EN;;7;7;7;N;;;;;
+0038;DIGIT EIGHT;Nd;0;EN;;8;8;8;N;;;;;
+0039;DIGIT NINE;Nd;0;EN;;9;9;9;N;;;;;
+003A;COLON;Po;0;CS;;;;;N;;;;;
+003B;SEMICOLON;Po;0;ON;;;;;N;;;;;
+003C;LESS-THAN SIGN;Sm;0;ON;;;;;Y;;;;;
+003D;EQUALS SIGN;Sm;0;ON;;;;;N;;;;;
+003E;GREATER-THAN SIGN;Sm;0;ON;;;;;Y;;;;;
+003F;QUESTION MARK;Po;0;ON;;;;;N;;;;;
+0040;COMMERCIAL AT;Po;0;ON;;;;;N;;;;;
+0041;LATIN CAPITAL LETTER A;Lu;0;L;;;;;N;;;;0061;
+0042;LATIN CAPITAL LETTER B;Lu;0;L;;;;;N;;;;0062;
+0043;LATIN CAPITAL LETTER C;Lu;0;L;;;;;N;;;;0063;
+0044;LATIN CAPITAL LETTER D;Lu;0;L;;;;;N;;;;0064;
+0045;LATIN CAPITAL LETTER E;Lu;0;L;;;;;N;;;;0065;
+0046;LATIN CAPITAL LETTER F;Lu;0;L;;;;;N;;;;0066;
+0047;LATIN CAPITAL LETTER G;Lu;0;L;;;;;N;;;;0067;
+0048;LATIN CAPITAL LETTER H;Lu;0;L;;;;;N;;;;0068;
+0049;LATIN CAPITAL LETTER I;Lu;0;L;;;;;N;;;;0069;
+004A;LATIN CAPITAL LETTER J;Lu;0;L;;;;;N;;;;006A;
+004B;LATIN CAPITAL LETTER K;Lu;0;L;;;;;N;;;;006B;
+004C;LATIN CAPITAL LETTER L;Lu;0;L;;;;;N;;;;006C;
+004D;LATIN CAPITAL LETTER M;Lu;0;L;;;;;N;;;;006D;
+004E;LATIN CAPITAL LETTER N;Lu;0;L;;;;;N;;;;006E;
+004F;LATIN CAPITAL LETTER O;Lu;0;L;;;;;N;;;;006F;
+0050;LATIN CAPITAL LETTER P;Lu;0;L;;;;;N;;;;0070;
+0051;LATIN CAPITAL LETTER Q;Lu;0;L;;;;;N;;;;0071;
+0052;LATIN CAPITAL LETTER R;Lu;0;L;;;;;N;;;;0072;
+0053;LATIN CAPITAL LETTER S;Lu;0;L;;;;;N;;;;0073;
+0054;LATIN CAPITAL LETTER T;Lu;0;L;;;;;N;;;;0074;
+0055;LATIN CAPITAL LETTER U;Lu;0;L;;;;;N;;;;0075;
+0056;LATIN CAPITAL LETTER V;Lu;0;L;;;;;N;;;;0076;
+0057;LATIN CAPITAL LETTER W;Lu;0;L;;;;;N;;;;0077;
+0058;LATIN CAPITAL LETTER X;Lu;0;L;;;;;N;;;;0078;
+0059;LATIN CAPITAL LETTER Y;Lu;0;L;;;;;N;;;;0079;
+005A;LATIN CAPITAL LETTER Z;Lu;0;L;;;;;N;;;;007A;
+005B;LEFT SQUARE BRACKET;Ps;0;ON;;;;;Y;OPENING SQUARE BRACKET;;;;
+005C;REVERSE SOLIDUS;Po;0;ON;;;;;N;BACKSLASH;;;;
+005D;RIGHT SQUARE BRACKET;Pe;0;ON;;;;;Y;CLOSING SQUARE BRACKET;;;;
+005E;CIRCUMFLEX ACCENT;Sk;0;ON;;;;;N;SPACING CIRCUMFLEX;;;;
+005F;LOW LINE;Pc;0;ON;;;;;N;SPACING UNDERSCORE;;;;
+0060;GRAVE ACCENT;Sk;0;ON;;;;;N;SPACING GRAVE;;;;
+0061;LATIN SMALL LETTER A;Ll;0;L;;;;;N;;;0041;;0041
+0062;LATIN SMALL LETTER B;Ll;0;L;;;;;N;;;0042;;0042
+0063;LATIN SMALL LETTER C;Ll;0;L;;;;;N;;;0043;;0043
+0064;LATIN SMALL LETTER D;Ll;0;L;;;;;N;;;0044;;0044
+0065;LATIN SMALL LETTER E;Ll;0;L;;;;;N;;;0045;;0045
+0066;LATIN SMALL LETTER F;Ll;0;L;;;;;N;;;0046;;0046
+0067;LATIN SMALL LETTER G;Ll;0;L;;;;;N;;;0047;;0047
+0068;LATIN SMALL LETTER H;Ll;0;L;;;;;N;;;0048;;0048
+0069;LATIN SMALL LETTER I;Ll;0;L;;;;;N;;;0049;;0049
+006A;LATIN SMALL LETTER J;Ll;0;L;;;;;N;;;004A;;004A
+006B;LATIN SMALL LETTER K;Ll;0;L;;;;;N;;;004B;;004B
+006C;LATIN SMALL LETTER L;Ll;0;L;;;;;N;;;004C;;004C
+006D;LATIN SMALL LETTER M;Ll;0;L;;;;;N;;;004D;;004D
+006E;LATIN SMALL LETTER N;Ll;0;L;;;;;N;;;004E;;004E
+006F;LATIN SMALL LETTER O;Ll;0;L;;;;;N;;;004F;;004F
+0070;LATIN SMALL LETTER P;Ll;0;L;;;;;N;;;0050;;0050
+0071;LATIN SMALL LETTER Q;Ll;0;L;;;;;N;;;0051;;0051
+0072;LATIN SMALL LETTER R;Ll;0;L;;;;;N;;;0052;;0052
+0073;LATIN SMALL LETTER S;Ll;0;L;;;;;N;;;0053;;0053
+0074;LATIN SMALL LETTER T;Ll;0;L;;;;;N;;;0054;;0054
+0075;LATIN SMALL LETTER U;Ll;0;L;;;;;N;;;0055;;0055
+0076;LATIN SMALL LETTER V;Ll;0;L;;;;;N;;;0056;;0056
+0077;LATIN SMALL LETTER W;Ll;0;L;;;;;N;;;0057;;0057
+0078;LATIN SMALL LETTER X;Ll;0;L;;;;;N;;;0058;;0058
+0079;LATIN SMALL LETTER Y;Ll;0;L;;;;;N;;;0059;;0059
+007A;LATIN SMALL LETTER Z;Ll;0;L;;;;;N;;;005A;;005A
+007B;LEFT CURLY BRACKET;Ps;0;ON;;;;;Y;OPENING CURLY BRACKET;;;;
+007C;VERTICAL LINE;Sm;0;ON;;;;;N;VERTICAL BAR;;;;
+007D;RIGHT CURLY BRACKET;Pe;0;ON;;;;;Y;CLOSING CURLY BRACKET;;;;
+007E;TILDE;Sm;0;ON;;;;;N;;;;;
+007F;<control>;Cc;0;BN;;;;;N;DELETE;;;;
+0080;<control>;Cc;0;BN;;;;;N;;;;;
+0081;<control>;Cc;0;BN;;;;;N;;;;;
+0082;<control>;Cc;0;BN;;;;;N;BREAK PERMITTED HERE;;;;
+0083;<control>;Cc;0;BN;;;;;N;NO BREAK HERE;;;;
+0084;<control>;Cc;0;BN;;;;;N;;;;;
+0085;<control>;Cc;0;B;;;;;N;NEXT LINE (NEL);;;;
+0086;<control>;Cc;0;BN;;;;;N;START OF SELECTED AREA;;;;
+0087;<control>;Cc;0;BN;;;;;N;END OF SELECTED AREA;;;;
+0088;<control>;Cc;0;BN;;;;;N;CHARACTER TABULATION SET;;;;
+0089;<control>;Cc;0;BN;;;;;N;CHARACTER TABULATION WITH JUSTIFICATION;;;;
+008A;<control>;Cc;0;BN;;;;;N;LINE TABULATION SET;;;;
+008B;<control>;Cc;0;BN;;;;;N;PARTIAL LINE FORWARD;;;;
+008C;<control>;Cc;0;BN;;;;;N;PARTIAL LINE BACKWARD;;;;
+008D;<control>;Cc;0;BN;;;;;N;REVERSE LINE FEED;;;;
+008E;<control>;Cc;0;BN;;;;;N;SINGLE SHIFT TWO;;;;
+008F;<control>;Cc;0;BN;;;;;N;SINGLE SHIFT THREE;;;;
+0090;<control>;Cc;0;BN;;;;;N;DEVICE CONTROL STRING;;;;
+0091;<control>;Cc;0;BN;;;;;N;PRIVATE USE ONE;;;;
+0092;<control>;Cc;0;BN;;;;;N;PRIVATE USE TWO;;;;
+0093;<control>;Cc;0;BN;;;;;N;SET TRANSMIT STATE;;;;
+0094;<control>;Cc;0;BN;;;;;N;CANCEL CHARACTER;;;;
+0095;<control>;Cc;0;BN;;;;;N;MESSAGE WAITING;;;;
+0096;<control>;Cc;0;BN;;;;;N;START OF GUARDED AREA;;;;
+0097;<control>;Cc;0;BN;;;;;N;END OF GUARDED AREA;;;;
+0098;<control>;Cc;0;BN;;;;;N;START OF STRING;;;;
+0099;<control>;Cc;0;BN;;;;;N;;;;;
+009A;<control>;Cc;0;BN;;;;;N;SINGLE CHARACTER INTRODUCER;;;;
+009B;<control>;Cc;0;BN;;;;;N;CONTROL SEQUENCE INTRODUCER;;;;
+009C;<control>;Cc;0;BN;;;;;N;STRING TERMINATOR;;;;
+009D;<control>;Cc;0;BN;;;;;N;OPERATING SYSTEM COMMAND;;;;
+009E;<control>;Cc;0;BN;;;;;N;PRIVACY MESSAGE;;;;
+009F;<control>;Cc;0;BN;;;;;N;APPLICATION PROGRAM COMMAND;;;;
+00A0;NO-BREAK SPACE;Zs;0;CS;<noBreak> 0020;;;;N;NON-BREAKING SPACE;;;;
+00A1;INVERTED EXCLAMATION MARK;Po;0;ON;;;;;N;;;;;
+00A2;CENT SIGN;Sc;0;ET;;;;;N;;;;;
+00A3;POUND SIGN;Sc;0;ET;;;;;N;;;;;
+00A4;CURRENCY SIGN;Sc;0;ET;;;;;N;;;;;
+00A5;YEN SIGN;Sc;0;ET;;;;;N;;;;;
+00A6;BROKEN BAR;So;0;ON;;;;;N;BROKEN VERTICAL BAR;;;;
+00A7;SECTION SIGN;So;0;ON;;;;;N;;;;;
+00A8;DIAERESIS;Sk;0;ON;<compat> 0020 0308;;;;N;SPACING DIAERESIS;;;;
+00A9;COPYRIGHT SIGN;So;0;ON;;;;;N;;;;;
+00AA;FEMININE ORDINAL INDICATOR;Ll;0;L;<super> 0061;;;;N;;;;;
+00AB;LEFT-POINTING DOUBLE ANGLE QUOTATION MARK;Pi;0;ON;;;;;Y;LEFT POINTING GUILLEMET;;;;
+00AC;NOT SIGN;Sm;0;ON;;;;;N;;;;;
+00AD;SOFT HYPHEN;Cf;0;BN;;;;;N;;;;;
+00AE;REGISTERED SIGN;So;0;ON;;;;;N;REGISTERED TRADE MARK SIGN;;;;
+00AF;MACRON;Sk;0;ON;<compat> 0020 0304;;;;N;SPACING MACRON;;;;
+00B0;DEGREE SIGN;So;0;ET;;;;;N;;;;;
+00B1;PLUS-MINUS SIGN;Sm;0;ET;;;;;N;PLUS-OR-MINUS SIGN;;;;
+00B2;SUPERSCRIPT TWO;No;0;EN;<super> 0032;;2;2;N;SUPERSCRIPT DIGIT TWO;;;;
+00B3;SUPERSCRIPT THREE;No;0;EN;<super> 0033;;3;3;N;SUPERSCRIPT DIGIT THREE;;;;
+00B4;ACUTE ACCENT;Sk;0;ON;<compat> 0020 0301;;;;N;SPACING ACUTE;;;;
+00B5;MICRO SIGN;Ll;0;L;<compat> 03BC;;;;N;;;039C;;039C
+00B6;PILCROW SIGN;So;0;ON;;;;;N;PARAGRAPH SIGN;;;;
+00B7;MIDDLE DOT;Po;0;ON;;;;;N;;;;;
+00B8;CEDILLA;Sk;0;ON;<compat> 0020 0327;;;;N;SPACING CEDILLA;;;;
+00B9;SUPERSCRIPT ONE;No;0;EN;<super> 0031;;1;1;N;SUPERSCRIPT DIGIT ONE;;;;
+00BA;MASCULINE ORDINAL INDICATOR;Ll;0;L;<super> 006F;;;;N;;;;;
+00BB;RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK;Pf;0;ON;;;;;Y;RIGHT POINTING GUILLEMET;;;;
+00BC;VULGAR FRACTION ONE QUARTER;No;0;ON;<fraction> 0031 2044 0034;;;1/4;N;FRACTION ONE QUARTER;;;;
+00BD;VULGAR FRACTION ONE HALF;No;0;ON;<fraction> 0031 2044 0032;;;1/2;N;FRACTION ONE HALF;;;;
+00BE;VULGAR FRACTION THREE QUARTERS;No;0;ON;<fraction> 0033 2044 0034;;;3/4;N;FRACTION THREE QUARTERS;;;;
+00BF;INVERTED QUESTION MARK;Po;0;ON;;;;;N;;;;;
+00C0;LATIN CAPITAL LETTER A WITH GRAVE;Lu;0;L;0041 0300;;;;N;LATIN CAPITAL LETTER A GRAVE;;;00E0;
+00C1;LATIN CAPITAL LETTER A WITH ACUTE;Lu;0;L;0041 0301;;;;N;LATIN CAPITAL LETTER A ACUTE;;;00E1;
+00C2;LATIN CAPITAL LETTER A WITH CIRCUMFLEX;Lu;0;L;0041 0302;;;;N;LATIN CAPITAL LETTER A CIRCUMFLEX;;;00E2;
+00C3;LATIN CAPITAL LETTER A WITH TILDE;Lu;0;L;0041 0303;;;;N;LATIN CAPITAL LETTER A TILDE;;;00E3;
+00C4;LATIN CAPITAL LETTER A WITH DIAERESIS;Lu;0;L;0041 0308;;;;N;LATIN CAPITAL LETTER A DIAERESIS;;;00E4;
+00C5;LATIN CAPITAL LETTER A WITH RING ABOVE;Lu;0;L;0041 030A;;;;N;LATIN CAPITAL LETTER A RING;;;00E5;
+00C6;LATIN CAPITAL LETTER AE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER A E;;;00E6;
+00C7;LATIN CAPITAL LETTER C WITH CEDILLA;Lu;0;L;0043 0327;;;;N;LATIN CAPITAL LETTER C CEDILLA;;;00E7;
+00C8;LATIN CAPITAL LETTER E WITH GRAVE;Lu;0;L;0045 0300;;;;N;LATIN CAPITAL LETTER E GRAVE;;;00E8;
+00C9;LATIN CAPITAL LETTER E WITH ACUTE;Lu;0;L;0045 0301;;;;N;LATIN CAPITAL LETTER E ACUTE;;;00E9;
+00CA;LATIN CAPITAL LETTER E WITH CIRCUMFLEX;Lu;0;L;0045 0302;;;;N;LATIN CAPITAL LETTER E CIRCUMFLEX;;;00EA;
+00CB;LATIN CAPITAL LETTER E WITH DIAERESIS;Lu;0;L;0045 0308;;;;N;LATIN CAPITAL LETTER E DIAERESIS;;;00EB;
+00CC;LATIN CAPITAL LETTER I WITH GRAVE;Lu;0;L;0049 0300;;;;N;LATIN CAPITAL LETTER I GRAVE;;;00EC;
+00CD;LATIN CAPITAL LETTER I WITH ACUTE;Lu;0;L;0049 0301;;;;N;LATIN CAPITAL LETTER I ACUTE;;;00ED;
+00CE;LATIN CAPITAL LETTER I WITH CIRCUMFLEX;Lu;0;L;0049 0302;;;;N;LATIN CAPITAL LETTER I CIRCUMFLEX;;;00EE;
+00CF;LATIN CAPITAL LETTER I WITH DIAERESIS;Lu;0;L;0049 0308;;;;N;LATIN CAPITAL LETTER I DIAERESIS;;;00EF;
+00D0;LATIN CAPITAL LETTER ETH;Lu;0;L;;;;;N;;;;00F0;
+00D1;LATIN CAPITAL LETTER N WITH TILDE;Lu;0;L;004E 0303;;;;N;LATIN CAPITAL LETTER N TILDE;;;00F1;
+00D2;LATIN CAPITAL LETTER O WITH GRAVE;Lu;0;L;004F 0300;;;;N;LATIN CAPITAL LETTER O GRAVE;;;00F2;
+00D3;LATIN CAPITAL LETTER O WITH ACUTE;Lu;0;L;004F 0301;;;;N;LATIN CAPITAL LETTER O ACUTE;;;00F3;
+00D4;LATIN CAPITAL LETTER O WITH CIRCUMFLEX;Lu;0;L;004F 0302;;;;N;LATIN CAPITAL LETTER O CIRCUMFLEX;;;00F4;
+00D5;LATIN CAPITAL LETTER O WITH TILDE;Lu;0;L;004F 0303;;;;N;LATIN CAPITAL LETTER O TILDE;;;00F5;
+00D6;LATIN CAPITAL LETTER O WITH DIAERESIS;Lu;0;L;004F 0308;;;;N;LATIN CAPITAL LETTER O DIAERESIS;;;00F6;
+00D7;MULTIPLICATION SIGN;Sm;0;ON;;;;;N;;;;;
+00D8;LATIN CAPITAL LETTER O WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER O SLASH;;;00F8;
+00D9;LATIN CAPITAL LETTER U WITH GRAVE;Lu;0;L;0055 0300;;;;N;LATIN CAPITAL LETTER U GRAVE;;;00F9;
+00DA;LATIN CAPITAL LETTER U WITH ACUTE;Lu;0;L;0055 0301;;;;N;LATIN CAPITAL LETTER U ACUTE;;;00FA;
+00DB;LATIN CAPITAL LETTER U WITH CIRCUMFLEX;Lu;0;L;0055 0302;;;;N;LATIN CAPITAL LETTER U CIRCUMFLEX;;;00FB;
+00DC;LATIN CAPITAL LETTER U WITH DIAERESIS;Lu;0;L;0055 0308;;;;N;LATIN CAPITAL LETTER U DIAERESIS;;;00FC;
+00DD;LATIN CAPITAL LETTER Y WITH ACUTE;Lu;0;L;0059 0301;;;;N;LATIN CAPITAL LETTER Y ACUTE;;;00FD;
+00DE;LATIN CAPITAL LETTER THORN;Lu;0;L;;;;;N;;;;00FE;
+00DF;LATIN SMALL LETTER SHARP S;Ll;0;L;;;;;N;;;;;
+00E0;LATIN SMALL LETTER A WITH GRAVE;Ll;0;L;0061 0300;;;;N;LATIN SMALL LETTER A GRAVE;;00C0;;00C0
+00E1;LATIN SMALL LETTER A WITH ACUTE;Ll;0;L;0061 0301;;;;N;LATIN SMALL LETTER A ACUTE;;00C1;;00C1
+00E2;LATIN SMALL LETTER A WITH CIRCUMFLEX;Ll;0;L;0061 0302;;;;N;LATIN SMALL LETTER A CIRCUMFLEX;;00C2;;00C2
+00E3;LATIN SMALL LETTER A WITH TILDE;Ll;0;L;0061 0303;;;;N;LATIN SMALL LETTER A TILDE;;00C3;;00C3
+00E4;LATIN SMALL LETTER A WITH DIAERESIS;Ll;0;L;0061 0308;;;;N;LATIN SMALL LETTER A DIAERESIS;;00C4;;00C4
+00E5;LATIN SMALL LETTER A WITH RING ABOVE;Ll;0;L;0061 030A;;;;N;LATIN SMALL LETTER A RING;;00C5;;00C5
+00E6;LATIN SMALL LETTER AE;Ll;0;L;;;;;N;LATIN SMALL LETTER A E;;00C6;;00C6
+00E7;LATIN SMALL LETTER C WITH CEDILLA;Ll;0;L;0063 0327;;;;N;LATIN SMALL LETTER C CEDILLA;;00C7;;00C7
+00E8;LATIN SMALL LETTER E WITH GRAVE;Ll;0;L;0065 0300;;;;N;LATIN SMALL LETTER E GRAVE;;00C8;;00C8
+00E9;LATIN SMALL LETTER E WITH ACUTE;Ll;0;L;0065 0301;;;;N;LATIN SMALL LETTER E ACUTE;;00C9;;00C9
+00EA;LATIN SMALL LETTER E WITH CIRCUMFLEX;Ll;0;L;0065 0302;;;;N;LATIN SMALL LETTER E CIRCUMFLEX;;00CA;;00CA
+00EB;LATIN SMALL LETTER E WITH DIAERESIS;Ll;0;L;0065 0308;;;;N;LATIN SMALL LETTER E DIAERESIS;;00CB;;00CB
+00EC;LATIN SMALL LETTER I WITH GRAVE;Ll;0;L;0069 0300;;;;N;LATIN SMALL LETTER I GRAVE;;00CC;;00CC
+00ED;LATIN SMALL LETTER I WITH ACUTE;Ll;0;L;0069 0301;;;;N;LATIN SMALL LETTER I ACUTE;;00CD;;00CD
+00EE;LATIN SMALL LETTER I WITH CIRCUMFLEX;Ll;0;L;0069 0302;;;;N;LATIN SMALL LETTER I CIRCUMFLEX;;00CE;;00CE
+00EF;LATIN SMALL LETTER I WITH DIAERESIS;Ll;0;L;0069 0308;;;;N;LATIN SMALL LETTER I DIAERESIS;;00CF;;00CF
+00F0;LATIN SMALL LETTER ETH;Ll;0;L;;;;;N;;;00D0;;00D0
+00F1;LATIN SMALL LETTER N WITH TILDE;Ll;0;L;006E 0303;;;;N;LATIN SMALL LETTER N TILDE;;00D1;;00D1
+00F2;LATIN SMALL LETTER O WITH GRAVE;Ll;0;L;006F 0300;;;;N;LATIN SMALL LETTER O GRAVE;;00D2;;00D2
+00F3;LATIN SMALL LETTER O WITH ACUTE;Ll;0;L;006F 0301;;;;N;LATIN SMALL LETTER O ACUTE;;00D3;;00D3
+00F4;LATIN SMALL LETTER O WITH CIRCUMFLEX;Ll;0;L;006F 0302;;;;N;LATIN SMALL LETTER O CIRCUMFLEX;;00D4;;00D4
+00F5;LATIN SMALL LETTER O WITH TILDE;Ll;0;L;006F 0303;;;;N;LATIN SMALL LETTER O TILDE;;00D5;;00D5
+00F6;LATIN SMALL LETTER O WITH DIAERESIS;Ll;0;L;006F 0308;;;;N;LATIN SMALL LETTER O DIAERESIS;;00D6;;00D6
+00F7;DIVISION SIGN;Sm;0;ON;;;;;N;;;;;
+00F8;LATIN SMALL LETTER O WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER O SLASH;;00D8;;00D8
+00F9;LATIN SMALL LETTER U WITH GRAVE;Ll;0;L;0075 0300;;;;N;LATIN SMALL LETTER U GRAVE;;00D9;;00D9
+00FA;LATIN SMALL LETTER U WITH ACUTE;Ll;0;L;0075 0301;;;;N;LATIN SMALL LETTER U ACUTE;;00DA;;00DA
+00FB;LATIN SMALL LETTER U WITH CIRCUMFLEX;Ll;0;L;0075 0302;;;;N;LATIN SMALL LETTER U CIRCUMFLEX;;00DB;;00DB
+00FC;LATIN SMALL LETTER U WITH DIAERESIS;Ll;0;L;0075 0308;;;;N;LATIN SMALL LETTER U DIAERESIS;;00DC;;00DC
+00FD;LATIN SMALL LETTER Y WITH ACUTE;Ll;0;L;0079 0301;;;;N;LATIN SMALL LETTER Y ACUTE;;00DD;;00DD
+00FE;LATIN SMALL LETTER THORN;Ll;0;L;;;;;N;;;00DE;;00DE
+00FF;LATIN SMALL LETTER Y WITH DIAERESIS;Ll;0;L;0079 0308;;;;N;LATIN SMALL LETTER Y DIAERESIS;;0178;;0178
+0100;LATIN CAPITAL LETTER A WITH MACRON;Lu;0;L;0041 0304;;;;N;LATIN CAPITAL LETTER A MACRON;;;0101;
+0101;LATIN SMALL LETTER A WITH MACRON;Ll;0;L;0061 0304;;;;N;LATIN SMALL LETTER A MACRON;;0100;;0100
+0102;LATIN CAPITAL LETTER A WITH BREVE;Lu;0;L;0041 0306;;;;N;LATIN CAPITAL LETTER A BREVE;;;0103;
+0103;LATIN SMALL LETTER A WITH BREVE;Ll;0;L;0061 0306;;;;N;LATIN SMALL LETTER A BREVE;;0102;;0102
+0104;LATIN CAPITAL LETTER A WITH OGONEK;Lu;0;L;0041 0328;;;;N;LATIN CAPITAL LETTER A OGONEK;;;0105;
+0105;LATIN SMALL LETTER A WITH OGONEK;Ll;0;L;0061 0328;;;;N;LATIN SMALL LETTER A OGONEK;;0104;;0104
+0106;LATIN CAPITAL LETTER C WITH ACUTE;Lu;0;L;0043 0301;;;;N;LATIN CAPITAL LETTER C ACUTE;;;0107;
+0107;LATIN SMALL LETTER C WITH ACUTE;Ll;0;L;0063 0301;;;;N;LATIN SMALL LETTER C ACUTE;;0106;;0106
+0108;LATIN CAPITAL LETTER C WITH CIRCUMFLEX;Lu;0;L;0043 0302;;;;N;LATIN CAPITAL LETTER C CIRCUMFLEX;;;0109;
+0109;LATIN SMALL LETTER C WITH CIRCUMFLEX;Ll;0;L;0063 0302;;;;N;LATIN SMALL LETTER C CIRCUMFLEX;;0108;;0108
+010A;LATIN CAPITAL LETTER C WITH DOT ABOVE;Lu;0;L;0043 0307;;;;N;LATIN CAPITAL LETTER C DOT;;;010B;
+010B;LATIN SMALL LETTER C WITH DOT ABOVE;Ll;0;L;0063 0307;;;;N;LATIN SMALL LETTER C DOT;;010A;;010A
+010C;LATIN CAPITAL LETTER C WITH CARON;Lu;0;L;0043 030C;;;;N;LATIN CAPITAL LETTER C HACEK;;;010D;
+010D;LATIN SMALL LETTER C WITH CARON;Ll;0;L;0063 030C;;;;N;LATIN SMALL LETTER C HACEK;;010C;;010C
+010E;LATIN CAPITAL LETTER D WITH CARON;Lu;0;L;0044 030C;;;;N;LATIN CAPITAL LETTER D HACEK;;;010F;
+010F;LATIN SMALL LETTER D WITH CARON;Ll;0;L;0064 030C;;;;N;LATIN SMALL LETTER D HACEK;;010E;;010E
+0110;LATIN CAPITAL LETTER D WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER D BAR;;;0111;
+0111;LATIN SMALL LETTER D WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER D BAR;;0110;;0110
+0112;LATIN CAPITAL LETTER E WITH MACRON;Lu;0;L;0045 0304;;;;N;LATIN CAPITAL LETTER E MACRON;;;0113;
+0113;LATIN SMALL LETTER E WITH MACRON;Ll;0;L;0065 0304;;;;N;LATIN SMALL LETTER E MACRON;;0112;;0112
+0114;LATIN CAPITAL LETTER E WITH BREVE;Lu;0;L;0045 0306;;;;N;LATIN CAPITAL LETTER E BREVE;;;0115;
+0115;LATIN SMALL LETTER E WITH BREVE;Ll;0;L;0065 0306;;;;N;LATIN SMALL LETTER E BREVE;;0114;;0114
+0116;LATIN CAPITAL LETTER E WITH DOT ABOVE;Lu;0;L;0045 0307;;;;N;LATIN CAPITAL LETTER E DOT;;;0117;
+0117;LATIN SMALL LETTER E WITH DOT ABOVE;Ll;0;L;0065 0307;;;;N;LATIN SMALL LETTER E DOT;;0116;;0116
+0118;LATIN CAPITAL LETTER E WITH OGONEK;Lu;0;L;0045 0328;;;;N;LATIN CAPITAL LETTER E OGONEK;;;0119;
+0119;LATIN SMALL LETTER E WITH OGONEK;Ll;0;L;0065 0328;;;;N;LATIN SMALL LETTER E OGONEK;;0118;;0118
+011A;LATIN CAPITAL LETTER E WITH CARON;Lu;0;L;0045 030C;;;;N;LATIN CAPITAL LETTER E HACEK;;;011B;
+011B;LATIN SMALL LETTER E WITH CARON;Ll;0;L;0065 030C;;;;N;LATIN SMALL LETTER E HACEK;;011A;;011A
+011C;LATIN CAPITAL LETTER G WITH CIRCUMFLEX;Lu;0;L;0047 0302;;;;N;LATIN CAPITAL LETTER G CIRCUMFLEX;;;011D;
+011D;LATIN SMALL LETTER G WITH CIRCUMFLEX;Ll;0;L;0067 0302;;;;N;LATIN SMALL LETTER G CIRCUMFLEX;;011C;;011C
+011E;LATIN CAPITAL LETTER G WITH BREVE;Lu;0;L;0047 0306;;;;N;LATIN CAPITAL LETTER G BREVE;;;011F;
+011F;LATIN SMALL LETTER G WITH BREVE;Ll;0;L;0067 0306;;;;N;LATIN SMALL LETTER G BREVE;;011E;;011E
+0120;LATIN CAPITAL LETTER G WITH DOT ABOVE;Lu;0;L;0047 0307;;;;N;LATIN CAPITAL LETTER G DOT;;;0121;
+0121;LATIN SMALL LETTER G WITH DOT ABOVE;Ll;0;L;0067 0307;;;;N;LATIN SMALL LETTER G DOT;;0120;;0120
+0122;LATIN CAPITAL LETTER G WITH CEDILLA;Lu;0;L;0047 0327;;;;N;LATIN CAPITAL LETTER G CEDILLA;;;0123;
+0123;LATIN SMALL LETTER G WITH CEDILLA;Ll;0;L;0067 0327;;;;N;LATIN SMALL LETTER G CEDILLA;;0122;;0122
+0124;LATIN CAPITAL LETTER H WITH CIRCUMFLEX;Lu;0;L;0048 0302;;;;N;LATIN CAPITAL LETTER H CIRCUMFLEX;;;0125;
+0125;LATIN SMALL LETTER H WITH CIRCUMFLEX;Ll;0;L;0068 0302;;;;N;LATIN SMALL LETTER H CIRCUMFLEX;;0124;;0124
+0126;LATIN CAPITAL LETTER H WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER H BAR;;;0127;
+0127;LATIN SMALL LETTER H WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER H BAR;;0126;;0126
+0128;LATIN CAPITAL LETTER I WITH TILDE;Lu;0;L;0049 0303;;;;N;LATIN CAPITAL LETTER I TILDE;;;0129;
+0129;LATIN SMALL LETTER I WITH TILDE;Ll;0;L;0069 0303;;;;N;LATIN SMALL LETTER I TILDE;;0128;;0128
+012A;LATIN CAPITAL LETTER I WITH MACRON;Lu;0;L;0049 0304;;;;N;LATIN CAPITAL LETTER I MACRON;;;012B;
+012B;LATIN SMALL LETTER I WITH MACRON;Ll;0;L;0069 0304;;;;N;LATIN SMALL LETTER I MACRON;;012A;;012A
+012C;LATIN CAPITAL LETTER I WITH BREVE;Lu;0;L;0049 0306;;;;N;LATIN CAPITAL LETTER I BREVE;;;012D;
+012D;LATIN SMALL LETTER I WITH BREVE;Ll;0;L;0069 0306;;;;N;LATIN SMALL LETTER I BREVE;;012C;;012C
+012E;LATIN CAPITAL LETTER I WITH OGONEK;Lu;0;L;0049 0328;;;;N;LATIN CAPITAL LETTER I OGONEK;;;012F;
+012F;LATIN SMALL LETTER I WITH OGONEK;Ll;0;L;0069 0328;;;;N;LATIN SMALL LETTER I OGONEK;;012E;;012E
+0130;LATIN CAPITAL LETTER I WITH DOT ABOVE;Lu;0;L;0049 0307;;;;N;LATIN CAPITAL LETTER I DOT;;;0069;
+0131;LATIN SMALL LETTER DOTLESS I;Ll;0;L;;;;;N;;;0049;;0049
+0132;LATIN CAPITAL LIGATURE IJ;Lu;0;L;<compat> 0049 004A;;;;N;LATIN CAPITAL LETTER I J;;;0133;
+0133;LATIN SMALL LIGATURE IJ;Ll;0;L;<compat> 0069 006A;;;;N;LATIN SMALL LETTER I J;;0132;;0132
+0134;LATIN CAPITAL LETTER J WITH CIRCUMFLEX;Lu;0;L;004A 0302;;;;N;LATIN CAPITAL LETTER J CIRCUMFLEX;;;0135;
+0135;LATIN SMALL LETTER J WITH CIRCUMFLEX;Ll;0;L;006A 0302;;;;N;LATIN SMALL LETTER J CIRCUMFLEX;;0134;;0134
+0136;LATIN CAPITAL LETTER K WITH CEDILLA;Lu;0;L;004B 0327;;;;N;LATIN CAPITAL LETTER K CEDILLA;;;0137;
+0137;LATIN SMALL LETTER K WITH CEDILLA;Ll;0;L;006B 0327;;;;N;LATIN SMALL LETTER K CEDILLA;;0136;;0136
+0138;LATIN SMALL LETTER KRA;Ll;0;L;;;;;N;;;;;
+0139;LATIN CAPITAL LETTER L WITH ACUTE;Lu;0;L;004C 0301;;;;N;LATIN CAPITAL LETTER L ACUTE;;;013A;
+013A;LATIN SMALL LETTER L WITH ACUTE;Ll;0;L;006C 0301;;;;N;LATIN SMALL LETTER L ACUTE;;0139;;0139
+013B;LATIN CAPITAL LETTER L WITH CEDILLA;Lu;0;L;004C 0327;;;;N;LATIN CAPITAL LETTER L CEDILLA;;;013C;
+013C;LATIN SMALL LETTER L WITH CEDILLA;Ll;0;L;006C 0327;;;;N;LATIN SMALL LETTER L CEDILLA;;013B;;013B
+013D;LATIN CAPITAL LETTER L WITH CARON;Lu;0;L;004C 030C;;;;N;LATIN CAPITAL LETTER L HACEK;;;013E;
+013E;LATIN SMALL LETTER L WITH CARON;Ll;0;L;006C 030C;;;;N;LATIN SMALL LETTER L HACEK;;013D;;013D
+013F;LATIN CAPITAL LETTER L WITH MIDDLE DOT;Lu;0;L;<compat> 004C 00B7;;;;N;;;;0140;
+0140;LATIN SMALL LETTER L WITH MIDDLE DOT;Ll;0;L;<compat> 006C 00B7;;;;N;;;013F;;013F
+0141;LATIN CAPITAL LETTER L WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER L SLASH;;;0142;
+0142;LATIN SMALL LETTER L WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER L SLASH;;0141;;0141
+0143;LATIN CAPITAL LETTER N WITH ACUTE;Lu;0;L;004E 0301;;;;N;LATIN CAPITAL LETTER N ACUTE;;;0144;
+0144;LATIN SMALL LETTER N WITH ACUTE;Ll;0;L;006E 0301;;;;N;LATIN SMALL LETTER N ACUTE;;0143;;0143
+0145;LATIN CAPITAL LETTER N WITH CEDILLA;Lu;0;L;004E 0327;;;;N;LATIN CAPITAL LETTER N CEDILLA;;;0146;
+0146;LATIN SMALL LETTER N WITH CEDILLA;Ll;0;L;006E 0327;;;;N;LATIN SMALL LETTER N CEDILLA;;0145;;0145
+0147;LATIN CAPITAL LETTER N WITH CARON;Lu;0;L;004E 030C;;;;N;LATIN CAPITAL LETTER N HACEK;;;0148;
+0148;LATIN SMALL LETTER N WITH CARON;Ll;0;L;006E 030C;;;;N;LATIN SMALL LETTER N HACEK;;0147;;0147
+0149;LATIN SMALL LETTER N PRECEDED BY APOSTROPHE;Ll;0;L;<compat> 02BC 006E;;;;N;LATIN SMALL LETTER APOSTROPHE N;;;;
+014A;LATIN CAPITAL LETTER ENG;Lu;0;L;;;;;N;;;;014B;
+014B;LATIN SMALL LETTER ENG;Ll;0;L;;;;;N;;;014A;;014A
+014C;LATIN CAPITAL LETTER O WITH MACRON;Lu;0;L;004F 0304;;;;N;LATIN CAPITAL LETTER O MACRON;;;014D;
+014D;LATIN SMALL LETTER O WITH MACRON;Ll;0;L;006F 0304;;;;N;LATIN SMALL LETTER O MACRON;;014C;;014C
+014E;LATIN CAPITAL LETTER O WITH BREVE;Lu;0;L;004F 0306;;;;N;LATIN CAPITAL LETTER O BREVE;;;014F;
+014F;LATIN SMALL LETTER O WITH BREVE;Ll;0;L;006F 0306;;;;N;LATIN SMALL LETTER O BREVE;;014E;;014E
+0150;LATIN CAPITAL LETTER O WITH DOUBLE ACUTE;Lu;0;L;004F 030B;;;;N;LATIN CAPITAL LETTER O DOUBLE ACUTE;;;0151;
+0151;LATIN SMALL LETTER O WITH DOUBLE ACUTE;Ll;0;L;006F 030B;;;;N;LATIN SMALL LETTER O DOUBLE ACUTE;;0150;;0150
+0152;LATIN CAPITAL LIGATURE OE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER O E;;;0153;
+0153;LATIN SMALL LIGATURE OE;Ll;0;L;;;;;N;LATIN SMALL LETTER O E;;0152;;0152
+0154;LATIN CAPITAL LETTER R WITH ACUTE;Lu;0;L;0052 0301;;;;N;LATIN CAPITAL LETTER R ACUTE;;;0155;
+0155;LATIN SMALL LETTER R WITH ACUTE;Ll;0;L;0072 0301;;;;N;LATIN SMALL LETTER R ACUTE;;0154;;0154
+0156;LATIN CAPITAL LETTER R WITH CEDILLA;Lu;0;L;0052 0327;;;;N;LATIN CAPITAL LETTER R CEDILLA;;;0157;
+0157;LATIN SMALL LETTER R WITH CEDILLA;Ll;0;L;0072 0327;;;;N;LATIN SMALL LETTER R CEDILLA;;0156;;0156
+0158;LATIN CAPITAL LETTER R WITH CARON;Lu;0;L;0052 030C;;;;N;LATIN CAPITAL LETTER R HACEK;;;0159;
+0159;LATIN SMALL LETTER R WITH CARON;Ll;0;L;0072 030C;;;;N;LATIN SMALL LETTER R HACEK;;0158;;0158
+015A;LATIN CAPITAL LETTER S WITH ACUTE;Lu;0;L;0053 0301;;;;N;LATIN CAPITAL LETTER S ACUTE;;;015B;
+015B;LATIN SMALL LETTER S WITH ACUTE;Ll;0;L;0073 0301;;;;N;LATIN SMALL LETTER S ACUTE;;015A;;015A
+015C;LATIN CAPITAL LETTER S WITH CIRCUMFLEX;Lu;0;L;0053 0302;;;;N;LATIN CAPITAL LETTER S CIRCUMFLEX;;;015D;
+015D;LATIN SMALL LETTER S WITH CIRCUMFLEX;Ll;0;L;0073 0302;;;;N;LATIN SMALL LETTER S CIRCUMFLEX;;015C;;015C
+015E;LATIN CAPITAL LETTER S WITH CEDILLA;Lu;0;L;0053 0327;;;;N;LATIN CAPITAL LETTER S CEDILLA;;;015F;
+015F;LATIN SMALL LETTER S WITH CEDILLA;Ll;0;L;0073 0327;;;;N;LATIN SMALL LETTER S CEDILLA;;015E;;015E
+0160;LATIN CAPITAL LETTER S WITH CARON;Lu;0;L;0053 030C;;;;N;LATIN CAPITAL LETTER S HACEK;;;0161;
+0161;LATIN SMALL LETTER S WITH CARON;Ll;0;L;0073 030C;;;;N;LATIN SMALL LETTER S HACEK;;0160;;0160
+0162;LATIN CAPITAL LETTER T WITH CEDILLA;Lu;0;L;0054 0327;;;;N;LATIN CAPITAL LETTER T CEDILLA;;;0163;
+0163;LATIN SMALL LETTER T WITH CEDILLA;Ll;0;L;0074 0327;;;;N;LATIN SMALL LETTER T CEDILLA;;0162;;0162
+0164;LATIN CAPITAL LETTER T WITH CARON;Lu;0;L;0054 030C;;;;N;LATIN CAPITAL LETTER T HACEK;;;0165;
+0165;LATIN SMALL LETTER T WITH CARON;Ll;0;L;0074 030C;;;;N;LATIN SMALL LETTER T HACEK;;0164;;0164
+0166;LATIN CAPITAL LETTER T WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER T BAR;;;0167;
+0167;LATIN SMALL LETTER T WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER T BAR;;0166;;0166
+0168;LATIN CAPITAL LETTER U WITH TILDE;Lu;0;L;0055 0303;;;;N;LATIN CAPITAL LETTER U TILDE;;;0169;
+0169;LATIN SMALL LETTER U WITH TILDE;Ll;0;L;0075 0303;;;;N;LATIN SMALL LETTER U TILDE;;0168;;0168
+016A;LATIN CAPITAL LETTER U WITH MACRON;Lu;0;L;0055 0304;;;;N;LATIN CAPITAL LETTER U MACRON;;;016B;
+016B;LATIN SMALL LETTER U WITH MACRON;Ll;0;L;0075 0304;;;;N;LATIN SMALL LETTER U MACRON;;016A;;016A
+016C;LATIN CAPITAL LETTER U WITH BREVE;Lu;0;L;0055 0306;;;;N;LATIN CAPITAL LETTER U BREVE;;;016D;
+016D;LATIN SMALL LETTER U WITH BREVE;Ll;0;L;0075 0306;;;;N;LATIN SMALL LETTER U BREVE;;016C;;016C
+016E;LATIN CAPITAL LETTER U WITH RING ABOVE;Lu;0;L;0055 030A;;;;N;LATIN CAPITAL LETTER U RING;;;016F;
+016F;LATIN SMALL LETTER U WITH RING ABOVE;Ll;0;L;0075 030A;;;;N;LATIN SMALL LETTER U RING;;016E;;016E
+0170;LATIN CAPITAL LETTER U WITH DOUBLE ACUTE;Lu;0;L;0055 030B;;;;N;LATIN CAPITAL LETTER U DOUBLE ACUTE;;;0171;
+0171;LATIN SMALL LETTER U WITH DOUBLE ACUTE;Ll;0;L;0075 030B;;;;N;LATIN SMALL LETTER U DOUBLE ACUTE;;0170;;0170
+0172;LATIN CAPITAL LETTER U WITH OGONEK;Lu;0;L;0055 0328;;;;N;LATIN CAPITAL LETTER U OGONEK;;;0173;
+0173;LATIN SMALL LETTER U WITH OGONEK;Ll;0;L;0075 0328;;;;N;LATIN SMALL LETTER U OGONEK;;0172;;0172
+0174;LATIN CAPITAL LETTER W WITH CIRCUMFLEX;Lu;0;L;0057 0302;;;;N;LATIN CAPITAL LETTER W CIRCUMFLEX;;;0175;
+0175;LATIN SMALL LETTER W WITH CIRCUMFLEX;Ll;0;L;0077 0302;;;;N;LATIN SMALL LETTER W CIRCUMFLEX;;0174;;0174
+0176;LATIN CAPITAL LETTER Y WITH CIRCUMFLEX;Lu;0;L;0059 0302;;;;N;LATIN CAPITAL LETTER Y CIRCUMFLEX;;;0177;
+0177;LATIN SMALL LETTER Y WITH CIRCUMFLEX;Ll;0;L;0079 0302;;;;N;LATIN SMALL LETTER Y CIRCUMFLEX;;0176;;0176
+0178;LATIN CAPITAL LETTER Y WITH DIAERESIS;Lu;0;L;0059 0308;;;;N;LATIN CAPITAL LETTER Y DIAERESIS;;;00FF;
+0179;LATIN CAPITAL LETTER Z WITH ACUTE;Lu;0;L;005A 0301;;;;N;LATIN CAPITAL LETTER Z ACUTE;;;017A;
+017A;LATIN SMALL LETTER Z WITH ACUTE;Ll;0;L;007A 0301;;;;N;LATIN SMALL LETTER Z ACUTE;;0179;;0179
+017B;LATIN CAPITAL LETTER Z WITH DOT ABOVE;Lu;0;L;005A 0307;;;;N;LATIN CAPITAL LETTER Z DOT;;;017C;
+017C;LATIN SMALL LETTER Z WITH DOT ABOVE;Ll;0;L;007A 0307;;;;N;LATIN SMALL LETTER Z DOT;;017B;;017B
+017D;LATIN CAPITAL LETTER Z WITH CARON;Lu;0;L;005A 030C;;;;N;LATIN CAPITAL LETTER Z HACEK;;;017E;
+017E;LATIN SMALL LETTER Z WITH CARON;Ll;0;L;007A 030C;;;;N;LATIN SMALL LETTER Z HACEK;;017D;;017D
+017F;LATIN SMALL LETTER LONG S;Ll;0;L;<compat> 0073;;;;N;;;0053;;0053
+0180;LATIN SMALL LETTER B WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER B BAR;;0243;;0243
+0181;LATIN CAPITAL LETTER B WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER B HOOK;;;0253;
+0182;LATIN CAPITAL LETTER B WITH TOPBAR;Lu;0;L;;;;;N;LATIN CAPITAL LETTER B TOPBAR;;;0183;
+0183;LATIN SMALL LETTER B WITH TOPBAR;Ll;0;L;;;;;N;LATIN SMALL LETTER B TOPBAR;;0182;;0182
+0184;LATIN CAPITAL LETTER TONE SIX;Lu;0;L;;;;;N;;;;0185;
+0185;LATIN SMALL LETTER TONE SIX;Ll;0;L;;;;;N;;;0184;;0184
+0186;LATIN CAPITAL LETTER OPEN O;Lu;0;L;;;;;N;;;;0254;
+0187;LATIN CAPITAL LETTER C WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER C HOOK;;;0188;
+0188;LATIN SMALL LETTER C WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER C HOOK;;0187;;0187
+0189;LATIN CAPITAL LETTER AFRICAN D;Lu;0;L;;;;;N;;;;0256;
+018A;LATIN CAPITAL LETTER D WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER D HOOK;;;0257;
+018B;LATIN CAPITAL LETTER D WITH TOPBAR;Lu;0;L;;;;;N;LATIN CAPITAL LETTER D TOPBAR;;;018C;
+018C;LATIN SMALL LETTER D WITH TOPBAR;Ll;0;L;;;;;N;LATIN SMALL LETTER D TOPBAR;;018B;;018B
+018D;LATIN SMALL LETTER TURNED DELTA;Ll;0;L;;;;;N;;;;;
+018E;LATIN CAPITAL LETTER REVERSED E;Lu;0;L;;;;;N;LATIN CAPITAL LETTER TURNED E;;;01DD;
+018F;LATIN CAPITAL LETTER SCHWA;Lu;0;L;;;;;N;;;;0259;
+0190;LATIN CAPITAL LETTER OPEN E;Lu;0;L;;;;;N;LATIN CAPITAL LETTER EPSILON;;;025B;
+0191;LATIN CAPITAL LETTER F WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER F HOOK;;;0192;
+0192;LATIN SMALL LETTER F WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER SCRIPT F;;0191;;0191
+0193;LATIN CAPITAL LETTER G WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER G HOOK;;;0260;
+0194;LATIN CAPITAL LETTER GAMMA;Lu;0;L;;;;;N;;;;0263;
+0195;LATIN SMALL LETTER HV;Ll;0;L;;;;;N;LATIN SMALL LETTER H V;;01F6;;01F6
+0196;LATIN CAPITAL LETTER IOTA;Lu;0;L;;;;;N;;;;0269;
+0197;LATIN CAPITAL LETTER I WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER BARRED I;;;0268;
+0198;LATIN CAPITAL LETTER K WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER K HOOK;;;0199;
+0199;LATIN SMALL LETTER K WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER K HOOK;;0198;;0198
+019A;LATIN SMALL LETTER L WITH BAR;Ll;0;L;;;;;N;LATIN SMALL LETTER BARRED L;;023D;;023D
+019B;LATIN SMALL LETTER LAMBDA WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER BARRED LAMBDA;;;;
+019C;LATIN CAPITAL LETTER TURNED M;Lu;0;L;;;;;N;;;;026F;
+019D;LATIN CAPITAL LETTER N WITH LEFT HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER N HOOK;;;0272;
+019E;LATIN SMALL LETTER N WITH LONG RIGHT LEG;Ll;0;L;;;;;N;;;0220;;0220
+019F;LATIN CAPITAL LETTER O WITH MIDDLE TILDE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER BARRED O;;;0275;
+01A0;LATIN CAPITAL LETTER O WITH HORN;Lu;0;L;004F 031B;;;;N;LATIN CAPITAL LETTER O HORN;;;01A1;
+01A1;LATIN SMALL LETTER O WITH HORN;Ll;0;L;006F 031B;;;;N;LATIN SMALL LETTER O HORN;;01A0;;01A0
+01A2;LATIN CAPITAL LETTER OI;Lu;0;L;;;;;N;LATIN CAPITAL LETTER O I;;;01A3;
+01A3;LATIN SMALL LETTER OI;Ll;0;L;;;;;N;LATIN SMALL LETTER O I;;01A2;;01A2
+01A4;LATIN CAPITAL LETTER P WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER P HOOK;;;01A5;
+01A5;LATIN SMALL LETTER P WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER P HOOK;;01A4;;01A4
+01A6;LATIN LETTER YR;Lu;0;L;;;;;N;LATIN LETTER Y R;;;0280;
+01A7;LATIN CAPITAL LETTER TONE TWO;Lu;0;L;;;;;N;;;;01A8;
+01A8;LATIN SMALL LETTER TONE TWO;Ll;0;L;;;;;N;;;01A7;;01A7
+01A9;LATIN CAPITAL LETTER ESH;Lu;0;L;;;;;N;;;;0283;
+01AA;LATIN LETTER REVERSED ESH LOOP;Ll;0;L;;;;;N;;;;;
+01AB;LATIN SMALL LETTER T WITH PALATAL HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER T PALATAL HOOK;;;;
+01AC;LATIN CAPITAL LETTER T WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER T HOOK;;;01AD;
+01AD;LATIN SMALL LETTER T WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER T HOOK;;01AC;;01AC
+01AE;LATIN CAPITAL LETTER T WITH RETROFLEX HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER T RETROFLEX HOOK;;;0288;
+01AF;LATIN CAPITAL LETTER U WITH HORN;Lu;0;L;0055 031B;;;;N;LATIN CAPITAL LETTER U HORN;;;01B0;
+01B0;LATIN SMALL LETTER U WITH HORN;Ll;0;L;0075 031B;;;;N;LATIN SMALL LETTER U HORN;;01AF;;01AF
+01B1;LATIN CAPITAL LETTER UPSILON;Lu;0;L;;;;;N;;;;028A;
+01B2;LATIN CAPITAL LETTER V WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER SCRIPT V;;;028B;
+01B3;LATIN CAPITAL LETTER Y WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER Y HOOK;;;01B4;
+01B4;LATIN SMALL LETTER Y WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER Y HOOK;;01B3;;01B3
+01B5;LATIN CAPITAL LETTER Z WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER Z BAR;;;01B6;
+01B6;LATIN SMALL LETTER Z WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER Z BAR;;01B5;;01B5
+01B7;LATIN CAPITAL LETTER EZH;Lu;0;L;;;;;N;LATIN CAPITAL LETTER YOGH;;;0292;
+01B8;LATIN CAPITAL LETTER EZH REVERSED;Lu;0;L;;;;;N;LATIN CAPITAL LETTER REVERSED YOGH;;;01B9;
+01B9;LATIN SMALL LETTER EZH REVERSED;Ll;0;L;;;;;N;LATIN SMALL LETTER REVERSED YOGH;;01B8;;01B8
+01BA;LATIN SMALL LETTER EZH WITH TAIL;Ll;0;L;;;;;N;LATIN SMALL LETTER YOGH WITH TAIL;;;;
+01BB;LATIN LETTER TWO WITH STROKE;Lo;0;L;;;;;N;LATIN LETTER TWO BAR;;;;
+01BC;LATIN CAPITAL LETTER TONE FIVE;Lu;0;L;;;;;N;;;;01BD;
+01BD;LATIN SMALL LETTER TONE FIVE;Ll;0;L;;;;;N;;;01BC;;01BC
+01BE;LATIN LETTER INVERTED GLOTTAL STOP WITH STROKE;Ll;0;L;;;;;N;LATIN LETTER INVERTED GLOTTAL STOP BAR;;;;
+01BF;LATIN LETTER WYNN;Ll;0;L;;;;;N;;;01F7;;01F7
+01C0;LATIN LETTER DENTAL CLICK;Lo;0;L;;;;;N;LATIN LETTER PIPE;;;;
+01C1;LATIN LETTER LATERAL CLICK;Lo;0;L;;;;;N;LATIN LETTER DOUBLE PIPE;;;;
+01C2;LATIN LETTER ALVEOLAR CLICK;Lo;0;L;;;;;N;LATIN LETTER PIPE DOUBLE BAR;;;;
+01C3;LATIN LETTER RETROFLEX CLICK;Lo;0;L;;;;;N;LATIN LETTER EXCLAMATION MARK;;;;
+01C4;LATIN CAPITAL LETTER DZ WITH CARON;Lu;0;L;<compat> 0044 017D;;;;N;LATIN CAPITAL LETTER D Z HACEK;;;01C6;01C5
+01C5;LATIN CAPITAL LETTER D WITH SMALL LETTER Z WITH CARON;Lt;0;L;<compat> 0044 017E;;;;N;LATIN LETTER CAPITAL D SMALL Z HACEK;;01C4;01C6;01C5
+01C6;LATIN SMALL LETTER DZ WITH CARON;Ll;0;L;<compat> 0064 017E;;;;N;LATIN SMALL LETTER D Z HACEK;;01C4;;01C5
+01C7;LATIN CAPITAL LETTER LJ;Lu;0;L;<compat> 004C 004A;;;;N;LATIN CAPITAL LETTER L J;;;01C9;01C8
+01C8;LATIN CAPITAL LETTER L WITH SMALL LETTER J;Lt;0;L;<compat> 004C 006A;;;;N;LATIN LETTER CAPITAL L SMALL J;;01C7;01C9;01C8
+01C9;LATIN SMALL LETTER LJ;Ll;0;L;<compat> 006C 006A;;;;N;LATIN SMALL LETTER L J;;01C7;;01C8
+01CA;LATIN CAPITAL LETTER NJ;Lu;0;L;<compat> 004E 004A;;;;N;LATIN CAPITAL LETTER N J;;;01CC;01CB
+01CB;LATIN CAPITAL LETTER N WITH SMALL LETTER J;Lt;0;L;<compat> 004E 006A;;;;N;LATIN LETTER CAPITAL N SMALL J;;01CA;01CC;01CB
+01CC;LATIN SMALL LETTER NJ;Ll;0;L;<compat> 006E 006A;;;;N;LATIN SMALL LETTER N J;;01CA;;01CB
+01CD;LATIN CAPITAL LETTER A WITH CARON;Lu;0;L;0041 030C;;;;N;LATIN CAPITAL LETTER A HACEK;;;01CE;
+01CE;LATIN SMALL LETTER A WITH CARON;Ll;0;L;0061 030C;;;;N;LATIN SMALL LETTER A HACEK;;01CD;;01CD
+01CF;LATIN CAPITAL LETTER I WITH CARON;Lu;0;L;0049 030C;;;;N;LATIN CAPITAL LETTER I HACEK;;;01D0;
+01D0;LATIN SMALL LETTER I WITH CARON;Ll;0;L;0069 030C;;;;N;LATIN SMALL LETTER I HACEK;;01CF;;01CF
+01D1;LATIN CAPITAL LETTER O WITH CARON;Lu;0;L;004F 030C;;;;N;LATIN CAPITAL LETTER O HACEK;;;01D2;
+01D2;LATIN SMALL LETTER O WITH CARON;Ll;0;L;006F 030C;;;;N;LATIN SMALL LETTER O HACEK;;01D1;;01D1
+01D3;LATIN CAPITAL LETTER U WITH CARON;Lu;0;L;0055 030C;;;;N;LATIN CAPITAL LETTER U HACEK;;;01D4;
+01D4;LATIN SMALL LETTER U WITH CARON;Ll;0;L;0075 030C;;;;N;LATIN SMALL LETTER U HACEK;;01D3;;01D3
+01D5;LATIN CAPITAL LETTER U WITH DIAERESIS AND MACRON;Lu;0;L;00DC 0304;;;;N;LATIN CAPITAL LETTER U DIAERESIS MACRON;;;01D6;
+01D6;LATIN SMALL LETTER U WITH DIAERESIS AND MACRON;Ll;0;L;00FC 0304;;;;N;LATIN SMALL LETTER U DIAERESIS MACRON;;01D5;;01D5
+01D7;LATIN CAPITAL LETTER U WITH DIAERESIS AND ACUTE;Lu;0;L;00DC 0301;;;;N;LATIN CAPITAL LETTER U DIAERESIS ACUTE;;;01D8;
+01D8;LATIN SMALL LETTER U WITH DIAERESIS AND ACUTE;Ll;0;L;00FC 0301;;;;N;LATIN SMALL LETTER U DIAERESIS ACUTE;;01D7;;01D7
+01D9;LATIN CAPITAL LETTER U WITH DIAERESIS AND CARON;Lu;0;L;00DC 030C;;;;N;LATIN CAPITAL LETTER U DIAERESIS HACEK;;;01DA;
+01DA;LATIN SMALL LETTER U WITH DIAERESIS AND CARON;Ll;0;L;00FC 030C;;;;N;LATIN SMALL LETTER U DIAERESIS HACEK;;01D9;;01D9
+01DB;LATIN CAPITAL LETTER U WITH DIAERESIS AND GRAVE;Lu;0;L;00DC 0300;;;;N;LATIN CAPITAL LETTER U DIAERESIS GRAVE;;;01DC;
+01DC;LATIN SMALL LETTER U WITH DIAERESIS AND GRAVE;Ll;0;L;00FC 0300;;;;N;LATIN SMALL LETTER U DIAERESIS GRAVE;;01DB;;01DB
+01DD;LATIN SMALL LETTER TURNED E;Ll;0;L;;;;;N;;;018E;;018E
+01DE;LATIN CAPITAL LETTER A WITH DIAERESIS AND MACRON;Lu;0;L;00C4 0304;;;;N;LATIN CAPITAL LETTER A DIAERESIS MACRON;;;01DF;
+01DF;LATIN SMALL LETTER A WITH DIAERESIS AND MACRON;Ll;0;L;00E4 0304;;;;N;LATIN SMALL LETTER A DIAERESIS MACRON;;01DE;;01DE
+01E0;LATIN CAPITAL LETTER A WITH DOT ABOVE AND MACRON;Lu;0;L;0226 0304;;;;N;LATIN CAPITAL LETTER A DOT MACRON;;;01E1;
+01E1;LATIN SMALL LETTER A WITH DOT ABOVE AND MACRON;Ll;0;L;0227 0304;;;;N;LATIN SMALL LETTER A DOT MACRON;;01E0;;01E0
+01E2;LATIN CAPITAL LETTER AE WITH MACRON;Lu;0;L;00C6 0304;;;;N;LATIN CAPITAL LETTER A E MACRON;;;01E3;
+01E3;LATIN SMALL LETTER AE WITH MACRON;Ll;0;L;00E6 0304;;;;N;LATIN SMALL LETTER A E MACRON;;01E2;;01E2
+01E4;LATIN CAPITAL LETTER G WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER G BAR;;;01E5;
+01E5;LATIN SMALL LETTER G WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER G BAR;;01E4;;01E4
+01E6;LATIN CAPITAL LETTER G WITH CARON;Lu;0;L;0047 030C;;;;N;LATIN CAPITAL LETTER G HACEK;;;01E7;
+01E7;LATIN SMALL LETTER G WITH CARON;Ll;0;L;0067 030C;;;;N;LATIN SMALL LETTER G HACEK;;01E6;;01E6
+01E8;LATIN CAPITAL LETTER K WITH CARON;Lu;0;L;004B 030C;;;;N;LATIN CAPITAL LETTER K HACEK;;;01E9;
+01E9;LATIN SMALL LETTER K WITH CARON;Ll;0;L;006B 030C;;;;N;LATIN SMALL LETTER K HACEK;;01E8;;01E8
+01EA;LATIN CAPITAL LETTER O WITH OGONEK;Lu;0;L;004F 0328;;;;N;LATIN CAPITAL LETTER O OGONEK;;;01EB;
+01EB;LATIN SMALL LETTER O WITH OGONEK;Ll;0;L;006F 0328;;;;N;LATIN SMALL LETTER O OGONEK;;01EA;;01EA
+01EC;LATIN CAPITAL LETTER O WITH OGONEK AND MACRON;Lu;0;L;01EA 0304;;;;N;LATIN CAPITAL LETTER O OGONEK MACRON;;;01ED;
+01ED;LATIN SMALL LETTER O WITH OGONEK AND MACRON;Ll;0;L;01EB 0304;;;;N;LATIN SMALL LETTER O OGONEK MACRON;;01EC;;01EC
+01EE;LATIN CAPITAL LETTER EZH WITH CARON;Lu;0;L;01B7 030C;;;;N;LATIN CAPITAL LETTER YOGH HACEK;;;01EF;
+01EF;LATIN SMALL LETTER EZH WITH CARON;Ll;0;L;0292 030C;;;;N;LATIN SMALL LETTER YOGH HACEK;;01EE;;01EE
+01F0;LATIN SMALL LETTER J WITH CARON;Ll;0;L;006A 030C;;;;N;LATIN SMALL LETTER J HACEK;;;;
+01F1;LATIN CAPITAL LETTER DZ;Lu;0;L;<compat> 0044 005A;;;;N;;;;01F3;01F2
+01F2;LATIN CAPITAL LETTER D WITH SMALL LETTER Z;Lt;0;L;<compat> 0044 007A;;;;N;;;01F1;01F3;01F2
+01F3;LATIN SMALL LETTER DZ;Ll;0;L;<compat> 0064 007A;;;;N;;;01F1;;01F2
+01F4;LATIN CAPITAL LETTER G WITH ACUTE;Lu;0;L;0047 0301;;;;N;;;;01F5;
+01F5;LATIN SMALL LETTER G WITH ACUTE;Ll;0;L;0067 0301;;;;N;;;01F4;;01F4
+01F6;LATIN CAPITAL LETTER HWAIR;Lu;0;L;;;;;N;;;;0195;
+01F7;LATIN CAPITAL LETTER WYNN;Lu;0;L;;;;;N;;;;01BF;
+01F8;LATIN CAPITAL LETTER N WITH GRAVE;Lu;0;L;004E 0300;;;;N;;;;01F9;
+01F9;LATIN SMALL LETTER N WITH GRAVE;Ll;0;L;006E 0300;;;;N;;;01F8;;01F8
+01FA;LATIN CAPITAL LETTER A WITH RING ABOVE AND ACUTE;Lu;0;L;00C5 0301;;;;N;;;;01FB;
+01FB;LATIN SMALL LETTER A WITH RING ABOVE AND ACUTE;Ll;0;L;00E5 0301;;;;N;;;01FA;;01FA
+01FC;LATIN CAPITAL LETTER AE WITH ACUTE;Lu;0;L;00C6 0301;;;;N;;;;01FD;
+01FD;LATIN SMALL LETTER AE WITH ACUTE;Ll;0;L;00E6 0301;;;;N;;;01FC;;01FC
+01FE;LATIN CAPITAL LETTER O WITH STROKE AND ACUTE;Lu;0;L;00D8 0301;;;;N;;;;01FF;
+01FF;LATIN SMALL LETTER O WITH STROKE AND ACUTE;Ll;0;L;00F8 0301;;;;N;;;01FE;;01FE
+0200;LATIN CAPITAL LETTER A WITH DOUBLE GRAVE;Lu;0;L;0041 030F;;;;N;;;;0201;
+0201;LATIN SMALL LETTER A WITH DOUBLE GRAVE;Ll;0;L;0061 030F;;;;N;;;0200;;0200
+0202;LATIN CAPITAL LETTER A WITH INVERTED BREVE;Lu;0;L;0041 0311;;;;N;;;;0203;
+0203;LATIN SMALL LETTER A WITH INVERTED BREVE;Ll;0;L;0061 0311;;;;N;;;0202;;0202
+0204;LATIN CAPITAL LETTER E WITH DOUBLE GRAVE;Lu;0;L;0045 030F;;;;N;;;;0205;
+0205;LATIN SMALL LETTER E WITH DOUBLE GRAVE;Ll;0;L;0065 030F;;;;N;;;0204;;0204
+0206;LATIN CAPITAL LETTER E WITH INVERTED BREVE;Lu;0;L;0045 0311;;;;N;;;;0207;
+0207;LATIN SMALL LETTER E WITH INVERTED BREVE;Ll;0;L;0065 0311;;;;N;;;0206;;0206
+0208;LATIN CAPITAL LETTER I WITH DOUBLE GRAVE;Lu;0;L;0049 030F;;;;N;;;;0209;
+0209;LATIN SMALL LETTER I WITH DOUBLE GRAVE;Ll;0;L;0069 030F;;;;N;;;0208;;0208
+020A;LATIN CAPITAL LETTER I WITH INVERTED BREVE;Lu;0;L;0049 0311;;;;N;;;;020B;
+020B;LATIN SMALL LETTER I WITH INVERTED BREVE;Ll;0;L;0069 0311;;;;N;;;020A;;020A
+020C;LATIN CAPITAL LETTER O WITH DOUBLE GRAVE;Lu;0;L;004F 030F;;;;N;;;;020D;
+020D;LATIN SMALL LETTER O WITH DOUBLE GRAVE;Ll;0;L;006F 030F;;;;N;;;020C;;020C
+020E;LATIN CAPITAL LETTER O WITH INVERTED BREVE;Lu;0;L;004F 0311;;;;N;;;;020F;
+020F;LATIN SMALL LETTER O WITH INVERTED BREVE;Ll;0;L;006F 0311;;;;N;;;020E;;020E
+0210;LATIN CAPITAL LETTER R WITH DOUBLE GRAVE;Lu;0;L;0052 030F;;;;N;;;;0211;
+0211;LATIN SMALL LETTER R WITH DOUBLE GRAVE;Ll;0;L;0072 030F;;;;N;;;0210;;0210
+0212;LATIN CAPITAL LETTER R WITH INVERTED BREVE;Lu;0;L;0052 0311;;;;N;;;;0213;
+0213;LATIN SMALL LETTER R WITH INVERTED BREVE;Ll;0;L;0072 0311;;;;N;;;0212;;0212
+0214;LATIN CAPITAL LETTER U WITH DOUBLE GRAVE;Lu;0;L;0055 030F;;;;N;;;;0215;
+0215;LATIN SMALL LETTER U WITH DOUBLE GRAVE;Ll;0;L;0075 030F;;;;N;;;0214;;0214
+0216;LATIN CAPITAL LETTER U WITH INVERTED BREVE;Lu;0;L;0055 0311;;;;N;;;;0217;
+0217;LATIN SMALL LETTER U WITH INVERTED BREVE;Ll;0;L;0075 0311;;;;N;;;0216;;0216
+0218;LATIN CAPITAL LETTER S WITH COMMA BELOW;Lu;0;L;0053 0326;;;;N;;;;0219;
+0219;LATIN SMALL LETTER S WITH COMMA BELOW;Ll;0;L;0073 0326;;;;N;;;0218;;0218
+021A;LATIN CAPITAL LETTER T WITH COMMA BELOW;Lu;0;L;0054 0326;;;;N;;;;021B;
+021B;LATIN SMALL LETTER T WITH COMMA BELOW;Ll;0;L;0074 0326;;;;N;;;021A;;021A
+021C;LATIN CAPITAL LETTER YOGH;Lu;0;L;;;;;N;;;;021D;
+021D;LATIN SMALL LETTER YOGH;Ll;0;L;;;;;N;;;021C;;021C
+021E;LATIN CAPITAL LETTER H WITH CARON;Lu;0;L;0048 030C;;;;N;;;;021F;
+021F;LATIN SMALL LETTER H WITH CARON;Ll;0;L;0068 030C;;;;N;;;021E;;021E
+0220;LATIN CAPITAL LETTER N WITH LONG RIGHT LEG;Lu;0;L;;;;;N;;;;019E;
+0221;LATIN SMALL LETTER D WITH CURL;Ll;0;L;;;;;N;;;;;
+0222;LATIN CAPITAL LETTER OU;Lu;0;L;;;;;N;;;;0223;
+0223;LATIN SMALL LETTER OU;Ll;0;L;;;;;N;;;0222;;0222
+0224;LATIN CAPITAL LETTER Z WITH HOOK;Lu;0;L;;;;;N;;;;0225;
+0225;LATIN SMALL LETTER Z WITH HOOK;Ll;0;L;;;;;N;;;0224;;0224
+0226;LATIN CAPITAL LETTER A WITH DOT ABOVE;Lu;0;L;0041 0307;;;;N;;;;0227;
+0227;LATIN SMALL LETTER A WITH DOT ABOVE;Ll;0;L;0061 0307;;;;N;;;0226;;0226
+0228;LATIN CAPITAL LETTER E WITH CEDILLA;Lu;0;L;0045 0327;;;;N;;;;0229;
+0229;LATIN SMALL LETTER E WITH CEDILLA;Ll;0;L;0065 0327;;;;N;;;0228;;0228
+022A;LATIN CAPITAL LETTER O WITH DIAERESIS AND MACRON;Lu;0;L;00D6 0304;;;;N;;;;022B;
+022B;LATIN SMALL LETTER O WITH DIAERESIS AND MACRON;Ll;0;L;00F6 0304;;;;N;;;022A;;022A
+022C;LATIN CAPITAL LETTER O WITH TILDE AND MACRON;Lu;0;L;00D5 0304;;;;N;;;;022D;
+022D;LATIN SMALL LETTER O WITH TILDE AND MACRON;Ll;0;L;00F5 0304;;;;N;;;022C;;022C
+022E;LATIN CAPITAL LETTER O WITH DOT ABOVE;Lu;0;L;004F 0307;;;;N;;;;022F;
+022F;LATIN SMALL LETTER O WITH DOT ABOVE;Ll;0;L;006F 0307;;;;N;;;022E;;022E
+0230;LATIN CAPITAL LETTER O WITH DOT ABOVE AND MACRON;Lu;0;L;022E 0304;;;;N;;;;0231;
+0231;LATIN SMALL LETTER O WITH DOT ABOVE AND MACRON;Ll;0;L;022F 0304;;;;N;;;0230;;0230
+0232;LATIN CAPITAL LETTER Y WITH MACRON;Lu;0;L;0059 0304;;;;N;;;;0233;
+0233;LATIN SMALL LETTER Y WITH MACRON;Ll;0;L;0079 0304;;;;N;;;0232;;0232
+0234;LATIN SMALL LETTER L WITH CURL;Ll;0;L;;;;;N;;;;;
+0235;LATIN SMALL LETTER N WITH CURL;Ll;0;L;;;;;N;;;;;
+0236;LATIN SMALL LETTER T WITH CURL;Ll;0;L;;;;;N;;;;;
+0237;LATIN SMALL LETTER DOTLESS J;Ll;0;L;;;;;N;;;;;
+0238;LATIN SMALL LETTER DB DIGRAPH;Ll;0;L;;;;;N;;;;;
+0239;LATIN SMALL LETTER QP DIGRAPH;Ll;0;L;;;;;N;;;;;
+023A;LATIN CAPITAL LETTER A WITH STROKE;Lu;0;L;;;;;N;;;;2C65;
+023B;LATIN CAPITAL LETTER C WITH STROKE;Lu;0;L;;;;;N;;;;023C;
+023C;LATIN SMALL LETTER C WITH STROKE;Ll;0;L;;;;;N;;;023B;;023B
+023D;LATIN CAPITAL LETTER L WITH BAR;Lu;0;L;;;;;N;;;;019A;
+023E;LATIN CAPITAL LETTER T WITH DIAGONAL STROKE;Lu;0;L;;;;;N;;;;2C66;
+023F;LATIN SMALL LETTER S WITH SWASH TAIL;Ll;0;L;;;;;N;;;2C7E;;2C7E
+0240;LATIN SMALL LETTER Z WITH SWASH TAIL;Ll;0;L;;;;;N;;;2C7F;;2C7F
+0241;LATIN CAPITAL LETTER GLOTTAL STOP;Lu;0;L;;;;;N;;;;0242;
+0242;LATIN SMALL LETTER GLOTTAL STOP;Ll;0;L;;;;;N;;;0241;;0241
+0243;LATIN CAPITAL LETTER B WITH STROKE;Lu;0;L;;;;;N;;;;0180;
+0244;LATIN CAPITAL LETTER U BAR;Lu;0;L;;;;;N;;;;0289;
+0245;LATIN CAPITAL LETTER TURNED V;Lu;0;L;;;;;N;;;;028C;
+0246;LATIN CAPITAL LETTER E WITH STROKE;Lu;0;L;;;;;N;;;;0247;
+0247;LATIN SMALL LETTER E WITH STROKE;Ll;0;L;;;;;N;;;0246;;0246
+0248;LATIN CAPITAL LETTER J WITH STROKE;Lu;0;L;;;;;N;;;;0249;
+0249;LATIN SMALL LETTER J WITH STROKE;Ll;0;L;;;;;N;;;0248;;0248
+024A;LATIN CAPITAL LETTER SMALL Q WITH HOOK TAIL;Lu;0;L;;;;;N;;;;024B;
+024B;LATIN SMALL LETTER Q WITH HOOK TAIL;Ll;0;L;;;;;N;;;024A;;024A
+024C;LATIN CAPITAL LETTER R WITH STROKE;Lu;0;L;;;;;N;;;;024D;
+024D;LATIN SMALL LETTER R WITH STROKE;Ll;0;L;;;;;N;;;024C;;024C
+024E;LATIN CAPITAL LETTER Y WITH STROKE;Lu;0;L;;;;;N;;;;024F;
+024F;LATIN SMALL LETTER Y WITH STROKE;Ll;0;L;;;;;N;;;024E;;024E
+0250;LATIN SMALL LETTER TURNED A;Ll;0;L;;;;;N;;;2C6F;;2C6F
+0251;LATIN SMALL LETTER ALPHA;Ll;0;L;;;;;N;LATIN SMALL LETTER SCRIPT A;;2C6D;;2C6D
+0252;LATIN SMALL LETTER TURNED ALPHA;Ll;0;L;;;;;N;LATIN SMALL LETTER TURNED SCRIPT A;;2C70;;2C70
+0253;LATIN SMALL LETTER B WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER B HOOK;;0181;;0181
+0254;LATIN SMALL LETTER OPEN O;Ll;0;L;;;;;N;;;0186;;0186
+0255;LATIN SMALL LETTER C WITH CURL;Ll;0;L;;;;;N;LATIN SMALL LETTER C CURL;;;;
+0256;LATIN SMALL LETTER D WITH TAIL;Ll;0;L;;;;;N;LATIN SMALL LETTER D RETROFLEX HOOK;;0189;;0189
+0257;LATIN SMALL LETTER D WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER D HOOK;;018A;;018A
+0258;LATIN SMALL LETTER REVERSED E;Ll;0;L;;;;;N;;;;;
+0259;LATIN SMALL LETTER SCHWA;Ll;0;L;;;;;N;;;018F;;018F
+025A;LATIN SMALL LETTER SCHWA WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER SCHWA HOOK;;;;
+025B;LATIN SMALL LETTER OPEN E;Ll;0;L;;;;;N;LATIN SMALL LETTER EPSILON;;0190;;0190
+025C;LATIN SMALL LETTER REVERSED OPEN E;Ll;0;L;;;;;N;LATIN SMALL LETTER REVERSED EPSILON;;;;
+025D;LATIN SMALL LETTER REVERSED OPEN E WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER REVERSED EPSILON HOOK;;;;
+025E;LATIN SMALL LETTER CLOSED REVERSED OPEN E;Ll;0;L;;;;;N;LATIN SMALL LETTER CLOSED REVERSED EPSILON;;;;
+025F;LATIN SMALL LETTER DOTLESS J WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER DOTLESS J BAR;;;;
+0260;LATIN SMALL LETTER G WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER G HOOK;;0193;;0193
+0261;LATIN SMALL LETTER SCRIPT G;Ll;0;L;;;;;N;;;;;
+0262;LATIN LETTER SMALL CAPITAL G;Ll;0;L;;;;;N;;;;;
+0263;LATIN SMALL LETTER GAMMA;Ll;0;L;;;;;N;;;0194;;0194
+0264;LATIN SMALL LETTER RAMS HORN;Ll;0;L;;;;;N;LATIN SMALL LETTER BABY GAMMA;;;;
+0265;LATIN SMALL LETTER TURNED H;Ll;0;L;;;;;N;;;A78D;;A78D
+0266;LATIN SMALL LETTER H WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER H HOOK;;;;
+0267;LATIN SMALL LETTER HENG WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER HENG HOOK;;;;
+0268;LATIN SMALL LETTER I WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER BARRED I;;0197;;0197
+0269;LATIN SMALL LETTER IOTA;Ll;0;L;;;;;N;;;0196;;0196
+026A;LATIN LETTER SMALL CAPITAL I;Ll;0;L;;;;;N;;;;;
+026B;LATIN SMALL LETTER L WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;2C62;;2C62
+026C;LATIN SMALL LETTER L WITH BELT;Ll;0;L;;;;;N;LATIN SMALL LETTER L BELT;;;;
+026D;LATIN SMALL LETTER L WITH RETROFLEX HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER L RETROFLEX HOOK;;;;
+026E;LATIN SMALL LETTER LEZH;Ll;0;L;;;;;N;LATIN SMALL LETTER L YOGH;;;;
+026F;LATIN SMALL LETTER TURNED M;Ll;0;L;;;;;N;;;019C;;019C
+0270;LATIN SMALL LETTER TURNED M WITH LONG LEG;Ll;0;L;;;;;N;;;;;
+0271;LATIN SMALL LETTER M WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER M HOOK;;2C6E;;2C6E
+0272;LATIN SMALL LETTER N WITH LEFT HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER N HOOK;;019D;;019D
+0273;LATIN SMALL LETTER N WITH RETROFLEX HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER N RETROFLEX HOOK;;;;
+0274;LATIN LETTER SMALL CAPITAL N;Ll;0;L;;;;;N;;;;;
+0275;LATIN SMALL LETTER BARRED O;Ll;0;L;;;;;N;;;019F;;019F
+0276;LATIN LETTER SMALL CAPITAL OE;Ll;0;L;;;;;N;LATIN LETTER SMALL CAPITAL O E;;;;
+0277;LATIN SMALL LETTER CLOSED OMEGA;Ll;0;L;;;;;N;;;;;
+0278;LATIN SMALL LETTER PHI;Ll;0;L;;;;;N;;;;;
+0279;LATIN SMALL LETTER TURNED R;Ll;0;L;;;;;N;;;;;
+027A;LATIN SMALL LETTER TURNED R WITH LONG LEG;Ll;0;L;;;;;N;;;;;
+027B;LATIN SMALL LETTER TURNED R WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER TURNED R HOOK;;;;
+027C;LATIN SMALL LETTER R WITH LONG LEG;Ll;0;L;;;;;N;;;;;
+027D;LATIN SMALL LETTER R WITH TAIL;Ll;0;L;;;;;N;LATIN SMALL LETTER R HOOK;;2C64;;2C64
+027E;LATIN SMALL LETTER R WITH FISHHOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER FISHHOOK R;;;;
+027F;LATIN SMALL LETTER REVERSED R WITH FISHHOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER REVERSED FISHHOOK R;;;;
+0280;LATIN LETTER SMALL CAPITAL R;Ll;0;L;;;;;N;;;01A6;;01A6
+0281;LATIN LETTER SMALL CAPITAL INVERTED R;Ll;0;L;;;;;N;;;;;
+0282;LATIN SMALL LETTER S WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER S HOOK;;;;
+0283;LATIN SMALL LETTER ESH;Ll;0;L;;;;;N;;;01A9;;01A9
+0284;LATIN SMALL LETTER DOTLESS J WITH STROKE AND HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER DOTLESS J BAR HOOK;;;;
+0285;LATIN SMALL LETTER SQUAT REVERSED ESH;Ll;0;L;;;;;N;;;;;
+0286;LATIN SMALL LETTER ESH WITH CURL;Ll;0;L;;;;;N;LATIN SMALL LETTER ESH CURL;;;;
+0287;LATIN SMALL LETTER TURNED T;Ll;0;L;;;;;N;;;;;
+0288;LATIN SMALL LETTER T WITH RETROFLEX HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER T RETROFLEX HOOK;;01AE;;01AE
+0289;LATIN SMALL LETTER U BAR;Ll;0;L;;;;;N;;;0244;;0244
+028A;LATIN SMALL LETTER UPSILON;Ll;0;L;;;;;N;;;01B1;;01B1
+028B;LATIN SMALL LETTER V WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER SCRIPT V;;01B2;;01B2
+028C;LATIN SMALL LETTER TURNED V;Ll;0;L;;;;;N;;;0245;;0245
+028D;LATIN SMALL LETTER TURNED W;Ll;0;L;;;;;N;;;;;
+028E;LATIN SMALL LETTER TURNED Y;Ll;0;L;;;;;N;;;;;
+028F;LATIN LETTER SMALL CAPITAL Y;Ll;0;L;;;;;N;;;;;
+0290;LATIN SMALL LETTER Z WITH RETROFLEX HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER Z RETROFLEX HOOK;;;;
+0291;LATIN SMALL LETTER Z WITH CURL;Ll;0;L;;;;;N;LATIN SMALL LETTER Z CURL;;;;
+0292;LATIN SMALL LETTER EZH;Ll;0;L;;;;;N;LATIN SMALL LETTER YOGH;;01B7;;01B7
+0293;LATIN SMALL LETTER EZH WITH CURL;Ll;0;L;;;;;N;LATIN SMALL LETTER YOGH CURL;;;;
+0294;LATIN LETTER GLOTTAL STOP;Lo;0;L;;;;;N;;;;;
+0295;LATIN LETTER PHARYNGEAL VOICED FRICATIVE;Ll;0;L;;;;;N;LATIN LETTER REVERSED GLOTTAL STOP;;;;
+0296;LATIN LETTER INVERTED GLOTTAL STOP;Ll;0;L;;;;;N;;;;;
+0297;LATIN LETTER STRETCHED C;Ll;0;L;;;;;N;;;;;
+0298;LATIN LETTER BILABIAL CLICK;Ll;0;L;;;;;N;LATIN LETTER BULLSEYE;;;;
+0299;LATIN LETTER SMALL CAPITAL B;Ll;0;L;;;;;N;;;;;
+029A;LATIN SMALL LETTER CLOSED OPEN E;Ll;0;L;;;;;N;LATIN SMALL LETTER CLOSED EPSILON;;;;
+029B;LATIN LETTER SMALL CAPITAL G WITH HOOK;Ll;0;L;;;;;N;LATIN LETTER SMALL CAPITAL G HOOK;;;;
+029C;LATIN LETTER SMALL CAPITAL H;Ll;0;L;;;;;N;;;;;
+029D;LATIN SMALL LETTER J WITH CROSSED-TAIL;Ll;0;L;;;;;N;LATIN SMALL LETTER CROSSED-TAIL J;;;;
+029E;LATIN SMALL LETTER TURNED K;Ll;0;L;;;;;N;;;;;
+029F;LATIN LETTER SMALL CAPITAL L;Ll;0;L;;;;;N;;;;;
+02A0;LATIN SMALL LETTER Q WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER Q HOOK;;;;
+02A1;LATIN LETTER GLOTTAL STOP WITH STROKE;Ll;0;L;;;;;N;LATIN LETTER GLOTTAL STOP BAR;;;;
+02A2;LATIN LETTER REVERSED GLOTTAL STOP WITH STROKE;Ll;0;L;;;;;N;LATIN LETTER REVERSED GLOTTAL STOP BAR;;;;
+02A3;LATIN SMALL LETTER DZ DIGRAPH;Ll;0;L;;;;;N;LATIN SMALL LETTER D Z;;;;
+02A4;LATIN SMALL LETTER DEZH DIGRAPH;Ll;0;L;;;;;N;LATIN SMALL LETTER D YOGH;;;;
+02A5;LATIN SMALL LETTER DZ DIGRAPH WITH CURL;Ll;0;L;;;;;N;LATIN SMALL LETTER D Z CURL;;;;
+02A6;LATIN SMALL LETTER TS DIGRAPH;Ll;0;L;;;;;N;LATIN SMALL LETTER T S;;;;
+02A7;LATIN SMALL LETTER TESH DIGRAPH;Ll;0;L;;;;;N;LATIN SMALL LETTER T ESH;;;;
+02A8;LATIN SMALL LETTER TC DIGRAPH WITH CURL;Ll;0;L;;;;;N;LATIN SMALL LETTER T C CURL;;;;
+02A9;LATIN SMALL LETTER FENG DIGRAPH;Ll;0;L;;;;;N;;;;;
+02AA;LATIN SMALL LETTER LS DIGRAPH;Ll;0;L;;;;;N;;;;;
+02AB;LATIN SMALL LETTER LZ DIGRAPH;Ll;0;L;;;;;N;;;;;
+02AC;LATIN LETTER BILABIAL PERCUSSIVE;Ll;0;L;;;;;N;;;;;
+02AD;LATIN LETTER BIDENTAL PERCUSSIVE;Ll;0;L;;;;;N;;;;;
+02AE;LATIN SMALL LETTER TURNED H WITH FISHHOOK;Ll;0;L;;;;;N;;;;;
+02AF;LATIN SMALL LETTER TURNED H WITH FISHHOOK AND TAIL;Ll;0;L;;;;;N;;;;;
+02B0;MODIFIER LETTER SMALL H;Lm;0;L;<super> 0068;;;;N;;;;;
+02B1;MODIFIER LETTER SMALL H WITH HOOK;Lm;0;L;<super> 0266;;;;N;MODIFIER LETTER SMALL H HOOK;;;;
+02B2;MODIFIER LETTER SMALL J;Lm;0;L;<super> 006A;;;;N;;;;;
+02B3;MODIFIER LETTER SMALL R;Lm;0;L;<super> 0072;;;;N;;;;;
+02B4;MODIFIER LETTER SMALL TURNED R;Lm;0;L;<super> 0279;;;;N;;;;;
+02B5;MODIFIER LETTER SMALL TURNED R WITH HOOK;Lm;0;L;<super> 027B;;;;N;MODIFIER LETTER SMALL TURNED R HOOK;;;;
+02B6;MODIFIER LETTER SMALL CAPITAL INVERTED R;Lm;0;L;<super> 0281;;;;N;;;;;
+02B7;MODIFIER LETTER SMALL W;Lm;0;L;<super> 0077;;;;N;;;;;
+02B8;MODIFIER LETTER SMALL Y;Lm;0;L;<super> 0079;;;;N;;;;;
+02B9;MODIFIER LETTER PRIME;Lm;0;ON;;;;;N;;;;;
+02BA;MODIFIER LETTER DOUBLE PRIME;Lm;0;ON;;;;;N;;;;;
+02BB;MODIFIER LETTER TURNED COMMA;Lm;0;L;;;;;N;;;;;
+02BC;MODIFIER LETTER APOSTROPHE;Lm;0;L;;;;;N;;;;;
+02BD;MODIFIER LETTER REVERSED COMMA;Lm;0;L;;;;;N;;;;;
+02BE;MODIFIER LETTER RIGHT HALF RING;Lm;0;L;;;;;N;;;;;
+02BF;MODIFIER LETTER LEFT HALF RING;Lm;0;L;;;;;N;;;;;
+02C0;MODIFIER LETTER GLOTTAL STOP;Lm;0;L;;;;;N;;;;;
+02C1;MODIFIER LETTER REVERSED GLOTTAL STOP;Lm;0;L;;;;;N;;;;;
+02C2;MODIFIER LETTER LEFT ARROWHEAD;Sk;0;ON;;;;;N;;;;;
+02C3;MODIFIER LETTER RIGHT ARROWHEAD;Sk;0;ON;;;;;N;;;;;
+02C4;MODIFIER LETTER UP ARROWHEAD;Sk;0;ON;;;;;N;;;;;
+02C5;MODIFIER LETTER DOWN ARROWHEAD;Sk;0;ON;;;;;N;;;;;
+02C6;MODIFIER LETTER CIRCUMFLEX ACCENT;Lm;0;ON;;;;;N;MODIFIER LETTER CIRCUMFLEX;;;;
+02C7;CARON;Lm;0;ON;;;;;N;MODIFIER LETTER HACEK;;;;
+02C8;MODIFIER LETTER VERTICAL LINE;Lm;0;ON;;;;;N;;;;;
+02C9;MODIFIER LETTER MACRON;Lm;0;ON;;;;;N;;;;;
+02CA;MODIFIER LETTER ACUTE ACCENT;Lm;0;ON;;;;;N;MODIFIER LETTER ACUTE;;;;
+02CB;MODIFIER LETTER GRAVE ACCENT;Lm;0;ON;;;;;N;MODIFIER LETTER GRAVE;;;;
+02CC;MODIFIER LETTER LOW VERTICAL LINE;Lm;0;ON;;;;;N;;;;;
+02CD;MODIFIER LETTER LOW MACRON;Lm;0;ON;;;;;N;;;;;
+02CE;MODIFIER LETTER LOW GRAVE ACCENT;Lm;0;ON;;;;;N;MODIFIER LETTER LOW GRAVE;;;;
+02CF;MODIFIER LETTER LOW ACUTE ACCENT;Lm;0;ON;;;;;N;MODIFIER LETTER LOW ACUTE;;;;
+02D0;MODIFIER LETTER TRIANGULAR COLON;Lm;0;L;;;;;N;;;;;
+02D1;MODIFIER LETTER HALF TRIANGULAR COLON;Lm;0;L;;;;;N;;;;;
+02D2;MODIFIER LETTER CENTRED RIGHT HALF RING;Sk;0;ON;;;;;N;MODIFIER LETTER CENTERED RIGHT HALF RING;;;;
+02D3;MODIFIER LETTER CENTRED LEFT HALF RING;Sk;0;ON;;;;;N;MODIFIER LETTER CENTERED LEFT HALF RING;;;;
+02D4;MODIFIER LETTER UP TACK;Sk;0;ON;;;;;N;;;;;
+02D5;MODIFIER LETTER DOWN TACK;Sk;0;ON;;;;;N;;;;;
+02D6;MODIFIER LETTER PLUS SIGN;Sk;0;ON;;;;;N;;;;;
+02D7;MODIFIER LETTER MINUS SIGN;Sk;0;ON;;;;;N;;;;;
+02D8;BREVE;Sk;0;ON;<compat> 0020 0306;;;;N;SPACING BREVE;;;;
+02D9;DOT ABOVE;Sk;0;ON;<compat> 0020 0307;;;;N;SPACING DOT ABOVE;;;;
+02DA;RING ABOVE;Sk;0;ON;<compat> 0020 030A;;;;N;SPACING RING ABOVE;;;;
+02DB;OGONEK;Sk;0;ON;<compat> 0020 0328;;;;N;SPACING OGONEK;;;;
+02DC;SMALL TILDE;Sk;0;ON;<compat> 0020 0303;;;;N;SPACING TILDE;;;;
+02DD;DOUBLE ACUTE ACCENT;Sk;0;ON;<compat> 0020 030B;;;;N;SPACING DOUBLE ACUTE;;;;
+02DE;MODIFIER LETTER RHOTIC HOOK;Sk;0;ON;;;;;N;;;;;
+02DF;MODIFIER LETTER CROSS ACCENT;Sk;0;ON;;;;;N;;;;;
+02E0;MODIFIER LETTER SMALL GAMMA;Lm;0;L;<super> 0263;;;;N;;;;;
+02E1;MODIFIER LETTER SMALL L;Lm;0;L;<super> 006C;;;;N;;;;;
+02E2;MODIFIER LETTER SMALL S;Lm;0;L;<super> 0073;;;;N;;;;;
+02E3;MODIFIER LETTER SMALL X;Lm;0;L;<super> 0078;;;;N;;;;;
+02E4;MODIFIER LETTER SMALL REVERSED GLOTTAL STOP;Lm;0;L;<super> 0295;;;;N;;;;;
+02E5;MODIFIER LETTER EXTRA-HIGH TONE BAR;Sk;0;ON;;;;;N;;;;;
+02E6;MODIFIER LETTER HIGH TONE BAR;Sk;0;ON;;;;;N;;;;;
+02E7;MODIFIER LETTER MID TONE BAR;Sk;0;ON;;;;;N;;;;;
+02E8;MODIFIER LETTER LOW TONE BAR;Sk;0;ON;;;;;N;;;;;
+02E9;MODIFIER LETTER EXTRA-LOW TONE BAR;Sk;0;ON;;;;;N;;;;;
+02EA;MODIFIER LETTER YIN DEPARTING TONE MARK;Sk;0;ON;;;;;N;;;;;
+02EB;MODIFIER LETTER YANG DEPARTING TONE MARK;Sk;0;ON;;;;;N;;;;;
+02EC;MODIFIER LETTER VOICING;Lm;0;ON;;;;;N;;;;;
+02ED;MODIFIER LETTER UNASPIRATED;Sk;0;ON;;;;;N;;;;;
+02EE;MODIFIER LETTER DOUBLE APOSTROPHE;Lm;0;L;;;;;N;;;;;
+02EF;MODIFIER LETTER LOW DOWN ARROWHEAD;Sk;0;ON;;;;;N;;;;;
+02F0;MODIFIER LETTER LOW UP ARROWHEAD;Sk;0;ON;;;;;N;;;;;
+02F1;MODIFIER LETTER LOW LEFT ARROWHEAD;Sk;0;ON;;;;;N;;;;;
+02F2;MODIFIER LETTER LOW RIGHT ARROWHEAD;Sk;0;ON;;;;;N;;;;;
+02F3;MODIFIER LETTER LOW RING;Sk;0;ON;;;;;N;;;;;
+02F4;MODIFIER LETTER MIDDLE GRAVE ACCENT;Sk;0;ON;;;;;N;;;;;
+02F5;MODIFIER LETTER MIDDLE DOUBLE GRAVE ACCENT;Sk;0;ON;;;;;N;;;;;
+02F6;MODIFIER LETTER MIDDLE DOUBLE ACUTE ACCENT;Sk;0;ON;;;;;N;;;;;
+02F7;MODIFIER LETTER LOW TILDE;Sk;0;ON;;;;;N;;;;;
+02F8;MODIFIER LETTER RAISED COLON;Sk;0;ON;;;;;N;;;;;
+02F9;MODIFIER LETTER BEGIN HIGH TONE;Sk;0;ON;;;;;N;;;;;
+02FA;MODIFIER LETTER END HIGH TONE;Sk;0;ON;;;;;N;;;;;
+02FB;MODIFIER LETTER BEGIN LOW TONE;Sk;0;ON;;;;;N;;;;;
+02FC;MODIFIER LETTER END LOW TONE;Sk;0;ON;;;;;N;;;;;
+02FD;MODIFIER LETTER SHELF;Sk;0;ON;;;;;N;;;;;
+02FE;MODIFIER LETTER OPEN SHELF;Sk;0;ON;;;;;N;;;;;
+02FF;MODIFIER LETTER LOW LEFT ARROW;Sk;0;ON;;;;;N;;;;;
+0300;COMBINING GRAVE ACCENT;Mn;230;NSM;;;;;N;NON-SPACING GRAVE;;;;
+0301;COMBINING ACUTE ACCENT;Mn;230;NSM;;;;;N;NON-SPACING ACUTE;;;;
+0302;COMBINING CIRCUMFLEX ACCENT;Mn;230;NSM;;;;;N;NON-SPACING CIRCUMFLEX;;;;
+0303;COMBINING TILDE;Mn;230;NSM;;;;;N;NON-SPACING TILDE;;;;
+0304;COMBINING MACRON;Mn;230;NSM;;;;;N;NON-SPACING MACRON;;;;
+0305;COMBINING OVERLINE;Mn;230;NSM;;;;;N;NON-SPACING OVERSCORE;;;;
+0306;COMBINING BREVE;Mn;230;NSM;;;;;N;NON-SPACING BREVE;;;;
+0307;COMBINING DOT ABOVE;Mn;230;NSM;;;;;N;NON-SPACING DOT ABOVE;;;;
+0308;COMBINING DIAERESIS;Mn;230;NSM;;;;;N;NON-SPACING DIAERESIS;;;;
+0309;COMBINING HOOK ABOVE;Mn;230;NSM;;;;;N;NON-SPACING HOOK ABOVE;;;;
+030A;COMBINING RING ABOVE;Mn;230;NSM;;;;;N;NON-SPACING RING ABOVE;;;;
+030B;COMBINING DOUBLE ACUTE ACCENT;Mn;230;NSM;;;;;N;NON-SPACING DOUBLE ACUTE;;;;
+030C;COMBINING CARON;Mn;230;NSM;;;;;N;NON-SPACING HACEK;;;;
+030D;COMBINING VERTICAL LINE ABOVE;Mn;230;NSM;;;;;N;NON-SPACING VERTICAL LINE ABOVE;;;;
+030E;COMBINING DOUBLE VERTICAL LINE ABOVE;Mn;230;NSM;;;;;N;NON-SPACING DOUBLE VERTICAL LINE ABOVE;;;;
+030F;COMBINING DOUBLE GRAVE ACCENT;Mn;230;NSM;;;;;N;NON-SPACING DOUBLE GRAVE;;;;
+0310;COMBINING CANDRABINDU;Mn;230;NSM;;;;;N;NON-SPACING CANDRABINDU;;;;
+0311;COMBINING INVERTED BREVE;Mn;230;NSM;;;;;N;NON-SPACING INVERTED BREVE;;;;
+0312;COMBINING TURNED COMMA ABOVE;Mn;230;NSM;;;;;N;NON-SPACING TURNED COMMA ABOVE;;;;
+0313;COMBINING COMMA ABOVE;Mn;230;NSM;;;;;N;NON-SPACING COMMA ABOVE;;;;
+0314;COMBINING REVERSED COMMA ABOVE;Mn;230;NSM;;;;;N;NON-SPACING REVERSED COMMA ABOVE;;;;
+0315;COMBINING COMMA ABOVE RIGHT;Mn;232;NSM;;;;;N;NON-SPACING COMMA ABOVE RIGHT;;;;
+0316;COMBINING GRAVE ACCENT BELOW;Mn;220;NSM;;;;;N;NON-SPACING GRAVE BELOW;;;;
+0317;COMBINING ACUTE ACCENT BELOW;Mn;220;NSM;;;;;N;NON-SPACING ACUTE BELOW;;;;
+0318;COMBINING LEFT TACK BELOW;Mn;220;NSM;;;;;N;NON-SPACING LEFT TACK BELOW;;;;
+0319;COMBINING RIGHT TACK BELOW;Mn;220;NSM;;;;;N;NON-SPACING RIGHT TACK BELOW;;;;
+031A;COMBINING LEFT ANGLE ABOVE;Mn;232;NSM;;;;;N;NON-SPACING LEFT ANGLE ABOVE;;;;
+031B;COMBINING HORN;Mn;216;NSM;;;;;N;NON-SPACING HORN;;;;
+031C;COMBINING LEFT HALF RING BELOW;Mn;220;NSM;;;;;N;NON-SPACING LEFT HALF RING BELOW;;;;
+031D;COMBINING UP TACK BELOW;Mn;220;NSM;;;;;N;NON-SPACING UP TACK BELOW;;;;
+031E;COMBINING DOWN TACK BELOW;Mn;220;NSM;;;;;N;NON-SPACING DOWN TACK BELOW;;;;
+031F;COMBINING PLUS SIGN BELOW;Mn;220;NSM;;;;;N;NON-SPACING PLUS SIGN BELOW;;;;
+0320;COMBINING MINUS SIGN BELOW;Mn;220;NSM;;;;;N;NON-SPACING MINUS SIGN BELOW;;;;
+0321;COMBINING PALATALIZED HOOK BELOW;Mn;202;NSM;;;;;N;NON-SPACING PALATALIZED HOOK BELOW;;;;
+0322;COMBINING RETROFLEX HOOK BELOW;Mn;202;NSM;;;;;N;NON-SPACING RETROFLEX HOOK BELOW;;;;
+0323;COMBINING DOT BELOW;Mn;220;NSM;;;;;N;NON-SPACING DOT BELOW;;;;
+0324;COMBINING DIAERESIS BELOW;Mn;220;NSM;;;;;N;NON-SPACING DOUBLE DOT BELOW;;;;
+0325;COMBINING RING BELOW;Mn;220;NSM;;;;;N;NON-SPACING RING BELOW;;;;
+0326;COMBINING COMMA BELOW;Mn;220;NSM;;;;;N;NON-SPACING COMMA BELOW;;;;
+0327;COMBINING CEDILLA;Mn;202;NSM;;;;;N;NON-SPACING CEDILLA;;;;
+0328;COMBINING OGONEK;Mn;202;NSM;;;;;N;NON-SPACING OGONEK;;;;
+0329;COMBINING VERTICAL LINE BELOW;Mn;220;NSM;;;;;N;NON-SPACING VERTICAL LINE BELOW;;;;
+032A;COMBINING BRIDGE BELOW;Mn;220;NSM;;;;;N;NON-SPACING BRIDGE BELOW;;;;
+032B;COMBINING INVERTED DOUBLE ARCH BELOW;Mn;220;NSM;;;;;N;NON-SPACING INVERTED DOUBLE ARCH BELOW;;;;
+032C;COMBINING CARON BELOW;Mn;220;NSM;;;;;N;NON-SPACING HACEK BELOW;;;;
+032D;COMBINING CIRCUMFLEX ACCENT BELOW;Mn;220;NSM;;;;;N;NON-SPACING CIRCUMFLEX BELOW;;;;
+032E;COMBINING BREVE BELOW;Mn;220;NSM;;;;;N;NON-SPACING BREVE BELOW;;;;
+032F;COMBINING INVERTED BREVE BELOW;Mn;220;NSM;;;;;N;NON-SPACING INVERTED BREVE BELOW;;;;
+0330;COMBINING TILDE BELOW;Mn;220;NSM;;;;;N;NON-SPACING TILDE BELOW;;;;
+0331;COMBINING MACRON BELOW;Mn;220;NSM;;;;;N;NON-SPACING MACRON BELOW;;;;
+0332;COMBINING LOW LINE;Mn;220;NSM;;;;;N;NON-SPACING UNDERSCORE;;;;
+0333;COMBINING DOUBLE LOW LINE;Mn;220;NSM;;;;;N;NON-SPACING DOUBLE UNDERSCORE;;;;
+0334;COMBINING TILDE OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING TILDE OVERLAY;;;;
+0335;COMBINING SHORT STROKE OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING SHORT BAR OVERLAY;;;;
+0336;COMBINING LONG STROKE OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING LONG BAR OVERLAY;;;;
+0337;COMBINING SHORT SOLIDUS OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING SHORT SLASH OVERLAY;;;;
+0338;COMBINING LONG SOLIDUS OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING LONG SLASH OVERLAY;;;;
+0339;COMBINING RIGHT HALF RING BELOW;Mn;220;NSM;;;;;N;NON-SPACING RIGHT HALF RING BELOW;;;;
+033A;COMBINING INVERTED BRIDGE BELOW;Mn;220;NSM;;;;;N;NON-SPACING INVERTED BRIDGE BELOW;;;;
+033B;COMBINING SQUARE BELOW;Mn;220;NSM;;;;;N;NON-SPACING SQUARE BELOW;;;;
+033C;COMBINING SEAGULL BELOW;Mn;220;NSM;;;;;N;NON-SPACING SEAGULL BELOW;;;;
+033D;COMBINING X ABOVE;Mn;230;NSM;;;;;N;NON-SPACING X ABOVE;;;;
+033E;COMBINING VERTICAL TILDE;Mn;230;NSM;;;;;N;NON-SPACING VERTICAL TILDE;;;;
+033F;COMBINING DOUBLE OVERLINE;Mn;230;NSM;;;;;N;NON-SPACING DOUBLE OVERSCORE;;;;
+0340;COMBINING GRAVE TONE MARK;Mn;230;NSM;0300;;;;N;NON-SPACING GRAVE TONE MARK;;;;
+0341;COMBINING ACUTE TONE MARK;Mn;230;NSM;0301;;;;N;NON-SPACING ACUTE TONE MARK;;;;
+0342;COMBINING GREEK PERISPOMENI;Mn;230;NSM;;;;;N;;;;;
+0343;COMBINING GREEK KORONIS;Mn;230;NSM;0313;;;;N;;;;;
+0344;COMBINING GREEK DIALYTIKA TONOS;Mn;230;NSM;0308 0301;;;;N;GREEK NON-SPACING DIAERESIS TONOS;;;;
+0345;COMBINING GREEK YPOGEGRAMMENI;Mn;240;NSM;;;;;N;GREEK NON-SPACING IOTA BELOW;;0399;;0399
+0346;COMBINING BRIDGE ABOVE;Mn;230;NSM;;;;;N;;;;;
+0347;COMBINING EQUALS SIGN BELOW;Mn;220;NSM;;;;;N;;;;;
+0348;COMBINING DOUBLE VERTICAL LINE BELOW;Mn;220;NSM;;;;;N;;;;;
+0349;COMBINING LEFT ANGLE BELOW;Mn;220;NSM;;;;;N;;;;;
+034A;COMBINING NOT TILDE ABOVE;Mn;230;NSM;;;;;N;;;;;
+034B;COMBINING HOMOTHETIC ABOVE;Mn;230;NSM;;;;;N;;;;;
+034C;COMBINING ALMOST EQUAL TO ABOVE;Mn;230;NSM;;;;;N;;;;;
+034D;COMBINING LEFT RIGHT ARROW BELOW;Mn;220;NSM;;;;;N;;;;;
+034E;COMBINING UPWARDS ARROW BELOW;Mn;220;NSM;;;;;N;;;;;
+034F;COMBINING GRAPHEME JOINER;Mn;0;NSM;;;;;N;;;;;
+0350;COMBINING RIGHT ARROWHEAD ABOVE;Mn;230;NSM;;;;;N;;;;;
+0351;COMBINING LEFT HALF RING ABOVE;Mn;230;NSM;;;;;N;;;;;
+0352;COMBINING FERMATA;Mn;230;NSM;;;;;N;;;;;
+0353;COMBINING X BELOW;Mn;220;NSM;;;;;N;;;;;
+0354;COMBINING LEFT ARROWHEAD BELOW;Mn;220;NSM;;;;;N;;;;;
+0355;COMBINING RIGHT ARROWHEAD BELOW;Mn;220;NSM;;;;;N;;;;;
+0356;COMBINING RIGHT ARROWHEAD AND UP ARROWHEAD BELOW;Mn;220;NSM;;;;;N;;;;;
+0357;COMBINING RIGHT HALF RING ABOVE;Mn;230;NSM;;;;;N;;;;;
+0358;COMBINING DOT ABOVE RIGHT;Mn;232;NSM;;;;;N;;;;;
+0359;COMBINING ASTERISK BELOW;Mn;220;NSM;;;;;N;;;;;
+035A;COMBINING DOUBLE RING BELOW;Mn;220;NSM;;;;;N;;;;;
+035B;COMBINING ZIGZAG ABOVE;Mn;230;NSM;;;;;N;;;;;
+035C;COMBINING DOUBLE BREVE BELOW;Mn;233;NSM;;;;;N;;;;;
+035D;COMBINING DOUBLE BREVE;Mn;234;NSM;;;;;N;;;;;
+035E;COMBINING DOUBLE MACRON;Mn;234;NSM;;;;;N;;;;;
+035F;COMBINING DOUBLE MACRON BELOW;Mn;233;NSM;;;;;N;;;;;
+0360;COMBINING DOUBLE TILDE;Mn;234;NSM;;;;;N;;;;;
+0361;COMBINING DOUBLE INVERTED BREVE;Mn;234;NSM;;;;;N;;;;;
+0362;COMBINING DOUBLE RIGHTWARDS ARROW BELOW;Mn;233;NSM;;;;;N;;;;;
+0363;COMBINING LATIN SMALL LETTER A;Mn;230;NSM;;;;;N;;;;;
+0364;COMBINING LATIN SMALL LETTER E;Mn;230;NSM;;;;;N;;;;;
+0365;COMBINING LATIN SMALL LETTER I;Mn;230;NSM;;;;;N;;;;;
+0366;COMBINING LATIN SMALL LETTER O;Mn;230;NSM;;;;;N;;;;;
+0367;COMBINING LATIN SMALL LETTER U;Mn;230;NSM;;;;;N;;;;;
+0368;COMBINING LATIN SMALL LETTER C;Mn;230;NSM;;;;;N;;;;;
+0369;COMBINING LATIN SMALL LETTER D;Mn;230;NSM;;;;;N;;;;;
+036A;COMBINING LATIN SMALL LETTER H;Mn;230;NSM;;;;;N;;;;;
+036B;COMBINING LATIN SMALL LETTER M;Mn;230;NSM;;;;;N;;;;;
+036C;COMBINING LATIN SMALL LETTER R;Mn;230;NSM;;;;;N;;;;;
+036D;COMBINING LATIN SMALL LETTER T;Mn;230;NSM;;;;;N;;;;;
+036E;COMBINING LATIN SMALL LETTER V;Mn;230;NSM;;;;;N;;;;;
+036F;COMBINING LATIN SMALL LETTER X;Mn;230;NSM;;;;;N;;;;;
+0370;GREEK CAPITAL LETTER HETA;Lu;0;L;;;;;N;;;;0371;
+0371;GREEK SMALL LETTER HETA;Ll;0;L;;;;;N;;;0370;;0370
+0372;GREEK CAPITAL LETTER ARCHAIC SAMPI;Lu;0;L;;;;;N;;;;0373;
+0373;GREEK SMALL LETTER ARCHAIC SAMPI;Ll;0;L;;;;;N;;;0372;;0372
+0374;GREEK NUMERAL SIGN;Lm;0;ON;02B9;;;;N;GREEK UPPER NUMERAL SIGN;;;;
+0375;GREEK LOWER NUMERAL SIGN;Sk;0;ON;;;;;N;;;;;
+0376;GREEK CAPITAL LETTER PAMPHYLIAN DIGAMMA;Lu;0;L;;;;;N;;;;0377;
+0377;GREEK SMALL LETTER PAMPHYLIAN DIGAMMA;Ll;0;L;;;;;N;;;0376;;0376
+037A;GREEK YPOGEGRAMMENI;Lm;0;L;<compat> 0020 0345;;;;N;GREEK SPACING IOTA BELOW;;;;
+037B;GREEK SMALL REVERSED LUNATE SIGMA SYMBOL;Ll;0;L;;;;;N;;;03FD;;03FD
+037C;GREEK SMALL DOTTED LUNATE SIGMA SYMBOL;Ll;0;L;;;;;N;;;03FE;;03FE
+037D;GREEK SMALL REVERSED DOTTED LUNATE SIGMA SYMBOL;Ll;0;L;;;;;N;;;03FF;;03FF
+037E;GREEK QUESTION MARK;Po;0;ON;003B;;;;N;;;;;
+0384;GREEK TONOS;Sk;0;ON;<compat> 0020 0301;;;;N;GREEK SPACING TONOS;;;;
+0385;GREEK DIALYTIKA TONOS;Sk;0;ON;00A8 0301;;;;N;GREEK SPACING DIAERESIS TONOS;;;;
+0386;GREEK CAPITAL LETTER ALPHA WITH TONOS;Lu;0;L;0391 0301;;;;N;GREEK CAPITAL LETTER ALPHA TONOS;;;03AC;
+0387;GREEK ANO TELEIA;Po;0;ON;00B7;;;;N;;;;;
+0388;GREEK CAPITAL LETTER EPSILON WITH TONOS;Lu;0;L;0395 0301;;;;N;GREEK CAPITAL LETTER EPSILON TONOS;;;03AD;
+0389;GREEK CAPITAL LETTER ETA WITH TONOS;Lu;0;L;0397 0301;;;;N;GREEK CAPITAL LETTER ETA TONOS;;;03AE;
+038A;GREEK CAPITAL LETTER IOTA WITH TONOS;Lu;0;L;0399 0301;;;;N;GREEK CAPITAL LETTER IOTA TONOS;;;03AF;
+038C;GREEK CAPITAL LETTER OMICRON WITH TONOS;Lu;0;L;039F 0301;;;;N;GREEK CAPITAL LETTER OMICRON TONOS;;;03CC;
+038E;GREEK CAPITAL LETTER UPSILON WITH TONOS;Lu;0;L;03A5 0301;;;;N;GREEK CAPITAL LETTER UPSILON TONOS;;;03CD;
+038F;GREEK CAPITAL LETTER OMEGA WITH TONOS;Lu;0;L;03A9 0301;;;;N;GREEK CAPITAL LETTER OMEGA TONOS;;;03CE;
+0390;GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS;Ll;0;L;03CA 0301;;;;N;GREEK SMALL LETTER IOTA DIAERESIS TONOS;;;;
+0391;GREEK CAPITAL LETTER ALPHA;Lu;0;L;;;;;N;;;;03B1;
+0392;GREEK CAPITAL LETTER BETA;Lu;0;L;;;;;N;;;;03B2;
+0393;GREEK CAPITAL LETTER GAMMA;Lu;0;L;;;;;N;;;;03B3;
+0394;GREEK CAPITAL LETTER DELTA;Lu;0;L;;;;;N;;;;03B4;
+0395;GREEK CAPITAL LETTER EPSILON;Lu;0;L;;;;;N;;;;03B5;
+0396;GREEK CAPITAL LETTER ZETA;Lu;0;L;;;;;N;;;;03B6;
+0397;GREEK CAPITAL LETTER ETA;Lu;0;L;;;;;N;;;;03B7;
+0398;GREEK CAPITAL LETTER THETA;Lu;0;L;;;;;N;;;;03B8;
+0399;GREEK CAPITAL LETTER IOTA;Lu;0;L;;;;;N;;;;03B9;
+039A;GREEK CAPITAL LETTER KAPPA;Lu;0;L;;;;;N;;;;03BA;
+039B;GREEK CAPITAL LETTER LAMDA;Lu;0;L;;;;;N;GREEK CAPITAL LETTER LAMBDA;;;03BB;
+039C;GREEK CAPITAL LETTER MU;Lu;0;L;;;;;N;;;;03BC;
+039D;GREEK CAPITAL LETTER NU;Lu;0;L;;;;;N;;;;03BD;
+039E;GREEK CAPITAL LETTER XI;Lu;0;L;;;;;N;;;;03BE;
+039F;GREEK CAPITAL LETTER OMICRON;Lu;0;L;;;;;N;;;;03BF;
+03A0;GREEK CAPITAL LETTER PI;Lu;0;L;;;;;N;;;;03C0;
+03A1;GREEK CAPITAL LETTER RHO;Lu;0;L;;;;;N;;;;03C1;
+03A3;GREEK CAPITAL LETTER SIGMA;Lu;0;L;;;;;N;;;;03C3;
+03A4;GREEK CAPITAL LETTER TAU;Lu;0;L;;;;;N;;;;03C4;
+03A5;GREEK CAPITAL LETTER UPSILON;Lu;0;L;;;;;N;;;;03C5;
+03A6;GREEK CAPITAL LETTER PHI;Lu;0;L;;;;;N;;;;03C6;
+03A7;GREEK CAPITAL LETTER CHI;Lu;0;L;;;;;N;;;;03C7;
+03A8;GREEK CAPITAL LETTER PSI;Lu;0;L;;;;;N;;;;03C8;
+03A9;GREEK CAPITAL LETTER OMEGA;Lu;0;L;;;;;N;;;;03C9;
+03AA;GREEK CAPITAL LETTER IOTA WITH DIALYTIKA;Lu;0;L;0399 0308;;;;N;GREEK CAPITAL LETTER IOTA DIAERESIS;;;03CA;
+03AB;GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA;Lu;0;L;03A5 0308;;;;N;GREEK CAPITAL LETTER UPSILON DIAERESIS;;;03CB;
+03AC;GREEK SMALL LETTER ALPHA WITH TONOS;Ll;0;L;03B1 0301;;;;N;GREEK SMALL LETTER ALPHA TONOS;;0386;;0386
+03AD;GREEK SMALL LETTER EPSILON WITH TONOS;Ll;0;L;03B5 0301;;;;N;GREEK SMALL LETTER EPSILON TONOS;;0388;;0388
+03AE;GREEK SMALL LETTER ETA WITH TONOS;Ll;0;L;03B7 0301;;;;N;GREEK SMALL LETTER ETA TONOS;;0389;;0389
+03AF;GREEK SMALL LETTER IOTA WITH TONOS;Ll;0;L;03B9 0301;;;;N;GREEK SMALL LETTER IOTA TONOS;;038A;;038A
+03B0;GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS;Ll;0;L;03CB 0301;;;;N;GREEK SMALL LETTER UPSILON DIAERESIS TONOS;;;;
+03B1;GREEK SMALL LETTER ALPHA;Ll;0;L;;;;;N;;;0391;;0391
+03B2;GREEK SMALL LETTER BETA;Ll;0;L;;;;;N;;;0392;;0392
+03B3;GREEK SMALL LETTER GAMMA;Ll;0;L;;;;;N;;;0393;;0393
+03B4;GREEK SMALL LETTER DELTA;Ll;0;L;;;;;N;;;0394;;0394
+03B5;GREEK SMALL LETTER EPSILON;Ll;0;L;;;;;N;;;0395;;0395
+03B6;GREEK SMALL LETTER ZETA;Ll;0;L;;;;;N;;;0396;;0396
+03B7;GREEK SMALL LETTER ETA;Ll;0;L;;;;;N;;;0397;;0397
+03B8;GREEK SMALL LETTER THETA;Ll;0;L;;;;;N;;;0398;;0398
+03B9;GREEK SMALL LETTER IOTA;Ll;0;L;;;;;N;;;0399;;0399
+03BA;GREEK SMALL LETTER KAPPA;Ll;0;L;;;;;N;;;039A;;039A
+03BB;GREEK SMALL LETTER LAMDA;Ll;0;L;;;;;N;GREEK SMALL LETTER LAMBDA;;039B;;039B
+03BC;GREEK SMALL LETTER MU;Ll;0;L;;;;;N;;;039C;;039C
+03BD;GREEK SMALL LETTER NU;Ll;0;L;;;;;N;;;039D;;039D
+03BE;GREEK SMALL LETTER XI;Ll;0;L;;;;;N;;;039E;;039E
+03BF;GREEK SMALL LETTER OMICRON;Ll;0;L;;;;;N;;;039F;;039F
+03C0;GREEK SMALL LETTER PI;Ll;0;L;;;;;N;;;03A0;;03A0
+03C1;GREEK SMALL LETTER RHO;Ll;0;L;;;;;N;;;03A1;;03A1
+03C2;GREEK SMALL LETTER FINAL SIGMA;Ll;0;L;;;;;N;;;03A3;;03A3
+03C3;GREEK SMALL LETTER SIGMA;Ll;0;L;;;;;N;;;03A3;;03A3
+03C4;GREEK SMALL LETTER TAU;Ll;0;L;;;;;N;;;03A4;;03A4
+03C5;GREEK SMALL LETTER UPSILON;Ll;0;L;;;;;N;;;03A5;;03A5
+03C6;GREEK SMALL LETTER PHI;Ll;0;L;;;;;N;;;03A6;;03A6
+03C7;GREEK SMALL LETTER CHI;Ll;0;L;;;;;N;;;03A7;;03A7
+03C8;GREEK SMALL LETTER PSI;Ll;0;L;;;;;N;;;03A8;;03A8
+03C9;GREEK SMALL LETTER OMEGA;Ll;0;L;;;;;N;;;03A9;;03A9
+03CA;GREEK SMALL LETTER IOTA WITH DIALYTIKA;Ll;0;L;03B9 0308;;;;N;GREEK SMALL LETTER IOTA DIAERESIS;;03AA;;03AA
+03CB;GREEK SMALL LETTER UPSILON WITH DIALYTIKA;Ll;0;L;03C5 0308;;;;N;GREEK SMALL LETTER UPSILON DIAERESIS;;03AB;;03AB
+03CC;GREEK SMALL LETTER OMICRON WITH TONOS;Ll;0;L;03BF 0301;;;;N;GREEK SMALL LETTER OMICRON TONOS;;038C;;038C
+03CD;GREEK SMALL LETTER UPSILON WITH TONOS;Ll;0;L;03C5 0301;;;;N;GREEK SMALL LETTER UPSILON TONOS;;038E;;038E
+03CE;GREEK SMALL LETTER OMEGA WITH TONOS;Ll;0;L;03C9 0301;;;;N;GREEK SMALL LETTER OMEGA TONOS;;038F;;038F
+03CF;GREEK CAPITAL KAI SYMBOL;Lu;0;L;;;;;N;;;;03D7;
+03D0;GREEK BETA SYMBOL;Ll;0;L;<compat> 03B2;;;;N;GREEK SMALL LETTER CURLED BETA;;0392;;0392
+03D1;GREEK THETA SYMBOL;Ll;0;L;<compat> 03B8;;;;N;GREEK SMALL LETTER SCRIPT THETA;;0398;;0398
+03D2;GREEK UPSILON WITH HOOK SYMBOL;Lu;0;L;<compat> 03A5;;;;N;GREEK CAPITAL LETTER UPSILON HOOK;;;;
+03D3;GREEK UPSILON WITH ACUTE AND HOOK SYMBOL;Lu;0;L;03D2 0301;;;;N;GREEK CAPITAL LETTER UPSILON HOOK TONOS;;;;
+03D4;GREEK UPSILON WITH DIAERESIS AND HOOK SYMBOL;Lu;0;L;03D2 0308;;;;N;GREEK CAPITAL LETTER UPSILON HOOK DIAERESIS;;;;
+03D5;GREEK PHI SYMBOL;Ll;0;L;<compat> 03C6;;;;N;GREEK SMALL LETTER SCRIPT PHI;;03A6;;03A6
+03D6;GREEK PI SYMBOL;Ll;0;L;<compat> 03C0;;;;N;GREEK SMALL LETTER OMEGA PI;;03A0;;03A0
+03D7;GREEK KAI SYMBOL;Ll;0;L;;;;;N;;;03CF;;03CF
+03D8;GREEK LETTER ARCHAIC KOPPA;Lu;0;L;;;;;N;;;;03D9;
+03D9;GREEK SMALL LETTER ARCHAIC KOPPA;Ll;0;L;;;;;N;;;03D8;;03D8
+03DA;GREEK LETTER STIGMA;Lu;0;L;;;;;N;GREEK CAPITAL LETTER STIGMA;;;03DB;
+03DB;GREEK SMALL LETTER STIGMA;Ll;0;L;;;;;N;;;03DA;;03DA
+03DC;GREEK LETTER DIGAMMA;Lu;0;L;;;;;N;GREEK CAPITAL LETTER DIGAMMA;;;03DD;
+03DD;GREEK SMALL LETTER DIGAMMA;Ll;0;L;;;;;N;;;03DC;;03DC
+03DE;GREEK LETTER KOPPA;Lu;0;L;;;;;N;GREEK CAPITAL LETTER KOPPA;;;03DF;
+03DF;GREEK SMALL LETTER KOPPA;Ll;0;L;;;;;N;;;03DE;;03DE
+03E0;GREEK LETTER SAMPI;Lu;0;L;;;;;N;GREEK CAPITAL LETTER SAMPI;;;03E1;
+03E1;GREEK SMALL LETTER SAMPI;Ll;0;L;;;;;N;;;03E0;;03E0
+03E2;COPTIC CAPITAL LETTER SHEI;Lu;0;L;;;;;N;GREEK CAPITAL LETTER SHEI;;;03E3;
+03E3;COPTIC SMALL LETTER SHEI;Ll;0;L;;;;;N;GREEK SMALL LETTER SHEI;;03E2;;03E2
+03E4;COPTIC CAPITAL LETTER FEI;Lu;0;L;;;;;N;GREEK CAPITAL LETTER FEI;;;03E5;
+03E5;COPTIC SMALL LETTER FEI;Ll;0;L;;;;;N;GREEK SMALL LETTER FEI;;03E4;;03E4
+03E6;COPTIC CAPITAL LETTER KHEI;Lu;0;L;;;;;N;GREEK CAPITAL LETTER KHEI;;;03E7;
+03E7;COPTIC SMALL LETTER KHEI;Ll;0;L;;;;;N;GREEK SMALL LETTER KHEI;;03E6;;03E6
+03E8;COPTIC CAPITAL LETTER HORI;Lu;0;L;;;;;N;GREEK CAPITAL LETTER HORI;;;03E9;
+03E9;COPTIC SMALL LETTER HORI;Ll;0;L;;;;;N;GREEK SMALL LETTER HORI;;03E8;;03E8
+03EA;COPTIC CAPITAL LETTER GANGIA;Lu;0;L;;;;;N;GREEK CAPITAL LETTER GANGIA;;;03EB;
+03EB;COPTIC SMALL LETTER GANGIA;Ll;0;L;;;;;N;GREEK SMALL LETTER GANGIA;;03EA;;03EA
+03EC;COPTIC CAPITAL LETTER SHIMA;Lu;0;L;;;;;N;GREEK CAPITAL LETTER SHIMA;;;03ED;
+03ED;COPTIC SMALL LETTER SHIMA;Ll;0;L;;;;;N;GREEK SMALL LETTER SHIMA;;03EC;;03EC
+03EE;COPTIC CAPITAL LETTER DEI;Lu;0;L;;;;;N;GREEK CAPITAL LETTER DEI;;;03EF;
+03EF;COPTIC SMALL LETTER DEI;Ll;0;L;;;;;N;GREEK SMALL LETTER DEI;;03EE;;03EE
+03F0;GREEK KAPPA SYMBOL;Ll;0;L;<compat> 03BA;;;;N;GREEK SMALL LETTER SCRIPT KAPPA;;039A;;039A
+03F1;GREEK RHO SYMBOL;Ll;0;L;<compat> 03C1;;;;N;GREEK SMALL LETTER TAILED RHO;;03A1;;03A1
+03F2;GREEK LUNATE SIGMA SYMBOL;Ll;0;L;<compat> 03C2;;;;N;GREEK SMALL LETTER LUNATE SIGMA;;03F9;;03F9
+03F3;GREEK LETTER YOT;Ll;0;L;;;;;N;;;;;
+03F4;GREEK CAPITAL THETA SYMBOL;Lu;0;L;<compat> 0398;;;;N;;;;03B8;
+03F5;GREEK LUNATE EPSILON SYMBOL;Ll;0;L;<compat> 03B5;;;;N;;;0395;;0395
+03F6;GREEK REVERSED LUNATE EPSILON SYMBOL;Sm;0;ON;;;;;N;;;;;
+03F7;GREEK CAPITAL LETTER SHO;Lu;0;L;;;;;N;;;;03F8;
+03F8;GREEK SMALL LETTER SHO;Ll;0;L;;;;;N;;;03F7;;03F7
+03F9;GREEK CAPITAL LUNATE SIGMA SYMBOL;Lu;0;L;<compat> 03A3;;;;N;;;;03F2;
+03FA;GREEK CAPITAL LETTER SAN;Lu;0;L;;;;;N;;;;03FB;
+03FB;GREEK SMALL LETTER SAN;Ll;0;L;;;;;N;;;03FA;;03FA
+03FC;GREEK RHO WITH STROKE SYMBOL;Ll;0;L;;;;;N;;;;;
+03FD;GREEK CAPITAL REVERSED LUNATE SIGMA SYMBOL;Lu;0;L;;;;;N;;;;037B;
+03FE;GREEK CAPITAL DOTTED LUNATE SIGMA SYMBOL;Lu;0;L;;;;;N;;;;037C;
+03FF;GREEK CAPITAL REVERSED DOTTED LUNATE SIGMA SYMBOL;Lu;0;L;;;;;N;;;;037D;
+0400;CYRILLIC CAPITAL LETTER IE WITH GRAVE;Lu;0;L;0415 0300;;;;N;;;;0450;
+0401;CYRILLIC CAPITAL LETTER IO;Lu;0;L;0415 0308;;;;N;;;;0451;
+0402;CYRILLIC CAPITAL LETTER DJE;Lu;0;L;;;;;N;;;;0452;
+0403;CYRILLIC CAPITAL LETTER GJE;Lu;0;L;0413 0301;;;;N;;;;0453;
+0404;CYRILLIC CAPITAL LETTER UKRAINIAN IE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER E;;;0454;
+0405;CYRILLIC CAPITAL LETTER DZE;Lu;0;L;;;;;N;;;;0455;
+0406;CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER I;;;0456;
+0407;CYRILLIC CAPITAL LETTER YI;Lu;0;L;0406 0308;;;;N;;;;0457;
+0408;CYRILLIC CAPITAL LETTER JE;Lu;0;L;;;;;N;;;;0458;
+0409;CYRILLIC CAPITAL LETTER LJE;Lu;0;L;;;;;N;;;;0459;
+040A;CYRILLIC CAPITAL LETTER NJE;Lu;0;L;;;;;N;;;;045A;
+040B;CYRILLIC CAPITAL LETTER TSHE;Lu;0;L;;;;;N;;;;045B;
+040C;CYRILLIC CAPITAL LETTER KJE;Lu;0;L;041A 0301;;;;N;;;;045C;
+040D;CYRILLIC CAPITAL LETTER I WITH GRAVE;Lu;0;L;0418 0300;;;;N;;;;045D;
+040E;CYRILLIC CAPITAL LETTER SHORT U;Lu;0;L;0423 0306;;;;N;;;;045E;
+040F;CYRILLIC CAPITAL LETTER DZHE;Lu;0;L;;;;;N;;;;045F;
+0410;CYRILLIC CAPITAL LETTER A;Lu;0;L;;;;;N;;;;0430;
+0411;CYRILLIC CAPITAL LETTER BE;Lu;0;L;;;;;N;;;;0431;
+0412;CYRILLIC CAPITAL LETTER VE;Lu;0;L;;;;;N;;;;0432;
+0413;CYRILLIC CAPITAL LETTER GHE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER GE;;;0433;
+0414;CYRILLIC CAPITAL LETTER DE;Lu;0;L;;;;;N;;;;0434;
+0415;CYRILLIC CAPITAL LETTER IE;Lu;0;L;;;;;N;;;;0435;
+0416;CYRILLIC CAPITAL LETTER ZHE;Lu;0;L;;;;;N;;;;0436;
+0417;CYRILLIC CAPITAL LETTER ZE;Lu;0;L;;;;;N;;;;0437;
+0418;CYRILLIC CAPITAL LETTER I;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER II;;;0438;
+0419;CYRILLIC CAPITAL LETTER SHORT I;Lu;0;L;0418 0306;;;;N;CYRILLIC CAPITAL LETTER SHORT II;;;0439;
+041A;CYRILLIC CAPITAL LETTER KA;Lu;0;L;;;;;N;;;;043A;
+041B;CYRILLIC CAPITAL LETTER EL;Lu;0;L;;;;;N;;;;043B;
+041C;CYRILLIC CAPITAL LETTER EM;Lu;0;L;;;;;N;;;;043C;
+041D;CYRILLIC CAPITAL LETTER EN;Lu;0;L;;;;;N;;;;043D;
+041E;CYRILLIC CAPITAL LETTER O;Lu;0;L;;;;;N;;;;043E;
+041F;CYRILLIC CAPITAL LETTER PE;Lu;0;L;;;;;N;;;;043F;
+0420;CYRILLIC CAPITAL LETTER ER;Lu;0;L;;;;;N;;;;0440;
+0421;CYRILLIC CAPITAL LETTER ES;Lu;0;L;;;;;N;;;;0441;
+0422;CYRILLIC CAPITAL LETTER TE;Lu;0;L;;;;;N;;;;0442;
+0423;CYRILLIC CAPITAL LETTER U;Lu;0;L;;;;;N;;;;0443;
+0424;CYRILLIC CAPITAL LETTER EF;Lu;0;L;;;;;N;;;;0444;
+0425;CYRILLIC CAPITAL LETTER HA;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER KHA;;;0445;
+0426;CYRILLIC CAPITAL LETTER TSE;Lu;0;L;;;;;N;;;;0446;
+0427;CYRILLIC CAPITAL LETTER CHE;Lu;0;L;;;;;N;;;;0447;
+0428;CYRILLIC CAPITAL LETTER SHA;Lu;0;L;;;;;N;;;;0448;
+0429;CYRILLIC CAPITAL LETTER SHCHA;Lu;0;L;;;;;N;;;;0449;
+042A;CYRILLIC CAPITAL LETTER HARD SIGN;Lu;0;L;;;;;N;;;;044A;
+042B;CYRILLIC CAPITAL LETTER YERU;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER YERI;;;044B;
+042C;CYRILLIC CAPITAL LETTER SOFT SIGN;Lu;0;L;;;;;N;;;;044C;
+042D;CYRILLIC CAPITAL LETTER E;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER REVERSED E;;;044D;
+042E;CYRILLIC CAPITAL LETTER YU;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER IU;;;044E;
+042F;CYRILLIC CAPITAL LETTER YA;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER IA;;;044F;
+0430;CYRILLIC SMALL LETTER A;Ll;0;L;;;;;N;;;0410;;0410
+0431;CYRILLIC SMALL LETTER BE;Ll;0;L;;;;;N;;;0411;;0411
+0432;CYRILLIC SMALL LETTER VE;Ll;0;L;;;;;N;;;0412;;0412
+0433;CYRILLIC SMALL LETTER GHE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER GE;;0413;;0413
+0434;CYRILLIC SMALL LETTER DE;Ll;0;L;;;;;N;;;0414;;0414
+0435;CYRILLIC SMALL LETTER IE;Ll;0;L;;;;;N;;;0415;;0415
+0436;CYRILLIC SMALL LETTER ZHE;Ll;0;L;;;;;N;;;0416;;0416
+0437;CYRILLIC SMALL LETTER ZE;Ll;0;L;;;;;N;;;0417;;0417
+0438;CYRILLIC SMALL LETTER I;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER II;;0418;;0418
+0439;CYRILLIC SMALL LETTER SHORT I;Ll;0;L;0438 0306;;;;N;CYRILLIC SMALL LETTER SHORT II;;0419;;0419
+043A;CYRILLIC SMALL LETTER KA;Ll;0;L;;;;;N;;;041A;;041A
+043B;CYRILLIC SMALL LETTER EL;Ll;0;L;;;;;N;;;041B;;041B
+043C;CYRILLIC SMALL LETTER EM;Ll;0;L;;;;;N;;;041C;;041C
+043D;CYRILLIC SMALL LETTER EN;Ll;0;L;;;;;N;;;041D;;041D
+043E;CYRILLIC SMALL LETTER O;Ll;0;L;;;;;N;;;041E;;041E
+043F;CYRILLIC SMALL LETTER PE;Ll;0;L;;;;;N;;;041F;;041F
+0440;CYRILLIC SMALL LETTER ER;Ll;0;L;;;;;N;;;0420;;0420
+0441;CYRILLIC SMALL LETTER ES;Ll;0;L;;;;;N;;;0421;;0421
+0442;CYRILLIC SMALL LETTER TE;Ll;0;L;;;;;N;;;0422;;0422
+0443;CYRILLIC SMALL LETTER U;Ll;0;L;;;;;N;;;0423;;0423
+0444;CYRILLIC SMALL LETTER EF;Ll;0;L;;;;;N;;;0424;;0424
+0445;CYRILLIC SMALL LETTER HA;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER KHA;;0425;;0425
+0446;CYRILLIC SMALL LETTER TSE;Ll;0;L;;;;;N;;;0426;;0426
+0447;CYRILLIC SMALL LETTER CHE;Ll;0;L;;;;;N;;;0427;;0427
+0448;CYRILLIC SMALL LETTER SHA;Ll;0;L;;;;;N;;;0428;;0428
+0449;CYRILLIC SMALL LETTER SHCHA;Ll;0;L;;;;;N;;;0429;;0429
+044A;CYRILLIC SMALL LETTER HARD SIGN;Ll;0;L;;;;;N;;;042A;;042A
+044B;CYRILLIC SMALL LETTER YERU;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER YERI;;042B;;042B
+044C;CYRILLIC SMALL LETTER SOFT SIGN;Ll;0;L;;;;;N;;;042C;;042C
+044D;CYRILLIC SMALL LETTER E;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER REVERSED E;;042D;;042D
+044E;CYRILLIC SMALL LETTER YU;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER IU;;042E;;042E
+044F;CYRILLIC SMALL LETTER YA;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER IA;;042F;;042F
+0450;CYRILLIC SMALL LETTER IE WITH GRAVE;Ll;0;L;0435 0300;;;;N;;;0400;;0400
+0451;CYRILLIC SMALL LETTER IO;Ll;0;L;0435 0308;;;;N;;;0401;;0401
+0452;CYRILLIC SMALL LETTER DJE;Ll;0;L;;;;;N;;;0402;;0402
+0453;CYRILLIC SMALL LETTER GJE;Ll;0;L;0433 0301;;;;N;;;0403;;0403
+0454;CYRILLIC SMALL LETTER UKRAINIAN IE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER E;;0404;;0404
+0455;CYRILLIC SMALL LETTER DZE;Ll;0;L;;;;;N;;;0405;;0405
+0456;CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER I;;0406;;0406
+0457;CYRILLIC SMALL LETTER YI;Ll;0;L;0456 0308;;;;N;;;0407;;0407
+0458;CYRILLIC SMALL LETTER JE;Ll;0;L;;;;;N;;;0408;;0408
+0459;CYRILLIC SMALL LETTER LJE;Ll;0;L;;;;;N;;;0409;;0409
+045A;CYRILLIC SMALL LETTER NJE;Ll;0;L;;;;;N;;;040A;;040A
+045B;CYRILLIC SMALL LETTER TSHE;Ll;0;L;;;;;N;;;040B;;040B
+045C;CYRILLIC SMALL LETTER KJE;Ll;0;L;043A 0301;;;;N;;;040C;;040C
+045D;CYRILLIC SMALL LETTER I WITH GRAVE;Ll;0;L;0438 0300;;;;N;;;040D;;040D
+045E;CYRILLIC SMALL LETTER SHORT U;Ll;0;L;0443 0306;;;;N;;;040E;;040E
+045F;CYRILLIC SMALL LETTER DZHE;Ll;0;L;;;;;N;;;040F;;040F
+0460;CYRILLIC CAPITAL LETTER OMEGA;Lu;0;L;;;;;N;;;;0461;
+0461;CYRILLIC SMALL LETTER OMEGA;Ll;0;L;;;;;N;;;0460;;0460
+0462;CYRILLIC CAPITAL LETTER YAT;Lu;0;L;;;;;N;;;;0463;
+0463;CYRILLIC SMALL LETTER YAT;Ll;0;L;;;;;N;;;0462;;0462
+0464;CYRILLIC CAPITAL LETTER IOTIFIED E;Lu;0;L;;;;;N;;;;0465;
+0465;CYRILLIC SMALL LETTER IOTIFIED E;Ll;0;L;;;;;N;;;0464;;0464
+0466;CYRILLIC CAPITAL LETTER LITTLE YUS;Lu;0;L;;;;;N;;;;0467;
+0467;CYRILLIC SMALL LETTER LITTLE YUS;Ll;0;L;;;;;N;;;0466;;0466
+0468;CYRILLIC CAPITAL LETTER IOTIFIED LITTLE YUS;Lu;0;L;;;;;N;;;;0469;
+0469;CYRILLIC SMALL LETTER IOTIFIED LITTLE YUS;Ll;0;L;;;;;N;;;0468;;0468
+046A;CYRILLIC CAPITAL LETTER BIG YUS;Lu;0;L;;;;;N;;;;046B;
+046B;CYRILLIC SMALL LETTER BIG YUS;Ll;0;L;;;;;N;;;046A;;046A
+046C;CYRILLIC CAPITAL LETTER IOTIFIED BIG YUS;Lu;0;L;;;;;N;;;;046D;
+046D;CYRILLIC SMALL LETTER IOTIFIED BIG YUS;Ll;0;L;;;;;N;;;046C;;046C
+046E;CYRILLIC CAPITAL LETTER KSI;Lu;0;L;;;;;N;;;;046F;
+046F;CYRILLIC SMALL LETTER KSI;Ll;0;L;;;;;N;;;046E;;046E
+0470;CYRILLIC CAPITAL LETTER PSI;Lu;0;L;;;;;N;;;;0471;
+0471;CYRILLIC SMALL LETTER PSI;Ll;0;L;;;;;N;;;0470;;0470
+0472;CYRILLIC CAPITAL LETTER FITA;Lu;0;L;;;;;N;;;;0473;
+0473;CYRILLIC SMALL LETTER FITA;Ll;0;L;;;;;N;;;0472;;0472
+0474;CYRILLIC CAPITAL LETTER IZHITSA;Lu;0;L;;;;;N;;;;0475;
+0475;CYRILLIC SMALL LETTER IZHITSA;Ll;0;L;;;;;N;;;0474;;0474
+0476;CYRILLIC CAPITAL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT;Lu;0;L;0474 030F;;;;N;CYRILLIC CAPITAL LETTER IZHITSA DOUBLE GRAVE;;;0477;
+0477;CYRILLIC SMALL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT;Ll;0;L;0475 030F;;;;N;CYRILLIC SMALL LETTER IZHITSA DOUBLE GRAVE;;0476;;0476
+0478;CYRILLIC CAPITAL LETTER UK;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER UK DIGRAPH;;;0479;
+0479;CYRILLIC SMALL LETTER UK;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER UK DIGRAPH;;0478;;0478
+047A;CYRILLIC CAPITAL LETTER ROUND OMEGA;Lu;0;L;;;;;N;;;;047B;
+047B;CYRILLIC SMALL LETTER ROUND OMEGA;Ll;0;L;;;;;N;;;047A;;047A
+047C;CYRILLIC CAPITAL LETTER OMEGA WITH TITLO;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER OMEGA TITLO;;;047D;
+047D;CYRILLIC SMALL LETTER OMEGA WITH TITLO;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER OMEGA TITLO;;047C;;047C
+047E;CYRILLIC CAPITAL LETTER OT;Lu;0;L;;;;;N;;;;047F;
+047F;CYRILLIC SMALL LETTER OT;Ll;0;L;;;;;N;;;047E;;047E
+0480;CYRILLIC CAPITAL LETTER KOPPA;Lu;0;L;;;;;N;;;;0481;
+0481;CYRILLIC SMALL LETTER KOPPA;Ll;0;L;;;;;N;;;0480;;0480
+0482;CYRILLIC THOUSANDS SIGN;So;0;L;;;;;N;;;;;
+0483;COMBINING CYRILLIC TITLO;Mn;230;NSM;;;;;N;CYRILLIC NON-SPACING TITLO;;;;
+0484;COMBINING CYRILLIC PALATALIZATION;Mn;230;NSM;;;;;N;CYRILLIC NON-SPACING PALATALIZATION;;;;
+0485;COMBINING CYRILLIC DASIA PNEUMATA;Mn;230;NSM;;;;;N;CYRILLIC NON-SPACING DASIA PNEUMATA;;;;
+0486;COMBINING CYRILLIC PSILI PNEUMATA;Mn;230;NSM;;;;;N;CYRILLIC NON-SPACING PSILI PNEUMATA;;;;
+0487;COMBINING CYRILLIC POKRYTIE;Mn;230;NSM;;;;;N;;;;;
+0488;COMBINING CYRILLIC HUNDRED THOUSANDS SIGN;Me;0;NSM;;;;;N;;;;;
+0489;COMBINING CYRILLIC MILLIONS SIGN;Me;0;NSM;;;;;N;;;;;
+048A;CYRILLIC CAPITAL LETTER SHORT I WITH TAIL;Lu;0;L;;;;;N;;;;048B;
+048B;CYRILLIC SMALL LETTER SHORT I WITH TAIL;Ll;0;L;;;;;N;;;048A;;048A
+048C;CYRILLIC CAPITAL LETTER SEMISOFT SIGN;Lu;0;L;;;;;N;;;;048D;
+048D;CYRILLIC SMALL LETTER SEMISOFT SIGN;Ll;0;L;;;;;N;;;048C;;048C
+048E;CYRILLIC CAPITAL LETTER ER WITH TICK;Lu;0;L;;;;;N;;;;048F;
+048F;CYRILLIC SMALL LETTER ER WITH TICK;Ll;0;L;;;;;N;;;048E;;048E
+0490;CYRILLIC CAPITAL LETTER GHE WITH UPTURN;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER GE WITH UPTURN;;;0491;
+0491;CYRILLIC SMALL LETTER GHE WITH UPTURN;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER GE WITH UPTURN;;0490;;0490
+0492;CYRILLIC CAPITAL LETTER GHE WITH STROKE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER GE BAR;;;0493;
+0493;CYRILLIC SMALL LETTER GHE WITH STROKE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER GE BAR;;0492;;0492
+0494;CYRILLIC CAPITAL LETTER GHE WITH MIDDLE HOOK;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER GE HOOK;;;0495;
+0495;CYRILLIC SMALL LETTER GHE WITH MIDDLE HOOK;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER GE HOOK;;0494;;0494
+0496;CYRILLIC CAPITAL LETTER ZHE WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER ZHE WITH RIGHT DESCENDER;;;0497;
+0497;CYRILLIC SMALL LETTER ZHE WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER ZHE WITH RIGHT DESCENDER;;0496;;0496
+0498;CYRILLIC CAPITAL LETTER ZE WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER ZE CEDILLA;;;0499;
+0499;CYRILLIC SMALL LETTER ZE WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER ZE CEDILLA;;0498;;0498
+049A;CYRILLIC CAPITAL LETTER KA WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER KA WITH RIGHT DESCENDER;;;049B;
+049B;CYRILLIC SMALL LETTER KA WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER KA WITH RIGHT DESCENDER;;049A;;049A
+049C;CYRILLIC CAPITAL LETTER KA WITH VERTICAL STROKE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER KA VERTICAL BAR;;;049D;
+049D;CYRILLIC SMALL LETTER KA WITH VERTICAL STROKE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER KA VERTICAL BAR;;049C;;049C
+049E;CYRILLIC CAPITAL LETTER KA WITH STROKE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER KA BAR;;;049F;
+049F;CYRILLIC SMALL LETTER KA WITH STROKE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER KA BAR;;049E;;049E
+04A0;CYRILLIC CAPITAL LETTER BASHKIR KA;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER REVERSED GE KA;;;04A1;
+04A1;CYRILLIC SMALL LETTER BASHKIR KA;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER REVERSED GE KA;;04A0;;04A0
+04A2;CYRILLIC CAPITAL LETTER EN WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER EN WITH RIGHT DESCENDER;;;04A3;
+04A3;CYRILLIC SMALL LETTER EN WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER EN WITH RIGHT DESCENDER;;04A2;;04A2
+04A4;CYRILLIC CAPITAL LIGATURE EN GHE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER EN GE;;;04A5;
+04A5;CYRILLIC SMALL LIGATURE EN GHE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER EN GE;;04A4;;04A4
+04A6;CYRILLIC CAPITAL LETTER PE WITH MIDDLE HOOK;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER PE HOOK;;;04A7;
+04A7;CYRILLIC SMALL LETTER PE WITH MIDDLE HOOK;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER PE HOOK;;04A6;;04A6
+04A8;CYRILLIC CAPITAL LETTER ABKHASIAN HA;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER O HOOK;;;04A9;
+04A9;CYRILLIC SMALL LETTER ABKHASIAN HA;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER O HOOK;;04A8;;04A8
+04AA;CYRILLIC CAPITAL LETTER ES WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER ES CEDILLA;;;04AB;
+04AB;CYRILLIC SMALL LETTER ES WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER ES CEDILLA;;04AA;;04AA
+04AC;CYRILLIC CAPITAL LETTER TE WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER TE WITH RIGHT DESCENDER;;;04AD;
+04AD;CYRILLIC SMALL LETTER TE WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER TE WITH RIGHT DESCENDER;;04AC;;04AC
+04AE;CYRILLIC CAPITAL LETTER STRAIGHT U;Lu;0;L;;;;;N;;;;04AF;
+04AF;CYRILLIC SMALL LETTER STRAIGHT U;Ll;0;L;;;;;N;;;04AE;;04AE
+04B0;CYRILLIC CAPITAL LETTER STRAIGHT U WITH STROKE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER STRAIGHT U BAR;;;04B1;
+04B1;CYRILLIC SMALL LETTER STRAIGHT U WITH STROKE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER STRAIGHT U BAR;;04B0;;04B0
+04B2;CYRILLIC CAPITAL LETTER HA WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER KHA WITH RIGHT DESCENDER;;;04B3;
+04B3;CYRILLIC SMALL LETTER HA WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER KHA WITH RIGHT DESCENDER;;04B2;;04B2
+04B4;CYRILLIC CAPITAL LIGATURE TE TSE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER TE TSE;;;04B5;
+04B5;CYRILLIC SMALL LIGATURE TE TSE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER TE TSE;;04B4;;04B4
+04B6;CYRILLIC CAPITAL LETTER CHE WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER CHE WITH RIGHT DESCENDER;;;04B7;
+04B7;CYRILLIC SMALL LETTER CHE WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER CHE WITH RIGHT DESCENDER;;04B6;;04B6
+04B8;CYRILLIC CAPITAL LETTER CHE WITH VERTICAL STROKE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER CHE VERTICAL BAR;;;04B9;
+04B9;CYRILLIC SMALL LETTER CHE WITH VERTICAL STROKE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER CHE VERTICAL BAR;;04B8;;04B8
+04BA;CYRILLIC CAPITAL LETTER SHHA;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER H;;;04BB;
+04BB;CYRILLIC SMALL LETTER SHHA;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER H;;04BA;;04BA
+04BC;CYRILLIC CAPITAL LETTER ABKHASIAN CHE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER IE HOOK;;;04BD;
+04BD;CYRILLIC SMALL LETTER ABKHASIAN CHE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER IE HOOK;;04BC;;04BC
+04BE;CYRILLIC CAPITAL LETTER ABKHASIAN CHE WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER IE HOOK OGONEK;;;04BF;
+04BF;CYRILLIC SMALL LETTER ABKHASIAN CHE WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER IE HOOK OGONEK;;04BE;;04BE
+04C0;CYRILLIC LETTER PALOCHKA;Lu;0;L;;;;;N;CYRILLIC LETTER I;;;04CF;
+04C1;CYRILLIC CAPITAL LETTER ZHE WITH BREVE;Lu;0;L;0416 0306;;;;N;CYRILLIC CAPITAL LETTER SHORT ZHE;;;04C2;
+04C2;CYRILLIC SMALL LETTER ZHE WITH BREVE;Ll;0;L;0436 0306;;;;N;CYRILLIC SMALL LETTER SHORT ZHE;;04C1;;04C1
+04C3;CYRILLIC CAPITAL LETTER KA WITH HOOK;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER KA HOOK;;;04C4;
+04C4;CYRILLIC SMALL LETTER KA WITH HOOK;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER KA HOOK;;04C3;;04C3
+04C5;CYRILLIC CAPITAL LETTER EL WITH TAIL;Lu;0;L;;;;;N;;;;04C6;
+04C6;CYRILLIC SMALL LETTER EL WITH TAIL;Ll;0;L;;;;;N;;;04C5;;04C5
+04C7;CYRILLIC CAPITAL LETTER EN WITH HOOK;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER EN HOOK;;;04C8;
+04C8;CYRILLIC SMALL LETTER EN WITH HOOK;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER EN HOOK;;04C7;;04C7
+04C9;CYRILLIC CAPITAL LETTER EN WITH TAIL;Lu;0;L;;;;;N;;;;04CA;
+04CA;CYRILLIC SMALL LETTER EN WITH TAIL;Ll;0;L;;;;;N;;;04C9;;04C9
+04CB;CYRILLIC CAPITAL LETTER KHAKASSIAN CHE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER CHE WITH LEFT DESCENDER;;;04CC;
+04CC;CYRILLIC SMALL LETTER KHAKASSIAN CHE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER CHE WITH LEFT DESCENDER;;04CB;;04CB
+04CD;CYRILLIC CAPITAL LETTER EM WITH TAIL;Lu;0;L;;;;;N;;;;04CE;
+04CE;CYRILLIC SMALL LETTER EM WITH TAIL;Ll;0;L;;;;;N;;;04CD;;04CD
+04CF;CYRILLIC SMALL LETTER PALOCHKA;Ll;0;L;;;;;N;;;04C0;;04C0
+04D0;CYRILLIC CAPITAL LETTER A WITH BREVE;Lu;0;L;0410 0306;;;;N;;;;04D1;
+04D1;CYRILLIC SMALL LETTER A WITH BREVE;Ll;0;L;0430 0306;;;;N;;;04D0;;04D0
+04D2;CYRILLIC CAPITAL LETTER A WITH DIAERESIS;Lu;0;L;0410 0308;;;;N;;;;04D3;
+04D3;CYRILLIC SMALL LETTER A WITH DIAERESIS;Ll;0;L;0430 0308;;;;N;;;04D2;;04D2
+04D4;CYRILLIC CAPITAL LIGATURE A IE;Lu;0;L;;;;;N;;;;04D5;
+04D5;CYRILLIC SMALL LIGATURE A IE;Ll;0;L;;;;;N;;;04D4;;04D4
+04D6;CYRILLIC CAPITAL LETTER IE WITH BREVE;Lu;0;L;0415 0306;;;;N;;;;04D7;
+04D7;CYRILLIC SMALL LETTER IE WITH BREVE;Ll;0;L;0435 0306;;;;N;;;04D6;;04D6
+04D8;CYRILLIC CAPITAL LETTER SCHWA;Lu;0;L;;;;;N;;;;04D9;
+04D9;CYRILLIC SMALL LETTER SCHWA;Ll;0;L;;;;;N;;;04D8;;04D8
+04DA;CYRILLIC CAPITAL LETTER SCHWA WITH DIAERESIS;Lu;0;L;04D8 0308;;;;N;;;;04DB;
+04DB;CYRILLIC SMALL LETTER SCHWA WITH DIAERESIS;Ll;0;L;04D9 0308;;;;N;;;04DA;;04DA
+04DC;CYRILLIC CAPITAL LETTER ZHE WITH DIAERESIS;Lu;0;L;0416 0308;;;;N;;;;04DD;
+04DD;CYRILLIC SMALL LETTER ZHE WITH DIAERESIS;Ll;0;L;0436 0308;;;;N;;;04DC;;04DC
+04DE;CYRILLIC CAPITAL LETTER ZE WITH DIAERESIS;Lu;0;L;0417 0308;;;;N;;;;04DF;
+04DF;CYRILLIC SMALL LETTER ZE WITH DIAERESIS;Ll;0;L;0437 0308;;;;N;;;04DE;;04DE
+04E0;CYRILLIC CAPITAL LETTER ABKHASIAN DZE;Lu;0;L;;;;;N;;;;04E1;
+04E1;CYRILLIC SMALL LETTER ABKHASIAN DZE;Ll;0;L;;;;;N;;;04E0;;04E0
+04E2;CYRILLIC CAPITAL LETTER I WITH MACRON;Lu;0;L;0418 0304;;;;N;;;;04E3;
+04E3;CYRILLIC SMALL LETTER I WITH MACRON;Ll;0;L;0438 0304;;;;N;;;04E2;;04E2
+04E4;CYRILLIC CAPITAL LETTER I WITH DIAERESIS;Lu;0;L;0418 0308;;;;N;;;;04E5;
+04E5;CYRILLIC SMALL LETTER I WITH DIAERESIS;Ll;0;L;0438 0308;;;;N;;;04E4;;04E4
+04E6;CYRILLIC CAPITAL LETTER O WITH DIAERESIS;Lu;0;L;041E 0308;;;;N;;;;04E7;
+04E7;CYRILLIC SMALL LETTER O WITH DIAERESIS;Ll;0;L;043E 0308;;;;N;;;04E6;;04E6
+04E8;CYRILLIC CAPITAL LETTER BARRED O;Lu;0;L;;;;;N;;;;04E9;
+04E9;CYRILLIC SMALL LETTER BARRED O;Ll;0;L;;;;;N;;;04E8;;04E8
+04EA;CYRILLIC CAPITAL LETTER BARRED O WITH DIAERESIS;Lu;0;L;04E8 0308;;;;N;;;;04EB;
+04EB;CYRILLIC SMALL LETTER BARRED O WITH DIAERESIS;Ll;0;L;04E9 0308;;;;N;;;04EA;;04EA
+04EC;CYRILLIC CAPITAL LETTER E WITH DIAERESIS;Lu;0;L;042D 0308;;;;N;;;;04ED;
+04ED;CYRILLIC SMALL LETTER E WITH DIAERESIS;Ll;0;L;044D 0308;;;;N;;;04EC;;04EC
+04EE;CYRILLIC CAPITAL LETTER U WITH MACRON;Lu;0;L;0423 0304;;;;N;;;;04EF;
+04EF;CYRILLIC SMALL LETTER U WITH MACRON;Ll;0;L;0443 0304;;;;N;;;04EE;;04EE
+04F0;CYRILLIC CAPITAL LETTER U WITH DIAERESIS;Lu;0;L;0423 0308;;;;N;;;;04F1;
+04F1;CYRILLIC SMALL LETTER U WITH DIAERESIS;Ll;0;L;0443 0308;;;;N;;;04F0;;04F0
+04F2;CYRILLIC CAPITAL LETTER U WITH DOUBLE ACUTE;Lu;0;L;0423 030B;;;;N;;;;04F3;
+04F3;CYRILLIC SMALL LETTER U WITH DOUBLE ACUTE;Ll;0;L;0443 030B;;;;N;;;04F2;;04F2
+04F4;CYRILLIC CAPITAL LETTER CHE WITH DIAERESIS;Lu;0;L;0427 0308;;;;N;;;;04F5;
+04F5;CYRILLIC SMALL LETTER CHE WITH DIAERESIS;Ll;0;L;0447 0308;;;;N;;;04F4;;04F4
+04F6;CYRILLIC CAPITAL LETTER GHE WITH DESCENDER;Lu;0;L;;;;;N;;;;04F7;
+04F7;CYRILLIC SMALL LETTER GHE WITH DESCENDER;Ll;0;L;;;;;N;;;04F6;;04F6
+04F8;CYRILLIC CAPITAL LETTER YERU WITH DIAERESIS;Lu;0;L;042B 0308;;;;N;;;;04F9;
+04F9;CYRILLIC SMALL LETTER YERU WITH DIAERESIS;Ll;0;L;044B 0308;;;;N;;;04F8;;04F8
+04FA;CYRILLIC CAPITAL LETTER GHE WITH STROKE AND HOOK;Lu;0;L;;;;;N;;;;04FB;
+04FB;CYRILLIC SMALL LETTER GHE WITH STROKE AND HOOK;Ll;0;L;;;;;N;;;04FA;;04FA
+04FC;CYRILLIC CAPITAL LETTER HA WITH HOOK;Lu;0;L;;;;;N;;;;04FD;
+04FD;CYRILLIC SMALL LETTER HA WITH HOOK;Ll;0;L;;;;;N;;;04FC;;04FC
+04FE;CYRILLIC CAPITAL LETTER HA WITH STROKE;Lu;0;L;;;;;N;;;;04FF;
+04FF;CYRILLIC SMALL LETTER HA WITH STROKE;Ll;0;L;;;;;N;;;04FE;;04FE
+0500;CYRILLIC CAPITAL LETTER KOMI DE;Lu;0;L;;;;;N;;;;0501;
+0501;CYRILLIC SMALL LETTER KOMI DE;Ll;0;L;;;;;N;;;0500;;0500
+0502;CYRILLIC CAPITAL LETTER KOMI DJE;Lu;0;L;;;;;N;;;;0503;
+0503;CYRILLIC SMALL LETTER KOMI DJE;Ll;0;L;;;;;N;;;0502;;0502
+0504;CYRILLIC CAPITAL LETTER KOMI ZJE;Lu;0;L;;;;;N;;;;0505;
+0505;CYRILLIC SMALL LETTER KOMI ZJE;Ll;0;L;;;;;N;;;0504;;0504
+0506;CYRILLIC CAPITAL LETTER KOMI DZJE;Lu;0;L;;;;;N;;;;0507;
+0507;CYRILLIC SMALL LETTER KOMI DZJE;Ll;0;L;;;;;N;;;0506;;0506
+0508;CYRILLIC CAPITAL LETTER KOMI LJE;Lu;0;L;;;;;N;;;;0509;
+0509;CYRILLIC SMALL LETTER KOMI LJE;Ll;0;L;;;;;N;;;0508;;0508
+050A;CYRILLIC CAPITAL LETTER KOMI NJE;Lu;0;L;;;;;N;;;;050B;
+050B;CYRILLIC SMALL LETTER KOMI NJE;Ll;0;L;;;;;N;;;050A;;050A
+050C;CYRILLIC CAPITAL LETTER KOMI SJE;Lu;0;L;;;;;N;;;;050D;
+050D;CYRILLIC SMALL LETTER KOMI SJE;Ll;0;L;;;;;N;;;050C;;050C
+050E;CYRILLIC CAPITAL LETTER KOMI TJE;Lu;0;L;;;;;N;;;;050F;
+050F;CYRILLIC SMALL LETTER KOMI TJE;Ll;0;L;;;;;N;;;050E;;050E
+0510;CYRILLIC CAPITAL LETTER REVERSED ZE;Lu;0;L;;;;;N;;;;0511;
+0511;CYRILLIC SMALL LETTER REVERSED ZE;Ll;0;L;;;;;N;;;0510;;0510
+0512;CYRILLIC CAPITAL LETTER EL WITH HOOK;Lu;0;L;;;;;N;;;;0513;
+0513;CYRILLIC SMALL LETTER EL WITH HOOK;Ll;0;L;;;;;N;;;0512;;0512
+0514;CYRILLIC CAPITAL LETTER LHA;Lu;0;L;;;;;N;;;;0515;
+0515;CYRILLIC SMALL LETTER LHA;Ll;0;L;;;;;N;;;0514;;0514
+0516;CYRILLIC CAPITAL LETTER RHA;Lu;0;L;;;;;N;;;;0517;
+0517;CYRILLIC SMALL LETTER RHA;Ll;0;L;;;;;N;;;0516;;0516
+0518;CYRILLIC CAPITAL LETTER YAE;Lu;0;L;;;;;N;;;;0519;
+0519;CYRILLIC SMALL LETTER YAE;Ll;0;L;;;;;N;;;0518;;0518
+051A;CYRILLIC CAPITAL LETTER QA;Lu;0;L;;;;;N;;;;051B;
+051B;CYRILLIC SMALL LETTER QA;Ll;0;L;;;;;N;;;051A;;051A
+051C;CYRILLIC CAPITAL LETTER WE;Lu;0;L;;;;;N;;;;051D;
+051D;CYRILLIC SMALL LETTER WE;Ll;0;L;;;;;N;;;051C;;051C
+051E;CYRILLIC CAPITAL LETTER ALEUT KA;Lu;0;L;;;;;N;;;;051F;
+051F;CYRILLIC SMALL LETTER ALEUT KA;Ll;0;L;;;;;N;;;051E;;051E
+0520;CYRILLIC CAPITAL LETTER EL WITH MIDDLE HOOK;Lu;0;L;;;;;N;;;;0521;
+0521;CYRILLIC SMALL LETTER EL WITH MIDDLE HOOK;Ll;0;L;;;;;N;;;0520;;0520
+0522;CYRILLIC CAPITAL LETTER EN WITH MIDDLE HOOK;Lu;0;L;;;;;N;;;;0523;
+0523;CYRILLIC SMALL LETTER EN WITH MIDDLE HOOK;Ll;0;L;;;;;N;;;0522;;0522
+0524;CYRILLIC CAPITAL LETTER PE WITH DESCENDER;Lu;0;L;;;;;N;;;;0525;
+0525;CYRILLIC SMALL LETTER PE WITH DESCENDER;Ll;0;L;;;;;N;;;0524;;0524
+0526;CYRILLIC CAPITAL LETTER SHHA WITH DESCENDER;Lu;0;L;;;;;N;;;;0527;
+0527;CYRILLIC SMALL LETTER SHHA WITH DESCENDER;Ll;0;L;;;;;N;;;0526;;0526
+0531;ARMENIAN CAPITAL LETTER AYB;Lu;0;L;;;;;N;;;;0561;
+0532;ARMENIAN CAPITAL LETTER BEN;Lu;0;L;;;;;N;;;;0562;
+0533;ARMENIAN CAPITAL LETTER GIM;Lu;0;L;;;;;N;;;;0563;
+0534;ARMENIAN CAPITAL LETTER DA;Lu;0;L;;;;;N;;;;0564;
+0535;ARMENIAN CAPITAL LETTER ECH;Lu;0;L;;;;;N;;;;0565;
+0536;ARMENIAN CAPITAL LETTER ZA;Lu;0;L;;;;;N;;;;0566;
+0537;ARMENIAN CAPITAL LETTER EH;Lu;0;L;;;;;N;;;;0567;
+0538;ARMENIAN CAPITAL LETTER ET;Lu;0;L;;;;;N;;;;0568;
+0539;ARMENIAN CAPITAL LETTER TO;Lu;0;L;;;;;N;;;;0569;
+053A;ARMENIAN CAPITAL LETTER ZHE;Lu;0;L;;;;;N;;;;056A;
+053B;ARMENIAN CAPITAL LETTER INI;Lu;0;L;;;;;N;;;;056B;
+053C;ARMENIAN CAPITAL LETTER LIWN;Lu;0;L;;;;;N;;;;056C;
+053D;ARMENIAN CAPITAL LETTER XEH;Lu;0;L;;;;;N;;;;056D;
+053E;ARMENIAN CAPITAL LETTER CA;Lu;0;L;;;;;N;;;;056E;
+053F;ARMENIAN CAPITAL LETTER KEN;Lu;0;L;;;;;N;;;;056F;
+0540;ARMENIAN CAPITAL LETTER HO;Lu;0;L;;;;;N;;;;0570;
+0541;ARMENIAN CAPITAL LETTER JA;Lu;0;L;;;;;N;;;;0571;
+0542;ARMENIAN CAPITAL LETTER GHAD;Lu;0;L;;;;;N;ARMENIAN CAPITAL LETTER LAD;;;0572;
+0543;ARMENIAN CAPITAL LETTER CHEH;Lu;0;L;;;;;N;;;;0573;
+0544;ARMENIAN CAPITAL LETTER MEN;Lu;0;L;;;;;N;;;;0574;
+0545;ARMENIAN CAPITAL LETTER YI;Lu;0;L;;;;;N;;;;0575;
+0546;ARMENIAN CAPITAL LETTER NOW;Lu;0;L;;;;;N;;;;0576;
+0547;ARMENIAN CAPITAL LETTER SHA;Lu;0;L;;;;;N;;;;0577;
+0548;ARMENIAN CAPITAL LETTER VO;Lu;0;L;;;;;N;;;;0578;
+0549;ARMENIAN CAPITAL LETTER CHA;Lu;0;L;;;;;N;;;;0579;
+054A;ARMENIAN CAPITAL LETTER PEH;Lu;0;L;;;;;N;;;;057A;
+054B;ARMENIAN CAPITAL LETTER JHEH;Lu;0;L;;;;;N;;;;057B;
+054C;ARMENIAN CAPITAL LETTER RA;Lu;0;L;;;;;N;;;;057C;
+054D;ARMENIAN CAPITAL LETTER SEH;Lu;0;L;;;;;N;;;;057D;
+054E;ARMENIAN CAPITAL LETTER VEW;Lu;0;L;;;;;N;;;;057E;
+054F;ARMENIAN CAPITAL LETTER TIWN;Lu;0;L;;;;;N;;;;057F;
+0550;ARMENIAN CAPITAL LETTER REH;Lu;0;L;;;;;N;;;;0580;
+0551;ARMENIAN CAPITAL LETTER CO;Lu;0;L;;;;;N;;;;0581;
+0552;ARMENIAN CAPITAL LETTER YIWN;Lu;0;L;;;;;N;;;;0582;
+0553;ARMENIAN CAPITAL LETTER PIWR;Lu;0;L;;;;;N;;;;0583;
+0554;ARMENIAN CAPITAL LETTER KEH;Lu;0;L;;;;;N;;;;0584;
+0555;ARMENIAN CAPITAL LETTER OH;Lu;0;L;;;;;N;;;;0585;
+0556;ARMENIAN CAPITAL LETTER FEH;Lu;0;L;;;;;N;;;;0586;
+0559;ARMENIAN MODIFIER LETTER LEFT HALF RING;Lm;0;L;;;;;N;;;;;
+055A;ARMENIAN APOSTROPHE;Po;0;L;;;;;N;ARMENIAN MODIFIER LETTER RIGHT HALF RING;;;;
+055B;ARMENIAN EMPHASIS MARK;Po;0;L;;;;;N;;;;;
+055C;ARMENIAN EXCLAMATION MARK;Po;0;L;;;;;N;;;;;
+055D;ARMENIAN COMMA;Po;0;L;;;;;N;;;;;
+055E;ARMENIAN QUESTION MARK;Po;0;L;;;;;N;;;;;
+055F;ARMENIAN ABBREVIATION MARK;Po;0;L;;;;;N;;;;;
+0561;ARMENIAN SMALL LETTER AYB;Ll;0;L;;;;;N;;;0531;;0531
+0562;ARMENIAN SMALL LETTER BEN;Ll;0;L;;;;;N;;;0532;;0532
+0563;ARMENIAN SMALL LETTER GIM;Ll;0;L;;;;;N;;;0533;;0533
+0564;ARMENIAN SMALL LETTER DA;Ll;0;L;;;;;N;;;0534;;0534
+0565;ARMENIAN SMALL LETTER ECH;Ll;0;L;;;;;N;;;0535;;0535
+0566;ARMENIAN SMALL LETTER ZA;Ll;0;L;;;;;N;;;0536;;0536
+0567;ARMENIAN SMALL LETTER EH;Ll;0;L;;;;;N;;;0537;;0537
+0568;ARMENIAN SMALL LETTER ET;Ll;0;L;;;;;N;;;0538;;0538
+0569;ARMENIAN SMALL LETTER TO;Ll;0;L;;;;;N;;;0539;;0539
+056A;ARMENIAN SMALL LETTER ZHE;Ll;0;L;;;;;N;;;053A;;053A
+056B;ARMENIAN SMALL LETTER INI;Ll;0;L;;;;;N;;;053B;;053B
+056C;ARMENIAN SMALL LETTER LIWN;Ll;0;L;;;;;N;;;053C;;053C
+056D;ARMENIAN SMALL LETTER XEH;Ll;0;L;;;;;N;;;053D;;053D
+056E;ARMENIAN SMALL LETTER CA;Ll;0;L;;;;;N;;;053E;;053E
+056F;ARMENIAN SMALL LETTER KEN;Ll;0;L;;;;;N;;;053F;;053F
+0570;ARMENIAN SMALL LETTER HO;Ll;0;L;;;;;N;;;0540;;0540
+0571;ARMENIAN SMALL LETTER JA;Ll;0;L;;;;;N;;;0541;;0541
+0572;ARMENIAN SMALL LETTER GHAD;Ll;0;L;;;;;N;ARMENIAN SMALL LETTER LAD;;0542;;0542
+0573;ARMENIAN SMALL LETTER CHEH;Ll;0;L;;;;;N;;;0543;;0543
+0574;ARMENIAN SMALL LETTER MEN;Ll;0;L;;;;;N;;;0544;;0544
+0575;ARMENIAN SMALL LETTER YI;Ll;0;L;;;;;N;;;0545;;0545
+0576;ARMENIAN SMALL LETTER NOW;Ll;0;L;;;;;N;;;0546;;0546
+0577;ARMENIAN SMALL LETTER SHA;Ll;0;L;;;;;N;;;0547;;0547
+0578;ARMENIAN SMALL LETTER VO;Ll;0;L;;;;;N;;;0548;;0548
+0579;ARMENIAN SMALL LETTER CHA;Ll;0;L;;;;;N;;;0549;;0549
+057A;ARMENIAN SMALL LETTER PEH;Ll;0;L;;;;;N;;;054A;;054A
+057B;ARMENIAN SMALL LETTER JHEH;Ll;0;L;;;;;N;;;054B;;054B
+057C;ARMENIAN SMALL LETTER RA;Ll;0;L;;;;;N;;;054C;;054C
+057D;ARMENIAN SMALL LETTER SEH;Ll;0;L;;;;;N;;;054D;;054D
+057E;ARMENIAN SMALL LETTER VEW;Ll;0;L;;;;;N;;;054E;;054E
+057F;ARMENIAN SMALL LETTER TIWN;Ll;0;L;;;;;N;;;054F;;054F
+0580;ARMENIAN SMALL LETTER REH;Ll;0;L;;;;;N;;;0550;;0550
+0581;ARMENIAN SMALL LETTER CO;Ll;0;L;;;;;N;;;0551;;0551
+0582;ARMENIAN SMALL LETTER YIWN;Ll;0;L;;;;;N;;;0552;;0552
+0583;ARMENIAN SMALL LETTER PIWR;Ll;0;L;;;;;N;;;0553;;0553
+0584;ARMENIAN SMALL LETTER KEH;Ll;0;L;;;;;N;;;0554;;0554
+0585;ARMENIAN SMALL LETTER OH;Ll;0;L;;;;;N;;;0555;;0555
+0586;ARMENIAN SMALL LETTER FEH;Ll;0;L;;;;;N;;;0556;;0556
+0587;ARMENIAN SMALL LIGATURE ECH YIWN;Ll;0;L;<compat> 0565 0582;;;;N;;;;;
+0589;ARMENIAN FULL STOP;Po;0;L;;;;;N;ARMENIAN PERIOD;;;;
+058A;ARMENIAN HYPHEN;Pd;0;ON;;;;;N;;;;;
+0591;HEBREW ACCENT ETNAHTA;Mn;220;NSM;;;;;N;;;;;
+0592;HEBREW ACCENT SEGOL;Mn;230;NSM;;;;;N;;;;;
+0593;HEBREW ACCENT SHALSHELET;Mn;230;NSM;;;;;N;;;;;
+0594;HEBREW ACCENT ZAQEF QATAN;Mn;230;NSM;;;;;N;;;;;
+0595;HEBREW ACCENT ZAQEF GADOL;Mn;230;NSM;;;;;N;;;;;
+0596;HEBREW ACCENT TIPEHA;Mn;220;NSM;;;;;N;;;;;
+0597;HEBREW ACCENT REVIA;Mn;230;NSM;;;;;N;;;;;
+0598;HEBREW ACCENT ZARQA;Mn;230;NSM;;;;;N;;;;;
+0599;HEBREW ACCENT PASHTA;Mn;230;NSM;;;;;N;;;;;
+059A;HEBREW ACCENT YETIV;Mn;222;NSM;;;;;N;;;;;
+059B;HEBREW ACCENT TEVIR;Mn;220;NSM;;;;;N;;;;;
+059C;HEBREW ACCENT GERESH;Mn;230;NSM;;;;;N;;;;;
+059D;HEBREW ACCENT GERESH MUQDAM;Mn;230;NSM;;;;;N;;;;;
+059E;HEBREW ACCENT GERSHAYIM;Mn;230;NSM;;;;;N;;;;;
+059F;HEBREW ACCENT QARNEY PARA;Mn;230;NSM;;;;;N;;;;;
+05A0;HEBREW ACCENT TELISHA GEDOLA;Mn;230;NSM;;;;;N;;;;;
+05A1;HEBREW ACCENT PAZER;Mn;230;NSM;;;;;N;;;;;
+05A2;HEBREW ACCENT ATNAH HAFUKH;Mn;220;NSM;;;;;N;;;;;
+05A3;HEBREW ACCENT MUNAH;Mn;220;NSM;;;;;N;;;;;
+05A4;HEBREW ACCENT MAHAPAKH;Mn;220;NSM;;;;;N;;;;;
+05A5;HEBREW ACCENT MERKHA;Mn;220;NSM;;;;;N;;;;;
+05A6;HEBREW ACCENT MERKHA KEFULA;Mn;220;NSM;;;;;N;;;;;
+05A7;HEBREW ACCENT DARGA;Mn;220;NSM;;;;;N;;;;;
+05A8;HEBREW ACCENT QADMA;Mn;230;NSM;;;;;N;;;;;
+05A9;HEBREW ACCENT TELISHA QETANA;Mn;230;NSM;;;;;N;;;;;
+05AA;HEBREW ACCENT YERAH BEN YOMO;Mn;220;NSM;;;;;N;;;;;
+05AB;HEBREW ACCENT OLE;Mn;230;NSM;;;;;N;;;;;
+05AC;HEBREW ACCENT ILUY;Mn;230;NSM;;;;;N;;;;;
+05AD;HEBREW ACCENT DEHI;Mn;222;NSM;;;;;N;;;;;
+05AE;HEBREW ACCENT ZINOR;Mn;228;NSM;;;;;N;;;;;
+05AF;HEBREW MARK MASORA CIRCLE;Mn;230;NSM;;;;;N;;;;;
+05B0;HEBREW POINT SHEVA;Mn;10;NSM;;;;;N;;;;;
+05B1;HEBREW POINT HATAF SEGOL;Mn;11;NSM;;;;;N;;;;;
+05B2;HEBREW POINT HATAF PATAH;Mn;12;NSM;;;;;N;;;;;
+05B3;HEBREW POINT HATAF QAMATS;Mn;13;NSM;;;;;N;;;;;
+05B4;HEBREW POINT HIRIQ;Mn;14;NSM;;;;;N;;;;;
+05B5;HEBREW POINT TSERE;Mn;15;NSM;;;;;N;;;;;
+05B6;HEBREW POINT SEGOL;Mn;16;NSM;;;;;N;;;;;
+05B7;HEBREW POINT PATAH;Mn;17;NSM;;;;;N;;;;;
+05B8;HEBREW POINT QAMATS;Mn;18;NSM;;;;;N;;;;;
+05B9;HEBREW POINT HOLAM;Mn;19;NSM;;;;;N;;;;;
+05BA;HEBREW POINT HOLAM HASER FOR VAV;Mn;19;NSM;;;;;N;;;;;
+05BB;HEBREW POINT QUBUTS;Mn;20;NSM;;;;;N;;;;;
+05BC;HEBREW POINT DAGESH OR MAPIQ;Mn;21;NSM;;;;;N;HEBREW POINT DAGESH;;;;
+05BD;HEBREW POINT METEG;Mn;22;NSM;;;;;N;;;;;
+05BE;HEBREW PUNCTUATION MAQAF;Pd;0;R;;;;;N;;;;;
+05BF;HEBREW POINT RAFE;Mn;23;NSM;;;;;N;;;;;
+05C0;HEBREW PUNCTUATION PASEQ;Po;0;R;;;;;N;HEBREW POINT PASEQ;;;;
+05C1;HEBREW POINT SHIN DOT;Mn;24;NSM;;;;;N;;;;;
+05C2;HEBREW POINT SIN DOT;Mn;25;NSM;;;;;N;;;;;
+05C3;HEBREW PUNCTUATION SOF PASUQ;Po;0;R;;;;;N;;;;;
+05C4;HEBREW MARK UPPER DOT;Mn;230;NSM;;;;;N;;;;;
+05C5;HEBREW MARK LOWER DOT;Mn;220;NSM;;;;;N;;;;;
+05C6;HEBREW PUNCTUATION NUN HAFUKHA;Po;0;R;;;;;N;;;;;
+05C7;HEBREW POINT QAMATS QATAN;Mn;18;NSM;;;;;N;;;;;
+05D0;HEBREW LETTER ALEF;Lo;0;R;;;;;N;;;;;
+05D1;HEBREW LETTER BET;Lo;0;R;;;;;N;;;;;
+05D2;HEBREW LETTER GIMEL;Lo;0;R;;;;;N;;;;;
+05D3;HEBREW LETTER DALET;Lo;0;R;;;;;N;;;;;
+05D4;HEBREW LETTER HE;Lo;0;R;;;;;N;;;;;
+05D5;HEBREW LETTER VAV;Lo;0;R;;;;;N;;;;;
+05D6;HEBREW LETTER ZAYIN;Lo;0;R;;;;;N;;;;;
+05D7;HEBREW LETTER HET;Lo;0;R;;;;;N;;;;;
+05D8;HEBREW LETTER TET;Lo;0;R;;;;;N;;;;;
+05D9;HEBREW LETTER YOD;Lo;0;R;;;;;N;;;;;
+05DA;HEBREW LETTER FINAL KAF;Lo;0;R;;;;;N;;;;;
+05DB;HEBREW LETTER KAF;Lo;0;R;;;;;N;;;;;
+05DC;HEBREW LETTER LAMED;Lo;0;R;;;;;N;;;;;
+05DD;HEBREW LETTER FINAL MEM;Lo;0;R;;;;;N;;;;;
+05DE;HEBREW LETTER MEM;Lo;0;R;;;;;N;;;;;
+05DF;HEBREW LETTER FINAL NUN;Lo;0;R;;;;;N;;;;;
+05E0;HEBREW LETTER NUN;Lo;0;R;;;;;N;;;;;
+05E1;HEBREW LETTER SAMEKH;Lo;0;R;;;;;N;;;;;
+05E2;HEBREW LETTER AYIN;Lo;0;R;;;;;N;;;;;
+05E3;HEBREW LETTER FINAL PE;Lo;0;R;;;;;N;;;;;
+05E4;HEBREW LETTER PE;Lo;0;R;;;;;N;;;;;
+05E5;HEBREW LETTER FINAL TSADI;Lo;0;R;;;;;N;;;;;
+05E6;HEBREW LETTER TSADI;Lo;0;R;;;;;N;;;;;
+05E7;HEBREW LETTER QOF;Lo;0;R;;;;;N;;;;;
+05E8;HEBREW LETTER RESH;Lo;0;R;;;;;N;;;;;
+05E9;HEBREW LETTER SHIN;Lo;0;R;;;;;N;;;;;
+05EA;HEBREW LETTER TAV;Lo;0;R;;;;;N;;;;;
+05F0;HEBREW LIGATURE YIDDISH DOUBLE VAV;Lo;0;R;;;;;N;HEBREW LETTER DOUBLE VAV;;;;
+05F1;HEBREW LIGATURE YIDDISH VAV YOD;Lo;0;R;;;;;N;HEBREW LETTER VAV YOD;;;;
+05F2;HEBREW LIGATURE YIDDISH DOUBLE YOD;Lo;0;R;;;;;N;HEBREW LETTER DOUBLE YOD;;;;
+05F3;HEBREW PUNCTUATION GERESH;Po;0;R;;;;;N;;;;;
+05F4;HEBREW PUNCTUATION GERSHAYIM;Po;0;R;;;;;N;;;;;
+0600;ARABIC NUMBER SIGN;Cf;0;AN;;;;;N;;;;;
+0601;ARABIC SIGN SANAH;Cf;0;AN;;;;;N;;;;;
+0602;ARABIC FOOTNOTE MARKER;Cf;0;AN;;;;;N;;;;;
+0603;ARABIC SIGN SAFHA;Cf;0;AN;;;;;N;;;;;
+0606;ARABIC-INDIC CUBE ROOT;Sm;0;ON;;;;;N;;;;;
+0607;ARABIC-INDIC FOURTH ROOT;Sm;0;ON;;;;;N;;;;;
+0608;ARABIC RAY;Sm;0;AL;;;;;N;;;;;
+0609;ARABIC-INDIC PER MILLE SIGN;Po;0;ET;;;;;N;;;;;
+060A;ARABIC-INDIC PER TEN THOUSAND SIGN;Po;0;ET;;;;;N;;;;;
+060B;AFGHANI SIGN;Sc;0;AL;;;;;N;;;;;
+060C;ARABIC COMMA;Po;0;CS;;;;;N;;;;;
+060D;ARABIC DATE SEPARATOR;Po;0;AL;;;;;N;;;;;
+060E;ARABIC POETIC VERSE SIGN;So;0;ON;;;;;N;;;;;
+060F;ARABIC SIGN MISRA;So;0;ON;;;;;N;;;;;
+0610;ARABIC SIGN SALLALLAHOU ALAYHE WASSALLAM;Mn;230;NSM;;;;;N;;;;;
+0611;ARABIC SIGN ALAYHE ASSALLAM;Mn;230;NSM;;;;;N;;;;;
+0612;ARABIC SIGN RAHMATULLAH ALAYHE;Mn;230;NSM;;;;;N;;;;;
+0613;ARABIC SIGN RADI ALLAHOU ANHU;Mn;230;NSM;;;;;N;;;;;
+0614;ARABIC SIGN TAKHALLUS;Mn;230;NSM;;;;;N;;;;;
+0615;ARABIC SMALL HIGH TAH;Mn;230;NSM;;;;;N;;;;;
+0616;ARABIC SMALL HIGH LIGATURE ALEF WITH LAM WITH YEH;Mn;230;NSM;;;;;N;;;;;
+0617;ARABIC SMALL HIGH ZAIN;Mn;230;NSM;;;;;N;;;;;
+0618;ARABIC SMALL FATHA;Mn;30;NSM;;;;;N;;;;;
+0619;ARABIC SMALL DAMMA;Mn;31;NSM;;;;;N;;;;;
+061A;ARABIC SMALL KASRA;Mn;32;NSM;;;;;N;;;;;
+061B;ARABIC SEMICOLON;Po;0;AL;;;;;N;;;;;
+061E;ARABIC TRIPLE DOT PUNCTUATION MARK;Po;0;AL;;;;;N;;;;;
+061F;ARABIC QUESTION MARK;Po;0;AL;;;;;N;;;;;
+0620;ARABIC LETTER KASHMIRI YEH;Lo;0;AL;;;;;N;;;;;
+0621;ARABIC LETTER HAMZA;Lo;0;AL;;;;;N;ARABIC LETTER HAMZAH;;;;
+0622;ARABIC LETTER ALEF WITH MADDA ABOVE;Lo;0;AL;0627 0653;;;;N;ARABIC LETTER MADDAH ON ALEF;;;;
+0623;ARABIC LETTER ALEF WITH HAMZA ABOVE;Lo;0;AL;0627 0654;;;;N;ARABIC LETTER HAMZAH ON ALEF;;;;
+0624;ARABIC LETTER WAW WITH HAMZA ABOVE;Lo;0;AL;0648 0654;;;;N;ARABIC LETTER HAMZAH ON WAW;;;;
+0625;ARABIC LETTER ALEF WITH HAMZA BELOW;Lo;0;AL;0627 0655;;;;N;ARABIC LETTER HAMZAH UNDER ALEF;;;;
+0626;ARABIC LETTER YEH WITH HAMZA ABOVE;Lo;0;AL;064A 0654;;;;N;ARABIC LETTER HAMZAH ON YA;;;;
+0627;ARABIC LETTER ALEF;Lo;0;AL;;;;;N;;;;;
+0628;ARABIC LETTER BEH;Lo;0;AL;;;;;N;ARABIC LETTER BAA;;;;
+0629;ARABIC LETTER TEH MARBUTA;Lo;0;AL;;;;;N;ARABIC LETTER TAA MARBUTAH;;;;
+062A;ARABIC LETTER TEH;Lo;0;AL;;;;;N;ARABIC LETTER TAA;;;;
+062B;ARABIC LETTER THEH;Lo;0;AL;;;;;N;ARABIC LETTER THAA;;;;
+062C;ARABIC LETTER JEEM;Lo;0;AL;;;;;N;;;;;
+062D;ARABIC LETTER HAH;Lo;0;AL;;;;;N;ARABIC LETTER HAA;;;;
+062E;ARABIC LETTER KHAH;Lo;0;AL;;;;;N;ARABIC LETTER KHAA;;;;
+062F;ARABIC LETTER DAL;Lo;0;AL;;;;;N;;;;;
+0630;ARABIC LETTER THAL;Lo;0;AL;;;;;N;;;;;
+0631;ARABIC LETTER REH;Lo;0;AL;;;;;N;ARABIC LETTER RA;;;;
+0632;ARABIC LETTER ZAIN;Lo;0;AL;;;;;N;;;;;
+0633;ARABIC LETTER SEEN;Lo;0;AL;;;;;N;;;;;
+0634;ARABIC LETTER SHEEN;Lo;0;AL;;;;;N;;;;;
+0635;ARABIC LETTER SAD;Lo;0;AL;;;;;N;;;;;
+0636;ARABIC LETTER DAD;Lo;0;AL;;;;;N;;;;;
+0637;ARABIC LETTER TAH;Lo;0;AL;;;;;N;;;;;
+0638;ARABIC LETTER ZAH;Lo;0;AL;;;;;N;ARABIC LETTER DHAH;;;;
+0639;ARABIC LETTER AIN;Lo;0;AL;;;;;N;;;;;
+063A;ARABIC LETTER GHAIN;Lo;0;AL;;;;;N;;;;;
+063B;ARABIC LETTER KEHEH WITH TWO DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
+063C;ARABIC LETTER KEHEH WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;;;;;
+063D;ARABIC LETTER FARSI YEH WITH INVERTED V;Lo;0;AL;;;;;N;;;;;
+063E;ARABIC LETTER FARSI YEH WITH TWO DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
+063F;ARABIC LETTER FARSI YEH WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
+0640;ARABIC TATWEEL;Lm;0;AL;;;;;N;;;;;
+0641;ARABIC LETTER FEH;Lo;0;AL;;;;;N;ARABIC LETTER FA;;;;
+0642;ARABIC LETTER QAF;Lo;0;AL;;;;;N;;;;;
+0643;ARABIC LETTER KAF;Lo;0;AL;;;;;N;ARABIC LETTER CAF;;;;
+0644;ARABIC LETTER LAM;Lo;0;AL;;;;;N;;;;;
+0645;ARABIC LETTER MEEM;Lo;0;AL;;;;;N;;;;;
+0646;ARABIC LETTER NOON;Lo;0;AL;;;;;N;;;;;
+0647;ARABIC LETTER HEH;Lo;0;AL;;;;;N;ARABIC LETTER HA;;;;
+0648;ARABIC LETTER WAW;Lo;0;AL;;;;;N;;;;;
+0649;ARABIC LETTER ALEF MAKSURA;Lo;0;AL;;;;;N;ARABIC LETTER ALEF MAQSURAH;;;;
+064A;ARABIC LETTER YEH;Lo;0;AL;;;;;N;ARABIC LETTER YA;;;;
+064B;ARABIC FATHATAN;Mn;27;NSM;;;;;N;;;;;
+064C;ARABIC DAMMATAN;Mn;28;NSM;;;;;N;;;;;
+064D;ARABIC KASRATAN;Mn;29;NSM;;;;;N;;;;;
+064E;ARABIC FATHA;Mn;30;NSM;;;;;N;ARABIC FATHAH;;;;
+064F;ARABIC DAMMA;Mn;31;NSM;;;;;N;ARABIC DAMMAH;;;;
+0650;ARABIC KASRA;Mn;32;NSM;;;;;N;ARABIC KASRAH;;;;
+0651;ARABIC SHADDA;Mn;33;NSM;;;;;N;ARABIC SHADDAH;;;;
+0652;ARABIC SUKUN;Mn;34;NSM;;;;;N;;;;;
+0653;ARABIC MADDAH ABOVE;Mn;230;NSM;;;;;N;;;;;
+0654;ARABIC HAMZA ABOVE;Mn;230;NSM;;;;;N;;;;;
+0655;ARABIC HAMZA BELOW;Mn;220;NSM;;;;;N;;;;;
+0656;ARABIC SUBSCRIPT ALEF;Mn;220;NSM;;;;;N;;;;;
+0657;ARABIC INVERTED DAMMA;Mn;230;NSM;;;;;N;;;;;
+0658;ARABIC MARK NOON GHUNNA;Mn;230;NSM;;;;;N;;;;;
+0659;ARABIC ZWARAKAY;Mn;230;NSM;;;;;N;;;;;
+065A;ARABIC VOWEL SIGN SMALL V ABOVE;Mn;230;NSM;;;;;N;;;;;
+065B;ARABIC VOWEL SIGN INVERTED SMALL V ABOVE;Mn;230;NSM;;;;;N;;;;;
+065C;ARABIC VOWEL SIGN DOT BELOW;Mn;220;NSM;;;;;N;;;;;
+065D;ARABIC REVERSED DAMMA;Mn;230;NSM;;;;;N;;;;;
+065E;ARABIC FATHA WITH TWO DOTS;Mn;230;NSM;;;;;N;;;;;
+065F;ARABIC WAVY HAMZA BELOW;Mn;220;NSM;;;;;N;;;;;
+0660;ARABIC-INDIC DIGIT ZERO;Nd;0;AN;;0;0;0;N;;;;;
+0661;ARABIC-INDIC DIGIT ONE;Nd;0;AN;;1;1;1;N;;;;;
+0662;ARABIC-INDIC DIGIT TWO;Nd;0;AN;;2;2;2;N;;;;;
+0663;ARABIC-INDIC DIGIT THREE;Nd;0;AN;;3;3;3;N;;;;;
+0664;ARABIC-INDIC DIGIT FOUR;Nd;0;AN;;4;4;4;N;;;;;
+0665;ARABIC-INDIC DIGIT FIVE;Nd;0;AN;;5;5;5;N;;;;;
+0666;ARABIC-INDIC DIGIT SIX;Nd;0;AN;;6;6;6;N;;;;;
+0667;ARABIC-INDIC DIGIT SEVEN;Nd;0;AN;;7;7;7;N;;;;;
+0668;ARABIC-INDIC DIGIT EIGHT;Nd;0;AN;;8;8;8;N;;;;;
+0669;ARABIC-INDIC DIGIT NINE;Nd;0;AN;;9;9;9;N;;;;;
+066A;ARABIC PERCENT SIGN;Po;0;ET;;;;;N;;;;;
+066B;ARABIC DECIMAL SEPARATOR;Po;0;AN;;;;;N;;;;;
+066C;ARABIC THOUSANDS SEPARATOR;Po;0;AN;;;;;N;;;;;
+066D;ARABIC FIVE POINTED STAR;Po;0;AL;;;;;N;;;;;
+066E;ARABIC LETTER DOTLESS BEH;Lo;0;AL;;;;;N;;;;;
+066F;ARABIC LETTER DOTLESS QAF;Lo;0;AL;;;;;N;;;;;
+0670;ARABIC LETTER SUPERSCRIPT ALEF;Mn;35;NSM;;;;;N;ARABIC ALEF ABOVE;;;;
+0671;ARABIC LETTER ALEF WASLA;Lo;0;AL;;;;;N;ARABIC LETTER HAMZAT WASL ON ALEF;;;;
+0672;ARABIC LETTER ALEF WITH WAVY HAMZA ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER WAVY HAMZAH ON ALEF;;;;
+0673;ARABIC LETTER ALEF WITH WAVY HAMZA BELOW;Lo;0;AL;;;;;N;ARABIC LETTER WAVY HAMZAH UNDER ALEF;;;;
+0674;ARABIC LETTER HIGH HAMZA;Lo;0;AL;;;;;N;ARABIC LETTER HIGH HAMZAH;;;;
+0675;ARABIC LETTER HIGH HAMZA ALEF;Lo;0;AL;<compat> 0627 0674;;;;N;ARABIC LETTER HIGH HAMZAH ALEF;;;;
+0676;ARABIC LETTER HIGH HAMZA WAW;Lo;0;AL;<compat> 0648 0674;;;;N;ARABIC LETTER HIGH HAMZAH WAW;;;;
+0677;ARABIC LETTER U WITH HAMZA ABOVE;Lo;0;AL;<compat> 06C7 0674;;;;N;ARABIC LETTER HIGH HAMZAH WAW WITH DAMMAH;;;;
+0678;ARABIC LETTER HIGH HAMZA YEH;Lo;0;AL;<compat> 064A 0674;;;;N;ARABIC LETTER HIGH HAMZAH YA;;;;
+0679;ARABIC LETTER TTEH;Lo;0;AL;;;;;N;ARABIC LETTER TAA WITH SMALL TAH;;;;
+067A;ARABIC LETTER TTEHEH;Lo;0;AL;;;;;N;ARABIC LETTER TAA WITH TWO DOTS VERTICAL ABOVE;;;;
+067B;ARABIC LETTER BEEH;Lo;0;AL;;;;;N;ARABIC LETTER BAA WITH TWO DOTS VERTICAL BELOW;;;;
+067C;ARABIC LETTER TEH WITH RING;Lo;0;AL;;;;;N;ARABIC LETTER TAA WITH RING;;;;
+067D;ARABIC LETTER TEH WITH THREE DOTS ABOVE DOWNWARDS;Lo;0;AL;;;;;N;ARABIC LETTER TAA WITH THREE DOTS ABOVE DOWNWARD;;;;
+067E;ARABIC LETTER PEH;Lo;0;AL;;;;;N;ARABIC LETTER TAA WITH THREE DOTS BELOW;;;;
+067F;ARABIC LETTER TEHEH;Lo;0;AL;;;;;N;ARABIC LETTER TAA WITH FOUR DOTS ABOVE;;;;
+0680;ARABIC LETTER BEHEH;Lo;0;AL;;;;;N;ARABIC LETTER BAA WITH FOUR DOTS BELOW;;;;
+0681;ARABIC LETTER HAH WITH HAMZA ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER HAMZAH ON HAA;;;;
+0682;ARABIC LETTER HAH WITH TWO DOTS VERTICAL ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER HAA WITH TWO DOTS VERTICAL ABOVE;;;;
+0683;ARABIC LETTER NYEH;Lo;0;AL;;;;;N;ARABIC LETTER HAA WITH MIDDLE TWO DOTS;;;;
+0684;ARABIC LETTER DYEH;Lo;0;AL;;;;;N;ARABIC LETTER HAA WITH MIDDLE TWO DOTS VERTICAL;;;;
+0685;ARABIC LETTER HAH WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER HAA WITH THREE DOTS ABOVE;;;;
+0686;ARABIC LETTER TCHEH;Lo;0;AL;;;;;N;ARABIC LETTER HAA WITH MIDDLE THREE DOTS DOWNWARD;;;;
+0687;ARABIC LETTER TCHEHEH;Lo;0;AL;;;;;N;ARABIC LETTER HAA WITH MIDDLE FOUR DOTS;;;;
+0688;ARABIC LETTER DDAL;Lo;0;AL;;;;;N;ARABIC LETTER DAL WITH SMALL TAH;;;;
+0689;ARABIC LETTER DAL WITH RING;Lo;0;AL;;;;;N;;;;;
+068A;ARABIC LETTER DAL WITH DOT BELOW;Lo;0;AL;;;;;N;;;;;
+068B;ARABIC LETTER DAL WITH DOT BELOW AND SMALL TAH;Lo;0;AL;;;;;N;;;;;
+068C;ARABIC LETTER DAHAL;Lo;0;AL;;;;;N;ARABIC LETTER DAL WITH TWO DOTS ABOVE;;;;
+068D;ARABIC LETTER DDAHAL;Lo;0;AL;;;;;N;ARABIC LETTER DAL WITH TWO DOTS BELOW;;;;
+068E;ARABIC LETTER DUL;Lo;0;AL;;;;;N;ARABIC LETTER DAL WITH THREE DOTS ABOVE;;;;
+068F;ARABIC LETTER DAL WITH THREE DOTS ABOVE DOWNWARDS;Lo;0;AL;;;;;N;ARABIC LETTER DAL WITH THREE DOTS ABOVE DOWNWARD;;;;
+0690;ARABIC LETTER DAL WITH FOUR DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
+0691;ARABIC LETTER RREH;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH SMALL TAH;;;;
+0692;ARABIC LETTER REH WITH SMALL V;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH SMALL V;;;;
+0693;ARABIC LETTER REH WITH RING;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH RING;;;;
+0694;ARABIC LETTER REH WITH DOT BELOW;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH DOT BELOW;;;;
+0695;ARABIC LETTER REH WITH SMALL V BELOW;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH SMALL V BELOW;;;;
+0696;ARABIC LETTER REH WITH DOT BELOW AND DOT ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH DOT BELOW AND DOT ABOVE;;;;
+0697;ARABIC LETTER REH WITH TWO DOTS ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH TWO DOTS ABOVE;;;;
+0698;ARABIC LETTER JEH;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH THREE DOTS ABOVE;;;;
+0699;ARABIC LETTER REH WITH FOUR DOTS ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH FOUR DOTS ABOVE;;;;
+069A;ARABIC LETTER SEEN WITH DOT BELOW AND DOT ABOVE;Lo;0;AL;;;;;N;;;;;
+069B;ARABIC LETTER SEEN WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;;;;;
+069C;ARABIC LETTER SEEN WITH THREE DOTS BELOW AND THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
+069D;ARABIC LETTER SAD WITH TWO DOTS BELOW;Lo;0;AL;;;;;N;;;;;
+069E;ARABIC LETTER SAD WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
+069F;ARABIC LETTER TAH WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
+06A0;ARABIC LETTER AIN WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
+06A1;ARABIC LETTER DOTLESS FEH;Lo;0;AL;;;;;N;ARABIC LETTER DOTLESS FA;;;;
+06A2;ARABIC LETTER FEH WITH DOT MOVED BELOW;Lo;0;AL;;;;;N;ARABIC LETTER FA WITH DOT MOVED BELOW;;;;
+06A3;ARABIC LETTER FEH WITH DOT BELOW;Lo;0;AL;;;;;N;ARABIC LETTER FA WITH DOT BELOW;;;;
+06A4;ARABIC LETTER VEH;Lo;0;AL;;;;;N;ARABIC LETTER FA WITH THREE DOTS ABOVE;;;;
+06A5;ARABIC LETTER FEH WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;ARABIC LETTER FA WITH THREE DOTS BELOW;;;;
+06A6;ARABIC LETTER PEHEH;Lo;0;AL;;;;;N;ARABIC LETTER FA WITH FOUR DOTS ABOVE;;;;
+06A7;ARABIC LETTER QAF WITH DOT ABOVE;Lo;0;AL;;;;;N;;;;;
+06A8;ARABIC LETTER QAF WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
+06A9;ARABIC LETTER KEHEH;Lo;0;AL;;;;;N;ARABIC LETTER OPEN CAF;;;;
+06AA;ARABIC LETTER SWASH KAF;Lo;0;AL;;;;;N;ARABIC LETTER SWASH CAF;;;;
+06AB;ARABIC LETTER KAF WITH RING;Lo;0;AL;;;;;N;ARABIC LETTER CAF WITH RING;;;;
+06AC;ARABIC LETTER KAF WITH DOT ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER CAF WITH DOT ABOVE;;;;
+06AD;ARABIC LETTER NG;Lo;0;AL;;;;;N;ARABIC LETTER CAF WITH THREE DOTS ABOVE;;;;
+06AE;ARABIC LETTER KAF WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;ARABIC LETTER CAF WITH THREE DOTS BELOW;;;;
+06AF;ARABIC LETTER GAF;Lo;0;AL;;;;;N;;;;;
+06B0;ARABIC LETTER GAF WITH RING;Lo;0;AL;;;;;N;;;;;
+06B1;ARABIC LETTER NGOEH;Lo;0;AL;;;;;N;ARABIC LETTER GAF WITH TWO DOTS ABOVE;;;;
+06B2;ARABIC LETTER GAF WITH TWO DOTS BELOW;Lo;0;AL;;;;;N;;;;;
+06B3;ARABIC LETTER GUEH;Lo;0;AL;;;;;N;ARABIC LETTER GAF WITH TWO DOTS VERTICAL BELOW;;;;
+06B4;ARABIC LETTER GAF WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
+06B5;ARABIC LETTER LAM WITH SMALL V;Lo;0;AL;;;;;N;;;;;
+06B6;ARABIC LETTER LAM WITH DOT ABOVE;Lo;0;AL;;;;;N;;;;;
+06B7;ARABIC LETTER LAM WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
+06B8;ARABIC LETTER LAM WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;;;;;
+06B9;ARABIC LETTER NOON WITH DOT BELOW;Lo;0;AL;;;;;N;;;;;
+06BA;ARABIC LETTER NOON GHUNNA;Lo;0;AL;;;;;N;ARABIC LETTER DOTLESS NOON;;;;
+06BB;ARABIC LETTER RNOON;Lo;0;AL;;;;;N;ARABIC LETTER DOTLESS NOON WITH SMALL TAH;;;;
+06BC;ARABIC LETTER NOON WITH RING;Lo;0;AL;;;;;N;;;;;
+06BD;ARABIC LETTER NOON WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
+06BE;ARABIC LETTER HEH DOACHASHMEE;Lo;0;AL;;;;;N;ARABIC LETTER KNOTTED HA;;;;
+06BF;ARABIC LETTER TCHEH WITH DOT ABOVE;Lo;0;AL;;;;;N;;;;;
+06C0;ARABIC LETTER HEH WITH YEH ABOVE;Lo;0;AL;06D5 0654;;;;N;ARABIC LETTER HAMZAH ON HA;;;;
+06C1;ARABIC LETTER HEH GOAL;Lo;0;AL;;;;;N;ARABIC LETTER HA GOAL;;;;
+06C2;ARABIC LETTER HEH GOAL WITH HAMZA ABOVE;Lo;0;AL;06C1 0654;;;;N;ARABIC LETTER HAMZAH ON HA GOAL;;;;
+06C3;ARABIC LETTER TEH MARBUTA GOAL;Lo;0;AL;;;;;N;ARABIC LETTER TAA MARBUTAH GOAL;;;;
+06C4;ARABIC LETTER WAW WITH RING;Lo;0;AL;;;;;N;;;;;
+06C5;ARABIC LETTER KIRGHIZ OE;Lo;0;AL;;;;;N;ARABIC LETTER WAW WITH BAR;;;;
+06C6;ARABIC LETTER OE;Lo;0;AL;;;;;N;ARABIC LETTER WAW WITH SMALL V;;;;
+06C7;ARABIC LETTER U;Lo;0;AL;;;;;N;ARABIC LETTER WAW WITH DAMMAH;;;;
+06C8;ARABIC LETTER YU;Lo;0;AL;;;;;N;ARABIC LETTER WAW WITH ALEF ABOVE;;;;
+06C9;ARABIC LETTER KIRGHIZ YU;Lo;0;AL;;;;;N;ARABIC LETTER WAW WITH INVERTED SMALL V;;;;
+06CA;ARABIC LETTER WAW WITH TWO DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
+06CB;ARABIC LETTER VE;Lo;0;AL;;;;;N;ARABIC LETTER WAW WITH THREE DOTS ABOVE;;;;
+06CC;ARABIC LETTER FARSI YEH;Lo;0;AL;;;;;N;ARABIC LETTER DOTLESS YA;;;;
+06CD;ARABIC LETTER YEH WITH TAIL;Lo;0;AL;;;;;N;ARABIC LETTER YA WITH TAIL;;;;
+06CE;ARABIC LETTER YEH WITH SMALL V;Lo;0;AL;;;;;N;ARABIC LETTER YA WITH SMALL V;;;;
+06CF;ARABIC LETTER WAW WITH DOT ABOVE;Lo;0;AL;;;;;N;;;;;
+06D0;ARABIC LETTER E;Lo;0;AL;;;;;N;ARABIC LETTER YA WITH TWO DOTS VERTICAL BELOW;;;;
+06D1;ARABIC LETTER YEH WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;ARABIC LETTER YA WITH THREE DOTS BELOW;;;;
+06D2;ARABIC LETTER YEH BARREE;Lo;0;AL;;;;;N;ARABIC LETTER YA BARREE;;;;
+06D3;ARABIC LETTER YEH BARREE WITH HAMZA ABOVE;Lo;0;AL;06D2 0654;;;;N;ARABIC LETTER HAMZAH ON YA BARREE;;;;
+06D4;ARABIC FULL STOP;Po;0;AL;;;;;N;ARABIC PERIOD;;;;
+06D5;ARABIC LETTER AE;Lo;0;AL;;;;;N;;;;;
+06D6;ARABIC SMALL HIGH LIGATURE SAD WITH LAM WITH ALEF MAKSURA;Mn;230;NSM;;;;;N;;;;;
+06D7;ARABIC SMALL HIGH LIGATURE QAF WITH LAM WITH ALEF MAKSURA;Mn;230;NSM;;;;;N;;;;;
+06D8;ARABIC SMALL HIGH MEEM INITIAL FORM;Mn;230;NSM;;;;;N;;;;;
+06D9;ARABIC SMALL HIGH LAM ALEF;Mn;230;NSM;;;;;N;;;;;
+06DA;ARABIC SMALL HIGH JEEM;Mn;230;NSM;;;;;N;;;;;
+06DB;ARABIC SMALL HIGH THREE DOTS;Mn;230;NSM;;;;;N;;;;;
+06DC;ARABIC SMALL HIGH SEEN;Mn;230;NSM;;;;;N;;;;;
+06DD;ARABIC END OF AYAH;Cf;0;AN;;;;;N;;;;;
+06DE;ARABIC START OF RUB EL HIZB;So;0;ON;;;;;N;;;;;
+06DF;ARABIC SMALL HIGH ROUNDED ZERO;Mn;230;NSM;;;;;N;;;;;
+06E0;ARABIC SMALL HIGH UPRIGHT RECTANGULAR ZERO;Mn;230;NSM;;;;;N;;;;;
+06E1;ARABIC SMALL HIGH DOTLESS HEAD OF KHAH;Mn;230;NSM;;;;;N;;;;;
+06E2;ARABIC SMALL HIGH MEEM ISOLATED FORM;Mn;230;NSM;;;;;N;;;;;
+06E3;ARABIC SMALL LOW SEEN;Mn;220;NSM;;;;;N;;;;;
+06E4;ARABIC SMALL HIGH MADDA;Mn;230;NSM;;;;;N;;;;;
+06E5;ARABIC SMALL WAW;Lm;0;AL;;;;;N;;;;;
+06E6;ARABIC SMALL YEH;Lm;0;AL;;;;;N;;;;;
+06E7;ARABIC SMALL HIGH YEH;Mn;230;NSM;;;;;N;;;;;
+06E8;ARABIC SMALL HIGH NOON;Mn;230;NSM;;;;;N;;;;;
+06E9;ARABIC PLACE OF SAJDAH;So;0;ON;;;;;N;;;;;
+06EA;ARABIC EMPTY CENTRE LOW STOP;Mn;220;NSM;;;;;N;;;;;
+06EB;ARABIC EMPTY CENTRE HIGH STOP;Mn;230;NSM;;;;;N;;;;;
+06EC;ARABIC ROUNDED HIGH STOP WITH FILLED CENTRE;Mn;230;NSM;;;;;N;;;;;
+06ED;ARABIC SMALL LOW MEEM;Mn;220;NSM;;;;;N;;;;;
+06EE;ARABIC LETTER DAL WITH INVERTED V;Lo;0;AL;;;;;N;;;;;
+06EF;ARABIC LETTER REH WITH INVERTED V;Lo;0;AL;;;;;N;;;;;
+06F0;EXTENDED ARABIC-INDIC DIGIT ZERO;Nd;0;EN;;0;0;0;N;EASTERN ARABIC-INDIC DIGIT ZERO;;;;
+06F1;EXTENDED ARABIC-INDIC DIGIT ONE;Nd;0;EN;;1;1;1;N;EASTERN ARABIC-INDIC DIGIT ONE;;;;
+06F2;EXTENDED ARABIC-INDIC DIGIT TWO;Nd;0;EN;;2;2;2;N;EASTERN ARABIC-INDIC DIGIT TWO;;;;
+06F3;EXTENDED ARABIC-INDIC DIGIT THREE;Nd;0;EN;;3;3;3;N;EASTERN ARABIC-INDIC DIGIT THREE;;;;
+06F4;EXTENDED ARABIC-INDIC DIGIT FOUR;Nd;0;EN;;4;4;4;N;EASTERN ARABIC-INDIC DIGIT FOUR;;;;
+06F5;EXTENDED ARABIC-INDIC DIGIT FIVE;Nd;0;EN;;5;5;5;N;EASTERN ARABIC-INDIC DIGIT FIVE;;;;
+06F6;EXTENDED ARABIC-INDIC DIGIT SIX;Nd;0;EN;;6;6;6;N;EASTERN ARABIC-INDIC DIGIT SIX;;;;
+06F7;EXTENDED ARABIC-INDIC DIGIT SEVEN;Nd;0;EN;;7;7;7;N;EASTERN ARABIC-INDIC DIGIT SEVEN;;;;
+06F8;EXTENDED ARABIC-INDIC DIGIT EIGHT;Nd;0;EN;;8;8;8;N;EASTERN ARABIC-INDIC DIGIT EIGHT;;;;
+06F9;EXTENDED ARABIC-INDIC DIGIT NINE;Nd;0;EN;;9;9;9;N;EASTERN ARABIC-INDIC DIGIT NINE;;;;
+06FA;ARABIC LETTER SHEEN WITH DOT BELOW;Lo;0;AL;;;;;N;;;;;
+06FB;ARABIC LETTER DAD WITH DOT BELOW;Lo;0;AL;;;;;N;;;;;
+06FC;ARABIC LETTER GHAIN WITH DOT BELOW;Lo;0;AL;;;;;N;;;;;
+06FD;ARABIC SIGN SINDHI AMPERSAND;So;0;AL;;;;;N;;;;;
+06FE;ARABIC SIGN SINDHI POSTPOSITION MEN;So;0;AL;;;;;N;;;;;
+06FF;ARABIC LETTER HEH WITH INVERTED V;Lo;0;AL;;;;;N;;;;;
+0700;SYRIAC END OF PARAGRAPH;Po;0;AL;;;;;N;;;;;
+0701;SYRIAC SUPRALINEAR FULL STOP;Po;0;AL;;;;;N;;;;;
+0702;SYRIAC SUBLINEAR FULL STOP;Po;0;AL;;;;;N;;;;;
+0703;SYRIAC SUPRALINEAR COLON;Po;0;AL;;;;;N;;;;;
+0704;SYRIAC SUBLINEAR COLON;Po;0;AL;;;;;N;;;;;
+0705;SYRIAC HORIZONTAL COLON;Po;0;AL;;;;;N;;;;;
+0706;SYRIAC COLON SKEWED LEFT;Po;0;AL;;;;;N;;;;;
+0707;SYRIAC COLON SKEWED RIGHT;Po;0;AL;;;;;N;;;;;
+0708;SYRIAC SUPRALINEAR COLON SKEWED LEFT;Po;0;AL;;;;;N;;;;;
+0709;SYRIAC SUBLINEAR COLON SKEWED RIGHT;Po;0;AL;;;;;N;;;;;
+070A;SYRIAC CONTRACTION;Po;0;AL;;;;;N;;;;;
+070B;SYRIAC HARKLEAN OBELUS;Po;0;AL;;;;;N;;;;;
+070C;SYRIAC HARKLEAN METOBELUS;Po;0;AL;;;;;N;;;;;
+070D;SYRIAC HARKLEAN ASTERISCUS;Po;0;AL;;;;;N;;;;;
+070F;SYRIAC ABBREVIATION MARK;Cf;0;AN;;;;;N;;;;;
+0710;SYRIAC LETTER ALAPH;Lo;0;AL;;;;;N;;;;;
+0711;SYRIAC LETTER SUPERSCRIPT ALAPH;Mn;36;NSM;;;;;N;;;;;
+0712;SYRIAC LETTER BETH;Lo;0;AL;;;;;N;;;;;
+0713;SYRIAC LETTER GAMAL;Lo;0;AL;;;;;N;;;;;
+0714;SYRIAC LETTER GAMAL GARSHUNI;Lo;0;AL;;;;;N;;;;;
+0715;SYRIAC LETTER DALATH;Lo;0;AL;;;;;N;;;;;
+0716;SYRIAC LETTER DOTLESS DALATH RISH;Lo;0;AL;;;;;N;;;;;
+0717;SYRIAC LETTER HE;Lo;0;AL;;;;;N;;;;;
+0718;SYRIAC LETTER WAW;Lo;0;AL;;;;;N;;;;;
+0719;SYRIAC LETTER ZAIN;Lo;0;AL;;;;;N;;;;;
+071A;SYRIAC LETTER HETH;Lo;0;AL;;;;;N;;;;;
+071B;SYRIAC LETTER TETH;Lo;0;AL;;;;;N;;;;;
+071C;SYRIAC LETTER TETH GARSHUNI;Lo;0;AL;;;;;N;;;;;
+071D;SYRIAC LETTER YUDH;Lo;0;AL;;;;;N;;;;;
+071E;SYRIAC LETTER YUDH HE;Lo;0;AL;;;;;N;;;;;
+071F;SYRIAC LETTER KAPH;Lo;0;AL;;;;;N;;;;;
+0720;SYRIAC LETTER LAMADH;Lo;0;AL;;;;;N;;;;;
+0721;SYRIAC LETTER MIM;Lo;0;AL;;;;;N;;;;;
+0722;SYRIAC LETTER NUN;Lo;0;AL;;;;;N;;;;;
+0723;SYRIAC LETTER SEMKATH;Lo;0;AL;;;;;N;;;;;
+0724;SYRIAC LETTER FINAL SEMKATH;Lo;0;AL;;;;;N;;;;;
+0725;SYRIAC LETTER E;Lo;0;AL;;;;;N;;;;;
+0726;SYRIAC LETTER PE;Lo;0;AL;;;;;N;;;;;
+0727;SYRIAC LETTER REVERSED PE;Lo;0;AL;;;;;N;;;;;
+0728;SYRIAC LETTER SADHE;Lo;0;AL;;;;;N;;;;;
+0729;SYRIAC LETTER QAPH;Lo;0;AL;;;;;N;;;;;
+072A;SYRIAC LETTER RISH;Lo;0;AL;;;;;N;;;;;
+072B;SYRIAC LETTER SHIN;Lo;0;AL;;;;;N;;;;;
+072C;SYRIAC LETTER TAW;Lo;0;AL;;;;;N;;;;;
+072D;SYRIAC LETTER PERSIAN BHETH;Lo;0;AL;;;;;N;;;;;
+072E;SYRIAC LETTER PERSIAN GHAMAL;Lo;0;AL;;;;;N;;;;;
+072F;SYRIAC LETTER PERSIAN DHALATH;Lo;0;AL;;;;;N;;;;;
+0730;SYRIAC PTHAHA ABOVE;Mn;230;NSM;;;;;N;;;;;
+0731;SYRIAC PTHAHA BELOW;Mn;220;NSM;;;;;N;;;;;
+0732;SYRIAC PTHAHA DOTTED;Mn;230;NSM;;;;;N;;;;;
+0733;SYRIAC ZQAPHA ABOVE;Mn;230;NSM;;;;;N;;;;;
+0734;SYRIAC ZQAPHA BELOW;Mn;220;NSM;;;;;N;;;;;
+0735;SYRIAC ZQAPHA DOTTED;Mn;230;NSM;;;;;N;;;;;
+0736;SYRIAC RBASA ABOVE;Mn;230;NSM;;;;;N;;;;;
+0737;SYRIAC RBASA BELOW;Mn;220;NSM;;;;;N;;;;;
+0738;SYRIAC DOTTED ZLAMA HORIZONTAL;Mn;220;NSM;;;;;N;;;;;
+0739;SYRIAC DOTTED ZLAMA ANGULAR;Mn;220;NSM;;;;;N;;;;;
+073A;SYRIAC HBASA ABOVE;Mn;230;NSM;;;;;N;;;;;
+073B;SYRIAC HBASA BELOW;Mn;220;NSM;;;;;N;;;;;
+073C;SYRIAC HBASA-ESASA DOTTED;Mn;220;NSM;;;;;N;;;;;
+073D;SYRIAC ESASA ABOVE;Mn;230;NSM;;;;;N;;;;;
+073E;SYRIAC ESASA BELOW;Mn;220;NSM;;;;;N;;;;;
+073F;SYRIAC RWAHA;Mn;230;NSM;;;;;N;;;;;
+0740;SYRIAC FEMININE DOT;Mn;230;NSM;;;;;N;;;;;
+0741;SYRIAC QUSHSHAYA;Mn;230;NSM;;;;;N;;;;;
+0742;SYRIAC RUKKAKHA;Mn;220;NSM;;;;;N;;;;;
+0743;SYRIAC TWO VERTICAL DOTS ABOVE;Mn;230;NSM;;;;;N;;;;;
+0744;SYRIAC TWO VERTICAL DOTS BELOW;Mn;220;NSM;;;;;N;;;;;
+0745;SYRIAC THREE DOTS ABOVE;Mn;230;NSM;;;;;N;;;;;
+0746;SYRIAC THREE DOTS BELOW;Mn;220;NSM;;;;;N;;;;;
+0747;SYRIAC OBLIQUE LINE ABOVE;Mn;230;NSM;;;;;N;;;;;
+0748;SYRIAC OBLIQUE LINE BELOW;Mn;220;NSM;;;;;N;;;;;
+0749;SYRIAC MUSIC;Mn;230;NSM;;;;;N;;;;;
+074A;SYRIAC BARREKH;Mn;230;NSM;;;;;N;;;;;
+074D;SYRIAC LETTER SOGDIAN ZHAIN;Lo;0;AL;;;;;N;;;;;
+074E;SYRIAC LETTER SOGDIAN KHAPH;Lo;0;AL;;;;;N;;;;;
+074F;SYRIAC LETTER SOGDIAN FE;Lo;0;AL;;;;;N;;;;;
+0750;ARABIC LETTER BEH WITH THREE DOTS HORIZONTALLY BELOW;Lo;0;AL;;;;;N;;;;;
+0751;ARABIC LETTER BEH WITH DOT BELOW AND THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
+0752;ARABIC LETTER BEH WITH THREE DOTS POINTING UPWARDS BELOW;Lo;0;AL;;;;;N;;;;;
+0753;ARABIC LETTER BEH WITH THREE DOTS POINTING UPWARDS BELOW AND TWO DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
+0754;ARABIC LETTER BEH WITH TWO DOTS BELOW AND DOT ABOVE;Lo;0;AL;;;;;N;;;;;
+0755;ARABIC LETTER BEH WITH INVERTED SMALL V BELOW;Lo;0;AL;;;;;N;;;;;
+0756;ARABIC LETTER BEH WITH SMALL V;Lo;0;AL;;;;;N;;;;;
+0757;ARABIC LETTER HAH WITH TWO DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
+0758;ARABIC LETTER HAH WITH THREE DOTS POINTING UPWARDS BELOW;Lo;0;AL;;;;;N;;;;;
+0759;ARABIC LETTER DAL WITH TWO DOTS VERTICALLY BELOW AND SMALL TAH;Lo;0;AL;;;;;N;;;;;
+075A;ARABIC LETTER DAL WITH INVERTED SMALL V BELOW;Lo;0;AL;;;;;N;;;;;
+075B;ARABIC LETTER REH WITH STROKE;Lo;0;AL;;;;;N;;;;;
+075C;ARABIC LETTER SEEN WITH FOUR DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
+075D;ARABIC LETTER AIN WITH TWO DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
+075E;ARABIC LETTER AIN WITH THREE DOTS POINTING DOWNWARDS ABOVE;Lo;0;AL;;;;;N;;;;;
+075F;ARABIC LETTER AIN WITH TWO DOTS VERTICALLY ABOVE;Lo;0;AL;;;;;N;;;;;
+0760;ARABIC LETTER FEH WITH TWO DOTS BELOW;Lo;0;AL;;;;;N;;;;;
+0761;ARABIC LETTER FEH WITH THREE DOTS POINTING UPWARDS BELOW;Lo;0;AL;;;;;N;;;;;
+0762;ARABIC LETTER KEHEH WITH DOT ABOVE;Lo;0;AL;;;;;N;;;;;
+0763;ARABIC LETTER KEHEH WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
+0764;ARABIC LETTER KEHEH WITH THREE DOTS POINTING UPWARDS BELOW;Lo;0;AL;;;;;N;;;;;
+0765;ARABIC LETTER MEEM WITH DOT ABOVE;Lo;0;AL;;;;;N;;;;;
+0766;ARABIC LETTER MEEM WITH DOT BELOW;Lo;0;AL;;;;;N;;;;;
+0767;ARABIC LETTER NOON WITH TWO DOTS BELOW;Lo;0;AL;;;;;N;;;;;
+0768;ARABIC LETTER NOON WITH SMALL TAH;Lo;0;AL;;;;;N;;;;;
+0769;ARABIC LETTER NOON WITH SMALL V;Lo;0;AL;;;;;N;;;;;
+076A;ARABIC LETTER LAM WITH BAR;Lo;0;AL;;;;;N;;;;;
+076B;ARABIC LETTER REH WITH TWO DOTS VERTICALLY ABOVE;Lo;0;AL;;;;;N;;;;;
+076C;ARABIC LETTER REH WITH HAMZA ABOVE;Lo;0;AL;;;;;N;;;;;
+076D;ARABIC LETTER SEEN WITH TWO DOTS VERTICALLY ABOVE;Lo;0;AL;;;;;N;;;;;
+076E;ARABIC LETTER HAH WITH SMALL ARABIC LETTER TAH BELOW;Lo;0;AL;;;;;N;;;;;
+076F;ARABIC LETTER HAH WITH SMALL ARABIC LETTER TAH AND TWO DOTS;Lo;0;AL;;;;;N;;;;;
+0770;ARABIC LETTER SEEN WITH SMALL ARABIC LETTER TAH AND TWO DOTS;Lo;0;AL;;;;;N;;;;;
+0771;ARABIC LETTER REH WITH SMALL ARABIC LETTER TAH AND TWO DOTS;Lo;0;AL;;;;;N;;;;;
+0772;ARABIC LETTER HAH WITH SMALL ARABIC LETTER TAH ABOVE;Lo;0;AL;;;;;N;;;;;
+0773;ARABIC LETTER ALEF WITH EXTENDED ARABIC-INDIC DIGIT TWO ABOVE;Lo;0;AL;;;;;N;;;;;
+0774;ARABIC LETTER ALEF WITH EXTENDED ARABIC-INDIC DIGIT THREE ABOVE;Lo;0;AL;;;;;N;;;;;
+0775;ARABIC LETTER FARSI YEH WITH EXTENDED ARABIC-INDIC DIGIT TWO ABOVE;Lo;0;AL;;;;;N;;;;;
+0776;ARABIC LETTER FARSI YEH WITH EXTENDED ARABIC-INDIC DIGIT THREE ABOVE;Lo;0;AL;;;;;N;;;;;
+0777;ARABIC LETTER FARSI YEH WITH EXTENDED ARABIC-INDIC DIGIT FOUR BELOW;Lo;0;AL;;;;;N;;;;;
+0778;ARABIC LETTER WAW WITH EXTENDED ARABIC-INDIC DIGIT TWO ABOVE;Lo;0;AL;;;;;N;;;;;
+0779;ARABIC LETTER WAW WITH EXTENDED ARABIC-INDIC DIGIT THREE ABOVE;Lo;0;AL;;;;;N;;;;;
+077A;ARABIC LETTER YEH BARREE WITH EXTENDED ARABIC-INDIC DIGIT TWO ABOVE;Lo;0;AL;;;;;N;;;;;
+077B;ARABIC LETTER YEH BARREE WITH EXTENDED ARABIC-INDIC DIGIT THREE ABOVE;Lo;0;AL;;;;;N;;;;;
+077C;ARABIC LETTER HAH WITH EXTENDED ARABIC-INDIC DIGIT FOUR BELOW;Lo;0;AL;;;;;N;;;;;
+077D;ARABIC LETTER SEEN WITH EXTENDED ARABIC-INDIC DIGIT FOUR ABOVE;Lo;0;AL;;;;;N;;;;;
+077E;ARABIC LETTER SEEN WITH INVERTED V;Lo;0;AL;;;;;N;;;;;
+077F;ARABIC LETTER KAF WITH TWO DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
+0780;THAANA LETTER HAA;Lo;0;AL;;;;;N;;;;;
+0781;THAANA LETTER SHAVIYANI;Lo;0;AL;;;;;N;;;;;
+0782;THAANA LETTER NOONU;Lo;0;AL;;;;;N;;;;;
+0783;THAANA LETTER RAA;Lo;0;AL;;;;;N;;;;;
+0784;THAANA LETTER BAA;Lo;0;AL;;;;;N;;;;;
+0785;THAANA LETTER LHAVIYANI;Lo;0;AL;;;;;N;;;;;
+0786;THAANA LETTER KAAFU;Lo;0;AL;;;;;N;;;;;
+0787;THAANA LETTER ALIFU;Lo;0;AL;;;;;N;;;;;
+0788;THAANA LETTER VAAVU;Lo;0;AL;;;;;N;;;;;
+0789;THAANA LETTER MEEMU;Lo;0;AL;;;;;N;;;;;
+078A;THAANA LETTER FAAFU;Lo;0;AL;;;;;N;;;;;
+078B;THAANA LETTER DHAALU;Lo;0;AL;;;;;N;;;;;
+078C;THAANA LETTER THAA;Lo;0;AL;;;;;N;;;;;
+078D;THAANA LETTER LAAMU;Lo;0;AL;;;;;N;;;;;
+078E;THAANA LETTER GAAFU;Lo;0;AL;;;;;N;;;;;
+078F;THAANA LETTER GNAVIYANI;Lo;0;AL;;;;;N;;;;;
+0790;THAANA LETTER SEENU;Lo;0;AL;;;;;N;;;;;
+0791;THAANA LETTER DAVIYANI;Lo;0;AL;;;;;N;;;;;
+0792;THAANA LETTER ZAVIYANI;Lo;0;AL;;;;;N;;;;;
+0793;THAANA LETTER TAVIYANI;Lo;0;AL;;;;;N;;;;;
+0794;THAANA LETTER YAA;Lo;0;AL;;;;;N;;;;;
+0795;THAANA LETTER PAVIYANI;Lo;0;AL;;;;;N;;;;;
+0796;THAANA LETTER JAVIYANI;Lo;0;AL;;;;;N;;;;;
+0797;THAANA LETTER CHAVIYANI;Lo;0;AL;;;;;N;;;;;
+0798;THAANA LETTER TTAA;Lo;0;AL;;;;;N;;;;;
+0799;THAANA LETTER HHAA;Lo;0;AL;;;;;N;;;;;
+079A;THAANA LETTER KHAA;Lo;0;AL;;;;;N;;;;;
+079B;THAANA LETTER THAALU;Lo;0;AL;;;;;N;;;;;
+079C;THAANA LETTER ZAA;Lo;0;AL;;;;;N;;;;;
+079D;THAANA LETTER SHEENU;Lo;0;AL;;;;;N;;;;;
+079E;THAANA LETTER SAADHU;Lo;0;AL;;;;;N;;;;;
+079F;THAANA LETTER DAADHU;Lo;0;AL;;;;;N;;;;;
+07A0;THAANA LETTER TO;Lo;0;AL;;;;;N;;;;;
+07A1;THAANA LETTER ZO;Lo;0;AL;;;;;N;;;;;
+07A2;THAANA LETTER AINU;Lo;0;AL;;;;;N;;;;;
+07A3;THAANA LETTER GHAINU;Lo;0;AL;;;;;N;;;;;
+07A4;THAANA LETTER QAAFU;Lo;0;AL;;;;;N;;;;;
+07A5;THAANA LETTER WAAVU;Lo;0;AL;;;;;N;;;;;
+07A6;THAANA ABAFILI;Mn;0;NSM;;;;;N;;;;;
+07A7;THAANA AABAAFILI;Mn;0;NSM;;;;;N;;;;;
+07A8;THAANA IBIFILI;Mn;0;NSM;;;;;N;;;;;
+07A9;THAANA EEBEEFILI;Mn;0;NSM;;;;;N;;;;;
+07AA;THAANA UBUFILI;Mn;0;NSM;;;;;N;;;;;
+07AB;THAANA OOBOOFILI;Mn;0;NSM;;;;;N;;;;;
+07AC;THAANA EBEFILI;Mn;0;NSM;;;;;N;;;;;
+07AD;THAANA EYBEYFILI;Mn;0;NSM;;;;;N;;;;;
+07AE;THAANA OBOFILI;Mn;0;NSM;;;;;N;;;;;
+07AF;THAANA OABOAFILI;Mn;0;NSM;;;;;N;;;;;
+07B0;THAANA SUKUN;Mn;0;NSM;;;;;N;;;;;
+07B1;THAANA LETTER NAA;Lo;0;AL;;;;;N;;;;;
+07C0;NKO DIGIT ZERO;Nd;0;R;;0;0;0;N;;;;;
+07C1;NKO DIGIT ONE;Nd;0;R;;1;1;1;N;;;;;
+07C2;NKO DIGIT TWO;Nd;0;R;;2;2;2;N;;;;;
+07C3;NKO DIGIT THREE;Nd;0;R;;3;3;3;N;;;;;
+07C4;NKO DIGIT FOUR;Nd;0;R;;4;4;4;N;;;;;
+07C5;NKO DIGIT FIVE;Nd;0;R;;5;5;5;N;;;;;
+07C6;NKO DIGIT SIX;Nd;0;R;;6;6;6;N;;;;;
+07C7;NKO DIGIT SEVEN;Nd;0;R;;7;7;7;N;;;;;
+07C8;NKO DIGIT EIGHT;Nd;0;R;;8;8;8;N;;;;;
+07C9;NKO DIGIT NINE;Nd;0;R;;9;9;9;N;;;;;
+07CA;NKO LETTER A;Lo;0;R;;;;;N;;;;;
+07CB;NKO LETTER EE;Lo;0;R;;;;;N;;;;;
+07CC;NKO LETTER I;Lo;0;R;;;;;N;;;;;
+07CD;NKO LETTER E;Lo;0;R;;;;;N;;;;;
+07CE;NKO LETTER U;Lo;0;R;;;;;N;;;;;
+07CF;NKO LETTER OO;Lo;0;R;;;;;N;;;;;
+07D0;NKO LETTER O;Lo;0;R;;;;;N;;;;;
+07D1;NKO LETTER DAGBASINNA;Lo;0;R;;;;;N;;;;;
+07D2;NKO LETTER N;Lo;0;R;;;;;N;;;;;
+07D3;NKO LETTER BA;Lo;0;R;;;;;N;;;;;
+07D4;NKO LETTER PA;Lo;0;R;;;;;N;;;;;
+07D5;NKO LETTER TA;Lo;0;R;;;;;N;;;;;
+07D6;NKO LETTER JA;Lo;0;R;;;;;N;;;;;
+07D7;NKO LETTER CHA;Lo;0;R;;;;;N;;;;;
+07D8;NKO LETTER DA;Lo;0;R;;;;;N;;;;;
+07D9;NKO LETTER RA;Lo;0;R;;;;;N;;;;;
+07DA;NKO LETTER RRA;Lo;0;R;;;;;N;;;;;
+07DB;NKO LETTER SA;Lo;0;R;;;;;N;;;;;
+07DC;NKO LETTER GBA;Lo;0;R;;;;;N;;;;;
+07DD;NKO LETTER FA;Lo;0;R;;;;;N;;;;;
+07DE;NKO LETTER KA;Lo;0;R;;;;;N;;;;;
+07DF;NKO LETTER LA;Lo;0;R;;;;;N;;;;;
+07E0;NKO LETTER NA WOLOSO;Lo;0;R;;;;;N;;;;;
+07E1;NKO LETTER MA;Lo;0;R;;;;;N;;;;;
+07E2;NKO LETTER NYA;Lo;0;R;;;;;N;;;;;
+07E3;NKO LETTER NA;Lo;0;R;;;;;N;;;;;
+07E4;NKO LETTER HA;Lo;0;R;;;;;N;;;;;
+07E5;NKO LETTER WA;Lo;0;R;;;;;N;;;;;
+07E6;NKO LETTER YA;Lo;0;R;;;;;N;;;;;
+07E7;NKO LETTER NYA WOLOSO;Lo;0;R;;;;;N;;;;;
+07E8;NKO LETTER JONA JA;Lo;0;R;;;;;N;;;;;
+07E9;NKO LETTER JONA CHA;Lo;0;R;;;;;N;;;;;
+07EA;NKO LETTER JONA RA;Lo;0;R;;;;;N;;;;;
+07EB;NKO COMBINING SHORT HIGH TONE;Mn;230;NSM;;;;;N;;;;;
+07EC;NKO COMBINING SHORT LOW TONE;Mn;230;NSM;;;;;N;;;;;
+07ED;NKO COMBINING SHORT RISING TONE;Mn;230;NSM;;;;;N;;;;;
+07EE;NKO COMBINING LONG DESCENDING TONE;Mn;230;NSM;;;;;N;;;;;
+07EF;NKO COMBINING LONG HIGH TONE;Mn;230;NSM;;;;;N;;;;;
+07F0;NKO COMBINING LONG LOW TONE;Mn;230;NSM;;;;;N;;;;;
+07F1;NKO COMBINING LONG RISING TONE;Mn;230;NSM;;;;;N;;;;;
+07F2;NKO COMBINING NASALIZATION MARK;Mn;220;NSM;;;;;N;;;;;
+07F3;NKO COMBINING DOUBLE DOT ABOVE;Mn;230;NSM;;;;;N;;;;;
+07F4;NKO HIGH TONE APOSTROPHE;Lm;0;R;;;;;N;;;;;
+07F5;NKO LOW TONE APOSTROPHE;Lm;0;R;;;;;N;;;;;
+07F6;NKO SYMBOL OO DENNEN;So;0;ON;;;;;N;;;;;
+07F7;NKO SYMBOL GBAKURUNEN;Po;0;ON;;;;;N;;;;;
+07F8;NKO COMMA;Po;0;ON;;;;;N;;;;;
+07F9;NKO EXCLAMATION MARK;Po;0;ON;;;;;N;;;;;
+07FA;NKO LAJANYALAN;Lm;0;R;;;;;N;;;;;
+0800;SAMARITAN LETTER ALAF;Lo;0;R;;;;;N;;;;;
+0801;SAMARITAN LETTER BIT;Lo;0;R;;;;;N;;;;;
+0802;SAMARITAN LETTER GAMAN;Lo;0;R;;;;;N;;;;;
+0803;SAMARITAN LETTER DALAT;Lo;0;R;;;;;N;;;;;
+0804;SAMARITAN LETTER IY;Lo;0;R;;;;;N;;;;;
+0805;SAMARITAN LETTER BAA;Lo;0;R;;;;;N;;;;;
+0806;SAMARITAN LETTER ZEN;Lo;0;R;;;;;N;;;;;
+0807;SAMARITAN LETTER IT;Lo;0;R;;;;;N;;;;;
+0808;SAMARITAN LETTER TIT;Lo;0;R;;;;;N;;;;;
+0809;SAMARITAN LETTER YUT;Lo;0;R;;;;;N;;;;;
+080A;SAMARITAN LETTER KAAF;Lo;0;R;;;;;N;;;;;
+080B;SAMARITAN LETTER LABAT;Lo;0;R;;;;;N;;;;;
+080C;SAMARITAN LETTER MIM;Lo;0;R;;;;;N;;;;;
+080D;SAMARITAN LETTER NUN;Lo;0;R;;;;;N;;;;;
+080E;SAMARITAN LETTER SINGAAT;Lo;0;R;;;;;N;;;;;
+080F;SAMARITAN LETTER IN;Lo;0;R;;;;;N;;;;;
+0810;SAMARITAN LETTER FI;Lo;0;R;;;;;N;;;;;
+0811;SAMARITAN LETTER TSAADIY;Lo;0;R;;;;;N;;;;;
+0812;SAMARITAN LETTER QUF;Lo;0;R;;;;;N;;;;;
+0813;SAMARITAN LETTER RISH;Lo;0;R;;;;;N;;;;;
+0814;SAMARITAN LETTER SHAN;Lo;0;R;;;;;N;;;;;
+0815;SAMARITAN LETTER TAAF;Lo;0;R;;;;;N;;;;;
+0816;SAMARITAN MARK IN;Mn;230;NSM;;;;;N;;;;;
+0817;SAMARITAN MARK IN-ALAF;Mn;230;NSM;;;;;N;;;;;
+0818;SAMARITAN MARK OCCLUSION;Mn;230;NSM;;;;;N;;;;;
+0819;SAMARITAN MARK DAGESH;Mn;230;NSM;;;;;N;;;;;
+081A;SAMARITAN MODIFIER LETTER EPENTHETIC YUT;Lm;0;R;;;;;N;;;;;
+081B;SAMARITAN MARK EPENTHETIC YUT;Mn;230;NSM;;;;;N;;;;;
+081C;SAMARITAN VOWEL SIGN LONG E;Mn;230;NSM;;;;;N;;;;;
+081D;SAMARITAN VOWEL SIGN E;Mn;230;NSM;;;;;N;;;;;
+081E;SAMARITAN VOWEL SIGN OVERLONG AA;Mn;230;NSM;;;;;N;;;;;
+081F;SAMARITAN VOWEL SIGN LONG AA;Mn;230;NSM;;;;;N;;;;;
+0820;SAMARITAN VOWEL SIGN AA;Mn;230;NSM;;;;;N;;;;;
+0821;SAMARITAN VOWEL SIGN OVERLONG A;Mn;230;NSM;;;;;N;;;;;
+0822;SAMARITAN VOWEL SIGN LONG A;Mn;230;NSM;;;;;N;;;;;
+0823;SAMARITAN VOWEL SIGN A;Mn;230;NSM;;;;;N;;;;;
+0824;SAMARITAN MODIFIER LETTER SHORT A;Lm;0;R;;;;;N;;;;;
+0825;SAMARITAN VOWEL SIGN SHORT A;Mn;230;NSM;;;;;N;;;;;
+0826;SAMARITAN VOWEL SIGN LONG U;Mn;230;NSM;;;;;N;;;;;
+0827;SAMARITAN VOWEL SIGN U;Mn;230;NSM;;;;;N;;;;;
+0828;SAMARITAN MODIFIER LETTER I;Lm;0;R;;;;;N;;;;;
+0829;SAMARITAN VOWEL SIGN LONG I;Mn;230;NSM;;;;;N;;;;;
+082A;SAMARITAN VOWEL SIGN I;Mn;230;NSM;;;;;N;;;;;
+082B;SAMARITAN VOWEL SIGN O;Mn;230;NSM;;;;;N;;;;;
+082C;SAMARITAN VOWEL SIGN SUKUN;Mn;230;NSM;;;;;N;;;;;
+082D;SAMARITAN MARK NEQUDAA;Mn;230;NSM;;;;;N;;;;;
+0830;SAMARITAN PUNCTUATION NEQUDAA;Po;0;R;;;;;N;;;;;
+0831;SAMARITAN PUNCTUATION AFSAAQ;Po;0;R;;;;;N;;;;;
+0832;SAMARITAN PUNCTUATION ANGED;Po;0;R;;;;;N;;;;;
+0833;SAMARITAN PUNCTUATION BAU;Po;0;R;;;;;N;;;;;
+0834;SAMARITAN PUNCTUATION ATMAAU;Po;0;R;;;;;N;;;;;
+0835;SAMARITAN PUNCTUATION SHIYYAALAA;Po;0;R;;;;;N;;;;;
+0836;SAMARITAN ABBREVIATION MARK;Po;0;R;;;;;N;;;;;
+0837;SAMARITAN PUNCTUATION MELODIC QITSA;Po;0;R;;;;;N;;;;;
+0838;SAMARITAN PUNCTUATION ZIQAA;Po;0;R;;;;;N;;;;;
+0839;SAMARITAN PUNCTUATION QITSA;Po;0;R;;;;;N;;;;;
+083A;SAMARITAN PUNCTUATION ZAEF;Po;0;R;;;;;N;;;;;
+083B;SAMARITAN PUNCTUATION TURU;Po;0;R;;;;;N;;;;;
+083C;SAMARITAN PUNCTUATION ARKAANU;Po;0;R;;;;;N;;;;;
+083D;SAMARITAN PUNCTUATION SOF MASHFAAT;Po;0;R;;;;;N;;;;;
+083E;SAMARITAN PUNCTUATION ANNAAU;Po;0;R;;;;;N;;;;;
+0840;MANDAIC LETTER HALQA;Lo;0;R;;;;;N;;;;;
+0841;MANDAIC LETTER AB;Lo;0;R;;;;;N;;;;;
+0842;MANDAIC LETTER AG;Lo;0;R;;;;;N;;;;;
+0843;MANDAIC LETTER AD;Lo;0;R;;;;;N;;;;;
+0844;MANDAIC LETTER AH;Lo;0;R;;;;;N;;;;;
+0845;MANDAIC LETTER USHENNA;Lo;0;R;;;;;N;;;;;
+0846;MANDAIC LETTER AZ;Lo;0;R;;;;;N;;;;;
+0847;MANDAIC LETTER IT;Lo;0;R;;;;;N;;;;;
+0848;MANDAIC LETTER ATT;Lo;0;R;;;;;N;;;;;
+0849;MANDAIC LETTER AKSA;Lo;0;R;;;;;N;;;;;
+084A;MANDAIC LETTER AK;Lo;0;R;;;;;N;;;;;
+084B;MANDAIC LETTER AL;Lo;0;R;;;;;N;;;;;
+084C;MANDAIC LETTER AM;Lo;0;R;;;;;N;;;;;
+084D;MANDAIC LETTER AN;Lo;0;R;;;;;N;;;;;
+084E;MANDAIC LETTER AS;Lo;0;R;;;;;N;;;;;
+084F;MANDAIC LETTER IN;Lo;0;R;;;;;N;;;;;
+0850;MANDAIC LETTER AP;Lo;0;R;;;;;N;;;;;
+0851;MANDAIC LETTER ASZ;Lo;0;R;;;;;N;;;;;
+0852;MANDAIC LETTER AQ;Lo;0;R;;;;;N;;;;;
+0853;MANDAIC LETTER AR;Lo;0;R;;;;;N;;;;;
+0854;MANDAIC LETTER ASH;Lo;0;R;;;;;N;;;;;
+0855;MANDAIC LETTER AT;Lo;0;R;;;;;N;;;;;
+0856;MANDAIC LETTER DUSHENNA;Lo;0;R;;;;;N;;;;;
+0857;MANDAIC LETTER KAD;Lo;0;R;;;;;N;;;;;
+0858;MANDAIC LETTER AIN;Lo;0;R;;;;;N;;;;;
+0859;MANDAIC AFFRICATION MARK;Mn;220;NSM;;;;;N;;;;;
+085A;MANDAIC VOCALIZATION MARK;Mn;220;NSM;;;;;N;;;;;
+085B;MANDAIC GEMINATION MARK;Mn;220;NSM;;;;;N;;;;;
+085E;MANDAIC PUNCTUATION;Po;0;R;;;;;N;;;;;
+0900;DEVANAGARI SIGN INVERTED CANDRABINDU;Mn;0;NSM;;;;;N;;;;;
+0901;DEVANAGARI SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;;
+0902;DEVANAGARI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;
+0903;DEVANAGARI SIGN VISARGA;Mc;0;L;;;;;N;;;;;
+0904;DEVANAGARI LETTER SHORT A;Lo;0;L;;;;;N;;;;;
+0905;DEVANAGARI LETTER A;Lo;0;L;;;;;N;;;;;
+0906;DEVANAGARI LETTER AA;Lo;0;L;;;;;N;;;;;
+0907;DEVANAGARI LETTER I;Lo;0;L;;;;;N;;;;;
+0908;DEVANAGARI LETTER II;Lo;0;L;;;;;N;;;;;
+0909;DEVANAGARI LETTER U;Lo;0;L;;;;;N;;;;;
+090A;DEVANAGARI LETTER UU;Lo;0;L;;;;;N;;;;;
+090B;DEVANAGARI LETTER VOCALIC R;Lo;0;L;;;;;N;;;;;
+090C;DEVANAGARI LETTER VOCALIC L;Lo;0;L;;;;;N;;;;;
+090D;DEVANAGARI LETTER CANDRA E;Lo;0;L;;;;;N;;;;;
+090E;DEVANAGARI LETTER SHORT E;Lo;0;L;;;;;N;;;;;
+090F;DEVANAGARI LETTER E;Lo;0;L;;;;;N;;;;;
+0910;DEVANAGARI LETTER AI;Lo;0;L;;;;;N;;;;;
+0911;DEVANAGARI LETTER CANDRA O;Lo;0;L;;;;;N;;;;;
+0912;DEVANAGARI LETTER SHORT O;Lo;0;L;;;;;N;;;;;
+0913;DEVANAGARI LETTER O;Lo;0;L;;;;;N;;;;;
+0914;DEVANAGARI LETTER AU;Lo;0;L;;;;;N;;;;;
+0915;DEVANAGARI LETTER KA;Lo;0;L;;;;;N;;;;;
+0916;DEVANAGARI LETTER KHA;Lo;0;L;;;;;N;;;;;
+0917;DEVANAGARI LETTER GA;Lo;0;L;;;;;N;;;;;
+0918;DEVANAGARI LETTER GHA;Lo;0;L;;;;;N;;;;;
+0919;DEVANAGARI LETTER NGA;Lo;0;L;;;;;N;;;;;
+091A;DEVANAGARI LETTER CA;Lo;0;L;;;;;N;;;;;
+091B;DEVANAGARI LETTER CHA;Lo;0;L;;;;;N;;;;;
+091C;DEVANAGARI LETTER JA;Lo;0;L;;;;;N;;;;;
+091D;DEVANAGARI LETTER JHA;Lo;0;L;;;;;N;;;;;
+091E;DEVANAGARI LETTER NYA;Lo;0;L;;;;;N;;;;;
+091F;DEVANAGARI LETTER TTA;Lo;0;L;;;;;N;;;;;
+0920;DEVANAGARI LETTER TTHA;Lo;0;L;;;;;N;;;;;
+0921;DEVANAGARI LETTER DDA;Lo;0;L;;;;;N;;;;;
+0922;DEVANAGARI LETTER DDHA;Lo;0;L;;;;;N;;;;;
+0923;DEVANAGARI LETTER NNA;Lo;0;L;;;;;N;;;;;
+0924;DEVANAGARI LETTER TA;Lo;0;L;;;;;N;;;;;
+0925;DEVANAGARI LETTER THA;Lo;0;L;;;;;N;;;;;
+0926;DEVANAGARI LETTER DA;Lo;0;L;;;;;N;;;;;
+0927;DEVANAGARI LETTER DHA;Lo;0;L;;;;;N;;;;;
+0928;DEVANAGARI LETTER NA;Lo;0;L;;;;;N;;;;;
+0929;DEVANAGARI LETTER NNNA;Lo;0;L;0928 093C;;;;N;;;;;
+092A;DEVANAGARI LETTER PA;Lo;0;L;;;;;N;;;;;
+092B;DEVANAGARI LETTER PHA;Lo;0;L;;;;;N;;;;;
+092C;DEVANAGARI LETTER BA;Lo;0;L;;;;;N;;;;;
+092D;DEVANAGARI LETTER BHA;Lo;0;L;;;;;N;;;;;
+092E;DEVANAGARI LETTER MA;Lo;0;L;;;;;N;;;;;
+092F;DEVANAGARI LETTER YA;Lo;0;L;;;;;N;;;;;
+0930;DEVANAGARI LETTER RA;Lo;0;L;;;;;N;;;;;
+0931;DEVANAGARI LETTER RRA;Lo;0;L;0930 093C;;;;N;;;;;
+0932;DEVANAGARI LETTER LA;Lo;0;L;;;;;N;;;;;
+0933;DEVANAGARI LETTER LLA;Lo;0;L;;;;;N;;;;;
+0934;DEVANAGARI LETTER LLLA;Lo;0;L;0933 093C;;;;N;;;;;
+0935;DEVANAGARI LETTER VA;Lo;0;L;;;;;N;;;;;
+0936;DEVANAGARI LETTER SHA;Lo;0;L;;;;;N;;;;;
+0937;DEVANAGARI LETTER SSA;Lo;0;L;;;;;N;;;;;
+0938;DEVANAGARI LETTER SA;Lo;0;L;;;;;N;;;;;
+0939;DEVANAGARI LETTER HA;Lo;0;L;;;;;N;;;;;
+093A;DEVANAGARI VOWEL SIGN OE;Mn;0;NSM;;;;;N;;;;;
+093B;DEVANAGARI VOWEL SIGN OOE;Mc;0;L;;;;;N;;;;;
+093C;DEVANAGARI SIGN NUKTA;Mn;7;NSM;;;;;N;;;;;
+093D;DEVANAGARI SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;;
+093E;DEVANAGARI VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
+093F;DEVANAGARI VOWEL SIGN I;Mc;0;L;;;;;N;;;;;
+0940;DEVANAGARI VOWEL SIGN II;Mc;0;L;;;;;N;;;;;
+0941;DEVANAGARI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+0942;DEVANAGARI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;
+0943;DEVANAGARI VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;;
+0944;DEVANAGARI VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;;
+0945;DEVANAGARI VOWEL SIGN CANDRA E;Mn;0;NSM;;;;;N;;;;;
+0946;DEVANAGARI VOWEL SIGN SHORT E;Mn;0;NSM;;;;;N;;;;;
+0947;DEVANAGARI VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;;
+0948;DEVANAGARI VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;;
+0949;DEVANAGARI VOWEL SIGN CANDRA O;Mc;0;L;;;;;N;;;;;
+094A;DEVANAGARI VOWEL SIGN SHORT O;Mc;0;L;;;;;N;;;;;
+094B;DEVANAGARI VOWEL SIGN O;Mc;0;L;;;;;N;;;;;
+094C;DEVANAGARI VOWEL SIGN AU;Mc;0;L;;;;;N;;;;;
+094D;DEVANAGARI SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;
+094E;DEVANAGARI VOWEL SIGN PRISHTHAMATRA E;Mc;0;L;;;;;N;;;;;
+094F;DEVANAGARI VOWEL SIGN AW;Mc;0;L;;;;;N;;;;;
+0950;DEVANAGARI OM;Lo;0;L;;;;;N;;;;;
+0951;DEVANAGARI STRESS SIGN UDATTA;Mn;230;NSM;;;;;N;;;;;
+0952;DEVANAGARI STRESS SIGN ANUDATTA;Mn;220;NSM;;;;;N;;;;;
+0953;DEVANAGARI GRAVE ACCENT;Mn;230;NSM;;;;;N;;;;;
+0954;DEVANAGARI ACUTE ACCENT;Mn;230;NSM;;;;;N;;;;;
+0955;DEVANAGARI VOWEL SIGN CANDRA LONG E;Mn;0;NSM;;;;;N;;;;;
+0956;DEVANAGARI VOWEL SIGN UE;Mn;0;NSM;;;;;N;;;;;
+0957;DEVANAGARI VOWEL SIGN UUE;Mn;0;NSM;;;;;N;;;;;
+0958;DEVANAGARI LETTER QA;Lo;0;L;0915 093C;;;;N;;;;;
+0959;DEVANAGARI LETTER KHHA;Lo;0;L;0916 093C;;;;N;;;;;
+095A;DEVANAGARI LETTER GHHA;Lo;0;L;0917 093C;;;;N;;;;;
+095B;DEVANAGARI LETTER ZA;Lo;0;L;091C 093C;;;;N;;;;;
+095C;DEVANAGARI LETTER DDDHA;Lo;0;L;0921 093C;;;;N;;;;;
+095D;DEVANAGARI LETTER RHA;Lo;0;L;0922 093C;;;;N;;;;;
+095E;DEVANAGARI LETTER FA;Lo;0;L;092B 093C;;;;N;;;;;
+095F;DEVANAGARI LETTER YYA;Lo;0;L;092F 093C;;;;N;;;;;
+0960;DEVANAGARI LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;;
+0961;DEVANAGARI LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;;
+0962;DEVANAGARI VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;;
+0963;DEVANAGARI VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;;
+0964;DEVANAGARI DANDA;Po;0;L;;;;;N;;;;;
+0965;DEVANAGARI DOUBLE DANDA;Po;0;L;;;;;N;;;;;
+0966;DEVANAGARI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+0967;DEVANAGARI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+0968;DEVANAGARI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+0969;DEVANAGARI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+096A;DEVANAGARI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+096B;DEVANAGARI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+096C;DEVANAGARI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+096D;DEVANAGARI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+096E;DEVANAGARI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+096F;DEVANAGARI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+0970;DEVANAGARI ABBREVIATION SIGN;Po;0;L;;;;;N;;;;;
+0971;DEVANAGARI SIGN HIGH SPACING DOT;Lm;0;L;;;;;N;;;;;
+0972;DEVANAGARI LETTER CANDRA A;Lo;0;L;;;;;N;;;;;
+0973;DEVANAGARI LETTER OE;Lo;0;L;;;;;N;;;;;
+0974;DEVANAGARI LETTER OOE;Lo;0;L;;;;;N;;;;;
+0975;DEVANAGARI LETTER AW;Lo;0;L;;;;;N;;;;;
+0976;DEVANAGARI LETTER UE;Lo;0;L;;;;;N;;;;;
+0977;DEVANAGARI LETTER UUE;Lo;0;L;;;;;N;;;;;
+0979;DEVANAGARI LETTER ZHA;Lo;0;L;;;;;N;;;;;
+097A;DEVANAGARI LETTER HEAVY YA;Lo;0;L;;;;;N;;;;;
+097B;DEVANAGARI LETTER GGA;Lo;0;L;;;;;N;;;;;
+097C;DEVANAGARI LETTER JJA;Lo;0;L;;;;;N;;;;;
+097D;DEVANAGARI LETTER GLOTTAL STOP;Lo;0;L;;;;;N;;;;;
+097E;DEVANAGARI LETTER DDDA;Lo;0;L;;;;;N;;;;;
+097F;DEVANAGARI LETTER BBA;Lo;0;L;;;;;N;;;;;
+0981;BENGALI SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;;
+0982;BENGALI SIGN ANUSVARA;Mc;0;L;;;;;N;;;;;
+0983;BENGALI SIGN VISARGA;Mc;0;L;;;;;N;;;;;
+0985;BENGALI LETTER A;Lo;0;L;;;;;N;;;;;
+0986;BENGALI LETTER AA;Lo;0;L;;;;;N;;;;;
+0987;BENGALI LETTER I;Lo;0;L;;;;;N;;;;;
+0988;BENGALI LETTER II;Lo;0;L;;;;;N;;;;;
+0989;BENGALI LETTER U;Lo;0;L;;;;;N;;;;;
+098A;BENGALI LETTER UU;Lo;0;L;;;;;N;;;;;
+098B;BENGALI LETTER VOCALIC R;Lo;0;L;;;;;N;;;;;
+098C;BENGALI LETTER VOCALIC L;Lo;0;L;;;;;N;;;;;
+098F;BENGALI LETTER E;Lo;0;L;;;;;N;;;;;
+0990;BENGALI LETTER AI;Lo;0;L;;;;;N;;;;;
+0993;BENGALI LETTER O;Lo;0;L;;;;;N;;;;;
+0994;BENGALI LETTER AU;Lo;0;L;;;;;N;;;;;
+0995;BENGALI LETTER KA;Lo;0;L;;;;;N;;;;;
+0996;BENGALI LETTER KHA;Lo;0;L;;;;;N;;;;;
+0997;BENGALI LETTER GA;Lo;0;L;;;;;N;;;;;
+0998;BENGALI LETTER GHA;Lo;0;L;;;;;N;;;;;
+0999;BENGALI LETTER NGA;Lo;0;L;;;;;N;;;;;
+099A;BENGALI LETTER CA;Lo;0;L;;;;;N;;;;;
+099B;BENGALI LETTER CHA;Lo;0;L;;;;;N;;;;;
+099C;BENGALI LETTER JA;Lo;0;L;;;;;N;;;;;
+099D;BENGALI LETTER JHA;Lo;0;L;;;;;N;;;;;
+099E;BENGALI LETTER NYA;Lo;0;L;;;;;N;;;;;
+099F;BENGALI LETTER TTA;Lo;0;L;;;;;N;;;;;
+09A0;BENGALI LETTER TTHA;Lo;0;L;;;;;N;;;;;
+09A1;BENGALI LETTER DDA;Lo;0;L;;;;;N;;;;;
+09A2;BENGALI LETTER DDHA;Lo;0;L;;;;;N;;;;;
+09A3;BENGALI LETTER NNA;Lo;0;L;;;;;N;;;;;
+09A4;BENGALI LETTER TA;Lo;0;L;;;;;N;;;;;
+09A5;BENGALI LETTER THA;Lo;0;L;;;;;N;;;;;
+09A6;BENGALI LETTER DA;Lo;0;L;;;;;N;;;;;
+09A7;BENGALI LETTER DHA;Lo;0;L;;;;;N;;;;;
+09A8;BENGALI LETTER NA;Lo;0;L;;;;;N;;;;;
+09AA;BENGALI LETTER PA;Lo;0;L;;;;;N;;;;;
+09AB;BENGALI LETTER PHA;Lo;0;L;;;;;N;;;;;
+09AC;BENGALI LETTER BA;Lo;0;L;;;;;N;;;;;
+09AD;BENGALI LETTER BHA;Lo;0;L;;;;;N;;;;;
+09AE;BENGALI LETTER MA;Lo;0;L;;;;;N;;;;;
+09AF;BENGALI LETTER YA;Lo;0;L;;;;;N;;;;;
+09B0;BENGALI LETTER RA;Lo;0;L;;;;;N;;;;;
+09B2;BENGALI LETTER LA;Lo;0;L;;;;;N;;;;;
+09B6;BENGALI LETTER SHA;Lo;0;L;;;;;N;;;;;
+09B7;BENGALI LETTER SSA;Lo;0;L;;;;;N;;;;;
+09B8;BENGALI LETTER SA;Lo;0;L;;;;;N;;;;;
+09B9;BENGALI LETTER HA;Lo;0;L;;;;;N;;;;;
+09BC;BENGALI SIGN NUKTA;Mn;7;NSM;;;;;N;;;;;
+09BD;BENGALI SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;;
+09BE;BENGALI VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
+09BF;BENGALI VOWEL SIGN I;Mc;0;L;;;;;N;;;;;
+09C0;BENGALI VOWEL SIGN II;Mc;0;L;;;;;N;;;;;
+09C1;BENGALI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+09C2;BENGALI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;
+09C3;BENGALI VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;;
+09C4;BENGALI VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;;
+09C7;BENGALI VOWEL SIGN E;Mc;0;L;;;;;N;;;;;
+09C8;BENGALI VOWEL SIGN AI;Mc;0;L;;;;;N;;;;;
+09CB;BENGALI VOWEL SIGN O;Mc;0;L;09C7 09BE;;;;N;;;;;
+09CC;BENGALI VOWEL SIGN AU;Mc;0;L;09C7 09D7;;;;N;;;;;
+09CD;BENGALI SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;
+09CE;BENGALI LETTER KHANDA TA;Lo;0;L;;;;;N;;;;;
+09D7;BENGALI AU LENGTH MARK;Mc;0;L;;;;;N;;;;;
+09DC;BENGALI LETTER RRA;Lo;0;L;09A1 09BC;;;;N;;;;;
+09DD;BENGALI LETTER RHA;Lo;0;L;09A2 09BC;;;;N;;;;;
+09DF;BENGALI LETTER YYA;Lo;0;L;09AF 09BC;;;;N;;;;;
+09E0;BENGALI LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;;
+09E1;BENGALI LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;;
+09E2;BENGALI VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;;
+09E3;BENGALI VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;;
+09E6;BENGALI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+09E7;BENGALI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+09E8;BENGALI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+09E9;BENGALI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+09EA;BENGALI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+09EB;BENGALI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+09EC;BENGALI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+09ED;BENGALI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+09EE;BENGALI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+09EF;BENGALI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+09F0;BENGALI LETTER RA WITH MIDDLE DIAGONAL;Lo;0;L;;;;;N;;;;;
+09F1;BENGALI LETTER RA WITH LOWER DIAGONAL;Lo;0;L;;;;;N;BENGALI LETTER VA WITH LOWER DIAGONAL;;;;
+09F2;BENGALI RUPEE MARK;Sc;0;ET;;;;;N;;;;;
+09F3;BENGALI RUPEE SIGN;Sc;0;ET;;;;;N;;;;;
+09F4;BENGALI CURRENCY NUMERATOR ONE;No;0;L;;;;1/16;N;;;;;
+09F5;BENGALI CURRENCY NUMERATOR TWO;No;0;L;;;;1/8;N;;;;;
+09F6;BENGALI CURRENCY NUMERATOR THREE;No;0;L;;;;3/16;N;;;;;
+09F7;BENGALI CURRENCY NUMERATOR FOUR;No;0;L;;;;1/4;N;;;;;
+09F8;BENGALI CURRENCY NUMERATOR ONE LESS THAN THE DENOMINATOR;No;0;L;;;;3/4;N;;;;;
+09F9;BENGALI CURRENCY DENOMINATOR SIXTEEN;No;0;L;;;;16;N;;;;;
+09FA;BENGALI ISSHAR;So;0;L;;;;;N;;;;;
+09FB;BENGALI GANDA MARK;Sc;0;ET;;;;;N;;;;;
+0A01;GURMUKHI SIGN ADAK BINDI;Mn;0;NSM;;;;;N;;;;;
+0A02;GURMUKHI SIGN BINDI;Mn;0;NSM;;;;;N;;;;;
+0A03;GURMUKHI SIGN VISARGA;Mc;0;L;;;;;N;;;;;
+0A05;GURMUKHI LETTER A;Lo;0;L;;;;;N;;;;;
+0A06;GURMUKHI LETTER AA;Lo;0;L;;;;;N;;;;;
+0A07;GURMUKHI LETTER I;Lo;0;L;;;;;N;;;;;
+0A08;GURMUKHI LETTER II;Lo;0;L;;;;;N;;;;;
+0A09;GURMUKHI LETTER U;Lo;0;L;;;;;N;;;;;
+0A0A;GURMUKHI LETTER UU;Lo;0;L;;;;;N;;;;;
+0A0F;GURMUKHI LETTER EE;Lo;0;L;;;;;N;;;;;
+0A10;GURMUKHI LETTER AI;Lo;0;L;;;;;N;;;;;
+0A13;GURMUKHI LETTER OO;Lo;0;L;;;;;N;;;;;
+0A14;GURMUKHI LETTER AU;Lo;0;L;;;;;N;;;;;
+0A15;GURMUKHI LETTER KA;Lo;0;L;;;;;N;;;;;
+0A16;GURMUKHI LETTER KHA;Lo;0;L;;;;;N;;;;;
+0A17;GURMUKHI LETTER GA;Lo;0;L;;;;;N;;;;;
+0A18;GURMUKHI LETTER GHA;Lo;0;L;;;;;N;;;;;
+0A19;GURMUKHI LETTER NGA;Lo;0;L;;;;;N;;;;;
+0A1A;GURMUKHI LETTER CA;Lo;0;L;;;;;N;;;;;
+0A1B;GURMUKHI LETTER CHA;Lo;0;L;;;;;N;;;;;
+0A1C;GURMUKHI LETTER JA;Lo;0;L;;;;;N;;;;;
+0A1D;GURMUKHI LETTER JHA;Lo;0;L;;;;;N;;;;;
+0A1E;GURMUKHI LETTER NYA;Lo;0;L;;;;;N;;;;;
+0A1F;GURMUKHI LETTER TTA;Lo;0;L;;;;;N;;;;;
+0A20;GURMUKHI LETTER TTHA;Lo;0;L;;;;;N;;;;;
+0A21;GURMUKHI LETTER DDA;Lo;0;L;;;;;N;;;;;
+0A22;GURMUKHI LETTER DDHA;Lo;0;L;;;;;N;;;;;
+0A23;GURMUKHI LETTER NNA;Lo;0;L;;;;;N;;;;;
+0A24;GURMUKHI LETTER TA;Lo;0;L;;;;;N;;;;;
+0A25;GURMUKHI LETTER THA;Lo;0;L;;;;;N;;;;;
+0A26;GURMUKHI LETTER DA;Lo;0;L;;;;;N;;;;;
+0A27;GURMUKHI LETTER DHA;Lo;0;L;;;;;N;;;;;
+0A28;GURMUKHI LETTER NA;Lo;0;L;;;;;N;;;;;
+0A2A;GURMUKHI LETTER PA;Lo;0;L;;;;;N;;;;;
+0A2B;GURMUKHI LETTER PHA;Lo;0;L;;;;;N;;;;;
+0A2C;GURMUKHI LETTER BA;Lo;0;L;;;;;N;;;;;
+0A2D;GURMUKHI LETTER BHA;Lo;0;L;;;;;N;;;;;
+0A2E;GURMUKHI LETTER MA;Lo;0;L;;;;;N;;;;;
+0A2F;GURMUKHI LETTER YA;Lo;0;L;;;;;N;;;;;
+0A30;GURMUKHI LETTER RA;Lo;0;L;;;;;N;;;;;
+0A32;GURMUKHI LETTER LA;Lo;0;L;;;;;N;;;;;
+0A33;GURMUKHI LETTER LLA;Lo;0;L;0A32 0A3C;;;;N;;;;;
+0A35;GURMUKHI LETTER VA;Lo;0;L;;;;;N;;;;;
+0A36;GURMUKHI LETTER SHA;Lo;0;L;0A38 0A3C;;;;N;;;;;
+0A38;GURMUKHI LETTER SA;Lo;0;L;;;;;N;;;;;
+0A39;GURMUKHI LETTER HA;Lo;0;L;;;;;N;;;;;
+0A3C;GURMUKHI SIGN NUKTA;Mn;7;NSM;;;;;N;;;;;
+0A3E;GURMUKHI VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
+0A3F;GURMUKHI VOWEL SIGN I;Mc;0;L;;;;;N;;;;;
+0A40;GURMUKHI VOWEL SIGN II;Mc;0;L;;;;;N;;;;;
+0A41;GURMUKHI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+0A42;GURMUKHI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;
+0A47;GURMUKHI VOWEL SIGN EE;Mn;0;NSM;;;;;N;;;;;
+0A48;GURMUKHI VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;;
+0A4B;GURMUKHI VOWEL SIGN OO;Mn;0;NSM;;;;;N;;;;;
+0A4C;GURMUKHI VOWEL SIGN AU;Mn;0;NSM;;;;;N;;;;;
+0A4D;GURMUKHI SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;
+0A51;GURMUKHI SIGN UDAAT;Mn;0;NSM;;;;;N;;;;;
+0A59;GURMUKHI LETTER KHHA;Lo;0;L;0A16 0A3C;;;;N;;;;;
+0A5A;GURMUKHI LETTER GHHA;Lo;0;L;0A17 0A3C;;;;N;;;;;
+0A5B;GURMUKHI LETTER ZA;Lo;0;L;0A1C 0A3C;;;;N;;;;;
+0A5C;GURMUKHI LETTER RRA;Lo;0;L;;;;;N;;;;;
+0A5E;GURMUKHI LETTER FA;Lo;0;L;0A2B 0A3C;;;;N;;;;;
+0A66;GURMUKHI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+0A67;GURMUKHI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+0A68;GURMUKHI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+0A69;GURMUKHI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+0A6A;GURMUKHI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+0A6B;GURMUKHI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+0A6C;GURMUKHI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+0A6D;GURMUKHI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+0A6E;GURMUKHI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+0A6F;GURMUKHI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+0A70;GURMUKHI TIPPI;Mn;0;NSM;;;;;N;;;;;
+0A71;GURMUKHI ADDAK;Mn;0;NSM;;;;;N;;;;;
+0A72;GURMUKHI IRI;Lo;0;L;;;;;N;;;;;
+0A73;GURMUKHI URA;Lo;0;L;;;;;N;;;;;
+0A74;GURMUKHI EK ONKAR;Lo;0;L;;;;;N;;;;;
+0A75;GURMUKHI SIGN YAKASH;Mn;0;NSM;;;;;N;;;;;
+0A81;GUJARATI SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;;
+0A82;GUJARATI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;
+0A83;GUJARATI SIGN VISARGA;Mc;0;L;;;;;N;;;;;
+0A85;GUJARATI LETTER A;Lo;0;L;;;;;N;;;;;
+0A86;GUJARATI LETTER AA;Lo;0;L;;;;;N;;;;;
+0A87;GUJARATI LETTER I;Lo;0;L;;;;;N;;;;;
+0A88;GUJARATI LETTER II;Lo;0;L;;;;;N;;;;;
+0A89;GUJARATI LETTER U;Lo;0;L;;;;;N;;;;;
+0A8A;GUJARATI LETTER UU;Lo;0;L;;;;;N;;;;;
+0A8B;GUJARATI LETTER VOCALIC R;Lo;0;L;;;;;N;;;;;
+0A8C;GUJARATI LETTER VOCALIC L;Lo;0;L;;;;;N;;;;;
+0A8D;GUJARATI VOWEL CANDRA E;Lo;0;L;;;;;N;;;;;
+0A8F;GUJARATI LETTER E;Lo;0;L;;;;;N;;;;;
+0A90;GUJARATI LETTER AI;Lo;0;L;;;;;N;;;;;
+0A91;GUJARATI VOWEL CANDRA O;Lo;0;L;;;;;N;;;;;
+0A93;GUJARATI LETTER O;Lo;0;L;;;;;N;;;;;
+0A94;GUJARATI LETTER AU;Lo;0;L;;;;;N;;;;;
+0A95;GUJARATI LETTER KA;Lo;0;L;;;;;N;;;;;
+0A96;GUJARATI LETTER KHA;Lo;0;L;;;;;N;;;;;
+0A97;GUJARATI LETTER GA;Lo;0;L;;;;;N;;;;;
+0A98;GUJARATI LETTER GHA;Lo;0;L;;;;;N;;;;;
+0A99;GUJARATI LETTER NGA;Lo;0;L;;;;;N;;;;;
+0A9A;GUJARATI LETTER CA;Lo;0;L;;;;;N;;;;;
+0A9B;GUJARATI LETTER CHA;Lo;0;L;;;;;N;;;;;
+0A9C;GUJARATI LETTER JA;Lo;0;L;;;;;N;;;;;
+0A9D;GUJARATI LETTER JHA;Lo;0;L;;;;;N;;;;;
+0A9E;GUJARATI LETTER NYA;Lo;0;L;;;;;N;;;;;
+0A9F;GUJARATI LETTER TTA;Lo;0;L;;;;;N;;;;;
+0AA0;GUJARATI LETTER TTHA;Lo;0;L;;;;;N;;;;;
+0AA1;GUJARATI LETTER DDA;Lo;0;L;;;;;N;;;;;
+0AA2;GUJARATI LETTER DDHA;Lo;0;L;;;;;N;;;;;
+0AA3;GUJARATI LETTER NNA;Lo;0;L;;;;;N;;;;;
+0AA4;GUJARATI LETTER TA;Lo;0;L;;;;;N;;;;;
+0AA5;GUJARATI LETTER THA;Lo;0;L;;;;;N;;;;;
+0AA6;GUJARATI LETTER DA;Lo;0;L;;;;;N;;;;;
+0AA7;GUJARATI LETTER DHA;Lo;0;L;;;;;N;;;;;
+0AA8;GUJARATI LETTER NA;Lo;0;L;;;;;N;;;;;
+0AAA;GUJARATI LETTER PA;Lo;0;L;;;;;N;;;;;
+0AAB;GUJARATI LETTER PHA;Lo;0;L;;;;;N;;;;;
+0AAC;GUJARATI LETTER BA;Lo;0;L;;;;;N;;;;;
+0AAD;GUJARATI LETTER BHA;Lo;0;L;;;;;N;;;;;
+0AAE;GUJARATI LETTER MA;Lo;0;L;;;;;N;;;;;
+0AAF;GUJARATI LETTER YA;Lo;0;L;;;;;N;;;;;
+0AB0;GUJARATI LETTER RA;Lo;0;L;;;;;N;;;;;
+0AB2;GUJARATI LETTER LA;Lo;0;L;;;;;N;;;;;
+0AB3;GUJARATI LETTER LLA;Lo;0;L;;;;;N;;;;;
+0AB5;GUJARATI LETTER VA;Lo;0;L;;;;;N;;;;;
+0AB6;GUJARATI LETTER SHA;Lo;0;L;;;;;N;;;;;
+0AB7;GUJARATI LETTER SSA;Lo;0;L;;;;;N;;;;;
+0AB8;GUJARATI LETTER SA;Lo;0;L;;;;;N;;;;;
+0AB9;GUJARATI LETTER HA;Lo;0;L;;;;;N;;;;;
+0ABC;GUJARATI SIGN NUKTA;Mn;7;NSM;;;;;N;;;;;
+0ABD;GUJARATI SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;;
+0ABE;GUJARATI VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
+0ABF;GUJARATI VOWEL SIGN I;Mc;0;L;;;;;N;;;;;
+0AC0;GUJARATI VOWEL SIGN II;Mc;0;L;;;;;N;;;;;
+0AC1;GUJARATI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+0AC2;GUJARATI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;
+0AC3;GUJARATI VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;;
+0AC4;GUJARATI VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;;
+0AC5;GUJARATI VOWEL SIGN CANDRA E;Mn;0;NSM;;;;;N;;;;;
+0AC7;GUJARATI VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;;
+0AC8;GUJARATI VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;;
+0AC9;GUJARATI VOWEL SIGN CANDRA O;Mc;0;L;;;;;N;;;;;
+0ACB;GUJARATI VOWEL SIGN O;Mc;0;L;;;;;N;;;;;
+0ACC;GUJARATI VOWEL SIGN AU;Mc;0;L;;;;;N;;;;;
+0ACD;GUJARATI SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;
+0AD0;GUJARATI OM;Lo;0;L;;;;;N;;;;;
+0AE0;GUJARATI LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;;
+0AE1;GUJARATI LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;;
+0AE2;GUJARATI VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;;
+0AE3;GUJARATI VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;;
+0AE6;GUJARATI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+0AE7;GUJARATI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+0AE8;GUJARATI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+0AE9;GUJARATI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+0AEA;GUJARATI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+0AEB;GUJARATI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+0AEC;GUJARATI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+0AED;GUJARATI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+0AEE;GUJARATI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+0AEF;GUJARATI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+0AF1;GUJARATI RUPEE SIGN;Sc;0;ET;;;;;N;;;;;
+0B01;ORIYA SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;;
+0B02;ORIYA SIGN ANUSVARA;Mc;0;L;;;;;N;;;;;
+0B03;ORIYA SIGN VISARGA;Mc;0;L;;;;;N;;;;;
+0B05;ORIYA LETTER A;Lo;0;L;;;;;N;;;;;
+0B06;ORIYA LETTER AA;Lo;0;L;;;;;N;;;;;
+0B07;ORIYA LETTER I;Lo;0;L;;;;;N;;;;;
+0B08;ORIYA LETTER II;Lo;0;L;;;;;N;;;;;
+0B09;ORIYA LETTER U;Lo;0;L;;;;;N;;;;;
+0B0A;ORIYA LETTER UU;Lo;0;L;;;;;N;;;;;
+0B0B;ORIYA LETTER VOCALIC R;Lo;0;L;;;;;N;;;;;
+0B0C;ORIYA LETTER VOCALIC L;Lo;0;L;;;;;N;;;;;
+0B0F;ORIYA LETTER E;Lo;0;L;;;;;N;;;;;
+0B10;ORIYA LETTER AI;Lo;0;L;;;;;N;;;;;
+0B13;ORIYA LETTER O;Lo;0;L;;;;;N;;;;;
+0B14;ORIYA LETTER AU;Lo;0;L;;;;;N;;;;;
+0B15;ORIYA LETTER KA;Lo;0;L;;;;;N;;;;;
+0B16;ORIYA LETTER KHA;Lo;0;L;;;;;N;;;;;
+0B17;ORIYA LETTER GA;Lo;0;L;;;;;N;;;;;
+0B18;ORIYA LETTER GHA;Lo;0;L;;;;;N;;;;;
+0B19;ORIYA LETTER NGA;Lo;0;L;;;;;N;;;;;
+0B1A;ORIYA LETTER CA;Lo;0;L;;;;;N;;;;;
+0B1B;ORIYA LETTER CHA;Lo;0;L;;;;;N;;;;;
+0B1C;ORIYA LETTER JA;Lo;0;L;;;;;N;;;;;
+0B1D;ORIYA LETTER JHA;Lo;0;L;;;;;N;;;;;
+0B1E;ORIYA LETTER NYA;Lo;0;L;;;;;N;;;;;
+0B1F;ORIYA LETTER TTA;Lo;0;L;;;;;N;;;;;
+0B20;ORIYA LETTER TTHA;Lo;0;L;;;;;N;;;;;
+0B21;ORIYA LETTER DDA;Lo;0;L;;;;;N;;;;;
+0B22;ORIYA LETTER DDHA;Lo;0;L;;;;;N;;;;;
+0B23;ORIYA LETTER NNA;Lo;0;L;;;;;N;;;;;
+0B24;ORIYA LETTER TA;Lo;0;L;;;;;N;;;;;
+0B25;ORIYA LETTER THA;Lo;0;L;;;;;N;;;;;
+0B26;ORIYA LETTER DA;Lo;0;L;;;;;N;;;;;
+0B27;ORIYA LETTER DHA;Lo;0;L;;;;;N;;;;;
+0B28;ORIYA LETTER NA;Lo;0;L;;;;;N;;;;;
+0B2A;ORIYA LETTER PA;Lo;0;L;;;;;N;;;;;
+0B2B;ORIYA LETTER PHA;Lo;0;L;;;;;N;;;;;
+0B2C;ORIYA LETTER BA;Lo;0;L;;;;;N;;;;;
+0B2D;ORIYA LETTER BHA;Lo;0;L;;;;;N;;;;;
+0B2E;ORIYA LETTER MA;Lo;0;L;;;;;N;;;;;
+0B2F;ORIYA LETTER YA;Lo;0;L;;;;;N;;;;;
+0B30;ORIYA LETTER RA;Lo;0;L;;;;;N;;;;;
+0B32;ORIYA LETTER LA;Lo;0;L;;;;;N;;;;;
+0B33;ORIYA LETTER LLA;Lo;0;L;;;;;N;;;;;
+0B35;ORIYA LETTER VA;Lo;0;L;;;;;N;;;;;
+0B36;ORIYA LETTER SHA;Lo;0;L;;;;;N;;;;;
+0B37;ORIYA LETTER SSA;Lo;0;L;;;;;N;;;;;
+0B38;ORIYA LETTER SA;Lo;0;L;;;;;N;;;;;
+0B39;ORIYA LETTER HA;Lo;0;L;;;;;N;;;;;
+0B3C;ORIYA SIGN NUKTA;Mn;7;NSM;;;;;N;;;;;
+0B3D;ORIYA SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;;
+0B3E;ORIYA VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
+0B3F;ORIYA VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;
+0B40;ORIYA VOWEL SIGN II;Mc;0;L;;;;;N;;;;;
+0B41;ORIYA VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+0B42;ORIYA VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;
+0B43;ORIYA VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;;
+0B44;ORIYA VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;;
+0B47;ORIYA VOWEL SIGN E;Mc;0;L;;;;;N;;;;;
+0B48;ORIYA VOWEL SIGN AI;Mc;0;L;0B47 0B56;;;;N;;;;;
+0B4B;ORIYA VOWEL SIGN O;Mc;0;L;0B47 0B3E;;;;N;;;;;
+0B4C;ORIYA VOWEL SIGN AU;Mc;0;L;0B47 0B57;;;;N;;;;;
+0B4D;ORIYA SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;
+0B56;ORIYA AI LENGTH MARK;Mn;0;NSM;;;;;N;;;;;
+0B57;ORIYA AU LENGTH MARK;Mc;0;L;;;;;N;;;;;
+0B5C;ORIYA LETTER RRA;Lo;0;L;0B21 0B3C;;;;N;;;;;
+0B5D;ORIYA LETTER RHA;Lo;0;L;0B22 0B3C;;;;N;;;;;
+0B5F;ORIYA LETTER YYA;Lo;0;L;;;;;N;;;;;
+0B60;ORIYA LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;;
+0B61;ORIYA LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;;
+0B62;ORIYA VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;;
+0B63;ORIYA VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;;
+0B66;ORIYA DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+0B67;ORIYA DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+0B68;ORIYA DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+0B69;ORIYA DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+0B6A;ORIYA DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+0B6B;ORIYA DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+0B6C;ORIYA DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+0B6D;ORIYA DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+0B6E;ORIYA DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+0B6F;ORIYA DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+0B70;ORIYA ISSHAR;So;0;L;;;;;N;;;;;
+0B71;ORIYA LETTER WA;Lo;0;L;;;;;N;;;;;
+0B72;ORIYA FRACTION ONE QUARTER;No;0;L;;;;1/4;N;;;;;
+0B73;ORIYA FRACTION ONE HALF;No;0;L;;;;1/2;N;;;;;
+0B74;ORIYA FRACTION THREE QUARTERS;No;0;L;;;;3/4;N;;;;;
+0B75;ORIYA FRACTION ONE SIXTEENTH;No;0;L;;;;1/16;N;;;;;
+0B76;ORIYA FRACTION ONE EIGHTH;No;0;L;;;;1/8;N;;;;;
+0B77;ORIYA FRACTION THREE SIXTEENTHS;No;0;L;;;;3/16;N;;;;;
+0B82;TAMIL SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;
+0B83;TAMIL SIGN VISARGA;Lo;0;L;;;;;N;;;;;
+0B85;TAMIL LETTER A;Lo;0;L;;;;;N;;;;;
+0B86;TAMIL LETTER AA;Lo;0;L;;;;;N;;;;;
+0B87;TAMIL LETTER I;Lo;0;L;;;;;N;;;;;
+0B88;TAMIL LETTER II;Lo;0;L;;;;;N;;;;;
+0B89;TAMIL LETTER U;Lo;0;L;;;;;N;;;;;
+0B8A;TAMIL LETTER UU;Lo;0;L;;;;;N;;;;;
+0B8E;TAMIL LETTER E;Lo;0;L;;;;;N;;;;;
+0B8F;TAMIL LETTER EE;Lo;0;L;;;;;N;;;;;
+0B90;TAMIL LETTER AI;Lo;0;L;;;;;N;;;;;
+0B92;TAMIL LETTER O;Lo;0;L;;;;;N;;;;;
+0B93;TAMIL LETTER OO;Lo;0;L;;;;;N;;;;;
+0B94;TAMIL LETTER AU;Lo;0;L;0B92 0BD7;;;;N;;;;;
+0B95;TAMIL LETTER KA;Lo;0;L;;;;;N;;;;;
+0B99;TAMIL LETTER NGA;Lo;0;L;;;;;N;;;;;
+0B9A;TAMIL LETTER CA;Lo;0;L;;;;;N;;;;;
+0B9C;TAMIL LETTER JA;Lo;0;L;;;;;N;;;;;
+0B9E;TAMIL LETTER NYA;Lo;0;L;;;;;N;;;;;
+0B9F;TAMIL LETTER TTA;Lo;0;L;;;;;N;;;;;
+0BA3;TAMIL LETTER NNA;Lo;0;L;;;;;N;;;;;
+0BA4;TAMIL LETTER TA;Lo;0;L;;;;;N;;;;;
+0BA8;TAMIL LETTER NA;Lo;0;L;;;;;N;;;;;
+0BA9;TAMIL LETTER NNNA;Lo;0;L;;;;;N;;;;;
+0BAA;TAMIL LETTER PA;Lo;0;L;;;;;N;;;;;
+0BAE;TAMIL LETTER MA;Lo;0;L;;;;;N;;;;;
+0BAF;TAMIL LETTER YA;Lo;0;L;;;;;N;;;;;
+0BB0;TAMIL LETTER RA;Lo;0;L;;;;;N;;;;;
+0BB1;TAMIL LETTER RRA;Lo;0;L;;;;;N;;;;;
+0BB2;TAMIL LETTER LA;Lo;0;L;;;;;N;;;;;
+0BB3;TAMIL LETTER LLA;Lo;0;L;;;;;N;;;;;
+0BB4;TAMIL LETTER LLLA;Lo;0;L;;;;;N;;;;;
+0BB5;TAMIL LETTER VA;Lo;0;L;;;;;N;;;;;
+0BB6;TAMIL LETTER SHA;Lo;0;L;;;;;N;;;;;
+0BB7;TAMIL LETTER SSA;Lo;0;L;;;;;N;;;;;
+0BB8;TAMIL LETTER SA;Lo;0;L;;;;;N;;;;;
+0BB9;TAMIL LETTER HA;Lo;0;L;;;;;N;;;;;
+0BBE;TAMIL VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
+0BBF;TAMIL VOWEL SIGN I;Mc;0;L;;;;;N;;;;;
+0BC0;TAMIL VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;;
+0BC1;TAMIL VOWEL SIGN U;Mc;0;L;;;;;N;;;;;
+0BC2;TAMIL VOWEL SIGN UU;Mc;0;L;;;;;N;;;;;
+0BC6;TAMIL VOWEL SIGN E;Mc;0;L;;;;;N;;;;;
+0BC7;TAMIL VOWEL SIGN EE;Mc;0;L;;;;;N;;;;;
+0BC8;TAMIL VOWEL SIGN AI;Mc;0;L;;;;;N;;;;;
+0BCA;TAMIL VOWEL SIGN O;Mc;0;L;0BC6 0BBE;;;;N;;;;;
+0BCB;TAMIL VOWEL SIGN OO;Mc;0;L;0BC7 0BBE;;;;N;;;;;
+0BCC;TAMIL VOWEL SIGN AU;Mc;0;L;0BC6 0BD7;;;;N;;;;;
+0BCD;TAMIL SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;
+0BD0;TAMIL OM;Lo;0;L;;;;;N;;;;;
+0BD7;TAMIL AU LENGTH MARK;Mc;0;L;;;;;N;;;;;
+0BE6;TAMIL DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+0BE7;TAMIL DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+0BE8;TAMIL DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+0BE9;TAMIL DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+0BEA;TAMIL DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+0BEB;TAMIL DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+0BEC;TAMIL DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+0BED;TAMIL DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+0BEE;TAMIL DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+0BEF;TAMIL DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+0BF0;TAMIL NUMBER TEN;No;0;L;;;;10;N;;;;;
+0BF1;TAMIL NUMBER ONE HUNDRED;No;0;L;;;;100;N;;;;;
+0BF2;TAMIL NUMBER ONE THOUSAND;No;0;L;;;;1000;N;;;;;
+0BF3;TAMIL DAY SIGN;So;0;ON;;;;;N;;;;;
+0BF4;TAMIL MONTH SIGN;So;0;ON;;;;;N;;;;;
+0BF5;TAMIL YEAR SIGN;So;0;ON;;;;;N;;;;;
+0BF6;TAMIL DEBIT SIGN;So;0;ON;;;;;N;;;;;
+0BF7;TAMIL CREDIT SIGN;So;0;ON;;;;;N;;;;;
+0BF8;TAMIL AS ABOVE SIGN;So;0;ON;;;;;N;;;;;
+0BF9;TAMIL RUPEE SIGN;Sc;0;ET;;;;;N;;;;;
+0BFA;TAMIL NUMBER SIGN;So;0;ON;;;;;N;;;;;
+0C01;TELUGU SIGN CANDRABINDU;Mc;0;L;;;;;N;;;;;
+0C02;TELUGU SIGN ANUSVARA;Mc;0;L;;;;;N;;;;;
+0C03;TELUGU SIGN VISARGA;Mc;0;L;;;;;N;;;;;
+0C05;TELUGU LETTER A;Lo;0;L;;;;;N;;;;;
+0C06;TELUGU LETTER AA;Lo;0;L;;;;;N;;;;;
+0C07;TELUGU LETTER I;Lo;0;L;;;;;N;;;;;
+0C08;TELUGU LETTER II;Lo;0;L;;;;;N;;;;;
+0C09;TELUGU LETTER U;Lo;0;L;;;;;N;;;;;
+0C0A;TELUGU LETTER UU;Lo;0;L;;;;;N;;;;;
+0C0B;TELUGU LETTER VOCALIC R;Lo;0;L;;;;;N;;;;;
+0C0C;TELUGU LETTER VOCALIC L;Lo;0;L;;;;;N;;;;;
+0C0E;TELUGU LETTER E;Lo;0;L;;;;;N;;;;;
+0C0F;TELUGU LETTER EE;Lo;0;L;;;;;N;;;;;
+0C10;TELUGU LETTER AI;Lo;0;L;;;;;N;;;;;
+0C12;TELUGU LETTER O;Lo;0;L;;;;;N;;;;;
+0C13;TELUGU LETTER OO;Lo;0;L;;;;;N;;;;;
+0C14;TELUGU LETTER AU;Lo;0;L;;;;;N;;;;;
+0C15;TELUGU LETTER KA;Lo;0;L;;;;;N;;;;;
+0C16;TELUGU LETTER KHA;Lo;0;L;;;;;N;;;;;
+0C17;TELUGU LETTER GA;Lo;0;L;;;;;N;;;;;
+0C18;TELUGU LETTER GHA;Lo;0;L;;;;;N;;;;;
+0C19;TELUGU LETTER NGA;Lo;0;L;;;;;N;;;;;
+0C1A;TELUGU LETTER CA;Lo;0;L;;;;;N;;;;;
+0C1B;TELUGU LETTER CHA;Lo;0;L;;;;;N;;;;;
+0C1C;TELUGU LETTER JA;Lo;0;L;;;;;N;;;;;
+0C1D;TELUGU LETTER JHA;Lo;0;L;;;;;N;;;;;
+0C1E;TELUGU LETTER NYA;Lo;0;L;;;;;N;;;;;
+0C1F;TELUGU LETTER TTA;Lo;0;L;;;;;N;;;;;
+0C20;TELUGU LETTER TTHA;Lo;0;L;;;;;N;;;;;
+0C21;TELUGU LETTER DDA;Lo;0;L;;;;;N;;;;;
+0C22;TELUGU LETTER DDHA;Lo;0;L;;;;;N;;;;;
+0C23;TELUGU LETTER NNA;Lo;0;L;;;;;N;;;;;
+0C24;TELUGU LETTER TA;Lo;0;L;;;;;N;;;;;
+0C25;TELUGU LETTER THA;Lo;0;L;;;;;N;;;;;
+0C26;TELUGU LETTER DA;Lo;0;L;;;;;N;;;;;
+0C27;TELUGU LETTER DHA;Lo;0;L;;;;;N;;;;;
+0C28;TELUGU LETTER NA;Lo;0;L;;;;;N;;;;;
+0C2A;TELUGU LETTER PA;Lo;0;L;;;;;N;;;;;
+0C2B;TELUGU LETTER PHA;Lo;0;L;;;;;N;;;;;
+0C2C;TELUGU LETTER BA;Lo;0;L;;;;;N;;;;;
+0C2D;TELUGU LETTER BHA;Lo;0;L;;;;;N;;;;;
+0C2E;TELUGU LETTER MA;Lo;0;L;;;;;N;;;;;
+0C2F;TELUGU LETTER YA;Lo;0;L;;;;;N;;;;;
+0C30;TELUGU LETTER RA;Lo;0;L;;;;;N;;;;;
+0C31;TELUGU LETTER RRA;Lo;0;L;;;;;N;;;;;
+0C32;TELUGU LETTER LA;Lo;0;L;;;;;N;;;;;
+0C33;TELUGU LETTER LLA;Lo;0;L;;;;;N;;;;;
+0C35;TELUGU LETTER VA;Lo;0;L;;;;;N;;;;;
+0C36;TELUGU LETTER SHA;Lo;0;L;;;;;N;;;;;
+0C37;TELUGU LETTER SSA;Lo;0;L;;;;;N;;;;;
+0C38;TELUGU LETTER SA;Lo;0;L;;;;;N;;;;;
+0C39;TELUGU LETTER HA;Lo;0;L;;;;;N;;;;;
+0C3D;TELUGU SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;;
+0C3E;TELUGU VOWEL SIGN AA;Mn;0;NSM;;;;;N;;;;;
+0C3F;TELUGU VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;
+0C40;TELUGU VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;;
+0C41;TELUGU VOWEL SIGN U;Mc;0;L;;;;;N;;;;;
+0C42;TELUGU VOWEL SIGN UU;Mc;0;L;;;;;N;;;;;
+0C43;TELUGU VOWEL SIGN VOCALIC R;Mc;0;L;;;;;N;;;;;
+0C44;TELUGU VOWEL SIGN VOCALIC RR;Mc;0;L;;;;;N;;;;;
+0C46;TELUGU VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;;
+0C47;TELUGU VOWEL SIGN EE;Mn;0;NSM;;;;;N;;;;;
+0C48;TELUGU VOWEL SIGN AI;Mn;0;NSM;0C46 0C56;;;;N;;;;;
+0C4A;TELUGU VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;;
+0C4B;TELUGU VOWEL SIGN OO;Mn;0;NSM;;;;;N;;;;;
+0C4C;TELUGU VOWEL SIGN AU;Mn;0;NSM;;;;;N;;;;;
+0C4D;TELUGU SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;
+0C55;TELUGU LENGTH MARK;Mn;84;NSM;;;;;N;;;;;
+0C56;TELUGU AI LENGTH MARK;Mn;91;NSM;;;;;N;;;;;
+0C58;TELUGU LETTER TSA;Lo;0;L;;;;;N;;;;;
+0C59;TELUGU LETTER DZA;Lo;0;L;;;;;N;;;;;
+0C60;TELUGU LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;;
+0C61;TELUGU LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;;
+0C62;TELUGU VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;;
+0C63;TELUGU VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;;
+0C66;TELUGU DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+0C67;TELUGU DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+0C68;TELUGU DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+0C69;TELUGU DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+0C6A;TELUGU DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+0C6B;TELUGU DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+0C6C;TELUGU DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+0C6D;TELUGU DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+0C6E;TELUGU DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+0C6F;TELUGU DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+0C78;TELUGU FRACTION DIGIT ZERO FOR ODD POWERS OF FOUR;No;0;ON;;;;0;N;;;;;
+0C79;TELUGU FRACTION DIGIT ONE FOR ODD POWERS OF FOUR;No;0;ON;;;;1;N;;;;;
+0C7A;TELUGU FRACTION DIGIT TWO FOR ODD POWERS OF FOUR;No;0;ON;;;;2;N;;;;;
+0C7B;TELUGU FRACTION DIGIT THREE FOR ODD POWERS OF FOUR;No;0;ON;;;;3;N;;;;;
+0C7C;TELUGU FRACTION DIGIT ONE FOR EVEN POWERS OF FOUR;No;0;ON;;;;1;N;;;;;
+0C7D;TELUGU FRACTION DIGIT TWO FOR EVEN POWERS OF FOUR;No;0;ON;;;;2;N;;;;;
+0C7E;TELUGU FRACTION DIGIT THREE FOR EVEN POWERS OF FOUR;No;0;ON;;;;3;N;;;;;
+0C7F;TELUGU SIGN TUUMU;So;0;L;;;;;N;;;;;
+0C82;KANNADA SIGN ANUSVARA;Mc;0;L;;;;;N;;;;;
+0C83;KANNADA SIGN VISARGA;Mc;0;L;;;;;N;;;;;
+0C85;KANNADA LETTER A;Lo;0;L;;;;;N;;;;;
+0C86;KANNADA LETTER AA;Lo;0;L;;;;;N;;;;;
+0C87;KANNADA LETTER I;Lo;0;L;;;;;N;;;;;
+0C88;KANNADA LETTER II;Lo;0;L;;;;;N;;;;;
+0C89;KANNADA LETTER U;Lo;0;L;;;;;N;;;;;
+0C8A;KANNADA LETTER UU;Lo;0;L;;;;;N;;;;;
+0C8B;KANNADA LETTER VOCALIC R;Lo;0;L;;;;;N;;;;;
+0C8C;KANNADA LETTER VOCALIC L;Lo;0;L;;;;;N;;;;;
+0C8E;KANNADA LETTER E;Lo;0;L;;;;;N;;;;;
+0C8F;KANNADA LETTER EE;Lo;0;L;;;;;N;;;;;
+0C90;KANNADA LETTER AI;Lo;0;L;;;;;N;;;;;
+0C92;KANNADA LETTER O;Lo;0;L;;;;;N;;;;;
+0C93;KANNADA LETTER OO;Lo;0;L;;;;;N;;;;;
+0C94;KANNADA LETTER AU;Lo;0;L;;;;;N;;;;;
+0C95;KANNADA LETTER KA;Lo;0;L;;;;;N;;;;;
+0C96;KANNADA LETTER KHA;Lo;0;L;;;;;N;;;;;
+0C97;KANNADA LETTER GA;Lo;0;L;;;;;N;;;;;
+0C98;KANNADA LETTER GHA;Lo;0;L;;;;;N;;;;;
+0C99;KANNADA LETTER NGA;Lo;0;L;;;;;N;;;;;
+0C9A;KANNADA LETTER CA;Lo;0;L;;;;;N;;;;;
+0C9B;KANNADA LETTER CHA;Lo;0;L;;;;;N;;;;;
+0C9C;KANNADA LETTER JA;Lo;0;L;;;;;N;;;;;
+0C9D;KANNADA LETTER JHA;Lo;0;L;;;;;N;;;;;
+0C9E;KANNADA LETTER NYA;Lo;0;L;;;;;N;;;;;
+0C9F;KANNADA LETTER TTA;Lo;0;L;;;;;N;;;;;
+0CA0;KANNADA LETTER TTHA;Lo;0;L;;;;;N;;;;;
+0CA1;KANNADA LETTER DDA;Lo;0;L;;;;;N;;;;;
+0CA2;KANNADA LETTER DDHA;Lo;0;L;;;;;N;;;;;
+0CA3;KANNADA LETTER NNA;Lo;0;L;;;;;N;;;;;
+0CA4;KANNADA LETTER TA;Lo;0;L;;;;;N;;;;;
+0CA5;KANNADA LETTER THA;Lo;0;L;;;;;N;;;;;
+0CA6;KANNADA LETTER DA;Lo;0;L;;;;;N;;;;;
+0CA7;KANNADA LETTER DHA;Lo;0;L;;;;;N;;;;;
+0CA8;KANNADA LETTER NA;Lo;0;L;;;;;N;;;;;
+0CAA;KANNADA LETTER PA;Lo;0;L;;;;;N;;;;;
+0CAB;KANNADA LETTER PHA;Lo;0;L;;;;;N;;;;;
+0CAC;KANNADA LETTER BA;Lo;0;L;;;;;N;;;;;
+0CAD;KANNADA LETTER BHA;Lo;0;L;;;;;N;;;;;
+0CAE;KANNADA LETTER MA;Lo;0;L;;;;;N;;;;;
+0CAF;KANNADA LETTER YA;Lo;0;L;;;;;N;;;;;
+0CB0;KANNADA LETTER RA;Lo;0;L;;;;;N;;;;;
+0CB1;KANNADA LETTER RRA;Lo;0;L;;;;;N;;;;;
+0CB2;KANNADA LETTER LA;Lo;0;L;;;;;N;;;;;
+0CB3;KANNADA LETTER LLA;Lo;0;L;;;;;N;;;;;
+0CB5;KANNADA LETTER VA;Lo;0;L;;;;;N;;;;;
+0CB6;KANNADA LETTER SHA;Lo;0;L;;;;;N;;;;;
+0CB7;KANNADA LETTER SSA;Lo;0;L;;;;;N;;;;;
+0CB8;KANNADA LETTER SA;Lo;0;L;;;;;N;;;;;
+0CB9;KANNADA LETTER HA;Lo;0;L;;;;;N;;;;;
+0CBC;KANNADA SIGN NUKTA;Mn;7;NSM;;;;;N;;;;;
+0CBD;KANNADA SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;;
+0CBE;KANNADA VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
+0CBF;KANNADA VOWEL SIGN I;Mn;0;L;;;;;N;;;;;
+0CC0;KANNADA VOWEL SIGN II;Mc;0;L;0CBF 0CD5;;;;N;;;;;
+0CC1;KANNADA VOWEL SIGN U;Mc;0;L;;;;;N;;;;;
+0CC2;KANNADA VOWEL SIGN UU;Mc;0;L;;;;;N;;;;;
+0CC3;KANNADA VOWEL SIGN VOCALIC R;Mc;0;L;;;;;N;;;;;
+0CC4;KANNADA VOWEL SIGN VOCALIC RR;Mc;0;L;;;;;N;;;;;
+0CC6;KANNADA VOWEL SIGN E;Mn;0;L;;;;;N;;;;;
+0CC7;KANNADA VOWEL SIGN EE;Mc;0;L;0CC6 0CD5;;;;N;;;;;
+0CC8;KANNADA VOWEL SIGN AI;Mc;0;L;0CC6 0CD6;;;;N;;;;;
+0CCA;KANNADA VOWEL SIGN O;Mc;0;L;0CC6 0CC2;;;;N;;;;;
+0CCB;KANNADA VOWEL SIGN OO;Mc;0;L;0CCA 0CD5;;;;N;;;;;
+0CCC;KANNADA VOWEL SIGN AU;Mn;0;NSM;;;;;N;;;;;
+0CCD;KANNADA SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;
+0CD5;KANNADA LENGTH MARK;Mc;0;L;;;;;N;;;;;
+0CD6;KANNADA AI LENGTH MARK;Mc;0;L;;;;;N;;;;;
+0CDE;KANNADA LETTER FA;Lo;0;L;;;;;N;;;;;
+0CE0;KANNADA LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;;
+0CE1;KANNADA LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;;
+0CE2;KANNADA VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;;
+0CE3;KANNADA VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;;
+0CE6;KANNADA DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+0CE7;KANNADA DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+0CE8;KANNADA DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+0CE9;KANNADA DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+0CEA;KANNADA DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+0CEB;KANNADA DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+0CEC;KANNADA DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+0CED;KANNADA DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+0CEE;KANNADA DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+0CEF;KANNADA DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+0CF1;KANNADA SIGN JIHVAMULIYA;Lo;0;L;;;;;N;;;;;
+0CF2;KANNADA SIGN UPADHMANIYA;Lo;0;L;;;;;N;;;;;
+0D02;MALAYALAM SIGN ANUSVARA;Mc;0;L;;;;;N;;;;;
+0D03;MALAYALAM SIGN VISARGA;Mc;0;L;;;;;N;;;;;
+0D05;MALAYALAM LETTER A;Lo;0;L;;;;;N;;;;;
+0D06;MALAYALAM LETTER AA;Lo;0;L;;;;;N;;;;;
+0D07;MALAYALAM LETTER I;Lo;0;L;;;;;N;;;;;
+0D08;MALAYALAM LETTER II;Lo;0;L;;;;;N;;;;;
+0D09;MALAYALAM LETTER U;Lo;0;L;;;;;N;;;;;
+0D0A;MALAYALAM LETTER UU;Lo;0;L;;;;;N;;;;;
+0D0B;MALAYALAM LETTER VOCALIC R;Lo;0;L;;;;;N;;;;;
+0D0C;MALAYALAM LETTER VOCALIC L;Lo;0;L;;;;;N;;;;;
+0D0E;MALAYALAM LETTER E;Lo;0;L;;;;;N;;;;;
+0D0F;MALAYALAM LETTER EE;Lo;0;L;;;;;N;;;;;
+0D10;MALAYALAM LETTER AI;Lo;0;L;;;;;N;;;;;
+0D12;MALAYALAM LETTER O;Lo;0;L;;;;;N;;;;;
+0D13;MALAYALAM LETTER OO;Lo;0;L;;;;;N;;;;;
+0D14;MALAYALAM LETTER AU;Lo;0;L;;;;;N;;;;;
+0D15;MALAYALAM LETTER KA;Lo;0;L;;;;;N;;;;;
+0D16;MALAYALAM LETTER KHA;Lo;0;L;;;;;N;;;;;
+0D17;MALAYALAM LETTER GA;Lo;0;L;;;;;N;;;;;
+0D18;MALAYALAM LETTER GHA;Lo;0;L;;;;;N;;;;;
+0D19;MALAYALAM LETTER NGA;Lo;0;L;;;;;N;;;;;
+0D1A;MALAYALAM LETTER CA;Lo;0;L;;;;;N;;;;;
+0D1B;MALAYALAM LETTER CHA;Lo;0;L;;;;;N;;;;;
+0D1C;MALAYALAM LETTER JA;Lo;0;L;;;;;N;;;;;
+0D1D;MALAYALAM LETTER JHA;Lo;0;L;;;;;N;;;;;
+0D1E;MALAYALAM LETTER NYA;Lo;0;L;;;;;N;;;;;
+0D1F;MALAYALAM LETTER TTA;Lo;0;L;;;;;N;;;;;
+0D20;MALAYALAM LETTER TTHA;Lo;0;L;;;;;N;;;;;
+0D21;MALAYALAM LETTER DDA;Lo;0;L;;;;;N;;;;;
+0D22;MALAYALAM LETTER DDHA;Lo;0;L;;;;;N;;;;;
+0D23;MALAYALAM LETTER NNA;Lo;0;L;;;;;N;;;;;
+0D24;MALAYALAM LETTER TA;Lo;0;L;;;;;N;;;;;
+0D25;MALAYALAM LETTER THA;Lo;0;L;;;;;N;;;;;
+0D26;MALAYALAM LETTER DA;Lo;0;L;;;;;N;;;;;
+0D27;MALAYALAM LETTER DHA;Lo;0;L;;;;;N;;;;;
+0D28;MALAYALAM LETTER NA;Lo;0;L;;;;;N;;;;;
+0D29;MALAYALAM LETTER NNNA;Lo;0;L;;;;;N;;;;;
+0D2A;MALAYALAM LETTER PA;Lo;0;L;;;;;N;;;;;
+0D2B;MALAYALAM LETTER PHA;Lo;0;L;;;;;N;;;;;
+0D2C;MALAYALAM LETTER BA;Lo;0;L;;;;;N;;;;;
+0D2D;MALAYALAM LETTER BHA;Lo;0;L;;;;;N;;;;;
+0D2E;MALAYALAM LETTER MA;Lo;0;L;;;;;N;;;;;
+0D2F;MALAYALAM LETTER YA;Lo;0;L;;;;;N;;;;;
+0D30;MALAYALAM LETTER RA;Lo;0;L;;;;;N;;;;;
+0D31;MALAYALAM LETTER RRA;Lo;0;L;;;;;N;;;;;
+0D32;MALAYALAM LETTER LA;Lo;0;L;;;;;N;;;;;
+0D33;MALAYALAM LETTER LLA;Lo;0;L;;;;;N;;;;;
+0D34;MALAYALAM LETTER LLLA;Lo;0;L;;;;;N;;;;;
+0D35;MALAYALAM LETTER VA;Lo;0;L;;;;;N;;;;;
+0D36;MALAYALAM LETTER SHA;Lo;0;L;;;;;N;;;;;
+0D37;MALAYALAM LETTER SSA;Lo;0;L;;;;;N;;;;;
+0D38;MALAYALAM LETTER SA;Lo;0;L;;;;;N;;;;;
+0D39;MALAYALAM LETTER HA;Lo;0;L;;;;;N;;;;;
+0D3A;MALAYALAM LETTER TTTA;Lo;0;L;;;;;N;;;;;
+0D3D;MALAYALAM SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;;
+0D3E;MALAYALAM VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
+0D3F;MALAYALAM VOWEL SIGN I;Mc;0;L;;;;;N;;;;;
+0D40;MALAYALAM VOWEL SIGN II;Mc;0;L;;;;;N;;;;;
+0D41;MALAYALAM VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+0D42;MALAYALAM VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;
+0D43;MALAYALAM VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;;
+0D44;MALAYALAM VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;;
+0D46;MALAYALAM VOWEL SIGN E;Mc;0;L;;;;;N;;;;;
+0D47;MALAYALAM VOWEL SIGN EE;Mc;0;L;;;;;N;;;;;
+0D48;MALAYALAM VOWEL SIGN AI;Mc;0;L;;;;;N;;;;;
+0D4A;MALAYALAM VOWEL SIGN O;Mc;0;L;0D46 0D3E;;;;N;;;;;
+0D4B;MALAYALAM VOWEL SIGN OO;Mc;0;L;0D47 0D3E;;;;N;;;;;
+0D4C;MALAYALAM VOWEL SIGN AU;Mc;0;L;0D46 0D57;;;;N;;;;;
+0D4D;MALAYALAM SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;
+0D4E;MALAYALAM LETTER DOT REPH;Lo;0;L;;;;;N;;;;;
+0D57;MALAYALAM AU LENGTH MARK;Mc;0;L;;;;;N;;;;;
+0D60;MALAYALAM LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;;
+0D61;MALAYALAM LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;;
+0D62;MALAYALAM VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;;
+0D63;MALAYALAM VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;;
+0D66;MALAYALAM DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+0D67;MALAYALAM DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+0D68;MALAYALAM DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+0D69;MALAYALAM DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+0D6A;MALAYALAM DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+0D6B;MALAYALAM DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+0D6C;MALAYALAM DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+0D6D;MALAYALAM DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+0D6E;MALAYALAM DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+0D6F;MALAYALAM DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+0D70;MALAYALAM NUMBER TEN;No;0;L;;;;10;N;;;;;
+0D71;MALAYALAM NUMBER ONE HUNDRED;No;0;L;;;;100;N;;;;;
+0D72;MALAYALAM NUMBER ONE THOUSAND;No;0;L;;;;1000;N;;;;;
+0D73;MALAYALAM FRACTION ONE QUARTER;No;0;L;;;;1/4;N;;;;;
+0D74;MALAYALAM FRACTION ONE HALF;No;0;L;;;;1/2;N;;;;;
+0D75;MALAYALAM FRACTION THREE QUARTERS;No;0;L;;;;3/4;N;;;;;
+0D79;MALAYALAM DATE MARK;So;0;L;;;;;N;;;;;
+0D7A;MALAYALAM LETTER CHILLU NN;Lo;0;L;;;;;N;;;;;
+0D7B;MALAYALAM LETTER CHILLU N;Lo;0;L;;;;;N;;;;;
+0D7C;MALAYALAM LETTER CHILLU RR;Lo;0;L;;;;;N;;;;;
+0D7D;MALAYALAM LETTER CHILLU L;Lo;0;L;;;;;N;;;;;
+0D7E;MALAYALAM LETTER CHILLU LL;Lo;0;L;;;;;N;;;;;
+0D7F;MALAYALAM LETTER CHILLU K;Lo;0;L;;;;;N;;;;;
+0D82;SINHALA SIGN ANUSVARAYA;Mc;0;L;;;;;N;;;;;
+0D83;SINHALA SIGN VISARGAYA;Mc;0;L;;;;;N;;;;;
+0D85;SINHALA LETTER AYANNA;Lo;0;L;;;;;N;;;;;
+0D86;SINHALA LETTER AAYANNA;Lo;0;L;;;;;N;;;;;
+0D87;SINHALA LETTER AEYANNA;Lo;0;L;;;;;N;;;;;
+0D88;SINHALA LETTER AEEYANNA;Lo;0;L;;;;;N;;;;;
+0D89;SINHALA LETTER IYANNA;Lo;0;L;;;;;N;;;;;
+0D8A;SINHALA LETTER IIYANNA;Lo;0;L;;;;;N;;;;;
+0D8B;SINHALA LETTER UYANNA;Lo;0;L;;;;;N;;;;;
+0D8C;SINHALA LETTER UUYANNA;Lo;0;L;;;;;N;;;;;
+0D8D;SINHALA LETTER IRUYANNA;Lo;0;L;;;;;N;;;;;
+0D8E;SINHALA LETTER IRUUYANNA;Lo;0;L;;;;;N;;;;;
+0D8F;SINHALA LETTER ILUYANNA;Lo;0;L;;;;;N;;;;;
+0D90;SINHALA LETTER ILUUYANNA;Lo;0;L;;;;;N;;;;;
+0D91;SINHALA LETTER EYANNA;Lo;0;L;;;;;N;;;;;
+0D92;SINHALA LETTER EEYANNA;Lo;0;L;;;;;N;;;;;
+0D93;SINHALA LETTER AIYANNA;Lo;0;L;;;;;N;;;;;
+0D94;SINHALA LETTER OYANNA;Lo;0;L;;;;;N;;;;;
+0D95;SINHALA LETTER OOYANNA;Lo;0;L;;;;;N;;;;;
+0D96;SINHALA LETTER AUYANNA;Lo;0;L;;;;;N;;;;;
+0D9A;SINHALA LETTER ALPAPRAANA KAYANNA;Lo;0;L;;;;;N;;;;;
+0D9B;SINHALA LETTER MAHAAPRAANA KAYANNA;Lo;0;L;;;;;N;;;;;
+0D9C;SINHALA LETTER ALPAPRAANA GAYANNA;Lo;0;L;;;;;N;;;;;
+0D9D;SINHALA LETTER MAHAAPRAANA GAYANNA;Lo;0;L;;;;;N;;;;;
+0D9E;SINHALA LETTER KANTAJA NAASIKYAYA;Lo;0;L;;;;;N;;;;;
+0D9F;SINHALA LETTER SANYAKA GAYANNA;Lo;0;L;;;;;N;;;;;
+0DA0;SINHALA LETTER ALPAPRAANA CAYANNA;Lo;0;L;;;;;N;;;;;
+0DA1;SINHALA LETTER MAHAAPRAANA CAYANNA;Lo;0;L;;;;;N;;;;;
+0DA2;SINHALA LETTER ALPAPRAANA JAYANNA;Lo;0;L;;;;;N;;;;;
+0DA3;SINHALA LETTER MAHAAPRAANA JAYANNA;Lo;0;L;;;;;N;;;;;
+0DA4;SINHALA LETTER TAALUJA NAASIKYAYA;Lo;0;L;;;;;N;;;;;
+0DA5;SINHALA LETTER TAALUJA SANYOOGA NAAKSIKYAYA;Lo;0;L;;;;;N;;;;;
+0DA6;SINHALA LETTER SANYAKA JAYANNA;Lo;0;L;;;;;N;;;;;
+0DA7;SINHALA LETTER ALPAPRAANA TTAYANNA;Lo;0;L;;;;;N;;;;;
+0DA8;SINHALA LETTER MAHAAPRAANA TTAYANNA;Lo;0;L;;;;;N;;;;;
+0DA9;SINHALA LETTER ALPAPRAANA DDAYANNA;Lo;0;L;;;;;N;;;;;
+0DAA;SINHALA LETTER MAHAAPRAANA DDAYANNA;Lo;0;L;;;;;N;;;;;
+0DAB;SINHALA LETTER MUURDHAJA NAYANNA;Lo;0;L;;;;;N;;;;;
+0DAC;SINHALA LETTER SANYAKA DDAYANNA;Lo;0;L;;;;;N;;;;;
+0DAD;SINHALA LETTER ALPAPRAANA TAYANNA;Lo;0;L;;;;;N;;;;;
+0DAE;SINHALA LETTER MAHAAPRAANA TAYANNA;Lo;0;L;;;;;N;;;;;
+0DAF;SINHALA LETTER ALPAPRAANA DAYANNA;Lo;0;L;;;;;N;;;;;
+0DB0;SINHALA LETTER MAHAAPRAANA DAYANNA;Lo;0;L;;;;;N;;;;;
+0DB1;SINHALA LETTER DANTAJA NAYANNA;Lo;0;L;;;;;N;;;;;
+0DB3;SINHALA LETTER SANYAKA DAYANNA;Lo;0;L;;;;;N;;;;;
+0DB4;SINHALA LETTER ALPAPRAANA PAYANNA;Lo;0;L;;;;;N;;;;;
+0DB5;SINHALA LETTER MAHAAPRAANA PAYANNA;Lo;0;L;;;;;N;;;;;
+0DB6;SINHALA LETTER ALPAPRAANA BAYANNA;Lo;0;L;;;;;N;;;;;
+0DB7;SINHALA LETTER MAHAAPRAANA BAYANNA;Lo;0;L;;;;;N;;;;;
+0DB8;SINHALA LETTER MAYANNA;Lo;0;L;;;;;N;;;;;
+0DB9;SINHALA LETTER AMBA BAYANNA;Lo;0;L;;;;;N;;;;;
+0DBA;SINHALA LETTER YAYANNA;Lo;0;L;;;;;N;;;;;
+0DBB;SINHALA LETTER RAYANNA;Lo;0;L;;;;;N;;;;;
+0DBD;SINHALA LETTER DANTAJA LAYANNA;Lo;0;L;;;;;N;;;;;
+0DC0;SINHALA LETTER VAYANNA;Lo;0;L;;;;;N;;;;;
+0DC1;SINHALA LETTER TAALUJA SAYANNA;Lo;0;L;;;;;N;;;;;
+0DC2;SINHALA LETTER MUURDHAJA SAYANNA;Lo;0;L;;;;;N;;;;;
+0DC3;SINHALA LETTER DANTAJA SAYANNA;Lo;0;L;;;;;N;;;;;
+0DC4;SINHALA LETTER HAYANNA;Lo;0;L;;;;;N;;;;;
+0DC5;SINHALA LETTER MUURDHAJA LAYANNA;Lo;0;L;;;;;N;;;;;
+0DC6;SINHALA LETTER FAYANNA;Lo;0;L;;;;;N;;;;;
+0DCA;SINHALA SIGN AL-LAKUNA;Mn;9;NSM;;;;;N;;;;;
+0DCF;SINHALA VOWEL SIGN AELA-PILLA;Mc;0;L;;;;;N;;;;;
+0DD0;SINHALA VOWEL SIGN KETTI AEDA-PILLA;Mc;0;L;;;;;N;;;;;
+0DD1;SINHALA VOWEL SIGN DIGA AEDA-PILLA;Mc;0;L;;;;;N;;;;;
+0DD2;SINHALA VOWEL SIGN KETTI IS-PILLA;Mn;0;NSM;;;;;N;;;;;
+0DD3;SINHALA VOWEL SIGN DIGA IS-PILLA;Mn;0;NSM;;;;;N;;;;;
+0DD4;SINHALA VOWEL SIGN KETTI PAA-PILLA;Mn;0;NSM;;;;;N;;;;;
+0DD6;SINHALA VOWEL SIGN DIGA PAA-PILLA;Mn;0;NSM;;;;;N;;;;;
+0DD8;SINHALA VOWEL SIGN GAETTA-PILLA;Mc;0;L;;;;;N;;;;;
+0DD9;SINHALA VOWEL SIGN KOMBUVA;Mc;0;L;;;;;N;;;;;
+0DDA;SINHALA VOWEL SIGN DIGA KOMBUVA;Mc;0;L;0DD9 0DCA;;;;N;;;;;
+0DDB;SINHALA VOWEL SIGN KOMBU DEKA;Mc;0;L;;;;;N;;;;;
+0DDC;SINHALA VOWEL SIGN KOMBUVA HAA AELA-PILLA;Mc;0;L;0DD9 0DCF;;;;N;;;;;
+0DDD;SINHALA VOWEL SIGN KOMBUVA HAA DIGA AELA-PILLA;Mc;0;L;0DDC 0DCA;;;;N;;;;;
+0DDE;SINHALA VOWEL SIGN KOMBUVA HAA GAYANUKITTA;Mc;0;L;0DD9 0DDF;;;;N;;;;;
+0DDF;SINHALA VOWEL SIGN GAYANUKITTA;Mc;0;L;;;;;N;;;;;
+0DF2;SINHALA VOWEL SIGN DIGA GAETTA-PILLA;Mc;0;L;;;;;N;;;;;
+0DF3;SINHALA VOWEL SIGN DIGA GAYANUKITTA;Mc;0;L;;;;;N;;;;;
+0DF4;SINHALA PUNCTUATION KUNDDALIYA;Po;0;L;;;;;N;;;;;
+0E01;THAI CHARACTER KO KAI;Lo;0;L;;;;;N;THAI LETTER KO KAI;;;;
+0E02;THAI CHARACTER KHO KHAI;Lo;0;L;;;;;N;THAI LETTER KHO KHAI;;;;
+0E03;THAI CHARACTER KHO KHUAT;Lo;0;L;;;;;N;THAI LETTER KHO KHUAT;;;;
+0E04;THAI CHARACTER KHO KHWAI;Lo;0;L;;;;;N;THAI LETTER KHO KHWAI;;;;
+0E05;THAI CHARACTER KHO KHON;Lo;0;L;;;;;N;THAI LETTER KHO KHON;;;;
+0E06;THAI CHARACTER KHO RAKHANG;Lo;0;L;;;;;N;THAI LETTER KHO RAKHANG;;;;
+0E07;THAI CHARACTER NGO NGU;Lo;0;L;;;;;N;THAI LETTER NGO NGU;;;;
+0E08;THAI CHARACTER CHO CHAN;Lo;0;L;;;;;N;THAI LETTER CHO CHAN;;;;
+0E09;THAI CHARACTER CHO CHING;Lo;0;L;;;;;N;THAI LETTER CHO CHING;;;;
+0E0A;THAI CHARACTER CHO CHANG;Lo;0;L;;;;;N;THAI LETTER CHO CHANG;;;;
+0E0B;THAI CHARACTER SO SO;Lo;0;L;;;;;N;THAI LETTER SO SO;;;;
+0E0C;THAI CHARACTER CHO CHOE;Lo;0;L;;;;;N;THAI LETTER CHO CHOE;;;;
+0E0D;THAI CHARACTER YO YING;Lo;0;L;;;;;N;THAI LETTER YO YING;;;;
+0E0E;THAI CHARACTER DO CHADA;Lo;0;L;;;;;N;THAI LETTER DO CHADA;;;;
+0E0F;THAI CHARACTER TO PATAK;Lo;0;L;;;;;N;THAI LETTER TO PATAK;;;;
+0E10;THAI CHARACTER THO THAN;Lo;0;L;;;;;N;THAI LETTER THO THAN;;;;
+0E11;THAI CHARACTER THO NANGMONTHO;Lo;0;L;;;;;N;THAI LETTER THO NANGMONTHO;;;;
+0E12;THAI CHARACTER THO PHUTHAO;Lo;0;L;;;;;N;THAI LETTER THO PHUTHAO;;;;
+0E13;THAI CHARACTER NO NEN;Lo;0;L;;;;;N;THAI LETTER NO NEN;;;;
+0E14;THAI CHARACTER DO DEK;Lo;0;L;;;;;N;THAI LETTER DO DEK;;;;
+0E15;THAI CHARACTER TO TAO;Lo;0;L;;;;;N;THAI LETTER TO TAO;;;;
+0E16;THAI CHARACTER THO THUNG;Lo;0;L;;;;;N;THAI LETTER THO THUNG;;;;
+0E17;THAI CHARACTER THO THAHAN;Lo;0;L;;;;;N;THAI LETTER THO THAHAN;;;;
+0E18;THAI CHARACTER THO THONG;Lo;0;L;;;;;N;THAI LETTER THO THONG;;;;
+0E19;THAI CHARACTER NO NU;Lo;0;L;;;;;N;THAI LETTER NO NU;;;;
+0E1A;THAI CHARACTER BO BAIMAI;Lo;0;L;;;;;N;THAI LETTER BO BAIMAI;;;;
+0E1B;THAI CHARACTER PO PLA;Lo;0;L;;;;;N;THAI LETTER PO PLA;;;;
+0E1C;THAI CHARACTER PHO PHUNG;Lo;0;L;;;;;N;THAI LETTER PHO PHUNG;;;;
+0E1D;THAI CHARACTER FO FA;Lo;0;L;;;;;N;THAI LETTER FO FA;;;;
+0E1E;THAI CHARACTER PHO PHAN;Lo;0;L;;;;;N;THAI LETTER PHO PHAN;;;;
+0E1F;THAI CHARACTER FO FAN;Lo;0;L;;;;;N;THAI LETTER FO FAN;;;;
+0E20;THAI CHARACTER PHO SAMPHAO;Lo;0;L;;;;;N;THAI LETTER PHO SAMPHAO;;;;
+0E21;THAI CHARACTER MO MA;Lo;0;L;;;;;N;THAI LETTER MO MA;;;;
+0E22;THAI CHARACTER YO YAK;Lo;0;L;;;;;N;THAI LETTER YO YAK;;;;
+0E23;THAI CHARACTER RO RUA;Lo;0;L;;;;;N;THAI LETTER RO RUA;;;;
+0E24;THAI CHARACTER RU;Lo;0;L;;;;;N;THAI LETTER RU;;;;
+0E25;THAI CHARACTER LO LING;Lo;0;L;;;;;N;THAI LETTER LO LING;;;;
+0E26;THAI CHARACTER LU;Lo;0;L;;;;;N;THAI LETTER LU;;;;
+0E27;THAI CHARACTER WO WAEN;Lo;0;L;;;;;N;THAI LETTER WO WAEN;;;;
+0E28;THAI CHARACTER SO SALA;Lo;0;L;;;;;N;THAI LETTER SO SALA;;;;
+0E29;THAI CHARACTER SO RUSI;Lo;0;L;;;;;N;THAI LETTER SO RUSI;;;;
+0E2A;THAI CHARACTER SO SUA;Lo;0;L;;;;;N;THAI LETTER SO SUA;;;;
+0E2B;THAI CHARACTER HO HIP;Lo;0;L;;;;;N;THAI LETTER HO HIP;;;;
+0E2C;THAI CHARACTER LO CHULA;Lo;0;L;;;;;N;THAI LETTER LO CHULA;;;;
+0E2D;THAI CHARACTER O ANG;Lo;0;L;;;;;N;THAI LETTER O ANG;;;;
+0E2E;THAI CHARACTER HO NOKHUK;Lo;0;L;;;;;N;THAI LETTER HO NOK HUK;;;;
+0E2F;THAI CHARACTER PAIYANNOI;Lo;0;L;;;;;N;THAI PAI YAN NOI;;;;
+0E30;THAI CHARACTER SARA A;Lo;0;L;;;;;N;THAI VOWEL SIGN SARA A;;;;
+0E31;THAI CHARACTER MAI HAN-AKAT;Mn;0;NSM;;;;;N;THAI VOWEL SIGN MAI HAN-AKAT;;;;
+0E32;THAI CHARACTER SARA AA;Lo;0;L;;;;;N;THAI VOWEL SIGN SARA AA;;;;
+0E33;THAI CHARACTER SARA AM;Lo;0;L;<compat> 0E4D 0E32;;;;N;THAI VOWEL SIGN SARA AM;;;;
+0E34;THAI CHARACTER SARA I;Mn;0;NSM;;;;;N;THAI VOWEL SIGN SARA I;;;;
+0E35;THAI CHARACTER SARA II;Mn;0;NSM;;;;;N;THAI VOWEL SIGN SARA II;;;;
+0E36;THAI CHARACTER SARA UE;Mn;0;NSM;;;;;N;THAI VOWEL SIGN SARA UE;;;;
+0E37;THAI CHARACTER SARA UEE;Mn;0;NSM;;;;;N;THAI VOWEL SIGN SARA UEE;;;;
+0E38;THAI CHARACTER SARA U;Mn;103;NSM;;;;;N;THAI VOWEL SIGN SARA U;;;;
+0E39;THAI CHARACTER SARA UU;Mn;103;NSM;;;;;N;THAI VOWEL SIGN SARA UU;;;;
+0E3A;THAI CHARACTER PHINTHU;Mn;9;NSM;;;;;N;THAI VOWEL SIGN PHINTHU;;;;
+0E3F;THAI CURRENCY SYMBOL BAHT;Sc;0;ET;;;;;N;THAI BAHT SIGN;;;;
+0E40;THAI CHARACTER SARA E;Lo;0;L;;;;;N;THAI VOWEL SIGN SARA E;;;;
+0E41;THAI CHARACTER SARA AE;Lo;0;L;;;;;N;THAI VOWEL SIGN SARA AE;;;;
+0E42;THAI CHARACTER SARA O;Lo;0;L;;;;;N;THAI VOWEL SIGN SARA O;;;;
+0E43;THAI CHARACTER SARA AI MAIMUAN;Lo;0;L;;;;;N;THAI VOWEL SIGN SARA MAI MUAN;;;;
+0E44;THAI CHARACTER SARA AI MAIMALAI;Lo;0;L;;;;;N;THAI VOWEL SIGN SARA MAI MALAI;;;;
+0E45;THAI CHARACTER LAKKHANGYAO;Lo;0;L;;;;;N;THAI LAK KHANG YAO;;;;
+0E46;THAI CHARACTER MAIYAMOK;Lm;0;L;;;;;N;THAI MAI YAMOK;;;;
+0E47;THAI CHARACTER MAITAIKHU;Mn;0;NSM;;;;;N;THAI VOWEL SIGN MAI TAI KHU;;;;
+0E48;THAI CHARACTER MAI EK;Mn;107;NSM;;;;;N;THAI TONE MAI EK;;;;
+0E49;THAI CHARACTER MAI THO;Mn;107;NSM;;;;;N;THAI TONE MAI THO;;;;
+0E4A;THAI CHARACTER MAI TRI;Mn;107;NSM;;;;;N;THAI TONE MAI TRI;;;;
+0E4B;THAI CHARACTER MAI CHATTAWA;Mn;107;NSM;;;;;N;THAI TONE MAI CHATTAWA;;;;
+0E4C;THAI CHARACTER THANTHAKHAT;Mn;0;NSM;;;;;N;THAI THANTHAKHAT;;;;
+0E4D;THAI CHARACTER NIKHAHIT;Mn;0;NSM;;;;;N;THAI NIKKHAHIT;;;;
+0E4E;THAI CHARACTER YAMAKKAN;Mn;0;NSM;;;;;N;THAI YAMAKKAN;;;;
+0E4F;THAI CHARACTER FONGMAN;Po;0;L;;;;;N;THAI FONGMAN;;;;
+0E50;THAI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+0E51;THAI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+0E52;THAI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+0E53;THAI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+0E54;THAI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+0E55;THAI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+0E56;THAI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+0E57;THAI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+0E58;THAI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+0E59;THAI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+0E5A;THAI CHARACTER ANGKHANKHU;Po;0;L;;;;;N;THAI ANGKHANKHU;;;;
+0E5B;THAI CHARACTER KHOMUT;Po;0;L;;;;;N;THAI KHOMUT;;;;
+0E81;LAO LETTER KO;Lo;0;L;;;;;N;;;;;
+0E82;LAO LETTER KHO SUNG;Lo;0;L;;;;;N;;;;;
+0E84;LAO LETTER KHO TAM;Lo;0;L;;;;;N;;;;;
+0E87;LAO LETTER NGO;Lo;0;L;;;;;N;;;;;
+0E88;LAO LETTER CO;Lo;0;L;;;;;N;;;;;
+0E8A;LAO LETTER SO TAM;Lo;0;L;;;;;N;;;;;
+0E8D;LAO LETTER NYO;Lo;0;L;;;;;N;;;;;
+0E94;LAO LETTER DO;Lo;0;L;;;;;N;;;;;
+0E95;LAO LETTER TO;Lo;0;L;;;;;N;;;;;
+0E96;LAO LETTER THO SUNG;Lo;0;L;;;;;N;;;;;
+0E97;LAO LETTER THO TAM;Lo;0;L;;;;;N;;;;;
+0E99;LAO LETTER NO;Lo;0;L;;;;;N;;;;;
+0E9A;LAO LETTER BO;Lo;0;L;;;;;N;;;;;
+0E9B;LAO LETTER PO;Lo;0;L;;;;;N;;;;;
+0E9C;LAO LETTER PHO SUNG;Lo;0;L;;;;;N;;;;;
+0E9D;LAO LETTER FO TAM;Lo;0;L;;;;;N;;;;;
+0E9E;LAO LETTER PHO TAM;Lo;0;L;;;;;N;;;;;
+0E9F;LAO LETTER FO SUNG;Lo;0;L;;;;;N;;;;;
+0EA1;LAO LETTER MO;Lo;0;L;;;;;N;;;;;
+0EA2;LAO LETTER YO;Lo;0;L;;;;;N;;;;;
+0EA3;LAO LETTER LO LING;Lo;0;L;;;;;N;;;;;
+0EA5;LAO LETTER LO LOOT;Lo;0;L;;;;;N;;;;;
+0EA7;LAO LETTER WO;Lo;0;L;;;;;N;;;;;
+0EAA;LAO LETTER SO SUNG;Lo;0;L;;;;;N;;;;;
+0EAB;LAO LETTER HO SUNG;Lo;0;L;;;;;N;;;;;
+0EAD;LAO LETTER O;Lo;0;L;;;;;N;;;;;
+0EAE;LAO LETTER HO TAM;Lo;0;L;;;;;N;;;;;
+0EAF;LAO ELLIPSIS;Lo;0;L;;;;;N;;;;;
+0EB0;LAO VOWEL SIGN A;Lo;0;L;;;;;N;;;;;
+0EB1;LAO VOWEL SIGN MAI KAN;Mn;0;NSM;;;;;N;;;;;
+0EB2;LAO VOWEL SIGN AA;Lo;0;L;;;;;N;;;;;
+0EB3;LAO VOWEL SIGN AM;Lo;0;L;<compat> 0ECD 0EB2;;;;N;;;;;
+0EB4;LAO VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;
+0EB5;LAO VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;;
+0EB6;LAO VOWEL SIGN Y;Mn;0;NSM;;;;;N;;;;;
+0EB7;LAO VOWEL SIGN YY;Mn;0;NSM;;;;;N;;;;;
+0EB8;LAO VOWEL SIGN U;Mn;118;NSM;;;;;N;;;;;
+0EB9;LAO VOWEL SIGN UU;Mn;118;NSM;;;;;N;;;;;
+0EBB;LAO VOWEL SIGN MAI KON;Mn;0;NSM;;;;;N;;;;;
+0EBC;LAO SEMIVOWEL SIGN LO;Mn;0;NSM;;;;;N;;;;;
+0EBD;LAO SEMIVOWEL SIGN NYO;Lo;0;L;;;;;N;;;;;
+0EC0;LAO VOWEL SIGN E;Lo;0;L;;;;;N;;;;;
+0EC1;LAO VOWEL SIGN EI;Lo;0;L;;;;;N;;;;;
+0EC2;LAO VOWEL SIGN O;Lo;0;L;;;;;N;;;;;
+0EC3;LAO VOWEL SIGN AY;Lo;0;L;;;;;N;;;;;
+0EC4;LAO VOWEL SIGN AI;Lo;0;L;;;;;N;;;;;
+0EC6;LAO KO LA;Lm;0;L;;;;;N;;;;;
+0EC8;LAO TONE MAI EK;Mn;122;NSM;;;;;N;;;;;
+0EC9;LAO TONE MAI THO;Mn;122;NSM;;;;;N;;;;;
+0ECA;LAO TONE MAI TI;Mn;122;NSM;;;;;N;;;;;
+0ECB;LAO TONE MAI CATAWA;Mn;122;NSM;;;;;N;;;;;
+0ECC;LAO CANCELLATION MARK;Mn;0;NSM;;;;;N;;;;;
+0ECD;LAO NIGGAHITA;Mn;0;NSM;;;;;N;;;;;
+0ED0;LAO DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+0ED1;LAO DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+0ED2;LAO DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+0ED3;LAO DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+0ED4;LAO DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+0ED5;LAO DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+0ED6;LAO DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+0ED7;LAO DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+0ED8;LAO DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+0ED9;LAO DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+0EDC;LAO HO NO;Lo;0;L;<compat> 0EAB 0E99;;;;N;;;;;
+0EDD;LAO HO MO;Lo;0;L;<compat> 0EAB 0EA1;;;;N;;;;;
+0F00;TIBETAN SYLLABLE OM;Lo;0;L;;;;;N;;;;;
+0F01;TIBETAN MARK GTER YIG MGO TRUNCATED A;So;0;L;;;;;N;;;;;
+0F02;TIBETAN MARK GTER YIG MGO -UM RNAM BCAD MA;So;0;L;;;;;N;;;;;
+0F03;TIBETAN MARK GTER YIG MGO -UM GTER TSHEG MA;So;0;L;;;;;N;;;;;
+0F04;TIBETAN MARK INITIAL YIG MGO MDUN MA;Po;0;L;;;;;N;TIBETAN SINGLE ORNAMENT;;;;
+0F05;TIBETAN MARK CLOSING YIG MGO SGAB MA;Po;0;L;;;;;N;;;;;
+0F06;TIBETAN MARK CARET YIG MGO PHUR SHAD MA;Po;0;L;;;;;N;;;;;
+0F07;TIBETAN MARK YIG MGO TSHEG SHAD MA;Po;0;L;;;;;N;;;;;
+0F08;TIBETAN MARK SBRUL SHAD;Po;0;L;;;;;N;TIBETAN RGYANSHAD;;;;
+0F09;TIBETAN MARK BSKUR YIG MGO;Po;0;L;;;;;N;;;;;
+0F0A;TIBETAN MARK BKA- SHOG YIG MGO;Po;0;L;;;;;N;;;;;
+0F0B;TIBETAN MARK INTERSYLLABIC TSHEG;Po;0;L;;;;;N;TIBETAN TSEG;;;;
+0F0C;TIBETAN MARK DELIMITER TSHEG BSTAR;Po;0;L;<noBreak> 0F0B;;;;N;;;;;
+0F0D;TIBETAN MARK SHAD;Po;0;L;;;;;N;TIBETAN SHAD;;;;
+0F0E;TIBETAN MARK NYIS SHAD;Po;0;L;;;;;N;TIBETAN DOUBLE SHAD;;;;
+0F0F;TIBETAN MARK TSHEG SHAD;Po;0;L;;;;;N;;;;;
+0F10;TIBETAN MARK NYIS TSHEG SHAD;Po;0;L;;;;;N;;;;;
+0F11;TIBETAN MARK RIN CHEN SPUNGS SHAD;Po;0;L;;;;;N;TIBETAN RINCHANPHUNGSHAD;;;;
+0F12;TIBETAN MARK RGYA GRAM SHAD;Po;0;L;;;;;N;;;;;
+0F13;TIBETAN MARK CARET -DZUD RTAGS ME LONG CAN;So;0;L;;;;;N;;;;;
+0F14;TIBETAN MARK GTER TSHEG;So;0;L;;;;;N;TIBETAN COMMA;;;;
+0F15;TIBETAN LOGOTYPE SIGN CHAD RTAGS;So;0;L;;;;;N;;;;;
+0F16;TIBETAN LOGOTYPE SIGN LHAG RTAGS;So;0;L;;;;;N;;;;;
+0F17;TIBETAN ASTROLOGICAL SIGN SGRA GCAN -CHAR RTAGS;So;0;L;;;;;N;;;;;
+0F18;TIBETAN ASTROLOGICAL SIGN -KHYUD PA;Mn;220;NSM;;;;;N;;;;;
+0F19;TIBETAN ASTROLOGICAL SIGN SDONG TSHUGS;Mn;220;NSM;;;;;N;;;;;
+0F1A;TIBETAN SIGN RDEL DKAR GCIG;So;0;L;;;;;N;;;;;
+0F1B;TIBETAN SIGN RDEL DKAR GNYIS;So;0;L;;;;;N;;;;;
+0F1C;TIBETAN SIGN RDEL DKAR GSUM;So;0;L;;;;;N;;;;;
+0F1D;TIBETAN SIGN RDEL NAG GCIG;So;0;L;;;;;N;;;;;
+0F1E;TIBETAN SIGN RDEL NAG GNYIS;So;0;L;;;;;N;;;;;
+0F1F;TIBETAN SIGN RDEL DKAR RDEL NAG;So;0;L;;;;;N;;;;;
+0F20;TIBETAN DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+0F21;TIBETAN DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+0F22;TIBETAN DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+0F23;TIBETAN DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+0F24;TIBETAN DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+0F25;TIBETAN DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+0F26;TIBETAN DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+0F27;TIBETAN DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+0F28;TIBETAN DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+0F29;TIBETAN DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+0F2A;TIBETAN DIGIT HALF ONE;No;0;L;;;;1/2;N;;;;;
+0F2B;TIBETAN DIGIT HALF TWO;No;0;L;;;;3/2;N;;;;;
+0F2C;TIBETAN DIGIT HALF THREE;No;0;L;;;;5/2;N;;;;;
+0F2D;TIBETAN DIGIT HALF FOUR;No;0;L;;;;7/2;N;;;;;
+0F2E;TIBETAN DIGIT HALF FIVE;No;0;L;;;;9/2;N;;;;;
+0F2F;TIBETAN DIGIT HALF SIX;No;0;L;;;;11/2;N;;;;;
+0F30;TIBETAN DIGIT HALF SEVEN;No;0;L;;;;13/2;N;;;;;
+0F31;TIBETAN DIGIT HALF EIGHT;No;0;L;;;;15/2;N;;;;;
+0F32;TIBETAN DIGIT HALF NINE;No;0;L;;;;17/2;N;;;;;
+0F33;TIBETAN DIGIT HALF ZERO;No;0;L;;;;-1/2;N;;;;;
+0F34;TIBETAN MARK BSDUS RTAGS;So;0;L;;;;;N;;;;;
+0F35;TIBETAN MARK NGAS BZUNG NYI ZLA;Mn;220;NSM;;;;;N;TIBETAN HONORIFIC UNDER RING;;;;
+0F36;TIBETAN MARK CARET -DZUD RTAGS BZHI MIG CAN;So;0;L;;;;;N;;;;;
+0F37;TIBETAN MARK NGAS BZUNG SGOR RTAGS;Mn;220;NSM;;;;;N;TIBETAN UNDER RING;;;;
+0F38;TIBETAN MARK CHE MGO;So;0;L;;;;;N;;;;;
+0F39;TIBETAN MARK TSA -PHRU;Mn;216;NSM;;;;;N;TIBETAN LENITION MARK;;;;
+0F3A;TIBETAN MARK GUG RTAGS GYON;Ps;0;ON;;;;;Y;;;;;
+0F3B;TIBETAN MARK GUG RTAGS GYAS;Pe;0;ON;;;;;Y;;;;;
+0F3C;TIBETAN MARK ANG KHANG GYON;Ps;0;ON;;;;;Y;TIBETAN LEFT BRACE;;;;
+0F3D;TIBETAN MARK ANG KHANG GYAS;Pe;0;ON;;;;;Y;TIBETAN RIGHT BRACE;;;;
+0F3E;TIBETAN SIGN YAR TSHES;Mc;0;L;;;;;N;;;;;
+0F3F;TIBETAN SIGN MAR TSHES;Mc;0;L;;;;;N;;;;;
+0F40;TIBETAN LETTER KA;Lo;0;L;;;;;N;;;;;
+0F41;TIBETAN LETTER KHA;Lo;0;L;;;;;N;;;;;
+0F42;TIBETAN LETTER GA;Lo;0;L;;;;;N;;;;;
+0F43;TIBETAN LETTER GHA;Lo;0;L;0F42 0FB7;;;;N;;;;;
+0F44;TIBETAN LETTER NGA;Lo;0;L;;;;;N;;;;;
+0F45;TIBETAN LETTER CA;Lo;0;L;;;;;N;;;;;
+0F46;TIBETAN LETTER CHA;Lo;0;L;;;;;N;;;;;
+0F47;TIBETAN LETTER JA;Lo;0;L;;;;;N;;;;;
+0F49;TIBETAN LETTER NYA;Lo;0;L;;;;;N;;;;;
+0F4A;TIBETAN LETTER TTA;Lo;0;L;;;;;N;TIBETAN LETTER REVERSED TA;;;;
+0F4B;TIBETAN LETTER TTHA;Lo;0;L;;;;;N;TIBETAN LETTER REVERSED THA;;;;
+0F4C;TIBETAN LETTER DDA;Lo;0;L;;;;;N;TIBETAN LETTER REVERSED DA;;;;
+0F4D;TIBETAN LETTER DDHA;Lo;0;L;0F4C 0FB7;;;;N;;;;;
+0F4E;TIBETAN LETTER NNA;Lo;0;L;;;;;N;TIBETAN LETTER REVERSED NA;;;;
+0F4F;TIBETAN LETTER TA;Lo;0;L;;;;;N;;;;;
+0F50;TIBETAN LETTER THA;Lo;0;L;;;;;N;;;;;
+0F51;TIBETAN LETTER DA;Lo;0;L;;;;;N;;;;;
+0F52;TIBETAN LETTER DHA;Lo;0;L;0F51 0FB7;;;;N;;;;;
+0F53;TIBETAN LETTER NA;Lo;0;L;;;;;N;;;;;
+0F54;TIBETAN LETTER PA;Lo;0;L;;;;;N;;;;;
+0F55;TIBETAN LETTER PHA;Lo;0;L;;;;;N;;;;;
+0F56;TIBETAN LETTER BA;Lo;0;L;;;;;N;;;;;
+0F57;TIBETAN LETTER BHA;Lo;0;L;0F56 0FB7;;;;N;;;;;
+0F58;TIBETAN LETTER MA;Lo;0;L;;;;;N;;;;;
+0F59;TIBETAN LETTER TSA;Lo;0;L;;;;;N;;;;;
+0F5A;TIBETAN LETTER TSHA;Lo;0;L;;;;;N;;;;;
+0F5B;TIBETAN LETTER DZA;Lo;0;L;;;;;N;;;;;
+0F5C;TIBETAN LETTER DZHA;Lo;0;L;0F5B 0FB7;;;;N;;;;;
+0F5D;TIBETAN LETTER WA;Lo;0;L;;;;;N;;;;;
+0F5E;TIBETAN LETTER ZHA;Lo;0;L;;;;;N;;;;;
+0F5F;TIBETAN LETTER ZA;Lo;0;L;;;;;N;;;;;
+0F60;TIBETAN LETTER -A;Lo;0;L;;;;;N;TIBETAN LETTER AA;;;;
+0F61;TIBETAN LETTER YA;Lo;0;L;;;;;N;;;;;
+0F62;TIBETAN LETTER RA;Lo;0;L;;;;;N;;;;;
+0F63;TIBETAN LETTER LA;Lo;0;L;;;;;N;;;;;
+0F64;TIBETAN LETTER SHA;Lo;0;L;;;;;N;;;;;
+0F65;TIBETAN LETTER SSA;Lo;0;L;;;;;N;TIBETAN LETTER REVERSED SHA;;;;
+0F66;TIBETAN LETTER SA;Lo;0;L;;;;;N;;;;;
+0F67;TIBETAN LETTER HA;Lo;0;L;;;;;N;;;;;
+0F68;TIBETAN LETTER A;Lo;0;L;;;;;N;;;;;
+0F69;TIBETAN LETTER KSSA;Lo;0;L;0F40 0FB5;;;;N;;;;;
+0F6A;TIBETAN LETTER FIXED-FORM RA;Lo;0;L;;;;;N;;;;;
+0F6B;TIBETAN LETTER KKA;Lo;0;L;;;;;N;;;;;
+0F6C;TIBETAN LETTER RRA;Lo;0;L;;;;;N;;;;;
+0F71;TIBETAN VOWEL SIGN AA;Mn;129;NSM;;;;;N;;;;;
+0F72;TIBETAN VOWEL SIGN I;Mn;130;NSM;;;;;N;;;;;
+0F73;TIBETAN VOWEL SIGN II;Mn;0;NSM;0F71 0F72;;;;N;;;;;
+0F74;TIBETAN VOWEL SIGN U;Mn;132;NSM;;;;;N;;;;;
+0F75;TIBETAN VOWEL SIGN UU;Mn;0;NSM;0F71 0F74;;;;N;;;;;
+0F76;TIBETAN VOWEL SIGN VOCALIC R;Mn;0;NSM;0FB2 0F80;;;;N;;;;;
+0F77;TIBETAN VOWEL SIGN VOCALIC RR;Mn;0;NSM;<compat> 0FB2 0F81;;;;N;;;;;
+0F78;TIBETAN VOWEL SIGN VOCALIC L;Mn;0;NSM;0FB3 0F80;;;;N;;;;;
+0F79;TIBETAN VOWEL SIGN VOCALIC LL;Mn;0;NSM;<compat> 0FB3 0F81;;;;N;;;;;
+0F7A;TIBETAN VOWEL SIGN E;Mn;130;NSM;;;;;N;;;;;
+0F7B;TIBETAN VOWEL SIGN EE;Mn;130;NSM;;;;;N;TIBETAN VOWEL SIGN AI;;;;
+0F7C;TIBETAN VOWEL SIGN O;Mn;130;NSM;;;;;N;;;;;
+0F7D;TIBETAN VOWEL SIGN OO;Mn;130;NSM;;;;;N;TIBETAN VOWEL SIGN AU;;;;
+0F7E;TIBETAN SIGN RJES SU NGA RO;Mn;0;NSM;;;;;N;TIBETAN ANUSVARA;;;;
+0F7F;TIBETAN SIGN RNAM BCAD;Mc;0;L;;;;;N;TIBETAN VISARGA;;;;
+0F80;TIBETAN VOWEL SIGN REVERSED I;Mn;130;NSM;;;;;N;TIBETAN VOWEL SIGN SHORT I;;;;
+0F81;TIBETAN VOWEL SIGN REVERSED II;Mn;0;NSM;0F71 0F80;;;;N;;;;;
+0F82;TIBETAN SIGN NYI ZLA NAA DA;Mn;230;NSM;;;;;N;TIBETAN CANDRABINDU WITH ORNAMENT;;;;
+0F83;TIBETAN SIGN SNA LDAN;Mn;230;NSM;;;;;N;TIBETAN CANDRABINDU;;;;
+0F84;TIBETAN MARK HALANTA;Mn;9;NSM;;;;;N;TIBETAN VIRAMA;;;;
+0F85;TIBETAN MARK PALUTA;Po;0;L;;;;;N;TIBETAN CHUCHENYIGE;;;;
+0F86;TIBETAN SIGN LCI RTAGS;Mn;230;NSM;;;;;N;;;;;
+0F87;TIBETAN SIGN YANG RTAGS;Mn;230;NSM;;;;;N;;;;;
+0F88;TIBETAN SIGN LCE TSA CAN;Lo;0;L;;;;;N;;;;;
+0F89;TIBETAN SIGN MCHU CAN;Lo;0;L;;;;;N;;;;;
+0F8A;TIBETAN SIGN GRU CAN RGYINGS;Lo;0;L;;;;;N;;;;;
+0F8B;TIBETAN SIGN GRU MED RGYINGS;Lo;0;L;;;;;N;;;;;
+0F8C;TIBETAN SIGN INVERTED MCHU CAN;Lo;0;L;;;;;N;;;;;
+0F8D;TIBETAN SUBJOINED SIGN LCE TSA CAN;Mn;0;NSM;;;;;N;;;;;
+0F8E;TIBETAN SUBJOINED SIGN MCHU CAN;Mn;0;NSM;;;;;N;;;;;
+0F8F;TIBETAN SUBJOINED SIGN INVERTED MCHU CAN;Mn;0;NSM;;;;;N;;;;;
+0F90;TIBETAN SUBJOINED LETTER KA;Mn;0;NSM;;;;;N;;;;;
+0F91;TIBETAN SUBJOINED LETTER KHA;Mn;0;NSM;;;;;N;;;;;
+0F92;TIBETAN SUBJOINED LETTER GA;Mn;0;NSM;;;;;N;;;;;
+0F93;TIBETAN SUBJOINED LETTER GHA;Mn;0;NSM;0F92 0FB7;;;;N;;;;;
+0F94;TIBETAN SUBJOINED LETTER NGA;Mn;0;NSM;;;;;N;;;;;
+0F95;TIBETAN SUBJOINED LETTER CA;Mn;0;NSM;;;;;N;;;;;
+0F96;TIBETAN SUBJOINED LETTER CHA;Mn;0;NSM;;;;;N;;;;;
+0F97;TIBETAN SUBJOINED LETTER JA;Mn;0;NSM;;;;;N;;;;;
+0F99;TIBETAN SUBJOINED LETTER NYA;Mn;0;NSM;;;;;N;;;;;
+0F9A;TIBETAN SUBJOINED LETTER TTA;Mn;0;NSM;;;;;N;;;;;
+0F9B;TIBETAN SUBJOINED LETTER TTHA;Mn;0;NSM;;;;;N;;;;;
+0F9C;TIBETAN SUBJOINED LETTER DDA;Mn;0;NSM;;;;;N;;;;;
+0F9D;TIBETAN SUBJOINED LETTER DDHA;Mn;0;NSM;0F9C 0FB7;;;;N;;;;;
+0F9E;TIBETAN SUBJOINED LETTER NNA;Mn;0;NSM;;;;;N;;;;;
+0F9F;TIBETAN SUBJOINED LETTER TA;Mn;0;NSM;;;;;N;;;;;
+0FA0;TIBETAN SUBJOINED LETTER THA;Mn;0;NSM;;;;;N;;;;;
+0FA1;TIBETAN SUBJOINED LETTER DA;Mn;0;NSM;;;;;N;;;;;
+0FA2;TIBETAN SUBJOINED LETTER DHA;Mn;0;NSM;0FA1 0FB7;;;;N;;;;;
+0FA3;TIBETAN SUBJOINED LETTER NA;Mn;0;NSM;;;;;N;;;;;
+0FA4;TIBETAN SUBJOINED LETTER PA;Mn;0;NSM;;;;;N;;;;;
+0FA5;TIBETAN SUBJOINED LETTER PHA;Mn;0;NSM;;;;;N;;;;;
+0FA6;TIBETAN SUBJOINED LETTER BA;Mn;0;NSM;;;;;N;;;;;
+0FA7;TIBETAN SUBJOINED LETTER BHA;Mn;0;NSM;0FA6 0FB7;;;;N;;;;;
+0FA8;TIBETAN SUBJOINED LETTER MA;Mn;0;NSM;;;;;N;;;;;
+0FA9;TIBETAN SUBJOINED LETTER TSA;Mn;0;NSM;;;;;N;;;;;
+0FAA;TIBETAN SUBJOINED LETTER TSHA;Mn;0;NSM;;;;;N;;;;;
+0FAB;TIBETAN SUBJOINED LETTER DZA;Mn;0;NSM;;;;;N;;;;;
+0FAC;TIBETAN SUBJOINED LETTER DZHA;Mn;0;NSM;0FAB 0FB7;;;;N;;;;;
+0FAD;TIBETAN SUBJOINED LETTER WA;Mn;0;NSM;;;;;N;;;;;
+0FAE;TIBETAN SUBJOINED LETTER ZHA;Mn;0;NSM;;;;;N;;;;;
+0FAF;TIBETAN SUBJOINED LETTER ZA;Mn;0;NSM;;;;;N;;;;;
+0FB0;TIBETAN SUBJOINED LETTER -A;Mn;0;NSM;;;;;N;;;;;
+0FB1;TIBETAN SUBJOINED LETTER YA;Mn;0;NSM;;;;;N;;;;;
+0FB2;TIBETAN SUBJOINED LETTER RA;Mn;0;NSM;;;;;N;;;;;
+0FB3;TIBETAN SUBJOINED LETTER LA;Mn;0;NSM;;;;;N;;;;;
+0FB4;TIBETAN SUBJOINED LETTER SHA;Mn;0;NSM;;;;;N;;;;;
+0FB5;TIBETAN SUBJOINED LETTER SSA;Mn;0;NSM;;;;;N;;;;;
+0FB6;TIBETAN SUBJOINED LETTER SA;Mn;0;NSM;;;;;N;;;;;
+0FB7;TIBETAN SUBJOINED LETTER HA;Mn;0;NSM;;;;;N;;;;;
+0FB8;TIBETAN SUBJOINED LETTER A;Mn;0;NSM;;;;;N;;;;;
+0FB9;TIBETAN SUBJOINED LETTER KSSA;Mn;0;NSM;0F90 0FB5;;;;N;;;;;
+0FBA;TIBETAN SUBJOINED LETTER FIXED-FORM WA;Mn;0;NSM;;;;;N;;;;;
+0FBB;TIBETAN SUBJOINED LETTER FIXED-FORM YA;Mn;0;NSM;;;;;N;;;;;
+0FBC;TIBETAN SUBJOINED LETTER FIXED-FORM RA;Mn;0;NSM;;;;;N;;;;;
+0FBE;TIBETAN KU RU KHA;So;0;L;;;;;N;;;;;
+0FBF;TIBETAN KU RU KHA BZHI MIG CAN;So;0;L;;;;;N;;;;;
+0FC0;TIBETAN CANTILLATION SIGN HEAVY BEAT;So;0;L;;;;;N;;;;;
+0FC1;TIBETAN CANTILLATION SIGN LIGHT BEAT;So;0;L;;;;;N;;;;;
+0FC2;TIBETAN CANTILLATION SIGN CANG TE-U;So;0;L;;;;;N;;;;;
+0FC3;TIBETAN CANTILLATION SIGN SBUB -CHAL;So;0;L;;;;;N;;;;;
+0FC4;TIBETAN SYMBOL DRIL BU;So;0;L;;;;;N;;;;;
+0FC5;TIBETAN SYMBOL RDO RJE;So;0;L;;;;;N;;;;;
+0FC6;TIBETAN SYMBOL PADMA GDAN;Mn;220;NSM;;;;;N;;;;;
+0FC7;TIBETAN SYMBOL RDO RJE RGYA GRAM;So;0;L;;;;;N;;;;;
+0FC8;TIBETAN SYMBOL PHUR PA;So;0;L;;;;;N;;;;;
+0FC9;TIBETAN SYMBOL NOR BU;So;0;L;;;;;N;;;;;
+0FCA;TIBETAN SYMBOL NOR BU NYIS -KHYIL;So;0;L;;;;;N;;;;;
+0FCB;TIBETAN SYMBOL NOR BU GSUM -KHYIL;So;0;L;;;;;N;;;;;
+0FCC;TIBETAN SYMBOL NOR BU BZHI -KHYIL;So;0;L;;;;;N;;;;;
+0FCE;TIBETAN SIGN RDEL NAG RDEL DKAR;So;0;L;;;;;N;;;;;
+0FCF;TIBETAN SIGN RDEL NAG GSUM;So;0;L;;;;;N;;;;;
+0FD0;TIBETAN MARK BSKA- SHOG GI MGO RGYAN;Po;0;L;;;;;N;;;;;
+0FD1;TIBETAN MARK MNYAM YIG GI MGO RGYAN;Po;0;L;;;;;N;;;;;
+0FD2;TIBETAN MARK NYIS TSHEG;Po;0;L;;;;;N;;;;;
+0FD3;TIBETAN MARK INITIAL BRDA RNYING YIG MGO MDUN MA;Po;0;L;;;;;N;;;;;
+0FD4;TIBETAN MARK CLOSING BRDA RNYING YIG MGO SGAB MA;Po;0;L;;;;;N;;;;;
+0FD5;RIGHT-FACING SVASTI SIGN;So;0;L;;;;;N;;;;;
+0FD6;LEFT-FACING SVASTI SIGN;So;0;L;;;;;N;;;;;
+0FD7;RIGHT-FACING SVASTI SIGN WITH DOTS;So;0;L;;;;;N;;;;;
+0FD8;LEFT-FACING SVASTI SIGN WITH DOTS;So;0;L;;;;;N;;;;;
+0FD9;TIBETAN MARK LEADING MCHAN RTAGS;Po;0;L;;;;;N;;;;;
+0FDA;TIBETAN MARK TRAILING MCHAN RTAGS;Po;0;L;;;;;N;;;;;
+1000;MYANMAR LETTER KA;Lo;0;L;;;;;N;;;;;
+1001;MYANMAR LETTER KHA;Lo;0;L;;;;;N;;;;;
+1002;MYANMAR LETTER GA;Lo;0;L;;;;;N;;;;;
+1003;MYANMAR LETTER GHA;Lo;0;L;;;;;N;;;;;
+1004;MYANMAR LETTER NGA;Lo;0;L;;;;;N;;;;;
+1005;MYANMAR LETTER CA;Lo;0;L;;;;;N;;;;;
+1006;MYANMAR LETTER CHA;Lo;0;L;;;;;N;;;;;
+1007;MYANMAR LETTER JA;Lo;0;L;;;;;N;;;;;
+1008;MYANMAR LETTER JHA;Lo;0;L;;;;;N;;;;;
+1009;MYANMAR LETTER NYA;Lo;0;L;;;;;N;;;;;
+100A;MYANMAR LETTER NNYA;Lo;0;L;;;;;N;;;;;
+100B;MYANMAR LETTER TTA;Lo;0;L;;;;;N;;;;;
+100C;MYANMAR LETTER TTHA;Lo;0;L;;;;;N;;;;;
+100D;MYANMAR LETTER DDA;Lo;0;L;;;;;N;;;;;
+100E;MYANMAR LETTER DDHA;Lo;0;L;;;;;N;;;;;
+100F;MYANMAR LETTER NNA;Lo;0;L;;;;;N;;;;;
+1010;MYANMAR LETTER TA;Lo;0;L;;;;;N;;;;;
+1011;MYANMAR LETTER THA;Lo;0;L;;;;;N;;;;;
+1012;MYANMAR LETTER DA;Lo;0;L;;;;;N;;;;;
+1013;MYANMAR LETTER DHA;Lo;0;L;;;;;N;;;;;
+1014;MYANMAR LETTER NA;Lo;0;L;;;;;N;;;;;
+1015;MYANMAR LETTER PA;Lo;0;L;;;;;N;;;;;
+1016;MYANMAR LETTER PHA;Lo;0;L;;;;;N;;;;;
+1017;MYANMAR LETTER BA;Lo;0;L;;;;;N;;;;;
+1018;MYANMAR LETTER BHA;Lo;0;L;;;;;N;;;;;
+1019;MYANMAR LETTER MA;Lo;0;L;;;;;N;;;;;
+101A;MYANMAR LETTER YA;Lo;0;L;;;;;N;;;;;
+101B;MYANMAR LETTER RA;Lo;0;L;;;;;N;;;;;
+101C;MYANMAR LETTER LA;Lo;0;L;;;;;N;;;;;
+101D;MYANMAR LETTER WA;Lo;0;L;;;;;N;;;;;
+101E;MYANMAR LETTER SA;Lo;0;L;;;;;N;;;;;
+101F;MYANMAR LETTER HA;Lo;0;L;;;;;N;;;;;
+1020;MYANMAR LETTER LLA;Lo;0;L;;;;;N;;;;;
+1021;MYANMAR LETTER A;Lo;0;L;;;;;N;;;;;
+1022;MYANMAR LETTER SHAN A;Lo;0;L;;;;;N;;;;;
+1023;MYANMAR LETTER I;Lo;0;L;;;;;N;;;;;
+1024;MYANMAR LETTER II;Lo;0;L;;;;;N;;;;;
+1025;MYANMAR LETTER U;Lo;0;L;;;;;N;;;;;
+1026;MYANMAR LETTER UU;Lo;0;L;1025 102E;;;;N;;;;;
+1027;MYANMAR LETTER E;Lo;0;L;;;;;N;;;;;
+1028;MYANMAR LETTER MON E;Lo;0;L;;;;;N;;;;;
+1029;MYANMAR LETTER O;Lo;0;L;;;;;N;;;;;
+102A;MYANMAR LETTER AU;Lo;0;L;;;;;N;;;;;
+102B;MYANMAR VOWEL SIGN TALL AA;Mc;0;L;;;;;N;;;;;
+102C;MYANMAR VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
+102D;MYANMAR VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;
+102E;MYANMAR VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;;
+102F;MYANMAR VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+1030;MYANMAR VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;
+1031;MYANMAR VOWEL SIGN E;Mc;0;L;;;;;N;;;;;
+1032;MYANMAR VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;;
+1033;MYANMAR VOWEL SIGN MON II;Mn;0;NSM;;;;;N;;;;;
+1034;MYANMAR VOWEL SIGN MON O;Mn;0;NSM;;;;;N;;;;;
+1035;MYANMAR VOWEL SIGN E ABOVE;Mn;0;NSM;;;;;N;;;;;
+1036;MYANMAR SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;
+1037;MYANMAR SIGN DOT BELOW;Mn;7;NSM;;;;;N;;;;;
+1038;MYANMAR SIGN VISARGA;Mc;0;L;;;;;N;;;;;
+1039;MYANMAR SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;
+103A;MYANMAR SIGN ASAT;Mn;9;NSM;;;;;N;;;;;
+103B;MYANMAR CONSONANT SIGN MEDIAL YA;Mc;0;L;;;;;N;;;;;
+103C;MYANMAR CONSONANT SIGN MEDIAL RA;Mc;0;L;;;;;N;;;;;
+103D;MYANMAR CONSONANT SIGN MEDIAL WA;Mn;0;NSM;;;;;N;;;;;
+103E;MYANMAR CONSONANT SIGN MEDIAL HA;Mn;0;NSM;;;;;N;;;;;
+103F;MYANMAR LETTER GREAT SA;Lo;0;L;;;;;N;;;;;
+1040;MYANMAR DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+1041;MYANMAR DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+1042;MYANMAR DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+1043;MYANMAR DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+1044;MYANMAR DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+1045;MYANMAR DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+1046;MYANMAR DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+1047;MYANMAR DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+1048;MYANMAR DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+1049;MYANMAR DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+104A;MYANMAR SIGN LITTLE SECTION;Po;0;L;;;;;N;;;;;
+104B;MYANMAR SIGN SECTION;Po;0;L;;;;;N;;;;;
+104C;MYANMAR SYMBOL LOCATIVE;Po;0;L;;;;;N;;;;;
+104D;MYANMAR SYMBOL COMPLETED;Po;0;L;;;;;N;;;;;
+104E;MYANMAR SYMBOL AFOREMENTIONED;Po;0;L;;;;;N;;;;;
+104F;MYANMAR SYMBOL GENITIVE;Po;0;L;;;;;N;;;;;
+1050;MYANMAR LETTER SHA;Lo;0;L;;;;;N;;;;;
+1051;MYANMAR LETTER SSA;Lo;0;L;;;;;N;;;;;
+1052;MYANMAR LETTER VOCALIC R;Lo;0;L;;;;;N;;;;;
+1053;MYANMAR LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;;
+1054;MYANMAR LETTER VOCALIC L;Lo;0;L;;;;;N;;;;;
+1055;MYANMAR LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;;
+1056;MYANMAR VOWEL SIGN VOCALIC R;Mc;0;L;;;;;N;;;;;
+1057;MYANMAR VOWEL SIGN VOCALIC RR;Mc;0;L;;;;;N;;;;;
+1058;MYANMAR VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;;
+1059;MYANMAR VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;;
+105A;MYANMAR LETTER MON NGA;Lo;0;L;;;;;N;;;;;
+105B;MYANMAR LETTER MON JHA;Lo;0;L;;;;;N;;;;;
+105C;MYANMAR LETTER MON BBA;Lo;0;L;;;;;N;;;;;
+105D;MYANMAR LETTER MON BBE;Lo;0;L;;;;;N;;;;;
+105E;MYANMAR CONSONANT SIGN MON MEDIAL NA;Mn;0;NSM;;;;;N;;;;;
+105F;MYANMAR CONSONANT SIGN MON MEDIAL MA;Mn;0;NSM;;;;;N;;;;;
+1060;MYANMAR CONSONANT SIGN MON MEDIAL LA;Mn;0;NSM;;;;;N;;;;;
+1061;MYANMAR LETTER SGAW KAREN SHA;Lo;0;L;;;;;N;;;;;
+1062;MYANMAR VOWEL SIGN SGAW KAREN EU;Mc;0;L;;;;;N;;;;;
+1063;MYANMAR TONE MARK SGAW KAREN HATHI;Mc;0;L;;;;;N;;;;;
+1064;MYANMAR TONE MARK SGAW KAREN KE PHO;Mc;0;L;;;;;N;;;;;
+1065;MYANMAR LETTER WESTERN PWO KAREN THA;Lo;0;L;;;;;N;;;;;
+1066;MYANMAR LETTER WESTERN PWO KAREN PWA;Lo;0;L;;;;;N;;;;;
+1067;MYANMAR VOWEL SIGN WESTERN PWO KAREN EU;Mc;0;L;;;;;N;;;;;
+1068;MYANMAR VOWEL SIGN WESTERN PWO KAREN UE;Mc;0;L;;;;;N;;;;;
+1069;MYANMAR SIGN WESTERN PWO KAREN TONE-1;Mc;0;L;;;;;N;;;;;
+106A;MYANMAR SIGN WESTERN PWO KAREN TONE-2;Mc;0;L;;;;;N;;;;;
+106B;MYANMAR SIGN WESTERN PWO KAREN TONE-3;Mc;0;L;;;;;N;;;;;
+106C;MYANMAR SIGN WESTERN PWO KAREN TONE-4;Mc;0;L;;;;;N;;;;;
+106D;MYANMAR SIGN WESTERN PWO KAREN TONE-5;Mc;0;L;;;;;N;;;;;
+106E;MYANMAR LETTER EASTERN PWO KAREN NNA;Lo;0;L;;;;;N;;;;;
+106F;MYANMAR LETTER EASTERN PWO KAREN YWA;Lo;0;L;;;;;N;;;;;
+1070;MYANMAR LETTER EASTERN PWO KAREN GHWA;Lo;0;L;;;;;N;;;;;
+1071;MYANMAR VOWEL SIGN GEBA KAREN I;Mn;0;NSM;;;;;N;;;;;
+1072;MYANMAR VOWEL SIGN KAYAH OE;Mn;0;NSM;;;;;N;;;;;
+1073;MYANMAR VOWEL SIGN KAYAH U;Mn;0;NSM;;;;;N;;;;;
+1074;MYANMAR VOWEL SIGN KAYAH EE;Mn;0;NSM;;;;;N;;;;;
+1075;MYANMAR LETTER SHAN KA;Lo;0;L;;;;;N;;;;;
+1076;MYANMAR LETTER SHAN KHA;Lo;0;L;;;;;N;;;;;
+1077;MYANMAR LETTER SHAN GA;Lo;0;L;;;;;N;;;;;
+1078;MYANMAR LETTER SHAN CA;Lo;0;L;;;;;N;;;;;
+1079;MYANMAR LETTER SHAN ZA;Lo;0;L;;;;;N;;;;;
+107A;MYANMAR LETTER SHAN NYA;Lo;0;L;;;;;N;;;;;
+107B;MYANMAR LETTER SHAN DA;Lo;0;L;;;;;N;;;;;
+107C;MYANMAR LETTER SHAN NA;Lo;0;L;;;;;N;;;;;
+107D;MYANMAR LETTER SHAN PHA;Lo;0;L;;;;;N;;;;;
+107E;MYANMAR LETTER SHAN FA;Lo;0;L;;;;;N;;;;;
+107F;MYANMAR LETTER SHAN BA;Lo;0;L;;;;;N;;;;;
+1080;MYANMAR LETTER SHAN THA;Lo;0;L;;;;;N;;;;;
+1081;MYANMAR LETTER SHAN HA;Lo;0;L;;;;;N;;;;;
+1082;MYANMAR CONSONANT SIGN SHAN MEDIAL WA;Mn;0;NSM;;;;;N;;;;;
+1083;MYANMAR VOWEL SIGN SHAN AA;Mc;0;L;;;;;N;;;;;
+1084;MYANMAR VOWEL SIGN SHAN E;Mc;0;L;;;;;N;;;;;
+1085;MYANMAR VOWEL SIGN SHAN E ABOVE;Mn;0;NSM;;;;;N;;;;;
+1086;MYANMAR VOWEL SIGN SHAN FINAL Y;Mn;0;NSM;;;;;N;;;;;
+1087;MYANMAR SIGN SHAN TONE-2;Mc;0;L;;;;;N;;;;;
+1088;MYANMAR SIGN SHAN TONE-3;Mc;0;L;;;;;N;;;;;
+1089;MYANMAR SIGN SHAN TONE-5;Mc;0;L;;;;;N;;;;;
+108A;MYANMAR SIGN SHAN TONE-6;Mc;0;L;;;;;N;;;;;
+108B;MYANMAR SIGN SHAN COUNCIL TONE-2;Mc;0;L;;;;;N;;;;;
+108C;MYANMAR SIGN SHAN COUNCIL TONE-3;Mc;0;L;;;;;N;;;;;
+108D;MYANMAR SIGN SHAN COUNCIL EMPHATIC TONE;Mn;220;NSM;;;;;N;;;;;
+108E;MYANMAR LETTER RUMAI PALAUNG FA;Lo;0;L;;;;;N;;;;;
+108F;MYANMAR SIGN RUMAI PALAUNG TONE-5;Mc;0;L;;;;;N;;;;;
+1090;MYANMAR SHAN DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+1091;MYANMAR SHAN DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+1092;MYANMAR SHAN DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+1093;MYANMAR SHAN DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+1094;MYANMAR SHAN DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+1095;MYANMAR SHAN DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+1096;MYANMAR SHAN DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+1097;MYANMAR SHAN DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+1098;MYANMAR SHAN DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+1099;MYANMAR SHAN DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+109A;MYANMAR SIGN KHAMTI TONE-1;Mc;0;L;;;;;N;;;;;
+109B;MYANMAR SIGN KHAMTI TONE-3;Mc;0;L;;;;;N;;;;;
+109C;MYANMAR VOWEL SIGN AITON A;Mc;0;L;;;;;N;;;;;
+109D;MYANMAR VOWEL SIGN AITON AI;Mn;0;NSM;;;;;N;;;;;
+109E;MYANMAR SYMBOL SHAN ONE;So;0;L;;;;;N;;;;;
+109F;MYANMAR SYMBOL SHAN EXCLAMATION;So;0;L;;;;;N;;;;;
+10A0;GEORGIAN CAPITAL LETTER AN;Lu;0;L;;;;;N;;;;2D00;
+10A1;GEORGIAN CAPITAL LETTER BAN;Lu;0;L;;;;;N;;;;2D01;
+10A2;GEORGIAN CAPITAL LETTER GAN;Lu;0;L;;;;;N;;;;2D02;
+10A3;GEORGIAN CAPITAL LETTER DON;Lu;0;L;;;;;N;;;;2D03;
+10A4;GEORGIAN CAPITAL LETTER EN;Lu;0;L;;;;;N;;;;2D04;
+10A5;GEORGIAN CAPITAL LETTER VIN;Lu;0;L;;;;;N;;;;2D05;
+10A6;GEORGIAN CAPITAL LETTER ZEN;Lu;0;L;;;;;N;;;;2D06;
+10A7;GEORGIAN CAPITAL LETTER TAN;Lu;0;L;;;;;N;;;;2D07;
+10A8;GEORGIAN CAPITAL LETTER IN;Lu;0;L;;;;;N;;;;2D08;
+10A9;GEORGIAN CAPITAL LETTER KAN;Lu;0;L;;;;;N;;;;2D09;
+10AA;GEORGIAN CAPITAL LETTER LAS;Lu;0;L;;;;;N;;;;2D0A;
+10AB;GEORGIAN CAPITAL LETTER MAN;Lu;0;L;;;;;N;;;;2D0B;
+10AC;GEORGIAN CAPITAL LETTER NAR;Lu;0;L;;;;;N;;;;2D0C;
+10AD;GEORGIAN CAPITAL LETTER ON;Lu;0;L;;;;;N;;;;2D0D;
+10AE;GEORGIAN CAPITAL LETTER PAR;Lu;0;L;;;;;N;;;;2D0E;
+10AF;GEORGIAN CAPITAL LETTER ZHAR;Lu;0;L;;;;;N;;;;2D0F;
+10B0;GEORGIAN CAPITAL LETTER RAE;Lu;0;L;;;;;N;;;;2D10;
+10B1;GEORGIAN CAPITAL LETTER SAN;Lu;0;L;;;;;N;;;;2D11;
+10B2;GEORGIAN CAPITAL LETTER TAR;Lu;0;L;;;;;N;;;;2D12;
+10B3;GEORGIAN CAPITAL LETTER UN;Lu;0;L;;;;;N;;;;2D13;
+10B4;GEORGIAN CAPITAL LETTER PHAR;Lu;0;L;;;;;N;;;;2D14;
+10B5;GEORGIAN CAPITAL LETTER KHAR;Lu;0;L;;;;;N;;;;2D15;
+10B6;GEORGIAN CAPITAL LETTER GHAN;Lu;0;L;;;;;N;;;;2D16;
+10B7;GEORGIAN CAPITAL LETTER QAR;Lu;0;L;;;;;N;;;;2D17;
+10B8;GEORGIAN CAPITAL LETTER SHIN;Lu;0;L;;;;;N;;;;2D18;
+10B9;GEORGIAN CAPITAL LETTER CHIN;Lu;0;L;;;;;N;;;;2D19;
+10BA;GEORGIAN CAPITAL LETTER CAN;Lu;0;L;;;;;N;;;;2D1A;
+10BB;GEORGIAN CAPITAL LETTER JIL;Lu;0;L;;;;;N;;;;2D1B;
+10BC;GEORGIAN CAPITAL LETTER CIL;Lu;0;L;;;;;N;;;;2D1C;
+10BD;GEORGIAN CAPITAL LETTER CHAR;Lu;0;L;;;;;N;;;;2D1D;
+10BE;GEORGIAN CAPITAL LETTER XAN;Lu;0;L;;;;;N;;;;2D1E;
+10BF;GEORGIAN CAPITAL LETTER JHAN;Lu;0;L;;;;;N;;;;2D1F;
+10C0;GEORGIAN CAPITAL LETTER HAE;Lu;0;L;;;;;N;;;;2D20;
+10C1;GEORGIAN CAPITAL LETTER HE;Lu;0;L;;;;;N;;;;2D21;
+10C2;GEORGIAN CAPITAL LETTER HIE;Lu;0;L;;;;;N;;;;2D22;
+10C3;GEORGIAN CAPITAL LETTER WE;Lu;0;L;;;;;N;;;;2D23;
+10C4;GEORGIAN CAPITAL LETTER HAR;Lu;0;L;;;;;N;;;;2D24;
+10C5;GEORGIAN CAPITAL LETTER HOE;Lu;0;L;;;;;N;;;;2D25;
+10D0;GEORGIAN LETTER AN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER AN;;;;
+10D1;GEORGIAN LETTER BAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER BAN;;;;
+10D2;GEORGIAN LETTER GAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER GAN;;;;
+10D3;GEORGIAN LETTER DON;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER DON;;;;
+10D4;GEORGIAN LETTER EN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER EN;;;;
+10D5;GEORGIAN LETTER VIN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER VIN;;;;
+10D6;GEORGIAN LETTER ZEN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER ZEN;;;;
+10D7;GEORGIAN LETTER TAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER TAN;;;;
+10D8;GEORGIAN LETTER IN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER IN;;;;
+10D9;GEORGIAN LETTER KAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER KAN;;;;
+10DA;GEORGIAN LETTER LAS;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER LAS;;;;
+10DB;GEORGIAN LETTER MAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER MAN;;;;
+10DC;GEORGIAN LETTER NAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER NAR;;;;
+10DD;GEORGIAN LETTER ON;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER ON;;;;
+10DE;GEORGIAN LETTER PAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER PAR;;;;
+10DF;GEORGIAN LETTER ZHAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER ZHAR;;;;
+10E0;GEORGIAN LETTER RAE;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER RAE;;;;
+10E1;GEORGIAN LETTER SAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER SAN;;;;
+10E2;GEORGIAN LETTER TAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER TAR;;;;
+10E3;GEORGIAN LETTER UN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER UN;;;;
+10E4;GEORGIAN LETTER PHAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER PHAR;;;;
+10E5;GEORGIAN LETTER KHAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER KHAR;;;;
+10E6;GEORGIAN LETTER GHAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER GHAN;;;;
+10E7;GEORGIAN LETTER QAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER QAR;;;;
+10E8;GEORGIAN LETTER SHIN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER SHIN;;;;
+10E9;GEORGIAN LETTER CHIN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER CHIN;;;;
+10EA;GEORGIAN LETTER CAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER CAN;;;;
+10EB;GEORGIAN LETTER JIL;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER JIL;;;;
+10EC;GEORGIAN LETTER CIL;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER CIL;;;;
+10ED;GEORGIAN LETTER CHAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER CHAR;;;;
+10EE;GEORGIAN LETTER XAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER XAN;;;;
+10EF;GEORGIAN LETTER JHAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER JHAN;;;;
+10F0;GEORGIAN LETTER HAE;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER HAE;;;;
+10F1;GEORGIAN LETTER HE;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER HE;;;;
+10F2;GEORGIAN LETTER HIE;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER HIE;;;;
+10F3;GEORGIAN LETTER WE;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER WE;;;;
+10F4;GEORGIAN LETTER HAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER HAR;;;;
+10F5;GEORGIAN LETTER HOE;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER HOE;;;;
+10F6;GEORGIAN LETTER FI;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER FI;;;;
+10F7;GEORGIAN LETTER YN;Lo;0;L;;;;;N;;;;;
+10F8;GEORGIAN LETTER ELIFI;Lo;0;L;;;;;N;;;;;
+10F9;GEORGIAN LETTER TURNED GAN;Lo;0;L;;;;;N;;;;;
+10FA;GEORGIAN LETTER AIN;Lo;0;L;;;;;N;;;;;
+10FB;GEORGIAN PARAGRAPH SEPARATOR;Po;0;L;;;;;N;;;;;
+10FC;MODIFIER LETTER GEORGIAN NAR;Lm;0;L;<super> 10DC;;;;N;;;;;
+1100;HANGUL CHOSEONG KIYEOK;Lo;0;L;;;;;N;;;;;
+1101;HANGUL CHOSEONG SSANGKIYEOK;Lo;0;L;;;;;N;;;;;
+1102;HANGUL CHOSEONG NIEUN;Lo;0;L;;;;;N;;;;;
+1103;HANGUL CHOSEONG TIKEUT;Lo;0;L;;;;;N;;;;;
+1104;HANGUL CHOSEONG SSANGTIKEUT;Lo;0;L;;;;;N;;;;;
+1105;HANGUL CHOSEONG RIEUL;Lo;0;L;;;;;N;;;;;
+1106;HANGUL CHOSEONG MIEUM;Lo;0;L;;;;;N;;;;;
+1107;HANGUL CHOSEONG PIEUP;Lo;0;L;;;;;N;;;;;
+1108;HANGUL CHOSEONG SSANGPIEUP;Lo;0;L;;;;;N;;;;;
+1109;HANGUL CHOSEONG SIOS;Lo;0;L;;;;;N;;;;;
+110A;HANGUL CHOSEONG SSANGSIOS;Lo;0;L;;;;;N;;;;;
+110B;HANGUL CHOSEONG IEUNG;Lo;0;L;;;;;N;;;;;
+110C;HANGUL CHOSEONG CIEUC;Lo;0;L;;;;;N;;;;;
+110D;HANGUL CHOSEONG SSANGCIEUC;Lo;0;L;;;;;N;;;;;
+110E;HANGUL CHOSEONG CHIEUCH;Lo;0;L;;;;;N;;;;;
+110F;HANGUL CHOSEONG KHIEUKH;Lo;0;L;;;;;N;;;;;
+1110;HANGUL CHOSEONG THIEUTH;Lo;0;L;;;;;N;;;;;
+1111;HANGUL CHOSEONG PHIEUPH;Lo;0;L;;;;;N;;;;;
+1112;HANGUL CHOSEONG HIEUH;Lo;0;L;;;;;N;;;;;
+1113;HANGUL CHOSEONG NIEUN-KIYEOK;Lo;0;L;;;;;N;;;;;
+1114;HANGUL CHOSEONG SSANGNIEUN;Lo;0;L;;;;;N;;;;;
+1115;HANGUL CHOSEONG NIEUN-TIKEUT;Lo;0;L;;;;;N;;;;;
+1116;HANGUL CHOSEONG NIEUN-PIEUP;Lo;0;L;;;;;N;;;;;
+1117;HANGUL CHOSEONG TIKEUT-KIYEOK;Lo;0;L;;;;;N;;;;;
+1118;HANGUL CHOSEONG RIEUL-NIEUN;Lo;0;L;;;;;N;;;;;
+1119;HANGUL CHOSEONG SSANGRIEUL;Lo;0;L;;;;;N;;;;;
+111A;HANGUL CHOSEONG RIEUL-HIEUH;Lo;0;L;;;;;N;;;;;
+111B;HANGUL CHOSEONG KAPYEOUNRIEUL;Lo;0;L;;;;;N;;;;;
+111C;HANGUL CHOSEONG MIEUM-PIEUP;Lo;0;L;;;;;N;;;;;
+111D;HANGUL CHOSEONG KAPYEOUNMIEUM;Lo;0;L;;;;;N;;;;;
+111E;HANGUL CHOSEONG PIEUP-KIYEOK;Lo;0;L;;;;;N;;;;;
+111F;HANGUL CHOSEONG PIEUP-NIEUN;Lo;0;L;;;;;N;;;;;
+1120;HANGUL CHOSEONG PIEUP-TIKEUT;Lo;0;L;;;;;N;;;;;
+1121;HANGUL CHOSEONG PIEUP-SIOS;Lo;0;L;;;;;N;;;;;
+1122;HANGUL CHOSEONG PIEUP-SIOS-KIYEOK;Lo;0;L;;;;;N;;;;;
+1123;HANGUL CHOSEONG PIEUP-SIOS-TIKEUT;Lo;0;L;;;;;N;;;;;
+1124;HANGUL CHOSEONG PIEUP-SIOS-PIEUP;Lo;0;L;;;;;N;;;;;
+1125;HANGUL CHOSEONG PIEUP-SSANGSIOS;Lo;0;L;;;;;N;;;;;
+1126;HANGUL CHOSEONG PIEUP-SIOS-CIEUC;Lo;0;L;;;;;N;;;;;
+1127;HANGUL CHOSEONG PIEUP-CIEUC;Lo;0;L;;;;;N;;;;;
+1128;HANGUL CHOSEONG PIEUP-CHIEUCH;Lo;0;L;;;;;N;;;;;
+1129;HANGUL CHOSEONG PIEUP-THIEUTH;Lo;0;L;;;;;N;;;;;
+112A;HANGUL CHOSEONG PIEUP-PHIEUPH;Lo;0;L;;;;;N;;;;;
+112B;HANGUL CHOSEONG KAPYEOUNPIEUP;Lo;0;L;;;;;N;;;;;
+112C;HANGUL CHOSEONG KAPYEOUNSSANGPIEUP;Lo;0;L;;;;;N;;;;;
+112D;HANGUL CHOSEONG SIOS-KIYEOK;Lo;0;L;;;;;N;;;;;
+112E;HANGUL CHOSEONG SIOS-NIEUN;Lo;0;L;;;;;N;;;;;
+112F;HANGUL CHOSEONG SIOS-TIKEUT;Lo;0;L;;;;;N;;;;;
+1130;HANGUL CHOSEONG SIOS-RIEUL;Lo;0;L;;;;;N;;;;;
+1131;HANGUL CHOSEONG SIOS-MIEUM;Lo;0;L;;;;;N;;;;;
+1132;HANGUL CHOSEONG SIOS-PIEUP;Lo;0;L;;;;;N;;;;;
+1133;HANGUL CHOSEONG SIOS-PIEUP-KIYEOK;Lo;0;L;;;;;N;;;;;
+1134;HANGUL CHOSEONG SIOS-SSANGSIOS;Lo;0;L;;;;;N;;;;;
+1135;HANGUL CHOSEONG SIOS-IEUNG;Lo;0;L;;;;;N;;;;;
+1136;HANGUL CHOSEONG SIOS-CIEUC;Lo;0;L;;;;;N;;;;;
+1137;HANGUL CHOSEONG SIOS-CHIEUCH;Lo;0;L;;;;;N;;;;;
+1138;HANGUL CHOSEONG SIOS-KHIEUKH;Lo;0;L;;;;;N;;;;;
+1139;HANGUL CHOSEONG SIOS-THIEUTH;Lo;0;L;;;;;N;;;;;
+113A;HANGUL CHOSEONG SIOS-PHIEUPH;Lo;0;L;;;;;N;;;;;
+113B;HANGUL CHOSEONG SIOS-HIEUH;Lo;0;L;;;;;N;;;;;
+113C;HANGUL CHOSEONG CHITUEUMSIOS;Lo;0;L;;;;;N;;;;;
+113D;HANGUL CHOSEONG CHITUEUMSSANGSIOS;Lo;0;L;;;;;N;;;;;
+113E;HANGUL CHOSEONG CEONGCHIEUMSIOS;Lo;0;L;;;;;N;;;;;
+113F;HANGUL CHOSEONG CEONGCHIEUMSSANGSIOS;Lo;0;L;;;;;N;;;;;
+1140;HANGUL CHOSEONG PANSIOS;Lo;0;L;;;;;N;;;;;
+1141;HANGUL CHOSEONG IEUNG-KIYEOK;Lo;0;L;;;;;N;;;;;
+1142;HANGUL CHOSEONG IEUNG-TIKEUT;Lo;0;L;;;;;N;;;;;
+1143;HANGUL CHOSEONG IEUNG-MIEUM;Lo;0;L;;;;;N;;;;;
+1144;HANGUL CHOSEONG IEUNG-PIEUP;Lo;0;L;;;;;N;;;;;
+1145;HANGUL CHOSEONG IEUNG-SIOS;Lo;0;L;;;;;N;;;;;
+1146;HANGUL CHOSEONG IEUNG-PANSIOS;Lo;0;L;;;;;N;;;;;
+1147;HANGUL CHOSEONG SSANGIEUNG;Lo;0;L;;;;;N;;;;;
+1148;HANGUL CHOSEONG IEUNG-CIEUC;Lo;0;L;;;;;N;;;;;
+1149;HANGUL CHOSEONG IEUNG-CHIEUCH;Lo;0;L;;;;;N;;;;;
+114A;HANGUL CHOSEONG IEUNG-THIEUTH;Lo;0;L;;;;;N;;;;;
+114B;HANGUL CHOSEONG IEUNG-PHIEUPH;Lo;0;L;;;;;N;;;;;
+114C;HANGUL CHOSEONG YESIEUNG;Lo;0;L;;;;;N;;;;;
+114D;HANGUL CHOSEONG CIEUC-IEUNG;Lo;0;L;;;;;N;;;;;
+114E;HANGUL CHOSEONG CHITUEUMCIEUC;Lo;0;L;;;;;N;;;;;
+114F;HANGUL CHOSEONG CHITUEUMSSANGCIEUC;Lo;0;L;;;;;N;;;;;
+1150;HANGUL CHOSEONG CEONGCHIEUMCIEUC;Lo;0;L;;;;;N;;;;;
+1151;HANGUL CHOSEONG CEONGCHIEUMSSANGCIEUC;Lo;0;L;;;;;N;;;;;
+1152;HANGUL CHOSEONG CHIEUCH-KHIEUKH;Lo;0;L;;;;;N;;;;;
+1153;HANGUL CHOSEONG CHIEUCH-HIEUH;Lo;0;L;;;;;N;;;;;
+1154;HANGUL CHOSEONG CHITUEUMCHIEUCH;Lo;0;L;;;;;N;;;;;
+1155;HANGUL CHOSEONG CEONGCHIEUMCHIEUCH;Lo;0;L;;;;;N;;;;;
+1156;HANGUL CHOSEONG PHIEUPH-PIEUP;Lo;0;L;;;;;N;;;;;
+1157;HANGUL CHOSEONG KAPYEOUNPHIEUPH;Lo;0;L;;;;;N;;;;;
+1158;HANGUL CHOSEONG SSANGHIEUH;Lo;0;L;;;;;N;;;;;
+1159;HANGUL CHOSEONG YEORINHIEUH;Lo;0;L;;;;;N;;;;;
+115A;HANGUL CHOSEONG KIYEOK-TIKEUT;Lo;0;L;;;;;N;;;;;
+115B;HANGUL CHOSEONG NIEUN-SIOS;Lo;0;L;;;;;N;;;;;
+115C;HANGUL CHOSEONG NIEUN-CIEUC;Lo;0;L;;;;;N;;;;;
+115D;HANGUL CHOSEONG NIEUN-HIEUH;Lo;0;L;;;;;N;;;;;
+115E;HANGUL CHOSEONG TIKEUT-RIEUL;Lo;0;L;;;;;N;;;;;
+115F;HANGUL CHOSEONG FILLER;Lo;0;L;;;;;N;;;;;
+1160;HANGUL JUNGSEONG FILLER;Lo;0;L;;;;;N;;;;;
+1161;HANGUL JUNGSEONG A;Lo;0;L;;;;;N;;;;;
+1162;HANGUL JUNGSEONG AE;Lo;0;L;;;;;N;;;;;
+1163;HANGUL JUNGSEONG YA;Lo;0;L;;;;;N;;;;;
+1164;HANGUL JUNGSEONG YAE;Lo;0;L;;;;;N;;;;;
+1165;HANGUL JUNGSEONG EO;Lo;0;L;;;;;N;;;;;
+1166;HANGUL JUNGSEONG E;Lo;0;L;;;;;N;;;;;
+1167;HANGUL JUNGSEONG YEO;Lo;0;L;;;;;N;;;;;
+1168;HANGUL JUNGSEONG YE;Lo;0;L;;;;;N;;;;;
+1169;HANGUL JUNGSEONG O;Lo;0;L;;;;;N;;;;;
+116A;HANGUL JUNGSEONG WA;Lo;0;L;;;;;N;;;;;
+116B;HANGUL JUNGSEONG WAE;Lo;0;L;;;;;N;;;;;
+116C;HANGUL JUNGSEONG OE;Lo;0;L;;;;;N;;;;;
+116D;HANGUL JUNGSEONG YO;Lo;0;L;;;;;N;;;;;
+116E;HANGUL JUNGSEONG U;Lo;0;L;;;;;N;;;;;
+116F;HANGUL JUNGSEONG WEO;Lo;0;L;;;;;N;;;;;
+1170;HANGUL JUNGSEONG WE;Lo;0;L;;;;;N;;;;;
+1171;HANGUL JUNGSEONG WI;Lo;0;L;;;;;N;;;;;
+1172;HANGUL JUNGSEONG YU;Lo;0;L;;;;;N;;;;;
+1173;HANGUL JUNGSEONG EU;Lo;0;L;;;;;N;;;;;
+1174;HANGUL JUNGSEONG YI;Lo;0;L;;;;;N;;;;;
+1175;HANGUL JUNGSEONG I;Lo;0;L;;;;;N;;;;;
+1176;HANGUL JUNGSEONG A-O;Lo;0;L;;;;;N;;;;;
+1177;HANGUL JUNGSEONG A-U;Lo;0;L;;;;;N;;;;;
+1178;HANGUL JUNGSEONG YA-O;Lo;0;L;;;;;N;;;;;
+1179;HANGUL JUNGSEONG YA-YO;Lo;0;L;;;;;N;;;;;
+117A;HANGUL JUNGSEONG EO-O;Lo;0;L;;;;;N;;;;;
+117B;HANGUL JUNGSEONG EO-U;Lo;0;L;;;;;N;;;;;
+117C;HANGUL JUNGSEONG EO-EU;Lo;0;L;;;;;N;;;;;
+117D;HANGUL JUNGSEONG YEO-O;Lo;0;L;;;;;N;;;;;
+117E;HANGUL JUNGSEONG YEO-U;Lo;0;L;;;;;N;;;;;
+117F;HANGUL JUNGSEONG O-EO;Lo;0;L;;;;;N;;;;;
+1180;HANGUL JUNGSEONG O-E;Lo;0;L;;;;;N;;;;;
+1181;HANGUL JUNGSEONG O-YE;Lo;0;L;;;;;N;;;;;
+1182;HANGUL JUNGSEONG O-O;Lo;0;L;;;;;N;;;;;
+1183;HANGUL JUNGSEONG O-U;Lo;0;L;;;;;N;;;;;
+1184;HANGUL JUNGSEONG YO-YA;Lo;0;L;;;;;N;;;;;
+1185;HANGUL JUNGSEONG YO-YAE;Lo;0;L;;;;;N;;;;;
+1186;HANGUL JUNGSEONG YO-YEO;Lo;0;L;;;;;N;;;;;
+1187;HANGUL JUNGSEONG YO-O;Lo;0;L;;;;;N;;;;;
+1188;HANGUL JUNGSEONG YO-I;Lo;0;L;;;;;N;;;;;
+1189;HANGUL JUNGSEONG U-A;Lo;0;L;;;;;N;;;;;
+118A;HANGUL JUNGSEONG U-AE;Lo;0;L;;;;;N;;;;;
+118B;HANGUL JUNGSEONG U-EO-EU;Lo;0;L;;;;;N;;;;;
+118C;HANGUL JUNGSEONG U-YE;Lo;0;L;;;;;N;;;;;
+118D;HANGUL JUNGSEONG U-U;Lo;0;L;;;;;N;;;;;
+118E;HANGUL JUNGSEONG YU-A;Lo;0;L;;;;;N;;;;;
+118F;HANGUL JUNGSEONG YU-EO;Lo;0;L;;;;;N;;;;;
+1190;HANGUL JUNGSEONG YU-E;Lo;0;L;;;;;N;;;;;
+1191;HANGUL JUNGSEONG YU-YEO;Lo;0;L;;;;;N;;;;;
+1192;HANGUL JUNGSEONG YU-YE;Lo;0;L;;;;;N;;;;;
+1193;HANGUL JUNGSEONG YU-U;Lo;0;L;;;;;N;;;;;
+1194;HANGUL JUNGSEONG YU-I;Lo;0;L;;;;;N;;;;;
+1195;HANGUL JUNGSEONG EU-U;Lo;0;L;;;;;N;;;;;
+1196;HANGUL JUNGSEONG EU-EU;Lo;0;L;;;;;N;;;;;
+1197;HANGUL JUNGSEONG YI-U;Lo;0;L;;;;;N;;;;;
+1198;HANGUL JUNGSEONG I-A;Lo;0;L;;;;;N;;;;;
+1199;HANGUL JUNGSEONG I-YA;Lo;0;L;;;;;N;;;;;
+119A;HANGUL JUNGSEONG I-O;Lo;0;L;;;;;N;;;;;
+119B;HANGUL JUNGSEONG I-U;Lo;0;L;;;;;N;;;;;
+119C;HANGUL JUNGSEONG I-EU;Lo;0;L;;;;;N;;;;;
+119D;HANGUL JUNGSEONG I-ARAEA;Lo;0;L;;;;;N;;;;;
+119E;HANGUL JUNGSEONG ARAEA;Lo;0;L;;;;;N;;;;;
+119F;HANGUL JUNGSEONG ARAEA-EO;Lo;0;L;;;;;N;;;;;
+11A0;HANGUL JUNGSEONG ARAEA-U;Lo;0;L;;;;;N;;;;;
+11A1;HANGUL JUNGSEONG ARAEA-I;Lo;0;L;;;;;N;;;;;
+11A2;HANGUL JUNGSEONG SSANGARAEA;Lo;0;L;;;;;N;;;;;
+11A3;HANGUL JUNGSEONG A-EU;Lo;0;L;;;;;N;;;;;
+11A4;HANGUL JUNGSEONG YA-U;Lo;0;L;;;;;N;;;;;
+11A5;HANGUL JUNGSEONG YEO-YA;Lo;0;L;;;;;N;;;;;
+11A6;HANGUL JUNGSEONG O-YA;Lo;0;L;;;;;N;;;;;
+11A7;HANGUL JUNGSEONG O-YAE;Lo;0;L;;;;;N;;;;;
+11A8;HANGUL JONGSEONG KIYEOK;Lo;0;L;;;;;N;;;;;
+11A9;HANGUL JONGSEONG SSANGKIYEOK;Lo;0;L;;;;;N;;;;;
+11AA;HANGUL JONGSEONG KIYEOK-SIOS;Lo;0;L;;;;;N;;;;;
+11AB;HANGUL JONGSEONG NIEUN;Lo;0;L;;;;;N;;;;;
+11AC;HANGUL JONGSEONG NIEUN-CIEUC;Lo;0;L;;;;;N;;;;;
+11AD;HANGUL JONGSEONG NIEUN-HIEUH;Lo;0;L;;;;;N;;;;;
+11AE;HANGUL JONGSEONG TIKEUT;Lo;0;L;;;;;N;;;;;
+11AF;HANGUL JONGSEONG RIEUL;Lo;0;L;;;;;N;;;;;
+11B0;HANGUL JONGSEONG RIEUL-KIYEOK;Lo;0;L;;;;;N;;;;;
+11B1;HANGUL JONGSEONG RIEUL-MIEUM;Lo;0;L;;;;;N;;;;;
+11B2;HANGUL JONGSEONG RIEUL-PIEUP;Lo;0;L;;;;;N;;;;;
+11B3;HANGUL JONGSEONG RIEUL-SIOS;Lo;0;L;;;;;N;;;;;
+11B4;HANGUL JONGSEONG RIEUL-THIEUTH;Lo;0;L;;;;;N;;;;;
+11B5;HANGUL JONGSEONG RIEUL-PHIEUPH;Lo;0;L;;;;;N;;;;;
+11B6;HANGUL JONGSEONG RIEUL-HIEUH;Lo;0;L;;;;;N;;;;;
+11B7;HANGUL JONGSEONG MIEUM;Lo;0;L;;;;;N;;;;;
+11B8;HANGUL JONGSEONG PIEUP;Lo;0;L;;;;;N;;;;;
+11B9;HANGUL JONGSEONG PIEUP-SIOS;Lo;0;L;;;;;N;;;;;
+11BA;HANGUL JONGSEONG SIOS;Lo;0;L;;;;;N;;;;;
+11BB;HANGUL JONGSEONG SSANGSIOS;Lo;0;L;;;;;N;;;;;
+11BC;HANGUL JONGSEONG IEUNG;Lo;0;L;;;;;N;;;;;
+11BD;HANGUL JONGSEONG CIEUC;Lo;0;L;;;;;N;;;;;
+11BE;HANGUL JONGSEONG CHIEUCH;Lo;0;L;;;;;N;;;;;
+11BF;HANGUL JONGSEONG KHIEUKH;Lo;0;L;;;;;N;;;;;
+11C0;HANGUL JONGSEONG THIEUTH;Lo;0;L;;;;;N;;;;;
+11C1;HANGUL JONGSEONG PHIEUPH;Lo;0;L;;;;;N;;;;;
+11C2;HANGUL JONGSEONG HIEUH;Lo;0;L;;;;;N;;;;;
+11C3;HANGUL JONGSEONG KIYEOK-RIEUL;Lo;0;L;;;;;N;;;;;
+11C4;HANGUL JONGSEONG KIYEOK-SIOS-KIYEOK;Lo;0;L;;;;;N;;;;;
+11C5;HANGUL JONGSEONG NIEUN-KIYEOK;Lo;0;L;;;;;N;;;;;
+11C6;HANGUL JONGSEONG NIEUN-TIKEUT;Lo;0;L;;;;;N;;;;;
+11C7;HANGUL JONGSEONG NIEUN-SIOS;Lo;0;L;;;;;N;;;;;
+11C8;HANGUL JONGSEONG NIEUN-PANSIOS;Lo;0;L;;;;;N;;;;;
+11C9;HANGUL JONGSEONG NIEUN-THIEUTH;Lo;0;L;;;;;N;;;;;
+11CA;HANGUL JONGSEONG TIKEUT-KIYEOK;Lo;0;L;;;;;N;;;;;
+11CB;HANGUL JONGSEONG TIKEUT-RIEUL;Lo;0;L;;;;;N;;;;;
+11CC;HANGUL JONGSEONG RIEUL-KIYEOK-SIOS;Lo;0;L;;;;;N;;;;;
+11CD;HANGUL JONGSEONG RIEUL-NIEUN;Lo;0;L;;;;;N;;;;;
+11CE;HANGUL JONGSEONG RIEUL-TIKEUT;Lo;0;L;;;;;N;;;;;
+11CF;HANGUL JONGSEONG RIEUL-TIKEUT-HIEUH;Lo;0;L;;;;;N;;;;;
+11D0;HANGUL JONGSEONG SSANGRIEUL;Lo;0;L;;;;;N;;;;;
+11D1;HANGUL JONGSEONG RIEUL-MIEUM-KIYEOK;Lo;0;L;;;;;N;;;;;
+11D2;HANGUL JONGSEONG RIEUL-MIEUM-SIOS;Lo;0;L;;;;;N;;;;;
+11D3;HANGUL JONGSEONG RIEUL-PIEUP-SIOS;Lo;0;L;;;;;N;;;;;
+11D4;HANGUL JONGSEONG RIEUL-PIEUP-HIEUH;Lo;0;L;;;;;N;;;;;
+11D5;HANGUL JONGSEONG RIEUL-KAPYEOUNPIEUP;Lo;0;L;;;;;N;;;;;
+11D6;HANGUL JONGSEONG RIEUL-SSANGSIOS;Lo;0;L;;;;;N;;;;;
+11D7;HANGUL JONGSEONG RIEUL-PANSIOS;Lo;0;L;;;;;N;;;;;
+11D8;HANGUL JONGSEONG RIEUL-KHIEUKH;Lo;0;L;;;;;N;;;;;
+11D9;HANGUL JONGSEONG RIEUL-YEORINHIEUH;Lo;0;L;;;;;N;;;;;
+11DA;HANGUL JONGSEONG MIEUM-KIYEOK;Lo;0;L;;;;;N;;;;;
+11DB;HANGUL JONGSEONG MIEUM-RIEUL;Lo;0;L;;;;;N;;;;;
+11DC;HANGUL JONGSEONG MIEUM-PIEUP;Lo;0;L;;;;;N;;;;;
+11DD;HANGUL JONGSEONG MIEUM-SIOS;Lo;0;L;;;;;N;;;;;
+11DE;HANGUL JONGSEONG MIEUM-SSANGSIOS;Lo;0;L;;;;;N;;;;;
+11DF;HANGUL JONGSEONG MIEUM-PANSIOS;Lo;0;L;;;;;N;;;;;
+11E0;HANGUL JONGSEONG MIEUM-CHIEUCH;Lo;0;L;;;;;N;;;;;
+11E1;HANGUL JONGSEONG MIEUM-HIEUH;Lo;0;L;;;;;N;;;;;
+11E2;HANGUL JONGSEONG KAPYEOUNMIEUM;Lo;0;L;;;;;N;;;;;
+11E3;HANGUL JONGSEONG PIEUP-RIEUL;Lo;0;L;;;;;N;;;;;
+11E4;HANGUL JONGSEONG PIEUP-PHIEUPH;Lo;0;L;;;;;N;;;;;
+11E5;HANGUL JONGSEONG PIEUP-HIEUH;Lo;0;L;;;;;N;;;;;
+11E6;HANGUL JONGSEONG KAPYEOUNPIEUP;Lo;0;L;;;;;N;;;;;
+11E7;HANGUL JONGSEONG SIOS-KIYEOK;Lo;0;L;;;;;N;;;;;
+11E8;HANGUL JONGSEONG SIOS-TIKEUT;Lo;0;L;;;;;N;;;;;
+11E9;HANGUL JONGSEONG SIOS-RIEUL;Lo;0;L;;;;;N;;;;;
+11EA;HANGUL JONGSEONG SIOS-PIEUP;Lo;0;L;;;;;N;;;;;
+11EB;HANGUL JONGSEONG PANSIOS;Lo;0;L;;;;;N;;;;;
+11EC;HANGUL JONGSEONG IEUNG-KIYEOK;Lo;0;L;;;;;N;;;;;
+11ED;HANGUL JONGSEONG IEUNG-SSANGKIYEOK;Lo;0;L;;;;;N;;;;;
+11EE;HANGUL JONGSEONG SSANGIEUNG;Lo;0;L;;;;;N;;;;;
+11EF;HANGUL JONGSEONG IEUNG-KHIEUKH;Lo;0;L;;;;;N;;;;;
+11F0;HANGUL JONGSEONG YESIEUNG;Lo;0;L;;;;;N;;;;;
+11F1;HANGUL JONGSEONG YESIEUNG-SIOS;Lo;0;L;;;;;N;;;;;
+11F2;HANGUL JONGSEONG YESIEUNG-PANSIOS;Lo;0;L;;;;;N;;;;;
+11F3;HANGUL JONGSEONG PHIEUPH-PIEUP;Lo;0;L;;;;;N;;;;;
+11F4;HANGUL JONGSEONG KAPYEOUNPHIEUPH;Lo;0;L;;;;;N;;;;;
+11F5;HANGUL JONGSEONG HIEUH-NIEUN;Lo;0;L;;;;;N;;;;;
+11F6;HANGUL JONGSEONG HIEUH-RIEUL;Lo;0;L;;;;;N;;;;;
+11F7;HANGUL JONGSEONG HIEUH-MIEUM;Lo;0;L;;;;;N;;;;;
+11F8;HANGUL JONGSEONG HIEUH-PIEUP;Lo;0;L;;;;;N;;;;;
+11F9;HANGUL JONGSEONG YEORINHIEUH;Lo;0;L;;;;;N;;;;;
+11FA;HANGUL JONGSEONG KIYEOK-NIEUN;Lo;0;L;;;;;N;;;;;
+11FB;HANGUL JONGSEONG KIYEOK-PIEUP;Lo;0;L;;;;;N;;;;;
+11FC;HANGUL JONGSEONG KIYEOK-CHIEUCH;Lo;0;L;;;;;N;;;;;
+11FD;HANGUL JONGSEONG KIYEOK-KHIEUKH;Lo;0;L;;;;;N;;;;;
+11FE;HANGUL JONGSEONG KIYEOK-HIEUH;Lo;0;L;;;;;N;;;;;
+11FF;HANGUL JONGSEONG SSANGNIEUN;Lo;0;L;;;;;N;;;;;
+1200;ETHIOPIC SYLLABLE HA;Lo;0;L;;;;;N;;;;;
+1201;ETHIOPIC SYLLABLE HU;Lo;0;L;;;;;N;;;;;
+1202;ETHIOPIC SYLLABLE HI;Lo;0;L;;;;;N;;;;;
+1203;ETHIOPIC SYLLABLE HAA;Lo;0;L;;;;;N;;;;;
+1204;ETHIOPIC SYLLABLE HEE;Lo;0;L;;;;;N;;;;;
+1205;ETHIOPIC SYLLABLE HE;Lo;0;L;;;;;N;;;;;
+1206;ETHIOPIC SYLLABLE HO;Lo;0;L;;;;;N;;;;;
+1207;ETHIOPIC SYLLABLE HOA;Lo;0;L;;;;;N;;;;;
+1208;ETHIOPIC SYLLABLE LA;Lo;0;L;;;;;N;;;;;
+1209;ETHIOPIC SYLLABLE LU;Lo;0;L;;;;;N;;;;;
+120A;ETHIOPIC SYLLABLE LI;Lo;0;L;;;;;N;;;;;
+120B;ETHIOPIC SYLLABLE LAA;Lo;0;L;;;;;N;;;;;
+120C;ETHIOPIC SYLLABLE LEE;Lo;0;L;;;;;N;;;;;
+120D;ETHIOPIC SYLLABLE LE;Lo;0;L;;;;;N;;;;;
+120E;ETHIOPIC SYLLABLE LO;Lo;0;L;;;;;N;;;;;
+120F;ETHIOPIC SYLLABLE LWA;Lo;0;L;;;;;N;;;;;
+1210;ETHIOPIC SYLLABLE HHA;Lo;0;L;;;;;N;;;;;
+1211;ETHIOPIC SYLLABLE HHU;Lo;0;L;;;;;N;;;;;
+1212;ETHIOPIC SYLLABLE HHI;Lo;0;L;;;;;N;;;;;
+1213;ETHIOPIC SYLLABLE HHAA;Lo;0;L;;;;;N;;;;;
+1214;ETHIOPIC SYLLABLE HHEE;Lo;0;L;;;;;N;;;;;
+1215;ETHIOPIC SYLLABLE HHE;Lo;0;L;;;;;N;;;;;
+1216;ETHIOPIC SYLLABLE HHO;Lo;0;L;;;;;N;;;;;
+1217;ETHIOPIC SYLLABLE HHWA;Lo;0;L;;;;;N;;;;;
+1218;ETHIOPIC SYLLABLE MA;Lo;0;L;;;;;N;;;;;
+1219;ETHIOPIC SYLLABLE MU;Lo;0;L;;;;;N;;;;;
+121A;ETHIOPIC SYLLABLE MI;Lo;0;L;;;;;N;;;;;
+121B;ETHIOPIC SYLLABLE MAA;Lo;0;L;;;;;N;;;;;
+121C;ETHIOPIC SYLLABLE MEE;Lo;0;L;;;;;N;;;;;
+121D;ETHIOPIC SYLLABLE ME;Lo;0;L;;;;;N;;;;;
+121E;ETHIOPIC SYLLABLE MO;Lo;0;L;;;;;N;;;;;
+121F;ETHIOPIC SYLLABLE MWA;Lo;0;L;;;;;N;;;;;
+1220;ETHIOPIC SYLLABLE SZA;Lo;0;L;;;;;N;;;;;
+1221;ETHIOPIC SYLLABLE SZU;Lo;0;L;;;;;N;;;;;
+1222;ETHIOPIC SYLLABLE SZI;Lo;0;L;;;;;N;;;;;
+1223;ETHIOPIC SYLLABLE SZAA;Lo;0;L;;;;;N;;;;;
+1224;ETHIOPIC SYLLABLE SZEE;Lo;0;L;;;;;N;;;;;
+1225;ETHIOPIC SYLLABLE SZE;Lo;0;L;;;;;N;;;;;
+1226;ETHIOPIC SYLLABLE SZO;Lo;0;L;;;;;N;;;;;
+1227;ETHIOPIC SYLLABLE SZWA;Lo;0;L;;;;;N;;;;;
+1228;ETHIOPIC SYLLABLE RA;Lo;0;L;;;;;N;;;;;
+1229;ETHIOPIC SYLLABLE RU;Lo;0;L;;;;;N;;;;;
+122A;ETHIOPIC SYLLABLE RI;Lo;0;L;;;;;N;;;;;
+122B;ETHIOPIC SYLLABLE RAA;Lo;0;L;;;;;N;;;;;
+122C;ETHIOPIC SYLLABLE REE;Lo;0;L;;;;;N;;;;;
+122D;ETHIOPIC SYLLABLE RE;Lo;0;L;;;;;N;;;;;
+122E;ETHIOPIC SYLLABLE RO;Lo;0;L;;;;;N;;;;;
+122F;ETHIOPIC SYLLABLE RWA;Lo;0;L;;;;;N;;;;;
+1230;ETHIOPIC SYLLABLE SA;Lo;0;L;;;;;N;;;;;
+1231;ETHIOPIC SYLLABLE SU;Lo;0;L;;;;;N;;;;;
+1232;ETHIOPIC SYLLABLE SI;Lo;0;L;;;;;N;;;;;
+1233;ETHIOPIC SYLLABLE SAA;Lo;0;L;;;;;N;;;;;
+1234;ETHIOPIC SYLLABLE SEE;Lo;0;L;;;;;N;;;;;
+1235;ETHIOPIC SYLLABLE SE;Lo;0;L;;;;;N;;;;;
+1236;ETHIOPIC SYLLABLE SO;Lo;0;L;;;;;N;;;;;
+1237;ETHIOPIC SYLLABLE SWA;Lo;0;L;;;;;N;;;;;
+1238;ETHIOPIC SYLLABLE SHA;Lo;0;L;;;;;N;;;;;
+1239;ETHIOPIC SYLLABLE SHU;Lo;0;L;;;;;N;;;;;
+123A;ETHIOPIC SYLLABLE SHI;Lo;0;L;;;;;N;;;;;
+123B;ETHIOPIC SYLLABLE SHAA;Lo;0;L;;;;;N;;;;;
+123C;ETHIOPIC SYLLABLE SHEE;Lo;0;L;;;;;N;;;;;
+123D;ETHIOPIC SYLLABLE SHE;Lo;0;L;;;;;N;;;;;
+123E;ETHIOPIC SYLLABLE SHO;Lo;0;L;;;;;N;;;;;
+123F;ETHIOPIC SYLLABLE SHWA;Lo;0;L;;;;;N;;;;;
+1240;ETHIOPIC SYLLABLE QA;Lo;0;L;;;;;N;;;;;
+1241;ETHIOPIC SYLLABLE QU;Lo;0;L;;;;;N;;;;;
+1242;ETHIOPIC SYLLABLE QI;Lo;0;L;;;;;N;;;;;
+1243;ETHIOPIC SYLLABLE QAA;Lo;0;L;;;;;N;;;;;
+1244;ETHIOPIC SYLLABLE QEE;Lo;0;L;;;;;N;;;;;
+1245;ETHIOPIC SYLLABLE QE;Lo;0;L;;;;;N;;;;;
+1246;ETHIOPIC SYLLABLE QO;Lo;0;L;;;;;N;;;;;
+1247;ETHIOPIC SYLLABLE QOA;Lo;0;L;;;;;N;;;;;
+1248;ETHIOPIC SYLLABLE QWA;Lo;0;L;;;;;N;;;;;
+124A;ETHIOPIC SYLLABLE QWI;Lo;0;L;;;;;N;;;;;
+124B;ETHIOPIC SYLLABLE QWAA;Lo;0;L;;;;;N;;;;;
+124C;ETHIOPIC SYLLABLE QWEE;Lo;0;L;;;;;N;;;;;
+124D;ETHIOPIC SYLLABLE QWE;Lo;0;L;;;;;N;;;;;
+1250;ETHIOPIC SYLLABLE QHA;Lo;0;L;;;;;N;;;;;
+1251;ETHIOPIC SYLLABLE QHU;Lo;0;L;;;;;N;;;;;
+1252;ETHIOPIC SYLLABLE QHI;Lo;0;L;;;;;N;;;;;
+1253;ETHIOPIC SYLLABLE QHAA;Lo;0;L;;;;;N;;;;;
+1254;ETHIOPIC SYLLABLE QHEE;Lo;0;L;;;;;N;;;;;
+1255;ETHIOPIC SYLLABLE QHE;Lo;0;L;;;;;N;;;;;
+1256;ETHIOPIC SYLLABLE QHO;Lo;0;L;;;;;N;;;;;
+1258;ETHIOPIC SYLLABLE QHWA;Lo;0;L;;;;;N;;;;;
+125A;ETHIOPIC SYLLABLE QHWI;Lo;0;L;;;;;N;;;;;
+125B;ETHIOPIC SYLLABLE QHWAA;Lo;0;L;;;;;N;;;;;
+125C;ETHIOPIC SYLLABLE QHWEE;Lo;0;L;;;;;N;;;;;
+125D;ETHIOPIC SYLLABLE QHWE;Lo;0;L;;;;;N;;;;;
+1260;ETHIOPIC SYLLABLE BA;Lo;0;L;;;;;N;;;;;
+1261;ETHIOPIC SYLLABLE BU;Lo;0;L;;;;;N;;;;;
+1262;ETHIOPIC SYLLABLE BI;Lo;0;L;;;;;N;;;;;
+1263;ETHIOPIC SYLLABLE BAA;Lo;0;L;;;;;N;;;;;
+1264;ETHIOPIC SYLLABLE BEE;Lo;0;L;;;;;N;;;;;
+1265;ETHIOPIC SYLLABLE BE;Lo;0;L;;;;;N;;;;;
+1266;ETHIOPIC SYLLABLE BO;Lo;0;L;;;;;N;;;;;
+1267;ETHIOPIC SYLLABLE BWA;Lo;0;L;;;;;N;;;;;
+1268;ETHIOPIC SYLLABLE VA;Lo;0;L;;;;;N;;;;;
+1269;ETHIOPIC SYLLABLE VU;Lo;0;L;;;;;N;;;;;
+126A;ETHIOPIC SYLLABLE VI;Lo;0;L;;;;;N;;;;;
+126B;ETHIOPIC SYLLABLE VAA;Lo;0;L;;;;;N;;;;;
+126C;ETHIOPIC SYLLABLE VEE;Lo;0;L;;;;;N;;;;;
+126D;ETHIOPIC SYLLABLE VE;Lo;0;L;;;;;N;;;;;
+126E;ETHIOPIC SYLLABLE VO;Lo;0;L;;;;;N;;;;;
+126F;ETHIOPIC SYLLABLE VWA;Lo;0;L;;;;;N;;;;;
+1270;ETHIOPIC SYLLABLE TA;Lo;0;L;;;;;N;;;;;
+1271;ETHIOPIC SYLLABLE TU;Lo;0;L;;;;;N;;;;;
+1272;ETHIOPIC SYLLABLE TI;Lo;0;L;;;;;N;;;;;
+1273;ETHIOPIC SYLLABLE TAA;Lo;0;L;;;;;N;;;;;
+1274;ETHIOPIC SYLLABLE TEE;Lo;0;L;;;;;N;;;;;
+1275;ETHIOPIC SYLLABLE TE;Lo;0;L;;;;;N;;;;;
+1276;ETHIOPIC SYLLABLE TO;Lo;0;L;;;;;N;;;;;
+1277;ETHIOPIC SYLLABLE TWA;Lo;0;L;;;;;N;;;;;
+1278;ETHIOPIC SYLLABLE CA;Lo;0;L;;;;;N;;;;;
+1279;ETHIOPIC SYLLABLE CU;Lo;0;L;;;;;N;;;;;
+127A;ETHIOPIC SYLLABLE CI;Lo;0;L;;;;;N;;;;;
+127B;ETHIOPIC SYLLABLE CAA;Lo;0;L;;;;;N;;;;;
+127C;ETHIOPIC SYLLABLE CEE;Lo;0;L;;;;;N;;;;;
+127D;ETHIOPIC SYLLABLE CE;Lo;0;L;;;;;N;;;;;
+127E;ETHIOPIC SYLLABLE CO;Lo;0;L;;;;;N;;;;;
+127F;ETHIOPIC SYLLABLE CWA;Lo;0;L;;;;;N;;;;;
+1280;ETHIOPIC SYLLABLE XA;Lo;0;L;;;;;N;;;;;
+1281;ETHIOPIC SYLLABLE XU;Lo;0;L;;;;;N;;;;;
+1282;ETHIOPIC SYLLABLE XI;Lo;0;L;;;;;N;;;;;
+1283;ETHIOPIC SYLLABLE XAA;Lo;0;L;;;;;N;;;;;
+1284;ETHIOPIC SYLLABLE XEE;Lo;0;L;;;;;N;;;;;
+1285;ETHIOPIC SYLLABLE XE;Lo;0;L;;;;;N;;;;;
+1286;ETHIOPIC SYLLABLE XO;Lo;0;L;;;;;N;;;;;
+1287;ETHIOPIC SYLLABLE XOA;Lo;0;L;;;;;N;;;;;
+1288;ETHIOPIC SYLLABLE XWA;Lo;0;L;;;;;N;;;;;
+128A;ETHIOPIC SYLLABLE XWI;Lo;0;L;;;;;N;;;;;
+128B;ETHIOPIC SYLLABLE XWAA;Lo;0;L;;;;;N;;;;;
+128C;ETHIOPIC SYLLABLE XWEE;Lo;0;L;;;;;N;;;;;
+128D;ETHIOPIC SYLLABLE XWE;Lo;0;L;;;;;N;;;;;
+1290;ETHIOPIC SYLLABLE NA;Lo;0;L;;;;;N;;;;;
+1291;ETHIOPIC SYLLABLE NU;Lo;0;L;;;;;N;;;;;
+1292;ETHIOPIC SYLLABLE NI;Lo;0;L;;;;;N;;;;;
+1293;ETHIOPIC SYLLABLE NAA;Lo;0;L;;;;;N;;;;;
+1294;ETHIOPIC SYLLABLE NEE;Lo;0;L;;;;;N;;;;;
+1295;ETHIOPIC SYLLABLE NE;Lo;0;L;;;;;N;;;;;
+1296;ETHIOPIC SYLLABLE NO;Lo;0;L;;;;;N;;;;;
+1297;ETHIOPIC SYLLABLE NWA;Lo;0;L;;;;;N;;;;;
+1298;ETHIOPIC SYLLABLE NYA;Lo;0;L;;;;;N;;;;;
+1299;ETHIOPIC SYLLABLE NYU;Lo;0;L;;;;;N;;;;;
+129A;ETHIOPIC SYLLABLE NYI;Lo;0;L;;;;;N;;;;;
+129B;ETHIOPIC SYLLABLE NYAA;Lo;0;L;;;;;N;;;;;
+129C;ETHIOPIC SYLLABLE NYEE;Lo;0;L;;;;;N;;;;;
+129D;ETHIOPIC SYLLABLE NYE;Lo;0;L;;;;;N;;;;;
+129E;ETHIOPIC SYLLABLE NYO;Lo;0;L;;;;;N;;;;;
+129F;ETHIOPIC SYLLABLE NYWA;Lo;0;L;;;;;N;;;;;
+12A0;ETHIOPIC SYLLABLE GLOTTAL A;Lo;0;L;;;;;N;;;;;
+12A1;ETHIOPIC SYLLABLE GLOTTAL U;Lo;0;L;;;;;N;;;;;
+12A2;ETHIOPIC SYLLABLE GLOTTAL I;Lo;0;L;;;;;N;;;;;
+12A3;ETHIOPIC SYLLABLE GLOTTAL AA;Lo;0;L;;;;;N;;;;;
+12A4;ETHIOPIC SYLLABLE GLOTTAL EE;Lo;0;L;;;;;N;;;;;
+12A5;ETHIOPIC SYLLABLE GLOTTAL E;Lo;0;L;;;;;N;;;;;
+12A6;ETHIOPIC SYLLABLE GLOTTAL O;Lo;0;L;;;;;N;;;;;
+12A7;ETHIOPIC SYLLABLE GLOTTAL WA;Lo;0;L;;;;;N;;;;;
+12A8;ETHIOPIC SYLLABLE KA;Lo;0;L;;;;;N;;;;;
+12A9;ETHIOPIC SYLLABLE KU;Lo;0;L;;;;;N;;;;;
+12AA;ETHIOPIC SYLLABLE KI;Lo;0;L;;;;;N;;;;;
+12AB;ETHIOPIC SYLLABLE KAA;Lo;0;L;;;;;N;;;;;
+12AC;ETHIOPIC SYLLABLE KEE;Lo;0;L;;;;;N;;;;;
+12AD;ETHIOPIC SYLLABLE KE;Lo;0;L;;;;;N;;;;;
+12AE;ETHIOPIC SYLLABLE KO;Lo;0;L;;;;;N;;;;;
+12AF;ETHIOPIC SYLLABLE KOA;Lo;0;L;;;;;N;;;;;
+12B0;ETHIOPIC SYLLABLE KWA;Lo;0;L;;;;;N;;;;;
+12B2;ETHIOPIC SYLLABLE KWI;Lo;0;L;;;;;N;;;;;
+12B3;ETHIOPIC SYLLABLE KWAA;Lo;0;L;;;;;N;;;;;
+12B4;ETHIOPIC SYLLABLE KWEE;Lo;0;L;;;;;N;;;;;
+12B5;ETHIOPIC SYLLABLE KWE;Lo;0;L;;;;;N;;;;;
+12B8;ETHIOPIC SYLLABLE KXA;Lo;0;L;;;;;N;;;;;
+12B9;ETHIOPIC SYLLABLE KXU;Lo;0;L;;;;;N;;;;;
+12BA;ETHIOPIC SYLLABLE KXI;Lo;0;L;;;;;N;;;;;
+12BB;ETHIOPIC SYLLABLE KXAA;Lo;0;L;;;;;N;;;;;
+12BC;ETHIOPIC SYLLABLE KXEE;Lo;0;L;;;;;N;;;;;
+12BD;ETHIOPIC SYLLABLE KXE;Lo;0;L;;;;;N;;;;;
+12BE;ETHIOPIC SYLLABLE KXO;Lo;0;L;;;;;N;;;;;
+12C0;ETHIOPIC SYLLABLE KXWA;Lo;0;L;;;;;N;;;;;
+12C2;ETHIOPIC SYLLABLE KXWI;Lo;0;L;;;;;N;;;;;
+12C3;ETHIOPIC SYLLABLE KXWAA;Lo;0;L;;;;;N;;;;;
+12C4;ETHIOPIC SYLLABLE KXWEE;Lo;0;L;;;;;N;;;;;
+12C5;ETHIOPIC SYLLABLE KXWE;Lo;0;L;;;;;N;;;;;
+12C8;ETHIOPIC SYLLABLE WA;Lo;0;L;;;;;N;;;;;
+12C9;ETHIOPIC SYLLABLE WU;Lo;0;L;;;;;N;;;;;
+12CA;ETHIOPIC SYLLABLE WI;Lo;0;L;;;;;N;;;;;
+12CB;ETHIOPIC SYLLABLE WAA;Lo;0;L;;;;;N;;;;;
+12CC;ETHIOPIC SYLLABLE WEE;Lo;0;L;;;;;N;;;;;
+12CD;ETHIOPIC SYLLABLE WE;Lo;0;L;;;;;N;;;;;
+12CE;ETHIOPIC SYLLABLE WO;Lo;0;L;;;;;N;;;;;
+12CF;ETHIOPIC SYLLABLE WOA;Lo;0;L;;;;;N;;;;;
+12D0;ETHIOPIC SYLLABLE PHARYNGEAL A;Lo;0;L;;;;;N;;;;;
+12D1;ETHIOPIC SYLLABLE PHARYNGEAL U;Lo;0;L;;;;;N;;;;;
+12D2;ETHIOPIC SYLLABLE PHARYNGEAL I;Lo;0;L;;;;;N;;;;;
+12D3;ETHIOPIC SYLLABLE PHARYNGEAL AA;Lo;0;L;;;;;N;;;;;
+12D4;ETHIOPIC SYLLABLE PHARYNGEAL EE;Lo;0;L;;;;;N;;;;;
+12D5;ETHIOPIC SYLLABLE PHARYNGEAL E;Lo;0;L;;;;;N;;;;;
+12D6;ETHIOPIC SYLLABLE PHARYNGEAL O;Lo;0;L;;;;;N;;;;;
+12D8;ETHIOPIC SYLLABLE ZA;Lo;0;L;;;;;N;;;;;
+12D9;ETHIOPIC SYLLABLE ZU;Lo;0;L;;;;;N;;;;;
+12DA;ETHIOPIC SYLLABLE ZI;Lo;0;L;;;;;N;;;;;
+12DB;ETHIOPIC SYLLABLE ZAA;Lo;0;L;;;;;N;;;;;
+12DC;ETHIOPIC SYLLABLE ZEE;Lo;0;L;;;;;N;;;;;
+12DD;ETHIOPIC SYLLABLE ZE;Lo;0;L;;;;;N;;;;;
+12DE;ETHIOPIC SYLLABLE ZO;Lo;0;L;;;;;N;;;;;
+12DF;ETHIOPIC SYLLABLE ZWA;Lo;0;L;;;;;N;;;;;
+12E0;ETHIOPIC SYLLABLE ZHA;Lo;0;L;;;;;N;;;;;
+12E1;ETHIOPIC SYLLABLE ZHU;Lo;0;L;;;;;N;;;;;
+12E2;ETHIOPIC SYLLABLE ZHI;Lo;0;L;;;;;N;;;;;
+12E3;ETHIOPIC SYLLABLE ZHAA;Lo;0;L;;;;;N;;;;;
+12E4;ETHIOPIC SYLLABLE ZHEE;Lo;0;L;;;;;N;;;;;
+12E5;ETHIOPIC SYLLABLE ZHE;Lo;0;L;;;;;N;;;;;
+12E6;ETHIOPIC SYLLABLE ZHO;Lo;0;L;;;;;N;;;;;
+12E7;ETHIOPIC SYLLABLE ZHWA;Lo;0;L;;;;;N;;;;;
+12E8;ETHIOPIC SYLLABLE YA;Lo;0;L;;;;;N;;;;;
+12E9;ETHIOPIC SYLLABLE YU;Lo;0;L;;;;;N;;;;;
+12EA;ETHIOPIC SYLLABLE YI;Lo;0;L;;;;;N;;;;;
+12EB;ETHIOPIC SYLLABLE YAA;Lo;0;L;;;;;N;;;;;
+12EC;ETHIOPIC SYLLABLE YEE;Lo;0;L;;;;;N;;;;;
+12ED;ETHIOPIC SYLLABLE YE;Lo;0;L;;;;;N;;;;;
+12EE;ETHIOPIC SYLLABLE YO;Lo;0;L;;;;;N;;;;;
+12EF;ETHIOPIC SYLLABLE YOA;Lo;0;L;;;;;N;;;;;
+12F0;ETHIOPIC SYLLABLE DA;Lo;0;L;;;;;N;;;;;
+12F1;ETHIOPIC SYLLABLE DU;Lo;0;L;;;;;N;;;;;
+12F2;ETHIOPIC SYLLABLE DI;Lo;0;L;;;;;N;;;;;
+12F3;ETHIOPIC SYLLABLE DAA;Lo;0;L;;;;;N;;;;;
+12F4;ETHIOPIC SYLLABLE DEE;Lo;0;L;;;;;N;;;;;
+12F5;ETHIOPIC SYLLABLE DE;Lo;0;L;;;;;N;;;;;
+12F6;ETHIOPIC SYLLABLE DO;Lo;0;L;;;;;N;;;;;
+12F7;ETHIOPIC SYLLABLE DWA;Lo;0;L;;;;;N;;;;;
+12F8;ETHIOPIC SYLLABLE DDA;Lo;0;L;;;;;N;;;;;
+12F9;ETHIOPIC SYLLABLE DDU;Lo;0;L;;;;;N;;;;;
+12FA;ETHIOPIC SYLLABLE DDI;Lo;0;L;;;;;N;;;;;
+12FB;ETHIOPIC SYLLABLE DDAA;Lo;0;L;;;;;N;;;;;
+12FC;ETHIOPIC SYLLABLE DDEE;Lo;0;L;;;;;N;;;;;
+12FD;ETHIOPIC SYLLABLE DDE;Lo;0;L;;;;;N;;;;;
+12FE;ETHIOPIC SYLLABLE DDO;Lo;0;L;;;;;N;;;;;
+12FF;ETHIOPIC SYLLABLE DDWA;Lo;0;L;;;;;N;;;;;
+1300;ETHIOPIC SYLLABLE JA;Lo;0;L;;;;;N;;;;;
+1301;ETHIOPIC SYLLABLE JU;Lo;0;L;;;;;N;;;;;
+1302;ETHIOPIC SYLLABLE JI;Lo;0;L;;;;;N;;;;;
+1303;ETHIOPIC SYLLABLE JAA;Lo;0;L;;;;;N;;;;;
+1304;ETHIOPIC SYLLABLE JEE;Lo;0;L;;;;;N;;;;;
+1305;ETHIOPIC SYLLABLE JE;Lo;0;L;;;;;N;;;;;
+1306;ETHIOPIC SYLLABLE JO;Lo;0;L;;;;;N;;;;;
+1307;ETHIOPIC SYLLABLE JWA;Lo;0;L;;;;;N;;;;;
+1308;ETHIOPIC SYLLABLE GA;Lo;0;L;;;;;N;;;;;
+1309;ETHIOPIC SYLLABLE GU;Lo;0;L;;;;;N;;;;;
+130A;ETHIOPIC SYLLABLE GI;Lo;0;L;;;;;N;;;;;
+130B;ETHIOPIC SYLLABLE GAA;Lo;0;L;;;;;N;;;;;
+130C;ETHIOPIC SYLLABLE GEE;Lo;0;L;;;;;N;;;;;
+130D;ETHIOPIC SYLLABLE GE;Lo;0;L;;;;;N;;;;;
+130E;ETHIOPIC SYLLABLE GO;Lo;0;L;;;;;N;;;;;
+130F;ETHIOPIC SYLLABLE GOA;Lo;0;L;;;;;N;;;;;
+1310;ETHIOPIC SYLLABLE GWA;Lo;0;L;;;;;N;;;;;
+1312;ETHIOPIC SYLLABLE GWI;Lo;0;L;;;;;N;;;;;
+1313;ETHIOPIC SYLLABLE GWAA;Lo;0;L;;;;;N;;;;;
+1314;ETHIOPIC SYLLABLE GWEE;Lo;0;L;;;;;N;;;;;
+1315;ETHIOPIC SYLLABLE GWE;Lo;0;L;;;;;N;;;;;
+1318;ETHIOPIC SYLLABLE GGA;Lo;0;L;;;;;N;;;;;
+1319;ETHIOPIC SYLLABLE GGU;Lo;0;L;;;;;N;;;;;
+131A;ETHIOPIC SYLLABLE GGI;Lo;0;L;;;;;N;;;;;
+131B;ETHIOPIC SYLLABLE GGAA;Lo;0;L;;;;;N;;;;;
+131C;ETHIOPIC SYLLABLE GGEE;Lo;0;L;;;;;N;;;;;
+131D;ETHIOPIC SYLLABLE GGE;Lo;0;L;;;;;N;;;;;
+131E;ETHIOPIC SYLLABLE GGO;Lo;0;L;;;;;N;;;;;
+131F;ETHIOPIC SYLLABLE GGWAA;Lo;0;L;;;;;N;;;;;
+1320;ETHIOPIC SYLLABLE THA;Lo;0;L;;;;;N;;;;;
+1321;ETHIOPIC SYLLABLE THU;Lo;0;L;;;;;N;;;;;
+1322;ETHIOPIC SYLLABLE THI;Lo;0;L;;;;;N;;;;;
+1323;ETHIOPIC SYLLABLE THAA;Lo;0;L;;;;;N;;;;;
+1324;ETHIOPIC SYLLABLE THEE;Lo;0;L;;;;;N;;;;;
+1325;ETHIOPIC SYLLABLE THE;Lo;0;L;;;;;N;;;;;
+1326;ETHIOPIC SYLLABLE THO;Lo;0;L;;;;;N;;;;;
+1327;ETHIOPIC SYLLABLE THWA;Lo;0;L;;;;;N;;;;;
+1328;ETHIOPIC SYLLABLE CHA;Lo;0;L;;;;;N;;;;;
+1329;ETHIOPIC SYLLABLE CHU;Lo;0;L;;;;;N;;;;;
+132A;ETHIOPIC SYLLABLE CHI;Lo;0;L;;;;;N;;;;;
+132B;ETHIOPIC SYLLABLE CHAA;Lo;0;L;;;;;N;;;;;
+132C;ETHIOPIC SYLLABLE CHEE;Lo;0;L;;;;;N;;;;;
+132D;ETHIOPIC SYLLABLE CHE;Lo;0;L;;;;;N;;;;;
+132E;ETHIOPIC SYLLABLE CHO;Lo;0;L;;;;;N;;;;;
+132F;ETHIOPIC SYLLABLE CHWA;Lo;0;L;;;;;N;;;;;
+1330;ETHIOPIC SYLLABLE PHA;Lo;0;L;;;;;N;;;;;
+1331;ETHIOPIC SYLLABLE PHU;Lo;0;L;;;;;N;;;;;
+1332;ETHIOPIC SYLLABLE PHI;Lo;0;L;;;;;N;;;;;
+1333;ETHIOPIC SYLLABLE PHAA;Lo;0;L;;;;;N;;;;;
+1334;ETHIOPIC SYLLABLE PHEE;Lo;0;L;;;;;N;;;;;
+1335;ETHIOPIC SYLLABLE PHE;Lo;0;L;;;;;N;;;;;
+1336;ETHIOPIC SYLLABLE PHO;Lo;0;L;;;;;N;;;;;
+1337;ETHIOPIC SYLLABLE PHWA;Lo;0;L;;;;;N;;;;;
+1338;ETHIOPIC SYLLABLE TSA;Lo;0;L;;;;;N;;;;;
+1339;ETHIOPIC SYLLABLE TSU;Lo;0;L;;;;;N;;;;;
+133A;ETHIOPIC SYLLABLE TSI;Lo;0;L;;;;;N;;;;;
+133B;ETHIOPIC SYLLABLE TSAA;Lo;0;L;;;;;N;;;;;
+133C;ETHIOPIC SYLLABLE TSEE;Lo;0;L;;;;;N;;;;;
+133D;ETHIOPIC SYLLABLE TSE;Lo;0;L;;;;;N;;;;;
+133E;ETHIOPIC SYLLABLE TSO;Lo;0;L;;;;;N;;;;;
+133F;ETHIOPIC SYLLABLE TSWA;Lo;0;L;;;;;N;;;;;
+1340;ETHIOPIC SYLLABLE TZA;Lo;0;L;;;;;N;;;;;
+1341;ETHIOPIC SYLLABLE TZU;Lo;0;L;;;;;N;;;;;
+1342;ETHIOPIC SYLLABLE TZI;Lo;0;L;;;;;N;;;;;
+1343;ETHIOPIC SYLLABLE TZAA;Lo;0;L;;;;;N;;;;;
+1344;ETHIOPIC SYLLABLE TZEE;Lo;0;L;;;;;N;;;;;
+1345;ETHIOPIC SYLLABLE TZE;Lo;0;L;;;;;N;;;;;
+1346;ETHIOPIC SYLLABLE TZO;Lo;0;L;;;;;N;;;;;
+1347;ETHIOPIC SYLLABLE TZOA;Lo;0;L;;;;;N;;;;;
+1348;ETHIOPIC SYLLABLE FA;Lo;0;L;;;;;N;;;;;
+1349;ETHIOPIC SYLLABLE FU;Lo;0;L;;;;;N;;;;;
+134A;ETHIOPIC SYLLABLE FI;Lo;0;L;;;;;N;;;;;
+134B;ETHIOPIC SYLLABLE FAA;Lo;0;L;;;;;N;;;;;
+134C;ETHIOPIC SYLLABLE FEE;Lo;0;L;;;;;N;;;;;
+134D;ETHIOPIC SYLLABLE FE;Lo;0;L;;;;;N;;;;;
+134E;ETHIOPIC SYLLABLE FO;Lo;0;L;;;;;N;;;;;
+134F;ETHIOPIC SYLLABLE FWA;Lo;0;L;;;;;N;;;;;
+1350;ETHIOPIC SYLLABLE PA;Lo;0;L;;;;;N;;;;;
+1351;ETHIOPIC SYLLABLE PU;Lo;0;L;;;;;N;;;;;
+1352;ETHIOPIC SYLLABLE PI;Lo;0;L;;;;;N;;;;;
+1353;ETHIOPIC SYLLABLE PAA;Lo;0;L;;;;;N;;;;;
+1354;ETHIOPIC SYLLABLE PEE;Lo;0;L;;;;;N;;;;;
+1355;ETHIOPIC SYLLABLE PE;Lo;0;L;;;;;N;;;;;
+1356;ETHIOPIC SYLLABLE PO;Lo;0;L;;;;;N;;;;;
+1357;ETHIOPIC SYLLABLE PWA;Lo;0;L;;;;;N;;;;;
+1358;ETHIOPIC SYLLABLE RYA;Lo;0;L;;;;;N;;;;;
+1359;ETHIOPIC SYLLABLE MYA;Lo;0;L;;;;;N;;;;;
+135A;ETHIOPIC SYLLABLE FYA;Lo;0;L;;;;;N;;;;;
+135D;ETHIOPIC COMBINING GEMINATION AND VOWEL LENGTH MARK;Mn;230;NSM;;;;;N;;;;;
+135E;ETHIOPIC COMBINING VOWEL LENGTH MARK;Mn;230;NSM;;;;;N;;;;;
+135F;ETHIOPIC COMBINING GEMINATION MARK;Mn;230;NSM;;;;;N;;;;;
+1360;ETHIOPIC SECTION MARK;So;0;L;;;;;N;;;;;
+1361;ETHIOPIC WORDSPACE;Po;0;L;;;;;N;;;;;
+1362;ETHIOPIC FULL STOP;Po;0;L;;;;;N;;;;;
+1363;ETHIOPIC COMMA;Po;0;L;;;;;N;;;;;
+1364;ETHIOPIC SEMICOLON;Po;0;L;;;;;N;;;;;
+1365;ETHIOPIC COLON;Po;0;L;;;;;N;;;;;
+1366;ETHIOPIC PREFACE COLON;Po;0;L;;;;;N;;;;;
+1367;ETHIOPIC QUESTION MARK;Po;0;L;;;;;N;;;;;
+1368;ETHIOPIC PARAGRAPH SEPARATOR;Po;0;L;;;;;N;;;;;
+1369;ETHIOPIC DIGIT ONE;No;0;L;;;1;1;N;;;;;
+136A;ETHIOPIC DIGIT TWO;No;0;L;;;2;2;N;;;;;
+136B;ETHIOPIC DIGIT THREE;No;0;L;;;3;3;N;;;;;
+136C;ETHIOPIC DIGIT FOUR;No;0;L;;;4;4;N;;;;;
+136D;ETHIOPIC DIGIT FIVE;No;0;L;;;5;5;N;;;;;
+136E;ETHIOPIC DIGIT SIX;No;0;L;;;6;6;N;;;;;
+136F;ETHIOPIC DIGIT SEVEN;No;0;L;;;7;7;N;;;;;
+1370;ETHIOPIC DIGIT EIGHT;No;0;L;;;8;8;N;;;;;
+1371;ETHIOPIC DIGIT NINE;No;0;L;;;9;9;N;;;;;
+1372;ETHIOPIC NUMBER TEN;No;0;L;;;;10;N;;;;;
+1373;ETHIOPIC NUMBER TWENTY;No;0;L;;;;20;N;;;;;
+1374;ETHIOPIC NUMBER THIRTY;No;0;L;;;;30;N;;;;;
+1375;ETHIOPIC NUMBER FORTY;No;0;L;;;;40;N;;;;;
+1376;ETHIOPIC NUMBER FIFTY;No;0;L;;;;50;N;;;;;
+1377;ETHIOPIC NUMBER SIXTY;No;0;L;;;;60;N;;;;;
+1378;ETHIOPIC NUMBER SEVENTY;No;0;L;;;;70;N;;;;;
+1379;ETHIOPIC NUMBER EIGHTY;No;0;L;;;;80;N;;;;;
+137A;ETHIOPIC NUMBER NINETY;No;0;L;;;;90;N;;;;;
+137B;ETHIOPIC NUMBER HUNDRED;No;0;L;;;;100;N;;;;;
+137C;ETHIOPIC NUMBER TEN THOUSAND;No;0;L;;;;10000;N;;;;;
+1380;ETHIOPIC SYLLABLE SEBATBEIT MWA;Lo;0;L;;;;;N;;;;;
+1381;ETHIOPIC SYLLABLE MWI;Lo;0;L;;;;;N;;;;;
+1382;ETHIOPIC SYLLABLE MWEE;Lo;0;L;;;;;N;;;;;
+1383;ETHIOPIC SYLLABLE MWE;Lo;0;L;;;;;N;;;;;
+1384;ETHIOPIC SYLLABLE SEBATBEIT BWA;Lo;0;L;;;;;N;;;;;
+1385;ETHIOPIC SYLLABLE BWI;Lo;0;L;;;;;N;;;;;
+1386;ETHIOPIC SYLLABLE BWEE;Lo;0;L;;;;;N;;;;;
+1387;ETHIOPIC SYLLABLE BWE;Lo;0;L;;;;;N;;;;;
+1388;ETHIOPIC SYLLABLE SEBATBEIT FWA;Lo;0;L;;;;;N;;;;;
+1389;ETHIOPIC SYLLABLE FWI;Lo;0;L;;;;;N;;;;;
+138A;ETHIOPIC SYLLABLE FWEE;Lo;0;L;;;;;N;;;;;
+138B;ETHIOPIC SYLLABLE FWE;Lo;0;L;;;;;N;;;;;
+138C;ETHIOPIC SYLLABLE SEBATBEIT PWA;Lo;0;L;;;;;N;;;;;
+138D;ETHIOPIC SYLLABLE PWI;Lo;0;L;;;;;N;;;;;
+138E;ETHIOPIC SYLLABLE PWEE;Lo;0;L;;;;;N;;;;;
+138F;ETHIOPIC SYLLABLE PWE;Lo;0;L;;;;;N;;;;;
+1390;ETHIOPIC TONAL MARK YIZET;So;0;ON;;;;;N;;;;;
+1391;ETHIOPIC TONAL MARK DERET;So;0;ON;;;;;N;;;;;
+1392;ETHIOPIC TONAL MARK RIKRIK;So;0;ON;;;;;N;;;;;
+1393;ETHIOPIC TONAL MARK SHORT RIKRIK;So;0;ON;;;;;N;;;;;
+1394;ETHIOPIC TONAL MARK DIFAT;So;0;ON;;;;;N;;;;;
+1395;ETHIOPIC TONAL MARK KENAT;So;0;ON;;;;;N;;;;;
+1396;ETHIOPIC TONAL MARK CHIRET;So;0;ON;;;;;N;;;;;
+1397;ETHIOPIC TONAL MARK HIDET;So;0;ON;;;;;N;;;;;
+1398;ETHIOPIC TONAL MARK DERET-HIDET;So;0;ON;;;;;N;;;;;
+1399;ETHIOPIC TONAL MARK KURT;So;0;ON;;;;;N;;;;;
+13A0;CHEROKEE LETTER A;Lo;0;L;;;;;N;;;;;
+13A1;CHEROKEE LETTER E;Lo;0;L;;;;;N;;;;;
+13A2;CHEROKEE LETTER I;Lo;0;L;;;;;N;;;;;
+13A3;CHEROKEE LETTER O;Lo;0;L;;;;;N;;;;;
+13A4;CHEROKEE LETTER U;Lo;0;L;;;;;N;;;;;
+13A5;CHEROKEE LETTER V;Lo;0;L;;;;;N;;;;;
+13A6;CHEROKEE LETTER GA;Lo;0;L;;;;;N;;;;;
+13A7;CHEROKEE LETTER KA;Lo;0;L;;;;;N;;;;;
+13A8;CHEROKEE LETTER GE;Lo;0;L;;;;;N;;;;;
+13A9;CHEROKEE LETTER GI;Lo;0;L;;;;;N;;;;;
+13AA;CHEROKEE LETTER GO;Lo;0;L;;;;;N;;;;;
+13AB;CHEROKEE LETTER GU;Lo;0;L;;;;;N;;;;;
+13AC;CHEROKEE LETTER GV;Lo;0;L;;;;;N;;;;;
+13AD;CHEROKEE LETTER HA;Lo;0;L;;;;;N;;;;;
+13AE;CHEROKEE LETTER HE;Lo;0;L;;;;;N;;;;;
+13AF;CHEROKEE LETTER HI;Lo;0;L;;;;;N;;;;;
+13B0;CHEROKEE LETTER HO;Lo;0;L;;;;;N;;;;;
+13B1;CHEROKEE LETTER HU;Lo;0;L;;;;;N;;;;;
+13B2;CHEROKEE LETTER HV;Lo;0;L;;;;;N;;;;;
+13B3;CHEROKEE LETTER LA;Lo;0;L;;;;;N;;;;;
+13B4;CHEROKEE LETTER LE;Lo;0;L;;;;;N;;;;;
+13B5;CHEROKEE LETTER LI;Lo;0;L;;;;;N;;;;;
+13B6;CHEROKEE LETTER LO;Lo;0;L;;;;;N;;;;;
+13B7;CHEROKEE LETTER LU;Lo;0;L;;;;;N;;;;;
+13B8;CHEROKEE LETTER LV;Lo;0;L;;;;;N;;;;;
+13B9;CHEROKEE LETTER MA;Lo;0;L;;;;;N;;;;;
+13BA;CHEROKEE LETTER ME;Lo;0;L;;;;;N;;;;;
+13BB;CHEROKEE LETTER MI;Lo;0;L;;;;;N;;;;;
+13BC;CHEROKEE LETTER MO;Lo;0;L;;;;;N;;;;;
+13BD;CHEROKEE LETTER MU;Lo;0;L;;;;;N;;;;;
+13BE;CHEROKEE LETTER NA;Lo;0;L;;;;;N;;;;;
+13BF;CHEROKEE LETTER HNA;Lo;0;L;;;;;N;;;;;
+13C0;CHEROKEE LETTER NAH;Lo;0;L;;;;;N;;;;;
+13C1;CHEROKEE LETTER NE;Lo;0;L;;;;;N;;;;;
+13C2;CHEROKEE LETTER NI;Lo;0;L;;;;;N;;;;;
+13C3;CHEROKEE LETTER NO;Lo;0;L;;;;;N;;;;;
+13C4;CHEROKEE LETTER NU;Lo;0;L;;;;;N;;;;;
+13C5;CHEROKEE LETTER NV;Lo;0;L;;;;;N;;;;;
+13C6;CHEROKEE LETTER QUA;Lo;0;L;;;;;N;;;;;
+13C7;CHEROKEE LETTER QUE;Lo;0;L;;;;;N;;;;;
+13C8;CHEROKEE LETTER QUI;Lo;0;L;;;;;N;;;;;
+13C9;CHEROKEE LETTER QUO;Lo;0;L;;;;;N;;;;;
+13CA;CHEROKEE LETTER QUU;Lo;0;L;;;;;N;;;;;
+13CB;CHEROKEE LETTER QUV;Lo;0;L;;;;;N;;;;;
+13CC;CHEROKEE LETTER SA;Lo;0;L;;;;;N;;;;;
+13CD;CHEROKEE LETTER S;Lo;0;L;;;;;N;;;;;
+13CE;CHEROKEE LETTER SE;Lo;0;L;;;;;N;;;;;
+13CF;CHEROKEE LETTER SI;Lo;0;L;;;;;N;;;;;
+13D0;CHEROKEE LETTER SO;Lo;0;L;;;;;N;;;;;
+13D1;CHEROKEE LETTER SU;Lo;0;L;;;;;N;;;;;
+13D2;CHEROKEE LETTER SV;Lo;0;L;;;;;N;;;;;
+13D3;CHEROKEE LETTER DA;Lo;0;L;;;;;N;;;;;
+13D4;CHEROKEE LETTER TA;Lo;0;L;;;;;N;;;;;
+13D5;CHEROKEE LETTER DE;Lo;0;L;;;;;N;;;;;
+13D6;CHEROKEE LETTER TE;Lo;0;L;;;;;N;;;;;
+13D7;CHEROKEE LETTER DI;Lo;0;L;;;;;N;;;;;
+13D8;CHEROKEE LETTER TI;Lo;0;L;;;;;N;;;;;
+13D9;CHEROKEE LETTER DO;Lo;0;L;;;;;N;;;;;
+13DA;CHEROKEE LETTER DU;Lo;0;L;;;;;N;;;;;
+13DB;CHEROKEE LETTER DV;Lo;0;L;;;;;N;;;;;
+13DC;CHEROKEE LETTER DLA;Lo;0;L;;;;;N;;;;;
+13DD;CHEROKEE LETTER TLA;Lo;0;L;;;;;N;;;;;
+13DE;CHEROKEE LETTER TLE;Lo;0;L;;;;;N;;;;;
+13DF;CHEROKEE LETTER TLI;Lo;0;L;;;;;N;;;;;
+13E0;CHEROKEE LETTER TLO;Lo;0;L;;;;;N;;;;;
+13E1;CHEROKEE LETTER TLU;Lo;0;L;;;;;N;;;;;
+13E2;CHEROKEE LETTER TLV;Lo;0;L;;;;;N;;;;;
+13E3;CHEROKEE LETTER TSA;Lo;0;L;;;;;N;;;;;
+13E4;CHEROKEE LETTER TSE;Lo;0;L;;;;;N;;;;;
+13E5;CHEROKEE LETTER TSI;Lo;0;L;;;;;N;;;;;
+13E6;CHEROKEE LETTER TSO;Lo;0;L;;;;;N;;;;;
+13E7;CHEROKEE LETTER TSU;Lo;0;L;;;;;N;;;;;
+13E8;CHEROKEE LETTER TSV;Lo;0;L;;;;;N;;;;;
+13E9;CHEROKEE LETTER WA;Lo;0;L;;;;;N;;;;;
+13EA;CHEROKEE LETTER WE;Lo;0;L;;;;;N;;;;;
+13EB;CHEROKEE LETTER WI;Lo;0;L;;;;;N;;;;;
+13EC;CHEROKEE LETTER WO;Lo;0;L;;;;;N;;;;;
+13ED;CHEROKEE LETTER WU;Lo;0;L;;;;;N;;;;;
+13EE;CHEROKEE LETTER WV;Lo;0;L;;;;;N;;;;;
+13EF;CHEROKEE LETTER YA;Lo;0;L;;;;;N;;;;;
+13F0;CHEROKEE LETTER YE;Lo;0;L;;;;;N;;;;;
+13F1;CHEROKEE LETTER YI;Lo;0;L;;;;;N;;;;;
+13F2;CHEROKEE LETTER YO;Lo;0;L;;;;;N;;;;;
+13F3;CHEROKEE LETTER YU;Lo;0;L;;;;;N;;;;;
+13F4;CHEROKEE LETTER YV;Lo;0;L;;;;;N;;;;;
+1400;CANADIAN SYLLABICS HYPHEN;Pd;0;ON;;;;;N;;;;;
+1401;CANADIAN SYLLABICS E;Lo;0;L;;;;;N;;;;;
+1402;CANADIAN SYLLABICS AAI;Lo;0;L;;;;;N;;;;;
+1403;CANADIAN SYLLABICS I;Lo;0;L;;;;;N;;;;;
+1404;CANADIAN SYLLABICS II;Lo;0;L;;;;;N;;;;;
+1405;CANADIAN SYLLABICS O;Lo;0;L;;;;;N;;;;;
+1406;CANADIAN SYLLABICS OO;Lo;0;L;;;;;N;;;;;
+1407;CANADIAN SYLLABICS Y-CREE OO;Lo;0;L;;;;;N;;;;;
+1408;CANADIAN SYLLABICS CARRIER EE;Lo;0;L;;;;;N;;;;;
+1409;CANADIAN SYLLABICS CARRIER I;Lo;0;L;;;;;N;;;;;
+140A;CANADIAN SYLLABICS A;Lo;0;L;;;;;N;;;;;
+140B;CANADIAN SYLLABICS AA;Lo;0;L;;;;;N;;;;;
+140C;CANADIAN SYLLABICS WE;Lo;0;L;;;;;N;;;;;
+140D;CANADIAN SYLLABICS WEST-CREE WE;Lo;0;L;;;;;N;;;;;
+140E;CANADIAN SYLLABICS WI;Lo;0;L;;;;;N;;;;;
+140F;CANADIAN SYLLABICS WEST-CREE WI;Lo;0;L;;;;;N;;;;;
+1410;CANADIAN SYLLABICS WII;Lo;0;L;;;;;N;;;;;
+1411;CANADIAN SYLLABICS WEST-CREE WII;Lo;0;L;;;;;N;;;;;
+1412;CANADIAN SYLLABICS WO;Lo;0;L;;;;;N;;;;;
+1413;CANADIAN SYLLABICS WEST-CREE WO;Lo;0;L;;;;;N;;;;;
+1414;CANADIAN SYLLABICS WOO;Lo;0;L;;;;;N;;;;;
+1415;CANADIAN SYLLABICS WEST-CREE WOO;Lo;0;L;;;;;N;;;;;
+1416;CANADIAN SYLLABICS NASKAPI WOO;Lo;0;L;;;;;N;;;;;
+1417;CANADIAN SYLLABICS WA;Lo;0;L;;;;;N;;;;;
+1418;CANADIAN SYLLABICS WEST-CREE WA;Lo;0;L;;;;;N;;;;;
+1419;CANADIAN SYLLABICS WAA;Lo;0;L;;;;;N;;;;;
+141A;CANADIAN SYLLABICS WEST-CREE WAA;Lo;0;L;;;;;N;;;;;
+141B;CANADIAN SYLLABICS NASKAPI WAA;Lo;0;L;;;;;N;;;;;
+141C;CANADIAN SYLLABICS AI;Lo;0;L;;;;;N;;;;;
+141D;CANADIAN SYLLABICS Y-CREE W;Lo;0;L;;;;;N;;;;;
+141E;CANADIAN SYLLABICS GLOTTAL STOP;Lo;0;L;;;;;N;;;;;
+141F;CANADIAN SYLLABICS FINAL ACUTE;Lo;0;L;;;;;N;;;;;
+1420;CANADIAN SYLLABICS FINAL GRAVE;Lo;0;L;;;;;N;;;;;
+1421;CANADIAN SYLLABICS FINAL BOTTOM HALF RING;Lo;0;L;;;;;N;;;;;
+1422;CANADIAN SYLLABICS FINAL TOP HALF RING;Lo;0;L;;;;;N;;;;;
+1423;CANADIAN SYLLABICS FINAL RIGHT HALF RING;Lo;0;L;;;;;N;;;;;
+1424;CANADIAN SYLLABICS FINAL RING;Lo;0;L;;;;;N;;;;;
+1425;CANADIAN SYLLABICS FINAL DOUBLE ACUTE;Lo;0;L;;;;;N;;;;;
+1426;CANADIAN SYLLABICS FINAL DOUBLE SHORT VERTICAL STROKES;Lo;0;L;;;;;N;;;;;
+1427;CANADIAN SYLLABICS FINAL MIDDLE DOT;Lo;0;L;;;;;N;;;;;
+1428;CANADIAN SYLLABICS FINAL SHORT HORIZONTAL STROKE;Lo;0;L;;;;;N;;;;;
+1429;CANADIAN SYLLABICS FINAL PLUS;Lo;0;L;;;;;N;;;;;
+142A;CANADIAN SYLLABICS FINAL DOWN TACK;Lo;0;L;;;;;N;;;;;
+142B;CANADIAN SYLLABICS EN;Lo;0;L;;;;;N;;;;;
+142C;CANADIAN SYLLABICS IN;Lo;0;L;;;;;N;;;;;
+142D;CANADIAN SYLLABICS ON;Lo;0;L;;;;;N;;;;;
+142E;CANADIAN SYLLABICS AN;Lo;0;L;;;;;N;;;;;
+142F;CANADIAN SYLLABICS PE;Lo;0;L;;;;;N;;;;;
+1430;CANADIAN SYLLABICS PAAI;Lo;0;L;;;;;N;;;;;
+1431;CANADIAN SYLLABICS PI;Lo;0;L;;;;;N;;;;;
+1432;CANADIAN SYLLABICS PII;Lo;0;L;;;;;N;;;;;
+1433;CANADIAN SYLLABICS PO;Lo;0;L;;;;;N;;;;;
+1434;CANADIAN SYLLABICS POO;Lo;0;L;;;;;N;;;;;
+1435;CANADIAN SYLLABICS Y-CREE POO;Lo;0;L;;;;;N;;;;;
+1436;CANADIAN SYLLABICS CARRIER HEE;Lo;0;L;;;;;N;;;;;
+1437;CANADIAN SYLLABICS CARRIER HI;Lo;0;L;;;;;N;;;;;
+1438;CANADIAN SYLLABICS PA;Lo;0;L;;;;;N;;;;;
+1439;CANADIAN SYLLABICS PAA;Lo;0;L;;;;;N;;;;;
+143A;CANADIAN SYLLABICS PWE;Lo;0;L;;;;;N;;;;;
+143B;CANADIAN SYLLABICS WEST-CREE PWE;Lo;0;L;;;;;N;;;;;
+143C;CANADIAN SYLLABICS PWI;Lo;0;L;;;;;N;;;;;
+143D;CANADIAN SYLLABICS WEST-CREE PWI;Lo;0;L;;;;;N;;;;;
+143E;CANADIAN SYLLABICS PWII;Lo;0;L;;;;;N;;;;;
+143F;CANADIAN SYLLABICS WEST-CREE PWII;Lo;0;L;;;;;N;;;;;
+1440;CANADIAN SYLLABICS PWO;Lo;0;L;;;;;N;;;;;
+1441;CANADIAN SYLLABICS WEST-CREE PWO;Lo;0;L;;;;;N;;;;;
+1442;CANADIAN SYLLABICS PWOO;Lo;0;L;;;;;N;;;;;
+1443;CANADIAN SYLLABICS WEST-CREE PWOO;Lo;0;L;;;;;N;;;;;
+1444;CANADIAN SYLLABICS PWA;Lo;0;L;;;;;N;;;;;
+1445;CANADIAN SYLLABICS WEST-CREE PWA;Lo;0;L;;;;;N;;;;;
+1446;CANADIAN SYLLABICS PWAA;Lo;0;L;;;;;N;;;;;
+1447;CANADIAN SYLLABICS WEST-CREE PWAA;Lo;0;L;;;;;N;;;;;
+1448;CANADIAN SYLLABICS Y-CREE PWAA;Lo;0;L;;;;;N;;;;;
+1449;CANADIAN SYLLABICS P;Lo;0;L;;;;;N;;;;;
+144A;CANADIAN SYLLABICS WEST-CREE P;Lo;0;L;;;;;N;;;;;
+144B;CANADIAN SYLLABICS CARRIER H;Lo;0;L;;;;;N;;;;;
+144C;CANADIAN SYLLABICS TE;Lo;0;L;;;;;N;;;;;
+144D;CANADIAN SYLLABICS TAAI;Lo;0;L;;;;;N;;;;;
+144E;CANADIAN SYLLABICS TI;Lo;0;L;;;;;N;;;;;
+144F;CANADIAN SYLLABICS TII;Lo;0;L;;;;;N;;;;;
+1450;CANADIAN SYLLABICS TO;Lo;0;L;;;;;N;;;;;
+1451;CANADIAN SYLLABICS TOO;Lo;0;L;;;;;N;;;;;
+1452;CANADIAN SYLLABICS Y-CREE TOO;Lo;0;L;;;;;N;;;;;
+1453;CANADIAN SYLLABICS CARRIER DEE;Lo;0;L;;;;;N;;;;;
+1454;CANADIAN SYLLABICS CARRIER DI;Lo;0;L;;;;;N;;;;;
+1455;CANADIAN SYLLABICS TA;Lo;0;L;;;;;N;;;;;
+1456;CANADIAN SYLLABICS TAA;Lo;0;L;;;;;N;;;;;
+1457;CANADIAN SYLLABICS TWE;Lo;0;L;;;;;N;;;;;
+1458;CANADIAN SYLLABICS WEST-CREE TWE;Lo;0;L;;;;;N;;;;;
+1459;CANADIAN SYLLABICS TWI;Lo;0;L;;;;;N;;;;;
+145A;CANADIAN SYLLABICS WEST-CREE TWI;Lo;0;L;;;;;N;;;;;
+145B;CANADIAN SYLLABICS TWII;Lo;0;L;;;;;N;;;;;
+145C;CANADIAN SYLLABICS WEST-CREE TWII;Lo;0;L;;;;;N;;;;;
+145D;CANADIAN SYLLABICS TWO;Lo;0;L;;;;;N;;;;;
+145E;CANADIAN SYLLABICS WEST-CREE TWO;Lo;0;L;;;;;N;;;;;
+145F;CANADIAN SYLLABICS TWOO;Lo;0;L;;;;;N;;;;;
+1460;CANADIAN SYLLABICS WEST-CREE TWOO;Lo;0;L;;;;;N;;;;;
+1461;CANADIAN SYLLABICS TWA;Lo;0;L;;;;;N;;;;;
+1462;CANADIAN SYLLABICS WEST-CREE TWA;Lo;0;L;;;;;N;;;;;
+1463;CANADIAN SYLLABICS TWAA;Lo;0;L;;;;;N;;;;;
+1464;CANADIAN SYLLABICS WEST-CREE TWAA;Lo;0;L;;;;;N;;;;;
+1465;CANADIAN SYLLABICS NASKAPI TWAA;Lo;0;L;;;;;N;;;;;
+1466;CANADIAN SYLLABICS T;Lo;0;L;;;;;N;;;;;
+1467;CANADIAN SYLLABICS TTE;Lo;0;L;;;;;N;;;;;
+1468;CANADIAN SYLLABICS TTI;Lo;0;L;;;;;N;;;;;
+1469;CANADIAN SYLLABICS TTO;Lo;0;L;;;;;N;;;;;
+146A;CANADIAN SYLLABICS TTA;Lo;0;L;;;;;N;;;;;
+146B;CANADIAN SYLLABICS KE;Lo;0;L;;;;;N;;;;;
+146C;CANADIAN SYLLABICS KAAI;Lo;0;L;;;;;N;;;;;
+146D;CANADIAN SYLLABICS KI;Lo;0;L;;;;;N;;;;;
+146E;CANADIAN SYLLABICS KII;Lo;0;L;;;;;N;;;;;
+146F;CANADIAN SYLLABICS KO;Lo;0;L;;;;;N;;;;;
+1470;CANADIAN SYLLABICS KOO;Lo;0;L;;;;;N;;;;;
+1471;CANADIAN SYLLABICS Y-CREE KOO;Lo;0;L;;;;;N;;;;;
+1472;CANADIAN SYLLABICS KA;Lo;0;L;;;;;N;;;;;
+1473;CANADIAN SYLLABICS KAA;Lo;0;L;;;;;N;;;;;
+1474;CANADIAN SYLLABICS KWE;Lo;0;L;;;;;N;;;;;
+1475;CANADIAN SYLLABICS WEST-CREE KWE;Lo;0;L;;;;;N;;;;;
+1476;CANADIAN SYLLABICS KWI;Lo;0;L;;;;;N;;;;;
+1477;CANADIAN SYLLABICS WEST-CREE KWI;Lo;0;L;;;;;N;;;;;
+1478;CANADIAN SYLLABICS KWII;Lo;0;L;;;;;N;;;;;
+1479;CANADIAN SYLLABICS WEST-CREE KWII;Lo;0;L;;;;;N;;;;;
+147A;CANADIAN SYLLABICS KWO;Lo;0;L;;;;;N;;;;;
+147B;CANADIAN SYLLABICS WEST-CREE KWO;Lo;0;L;;;;;N;;;;;
+147C;CANADIAN SYLLABICS KWOO;Lo;0;L;;;;;N;;;;;
+147D;CANADIAN SYLLABICS WEST-CREE KWOO;Lo;0;L;;;;;N;;;;;
+147E;CANADIAN SYLLABICS KWA;Lo;0;L;;;;;N;;;;;
+147F;CANADIAN SYLLABICS WEST-CREE KWA;Lo;0;L;;;;;N;;;;;
+1480;CANADIAN SYLLABICS KWAA;Lo;0;L;;;;;N;;;;;
+1481;CANADIAN SYLLABICS WEST-CREE KWAA;Lo;0;L;;;;;N;;;;;
+1482;CANADIAN SYLLABICS NASKAPI KWAA;Lo;0;L;;;;;N;;;;;
+1483;CANADIAN SYLLABICS K;Lo;0;L;;;;;N;;;;;
+1484;CANADIAN SYLLABICS KW;Lo;0;L;;;;;N;;;;;
+1485;CANADIAN SYLLABICS SOUTH-SLAVEY KEH;Lo;0;L;;;;;N;;;;;
+1486;CANADIAN SYLLABICS SOUTH-SLAVEY KIH;Lo;0;L;;;;;N;;;;;
+1487;CANADIAN SYLLABICS SOUTH-SLAVEY KOH;Lo;0;L;;;;;N;;;;;
+1488;CANADIAN SYLLABICS SOUTH-SLAVEY KAH;Lo;0;L;;;;;N;;;;;
+1489;CANADIAN SYLLABICS CE;Lo;0;L;;;;;N;;;;;
+148A;CANADIAN SYLLABICS CAAI;Lo;0;L;;;;;N;;;;;
+148B;CANADIAN SYLLABICS CI;Lo;0;L;;;;;N;;;;;
+148C;CANADIAN SYLLABICS CII;Lo;0;L;;;;;N;;;;;
+148D;CANADIAN SYLLABICS CO;Lo;0;L;;;;;N;;;;;
+148E;CANADIAN SYLLABICS COO;Lo;0;L;;;;;N;;;;;
+148F;CANADIAN SYLLABICS Y-CREE COO;Lo;0;L;;;;;N;;;;;
+1490;CANADIAN SYLLABICS CA;Lo;0;L;;;;;N;;;;;
+1491;CANADIAN SYLLABICS CAA;Lo;0;L;;;;;N;;;;;
+1492;CANADIAN SYLLABICS CWE;Lo;0;L;;;;;N;;;;;
+1493;CANADIAN SYLLABICS WEST-CREE CWE;Lo;0;L;;;;;N;;;;;
+1494;CANADIAN SYLLABICS CWI;Lo;0;L;;;;;N;;;;;
+1495;CANADIAN SYLLABICS WEST-CREE CWI;Lo;0;L;;;;;N;;;;;
+1496;CANADIAN SYLLABICS CWII;Lo;0;L;;;;;N;;;;;
+1497;CANADIAN SYLLABICS WEST-CREE CWII;Lo;0;L;;;;;N;;;;;
+1498;CANADIAN SYLLABICS CWO;Lo;0;L;;;;;N;;;;;
+1499;CANADIAN SYLLABICS WEST-CREE CWO;Lo;0;L;;;;;N;;;;;
+149A;CANADIAN SYLLABICS CWOO;Lo;0;L;;;;;N;;;;;
+149B;CANADIAN SYLLABICS WEST-CREE CWOO;Lo;0;L;;;;;N;;;;;
+149C;CANADIAN SYLLABICS CWA;Lo;0;L;;;;;N;;;;;
+149D;CANADIAN SYLLABICS WEST-CREE CWA;Lo;0;L;;;;;N;;;;;
+149E;CANADIAN SYLLABICS CWAA;Lo;0;L;;;;;N;;;;;
+149F;CANADIAN SYLLABICS WEST-CREE CWAA;Lo;0;L;;;;;N;;;;;
+14A0;CANADIAN SYLLABICS NASKAPI CWAA;Lo;0;L;;;;;N;;;;;
+14A1;CANADIAN SYLLABICS C;Lo;0;L;;;;;N;;;;;
+14A2;CANADIAN SYLLABICS SAYISI TH;Lo;0;L;;;;;N;;;;;
+14A3;CANADIAN SYLLABICS ME;Lo;0;L;;;;;N;;;;;
+14A4;CANADIAN SYLLABICS MAAI;Lo;0;L;;;;;N;;;;;
+14A5;CANADIAN SYLLABICS MI;Lo;0;L;;;;;N;;;;;
+14A6;CANADIAN SYLLABICS MII;Lo;0;L;;;;;N;;;;;
+14A7;CANADIAN SYLLABICS MO;Lo;0;L;;;;;N;;;;;
+14A8;CANADIAN SYLLABICS MOO;Lo;0;L;;;;;N;;;;;
+14A9;CANADIAN SYLLABICS Y-CREE MOO;Lo;0;L;;;;;N;;;;;
+14AA;CANADIAN SYLLABICS MA;Lo;0;L;;;;;N;;;;;
+14AB;CANADIAN SYLLABICS MAA;Lo;0;L;;;;;N;;;;;
+14AC;CANADIAN SYLLABICS MWE;Lo;0;L;;;;;N;;;;;
+14AD;CANADIAN SYLLABICS WEST-CREE MWE;Lo;0;L;;;;;N;;;;;
+14AE;CANADIAN SYLLABICS MWI;Lo;0;L;;;;;N;;;;;
+14AF;CANADIAN SYLLABICS WEST-CREE MWI;Lo;0;L;;;;;N;;;;;
+14B0;CANADIAN SYLLABICS MWII;Lo;0;L;;;;;N;;;;;
+14B1;CANADIAN SYLLABICS WEST-CREE MWII;Lo;0;L;;;;;N;;;;;
+14B2;CANADIAN SYLLABICS MWO;Lo;0;L;;;;;N;;;;;
+14B3;CANADIAN SYLLABICS WEST-CREE MWO;Lo;0;L;;;;;N;;;;;
+14B4;CANADIAN SYLLABICS MWOO;Lo;0;L;;;;;N;;;;;
+14B5;CANADIAN SYLLABICS WEST-CREE MWOO;Lo;0;L;;;;;N;;;;;
+14B6;CANADIAN SYLLABICS MWA;Lo;0;L;;;;;N;;;;;
+14B7;CANADIAN SYLLABICS WEST-CREE MWA;Lo;0;L;;;;;N;;;;;
+14B8;CANADIAN SYLLABICS MWAA;Lo;0;L;;;;;N;;;;;
+14B9;CANADIAN SYLLABICS WEST-CREE MWAA;Lo;0;L;;;;;N;;;;;
+14BA;CANADIAN SYLLABICS NASKAPI MWAA;Lo;0;L;;;;;N;;;;;
+14BB;CANADIAN SYLLABICS M;Lo;0;L;;;;;N;;;;;
+14BC;CANADIAN SYLLABICS WEST-CREE M;Lo;0;L;;;;;N;;;;;
+14BD;CANADIAN SYLLABICS MH;Lo;0;L;;;;;N;;;;;
+14BE;CANADIAN SYLLABICS ATHAPASCAN M;Lo;0;L;;;;;N;;;;;
+14BF;CANADIAN SYLLABICS SAYISI M;Lo;0;L;;;;;N;;;;;
+14C0;CANADIAN SYLLABICS NE;Lo;0;L;;;;;N;;;;;
+14C1;CANADIAN SYLLABICS NAAI;Lo;0;L;;;;;N;;;;;
+14C2;CANADIAN SYLLABICS NI;Lo;0;L;;;;;N;;;;;
+14C3;CANADIAN SYLLABICS NII;Lo;0;L;;;;;N;;;;;
+14C4;CANADIAN SYLLABICS NO;Lo;0;L;;;;;N;;;;;
+14C5;CANADIAN SYLLABICS NOO;Lo;0;L;;;;;N;;;;;
+14C6;CANADIAN SYLLABICS Y-CREE NOO;Lo;0;L;;;;;N;;;;;
+14C7;CANADIAN SYLLABICS NA;Lo;0;L;;;;;N;;;;;
+14C8;CANADIAN SYLLABICS NAA;Lo;0;L;;;;;N;;;;;
+14C9;CANADIAN SYLLABICS NWE;Lo;0;L;;;;;N;;;;;
+14CA;CANADIAN SYLLABICS WEST-CREE NWE;Lo;0;L;;;;;N;;;;;
+14CB;CANADIAN SYLLABICS NWA;Lo;0;L;;;;;N;;;;;
+14CC;CANADIAN SYLLABICS WEST-CREE NWA;Lo;0;L;;;;;N;;;;;
+14CD;CANADIAN SYLLABICS NWAA;Lo;0;L;;;;;N;;;;;
+14CE;CANADIAN SYLLABICS WEST-CREE NWAA;Lo;0;L;;;;;N;;;;;
+14CF;CANADIAN SYLLABICS NASKAPI NWAA;Lo;0;L;;;;;N;;;;;
+14D0;CANADIAN SYLLABICS N;Lo;0;L;;;;;N;;;;;
+14D1;CANADIAN SYLLABICS CARRIER NG;Lo;0;L;;;;;N;;;;;
+14D2;CANADIAN SYLLABICS NH;Lo;0;L;;;;;N;;;;;
+14D3;CANADIAN SYLLABICS LE;Lo;0;L;;;;;N;;;;;
+14D4;CANADIAN SYLLABICS LAAI;Lo;0;L;;;;;N;;;;;
+14D5;CANADIAN SYLLABICS LI;Lo;0;L;;;;;N;;;;;
+14D6;CANADIAN SYLLABICS LII;Lo;0;L;;;;;N;;;;;
+14D7;CANADIAN SYLLABICS LO;Lo;0;L;;;;;N;;;;;
+14D8;CANADIAN SYLLABICS LOO;Lo;0;L;;;;;N;;;;;
+14D9;CANADIAN SYLLABICS Y-CREE LOO;Lo;0;L;;;;;N;;;;;
+14DA;CANADIAN SYLLABICS LA;Lo;0;L;;;;;N;;;;;
+14DB;CANADIAN SYLLABICS LAA;Lo;0;L;;;;;N;;;;;
+14DC;CANADIAN SYLLABICS LWE;Lo;0;L;;;;;N;;;;;
+14DD;CANADIAN SYLLABICS WEST-CREE LWE;Lo;0;L;;;;;N;;;;;
+14DE;CANADIAN SYLLABICS LWI;Lo;0;L;;;;;N;;;;;
+14DF;CANADIAN SYLLABICS WEST-CREE LWI;Lo;0;L;;;;;N;;;;;
+14E0;CANADIAN SYLLABICS LWII;Lo;0;L;;;;;N;;;;;
+14E1;CANADIAN SYLLABICS WEST-CREE LWII;Lo;0;L;;;;;N;;;;;
+14E2;CANADIAN SYLLABICS LWO;Lo;0;L;;;;;N;;;;;
+14E3;CANADIAN SYLLABICS WEST-CREE LWO;Lo;0;L;;;;;N;;;;;
+14E4;CANADIAN SYLLABICS LWOO;Lo;0;L;;;;;N;;;;;
+14E5;CANADIAN SYLLABICS WEST-CREE LWOO;Lo;0;L;;;;;N;;;;;
+14E6;CANADIAN SYLLABICS LWA;Lo;0;L;;;;;N;;;;;
+14E7;CANADIAN SYLLABICS WEST-CREE LWA;Lo;0;L;;;;;N;;;;;
+14E8;CANADIAN SYLLABICS LWAA;Lo;0;L;;;;;N;;;;;
+14E9;CANADIAN SYLLABICS WEST-CREE LWAA;Lo;0;L;;;;;N;;;;;
+14EA;CANADIAN SYLLABICS L;Lo;0;L;;;;;N;;;;;
+14EB;CANADIAN SYLLABICS WEST-CREE L;Lo;0;L;;;;;N;;;;;
+14EC;CANADIAN SYLLABICS MEDIAL L;Lo;0;L;;;;;N;;;;;
+14ED;CANADIAN SYLLABICS SE;Lo;0;L;;;;;N;;;;;
+14EE;CANADIAN SYLLABICS SAAI;Lo;0;L;;;;;N;;;;;
+14EF;CANADIAN SYLLABICS SI;Lo;0;L;;;;;N;;;;;
+14F0;CANADIAN SYLLABICS SII;Lo;0;L;;;;;N;;;;;
+14F1;CANADIAN SYLLABICS SO;Lo;0;L;;;;;N;;;;;
+14F2;CANADIAN SYLLABICS SOO;Lo;0;L;;;;;N;;;;;
+14F3;CANADIAN SYLLABICS Y-CREE SOO;Lo;0;L;;;;;N;;;;;
+14F4;CANADIAN SYLLABICS SA;Lo;0;L;;;;;N;;;;;
+14F5;CANADIAN SYLLABICS SAA;Lo;0;L;;;;;N;;;;;
+14F6;CANADIAN SYLLABICS SWE;Lo;0;L;;;;;N;;;;;
+14F7;CANADIAN SYLLABICS WEST-CREE SWE;Lo;0;L;;;;;N;;;;;
+14F8;CANADIAN SYLLABICS SWI;Lo;0;L;;;;;N;;;;;
+14F9;CANADIAN SYLLABICS WEST-CREE SWI;Lo;0;L;;;;;N;;;;;
+14FA;CANADIAN SYLLABICS SWII;Lo;0;L;;;;;N;;;;;
+14FB;CANADIAN SYLLABICS WEST-CREE SWII;Lo;0;L;;;;;N;;;;;
+14FC;CANADIAN SYLLABICS SWO;Lo;0;L;;;;;N;;;;;
+14FD;CANADIAN SYLLABICS WEST-CREE SWO;Lo;0;L;;;;;N;;;;;
+14FE;CANADIAN SYLLABICS SWOO;Lo;0;L;;;;;N;;;;;
+14FF;CANADIAN SYLLABICS WEST-CREE SWOO;Lo;0;L;;;;;N;;;;;
+1500;CANADIAN SYLLABICS SWA;Lo;0;L;;;;;N;;;;;
+1501;CANADIAN SYLLABICS WEST-CREE SWA;Lo;0;L;;;;;N;;;;;
+1502;CANADIAN SYLLABICS SWAA;Lo;0;L;;;;;N;;;;;
+1503;CANADIAN SYLLABICS WEST-CREE SWAA;Lo;0;L;;;;;N;;;;;
+1504;CANADIAN SYLLABICS NASKAPI SWAA;Lo;0;L;;;;;N;;;;;
+1505;CANADIAN SYLLABICS S;Lo;0;L;;;;;N;;;;;
+1506;CANADIAN SYLLABICS ATHAPASCAN S;Lo;0;L;;;;;N;;;;;
+1507;CANADIAN SYLLABICS SW;Lo;0;L;;;;;N;;;;;
+1508;CANADIAN SYLLABICS BLACKFOOT S;Lo;0;L;;;;;N;;;;;
+1509;CANADIAN SYLLABICS MOOSE-CREE SK;Lo;0;L;;;;;N;;;;;
+150A;CANADIAN SYLLABICS NASKAPI SKW;Lo;0;L;;;;;N;;;;;
+150B;CANADIAN SYLLABICS NASKAPI S-W;Lo;0;L;;;;;N;;;;;
+150C;CANADIAN SYLLABICS NASKAPI SPWA;Lo;0;L;;;;;N;;;;;
+150D;CANADIAN SYLLABICS NASKAPI STWA;Lo;0;L;;;;;N;;;;;
+150E;CANADIAN SYLLABICS NASKAPI SKWA;Lo;0;L;;;;;N;;;;;
+150F;CANADIAN SYLLABICS NASKAPI SCWA;Lo;0;L;;;;;N;;;;;
+1510;CANADIAN SYLLABICS SHE;Lo;0;L;;;;;N;;;;;
+1511;CANADIAN SYLLABICS SHI;Lo;0;L;;;;;N;;;;;
+1512;CANADIAN SYLLABICS SHII;Lo;0;L;;;;;N;;;;;
+1513;CANADIAN SYLLABICS SHO;Lo;0;L;;;;;N;;;;;
+1514;CANADIAN SYLLABICS SHOO;Lo;0;L;;;;;N;;;;;
+1515;CANADIAN SYLLABICS SHA;Lo;0;L;;;;;N;;;;;
+1516;CANADIAN SYLLABICS SHAA;Lo;0;L;;;;;N;;;;;
+1517;CANADIAN SYLLABICS SHWE;Lo;0;L;;;;;N;;;;;
+1518;CANADIAN SYLLABICS WEST-CREE SHWE;Lo;0;L;;;;;N;;;;;
+1519;CANADIAN SYLLABICS SHWI;Lo;0;L;;;;;N;;;;;
+151A;CANADIAN SYLLABICS WEST-CREE SHWI;Lo;0;L;;;;;N;;;;;
+151B;CANADIAN SYLLABICS SHWII;Lo;0;L;;;;;N;;;;;
+151C;CANADIAN SYLLABICS WEST-CREE SHWII;Lo;0;L;;;;;N;;;;;
+151D;CANADIAN SYLLABICS SHWO;Lo;0;L;;;;;N;;;;;
+151E;CANADIAN SYLLABICS WEST-CREE SHWO;Lo;0;L;;;;;N;;;;;
+151F;CANADIAN SYLLABICS SHWOO;Lo;0;L;;;;;N;;;;;
+1520;CANADIAN SYLLABICS WEST-CREE SHWOO;Lo;0;L;;;;;N;;;;;
+1521;CANADIAN SYLLABICS SHWA;Lo;0;L;;;;;N;;;;;
+1522;CANADIAN SYLLABICS WEST-CREE SHWA;Lo;0;L;;;;;N;;;;;
+1523;CANADIAN SYLLABICS SHWAA;Lo;0;L;;;;;N;;;;;
+1524;CANADIAN SYLLABICS WEST-CREE SHWAA;Lo;0;L;;;;;N;;;;;
+1525;CANADIAN SYLLABICS SH;Lo;0;L;;;;;N;;;;;
+1526;CANADIAN SYLLABICS YE;Lo;0;L;;;;;N;;;;;
+1527;CANADIAN SYLLABICS YAAI;Lo;0;L;;;;;N;;;;;
+1528;CANADIAN SYLLABICS YI;Lo;0;L;;;;;N;;;;;
+1529;CANADIAN SYLLABICS YII;Lo;0;L;;;;;N;;;;;
+152A;CANADIAN SYLLABICS YO;Lo;0;L;;;;;N;;;;;
+152B;CANADIAN SYLLABICS YOO;Lo;0;L;;;;;N;;;;;
+152C;CANADIAN SYLLABICS Y-CREE YOO;Lo;0;L;;;;;N;;;;;
+152D;CANADIAN SYLLABICS YA;Lo;0;L;;;;;N;;;;;
+152E;CANADIAN SYLLABICS YAA;Lo;0;L;;;;;N;;;;;
+152F;CANADIAN SYLLABICS YWE;Lo;0;L;;;;;N;;;;;
+1530;CANADIAN SYLLABICS WEST-CREE YWE;Lo;0;L;;;;;N;;;;;
+1531;CANADIAN SYLLABICS YWI;Lo;0;L;;;;;N;;;;;
+1532;CANADIAN SYLLABICS WEST-CREE YWI;Lo;0;L;;;;;N;;;;;
+1533;CANADIAN SYLLABICS YWII;Lo;0;L;;;;;N;;;;;
+1534;CANADIAN SYLLABICS WEST-CREE YWII;Lo;0;L;;;;;N;;;;;
+1535;CANADIAN SYLLABICS YWO;Lo;0;L;;;;;N;;;;;
+1536;CANADIAN SYLLABICS WEST-CREE YWO;Lo;0;L;;;;;N;;;;;
+1537;CANADIAN SYLLABICS YWOO;Lo;0;L;;;;;N;;;;;
+1538;CANADIAN SYLLABICS WEST-CREE YWOO;Lo;0;L;;;;;N;;;;;
+1539;CANADIAN SYLLABICS YWA;Lo;0;L;;;;;N;;;;;
+153A;CANADIAN SYLLABICS WEST-CREE YWA;Lo;0;L;;;;;N;;;;;
+153B;CANADIAN SYLLABICS YWAA;Lo;0;L;;;;;N;;;;;
+153C;CANADIAN SYLLABICS WEST-CREE YWAA;Lo;0;L;;;;;N;;;;;
+153D;CANADIAN SYLLABICS NASKAPI YWAA;Lo;0;L;;;;;N;;;;;
+153E;CANADIAN SYLLABICS Y;Lo;0;L;;;;;N;;;;;
+153F;CANADIAN SYLLABICS BIBLE-CREE Y;Lo;0;L;;;;;N;;;;;
+1540;CANADIAN SYLLABICS WEST-CREE Y;Lo;0;L;;;;;N;;;;;
+1541;CANADIAN SYLLABICS SAYISI YI;Lo;0;L;;;;;N;;;;;
+1542;CANADIAN SYLLABICS RE;Lo;0;L;;;;;N;;;;;
+1543;CANADIAN SYLLABICS R-CREE RE;Lo;0;L;;;;;N;;;;;
+1544;CANADIAN SYLLABICS WEST-CREE LE;Lo;0;L;;;;;N;;;;;
+1545;CANADIAN SYLLABICS RAAI;Lo;0;L;;;;;N;;;;;
+1546;CANADIAN SYLLABICS RI;Lo;0;L;;;;;N;;;;;
+1547;CANADIAN SYLLABICS RII;Lo;0;L;;;;;N;;;;;
+1548;CANADIAN SYLLABICS RO;Lo;0;L;;;;;N;;;;;
+1549;CANADIAN SYLLABICS ROO;Lo;0;L;;;;;N;;;;;
+154A;CANADIAN SYLLABICS WEST-CREE LO;Lo;0;L;;;;;N;;;;;
+154B;CANADIAN SYLLABICS RA;Lo;0;L;;;;;N;;;;;
+154C;CANADIAN SYLLABICS RAA;Lo;0;L;;;;;N;;;;;
+154D;CANADIAN SYLLABICS WEST-CREE LA;Lo;0;L;;;;;N;;;;;
+154E;CANADIAN SYLLABICS RWAA;Lo;0;L;;;;;N;;;;;
+154F;CANADIAN SYLLABICS WEST-CREE RWAA;Lo;0;L;;;;;N;;;;;
+1550;CANADIAN SYLLABICS R;Lo;0;L;;;;;N;;;;;
+1551;CANADIAN SYLLABICS WEST-CREE R;Lo;0;L;;;;;N;;;;;
+1552;CANADIAN SYLLABICS MEDIAL R;Lo;0;L;;;;;N;;;;;
+1553;CANADIAN SYLLABICS FE;Lo;0;L;;;;;N;;;;;
+1554;CANADIAN SYLLABICS FAAI;Lo;0;L;;;;;N;;;;;
+1555;CANADIAN SYLLABICS FI;Lo;0;L;;;;;N;;;;;
+1556;CANADIAN SYLLABICS FII;Lo;0;L;;;;;N;;;;;
+1557;CANADIAN SYLLABICS FO;Lo;0;L;;;;;N;;;;;
+1558;CANADIAN SYLLABICS FOO;Lo;0;L;;;;;N;;;;;
+1559;CANADIAN SYLLABICS FA;Lo;0;L;;;;;N;;;;;
+155A;CANADIAN SYLLABICS FAA;Lo;0;L;;;;;N;;;;;
+155B;CANADIAN SYLLABICS FWAA;Lo;0;L;;;;;N;;;;;
+155C;CANADIAN SYLLABICS WEST-CREE FWAA;Lo;0;L;;;;;N;;;;;
+155D;CANADIAN SYLLABICS F;Lo;0;L;;;;;N;;;;;
+155E;CANADIAN SYLLABICS THE;Lo;0;L;;;;;N;;;;;
+155F;CANADIAN SYLLABICS N-CREE THE;Lo;0;L;;;;;N;;;;;
+1560;CANADIAN SYLLABICS THI;Lo;0;L;;;;;N;;;;;
+1561;CANADIAN SYLLABICS N-CREE THI;Lo;0;L;;;;;N;;;;;
+1562;CANADIAN SYLLABICS THII;Lo;0;L;;;;;N;;;;;
+1563;CANADIAN SYLLABICS N-CREE THII;Lo;0;L;;;;;N;;;;;
+1564;CANADIAN SYLLABICS THO;Lo;0;L;;;;;N;;;;;
+1565;CANADIAN SYLLABICS THOO;Lo;0;L;;;;;N;;;;;
+1566;CANADIAN SYLLABICS THA;Lo;0;L;;;;;N;;;;;
+1567;CANADIAN SYLLABICS THAA;Lo;0;L;;;;;N;;;;;
+1568;CANADIAN SYLLABICS THWAA;Lo;0;L;;;;;N;;;;;
+1569;CANADIAN SYLLABICS WEST-CREE THWAA;Lo;0;L;;;;;N;;;;;
+156A;CANADIAN SYLLABICS TH;Lo;0;L;;;;;N;;;;;
+156B;CANADIAN SYLLABICS TTHE;Lo;0;L;;;;;N;;;;;
+156C;CANADIAN SYLLABICS TTHI;Lo;0;L;;;;;N;;;;;
+156D;CANADIAN SYLLABICS TTHO;Lo;0;L;;;;;N;;;;;
+156E;CANADIAN SYLLABICS TTHA;Lo;0;L;;;;;N;;;;;
+156F;CANADIAN SYLLABICS TTH;Lo;0;L;;;;;N;;;;;
+1570;CANADIAN SYLLABICS TYE;Lo;0;L;;;;;N;;;;;
+1571;CANADIAN SYLLABICS TYI;Lo;0;L;;;;;N;;;;;
+1572;CANADIAN SYLLABICS TYO;Lo;0;L;;;;;N;;;;;
+1573;CANADIAN SYLLABICS TYA;Lo;0;L;;;;;N;;;;;
+1574;CANADIAN SYLLABICS NUNAVIK HE;Lo;0;L;;;;;N;;;;;
+1575;CANADIAN SYLLABICS NUNAVIK HI;Lo;0;L;;;;;N;;;;;
+1576;CANADIAN SYLLABICS NUNAVIK HII;Lo;0;L;;;;;N;;;;;
+1577;CANADIAN SYLLABICS NUNAVIK HO;Lo;0;L;;;;;N;;;;;
+1578;CANADIAN SYLLABICS NUNAVIK HOO;Lo;0;L;;;;;N;;;;;
+1579;CANADIAN SYLLABICS NUNAVIK HA;Lo;0;L;;;;;N;;;;;
+157A;CANADIAN SYLLABICS NUNAVIK HAA;Lo;0;L;;;;;N;;;;;
+157B;CANADIAN SYLLABICS NUNAVIK H;Lo;0;L;;;;;N;;;;;
+157C;CANADIAN SYLLABICS NUNAVUT H;Lo;0;L;;;;;N;;;;;
+157D;CANADIAN SYLLABICS HK;Lo;0;L;;;;;N;;;;;
+157E;CANADIAN SYLLABICS QAAI;Lo;0;L;;;;;N;;;;;
+157F;CANADIAN SYLLABICS QI;Lo;0;L;;;;;N;;;;;
+1580;CANADIAN SYLLABICS QII;Lo;0;L;;;;;N;;;;;
+1581;CANADIAN SYLLABICS QO;Lo;0;L;;;;;N;;;;;
+1582;CANADIAN SYLLABICS QOO;Lo;0;L;;;;;N;;;;;
+1583;CANADIAN SYLLABICS QA;Lo;0;L;;;;;N;;;;;
+1584;CANADIAN SYLLABICS QAA;Lo;0;L;;;;;N;;;;;
+1585;CANADIAN SYLLABICS Q;Lo;0;L;;;;;N;;;;;
+1586;CANADIAN SYLLABICS TLHE;Lo;0;L;;;;;N;;;;;
+1587;CANADIAN SYLLABICS TLHI;Lo;0;L;;;;;N;;;;;
+1588;CANADIAN SYLLABICS TLHO;Lo;0;L;;;;;N;;;;;
+1589;CANADIAN SYLLABICS TLHA;Lo;0;L;;;;;N;;;;;
+158A;CANADIAN SYLLABICS WEST-CREE RE;Lo;0;L;;;;;N;;;;;
+158B;CANADIAN SYLLABICS WEST-CREE RI;Lo;0;L;;;;;N;;;;;
+158C;CANADIAN SYLLABICS WEST-CREE RO;Lo;0;L;;;;;N;;;;;
+158D;CANADIAN SYLLABICS WEST-CREE RA;Lo;0;L;;;;;N;;;;;
+158E;CANADIAN SYLLABICS NGAAI;Lo;0;L;;;;;N;;;;;
+158F;CANADIAN SYLLABICS NGI;Lo;0;L;;;;;N;;;;;
+1590;CANADIAN SYLLABICS NGII;Lo;0;L;;;;;N;;;;;
+1591;CANADIAN SYLLABICS NGO;Lo;0;L;;;;;N;;;;;
+1592;CANADIAN SYLLABICS NGOO;Lo;0;L;;;;;N;;;;;
+1593;CANADIAN SYLLABICS NGA;Lo;0;L;;;;;N;;;;;
+1594;CANADIAN SYLLABICS NGAA;Lo;0;L;;;;;N;;;;;
+1595;CANADIAN SYLLABICS NG;Lo;0;L;;;;;N;;;;;
+1596;CANADIAN SYLLABICS NNG;Lo;0;L;;;;;N;;;;;
+1597;CANADIAN SYLLABICS SAYISI SHE;Lo;0;L;;;;;N;;;;;
+1598;CANADIAN SYLLABICS SAYISI SHI;Lo;0;L;;;;;N;;;;;
+1599;CANADIAN SYLLABICS SAYISI SHO;Lo;0;L;;;;;N;;;;;
+159A;CANADIAN SYLLABICS SAYISI SHA;Lo;0;L;;;;;N;;;;;
+159B;CANADIAN SYLLABICS WOODS-CREE THE;Lo;0;L;;;;;N;;;;;
+159C;CANADIAN SYLLABICS WOODS-CREE THI;Lo;0;L;;;;;N;;;;;
+159D;CANADIAN SYLLABICS WOODS-CREE THO;Lo;0;L;;;;;N;;;;;
+159E;CANADIAN SYLLABICS WOODS-CREE THA;Lo;0;L;;;;;N;;;;;
+159F;CANADIAN SYLLABICS WOODS-CREE TH;Lo;0;L;;;;;N;;;;;
+15A0;CANADIAN SYLLABICS LHI;Lo;0;L;;;;;N;;;;;
+15A1;CANADIAN SYLLABICS LHII;Lo;0;L;;;;;N;;;;;
+15A2;CANADIAN SYLLABICS LHO;Lo;0;L;;;;;N;;;;;
+15A3;CANADIAN SYLLABICS LHOO;Lo;0;L;;;;;N;;;;;
+15A4;CANADIAN SYLLABICS LHA;Lo;0;L;;;;;N;;;;;
+15A5;CANADIAN SYLLABICS LHAA;Lo;0;L;;;;;N;;;;;
+15A6;CANADIAN SYLLABICS LH;Lo;0;L;;;;;N;;;;;
+15A7;CANADIAN SYLLABICS TH-CREE THE;Lo;0;L;;;;;N;;;;;
+15A8;CANADIAN SYLLABICS TH-CREE THI;Lo;0;L;;;;;N;;;;;
+15A9;CANADIAN SYLLABICS TH-CREE THII;Lo;0;L;;;;;N;;;;;
+15AA;CANADIAN SYLLABICS TH-CREE THO;Lo;0;L;;;;;N;;;;;
+15AB;CANADIAN SYLLABICS TH-CREE THOO;Lo;0;L;;;;;N;;;;;
+15AC;CANADIAN SYLLABICS TH-CREE THA;Lo;0;L;;;;;N;;;;;
+15AD;CANADIAN SYLLABICS TH-CREE THAA;Lo;0;L;;;;;N;;;;;
+15AE;CANADIAN SYLLABICS TH-CREE TH;Lo;0;L;;;;;N;;;;;
+15AF;CANADIAN SYLLABICS AIVILIK B;Lo;0;L;;;;;N;;;;;
+15B0;CANADIAN SYLLABICS BLACKFOOT E;Lo;0;L;;;;;N;;;;;
+15B1;CANADIAN SYLLABICS BLACKFOOT I;Lo;0;L;;;;;N;;;;;
+15B2;CANADIAN SYLLABICS BLACKFOOT O;Lo;0;L;;;;;N;;;;;
+15B3;CANADIAN SYLLABICS BLACKFOOT A;Lo;0;L;;;;;N;;;;;
+15B4;CANADIAN SYLLABICS BLACKFOOT WE;Lo;0;L;;;;;N;;;;;
+15B5;CANADIAN SYLLABICS BLACKFOOT WI;Lo;0;L;;;;;N;;;;;
+15B6;CANADIAN SYLLABICS BLACKFOOT WO;Lo;0;L;;;;;N;;;;;
+15B7;CANADIAN SYLLABICS BLACKFOOT WA;Lo;0;L;;;;;N;;;;;
+15B8;CANADIAN SYLLABICS BLACKFOOT NE;Lo;0;L;;;;;N;;;;;
+15B9;CANADIAN SYLLABICS BLACKFOOT NI;Lo;0;L;;;;;N;;;;;
+15BA;CANADIAN SYLLABICS BLACKFOOT NO;Lo;0;L;;;;;N;;;;;
+15BB;CANADIAN SYLLABICS BLACKFOOT NA;Lo;0;L;;;;;N;;;;;
+15BC;CANADIAN SYLLABICS BLACKFOOT KE;Lo;0;L;;;;;N;;;;;
+15BD;CANADIAN SYLLABICS BLACKFOOT KI;Lo;0;L;;;;;N;;;;;
+15BE;CANADIAN SYLLABICS BLACKFOOT KO;Lo;0;L;;;;;N;;;;;
+15BF;CANADIAN SYLLABICS BLACKFOOT KA;Lo;0;L;;;;;N;;;;;
+15C0;CANADIAN SYLLABICS SAYISI HE;Lo;0;L;;;;;N;;;;;
+15C1;CANADIAN SYLLABICS SAYISI HI;Lo;0;L;;;;;N;;;;;
+15C2;CANADIAN SYLLABICS SAYISI HO;Lo;0;L;;;;;N;;;;;
+15C3;CANADIAN SYLLABICS SAYISI HA;Lo;0;L;;;;;N;;;;;
+15C4;CANADIAN SYLLABICS CARRIER GHU;Lo;0;L;;;;;N;;;;;
+15C5;CANADIAN SYLLABICS CARRIER GHO;Lo;0;L;;;;;N;;;;;
+15C6;CANADIAN SYLLABICS CARRIER GHE;Lo;0;L;;;;;N;;;;;
+15C7;CANADIAN SYLLABICS CARRIER GHEE;Lo;0;L;;;;;N;;;;;
+15C8;CANADIAN SYLLABICS CARRIER GHI;Lo;0;L;;;;;N;;;;;
+15C9;CANADIAN SYLLABICS CARRIER GHA;Lo;0;L;;;;;N;;;;;
+15CA;CANADIAN SYLLABICS CARRIER RU;Lo;0;L;;;;;N;;;;;
+15CB;CANADIAN SYLLABICS CARRIER RO;Lo;0;L;;;;;N;;;;;
+15CC;CANADIAN SYLLABICS CARRIER RE;Lo;0;L;;;;;N;;;;;
+15CD;CANADIAN SYLLABICS CARRIER REE;Lo;0;L;;;;;N;;;;;
+15CE;CANADIAN SYLLABICS CARRIER RI;Lo;0;L;;;;;N;;;;;
+15CF;CANADIAN SYLLABICS CARRIER RA;Lo;0;L;;;;;N;;;;;
+15D0;CANADIAN SYLLABICS CARRIER WU;Lo;0;L;;;;;N;;;;;
+15D1;CANADIAN SYLLABICS CARRIER WO;Lo;0;L;;;;;N;;;;;
+15D2;CANADIAN SYLLABICS CARRIER WE;Lo;0;L;;;;;N;;;;;
+15D3;CANADIAN SYLLABICS CARRIER WEE;Lo;0;L;;;;;N;;;;;
+15D4;CANADIAN SYLLABICS CARRIER WI;Lo;0;L;;;;;N;;;;;
+15D5;CANADIAN SYLLABICS CARRIER WA;Lo;0;L;;;;;N;;;;;
+15D6;CANADIAN SYLLABICS CARRIER HWU;Lo;0;L;;;;;N;;;;;
+15D7;CANADIAN SYLLABICS CARRIER HWO;Lo;0;L;;;;;N;;;;;
+15D8;CANADIAN SYLLABICS CARRIER HWE;Lo;0;L;;;;;N;;;;;
+15D9;CANADIAN SYLLABICS CARRIER HWEE;Lo;0;L;;;;;N;;;;;
+15DA;CANADIAN SYLLABICS CARRIER HWI;Lo;0;L;;;;;N;;;;;
+15DB;CANADIAN SYLLABICS CARRIER HWA;Lo;0;L;;;;;N;;;;;
+15DC;CANADIAN SYLLABICS CARRIER THU;Lo;0;L;;;;;N;;;;;
+15DD;CANADIAN SYLLABICS CARRIER THO;Lo;0;L;;;;;N;;;;;
+15DE;CANADIAN SYLLABICS CARRIER THE;Lo;0;L;;;;;N;;;;;
+15DF;CANADIAN SYLLABICS CARRIER THEE;Lo;0;L;;;;;N;;;;;
+15E0;CANADIAN SYLLABICS CARRIER THI;Lo;0;L;;;;;N;;;;;
+15E1;CANADIAN SYLLABICS CARRIER THA;Lo;0;L;;;;;N;;;;;
+15E2;CANADIAN SYLLABICS CARRIER TTU;Lo;0;L;;;;;N;;;;;
+15E3;CANADIAN SYLLABICS CARRIER TTO;Lo;0;L;;;;;N;;;;;
+15E4;CANADIAN SYLLABICS CARRIER TTE;Lo;0;L;;;;;N;;;;;
+15E5;CANADIAN SYLLABICS CARRIER TTEE;Lo;0;L;;;;;N;;;;;
+15E6;CANADIAN SYLLABICS CARRIER TTI;Lo;0;L;;;;;N;;;;;
+15E7;CANADIAN SYLLABICS CARRIER TTA;Lo;0;L;;;;;N;;;;;
+15E8;CANADIAN SYLLABICS CARRIER PU;Lo;0;L;;;;;N;;;;;
+15E9;CANADIAN SYLLABICS CARRIER PO;Lo;0;L;;;;;N;;;;;
+15EA;CANADIAN SYLLABICS CARRIER PE;Lo;0;L;;;;;N;;;;;
+15EB;CANADIAN SYLLABICS CARRIER PEE;Lo;0;L;;;;;N;;;;;
+15EC;CANADIAN SYLLABICS CARRIER PI;Lo;0;L;;;;;N;;;;;
+15ED;CANADIAN SYLLABICS CARRIER PA;Lo;0;L;;;;;N;;;;;
+15EE;CANADIAN SYLLABICS CARRIER P;Lo;0;L;;;;;N;;;;;
+15EF;CANADIAN SYLLABICS CARRIER GU;Lo;0;L;;;;;N;;;;;
+15F0;CANADIAN SYLLABICS CARRIER GO;Lo;0;L;;;;;N;;;;;
+15F1;CANADIAN SYLLABICS CARRIER GE;Lo;0;L;;;;;N;;;;;
+15F2;CANADIAN SYLLABICS CARRIER GEE;Lo;0;L;;;;;N;;;;;
+15F3;CANADIAN SYLLABICS CARRIER GI;Lo;0;L;;;;;N;;;;;
+15F4;CANADIAN SYLLABICS CARRIER GA;Lo;0;L;;;;;N;;;;;
+15F5;CANADIAN SYLLABICS CARRIER KHU;Lo;0;L;;;;;N;;;;;
+15F6;CANADIAN SYLLABICS CARRIER KHO;Lo;0;L;;;;;N;;;;;
+15F7;CANADIAN SYLLABICS CARRIER KHE;Lo;0;L;;;;;N;;;;;
+15F8;CANADIAN SYLLABICS CARRIER KHEE;Lo;0;L;;;;;N;;;;;
+15F9;CANADIAN SYLLABICS CARRIER KHI;Lo;0;L;;;;;N;;;;;
+15FA;CANADIAN SYLLABICS CARRIER KHA;Lo;0;L;;;;;N;;;;;
+15FB;CANADIAN SYLLABICS CARRIER KKU;Lo;0;L;;;;;N;;;;;
+15FC;CANADIAN SYLLABICS CARRIER KKO;Lo;0;L;;;;;N;;;;;
+15FD;CANADIAN SYLLABICS CARRIER KKE;Lo;0;L;;;;;N;;;;;
+15FE;CANADIAN SYLLABICS CARRIER KKEE;Lo;0;L;;;;;N;;;;;
+15FF;CANADIAN SYLLABICS CARRIER KKI;Lo;0;L;;;;;N;;;;;
+1600;CANADIAN SYLLABICS CARRIER KKA;Lo;0;L;;;;;N;;;;;
+1601;CANADIAN SYLLABICS CARRIER KK;Lo;0;L;;;;;N;;;;;
+1602;CANADIAN SYLLABICS CARRIER NU;Lo;0;L;;;;;N;;;;;
+1603;CANADIAN SYLLABICS CARRIER NO;Lo;0;L;;;;;N;;;;;
+1604;CANADIAN SYLLABICS CARRIER NE;Lo;0;L;;;;;N;;;;;
+1605;CANADIAN SYLLABICS CARRIER NEE;Lo;0;L;;;;;N;;;;;
+1606;CANADIAN SYLLABICS CARRIER NI;Lo;0;L;;;;;N;;;;;
+1607;CANADIAN SYLLABICS CARRIER NA;Lo;0;L;;;;;N;;;;;
+1608;CANADIAN SYLLABICS CARRIER MU;Lo;0;L;;;;;N;;;;;
+1609;CANADIAN SYLLABICS CARRIER MO;Lo;0;L;;;;;N;;;;;
+160A;CANADIAN SYLLABICS CARRIER ME;Lo;0;L;;;;;N;;;;;
+160B;CANADIAN SYLLABICS CARRIER MEE;Lo;0;L;;;;;N;;;;;
+160C;CANADIAN SYLLABICS CARRIER MI;Lo;0;L;;;;;N;;;;;
+160D;CANADIAN SYLLABICS CARRIER MA;Lo;0;L;;;;;N;;;;;
+160E;CANADIAN SYLLABICS CARRIER YU;Lo;0;L;;;;;N;;;;;
+160F;CANADIAN SYLLABICS CARRIER YO;Lo;0;L;;;;;N;;;;;
+1610;CANADIAN SYLLABICS CARRIER YE;Lo;0;L;;;;;N;;;;;
+1611;CANADIAN SYLLABICS CARRIER YEE;Lo;0;L;;;;;N;;;;;
+1612;CANADIAN SYLLABICS CARRIER YI;Lo;0;L;;;;;N;;;;;
+1613;CANADIAN SYLLABICS CARRIER YA;Lo;0;L;;;;;N;;;;;
+1614;CANADIAN SYLLABICS CARRIER JU;Lo;0;L;;;;;N;;;;;
+1615;CANADIAN SYLLABICS SAYISI JU;Lo;0;L;;;;;N;;;;;
+1616;CANADIAN SYLLABICS CARRIER JO;Lo;0;L;;;;;N;;;;;
+1617;CANADIAN SYLLABICS CARRIER JE;Lo;0;L;;;;;N;;;;;
+1618;CANADIAN SYLLABICS CARRIER JEE;Lo;0;L;;;;;N;;;;;
+1619;CANADIAN SYLLABICS CARRIER JI;Lo;0;L;;;;;N;;;;;
+161A;CANADIAN SYLLABICS SAYISI JI;Lo;0;L;;;;;N;;;;;
+161B;CANADIAN SYLLABICS CARRIER JA;Lo;0;L;;;;;N;;;;;
+161C;CANADIAN SYLLABICS CARRIER JJU;Lo;0;L;;;;;N;;;;;
+161D;CANADIAN SYLLABICS CARRIER JJO;Lo;0;L;;;;;N;;;;;
+161E;CANADIAN SYLLABICS CARRIER JJE;Lo;0;L;;;;;N;;;;;
+161F;CANADIAN SYLLABICS CARRIER JJEE;Lo;0;L;;;;;N;;;;;
+1620;CANADIAN SYLLABICS CARRIER JJI;Lo;0;L;;;;;N;;;;;
+1621;CANADIAN SYLLABICS CARRIER JJA;Lo;0;L;;;;;N;;;;;
+1622;CANADIAN SYLLABICS CARRIER LU;Lo;0;L;;;;;N;;;;;
+1623;CANADIAN SYLLABICS CARRIER LO;Lo;0;L;;;;;N;;;;;
+1624;CANADIAN SYLLABICS CARRIER LE;Lo;0;L;;;;;N;;;;;
+1625;CANADIAN SYLLABICS CARRIER LEE;Lo;0;L;;;;;N;;;;;
+1626;CANADIAN SYLLABICS CARRIER LI;Lo;0;L;;;;;N;;;;;
+1627;CANADIAN SYLLABICS CARRIER LA;Lo;0;L;;;;;N;;;;;
+1628;CANADIAN SYLLABICS CARRIER DLU;Lo;0;L;;;;;N;;;;;
+1629;CANADIAN SYLLABICS CARRIER DLO;Lo;0;L;;;;;N;;;;;
+162A;CANADIAN SYLLABICS CARRIER DLE;Lo;0;L;;;;;N;;;;;
+162B;CANADIAN SYLLABICS CARRIER DLEE;Lo;0;L;;;;;N;;;;;
+162C;CANADIAN SYLLABICS CARRIER DLI;Lo;0;L;;;;;N;;;;;
+162D;CANADIAN SYLLABICS CARRIER DLA;Lo;0;L;;;;;N;;;;;
+162E;CANADIAN SYLLABICS CARRIER LHU;Lo;0;L;;;;;N;;;;;
+162F;CANADIAN SYLLABICS CARRIER LHO;Lo;0;L;;;;;N;;;;;
+1630;CANADIAN SYLLABICS CARRIER LHE;Lo;0;L;;;;;N;;;;;
+1631;CANADIAN SYLLABICS CARRIER LHEE;Lo;0;L;;;;;N;;;;;
+1632;CANADIAN SYLLABICS CARRIER LHI;Lo;0;L;;;;;N;;;;;
+1633;CANADIAN SYLLABICS CARRIER LHA;Lo;0;L;;;;;N;;;;;
+1634;CANADIAN SYLLABICS CARRIER TLHU;Lo;0;L;;;;;N;;;;;
+1635;CANADIAN SYLLABICS CARRIER TLHO;Lo;0;L;;;;;N;;;;;
+1636;CANADIAN SYLLABICS CARRIER TLHE;Lo;0;L;;;;;N;;;;;
+1637;CANADIAN SYLLABICS CARRIER TLHEE;Lo;0;L;;;;;N;;;;;
+1638;CANADIAN SYLLABICS CARRIER TLHI;Lo;0;L;;;;;N;;;;;
+1639;CANADIAN SYLLABICS CARRIER TLHA;Lo;0;L;;;;;N;;;;;
+163A;CANADIAN SYLLABICS CARRIER TLU;Lo;0;L;;;;;N;;;;;
+163B;CANADIAN SYLLABICS CARRIER TLO;Lo;0;L;;;;;N;;;;;
+163C;CANADIAN SYLLABICS CARRIER TLE;Lo;0;L;;;;;N;;;;;
+163D;CANADIAN SYLLABICS CARRIER TLEE;Lo;0;L;;;;;N;;;;;
+163E;CANADIAN SYLLABICS CARRIER TLI;Lo;0;L;;;;;N;;;;;
+163F;CANADIAN SYLLABICS CARRIER TLA;Lo;0;L;;;;;N;;;;;
+1640;CANADIAN SYLLABICS CARRIER ZU;Lo;0;L;;;;;N;;;;;
+1641;CANADIAN SYLLABICS CARRIER ZO;Lo;0;L;;;;;N;;;;;
+1642;CANADIAN SYLLABICS CARRIER ZE;Lo;0;L;;;;;N;;;;;
+1643;CANADIAN SYLLABICS CARRIER ZEE;Lo;0;L;;;;;N;;;;;
+1644;CANADIAN SYLLABICS CARRIER ZI;Lo;0;L;;;;;N;;;;;
+1645;CANADIAN SYLLABICS CARRIER ZA;Lo;0;L;;;;;N;;;;;
+1646;CANADIAN SYLLABICS CARRIER Z;Lo;0;L;;;;;N;;;;;
+1647;CANADIAN SYLLABICS CARRIER INITIAL Z;Lo;0;L;;;;;N;;;;;
+1648;CANADIAN SYLLABICS CARRIER DZU;Lo;0;L;;;;;N;;;;;
+1649;CANADIAN SYLLABICS CARRIER DZO;Lo;0;L;;;;;N;;;;;
+164A;CANADIAN SYLLABICS CARRIER DZE;Lo;0;L;;;;;N;;;;;
+164B;CANADIAN SYLLABICS CARRIER DZEE;Lo;0;L;;;;;N;;;;;
+164C;CANADIAN SYLLABICS CARRIER DZI;Lo;0;L;;;;;N;;;;;
+164D;CANADIAN SYLLABICS CARRIER DZA;Lo;0;L;;;;;N;;;;;
+164E;CANADIAN SYLLABICS CARRIER SU;Lo;0;L;;;;;N;;;;;
+164F;CANADIAN SYLLABICS CARRIER SO;Lo;0;L;;;;;N;;;;;
+1650;CANADIAN SYLLABICS CARRIER SE;Lo;0;L;;;;;N;;;;;
+1651;CANADIAN SYLLABICS CARRIER SEE;Lo;0;L;;;;;N;;;;;
+1652;CANADIAN SYLLABICS CARRIER SI;Lo;0;L;;;;;N;;;;;
+1653;CANADIAN SYLLABICS CARRIER SA;Lo;0;L;;;;;N;;;;;
+1654;CANADIAN SYLLABICS CARRIER SHU;Lo;0;L;;;;;N;;;;;
+1655;CANADIAN SYLLABICS CARRIER SHO;Lo;0;L;;;;;N;;;;;
+1656;CANADIAN SYLLABICS CARRIER SHE;Lo;0;L;;;;;N;;;;;
+1657;CANADIAN SYLLABICS CARRIER SHEE;Lo;0;L;;;;;N;;;;;
+1658;CANADIAN SYLLABICS CARRIER SHI;Lo;0;L;;;;;N;;;;;
+1659;CANADIAN SYLLABICS CARRIER SHA;Lo;0;L;;;;;N;;;;;
+165A;CANADIAN SYLLABICS CARRIER SH;Lo;0;L;;;;;N;;;;;
+165B;CANADIAN SYLLABICS CARRIER TSU;Lo;0;L;;;;;N;;;;;
+165C;CANADIAN SYLLABICS CARRIER TSO;Lo;0;L;;;;;N;;;;;
+165D;CANADIAN SYLLABICS CARRIER TSE;Lo;0;L;;;;;N;;;;;
+165E;CANADIAN SYLLABICS CARRIER TSEE;Lo;0;L;;;;;N;;;;;
+165F;CANADIAN SYLLABICS CARRIER TSI;Lo;0;L;;;;;N;;;;;
+1660;CANADIAN SYLLABICS CARRIER TSA;Lo;0;L;;;;;N;;;;;
+1661;CANADIAN SYLLABICS CARRIER CHU;Lo;0;L;;;;;N;;;;;
+1662;CANADIAN SYLLABICS CARRIER CHO;Lo;0;L;;;;;N;;;;;
+1663;CANADIAN SYLLABICS CARRIER CHE;Lo;0;L;;;;;N;;;;;
+1664;CANADIAN SYLLABICS CARRIER CHEE;Lo;0;L;;;;;N;;;;;
+1665;CANADIAN SYLLABICS CARRIER CHI;Lo;0;L;;;;;N;;;;;
+1666;CANADIAN SYLLABICS CARRIER CHA;Lo;0;L;;;;;N;;;;;
+1667;CANADIAN SYLLABICS CARRIER TTSU;Lo;0;L;;;;;N;;;;;
+1668;CANADIAN SYLLABICS CARRIER TTSO;Lo;0;L;;;;;N;;;;;
+1669;CANADIAN SYLLABICS CARRIER TTSE;Lo;0;L;;;;;N;;;;;
+166A;CANADIAN SYLLABICS CARRIER TTSEE;Lo;0;L;;;;;N;;;;;
+166B;CANADIAN SYLLABICS CARRIER TTSI;Lo;0;L;;;;;N;;;;;
+166C;CANADIAN SYLLABICS CARRIER TTSA;Lo;0;L;;;;;N;;;;;
+166D;CANADIAN SYLLABICS CHI SIGN;Po;0;L;;;;;N;;;;;
+166E;CANADIAN SYLLABICS FULL STOP;Po;0;L;;;;;N;;;;;
+166F;CANADIAN SYLLABICS QAI;Lo;0;L;;;;;N;;;;;
+1670;CANADIAN SYLLABICS NGAI;Lo;0;L;;;;;N;;;;;
+1671;CANADIAN SYLLABICS NNGI;Lo;0;L;;;;;N;;;;;
+1672;CANADIAN SYLLABICS NNGII;Lo;0;L;;;;;N;;;;;
+1673;CANADIAN SYLLABICS NNGO;Lo;0;L;;;;;N;;;;;
+1674;CANADIAN SYLLABICS NNGOO;Lo;0;L;;;;;N;;;;;
+1675;CANADIAN SYLLABICS NNGA;Lo;0;L;;;;;N;;;;;
+1676;CANADIAN SYLLABICS NNGAA;Lo;0;L;;;;;N;;;;;
+1677;CANADIAN SYLLABICS WOODS-CREE THWEE;Lo;0;L;;;;;N;;;;;
+1678;CANADIAN SYLLABICS WOODS-CREE THWI;Lo;0;L;;;;;N;;;;;
+1679;CANADIAN SYLLABICS WOODS-CREE THWII;Lo;0;L;;;;;N;;;;;
+167A;CANADIAN SYLLABICS WOODS-CREE THWO;Lo;0;L;;;;;N;;;;;
+167B;CANADIAN SYLLABICS WOODS-CREE THWOO;Lo;0;L;;;;;N;;;;;
+167C;CANADIAN SYLLABICS WOODS-CREE THWA;Lo;0;L;;;;;N;;;;;
+167D;CANADIAN SYLLABICS WOODS-CREE THWAA;Lo;0;L;;;;;N;;;;;
+167E;CANADIAN SYLLABICS WOODS-CREE FINAL TH;Lo;0;L;;;;;N;;;;;
+167F;CANADIAN SYLLABICS BLACKFOOT W;Lo;0;L;;;;;N;;;;;
+1680;OGHAM SPACE MARK;Zs;0;WS;;;;;N;;;;;
+1681;OGHAM LETTER BEITH;Lo;0;L;;;;;N;;;;;
+1682;OGHAM LETTER LUIS;Lo;0;L;;;;;N;;;;;
+1683;OGHAM LETTER FEARN;Lo;0;L;;;;;N;;;;;
+1684;OGHAM LETTER SAIL;Lo;0;L;;;;;N;;;;;
+1685;OGHAM LETTER NION;Lo;0;L;;;;;N;;;;;
+1686;OGHAM LETTER UATH;Lo;0;L;;;;;N;;;;;
+1687;OGHAM LETTER DAIR;Lo;0;L;;;;;N;;;;;
+1688;OGHAM LETTER TINNE;Lo;0;L;;;;;N;;;;;
+1689;OGHAM LETTER COLL;Lo;0;L;;;;;N;;;;;
+168A;OGHAM LETTER CEIRT;Lo;0;L;;;;;N;;;;;
+168B;OGHAM LETTER MUIN;Lo;0;L;;;;;N;;;;;
+168C;OGHAM LETTER GORT;Lo;0;L;;;;;N;;;;;
+168D;OGHAM LETTER NGEADAL;Lo;0;L;;;;;N;;;;;
+168E;OGHAM LETTER STRAIF;Lo;0;L;;;;;N;;;;;
+168F;OGHAM LETTER RUIS;Lo;0;L;;;;;N;;;;;
+1690;OGHAM LETTER AILM;Lo;0;L;;;;;N;;;;;
+1691;OGHAM LETTER ONN;Lo;0;L;;;;;N;;;;;
+1692;OGHAM LETTER UR;Lo;0;L;;;;;N;;;;;
+1693;OGHAM LETTER EADHADH;Lo;0;L;;;;;N;;;;;
+1694;OGHAM LETTER IODHADH;Lo;0;L;;;;;N;;;;;
+1695;OGHAM LETTER EABHADH;Lo;0;L;;;;;N;;;;;
+1696;OGHAM LETTER OR;Lo;0;L;;;;;N;;;;;
+1697;OGHAM LETTER UILLEANN;Lo;0;L;;;;;N;;;;;
+1698;OGHAM LETTER IFIN;Lo;0;L;;;;;N;;;;;
+1699;OGHAM LETTER EAMHANCHOLL;Lo;0;L;;;;;N;;;;;
+169A;OGHAM LETTER PEITH;Lo;0;L;;;;;N;;;;;
+169B;OGHAM FEATHER MARK;Ps;0;ON;;;;;Y;;;;;
+169C;OGHAM REVERSED FEATHER MARK;Pe;0;ON;;;;;Y;;;;;
+16A0;RUNIC LETTER FEHU FEOH FE F;Lo;0;L;;;;;N;;;;;
+16A1;RUNIC LETTER V;Lo;0;L;;;;;N;;;;;
+16A2;RUNIC LETTER URUZ UR U;Lo;0;L;;;;;N;;;;;
+16A3;RUNIC LETTER YR;Lo;0;L;;;;;N;;;;;
+16A4;RUNIC LETTER Y;Lo;0;L;;;;;N;;;;;
+16A5;RUNIC LETTER W;Lo;0;L;;;;;N;;;;;
+16A6;RUNIC LETTER THURISAZ THURS THORN;Lo;0;L;;;;;N;;;;;
+16A7;RUNIC LETTER ETH;Lo;0;L;;;;;N;;;;;
+16A8;RUNIC LETTER ANSUZ A;Lo;0;L;;;;;N;;;;;
+16A9;RUNIC LETTER OS O;Lo;0;L;;;;;N;;;;;
+16AA;RUNIC LETTER AC A;Lo;0;L;;;;;N;;;;;
+16AB;RUNIC LETTER AESC;Lo;0;L;;;;;N;;;;;
+16AC;RUNIC LETTER LONG-BRANCH-OSS O;Lo;0;L;;;;;N;;;;;
+16AD;RUNIC LETTER SHORT-TWIG-OSS O;Lo;0;L;;;;;N;;;;;
+16AE;RUNIC LETTER O;Lo;0;L;;;;;N;;;;;
+16AF;RUNIC LETTER OE;Lo;0;L;;;;;N;;;;;
+16B0;RUNIC LETTER ON;Lo;0;L;;;;;N;;;;;
+16B1;RUNIC LETTER RAIDO RAD REID R;Lo;0;L;;;;;N;;;;;
+16B2;RUNIC LETTER KAUNA;Lo;0;L;;;;;N;;;;;
+16B3;RUNIC LETTER CEN;Lo;0;L;;;;;N;;;;;
+16B4;RUNIC LETTER KAUN K;Lo;0;L;;;;;N;;;;;
+16B5;RUNIC LETTER G;Lo;0;L;;;;;N;;;;;
+16B6;RUNIC LETTER ENG;Lo;0;L;;;;;N;;;;;
+16B7;RUNIC LETTER GEBO GYFU G;Lo;0;L;;;;;N;;;;;
+16B8;RUNIC LETTER GAR;Lo;0;L;;;;;N;;;;;
+16B9;RUNIC LETTER WUNJO WYNN W;Lo;0;L;;;;;N;;;;;
+16BA;RUNIC LETTER HAGLAZ H;Lo;0;L;;;;;N;;;;;
+16BB;RUNIC LETTER HAEGL H;Lo;0;L;;;;;N;;;;;
+16BC;RUNIC LETTER LONG-BRANCH-HAGALL H;Lo;0;L;;;;;N;;;;;
+16BD;RUNIC LETTER SHORT-TWIG-HAGALL H;Lo;0;L;;;;;N;;;;;
+16BE;RUNIC LETTER NAUDIZ NYD NAUD N;Lo;0;L;;;;;N;;;;;
+16BF;RUNIC LETTER SHORT-TWIG-NAUD N;Lo;0;L;;;;;N;;;;;
+16C0;RUNIC LETTER DOTTED-N;Lo;0;L;;;;;N;;;;;
+16C1;RUNIC LETTER ISAZ IS ISS I;Lo;0;L;;;;;N;;;;;
+16C2;RUNIC LETTER E;Lo;0;L;;;;;N;;;;;
+16C3;RUNIC LETTER JERAN J;Lo;0;L;;;;;N;;;;;
+16C4;RUNIC LETTER GER;Lo;0;L;;;;;N;;;;;
+16C5;RUNIC LETTER LONG-BRANCH-AR AE;Lo;0;L;;;;;N;;;;;
+16C6;RUNIC LETTER SHORT-TWIG-AR A;Lo;0;L;;;;;N;;;;;
+16C7;RUNIC LETTER IWAZ EOH;Lo;0;L;;;;;N;;;;;
+16C8;RUNIC LETTER PERTHO PEORTH P;Lo;0;L;;;;;N;;;;;
+16C9;RUNIC LETTER ALGIZ EOLHX;Lo;0;L;;;;;N;;;;;
+16CA;RUNIC LETTER SOWILO S;Lo;0;L;;;;;N;;;;;
+16CB;RUNIC LETTER SIGEL LONG-BRANCH-SOL S;Lo;0;L;;;;;N;;;;;
+16CC;RUNIC LETTER SHORT-TWIG-SOL S;Lo;0;L;;;;;N;;;;;
+16CD;RUNIC LETTER C;Lo;0;L;;;;;N;;;;;
+16CE;RUNIC LETTER Z;Lo;0;L;;;;;N;;;;;
+16CF;RUNIC LETTER TIWAZ TIR TYR T;Lo;0;L;;;;;N;;;;;
+16D0;RUNIC LETTER SHORT-TWIG-TYR T;Lo;0;L;;;;;N;;;;;
+16D1;RUNIC LETTER D;Lo;0;L;;;;;N;;;;;
+16D2;RUNIC LETTER BERKANAN BEORC BJARKAN B;Lo;0;L;;;;;N;;;;;
+16D3;RUNIC LETTER SHORT-TWIG-BJARKAN B;Lo;0;L;;;;;N;;;;;
+16D4;RUNIC LETTER DOTTED-P;Lo;0;L;;;;;N;;;;;
+16D5;RUNIC LETTER OPEN-P;Lo;0;L;;;;;N;;;;;
+16D6;RUNIC LETTER EHWAZ EH E;Lo;0;L;;;;;N;;;;;
+16D7;RUNIC LETTER MANNAZ MAN M;Lo;0;L;;;;;N;;;;;
+16D8;RUNIC LETTER LONG-BRANCH-MADR M;Lo;0;L;;;;;N;;;;;
+16D9;RUNIC LETTER SHORT-TWIG-MADR M;Lo;0;L;;;;;N;;;;;
+16DA;RUNIC LETTER LAUKAZ LAGU LOGR L;Lo;0;L;;;;;N;;;;;
+16DB;RUNIC LETTER DOTTED-L;Lo;0;L;;;;;N;;;;;
+16DC;RUNIC LETTER INGWAZ;Lo;0;L;;;;;N;;;;;
+16DD;RUNIC LETTER ING;Lo;0;L;;;;;N;;;;;
+16DE;RUNIC LETTER DAGAZ DAEG D;Lo;0;L;;;;;N;;;;;
+16DF;RUNIC LETTER OTHALAN ETHEL O;Lo;0;L;;;;;N;;;;;
+16E0;RUNIC LETTER EAR;Lo;0;L;;;;;N;;;;;
+16E1;RUNIC LETTER IOR;Lo;0;L;;;;;N;;;;;
+16E2;RUNIC LETTER CWEORTH;Lo;0;L;;;;;N;;;;;
+16E3;RUNIC LETTER CALC;Lo;0;L;;;;;N;;;;;
+16E4;RUNIC LETTER CEALC;Lo;0;L;;;;;N;;;;;
+16E5;RUNIC LETTER STAN;Lo;0;L;;;;;N;;;;;
+16E6;RUNIC LETTER LONG-BRANCH-YR;Lo;0;L;;;;;N;;;;;
+16E7;RUNIC LETTER SHORT-TWIG-YR;Lo;0;L;;;;;N;;;;;
+16E8;RUNIC LETTER ICELANDIC-YR;Lo;0;L;;;;;N;;;;;
+16E9;RUNIC LETTER Q;Lo;0;L;;;;;N;;;;;
+16EA;RUNIC LETTER X;Lo;0;L;;;;;N;;;;;
+16EB;RUNIC SINGLE PUNCTUATION;Po;0;L;;;;;N;;;;;
+16EC;RUNIC MULTIPLE PUNCTUATION;Po;0;L;;;;;N;;;;;
+16ED;RUNIC CROSS PUNCTUATION;Po;0;L;;;;;N;;;;;
+16EE;RUNIC ARLAUG SYMBOL;Nl;0;L;;;;17;N;;;;;
+16EF;RUNIC TVIMADUR SYMBOL;Nl;0;L;;;;18;N;;;;;
+16F0;RUNIC BELGTHOR SYMBOL;Nl;0;L;;;;19;N;;;;;
+1700;TAGALOG LETTER A;Lo;0;L;;;;;N;;;;;
+1701;TAGALOG LETTER I;Lo;0;L;;;;;N;;;;;
+1702;TAGALOG LETTER U;Lo;0;L;;;;;N;;;;;
+1703;TAGALOG LETTER KA;Lo;0;L;;;;;N;;;;;
+1704;TAGALOG LETTER GA;Lo;0;L;;;;;N;;;;;
+1705;TAGALOG LETTER NGA;Lo;0;L;;;;;N;;;;;
+1706;TAGALOG LETTER TA;Lo;0;L;;;;;N;;;;;
+1707;TAGALOG LETTER DA;Lo;0;L;;;;;N;;;;;
+1708;TAGALOG LETTER NA;Lo;0;L;;;;;N;;;;;
+1709;TAGALOG LETTER PA;Lo;0;L;;;;;N;;;;;
+170A;TAGALOG LETTER BA;Lo;0;L;;;;;N;;;;;
+170B;TAGALOG LETTER MA;Lo;0;L;;;;;N;;;;;
+170C;TAGALOG LETTER YA;Lo;0;L;;;;;N;;;;;
+170E;TAGALOG LETTER LA;Lo;0;L;;;;;N;;;;;
+170F;TAGALOG LETTER WA;Lo;0;L;;;;;N;;;;;
+1710;TAGALOG LETTER SA;Lo;0;L;;;;;N;;;;;
+1711;TAGALOG LETTER HA;Lo;0;L;;;;;N;;;;;
+1712;TAGALOG VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;
+1713;TAGALOG VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+1714;TAGALOG SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;
+1720;HANUNOO LETTER A;Lo;0;L;;;;;N;;;;;
+1721;HANUNOO LETTER I;Lo;0;L;;;;;N;;;;;
+1722;HANUNOO LETTER U;Lo;0;L;;;;;N;;;;;
+1723;HANUNOO LETTER KA;Lo;0;L;;;;;N;;;;;
+1724;HANUNOO LETTER GA;Lo;0;L;;;;;N;;;;;
+1725;HANUNOO LETTER NGA;Lo;0;L;;;;;N;;;;;
+1726;HANUNOO LETTER TA;Lo;0;L;;;;;N;;;;;
+1727;HANUNOO LETTER DA;Lo;0;L;;;;;N;;;;;
+1728;HANUNOO LETTER NA;Lo;0;L;;;;;N;;;;;
+1729;HANUNOO LETTER PA;Lo;0;L;;;;;N;;;;;
+172A;HANUNOO LETTER BA;Lo;0;L;;;;;N;;;;;
+172B;HANUNOO LETTER MA;Lo;0;L;;;;;N;;;;;
+172C;HANUNOO LETTER YA;Lo;0;L;;;;;N;;;;;
+172D;HANUNOO LETTER RA;Lo;0;L;;;;;N;;;;;
+172E;HANUNOO LETTER LA;Lo;0;L;;;;;N;;;;;
+172F;HANUNOO LETTER WA;Lo;0;L;;;;;N;;;;;
+1730;HANUNOO LETTER SA;Lo;0;L;;;;;N;;;;;
+1731;HANUNOO LETTER HA;Lo;0;L;;;;;N;;;;;
+1732;HANUNOO VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;
+1733;HANUNOO VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+1734;HANUNOO SIGN PAMUDPOD;Mn;9;NSM;;;;;N;;;;;
+1735;PHILIPPINE SINGLE PUNCTUATION;Po;0;L;;;;;N;;;;;
+1736;PHILIPPINE DOUBLE PUNCTUATION;Po;0;L;;;;;N;;;;;
+1740;BUHID LETTER A;Lo;0;L;;;;;N;;;;;
+1741;BUHID LETTER I;Lo;0;L;;;;;N;;;;;
+1742;BUHID LETTER U;Lo;0;L;;;;;N;;;;;
+1743;BUHID LETTER KA;Lo;0;L;;;;;N;;;;;
+1744;BUHID LETTER GA;Lo;0;L;;;;;N;;;;;
+1745;BUHID LETTER NGA;Lo;0;L;;;;;N;;;;;
+1746;BUHID LETTER TA;Lo;0;L;;;;;N;;;;;
+1747;BUHID LETTER DA;Lo;0;L;;;;;N;;;;;
+1748;BUHID LETTER NA;Lo;0;L;;;;;N;;;;;
+1749;BUHID LETTER PA;Lo;0;L;;;;;N;;;;;
+174A;BUHID LETTER BA;Lo;0;L;;;;;N;;;;;
+174B;BUHID LETTER MA;Lo;0;L;;;;;N;;;;;
+174C;BUHID LETTER YA;Lo;0;L;;;;;N;;;;;
+174D;BUHID LETTER RA;Lo;0;L;;;;;N;;;;;
+174E;BUHID LETTER LA;Lo;0;L;;;;;N;;;;;
+174F;BUHID LETTER WA;Lo;0;L;;;;;N;;;;;
+1750;BUHID LETTER SA;Lo;0;L;;;;;N;;;;;
+1751;BUHID LETTER HA;Lo;0;L;;;;;N;;;;;
+1752;BUHID VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;
+1753;BUHID VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+1760;TAGBANWA LETTER A;Lo;0;L;;;;;N;;;;;
+1761;TAGBANWA LETTER I;Lo;0;L;;;;;N;;;;;
+1762;TAGBANWA LETTER U;Lo;0;L;;;;;N;;;;;
+1763;TAGBANWA LETTER KA;Lo;0;L;;;;;N;;;;;
+1764;TAGBANWA LETTER GA;Lo;0;L;;;;;N;;;;;
+1765;TAGBANWA LETTER NGA;Lo;0;L;;;;;N;;;;;
+1766;TAGBANWA LETTER TA;Lo;0;L;;;;;N;;;;;
+1767;TAGBANWA LETTER DA;Lo;0;L;;;;;N;;;;;
+1768;TAGBANWA LETTER NA;Lo;0;L;;;;;N;;;;;
+1769;TAGBANWA LETTER PA;Lo;0;L;;;;;N;;;;;
+176A;TAGBANWA LETTER BA;Lo;0;L;;;;;N;;;;;
+176B;TAGBANWA LETTER MA;Lo;0;L;;;;;N;;;;;
+176C;TAGBANWA LETTER YA;Lo;0;L;;;;;N;;;;;
+176E;TAGBANWA LETTER LA;Lo;0;L;;;;;N;;;;;
+176F;TAGBANWA LETTER WA;Lo;0;L;;;;;N;;;;;
+1770;TAGBANWA LETTER SA;Lo;0;L;;;;;N;;;;;
+1772;TAGBANWA VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;
+1773;TAGBANWA VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+1780;KHMER LETTER KA;Lo;0;L;;;;;N;;;;;
+1781;KHMER LETTER KHA;Lo;0;L;;;;;N;;;;;
+1782;KHMER LETTER KO;Lo;0;L;;;;;N;;;;;
+1783;KHMER LETTER KHO;Lo;0;L;;;;;N;;;;;
+1784;KHMER LETTER NGO;Lo;0;L;;;;;N;;;;;
+1785;KHMER LETTER CA;Lo;0;L;;;;;N;;;;;
+1786;KHMER LETTER CHA;Lo;0;L;;;;;N;;;;;
+1787;KHMER LETTER CO;Lo;0;L;;;;;N;;;;;
+1788;KHMER LETTER CHO;Lo;0;L;;;;;N;;;;;
+1789;KHMER LETTER NYO;Lo;0;L;;;;;N;;;;;
+178A;KHMER LETTER DA;Lo;0;L;;;;;N;;;;;
+178B;KHMER LETTER TTHA;Lo;0;L;;;;;N;;;;;
+178C;KHMER LETTER DO;Lo;0;L;;;;;N;;;;;
+178D;KHMER LETTER TTHO;Lo;0;L;;;;;N;;;;;
+178E;KHMER LETTER NNO;Lo;0;L;;;;;N;;;;;
+178F;KHMER LETTER TA;Lo;0;L;;;;;N;;;;;
+1790;KHMER LETTER THA;Lo;0;L;;;;;N;;;;;
+1791;KHMER LETTER TO;Lo;0;L;;;;;N;;;;;
+1792;KHMER LETTER THO;Lo;0;L;;;;;N;;;;;
+1793;KHMER LETTER NO;Lo;0;L;;;;;N;;;;;
+1794;KHMER LETTER BA;Lo;0;L;;;;;N;;;;;
+1795;KHMER LETTER PHA;Lo;0;L;;;;;N;;;;;
+1796;KHMER LETTER PO;Lo;0;L;;;;;N;;;;;
+1797;KHMER LETTER PHO;Lo;0;L;;;;;N;;;;;
+1798;KHMER LETTER MO;Lo;0;L;;;;;N;;;;;
+1799;KHMER LETTER YO;Lo;0;L;;;;;N;;;;;
+179A;KHMER LETTER RO;Lo;0;L;;;;;N;;;;;
+179B;KHMER LETTER LO;Lo;0;L;;;;;N;;;;;
+179C;KHMER LETTER VO;Lo;0;L;;;;;N;;;;;
+179D;KHMER LETTER SHA;Lo;0;L;;;;;N;;;;;
+179E;KHMER LETTER SSO;Lo;0;L;;;;;N;;;;;
+179F;KHMER LETTER SA;Lo;0;L;;;;;N;;;;;
+17A0;KHMER LETTER HA;Lo;0;L;;;;;N;;;;;
+17A1;KHMER LETTER LA;Lo;0;L;;;;;N;;;;;
+17A2;KHMER LETTER QA;Lo;0;L;;;;;N;;;;;
+17A3;KHMER INDEPENDENT VOWEL QAQ;Lo;0;L;;;;;N;;;;;
+17A4;KHMER INDEPENDENT VOWEL QAA;Lo;0;L;;;;;N;;;;;
+17A5;KHMER INDEPENDENT VOWEL QI;Lo;0;L;;;;;N;;;;;
+17A6;KHMER INDEPENDENT VOWEL QII;Lo;0;L;;;;;N;;;;;
+17A7;KHMER INDEPENDENT VOWEL QU;Lo;0;L;;;;;N;;;;;
+17A8;KHMER INDEPENDENT VOWEL QUK;Lo;0;L;;;;;N;;;;;
+17A9;KHMER INDEPENDENT VOWEL QUU;Lo;0;L;;;;;N;;;;;
+17AA;KHMER INDEPENDENT VOWEL QUUV;Lo;0;L;;;;;N;;;;;
+17AB;KHMER INDEPENDENT VOWEL RY;Lo;0;L;;;;;N;;;;;
+17AC;KHMER INDEPENDENT VOWEL RYY;Lo;0;L;;;;;N;;;;;
+17AD;KHMER INDEPENDENT VOWEL LY;Lo;0;L;;;;;N;;;;;
+17AE;KHMER INDEPENDENT VOWEL LYY;Lo;0;L;;;;;N;;;;;
+17AF;KHMER INDEPENDENT VOWEL QE;Lo;0;L;;;;;N;;;;;
+17B0;KHMER INDEPENDENT VOWEL QAI;Lo;0;L;;;;;N;;;;;
+17B1;KHMER INDEPENDENT VOWEL QOO TYPE ONE;Lo;0;L;;;;;N;;;;;
+17B2;KHMER INDEPENDENT VOWEL QOO TYPE TWO;Lo;0;L;;;;;N;;;;;
+17B3;KHMER INDEPENDENT VOWEL QAU;Lo;0;L;;;;;N;;;;;
+17B4;KHMER VOWEL INHERENT AQ;Cf;0;L;;;;;N;;;;;
+17B5;KHMER VOWEL INHERENT AA;Cf;0;L;;;;;N;;;;;
+17B6;KHMER VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
+17B7;KHMER VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;
+17B8;KHMER VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;;
+17B9;KHMER VOWEL SIGN Y;Mn;0;NSM;;;;;N;;;;;
+17BA;KHMER VOWEL SIGN YY;Mn;0;NSM;;;;;N;;;;;
+17BB;KHMER VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+17BC;KHMER VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;
+17BD;KHMER VOWEL SIGN UA;Mn;0;NSM;;;;;N;;;;;
+17BE;KHMER VOWEL SIGN OE;Mc;0;L;;;;;N;;;;;
+17BF;KHMER VOWEL SIGN YA;Mc;0;L;;;;;N;;;;;
+17C0;KHMER VOWEL SIGN IE;Mc;0;L;;;;;N;;;;;
+17C1;KHMER VOWEL SIGN E;Mc;0;L;;;;;N;;;;;
+17C2;KHMER VOWEL SIGN AE;Mc;0;L;;;;;N;;;;;
+17C3;KHMER VOWEL SIGN AI;Mc;0;L;;;;;N;;;;;
+17C4;KHMER VOWEL SIGN OO;Mc;0;L;;;;;N;;;;;
+17C5;KHMER VOWEL SIGN AU;Mc;0;L;;;;;N;;;;;
+17C6;KHMER SIGN NIKAHIT;Mn;0;NSM;;;;;N;;;;;
+17C7;KHMER SIGN REAHMUK;Mc;0;L;;;;;N;;;;;
+17C8;KHMER SIGN YUUKALEAPINTU;Mc;0;L;;;;;N;;;;;
+17C9;KHMER SIGN MUUSIKATOAN;Mn;0;NSM;;;;;N;;;;;
+17CA;KHMER SIGN TRIISAP;Mn;0;NSM;;;;;N;;;;;
+17CB;KHMER SIGN BANTOC;Mn;0;NSM;;;;;N;;;;;
+17CC;KHMER SIGN ROBAT;Mn;0;NSM;;;;;N;;;;;
+17CD;KHMER SIGN TOANDAKHIAT;Mn;0;NSM;;;;;N;;;;;
+17CE;KHMER SIGN KAKABAT;Mn;0;NSM;;;;;N;;;;;
+17CF;KHMER SIGN AHSDA;Mn;0;NSM;;;;;N;;;;;
+17D0;KHMER SIGN SAMYOK SANNYA;Mn;0;NSM;;;;;N;;;;;
+17D1;KHMER SIGN VIRIAM;Mn;0;NSM;;;;;N;;;;;
+17D2;KHMER SIGN COENG;Mn;9;NSM;;;;;N;;;;;
+17D3;KHMER SIGN BATHAMASAT;Mn;0;NSM;;;;;N;;;;;
+17D4;KHMER SIGN KHAN;Po;0;L;;;;;N;;;;;
+17D5;KHMER SIGN BARIYOOSAN;Po;0;L;;;;;N;;;;;
+17D6;KHMER SIGN CAMNUC PII KUUH;Po;0;L;;;;;N;;;;;
+17D7;KHMER SIGN LEK TOO;Lm;0;L;;;;;N;;;;;
+17D8;KHMER SIGN BEYYAL;Po;0;L;;;;;N;;;;;
+17D9;KHMER SIGN PHNAEK MUAN;Po;0;L;;;;;N;;;;;
+17DA;KHMER SIGN KOOMUUT;Po;0;L;;;;;N;;;;;
+17DB;KHMER CURRENCY SYMBOL RIEL;Sc;0;ET;;;;;N;;;;;
+17DC;KHMER SIGN AVAKRAHASANYA;Lo;0;L;;;;;N;;;;;
+17DD;KHMER SIGN ATTHACAN;Mn;230;NSM;;;;;N;;;;;
+17E0;KHMER DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+17E1;KHMER DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+17E2;KHMER DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+17E3;KHMER DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+17E4;KHMER DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+17E5;KHMER DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+17E6;KHMER DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+17E7;KHMER DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+17E8;KHMER DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+17E9;KHMER DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+17F0;KHMER SYMBOL LEK ATTAK SON;No;0;ON;;;;0;N;;;;;
+17F1;KHMER SYMBOL LEK ATTAK MUOY;No;0;ON;;;;1;N;;;;;
+17F2;KHMER SYMBOL LEK ATTAK PII;No;0;ON;;;;2;N;;;;;
+17F3;KHMER SYMBOL LEK ATTAK BEI;No;0;ON;;;;3;N;;;;;
+17F4;KHMER SYMBOL LEK ATTAK BUON;No;0;ON;;;;4;N;;;;;
+17F5;KHMER SYMBOL LEK ATTAK PRAM;No;0;ON;;;;5;N;;;;;
+17F6;KHMER SYMBOL LEK ATTAK PRAM-MUOY;No;0;ON;;;;6;N;;;;;
+17F7;KHMER SYMBOL LEK ATTAK PRAM-PII;No;0;ON;;;;7;N;;;;;
+17F8;KHMER SYMBOL LEK ATTAK PRAM-BEI;No;0;ON;;;;8;N;;;;;
+17F9;KHMER SYMBOL LEK ATTAK PRAM-BUON;No;0;ON;;;;9;N;;;;;
+1800;MONGOLIAN BIRGA;Po;0;ON;;;;;N;;;;;
+1801;MONGOLIAN ELLIPSIS;Po;0;ON;;;;;N;;;;;
+1802;MONGOLIAN COMMA;Po;0;ON;;;;;N;;;;;
+1803;MONGOLIAN FULL STOP;Po;0;ON;;;;;N;;;;;
+1804;MONGOLIAN COLON;Po;0;ON;;;;;N;;;;;
+1805;MONGOLIAN FOUR DOTS;Po;0;ON;;;;;N;;;;;
+1806;MONGOLIAN TODO SOFT HYPHEN;Pd;0;ON;;;;;N;;;;;
+1807;MONGOLIAN SIBE SYLLABLE BOUNDARY MARKER;Po;0;ON;;;;;N;;;;;
+1808;MONGOLIAN MANCHU COMMA;Po;0;ON;;;;;N;;;;;
+1809;MONGOLIAN MANCHU FULL STOP;Po;0;ON;;;;;N;;;;;
+180A;MONGOLIAN NIRUGU;Po;0;ON;;;;;N;;;;;
+180B;MONGOLIAN FREE VARIATION SELECTOR ONE;Mn;0;NSM;;;;;N;;;;;
+180C;MONGOLIAN FREE VARIATION SELECTOR TWO;Mn;0;NSM;;;;;N;;;;;
+180D;MONGOLIAN FREE VARIATION SELECTOR THREE;Mn;0;NSM;;;;;N;;;;;
+180E;MONGOLIAN VOWEL SEPARATOR;Zs;0;WS;;;;;N;;;;;
+1810;MONGOLIAN DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+1811;MONGOLIAN DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+1812;MONGOLIAN DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+1813;MONGOLIAN DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+1814;MONGOLIAN DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+1815;MONGOLIAN DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+1816;MONGOLIAN DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+1817;MONGOLIAN DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+1818;MONGOLIAN DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+1819;MONGOLIAN DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+1820;MONGOLIAN LETTER A;Lo;0;L;;;;;N;;;;;
+1821;MONGOLIAN LETTER E;Lo;0;L;;;;;N;;;;;
+1822;MONGOLIAN LETTER I;Lo;0;L;;;;;N;;;;;
+1823;MONGOLIAN LETTER O;Lo;0;L;;;;;N;;;;;
+1824;MONGOLIAN LETTER U;Lo;0;L;;;;;N;;;;;
+1825;MONGOLIAN LETTER OE;Lo;0;L;;;;;N;;;;;
+1826;MONGOLIAN LETTER UE;Lo;0;L;;;;;N;;;;;
+1827;MONGOLIAN LETTER EE;Lo;0;L;;;;;N;;;;;
+1828;MONGOLIAN LETTER NA;Lo;0;L;;;;;N;;;;;
+1829;MONGOLIAN LETTER ANG;Lo;0;L;;;;;N;;;;;
+182A;MONGOLIAN LETTER BA;Lo;0;L;;;;;N;;;;;
+182B;MONGOLIAN LETTER PA;Lo;0;L;;;;;N;;;;;
+182C;MONGOLIAN LETTER QA;Lo;0;L;;;;;N;;;;;
+182D;MONGOLIAN LETTER GA;Lo;0;L;;;;;N;;;;;
+182E;MONGOLIAN LETTER MA;Lo;0;L;;;;;N;;;;;
+182F;MONGOLIAN LETTER LA;Lo;0;L;;;;;N;;;;;
+1830;MONGOLIAN LETTER SA;Lo;0;L;;;;;N;;;;;
+1831;MONGOLIAN LETTER SHA;Lo;0;L;;;;;N;;;;;
+1832;MONGOLIAN LETTER TA;Lo;0;L;;;;;N;;;;;
+1833;MONGOLIAN LETTER DA;Lo;0;L;;;;;N;;;;;
+1834;MONGOLIAN LETTER CHA;Lo;0;L;;;;;N;;;;;
+1835;MONGOLIAN LETTER JA;Lo;0;L;;;;;N;;;;;
+1836;MONGOLIAN LETTER YA;Lo;0;L;;;;;N;;;;;
+1837;MONGOLIAN LETTER RA;Lo;0;L;;;;;N;;;;;
+1838;MONGOLIAN LETTER WA;Lo;0;L;;;;;N;;;;;
+1839;MONGOLIAN LETTER FA;Lo;0;L;;;;;N;;;;;
+183A;MONGOLIAN LETTER KA;Lo;0;L;;;;;N;;;;;
+183B;MONGOLIAN LETTER KHA;Lo;0;L;;;;;N;;;;;
+183C;MONGOLIAN LETTER TSA;Lo;0;L;;;;;N;;;;;
+183D;MONGOLIAN LETTER ZA;Lo;0;L;;;;;N;;;;;
+183E;MONGOLIAN LETTER HAA;Lo;0;L;;;;;N;;;;;
+183F;MONGOLIAN LETTER ZRA;Lo;0;L;;;;;N;;;;;
+1840;MONGOLIAN LETTER LHA;Lo;0;L;;;;;N;;;;;
+1841;MONGOLIAN LETTER ZHI;Lo;0;L;;;;;N;;;;;
+1842;MONGOLIAN LETTER CHI;Lo;0;L;;;;;N;;;;;
+1843;MONGOLIAN LETTER TODO LONG VOWEL SIGN;Lm;0;L;;;;;N;;;;;
+1844;MONGOLIAN LETTER TODO E;Lo;0;L;;;;;N;;;;;
+1845;MONGOLIAN LETTER TODO I;Lo;0;L;;;;;N;;;;;
+1846;MONGOLIAN LETTER TODO O;Lo;0;L;;;;;N;;;;;
+1847;MONGOLIAN LETTER TODO U;Lo;0;L;;;;;N;;;;;
+1848;MONGOLIAN LETTER TODO OE;Lo;0;L;;;;;N;;;;;
+1849;MONGOLIAN LETTER TODO UE;Lo;0;L;;;;;N;;;;;
+184A;MONGOLIAN LETTER TODO ANG;Lo;0;L;;;;;N;;;;;
+184B;MONGOLIAN LETTER TODO BA;Lo;0;L;;;;;N;;;;;
+184C;MONGOLIAN LETTER TODO PA;Lo;0;L;;;;;N;;;;;
+184D;MONGOLIAN LETTER TODO QA;Lo;0;L;;;;;N;;;;;
+184E;MONGOLIAN LETTER TODO GA;Lo;0;L;;;;;N;;;;;
+184F;MONGOLIAN LETTER TODO MA;Lo;0;L;;;;;N;;;;;
+1850;MONGOLIAN LETTER TODO TA;Lo;0;L;;;;;N;;;;;
+1851;MONGOLIAN LETTER TODO DA;Lo;0;L;;;;;N;;;;;
+1852;MONGOLIAN LETTER TODO CHA;Lo;0;L;;;;;N;;;;;
+1853;MONGOLIAN LETTER TODO JA;Lo;0;L;;;;;N;;;;;
+1854;MONGOLIAN LETTER TODO TSA;Lo;0;L;;;;;N;;;;;
+1855;MONGOLIAN LETTER TODO YA;Lo;0;L;;;;;N;;;;;
+1856;MONGOLIAN LETTER TODO WA;Lo;0;L;;;;;N;;;;;
+1857;MONGOLIAN LETTER TODO KA;Lo;0;L;;;;;N;;;;;
+1858;MONGOLIAN LETTER TODO GAA;Lo;0;L;;;;;N;;;;;
+1859;MONGOLIAN LETTER TODO HAA;Lo;0;L;;;;;N;;;;;
+185A;MONGOLIAN LETTER TODO JIA;Lo;0;L;;;;;N;;;;;
+185B;MONGOLIAN LETTER TODO NIA;Lo;0;L;;;;;N;;;;;
+185C;MONGOLIAN LETTER TODO DZA;Lo;0;L;;;;;N;;;;;
+185D;MONGOLIAN LETTER SIBE E;Lo;0;L;;;;;N;;;;;
+185E;MONGOLIAN LETTER SIBE I;Lo;0;L;;;;;N;;;;;
+185F;MONGOLIAN LETTER SIBE IY;Lo;0;L;;;;;N;;;;;
+1860;MONGOLIAN LETTER SIBE UE;Lo;0;L;;;;;N;;;;;
+1861;MONGOLIAN LETTER SIBE U;Lo;0;L;;;;;N;;;;;
+1862;MONGOLIAN LETTER SIBE ANG;Lo;0;L;;;;;N;;;;;
+1863;MONGOLIAN LETTER SIBE KA;Lo;0;L;;;;;N;;;;;
+1864;MONGOLIAN LETTER SIBE GA;Lo;0;L;;;;;N;;;;;
+1865;MONGOLIAN LETTER SIBE HA;Lo;0;L;;;;;N;;;;;
+1866;MONGOLIAN LETTER SIBE PA;Lo;0;L;;;;;N;;;;;
+1867;MONGOLIAN LETTER SIBE SHA;Lo;0;L;;;;;N;;;;;
+1868;MONGOLIAN LETTER SIBE TA;Lo;0;L;;;;;N;;;;;
+1869;MONGOLIAN LETTER SIBE DA;Lo;0;L;;;;;N;;;;;
+186A;MONGOLIAN LETTER SIBE JA;Lo;0;L;;;;;N;;;;;
+186B;MONGOLIAN LETTER SIBE FA;Lo;0;L;;;;;N;;;;;
+186C;MONGOLIAN LETTER SIBE GAA;Lo;0;L;;;;;N;;;;;
+186D;MONGOLIAN LETTER SIBE HAA;Lo;0;L;;;;;N;;;;;
+186E;MONGOLIAN LETTER SIBE TSA;Lo;0;L;;;;;N;;;;;
+186F;MONGOLIAN LETTER SIBE ZA;Lo;0;L;;;;;N;;;;;
+1870;MONGOLIAN LETTER SIBE RAA;Lo;0;L;;;;;N;;;;;
+1871;MONGOLIAN LETTER SIBE CHA;Lo;0;L;;;;;N;;;;;
+1872;MONGOLIAN LETTER SIBE ZHA;Lo;0;L;;;;;N;;;;;
+1873;MONGOLIAN LETTER MANCHU I;Lo;0;L;;;;;N;;;;;
+1874;MONGOLIAN LETTER MANCHU KA;Lo;0;L;;;;;N;;;;;
+1875;MONGOLIAN LETTER MANCHU RA;Lo;0;L;;;;;N;;;;;
+1876;MONGOLIAN LETTER MANCHU FA;Lo;0;L;;;;;N;;;;;
+1877;MONGOLIAN LETTER MANCHU ZHA;Lo;0;L;;;;;N;;;;;
+1880;MONGOLIAN LETTER ALI GALI ANUSVARA ONE;Lo;0;L;;;;;N;;;;;
+1881;MONGOLIAN LETTER ALI GALI VISARGA ONE;Lo;0;L;;;;;N;;;;;
+1882;MONGOLIAN LETTER ALI GALI DAMARU;Lo;0;L;;;;;N;;;;;
+1883;MONGOLIAN LETTER ALI GALI UBADAMA;Lo;0;L;;;;;N;;;;;
+1884;MONGOLIAN LETTER ALI GALI INVERTED UBADAMA;Lo;0;L;;;;;N;;;;;
+1885;MONGOLIAN LETTER ALI GALI BALUDA;Lo;0;L;;;;;N;;;;;
+1886;MONGOLIAN LETTER ALI GALI THREE BALUDA;Lo;0;L;;;;;N;;;;;
+1887;MONGOLIAN LETTER ALI GALI A;Lo;0;L;;;;;N;;;;;
+1888;MONGOLIAN LETTER ALI GALI I;Lo;0;L;;;;;N;;;;;
+1889;MONGOLIAN LETTER ALI GALI KA;Lo;0;L;;;;;N;;;;;
+188A;MONGOLIAN LETTER ALI GALI NGA;Lo;0;L;;;;;N;;;;;
+188B;MONGOLIAN LETTER ALI GALI CA;Lo;0;L;;;;;N;;;;;
+188C;MONGOLIAN LETTER ALI GALI TTA;Lo;0;L;;;;;N;;;;;
+188D;MONGOLIAN LETTER ALI GALI TTHA;Lo;0;L;;;;;N;;;;;
+188E;MONGOLIAN LETTER ALI GALI DDA;Lo;0;L;;;;;N;;;;;
+188F;MONGOLIAN LETTER ALI GALI NNA;Lo;0;L;;;;;N;;;;;
+1890;MONGOLIAN LETTER ALI GALI TA;Lo;0;L;;;;;N;;;;;
+1891;MONGOLIAN LETTER ALI GALI DA;Lo;0;L;;;;;N;;;;;
+1892;MONGOLIAN LETTER ALI GALI PA;Lo;0;L;;;;;N;;;;;
+1893;MONGOLIAN LETTER ALI GALI PHA;Lo;0;L;;;;;N;;;;;
+1894;MONGOLIAN LETTER ALI GALI SSA;Lo;0;L;;;;;N;;;;;
+1895;MONGOLIAN LETTER ALI GALI ZHA;Lo;0;L;;;;;N;;;;;
+1896;MONGOLIAN LETTER ALI GALI ZA;Lo;0;L;;;;;N;;;;;
+1897;MONGOLIAN LETTER ALI GALI AH;Lo;0;L;;;;;N;;;;;
+1898;MONGOLIAN LETTER TODO ALI GALI TA;Lo;0;L;;;;;N;;;;;
+1899;MONGOLIAN LETTER TODO ALI GALI ZHA;Lo;0;L;;;;;N;;;;;
+189A;MONGOLIAN LETTER MANCHU ALI GALI GHA;Lo;0;L;;;;;N;;;;;
+189B;MONGOLIAN LETTER MANCHU ALI GALI NGA;Lo;0;L;;;;;N;;;;;
+189C;MONGOLIAN LETTER MANCHU ALI GALI CA;Lo;0;L;;;;;N;;;;;
+189D;MONGOLIAN LETTER MANCHU ALI GALI JHA;Lo;0;L;;;;;N;;;;;
+189E;MONGOLIAN LETTER MANCHU ALI GALI TTA;Lo;0;L;;;;;N;;;;;
+189F;MONGOLIAN LETTER MANCHU ALI GALI DDHA;Lo;0;L;;;;;N;;;;;
+18A0;MONGOLIAN LETTER MANCHU ALI GALI TA;Lo;0;L;;;;;N;;;;;
+18A1;MONGOLIAN LETTER MANCHU ALI GALI DHA;Lo;0;L;;;;;N;;;;;
+18A2;MONGOLIAN LETTER MANCHU ALI GALI SSA;Lo;0;L;;;;;N;;;;;
+18A3;MONGOLIAN LETTER MANCHU ALI GALI CYA;Lo;0;L;;;;;N;;;;;
+18A4;MONGOLIAN LETTER MANCHU ALI GALI ZHA;Lo;0;L;;;;;N;;;;;
+18A5;MONGOLIAN LETTER MANCHU ALI GALI ZA;Lo;0;L;;;;;N;;;;;
+18A6;MONGOLIAN LETTER ALI GALI HALF U;Lo;0;L;;;;;N;;;;;
+18A7;MONGOLIAN LETTER ALI GALI HALF YA;Lo;0;L;;;;;N;;;;;
+18A8;MONGOLIAN LETTER MANCHU ALI GALI BHA;Lo;0;L;;;;;N;;;;;
+18A9;MONGOLIAN LETTER ALI GALI DAGALGA;Mn;228;NSM;;;;;N;;;;;
+18AA;MONGOLIAN LETTER MANCHU ALI GALI LHA;Lo;0;L;;;;;N;;;;;
+18B0;CANADIAN SYLLABICS OY;Lo;0;L;;;;;N;;;;;
+18B1;CANADIAN SYLLABICS AY;Lo;0;L;;;;;N;;;;;
+18B2;CANADIAN SYLLABICS AAY;Lo;0;L;;;;;N;;;;;
+18B3;CANADIAN SYLLABICS WAY;Lo;0;L;;;;;N;;;;;
+18B4;CANADIAN SYLLABICS POY;Lo;0;L;;;;;N;;;;;
+18B5;CANADIAN SYLLABICS PAY;Lo;0;L;;;;;N;;;;;
+18B6;CANADIAN SYLLABICS PWOY;Lo;0;L;;;;;N;;;;;
+18B7;CANADIAN SYLLABICS TAY;Lo;0;L;;;;;N;;;;;
+18B8;CANADIAN SYLLABICS KAY;Lo;0;L;;;;;N;;;;;
+18B9;CANADIAN SYLLABICS KWAY;Lo;0;L;;;;;N;;;;;
+18BA;CANADIAN SYLLABICS MAY;Lo;0;L;;;;;N;;;;;
+18BB;CANADIAN SYLLABICS NOY;Lo;0;L;;;;;N;;;;;
+18BC;CANADIAN SYLLABICS NAY;Lo;0;L;;;;;N;;;;;
+18BD;CANADIAN SYLLABICS LAY;Lo;0;L;;;;;N;;;;;
+18BE;CANADIAN SYLLABICS SOY;Lo;0;L;;;;;N;;;;;
+18BF;CANADIAN SYLLABICS SAY;Lo;0;L;;;;;N;;;;;
+18C0;CANADIAN SYLLABICS SHOY;Lo;0;L;;;;;N;;;;;
+18C1;CANADIAN SYLLABICS SHAY;Lo;0;L;;;;;N;;;;;
+18C2;CANADIAN SYLLABICS SHWOY;Lo;0;L;;;;;N;;;;;
+18C3;CANADIAN SYLLABICS YOY;Lo;0;L;;;;;N;;;;;
+18C4;CANADIAN SYLLABICS YAY;Lo;0;L;;;;;N;;;;;
+18C5;CANADIAN SYLLABICS RAY;Lo;0;L;;;;;N;;;;;
+18C6;CANADIAN SYLLABICS NWI;Lo;0;L;;;;;N;;;;;
+18C7;CANADIAN SYLLABICS OJIBWAY NWI;Lo;0;L;;;;;N;;;;;
+18C8;CANADIAN SYLLABICS NWII;Lo;0;L;;;;;N;;;;;
+18C9;CANADIAN SYLLABICS OJIBWAY NWII;Lo;0;L;;;;;N;;;;;
+18CA;CANADIAN SYLLABICS NWO;Lo;0;L;;;;;N;;;;;
+18CB;CANADIAN SYLLABICS OJIBWAY NWO;Lo;0;L;;;;;N;;;;;
+18CC;CANADIAN SYLLABICS NWOO;Lo;0;L;;;;;N;;;;;
+18CD;CANADIAN SYLLABICS OJIBWAY NWOO;Lo;0;L;;;;;N;;;;;
+18CE;CANADIAN SYLLABICS RWEE;Lo;0;L;;;;;N;;;;;
+18CF;CANADIAN SYLLABICS RWI;Lo;0;L;;;;;N;;;;;
+18D0;CANADIAN SYLLABICS RWII;Lo;0;L;;;;;N;;;;;
+18D1;CANADIAN SYLLABICS RWO;Lo;0;L;;;;;N;;;;;
+18D2;CANADIAN SYLLABICS RWOO;Lo;0;L;;;;;N;;;;;
+18D3;CANADIAN SYLLABICS RWA;Lo;0;L;;;;;N;;;;;
+18D4;CANADIAN SYLLABICS OJIBWAY P;Lo;0;L;;;;;N;;;;;
+18D5;CANADIAN SYLLABICS OJIBWAY T;Lo;0;L;;;;;N;;;;;
+18D6;CANADIAN SYLLABICS OJIBWAY K;Lo;0;L;;;;;N;;;;;
+18D7;CANADIAN SYLLABICS OJIBWAY C;Lo;0;L;;;;;N;;;;;
+18D8;CANADIAN SYLLABICS OJIBWAY M;Lo;0;L;;;;;N;;;;;
+18D9;CANADIAN SYLLABICS OJIBWAY N;Lo;0;L;;;;;N;;;;;
+18DA;CANADIAN SYLLABICS OJIBWAY S;Lo;0;L;;;;;N;;;;;
+18DB;CANADIAN SYLLABICS OJIBWAY SH;Lo;0;L;;;;;N;;;;;
+18DC;CANADIAN SYLLABICS EASTERN W;Lo;0;L;;;;;N;;;;;
+18DD;CANADIAN SYLLABICS WESTERN W;Lo;0;L;;;;;N;;;;;
+18DE;CANADIAN SYLLABICS FINAL SMALL RING;Lo;0;L;;;;;N;;;;;
+18DF;CANADIAN SYLLABICS FINAL RAISED DOT;Lo;0;L;;;;;N;;;;;
+18E0;CANADIAN SYLLABICS R-CREE RWE;Lo;0;L;;;;;N;;;;;
+18E1;CANADIAN SYLLABICS WEST-CREE LOO;Lo;0;L;;;;;N;;;;;
+18E2;CANADIAN SYLLABICS WEST-CREE LAA;Lo;0;L;;;;;N;;;;;
+18E3;CANADIAN SYLLABICS THWE;Lo;0;L;;;;;N;;;;;
+18E4;CANADIAN SYLLABICS THWA;Lo;0;L;;;;;N;;;;;
+18E5;CANADIAN SYLLABICS TTHWE;Lo;0;L;;;;;N;;;;;
+18E6;CANADIAN SYLLABICS TTHOO;Lo;0;L;;;;;N;;;;;
+18E7;CANADIAN SYLLABICS TTHAA;Lo;0;L;;;;;N;;;;;
+18E8;CANADIAN SYLLABICS TLHWE;Lo;0;L;;;;;N;;;;;
+18E9;CANADIAN SYLLABICS TLHOO;Lo;0;L;;;;;N;;;;;
+18EA;CANADIAN SYLLABICS SAYISI SHWE;Lo;0;L;;;;;N;;;;;
+18EB;CANADIAN SYLLABICS SAYISI SHOO;Lo;0;L;;;;;N;;;;;
+18EC;CANADIAN SYLLABICS SAYISI HOO;Lo;0;L;;;;;N;;;;;
+18ED;CANADIAN SYLLABICS CARRIER GWU;Lo;0;L;;;;;N;;;;;
+18EE;CANADIAN SYLLABICS CARRIER DENE GEE;Lo;0;L;;;;;N;;;;;
+18EF;CANADIAN SYLLABICS CARRIER GAA;Lo;0;L;;;;;N;;;;;
+18F0;CANADIAN SYLLABICS CARRIER GWA;Lo;0;L;;;;;N;;;;;
+18F1;CANADIAN SYLLABICS SAYISI JUU;Lo;0;L;;;;;N;;;;;
+18F2;CANADIAN SYLLABICS CARRIER JWA;Lo;0;L;;;;;N;;;;;
+18F3;CANADIAN SYLLABICS BEAVER DENE L;Lo;0;L;;;;;N;;;;;
+18F4;CANADIAN SYLLABICS BEAVER DENE R;Lo;0;L;;;;;N;;;;;
+18F5;CANADIAN SYLLABICS CARRIER DENTAL S;Lo;0;L;;;;;N;;;;;
+1900;LIMBU VOWEL-CARRIER LETTER;Lo;0;L;;;;;N;;;;;
+1901;LIMBU LETTER KA;Lo;0;L;;;;;N;;;;;
+1902;LIMBU LETTER KHA;Lo;0;L;;;;;N;;;;;
+1903;LIMBU LETTER GA;Lo;0;L;;;;;N;;;;;
+1904;LIMBU LETTER GHA;Lo;0;L;;;;;N;;;;;
+1905;LIMBU LETTER NGA;Lo;0;L;;;;;N;;;;;
+1906;LIMBU LETTER CA;Lo;0;L;;;;;N;;;;;
+1907;LIMBU LETTER CHA;Lo;0;L;;;;;N;;;;;
+1908;LIMBU LETTER JA;Lo;0;L;;;;;N;;;;;
+1909;LIMBU LETTER JHA;Lo;0;L;;;;;N;;;;;
+190A;LIMBU LETTER YAN;Lo;0;L;;;;;N;;;;;
+190B;LIMBU LETTER TA;Lo;0;L;;;;;N;;;;;
+190C;LIMBU LETTER THA;Lo;0;L;;;;;N;;;;;
+190D;LIMBU LETTER DA;Lo;0;L;;;;;N;;;;;
+190E;LIMBU LETTER DHA;Lo;0;L;;;;;N;;;;;
+190F;LIMBU LETTER NA;Lo;0;L;;;;;N;;;;;
+1910;LIMBU LETTER PA;Lo;0;L;;;;;N;;;;;
+1911;LIMBU LETTER PHA;Lo;0;L;;;;;N;;;;;
+1912;LIMBU LETTER BA;Lo;0;L;;;;;N;;;;;
+1913;LIMBU LETTER BHA;Lo;0;L;;;;;N;;;;;
+1914;LIMBU LETTER MA;Lo;0;L;;;;;N;;;;;
+1915;LIMBU LETTER YA;Lo;0;L;;;;;N;;;;;
+1916;LIMBU LETTER RA;Lo;0;L;;;;;N;;;;;
+1917;LIMBU LETTER LA;Lo;0;L;;;;;N;;;;;
+1918;LIMBU LETTER WA;Lo;0;L;;;;;N;;;;;
+1919;LIMBU LETTER SHA;Lo;0;L;;;;;N;;;;;
+191A;LIMBU LETTER SSA;Lo;0;L;;;;;N;;;;;
+191B;LIMBU LETTER SA;Lo;0;L;;;;;N;;;;;
+191C;LIMBU LETTER HA;Lo;0;L;;;;;N;;;;;
+1920;LIMBU VOWEL SIGN A;Mn;0;NSM;;;;;N;;;;;
+1921;LIMBU VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;
+1922;LIMBU VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+1923;LIMBU VOWEL SIGN EE;Mc;0;L;;;;;N;;;;;
+1924;LIMBU VOWEL SIGN AI;Mc;0;L;;;;;N;;;;;
+1925;LIMBU VOWEL SIGN OO;Mc;0;L;;;;;N;;;;;
+1926;LIMBU VOWEL SIGN AU;Mc;0;L;;;;;N;;;;;
+1927;LIMBU VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;;
+1928;LIMBU VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;;
+1929;LIMBU SUBJOINED LETTER YA;Mc;0;L;;;;;N;;;;;
+192A;LIMBU SUBJOINED LETTER RA;Mc;0;L;;;;;N;;;;;
+192B;LIMBU SUBJOINED LETTER WA;Mc;0;L;;;;;N;;;;;
+1930;LIMBU SMALL LETTER KA;Mc;0;L;;;;;N;;;;;
+1931;LIMBU SMALL LETTER NGA;Mc;0;L;;;;;N;;;;;
+1932;LIMBU SMALL LETTER ANUSVARA;Mn;0;NSM;;;;;N;;;;;
+1933;LIMBU SMALL LETTER TA;Mc;0;L;;;;;N;;;;;
+1934;LIMBU SMALL LETTER NA;Mc;0;L;;;;;N;;;;;
+1935;LIMBU SMALL LETTER PA;Mc;0;L;;;;;N;;;;;
+1936;LIMBU SMALL LETTER MA;Mc;0;L;;;;;N;;;;;
+1937;LIMBU SMALL LETTER RA;Mc;0;L;;;;;N;;;;;
+1938;LIMBU SMALL LETTER LA;Mc;0;L;;;;;N;;;;;
+1939;LIMBU SIGN MUKPHRENG;Mn;222;NSM;;;;;N;;;;;
+193A;LIMBU SIGN KEMPHRENG;Mn;230;NSM;;;;;N;;;;;
+193B;LIMBU SIGN SA-I;Mn;220;NSM;;;;;N;;;;;
+1940;LIMBU SIGN LOO;So;0;ON;;;;;N;;;;;
+1944;LIMBU EXCLAMATION MARK;Po;0;ON;;;;;N;;;;;
+1945;LIMBU QUESTION MARK;Po;0;ON;;;;;N;;;;;
+1946;LIMBU DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+1947;LIMBU DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+1948;LIMBU DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+1949;LIMBU DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+194A;LIMBU DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+194B;LIMBU DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+194C;LIMBU DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+194D;LIMBU DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+194E;LIMBU DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+194F;LIMBU DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+1950;TAI LE LETTER KA;Lo;0;L;;;;;N;;;;;
+1951;TAI LE LETTER XA;Lo;0;L;;;;;N;;;;;
+1952;TAI LE LETTER NGA;Lo;0;L;;;;;N;;;;;
+1953;TAI LE LETTER TSA;Lo;0;L;;;;;N;;;;;
+1954;TAI LE LETTER SA;Lo;0;L;;;;;N;;;;;
+1955;TAI LE LETTER YA;Lo;0;L;;;;;N;;;;;
+1956;TAI LE LETTER TA;Lo;0;L;;;;;N;;;;;
+1957;TAI LE LETTER THA;Lo;0;L;;;;;N;;;;;
+1958;TAI LE LETTER LA;Lo;0;L;;;;;N;;;;;
+1959;TAI LE LETTER PA;Lo;0;L;;;;;N;;;;;
+195A;TAI LE LETTER PHA;Lo;0;L;;;;;N;;;;;
+195B;TAI LE LETTER MA;Lo;0;L;;;;;N;;;;;
+195C;TAI LE LETTER FA;Lo;0;L;;;;;N;;;;;
+195D;TAI LE LETTER VA;Lo;0;L;;;;;N;;;;;
+195E;TAI LE LETTER HA;Lo;0;L;;;;;N;;;;;
+195F;TAI LE LETTER QA;Lo;0;L;;;;;N;;;;;
+1960;TAI LE LETTER KHA;Lo;0;L;;;;;N;;;;;
+1961;TAI LE LETTER TSHA;Lo;0;L;;;;;N;;;;;
+1962;TAI LE LETTER NA;Lo;0;L;;;;;N;;;;;
+1963;TAI LE LETTER A;Lo;0;L;;;;;N;;;;;
+1964;TAI LE LETTER I;Lo;0;L;;;;;N;;;;;
+1965;TAI LE LETTER EE;Lo;0;L;;;;;N;;;;;
+1966;TAI LE LETTER EH;Lo;0;L;;;;;N;;;;;
+1967;TAI LE LETTER U;Lo;0;L;;;;;N;;;;;
+1968;TAI LE LETTER OO;Lo;0;L;;;;;N;;;;;
+1969;TAI LE LETTER O;Lo;0;L;;;;;N;;;;;
+196A;TAI LE LETTER UE;Lo;0;L;;;;;N;;;;;
+196B;TAI LE LETTER E;Lo;0;L;;;;;N;;;;;
+196C;TAI LE LETTER AUE;Lo;0;L;;;;;N;;;;;
+196D;TAI LE LETTER AI;Lo;0;L;;;;;N;;;;;
+1970;TAI LE LETTER TONE-2;Lo;0;L;;;;;N;;;;;
+1971;TAI LE LETTER TONE-3;Lo;0;L;;;;;N;;;;;
+1972;TAI LE LETTER TONE-4;Lo;0;L;;;;;N;;;;;
+1973;TAI LE LETTER TONE-5;Lo;0;L;;;;;N;;;;;
+1974;TAI LE LETTER TONE-6;Lo;0;L;;;;;N;;;;;
+1980;NEW TAI LUE LETTER HIGH QA;Lo;0;L;;;;;N;;;;;
+1981;NEW TAI LUE LETTER LOW QA;Lo;0;L;;;;;N;;;;;
+1982;NEW TAI LUE LETTER HIGH KA;Lo;0;L;;;;;N;;;;;
+1983;NEW TAI LUE LETTER HIGH XA;Lo;0;L;;;;;N;;;;;
+1984;NEW TAI LUE LETTER HIGH NGA;Lo;0;L;;;;;N;;;;;
+1985;NEW TAI LUE LETTER LOW KA;Lo;0;L;;;;;N;;;;;
+1986;NEW TAI LUE LETTER LOW XA;Lo;0;L;;;;;N;;;;;
+1987;NEW TAI LUE LETTER LOW NGA;Lo;0;L;;;;;N;;;;;
+1988;NEW TAI LUE LETTER HIGH TSA;Lo;0;L;;;;;N;;;;;
+1989;NEW TAI LUE LETTER HIGH SA;Lo;0;L;;;;;N;;;;;
+198A;NEW TAI LUE LETTER HIGH YA;Lo;0;L;;;;;N;;;;;
+198B;NEW TAI LUE LETTER LOW TSA;Lo;0;L;;;;;N;;;;;
+198C;NEW TAI LUE LETTER LOW SA;Lo;0;L;;;;;N;;;;;
+198D;NEW TAI LUE LETTER LOW YA;Lo;0;L;;;;;N;;;;;
+198E;NEW TAI LUE LETTER HIGH TA;Lo;0;L;;;;;N;;;;;
+198F;NEW TAI LUE LETTER HIGH THA;Lo;0;L;;;;;N;;;;;
+1990;NEW TAI LUE LETTER HIGH NA;Lo;0;L;;;;;N;;;;;
+1991;NEW TAI LUE LETTER LOW TA;Lo;0;L;;;;;N;;;;;
+1992;NEW TAI LUE LETTER LOW THA;Lo;0;L;;;;;N;;;;;
+1993;NEW TAI LUE LETTER LOW NA;Lo;0;L;;;;;N;;;;;
+1994;NEW TAI LUE LETTER HIGH PA;Lo;0;L;;;;;N;;;;;
+1995;NEW TAI LUE LETTER HIGH PHA;Lo;0;L;;;;;N;;;;;
+1996;NEW TAI LUE LETTER HIGH MA;Lo;0;L;;;;;N;;;;;
+1997;NEW TAI LUE LETTER LOW PA;Lo;0;L;;;;;N;;;;;
+1998;NEW TAI LUE LETTER LOW PHA;Lo;0;L;;;;;N;;;;;
+1999;NEW TAI LUE LETTER LOW MA;Lo;0;L;;;;;N;;;;;
+199A;NEW TAI LUE LETTER HIGH FA;Lo;0;L;;;;;N;;;;;
+199B;NEW TAI LUE LETTER HIGH VA;Lo;0;L;;;;;N;;;;;
+199C;NEW TAI LUE LETTER HIGH LA;Lo;0;L;;;;;N;;;;;
+199D;NEW TAI LUE LETTER LOW FA;Lo;0;L;;;;;N;;;;;
+199E;NEW TAI LUE LETTER LOW VA;Lo;0;L;;;;;N;;;;;
+199F;NEW TAI LUE LETTER LOW LA;Lo;0;L;;;;;N;;;;;
+19A0;NEW TAI LUE LETTER HIGH HA;Lo;0;L;;;;;N;;;;;
+19A1;NEW TAI LUE LETTER HIGH DA;Lo;0;L;;;;;N;;;;;
+19A2;NEW TAI LUE LETTER HIGH BA;Lo;0;L;;;;;N;;;;;
+19A3;NEW TAI LUE LETTER LOW HA;Lo;0;L;;;;;N;;;;;
+19A4;NEW TAI LUE LETTER LOW DA;Lo;0;L;;;;;N;;;;;
+19A5;NEW TAI LUE LETTER LOW BA;Lo;0;L;;;;;N;;;;;
+19A6;NEW TAI LUE LETTER HIGH KVA;Lo;0;L;;;;;N;;;;;
+19A7;NEW TAI LUE LETTER HIGH XVA;Lo;0;L;;;;;N;;;;;
+19A8;NEW TAI LUE LETTER LOW KVA;Lo;0;L;;;;;N;;;;;
+19A9;NEW TAI LUE LETTER LOW XVA;Lo;0;L;;;;;N;;;;;
+19AA;NEW TAI LUE LETTER HIGH SUA;Lo;0;L;;;;;N;;;;;
+19AB;NEW TAI LUE LETTER LOW SUA;Lo;0;L;;;;;N;;;;;
+19B0;NEW TAI LUE VOWEL SIGN VOWEL SHORTENER;Mc;0;L;;;;;N;;;;;
+19B1;NEW TAI LUE VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
+19B2;NEW TAI LUE VOWEL SIGN II;Mc;0;L;;;;;N;;;;;
+19B3;NEW TAI LUE VOWEL SIGN U;Mc;0;L;;;;;N;;;;;
+19B4;NEW TAI LUE VOWEL SIGN UU;Mc;0;L;;;;;N;;;;;
+19B5;NEW TAI LUE VOWEL SIGN E;Mc;0;L;;;;;N;;;;;
+19B6;NEW TAI LUE VOWEL SIGN AE;Mc;0;L;;;;;N;;;;;
+19B7;NEW TAI LUE VOWEL SIGN O;Mc;0;L;;;;;N;;;;;
+19B8;NEW TAI LUE VOWEL SIGN OA;Mc;0;L;;;;;N;;;;;
+19B9;NEW TAI LUE VOWEL SIGN UE;Mc;0;L;;;;;N;;;;;
+19BA;NEW TAI LUE VOWEL SIGN AY;Mc;0;L;;;;;N;;;;;
+19BB;NEW TAI LUE VOWEL SIGN AAY;Mc;0;L;;;;;N;;;;;
+19BC;NEW TAI LUE VOWEL SIGN UY;Mc;0;L;;;;;N;;;;;
+19BD;NEW TAI LUE VOWEL SIGN OY;Mc;0;L;;;;;N;;;;;
+19BE;NEW TAI LUE VOWEL SIGN OAY;Mc;0;L;;;;;N;;;;;
+19BF;NEW TAI LUE VOWEL SIGN UEY;Mc;0;L;;;;;N;;;;;
+19C0;NEW TAI LUE VOWEL SIGN IY;Mc;0;L;;;;;N;;;;;
+19C1;NEW TAI LUE LETTER FINAL V;Lo;0;L;;;;;N;;;;;
+19C2;NEW TAI LUE LETTER FINAL NG;Lo;0;L;;;;;N;;;;;
+19C3;NEW TAI LUE LETTER FINAL N;Lo;0;L;;;;;N;;;;;
+19C4;NEW TAI LUE LETTER FINAL M;Lo;0;L;;;;;N;;;;;
+19C5;NEW TAI LUE LETTER FINAL K;Lo;0;L;;;;;N;;;;;
+19C6;NEW TAI LUE LETTER FINAL D;Lo;0;L;;;;;N;;;;;
+19C7;NEW TAI LUE LETTER FINAL B;Lo;0;L;;;;;N;;;;;
+19C8;NEW TAI LUE TONE MARK-1;Mc;0;L;;;;;N;;;;;
+19C9;NEW TAI LUE TONE MARK-2;Mc;0;L;;;;;N;;;;;
+19D0;NEW TAI LUE DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+19D1;NEW TAI LUE DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+19D2;NEW TAI LUE DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+19D3;NEW TAI LUE DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+19D4;NEW TAI LUE DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+19D5;NEW TAI LUE DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+19D6;NEW TAI LUE DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+19D7;NEW TAI LUE DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+19D8;NEW TAI LUE DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+19D9;NEW TAI LUE DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+19DA;NEW TAI LUE THAM DIGIT ONE;No;0;L;;;1;1;N;;;;;
+19DE;NEW TAI LUE SIGN LAE;So;0;ON;;;;;N;;;;;
+19DF;NEW TAI LUE SIGN LAEV;So;0;ON;;;;;N;;;;;
+19E0;KHMER SYMBOL PATHAMASAT;So;0;ON;;;;;N;;;;;
+19E1;KHMER SYMBOL MUOY KOET;So;0;ON;;;;;N;;;;;
+19E2;KHMER SYMBOL PII KOET;So;0;ON;;;;;N;;;;;
+19E3;KHMER SYMBOL BEI KOET;So;0;ON;;;;;N;;;;;
+19E4;KHMER SYMBOL BUON KOET;So;0;ON;;;;;N;;;;;
+19E5;KHMER SYMBOL PRAM KOET;So;0;ON;;;;;N;;;;;
+19E6;KHMER SYMBOL PRAM-MUOY KOET;So;0;ON;;;;;N;;;;;
+19E7;KHMER SYMBOL PRAM-PII KOET;So;0;ON;;;;;N;;;;;
+19E8;KHMER SYMBOL PRAM-BEI KOET;So;0;ON;;;;;N;;;;;
+19E9;KHMER SYMBOL PRAM-BUON KOET;So;0;ON;;;;;N;;;;;
+19EA;KHMER SYMBOL DAP KOET;So;0;ON;;;;;N;;;;;
+19EB;KHMER SYMBOL DAP-MUOY KOET;So;0;ON;;;;;N;;;;;
+19EC;KHMER SYMBOL DAP-PII KOET;So;0;ON;;;;;N;;;;;
+19ED;KHMER SYMBOL DAP-BEI KOET;So;0;ON;;;;;N;;;;;
+19EE;KHMER SYMBOL DAP-BUON KOET;So;0;ON;;;;;N;;;;;
+19EF;KHMER SYMBOL DAP-PRAM KOET;So;0;ON;;;;;N;;;;;
+19F0;KHMER SYMBOL TUTEYASAT;So;0;ON;;;;;N;;;;;
+19F1;KHMER SYMBOL MUOY ROC;So;0;ON;;;;;N;;;;;
+19F2;KHMER SYMBOL PII ROC;So;0;ON;;;;;N;;;;;
+19F3;KHMER SYMBOL BEI ROC;So;0;ON;;;;;N;;;;;
+19F4;KHMER SYMBOL BUON ROC;So;0;ON;;;;;N;;;;;
+19F5;KHMER SYMBOL PRAM ROC;So;0;ON;;;;;N;;;;;
+19F6;KHMER SYMBOL PRAM-MUOY ROC;So;0;ON;;;;;N;;;;;
+19F7;KHMER SYMBOL PRAM-PII ROC;So;0;ON;;;;;N;;;;;
+19F8;KHMER SYMBOL PRAM-BEI ROC;So;0;ON;;;;;N;;;;;
+19F9;KHMER SYMBOL PRAM-BUON ROC;So;0;ON;;;;;N;;;;;
+19FA;KHMER SYMBOL DAP ROC;So;0;ON;;;;;N;;;;;
+19FB;KHMER SYMBOL DAP-MUOY ROC;So;0;ON;;;;;N;;;;;
+19FC;KHMER SYMBOL DAP-PII ROC;So;0;ON;;;;;N;;;;;
+19FD;KHMER SYMBOL DAP-BEI ROC;So;0;ON;;;;;N;;;;;
+19FE;KHMER SYMBOL DAP-BUON ROC;So;0;ON;;;;;N;;;;;
+19FF;KHMER SYMBOL DAP-PRAM ROC;So;0;ON;;;;;N;;;;;
+1A00;BUGINESE LETTER KA;Lo;0;L;;;;;N;;;;;
+1A01;BUGINESE LETTER GA;Lo;0;L;;;;;N;;;;;
+1A02;BUGINESE LETTER NGA;Lo;0;L;;;;;N;;;;;
+1A03;BUGINESE LETTER NGKA;Lo;0;L;;;;;N;;;;;
+1A04;BUGINESE LETTER PA;Lo;0;L;;;;;N;;;;;
+1A05;BUGINESE LETTER BA;Lo;0;L;;;;;N;;;;;
+1A06;BUGINESE LETTER MA;Lo;0;L;;;;;N;;;;;
+1A07;BUGINESE LETTER MPA;Lo;0;L;;;;;N;;;;;
+1A08;BUGINESE LETTER TA;Lo;0;L;;;;;N;;;;;
+1A09;BUGINESE LETTER DA;Lo;0;L;;;;;N;;;;;
+1A0A;BUGINESE LETTER NA;Lo;0;L;;;;;N;;;;;
+1A0B;BUGINESE LETTER NRA;Lo;0;L;;;;;N;;;;;
+1A0C;BUGINESE LETTER CA;Lo;0;L;;;;;N;;;;;
+1A0D;BUGINESE LETTER JA;Lo;0;L;;;;;N;;;;;
+1A0E;BUGINESE LETTER NYA;Lo;0;L;;;;;N;;;;;
+1A0F;BUGINESE LETTER NYCA;Lo;0;L;;;;;N;;;;;
+1A10;BUGINESE LETTER YA;Lo;0;L;;;;;N;;;;;
+1A11;BUGINESE LETTER RA;Lo;0;L;;;;;N;;;;;
+1A12;BUGINESE LETTER LA;Lo;0;L;;;;;N;;;;;
+1A13;BUGINESE LETTER VA;Lo;0;L;;;;;N;;;;;
+1A14;BUGINESE LETTER SA;Lo;0;L;;;;;N;;;;;
+1A15;BUGINESE LETTER A;Lo;0;L;;;;;N;;;;;
+1A16;BUGINESE LETTER HA;Lo;0;L;;;;;N;;;;;
+1A17;BUGINESE VOWEL SIGN I;Mn;230;NSM;;;;;N;;;;;
+1A18;BUGINESE VOWEL SIGN U;Mn;220;NSM;;;;;N;;;;;
+1A19;BUGINESE VOWEL SIGN E;Mc;0;L;;;;;N;;;;;
+1A1A;BUGINESE VOWEL SIGN O;Mc;0;L;;;;;N;;;;;
+1A1B;BUGINESE VOWEL SIGN AE;Mc;0;L;;;;;N;;;;;
+1A1E;BUGINESE PALLAWA;Po;0;L;;;;;N;;;;;
+1A1F;BUGINESE END OF SECTION;Po;0;L;;;;;N;;;;;
+1A20;TAI THAM LETTER HIGH KA;Lo;0;L;;;;;N;;;;;
+1A21;TAI THAM LETTER HIGH KHA;Lo;0;L;;;;;N;;;;;
+1A22;TAI THAM LETTER HIGH KXA;Lo;0;L;;;;;N;;;;;
+1A23;TAI THAM LETTER LOW KA;Lo;0;L;;;;;N;;;;;
+1A24;TAI THAM LETTER LOW KXA;Lo;0;L;;;;;N;;;;;
+1A25;TAI THAM LETTER LOW KHA;Lo;0;L;;;;;N;;;;;
+1A26;TAI THAM LETTER NGA;Lo;0;L;;;;;N;;;;;
+1A27;TAI THAM LETTER HIGH CA;Lo;0;L;;;;;N;;;;;
+1A28;TAI THAM LETTER HIGH CHA;Lo;0;L;;;;;N;;;;;
+1A29;TAI THAM LETTER LOW CA;Lo;0;L;;;;;N;;;;;
+1A2A;TAI THAM LETTER LOW SA;Lo;0;L;;;;;N;;;;;
+1A2B;TAI THAM LETTER LOW CHA;Lo;0;L;;;;;N;;;;;
+1A2C;TAI THAM LETTER NYA;Lo;0;L;;;;;N;;;;;
+1A2D;TAI THAM LETTER RATA;Lo;0;L;;;;;N;;;;;
+1A2E;TAI THAM LETTER HIGH RATHA;Lo;0;L;;;;;N;;;;;
+1A2F;TAI THAM LETTER DA;Lo;0;L;;;;;N;;;;;
+1A30;TAI THAM LETTER LOW RATHA;Lo;0;L;;;;;N;;;;;
+1A31;TAI THAM LETTER RANA;Lo;0;L;;;;;N;;;;;
+1A32;TAI THAM LETTER HIGH TA;Lo;0;L;;;;;N;;;;;
+1A33;TAI THAM LETTER HIGH THA;Lo;0;L;;;;;N;;;;;
+1A34;TAI THAM LETTER LOW TA;Lo;0;L;;;;;N;;;;;
+1A35;TAI THAM LETTER LOW THA;Lo;0;L;;;;;N;;;;;
+1A36;TAI THAM LETTER NA;Lo;0;L;;;;;N;;;;;
+1A37;TAI THAM LETTER BA;Lo;0;L;;;;;N;;;;;
+1A38;TAI THAM LETTER HIGH PA;Lo;0;L;;;;;N;;;;;
+1A39;TAI THAM LETTER HIGH PHA;Lo;0;L;;;;;N;;;;;
+1A3A;TAI THAM LETTER HIGH FA;Lo;0;L;;;;;N;;;;;
+1A3B;TAI THAM LETTER LOW PA;Lo;0;L;;;;;N;;;;;
+1A3C;TAI THAM LETTER LOW FA;Lo;0;L;;;;;N;;;;;
+1A3D;TAI THAM LETTER LOW PHA;Lo;0;L;;;;;N;;;;;
+1A3E;TAI THAM LETTER MA;Lo;0;L;;;;;N;;;;;
+1A3F;TAI THAM LETTER LOW YA;Lo;0;L;;;;;N;;;;;
+1A40;TAI THAM LETTER HIGH YA;Lo;0;L;;;;;N;;;;;
+1A41;TAI THAM LETTER RA;Lo;0;L;;;;;N;;;;;
+1A42;TAI THAM LETTER RUE;Lo;0;L;;;;;N;;;;;
+1A43;TAI THAM LETTER LA;Lo;0;L;;;;;N;;;;;
+1A44;TAI THAM LETTER LUE;Lo;0;L;;;;;N;;;;;
+1A45;TAI THAM LETTER WA;Lo;0;L;;;;;N;;;;;
+1A46;TAI THAM LETTER HIGH SHA;Lo;0;L;;;;;N;;;;;
+1A47;TAI THAM LETTER HIGH SSA;Lo;0;L;;;;;N;;;;;
+1A48;TAI THAM LETTER HIGH SA;Lo;0;L;;;;;N;;;;;
+1A49;TAI THAM LETTER HIGH HA;Lo;0;L;;;;;N;;;;;
+1A4A;TAI THAM LETTER LLA;Lo;0;L;;;;;N;;;;;
+1A4B;TAI THAM LETTER A;Lo;0;L;;;;;N;;;;;
+1A4C;TAI THAM LETTER LOW HA;Lo;0;L;;;;;N;;;;;
+1A4D;TAI THAM LETTER I;Lo;0;L;;;;;N;;;;;
+1A4E;TAI THAM LETTER II;Lo;0;L;;;;;N;;;;;
+1A4F;TAI THAM LETTER U;Lo;0;L;;;;;N;;;;;
+1A50;TAI THAM LETTER UU;Lo;0;L;;;;;N;;;;;
+1A51;TAI THAM LETTER EE;Lo;0;L;;;;;N;;;;;
+1A52;TAI THAM LETTER OO;Lo;0;L;;;;;N;;;;;
+1A53;TAI THAM LETTER LAE;Lo;0;L;;;;;N;;;;;
+1A54;TAI THAM LETTER GREAT SA;Lo;0;L;;;;;N;;;;;
+1A55;TAI THAM CONSONANT SIGN MEDIAL RA;Mc;0;L;;;;;N;;;;;
+1A56;TAI THAM CONSONANT SIGN MEDIAL LA;Mn;0;NSM;;;;;N;;;;;
+1A57;TAI THAM CONSONANT SIGN LA TANG LAI;Mc;0;L;;;;;N;;;;;
+1A58;TAI THAM SIGN MAI KANG LAI;Mn;0;NSM;;;;;N;;;;;
+1A59;TAI THAM CONSONANT SIGN FINAL NGA;Mn;0;NSM;;;;;N;;;;;
+1A5A;TAI THAM CONSONANT SIGN LOW PA;Mn;0;NSM;;;;;N;;;;;
+1A5B;TAI THAM CONSONANT SIGN HIGH RATHA OR LOW PA;Mn;0;NSM;;;;;N;;;;;
+1A5C;TAI THAM CONSONANT SIGN MA;Mn;0;NSM;;;;;N;;;;;
+1A5D;TAI THAM CONSONANT SIGN BA;Mn;0;NSM;;;;;N;;;;;
+1A5E;TAI THAM CONSONANT SIGN SA;Mn;0;NSM;;;;;N;;;;;
+1A60;TAI THAM SIGN SAKOT;Mn;9;NSM;;;;;N;;;;;
+1A61;TAI THAM VOWEL SIGN A;Mc;0;L;;;;;N;;;;;
+1A62;TAI THAM VOWEL SIGN MAI SAT;Mn;0;NSM;;;;;N;;;;;
+1A63;TAI THAM VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
+1A64;TAI THAM VOWEL SIGN TALL AA;Mc;0;L;;;;;N;;;;;
+1A65;TAI THAM VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;
+1A66;TAI THAM VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;;
+1A67;TAI THAM VOWEL SIGN UE;Mn;0;NSM;;;;;N;;;;;
+1A68;TAI THAM VOWEL SIGN UUE;Mn;0;NSM;;;;;N;;;;;
+1A69;TAI THAM VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+1A6A;TAI THAM VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;
+1A6B;TAI THAM VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;;
+1A6C;TAI THAM VOWEL SIGN OA BELOW;Mn;0;NSM;;;;;N;;;;;
+1A6D;TAI THAM VOWEL SIGN OY;Mc;0;L;;;;;N;;;;;
+1A6E;TAI THAM VOWEL SIGN E;Mc;0;L;;;;;N;;;;;
+1A6F;TAI THAM VOWEL SIGN AE;Mc;0;L;;;;;N;;;;;
+1A70;TAI THAM VOWEL SIGN OO;Mc;0;L;;;;;N;;;;;
+1A71;TAI THAM VOWEL SIGN AI;Mc;0;L;;;;;N;;;;;
+1A72;TAI THAM VOWEL SIGN THAM AI;Mc;0;L;;;;;N;;;;;
+1A73;TAI THAM VOWEL SIGN OA ABOVE;Mn;0;NSM;;;;;N;;;;;
+1A74;TAI THAM SIGN MAI KANG;Mn;0;NSM;;;;;N;;;;;
+1A75;TAI THAM SIGN TONE-1;Mn;230;NSM;;;;;N;;;;;
+1A76;TAI THAM SIGN TONE-2;Mn;230;NSM;;;;;N;;;;;
+1A77;TAI THAM SIGN KHUEN TONE-3;Mn;230;NSM;;;;;N;;;;;
+1A78;TAI THAM SIGN KHUEN TONE-4;Mn;230;NSM;;;;;N;;;;;
+1A79;TAI THAM SIGN KHUEN TONE-5;Mn;230;NSM;;;;;N;;;;;
+1A7A;TAI THAM SIGN RA HAAM;Mn;230;NSM;;;;;N;;;;;
+1A7B;TAI THAM SIGN MAI SAM;Mn;230;NSM;;;;;N;;;;;
+1A7C;TAI THAM SIGN KHUEN-LUE KARAN;Mn;230;NSM;;;;;N;;;;;
+1A7F;TAI THAM COMBINING CRYPTOGRAMMIC DOT;Mn;220;NSM;;;;;N;;;;;
+1A80;TAI THAM HORA DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+1A81;TAI THAM HORA DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+1A82;TAI THAM HORA DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+1A83;TAI THAM HORA DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+1A84;TAI THAM HORA DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+1A85;TAI THAM HORA DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+1A86;TAI THAM HORA DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+1A87;TAI THAM HORA DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+1A88;TAI THAM HORA DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+1A89;TAI THAM HORA DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+1A90;TAI THAM THAM DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+1A91;TAI THAM THAM DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+1A92;TAI THAM THAM DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+1A93;TAI THAM THAM DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+1A94;TAI THAM THAM DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+1A95;TAI THAM THAM DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+1A96;TAI THAM THAM DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+1A97;TAI THAM THAM DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+1A98;TAI THAM THAM DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+1A99;TAI THAM THAM DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+1AA0;TAI THAM SIGN WIANG;Po;0;L;;;;;N;;;;;
+1AA1;TAI THAM SIGN WIANGWAAK;Po;0;L;;;;;N;;;;;
+1AA2;TAI THAM SIGN SAWAN;Po;0;L;;;;;N;;;;;
+1AA3;TAI THAM SIGN KEOW;Po;0;L;;;;;N;;;;;
+1AA4;TAI THAM SIGN HOY;Po;0;L;;;;;N;;;;;
+1AA5;TAI THAM SIGN DOKMAI;Po;0;L;;;;;N;;;;;
+1AA6;TAI THAM SIGN REVERSED ROTATED RANA;Po;0;L;;;;;N;;;;;
+1AA7;TAI THAM SIGN MAI YAMOK;Lm;0;L;;;;;N;;;;;
+1AA8;TAI THAM SIGN KAAN;Po;0;L;;;;;N;;;;;
+1AA9;TAI THAM SIGN KAANKUU;Po;0;L;;;;;N;;;;;
+1AAA;TAI THAM SIGN SATKAAN;Po;0;L;;;;;N;;;;;
+1AAB;TAI THAM SIGN SATKAANKUU;Po;0;L;;;;;N;;;;;
+1AAC;TAI THAM SIGN HANG;Po;0;L;;;;;N;;;;;
+1AAD;TAI THAM SIGN CAANG;Po;0;L;;;;;N;;;;;
+1B00;BALINESE SIGN ULU RICEM;Mn;0;NSM;;;;;N;;;;;
+1B01;BALINESE SIGN ULU CANDRA;Mn;0;NSM;;;;;N;;;;;
+1B02;BALINESE SIGN CECEK;Mn;0;NSM;;;;;N;;;;;
+1B03;BALINESE SIGN SURANG;Mn;0;NSM;;;;;N;;;;;
+1B04;BALINESE SIGN BISAH;Mc;0;L;;;;;N;;;;;
+1B05;BALINESE LETTER AKARA;Lo;0;L;;;;;N;;;;;
+1B06;BALINESE LETTER AKARA TEDUNG;Lo;0;L;1B05 1B35;;;;N;;;;;
+1B07;BALINESE LETTER IKARA;Lo;0;L;;;;;N;;;;;
+1B08;BALINESE LETTER IKARA TEDUNG;Lo;0;L;1B07 1B35;;;;N;;;;;
+1B09;BALINESE LETTER UKARA;Lo;0;L;;;;;N;;;;;
+1B0A;BALINESE LETTER UKARA TEDUNG;Lo;0;L;1B09 1B35;;;;N;;;;;
+1B0B;BALINESE LETTER RA REPA;Lo;0;L;;;;;N;;;;;
+1B0C;BALINESE LETTER RA REPA TEDUNG;Lo;0;L;1B0B 1B35;;;;N;;;;;
+1B0D;BALINESE LETTER LA LENGA;Lo;0;L;;;;;N;;;;;
+1B0E;BALINESE LETTER LA LENGA TEDUNG;Lo;0;L;1B0D 1B35;;;;N;;;;;
+1B0F;BALINESE LETTER EKARA;Lo;0;L;;;;;N;;;;;
+1B10;BALINESE LETTER AIKARA;Lo;0;L;;;;;N;;;;;
+1B11;BALINESE LETTER OKARA;Lo;0;L;;;;;N;;;;;
+1B12;BALINESE LETTER OKARA TEDUNG;Lo;0;L;1B11 1B35;;;;N;;;;;
+1B13;BALINESE LETTER KA;Lo;0;L;;;;;N;;;;;
+1B14;BALINESE LETTER KA MAHAPRANA;Lo;0;L;;;;;N;;;;;
+1B15;BALINESE LETTER GA;Lo;0;L;;;;;N;;;;;
+1B16;BALINESE LETTER GA GORA;Lo;0;L;;;;;N;;;;;
+1B17;BALINESE LETTER NGA;Lo;0;L;;;;;N;;;;;
+1B18;BALINESE LETTER CA;Lo;0;L;;;;;N;;;;;
+1B19;BALINESE LETTER CA LACA;Lo;0;L;;;;;N;;;;;
+1B1A;BALINESE LETTER JA;Lo;0;L;;;;;N;;;;;
+1B1B;BALINESE LETTER JA JERA;Lo;0;L;;;;;N;;;;;
+1B1C;BALINESE LETTER NYA;Lo;0;L;;;;;N;;;;;
+1B1D;BALINESE LETTER TA LATIK;Lo;0;L;;;;;N;;;;;
+1B1E;BALINESE LETTER TA MURDA MAHAPRANA;Lo;0;L;;;;;N;;;;;
+1B1F;BALINESE LETTER DA MURDA ALPAPRANA;Lo;0;L;;;;;N;;;;;
+1B20;BALINESE LETTER DA MURDA MAHAPRANA;Lo;0;L;;;;;N;;;;;
+1B21;BALINESE LETTER NA RAMBAT;Lo;0;L;;;;;N;;;;;
+1B22;BALINESE LETTER TA;Lo;0;L;;;;;N;;;;;
+1B23;BALINESE LETTER TA TAWA;Lo;0;L;;;;;N;;;;;
+1B24;BALINESE LETTER DA;Lo;0;L;;;;;N;;;;;
+1B25;BALINESE LETTER DA MADU;Lo;0;L;;;;;N;;;;;
+1B26;BALINESE LETTER NA;Lo;0;L;;;;;N;;;;;
+1B27;BALINESE LETTER PA;Lo;0;L;;;;;N;;;;;
+1B28;BALINESE LETTER PA KAPAL;Lo;0;L;;;;;N;;;;;
+1B29;BALINESE LETTER BA;Lo;0;L;;;;;N;;;;;
+1B2A;BALINESE LETTER BA KEMBANG;Lo;0;L;;;;;N;;;;;
+1B2B;BALINESE LETTER MA;Lo;0;L;;;;;N;;;;;
+1B2C;BALINESE LETTER YA;Lo;0;L;;;;;N;;;;;
+1B2D;BALINESE LETTER RA;Lo;0;L;;;;;N;;;;;
+1B2E;BALINESE LETTER LA;Lo;0;L;;;;;N;;;;;
+1B2F;BALINESE LETTER WA;Lo;0;L;;;;;N;;;;;
+1B30;BALINESE LETTER SA SAGA;Lo;0;L;;;;;N;;;;;
+1B31;BALINESE LETTER SA SAPA;Lo;0;L;;;;;N;;;;;
+1B32;BALINESE LETTER SA;Lo;0;L;;;;;N;;;;;
+1B33;BALINESE LETTER HA;Lo;0;L;;;;;N;;;;;
+1B34;BALINESE SIGN REREKAN;Mn;7;NSM;;;;;N;;;;;
+1B35;BALINESE VOWEL SIGN TEDUNG;Mc;0;L;;;;;N;;;;;
+1B36;BALINESE VOWEL SIGN ULU;Mn;0;NSM;;;;;N;;;;;
+1B37;BALINESE VOWEL SIGN ULU SARI;Mn;0;NSM;;;;;N;;;;;
+1B38;BALINESE VOWEL SIGN SUKU;Mn;0;NSM;;;;;N;;;;;
+1B39;BALINESE VOWEL SIGN SUKU ILUT;Mn;0;NSM;;;;;N;;;;;
+1B3A;BALINESE VOWEL SIGN RA REPA;Mn;0;NSM;;;;;N;;;;;
+1B3B;BALINESE VOWEL SIGN RA REPA TEDUNG;Mc;0;L;1B3A 1B35;;;;N;;;;;
+1B3C;BALINESE VOWEL SIGN LA LENGA;Mn;0;NSM;;;;;N;;;;;
+1B3D;BALINESE VOWEL SIGN LA LENGA TEDUNG;Mc;0;L;1B3C 1B35;;;;N;;;;;
+1B3E;BALINESE VOWEL SIGN TALING;Mc;0;L;;;;;N;;;;;
+1B3F;BALINESE VOWEL SIGN TALING REPA;Mc;0;L;;;;;N;;;;;
+1B40;BALINESE VOWEL SIGN TALING TEDUNG;Mc;0;L;1B3E 1B35;;;;N;;;;;
+1B41;BALINESE VOWEL SIGN TALING REPA TEDUNG;Mc;0;L;1B3F 1B35;;;;N;;;;;
+1B42;BALINESE VOWEL SIGN PEPET;Mn;0;NSM;;;;;N;;;;;
+1B43;BALINESE VOWEL SIGN PEPET TEDUNG;Mc;0;L;1B42 1B35;;;;N;;;;;
+1B44;BALINESE ADEG ADEG;Mc;9;L;;;;;N;;;;;
+1B45;BALINESE LETTER KAF SASAK;Lo;0;L;;;;;N;;;;;
+1B46;BALINESE LETTER KHOT SASAK;Lo;0;L;;;;;N;;;;;
+1B47;BALINESE LETTER TZIR SASAK;Lo;0;L;;;;;N;;;;;
+1B48;BALINESE LETTER EF SASAK;Lo;0;L;;;;;N;;;;;
+1B49;BALINESE LETTER VE SASAK;Lo;0;L;;;;;N;;;;;
+1B4A;BALINESE LETTER ZAL SASAK;Lo;0;L;;;;;N;;;;;
+1B4B;BALINESE LETTER ASYURA SASAK;Lo;0;L;;;;;N;;;;;
+1B50;BALINESE DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+1B51;BALINESE DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+1B52;BALINESE DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+1B53;BALINESE DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+1B54;BALINESE DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+1B55;BALINESE DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+1B56;BALINESE DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+1B57;BALINESE DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+1B58;BALINESE DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+1B59;BALINESE DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+1B5A;BALINESE PANTI;Po;0;L;;;;;N;;;;;
+1B5B;BALINESE PAMADA;Po;0;L;;;;;N;;;;;
+1B5C;BALINESE WINDU;Po;0;L;;;;;N;;;;;
+1B5D;BALINESE CARIK PAMUNGKAH;Po;0;L;;;;;N;;;;;
+1B5E;BALINESE CARIK SIKI;Po;0;L;;;;;N;;;;;
+1B5F;BALINESE CARIK PAREREN;Po;0;L;;;;;N;;;;;
+1B60;BALINESE PAMENENG;Po;0;L;;;;;N;;;;;
+1B61;BALINESE MUSICAL SYMBOL DONG;So;0;L;;;;;N;;;;;
+1B62;BALINESE MUSICAL SYMBOL DENG;So;0;L;;;;;N;;;;;
+1B63;BALINESE MUSICAL SYMBOL DUNG;So;0;L;;;;;N;;;;;
+1B64;BALINESE MUSICAL SYMBOL DANG;So;0;L;;;;;N;;;;;
+1B65;BALINESE MUSICAL SYMBOL DANG SURANG;So;0;L;;;;;N;;;;;
+1B66;BALINESE MUSICAL SYMBOL DING;So;0;L;;;;;N;;;;;
+1B67;BALINESE MUSICAL SYMBOL DAENG;So;0;L;;;;;N;;;;;
+1B68;BALINESE MUSICAL SYMBOL DEUNG;So;0;L;;;;;N;;;;;
+1B69;BALINESE MUSICAL SYMBOL DAING;So;0;L;;;;;N;;;;;
+1B6A;BALINESE MUSICAL SYMBOL DANG GEDE;So;0;L;;;;;N;;;;;
+1B6B;BALINESE MUSICAL SYMBOL COMBINING TEGEH;Mn;230;NSM;;;;;N;;;;;
+1B6C;BALINESE MUSICAL SYMBOL COMBINING ENDEP;Mn;220;NSM;;;;;N;;;;;
+1B6D;BALINESE MUSICAL SYMBOL COMBINING KEMPUL;Mn;230;NSM;;;;;N;;;;;
+1B6E;BALINESE MUSICAL SYMBOL COMBINING KEMPLI;Mn;230;NSM;;;;;N;;;;;
+1B6F;BALINESE MUSICAL SYMBOL COMBINING JEGOGAN;Mn;230;NSM;;;;;N;;;;;
+1B70;BALINESE MUSICAL SYMBOL COMBINING KEMPUL WITH JEGOGAN;Mn;230;NSM;;;;;N;;;;;
+1B71;BALINESE MUSICAL SYMBOL COMBINING KEMPLI WITH JEGOGAN;Mn;230;NSM;;;;;N;;;;;
+1B72;BALINESE MUSICAL SYMBOL COMBINING BENDE;Mn;230;NSM;;;;;N;;;;;
+1B73;BALINESE MUSICAL SYMBOL COMBINING GONG;Mn;230;NSM;;;;;N;;;;;
+1B74;BALINESE MUSICAL SYMBOL RIGHT-HAND OPEN DUG;So;0;L;;;;;N;;;;;
+1B75;BALINESE MUSICAL SYMBOL RIGHT-HAND OPEN DAG;So;0;L;;;;;N;;;;;
+1B76;BALINESE MUSICAL SYMBOL RIGHT-HAND CLOSED TUK;So;0;L;;;;;N;;;;;
+1B77;BALINESE MUSICAL SYMBOL RIGHT-HAND CLOSED TAK;So;0;L;;;;;N;;;;;
+1B78;BALINESE MUSICAL SYMBOL LEFT-HAND OPEN PANG;So;0;L;;;;;N;;;;;
+1B79;BALINESE MUSICAL SYMBOL LEFT-HAND OPEN PUNG;So;0;L;;;;;N;;;;;
+1B7A;BALINESE MUSICAL SYMBOL LEFT-HAND CLOSED PLAK;So;0;L;;;;;N;;;;;
+1B7B;BALINESE MUSICAL SYMBOL LEFT-HAND CLOSED PLUK;So;0;L;;;;;N;;;;;
+1B7C;BALINESE MUSICAL SYMBOL LEFT-HAND OPEN PING;So;0;L;;;;;N;;;;;
+1B80;SUNDANESE SIGN PANYECEK;Mn;0;NSM;;;;;N;;;;;
+1B81;SUNDANESE SIGN PANGLAYAR;Mn;0;NSM;;;;;N;;;;;
+1B82;SUNDANESE SIGN PANGWISAD;Mc;0;L;;;;;N;;;;;
+1B83;SUNDANESE LETTER A;Lo;0;L;;;;;N;;;;;
+1B84;SUNDANESE LETTER I;Lo;0;L;;;;;N;;;;;
+1B85;SUNDANESE LETTER U;Lo;0;L;;;;;N;;;;;
+1B86;SUNDANESE LETTER AE;Lo;0;L;;;;;N;;;;;
+1B87;SUNDANESE LETTER O;Lo;0;L;;;;;N;;;;;
+1B88;SUNDANESE LETTER E;Lo;0;L;;;;;N;;;;;
+1B89;SUNDANESE LETTER EU;Lo;0;L;;;;;N;;;;;
+1B8A;SUNDANESE LETTER KA;Lo;0;L;;;;;N;;;;;
+1B8B;SUNDANESE LETTER QA;Lo;0;L;;;;;N;;;;;
+1B8C;SUNDANESE LETTER GA;Lo;0;L;;;;;N;;;;;
+1B8D;SUNDANESE LETTER NGA;Lo;0;L;;;;;N;;;;;
+1B8E;SUNDANESE LETTER CA;Lo;0;L;;;;;N;;;;;
+1B8F;SUNDANESE LETTER JA;Lo;0;L;;;;;N;;;;;
+1B90;SUNDANESE LETTER ZA;Lo;0;L;;;;;N;;;;;
+1B91;SUNDANESE LETTER NYA;Lo;0;L;;;;;N;;;;;
+1B92;SUNDANESE LETTER TA;Lo;0;L;;;;;N;;;;;
+1B93;SUNDANESE LETTER DA;Lo;0;L;;;;;N;;;;;
+1B94;SUNDANESE LETTER NA;Lo;0;L;;;;;N;;;;;
+1B95;SUNDANESE LETTER PA;Lo;0;L;;;;;N;;;;;
+1B96;SUNDANESE LETTER FA;Lo;0;L;;;;;N;;;;;
+1B97;SUNDANESE LETTER VA;Lo;0;L;;;;;N;;;;;
+1B98;SUNDANESE LETTER BA;Lo;0;L;;;;;N;;;;;
+1B99;SUNDANESE LETTER MA;Lo;0;L;;;;;N;;;;;
+1B9A;SUNDANESE LETTER YA;Lo;0;L;;;;;N;;;;;
+1B9B;SUNDANESE LETTER RA;Lo;0;L;;;;;N;;;;;
+1B9C;SUNDANESE LETTER LA;Lo;0;L;;;;;N;;;;;
+1B9D;SUNDANESE LETTER WA;Lo;0;L;;;;;N;;;;;
+1B9E;SUNDANESE LETTER SA;Lo;0;L;;;;;N;;;;;
+1B9F;SUNDANESE LETTER XA;Lo;0;L;;;;;N;;;;;
+1BA0;SUNDANESE LETTER HA;Lo;0;L;;;;;N;;;;;
+1BA1;SUNDANESE CONSONANT SIGN PAMINGKAL;Mc;0;L;;;;;N;;;;;
+1BA2;SUNDANESE CONSONANT SIGN PANYAKRA;Mn;0;NSM;;;;;N;;;;;
+1BA3;SUNDANESE CONSONANT SIGN PANYIKU;Mn;0;NSM;;;;;N;;;;;
+1BA4;SUNDANESE VOWEL SIGN PANGHULU;Mn;0;NSM;;;;;N;;;;;
+1BA5;SUNDANESE VOWEL SIGN PANYUKU;Mn;0;NSM;;;;;N;;;;;
+1BA6;SUNDANESE VOWEL SIGN PANAELAENG;Mc;0;L;;;;;N;;;;;
+1BA7;SUNDANESE VOWEL SIGN PANOLONG;Mc;0;L;;;;;N;;;;;
+1BA8;SUNDANESE VOWEL SIGN PAMEPET;Mn;0;NSM;;;;;N;;;;;
+1BA9;SUNDANESE VOWEL SIGN PANEULEUNG;Mn;0;NSM;;;;;N;;;;;
+1BAA;SUNDANESE SIGN PAMAAEH;Mc;9;L;;;;;N;;;;;
+1BAE;SUNDANESE LETTER KHA;Lo;0;L;;;;;N;;;;;
+1BAF;SUNDANESE LETTER SYA;Lo;0;L;;;;;N;;;;;
+1BB0;SUNDANESE DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+1BB1;SUNDANESE DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+1BB2;SUNDANESE DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+1BB3;SUNDANESE DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+1BB4;SUNDANESE DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+1BB5;SUNDANESE DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+1BB6;SUNDANESE DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+1BB7;SUNDANESE DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+1BB8;SUNDANESE DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+1BB9;SUNDANESE DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+1BC0;BATAK LETTER A;Lo;0;L;;;;;N;;;;;
+1BC1;BATAK LETTER SIMALUNGUN A;Lo;0;L;;;;;N;;;;;
+1BC2;BATAK LETTER HA;Lo;0;L;;;;;N;;;;;
+1BC3;BATAK LETTER SIMALUNGUN HA;Lo;0;L;;;;;N;;;;;
+1BC4;BATAK LETTER MANDAILING HA;Lo;0;L;;;;;N;;;;;
+1BC5;BATAK LETTER BA;Lo;0;L;;;;;N;;;;;
+1BC6;BATAK LETTER KARO BA;Lo;0;L;;;;;N;;;;;
+1BC7;BATAK LETTER PA;Lo;0;L;;;;;N;;;;;
+1BC8;BATAK LETTER SIMALUNGUN PA;Lo;0;L;;;;;N;;;;;
+1BC9;BATAK LETTER NA;Lo;0;L;;;;;N;;;;;
+1BCA;BATAK LETTER MANDAILING NA;Lo;0;L;;;;;N;;;;;
+1BCB;BATAK LETTER WA;Lo;0;L;;;;;N;;;;;
+1BCC;BATAK LETTER SIMALUNGUN WA;Lo;0;L;;;;;N;;;;;
+1BCD;BATAK LETTER PAKPAK WA;Lo;0;L;;;;;N;;;;;
+1BCE;BATAK LETTER GA;Lo;0;L;;;;;N;;;;;
+1BCF;BATAK LETTER SIMALUNGUN GA;Lo;0;L;;;;;N;;;;;
+1BD0;BATAK LETTER JA;Lo;0;L;;;;;N;;;;;
+1BD1;BATAK LETTER DA;Lo;0;L;;;;;N;;;;;
+1BD2;BATAK LETTER RA;Lo;0;L;;;;;N;;;;;
+1BD3;BATAK LETTER SIMALUNGUN RA;Lo;0;L;;;;;N;;;;;
+1BD4;BATAK LETTER MA;Lo;0;L;;;;;N;;;;;
+1BD5;BATAK LETTER SIMALUNGUN MA;Lo;0;L;;;;;N;;;;;
+1BD6;BATAK LETTER SOUTHERN TA;Lo;0;L;;;;;N;;;;;
+1BD7;BATAK LETTER NORTHERN TA;Lo;0;L;;;;;N;;;;;
+1BD8;BATAK LETTER SA;Lo;0;L;;;;;N;;;;;
+1BD9;BATAK LETTER SIMALUNGUN SA;Lo;0;L;;;;;N;;;;;
+1BDA;BATAK LETTER MANDAILING SA;Lo;0;L;;;;;N;;;;;
+1BDB;BATAK LETTER YA;Lo;0;L;;;;;N;;;;;
+1BDC;BATAK LETTER SIMALUNGUN YA;Lo;0;L;;;;;N;;;;;
+1BDD;BATAK LETTER NGA;Lo;0;L;;;;;N;;;;;
+1BDE;BATAK LETTER LA;Lo;0;L;;;;;N;;;;;
+1BDF;BATAK LETTER SIMALUNGUN LA;Lo;0;L;;;;;N;;;;;
+1BE0;BATAK LETTER NYA;Lo;0;L;;;;;N;;;;;
+1BE1;BATAK LETTER CA;Lo;0;L;;;;;N;;;;;
+1BE2;BATAK LETTER NDA;Lo;0;L;;;;;N;;;;;
+1BE3;BATAK LETTER MBA;Lo;0;L;;;;;N;;;;;
+1BE4;BATAK LETTER I;Lo;0;L;;;;;N;;;;;
+1BE5;BATAK LETTER U;Lo;0;L;;;;;N;;;;;
+1BE6;BATAK SIGN TOMPI;Mn;7;NSM;;;;;N;;;;;
+1BE7;BATAK VOWEL SIGN E;Mc;0;L;;;;;N;;;;;
+1BE8;BATAK VOWEL SIGN PAKPAK E;Mn;0;NSM;;;;;N;;;;;
+1BE9;BATAK VOWEL SIGN EE;Mn;0;NSM;;;;;N;;;;;
+1BEA;BATAK VOWEL SIGN I;Mc;0;L;;;;;N;;;;;
+1BEB;BATAK VOWEL SIGN KARO I;Mc;0;L;;;;;N;;;;;
+1BEC;BATAK VOWEL SIGN O;Mc;0;L;;;;;N;;;;;
+1BED;BATAK VOWEL SIGN KARO O;Mn;0;NSM;;;;;N;;;;;
+1BEE;BATAK VOWEL SIGN U;Mc;0;L;;;;;N;;;;;
+1BEF;BATAK VOWEL SIGN U FOR SIMALUNGUN SA;Mn;0;NSM;;;;;N;;;;;
+1BF0;BATAK CONSONANT SIGN NG;Mn;0;NSM;;;;;N;;;;;
+1BF1;BATAK CONSONANT SIGN H;Mn;0;NSM;;;;;N;;;;;
+1BF2;BATAK PANGOLAT;Mc;9;L;;;;;N;;;;;
+1BF3;BATAK PANONGONAN;Mc;9;L;;;;;N;;;;;
+1BFC;BATAK SYMBOL BINDU NA METEK;Po;0;L;;;;;N;;;;;
+1BFD;BATAK SYMBOL BINDU PINARBORAS;Po;0;L;;;;;N;;;;;
+1BFE;BATAK SYMBOL BINDU JUDUL;Po;0;L;;;;;N;;;;;
+1BFF;BATAK SYMBOL BINDU PANGOLAT;Po;0;L;;;;;N;;;;;
+1C00;LEPCHA LETTER KA;Lo;0;L;;;;;N;;;;;
+1C01;LEPCHA LETTER KLA;Lo;0;L;;;;;N;;;;;
+1C02;LEPCHA LETTER KHA;Lo;0;L;;;;;N;;;;;
+1C03;LEPCHA LETTER GA;Lo;0;L;;;;;N;;;;;
+1C04;LEPCHA LETTER GLA;Lo;0;L;;;;;N;;;;;
+1C05;LEPCHA LETTER NGA;Lo;0;L;;;;;N;;;;;
+1C06;LEPCHA LETTER CA;Lo;0;L;;;;;N;;;;;
+1C07;LEPCHA LETTER CHA;Lo;0;L;;;;;N;;;;;
+1C08;LEPCHA LETTER JA;Lo;0;L;;;;;N;;;;;
+1C09;LEPCHA LETTER NYA;Lo;0;L;;;;;N;;;;;
+1C0A;LEPCHA LETTER TA;Lo;0;L;;;;;N;;;;;
+1C0B;LEPCHA LETTER THA;Lo;0;L;;;;;N;;;;;
+1C0C;LEPCHA LETTER DA;Lo;0;L;;;;;N;;;;;
+1C0D;LEPCHA LETTER NA;Lo;0;L;;;;;N;;;;;
+1C0E;LEPCHA LETTER PA;Lo;0;L;;;;;N;;;;;
+1C0F;LEPCHA LETTER PLA;Lo;0;L;;;;;N;;;;;
+1C10;LEPCHA LETTER PHA;Lo;0;L;;;;;N;;;;;
+1C11;LEPCHA LETTER FA;Lo;0;L;;;;;N;;;;;
+1C12;LEPCHA LETTER FLA;Lo;0;L;;;;;N;;;;;
+1C13;LEPCHA LETTER BA;Lo;0;L;;;;;N;;;;;
+1C14;LEPCHA LETTER BLA;Lo;0;L;;;;;N;;;;;
+1C15;LEPCHA LETTER MA;Lo;0;L;;;;;N;;;;;
+1C16;LEPCHA LETTER MLA;Lo;0;L;;;;;N;;;;;
+1C17;LEPCHA LETTER TSA;Lo;0;L;;;;;N;;;;;
+1C18;LEPCHA LETTER TSHA;Lo;0;L;;;;;N;;;;;
+1C19;LEPCHA LETTER DZA;Lo;0;L;;;;;N;;;;;
+1C1A;LEPCHA LETTER YA;Lo;0;L;;;;;N;;;;;
+1C1B;LEPCHA LETTER RA;Lo;0;L;;;;;N;;;;;
+1C1C;LEPCHA LETTER LA;Lo;0;L;;;;;N;;;;;
+1C1D;LEPCHA LETTER HA;Lo;0;L;;;;;N;;;;;
+1C1E;LEPCHA LETTER HLA;Lo;0;L;;;;;N;;;;;
+1C1F;LEPCHA LETTER VA;Lo;0;L;;;;;N;;;;;
+1C20;LEPCHA LETTER SA;Lo;0;L;;;;;N;;;;;
+1C21;LEPCHA LETTER SHA;Lo;0;L;;;;;N;;;;;
+1C22;LEPCHA LETTER WA;Lo;0;L;;;;;N;;;;;
+1C23;LEPCHA LETTER A;Lo;0;L;;;;;N;;;;;
+1C24;LEPCHA SUBJOINED LETTER YA;Mc;0;L;;;;;N;;;;;
+1C25;LEPCHA SUBJOINED LETTER RA;Mc;0;L;;;;;N;;;;;
+1C26;LEPCHA VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
+1C27;LEPCHA VOWEL SIGN I;Mc;0;L;;;;;N;;;;;
+1C28;LEPCHA VOWEL SIGN O;Mc;0;L;;;;;N;;;;;
+1C29;LEPCHA VOWEL SIGN OO;Mc;0;L;;;;;N;;;;;
+1C2A;LEPCHA VOWEL SIGN U;Mc;0;L;;;;;N;;;;;
+1C2B;LEPCHA VOWEL SIGN UU;Mc;0;L;;;;;N;;;;;
+1C2C;LEPCHA VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;;
+1C2D;LEPCHA CONSONANT SIGN K;Mn;0;NSM;;;;;N;;;;;
+1C2E;LEPCHA CONSONANT SIGN M;Mn;0;NSM;;;;;N;;;;;
+1C2F;LEPCHA CONSONANT SIGN L;Mn;0;NSM;;;;;N;;;;;
+1C30;LEPCHA CONSONANT SIGN N;Mn;0;NSM;;;;;N;;;;;
+1C31;LEPCHA CONSONANT SIGN P;Mn;0;NSM;;;;;N;;;;;
+1C32;LEPCHA CONSONANT SIGN R;Mn;0;NSM;;;;;N;;;;;
+1C33;LEPCHA CONSONANT SIGN T;Mn;0;NSM;;;;;N;;;;;
+1C34;LEPCHA CONSONANT SIGN NYIN-DO;Mc;0;L;;;;;N;;;;;
+1C35;LEPCHA CONSONANT SIGN KANG;Mc;0;L;;;;;N;;;;;
+1C36;LEPCHA SIGN RAN;Mn;0;NSM;;;;;N;;;;;
+1C37;LEPCHA SIGN NUKTA;Mn;7;NSM;;;;;N;;;;;
+1C3B;LEPCHA PUNCTUATION TA-ROL;Po;0;L;;;;;N;;;;;
+1C3C;LEPCHA PUNCTUATION NYET THYOOM TA-ROL;Po;0;L;;;;;N;;;;;
+1C3D;LEPCHA PUNCTUATION CER-WA;Po;0;L;;;;;N;;;;;
+1C3E;LEPCHA PUNCTUATION TSHOOK CER-WA;Po;0;L;;;;;N;;;;;
+1C3F;LEPCHA PUNCTUATION TSHOOK;Po;0;L;;;;;N;;;;;
+1C40;LEPCHA DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+1C41;LEPCHA DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+1C42;LEPCHA DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+1C43;LEPCHA DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+1C44;LEPCHA DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+1C45;LEPCHA DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+1C46;LEPCHA DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+1C47;LEPCHA DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+1C48;LEPCHA DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+1C49;LEPCHA DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+1C4D;LEPCHA LETTER TTA;Lo;0;L;;;;;N;;;;;
+1C4E;LEPCHA LETTER TTHA;Lo;0;L;;;;;N;;;;;
+1C4F;LEPCHA LETTER DDA;Lo;0;L;;;;;N;;;;;
+1C50;OL CHIKI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+1C51;OL CHIKI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+1C52;OL CHIKI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+1C53;OL CHIKI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+1C54;OL CHIKI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+1C55;OL CHIKI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+1C56;OL CHIKI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+1C57;OL CHIKI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+1C58;OL CHIKI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+1C59;OL CHIKI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+1C5A;OL CHIKI LETTER LA;Lo;0;L;;;;;N;;;;;
+1C5B;OL CHIKI LETTER AT;Lo;0;L;;;;;N;;;;;
+1C5C;OL CHIKI LETTER AG;Lo;0;L;;;;;N;;;;;
+1C5D;OL CHIKI LETTER ANG;Lo;0;L;;;;;N;;;;;
+1C5E;OL CHIKI LETTER AL;Lo;0;L;;;;;N;;;;;
+1C5F;OL CHIKI LETTER LAA;Lo;0;L;;;;;N;;;;;
+1C60;OL CHIKI LETTER AAK;Lo;0;L;;;;;N;;;;;
+1C61;OL CHIKI LETTER AAJ;Lo;0;L;;;;;N;;;;;
+1C62;OL CHIKI LETTER AAM;Lo;0;L;;;;;N;;;;;
+1C63;OL CHIKI LETTER AAW;Lo;0;L;;;;;N;;;;;
+1C64;OL CHIKI LETTER LI;Lo;0;L;;;;;N;;;;;
+1C65;OL CHIKI LETTER IS;Lo;0;L;;;;;N;;;;;
+1C66;OL CHIKI LETTER IH;Lo;0;L;;;;;N;;;;;
+1C67;OL CHIKI LETTER INY;Lo;0;L;;;;;N;;;;;
+1C68;OL CHIKI LETTER IR;Lo;0;L;;;;;N;;;;;
+1C69;OL CHIKI LETTER LU;Lo;0;L;;;;;N;;;;;
+1C6A;OL CHIKI LETTER UC;Lo;0;L;;;;;N;;;;;
+1C6B;OL CHIKI LETTER UD;Lo;0;L;;;;;N;;;;;
+1C6C;OL CHIKI LETTER UNN;Lo;0;L;;;;;N;;;;;
+1C6D;OL CHIKI LETTER UY;Lo;0;L;;;;;N;;;;;
+1C6E;OL CHIKI LETTER LE;Lo;0;L;;;;;N;;;;;
+1C6F;OL CHIKI LETTER EP;Lo;0;L;;;;;N;;;;;
+1C70;OL CHIKI LETTER EDD;Lo;0;L;;;;;N;;;;;
+1C71;OL CHIKI LETTER EN;Lo;0;L;;;;;N;;;;;
+1C72;OL CHIKI LETTER ERR;Lo;0;L;;;;;N;;;;;
+1C73;OL CHIKI LETTER LO;Lo;0;L;;;;;N;;;;;
+1C74;OL CHIKI LETTER OTT;Lo;0;L;;;;;N;;;;;
+1C75;OL CHIKI LETTER OB;Lo;0;L;;;;;N;;;;;
+1C76;OL CHIKI LETTER OV;Lo;0;L;;;;;N;;;;;
+1C77;OL CHIKI LETTER OH;Lo;0;L;;;;;N;;;;;
+1C78;OL CHIKI MU TTUDDAG;Lm;0;L;;;;;N;;;;;
+1C79;OL CHIKI GAAHLAA TTUDDAAG;Lm;0;L;;;;;N;;;;;
+1C7A;OL CHIKI MU-GAAHLAA TTUDDAAG;Lm;0;L;;;;;N;;;;;
+1C7B;OL CHIKI RELAA;Lm;0;L;;;;;N;;;;;
+1C7C;OL CHIKI PHAARKAA;Lm;0;L;;;;;N;;;;;
+1C7D;OL CHIKI AHAD;Lm;0;L;;;;;N;;;;;
+1C7E;OL CHIKI PUNCTUATION MUCAAD;Po;0;L;;;;;N;;;;;
+1C7F;OL CHIKI PUNCTUATION DOUBLE MUCAAD;Po;0;L;;;;;N;;;;;
+1CD0;VEDIC TONE KARSHANA;Mn;230;NSM;;;;;N;;;;;
+1CD1;VEDIC TONE SHARA;Mn;230;NSM;;;;;N;;;;;
+1CD2;VEDIC TONE PRENKHA;Mn;230;NSM;;;;;N;;;;;
+1CD3;VEDIC SIGN NIHSHVASA;Po;0;L;;;;;N;;;;;
+1CD4;VEDIC SIGN YAJURVEDIC MIDLINE SVARITA;Mn;1;NSM;;;;;N;;;;;
+1CD5;VEDIC TONE YAJURVEDIC AGGRAVATED INDEPENDENT SVARITA;Mn;220;NSM;;;;;N;;;;;
+1CD6;VEDIC TONE YAJURVEDIC INDEPENDENT SVARITA;Mn;220;NSM;;;;;N;;;;;
+1CD7;VEDIC TONE YAJURVEDIC KATHAKA INDEPENDENT SVARITA;Mn;220;NSM;;;;;N;;;;;
+1CD8;VEDIC TONE CANDRA BELOW;Mn;220;NSM;;;;;N;;;;;
+1CD9;VEDIC TONE YAJURVEDIC KATHAKA INDEPENDENT SVARITA SCHROEDER;Mn;220;NSM;;;;;N;;;;;
+1CDA;VEDIC TONE DOUBLE SVARITA;Mn;230;NSM;;;;;N;;;;;
+1CDB;VEDIC TONE TRIPLE SVARITA;Mn;230;NSM;;;;;N;;;;;
+1CDC;VEDIC TONE KATHAKA ANUDATTA;Mn;220;NSM;;;;;N;;;;;
+1CDD;VEDIC TONE DOT BELOW;Mn;220;NSM;;;;;N;;;;;
+1CDE;VEDIC TONE TWO DOTS BELOW;Mn;220;NSM;;;;;N;;;;;
+1CDF;VEDIC TONE THREE DOTS BELOW;Mn;220;NSM;;;;;N;;;;;
+1CE0;VEDIC TONE RIGVEDIC KASHMIRI INDEPENDENT SVARITA;Mn;230;NSM;;;;;N;;;;;
+1CE1;VEDIC TONE ATHARVAVEDIC INDEPENDENT SVARITA;Mc;0;L;;;;;N;;;;;
+1CE2;VEDIC SIGN VISARGA SVARITA;Mn;1;NSM;;;;;N;;;;;
+1CE3;VEDIC SIGN VISARGA UDATTA;Mn;1;NSM;;;;;N;;;;;
+1CE4;VEDIC SIGN REVERSED VISARGA UDATTA;Mn;1;NSM;;;;;N;;;;;
+1CE5;VEDIC SIGN VISARGA ANUDATTA;Mn;1;NSM;;;;;N;;;;;
+1CE6;VEDIC SIGN REVERSED VISARGA ANUDATTA;Mn;1;NSM;;;;;N;;;;;
+1CE7;VEDIC SIGN VISARGA UDATTA WITH TAIL;Mn;1;NSM;;;;;N;;;;;
+1CE8;VEDIC SIGN VISARGA ANUDATTA WITH TAIL;Mn;1;NSM;;;;;N;;;;;
+1CE9;VEDIC SIGN ANUSVARA ANTARGOMUKHA;Lo;0;L;;;;;N;;;;;
+1CEA;VEDIC SIGN ANUSVARA BAHIRGOMUKHA;Lo;0;L;;;;;N;;;;;
+1CEB;VEDIC SIGN ANUSVARA VAMAGOMUKHA;Lo;0;L;;;;;N;;;;;
+1CEC;VEDIC SIGN ANUSVARA VAMAGOMUKHA WITH TAIL;Lo;0;L;;;;;N;;;;;
+1CED;VEDIC SIGN TIRYAK;Mn;220;NSM;;;;;N;;;;;
+1CEE;VEDIC SIGN HEXIFORM LONG ANUSVARA;Lo;0;L;;;;;N;;;;;
+1CEF;VEDIC SIGN LONG ANUSVARA;Lo;0;L;;;;;N;;;;;
+1CF0;VEDIC SIGN RTHANG LONG ANUSVARA;Lo;0;L;;;;;N;;;;;
+1CF1;VEDIC SIGN ANUSVARA UBHAYATO MUKHA;Lo;0;L;;;;;N;;;;;
+1CF2;VEDIC SIGN ARDHAVISARGA;Mc;0;L;;;;;N;;;;;
+1D00;LATIN LETTER SMALL CAPITAL A;Ll;0;L;;;;;N;;;;;
+1D01;LATIN LETTER SMALL CAPITAL AE;Ll;0;L;;;;;N;;;;;
+1D02;LATIN SMALL LETTER TURNED AE;Ll;0;L;;;;;N;;;;;
+1D03;LATIN LETTER SMALL CAPITAL BARRED B;Ll;0;L;;;;;N;;;;;
+1D04;LATIN LETTER SMALL CAPITAL C;Ll;0;L;;;;;N;;;;;
+1D05;LATIN LETTER SMALL CAPITAL D;Ll;0;L;;;;;N;;;;;
+1D06;LATIN LETTER SMALL CAPITAL ETH;Ll;0;L;;;;;N;;;;;
+1D07;LATIN LETTER SMALL CAPITAL E;Ll;0;L;;;;;N;;;;;
+1D08;LATIN SMALL LETTER TURNED OPEN E;Ll;0;L;;;;;N;;;;;
+1D09;LATIN SMALL LETTER TURNED I;Ll;0;L;;;;;N;;;;;
+1D0A;LATIN LETTER SMALL CAPITAL J;Ll;0;L;;;;;N;;;;;
+1D0B;LATIN LETTER SMALL CAPITAL K;Ll;0;L;;;;;N;;;;;
+1D0C;LATIN LETTER SMALL CAPITAL L WITH STROKE;Ll;0;L;;;;;N;;;;;
+1D0D;LATIN LETTER SMALL CAPITAL M;Ll;0;L;;;;;N;;;;;
+1D0E;LATIN LETTER SMALL CAPITAL REVERSED N;Ll;0;L;;;;;N;;;;;
+1D0F;LATIN LETTER SMALL CAPITAL O;Ll;0;L;;;;;N;;;;;
+1D10;LATIN LETTER SMALL CAPITAL OPEN O;Ll;0;L;;;;;N;;;;;
+1D11;LATIN SMALL LETTER SIDEWAYS O;Ll;0;L;;;;;N;;;;;
+1D12;LATIN SMALL LETTER SIDEWAYS OPEN O;Ll;0;L;;;;;N;;;;;
+1D13;LATIN SMALL LETTER SIDEWAYS O WITH STROKE;Ll;0;L;;;;;N;;;;;
+1D14;LATIN SMALL LETTER TURNED OE;Ll;0;L;;;;;N;;;;;
+1D15;LATIN LETTER SMALL CAPITAL OU;Ll;0;L;;;;;N;;;;;
+1D16;LATIN SMALL LETTER TOP HALF O;Ll;0;L;;;;;N;;;;;
+1D17;LATIN SMALL LETTER BOTTOM HALF O;Ll;0;L;;;;;N;;;;;
+1D18;LATIN LETTER SMALL CAPITAL P;Ll;0;L;;;;;N;;;;;
+1D19;LATIN LETTER SMALL CAPITAL REVERSED R;Ll;0;L;;;;;N;;;;;
+1D1A;LATIN LETTER SMALL CAPITAL TURNED R;Ll;0;L;;;;;N;;;;;
+1D1B;LATIN LETTER SMALL CAPITAL T;Ll;0;L;;;;;N;;;;;
+1D1C;LATIN LETTER SMALL CAPITAL U;Ll;0;L;;;;;N;;;;;
+1D1D;LATIN SMALL LETTER SIDEWAYS U;Ll;0;L;;;;;N;;;;;
+1D1E;LATIN SMALL LETTER SIDEWAYS DIAERESIZED U;Ll;0;L;;;;;N;;;;;
+1D1F;LATIN SMALL LETTER SIDEWAYS TURNED M;Ll;0;L;;;;;N;;;;;
+1D20;LATIN LETTER SMALL CAPITAL V;Ll;0;L;;;;;N;;;;;
+1D21;LATIN LETTER SMALL CAPITAL W;Ll;0;L;;;;;N;;;;;
+1D22;LATIN LETTER SMALL CAPITAL Z;Ll;0;L;;;;;N;;;;;
+1D23;LATIN LETTER SMALL CAPITAL EZH;Ll;0;L;;;;;N;;;;;
+1D24;LATIN LETTER VOICED LARYNGEAL SPIRANT;Ll;0;L;;;;;N;;;;;
+1D25;LATIN LETTER AIN;Ll;0;L;;;;;N;;;;;
+1D26;GREEK LETTER SMALL CAPITAL GAMMA;Ll;0;L;;;;;N;;;;;
+1D27;GREEK LETTER SMALL CAPITAL LAMDA;Ll;0;L;;;;;N;;;;;
+1D28;GREEK LETTER SMALL CAPITAL PI;Ll;0;L;;;;;N;;;;;
+1D29;GREEK LETTER SMALL CAPITAL RHO;Ll;0;L;;;;;N;;;;;
+1D2A;GREEK LETTER SMALL CAPITAL PSI;Ll;0;L;;;;;N;;;;;
+1D2B;CYRILLIC LETTER SMALL CAPITAL EL;Ll;0;L;;;;;N;;;;;
+1D2C;MODIFIER LETTER CAPITAL A;Lm;0;L;<super> 0041;;;;N;;;;;
+1D2D;MODIFIER LETTER CAPITAL AE;Lm;0;L;<super> 00C6;;;;N;;;;;
+1D2E;MODIFIER LETTER CAPITAL B;Lm;0;L;<super> 0042;;;;N;;;;;
+1D2F;MODIFIER LETTER CAPITAL BARRED B;Lm;0;L;;;;;N;;;;;
+1D30;MODIFIER LETTER CAPITAL D;Lm;0;L;<super> 0044;;;;N;;;;;
+1D31;MODIFIER LETTER CAPITAL E;Lm;0;L;<super> 0045;;;;N;;;;;
+1D32;MODIFIER LETTER CAPITAL REVERSED E;Lm;0;L;<super> 018E;;;;N;;;;;
+1D33;MODIFIER LETTER CAPITAL G;Lm;0;L;<super> 0047;;;;N;;;;;
+1D34;MODIFIER LETTER CAPITAL H;Lm;0;L;<super> 0048;;;;N;;;;;
+1D35;MODIFIER LETTER CAPITAL I;Lm;0;L;<super> 0049;;;;N;;;;;
+1D36;MODIFIER LETTER CAPITAL J;Lm;0;L;<super> 004A;;;;N;;;;;
+1D37;MODIFIER LETTER CAPITAL K;Lm;0;L;<super> 004B;;;;N;;;;;
+1D38;MODIFIER LETTER CAPITAL L;Lm;0;L;<super> 004C;;;;N;;;;;
+1D39;MODIFIER LETTER CAPITAL M;Lm;0;L;<super> 004D;;;;N;;;;;
+1D3A;MODIFIER LETTER CAPITAL N;Lm;0;L;<super> 004E;;;;N;;;;;
+1D3B;MODIFIER LETTER CAPITAL REVERSED N;Lm;0;L;;;;;N;;;;;
+1D3C;MODIFIER LETTER CAPITAL O;Lm;0;L;<super> 004F;;;;N;;;;;
+1D3D;MODIFIER LETTER CAPITAL OU;Lm;0;L;<super> 0222;;;;N;;;;;
+1D3E;MODIFIER LETTER CAPITAL P;Lm;0;L;<super> 0050;;;;N;;;;;
+1D3F;MODIFIER LETTER CAPITAL R;Lm;0;L;<super> 0052;;;;N;;;;;
+1D40;MODIFIER LETTER CAPITAL T;Lm;0;L;<super> 0054;;;;N;;;;;
+1D41;MODIFIER LETTER CAPITAL U;Lm;0;L;<super> 0055;;;;N;;;;;
+1D42;MODIFIER LETTER CAPITAL W;Lm;0;L;<super> 0057;;;;N;;;;;
+1D43;MODIFIER LETTER SMALL A;Lm;0;L;<super> 0061;;;;N;;;;;
+1D44;MODIFIER LETTER SMALL TURNED A;Lm;0;L;<super> 0250;;;;N;;;;;
+1D45;MODIFIER LETTER SMALL ALPHA;Lm;0;L;<super> 0251;;;;N;;;;;
+1D46;MODIFIER LETTER SMALL TURNED AE;Lm;0;L;<super> 1D02;;;;N;;;;;
+1D47;MODIFIER LETTER SMALL B;Lm;0;L;<super> 0062;;;;N;;;;;
+1D48;MODIFIER LETTER SMALL D;Lm;0;L;<super> 0064;;;;N;;;;;
+1D49;MODIFIER LETTER SMALL E;Lm;0;L;<super> 0065;;;;N;;;;;
+1D4A;MODIFIER LETTER SMALL SCHWA;Lm;0;L;<super> 0259;;;;N;;;;;
+1D4B;MODIFIER LETTER SMALL OPEN E;Lm;0;L;<super> 025B;;;;N;;;;;
+1D4C;MODIFIER LETTER SMALL TURNED OPEN E;Lm;0;L;<super> 025C;;;;N;;;;;
+1D4D;MODIFIER LETTER SMALL G;Lm;0;L;<super> 0067;;;;N;;;;;
+1D4E;MODIFIER LETTER SMALL TURNED I;Lm;0;L;;;;;N;;;;;
+1D4F;MODIFIER LETTER SMALL K;Lm;0;L;<super> 006B;;;;N;;;;;
+1D50;MODIFIER LETTER SMALL M;Lm;0;L;<super> 006D;;;;N;;;;;
+1D51;MODIFIER LETTER SMALL ENG;Lm;0;L;<super> 014B;;;;N;;;;;
+1D52;MODIFIER LETTER SMALL O;Lm;0;L;<super> 006F;;;;N;;;;;
+1D53;MODIFIER LETTER SMALL OPEN O;Lm;0;L;<super> 0254;;;;N;;;;;
+1D54;MODIFIER LETTER SMALL TOP HALF O;Lm;0;L;<super> 1D16;;;;N;;;;;
+1D55;MODIFIER LETTER SMALL BOTTOM HALF O;Lm;0;L;<super> 1D17;;;;N;;;;;
+1D56;MODIFIER LETTER SMALL P;Lm;0;L;<super> 0070;;;;N;;;;;
+1D57;MODIFIER LETTER SMALL T;Lm;0;L;<super> 0074;;;;N;;;;;
+1D58;MODIFIER LETTER SMALL U;Lm;0;L;<super> 0075;;;;N;;;;;
+1D59;MODIFIER LETTER SMALL SIDEWAYS U;Lm;0;L;<super> 1D1D;;;;N;;;;;
+1D5A;MODIFIER LETTER SMALL TURNED M;Lm;0;L;<super> 026F;;;;N;;;;;
+1D5B;MODIFIER LETTER SMALL V;Lm;0;L;<super> 0076;;;;N;;;;;
+1D5C;MODIFIER LETTER SMALL AIN;Lm;0;L;<super> 1D25;;;;N;;;;;
+1D5D;MODIFIER LETTER SMALL BETA;Lm;0;L;<super> 03B2;;;;N;;;;;
+1D5E;MODIFIER LETTER SMALL GREEK GAMMA;Lm;0;L;<super> 03B3;;;;N;;;;;
+1D5F;MODIFIER LETTER SMALL DELTA;Lm;0;L;<super> 03B4;;;;N;;;;;
+1D60;MODIFIER LETTER SMALL GREEK PHI;Lm;0;L;<super> 03C6;;;;N;;;;;
+1D61;MODIFIER LETTER SMALL CHI;Lm;0;L;<super> 03C7;;;;N;;;;;
+1D62;LATIN SUBSCRIPT SMALL LETTER I;Ll;0;L;<sub> 0069;;;;N;;;;;
+1D63;LATIN SUBSCRIPT SMALL LETTER R;Ll;0;L;<sub> 0072;;;;N;;;;;
+1D64;LATIN SUBSCRIPT SMALL LETTER U;Ll;0;L;<sub> 0075;;;;N;;;;;
+1D65;LATIN SUBSCRIPT SMALL LETTER V;Ll;0;L;<sub> 0076;;;;N;;;;;
+1D66;GREEK SUBSCRIPT SMALL LETTER BETA;Ll;0;L;<sub> 03B2;;;;N;;;;;
+1D67;GREEK SUBSCRIPT SMALL LETTER GAMMA;Ll;0;L;<sub> 03B3;;;;N;;;;;
+1D68;GREEK SUBSCRIPT SMALL LETTER RHO;Ll;0;L;<sub> 03C1;;;;N;;;;;
+1D69;GREEK SUBSCRIPT SMALL LETTER PHI;Ll;0;L;<sub> 03C6;;;;N;;;;;
+1D6A;GREEK SUBSCRIPT SMALL LETTER CHI;Ll;0;L;<sub> 03C7;;;;N;;;;;
+1D6B;LATIN SMALL LETTER UE;Ll;0;L;;;;;N;;;;;
+1D6C;LATIN SMALL LETTER B WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;;;
+1D6D;LATIN SMALL LETTER D WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;;;
+1D6E;LATIN SMALL LETTER F WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;;;
+1D6F;LATIN SMALL LETTER M WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;;;
+1D70;LATIN SMALL LETTER N WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;;;
+1D71;LATIN SMALL LETTER P WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;;;
+1D72;LATIN SMALL LETTER R WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;;;
+1D73;LATIN SMALL LETTER R WITH FISHHOOK AND MIDDLE TILDE;Ll;0;L;;;;;N;;;;;
+1D74;LATIN SMALL LETTER S WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;;;
+1D75;LATIN SMALL LETTER T WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;;;
+1D76;LATIN SMALL LETTER Z WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;;;
+1D77;LATIN SMALL LETTER TURNED G;Ll;0;L;;;;;N;;;;;
+1D78;MODIFIER LETTER CYRILLIC EN;Lm;0;L;<super> 043D;;;;N;;;;;
+1D79;LATIN SMALL LETTER INSULAR G;Ll;0;L;;;;;N;;;A77D;;A77D
+1D7A;LATIN SMALL LETTER TH WITH STRIKETHROUGH;Ll;0;L;;;;;N;;;;;
+1D7B;LATIN SMALL CAPITAL LETTER I WITH STROKE;Ll;0;L;;;;;N;;;;;
+1D7C;LATIN SMALL LETTER IOTA WITH STROKE;Ll;0;L;;;;;N;;;;;
+1D7D;LATIN SMALL LETTER P WITH STROKE;Ll;0;L;;;;;N;;;2C63;;2C63
+1D7E;LATIN SMALL CAPITAL LETTER U WITH STROKE;Ll;0;L;;;;;N;;;;;
+1D7F;LATIN SMALL LETTER UPSILON WITH STROKE;Ll;0;L;;;;;N;;;;;
+1D80;LATIN SMALL LETTER B WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;
+1D81;LATIN SMALL LETTER D WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;
+1D82;LATIN SMALL LETTER F WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;
+1D83;LATIN SMALL LETTER G WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;
+1D84;LATIN SMALL LETTER K WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;
+1D85;LATIN SMALL LETTER L WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;
+1D86;LATIN SMALL LETTER M WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;
+1D87;LATIN SMALL LETTER N WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;
+1D88;LATIN SMALL LETTER P WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;
+1D89;LATIN SMALL LETTER R WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;
+1D8A;LATIN SMALL LETTER S WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;
+1D8B;LATIN SMALL LETTER ESH WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;
+1D8C;LATIN SMALL LETTER V WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;
+1D8D;LATIN SMALL LETTER X WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;
+1D8E;LATIN SMALL LETTER Z WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;
+1D8F;LATIN SMALL LETTER A WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;;
+1D90;LATIN SMALL LETTER ALPHA WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;;
+1D91;LATIN SMALL LETTER D WITH HOOK AND TAIL;Ll;0;L;;;;;N;;;;;
+1D92;LATIN SMALL LETTER E WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;;
+1D93;LATIN SMALL LETTER OPEN E WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;;
+1D94;LATIN SMALL LETTER REVERSED OPEN E WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;;
+1D95;LATIN SMALL LETTER SCHWA WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;;
+1D96;LATIN SMALL LETTER I WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;;
+1D97;LATIN SMALL LETTER OPEN O WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;;
+1D98;LATIN SMALL LETTER ESH WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;;
+1D99;LATIN SMALL LETTER U WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;;
+1D9A;LATIN SMALL LETTER EZH WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;;
+1D9B;MODIFIER LETTER SMALL TURNED ALPHA;Lm;0;L;<super> 0252;;;;N;;;;;
+1D9C;MODIFIER LETTER SMALL C;Lm;0;L;<super> 0063;;;;N;;;;;
+1D9D;MODIFIER LETTER SMALL C WITH CURL;Lm;0;L;<super> 0255;;;;N;;;;;
+1D9E;MODIFIER LETTER SMALL ETH;Lm;0;L;<super> 00F0;;;;N;;;;;
+1D9F;MODIFIER LETTER SMALL REVERSED OPEN E;Lm;0;L;<super> 025C;;;;N;;;;;
+1DA0;MODIFIER LETTER SMALL F;Lm;0;L;<super> 0066;;;;N;;;;;
+1DA1;MODIFIER LETTER SMALL DOTLESS J WITH STROKE;Lm;0;L;<super> 025F;;;;N;;;;;
+1DA2;MODIFIER LETTER SMALL SCRIPT G;Lm;0;L;<super> 0261;;;;N;;;;;
+1DA3;MODIFIER LETTER SMALL TURNED H;Lm;0;L;<super> 0265;;;;N;;;;;
+1DA4;MODIFIER LETTER SMALL I WITH STROKE;Lm;0;L;<super> 0268;;;;N;;;;;
+1DA5;MODIFIER LETTER SMALL IOTA;Lm;0;L;<super> 0269;;;;N;;;;;
+1DA6;MODIFIER LETTER SMALL CAPITAL I;Lm;0;L;<super> 026A;;;;N;;;;;
+1DA7;MODIFIER LETTER SMALL CAPITAL I WITH STROKE;Lm;0;L;<super> 1D7B;;;;N;;;;;
+1DA8;MODIFIER LETTER SMALL J WITH CROSSED-TAIL;Lm;0;L;<super> 029D;;;;N;;;;;
+1DA9;MODIFIER LETTER SMALL L WITH RETROFLEX HOOK;Lm;0;L;<super> 026D;;;;N;;;;;
+1DAA;MODIFIER LETTER SMALL L WITH PALATAL HOOK;Lm;0;L;<super> 1D85;;;;N;;;;;
+1DAB;MODIFIER LETTER SMALL CAPITAL L;Lm;0;L;<super> 029F;;;;N;;;;;
+1DAC;MODIFIER LETTER SMALL M WITH HOOK;Lm;0;L;<super> 0271;;;;N;;;;;
+1DAD;MODIFIER LETTER SMALL TURNED M WITH LONG LEG;Lm;0;L;<super> 0270;;;;N;;;;;
+1DAE;MODIFIER LETTER SMALL N WITH LEFT HOOK;Lm;0;L;<super> 0272;;;;N;;;;;
+1DAF;MODIFIER LETTER SMALL N WITH RETROFLEX HOOK;Lm;0;L;<super> 0273;;;;N;;;;;
+1DB0;MODIFIER LETTER SMALL CAPITAL N;Lm;0;L;<super> 0274;;;;N;;;;;
+1DB1;MODIFIER LETTER SMALL BARRED O;Lm;0;L;<super> 0275;;;;N;;;;;
+1DB2;MODIFIER LETTER SMALL PHI;Lm;0;L;<super> 0278;;;;N;;;;;
+1DB3;MODIFIER LETTER SMALL S WITH HOOK;Lm;0;L;<super> 0282;;;;N;;;;;
+1DB4;MODIFIER LETTER SMALL ESH;Lm;0;L;<super> 0283;;;;N;;;;;
+1DB5;MODIFIER LETTER SMALL T WITH PALATAL HOOK;Lm;0;L;<super> 01AB;;;;N;;;;;
+1DB6;MODIFIER LETTER SMALL U BAR;Lm;0;L;<super> 0289;;;;N;;;;;
+1DB7;MODIFIER LETTER SMALL UPSILON;Lm;0;L;<super> 028A;;;;N;;;;;
+1DB8;MODIFIER LETTER SMALL CAPITAL U;Lm;0;L;<super> 1D1C;;;;N;;;;;
+1DB9;MODIFIER LETTER SMALL V WITH HOOK;Lm;0;L;<super> 028B;;;;N;;;;;
+1DBA;MODIFIER LETTER SMALL TURNED V;Lm;0;L;<super> 028C;;;;N;;;;;
+1DBB;MODIFIER LETTER SMALL Z;Lm;0;L;<super> 007A;;;;N;;;;;
+1DBC;MODIFIER LETTER SMALL Z WITH RETROFLEX HOOK;Lm;0;L;<super> 0290;;;;N;;;;;
+1DBD;MODIFIER LETTER SMALL Z WITH CURL;Lm;0;L;<super> 0291;;;;N;;;;;
+1DBE;MODIFIER LETTER SMALL EZH;Lm;0;L;<super> 0292;;;;N;;;;;
+1DBF;MODIFIER LETTER SMALL THETA;Lm;0;L;<super> 03B8;;;;N;;;;;
+1DC0;COMBINING DOTTED GRAVE ACCENT;Mn;230;NSM;;;;;N;;;;;
+1DC1;COMBINING DOTTED ACUTE ACCENT;Mn;230;NSM;;;;;N;;;;;
+1DC2;COMBINING SNAKE BELOW;Mn;220;NSM;;;;;N;;;;;
+1DC3;COMBINING SUSPENSION MARK;Mn;230;NSM;;;;;N;;;;;
+1DC4;COMBINING MACRON-ACUTE;Mn;230;NSM;;;;;N;;;;;
+1DC5;COMBINING GRAVE-MACRON;Mn;230;NSM;;;;;N;;;;;
+1DC6;COMBINING MACRON-GRAVE;Mn;230;NSM;;;;;N;;;;;
+1DC7;COMBINING ACUTE-MACRON;Mn;230;NSM;;;;;N;;;;;
+1DC8;COMBINING GRAVE-ACUTE-GRAVE;Mn;230;NSM;;;;;N;;;;;
+1DC9;COMBINING ACUTE-GRAVE-ACUTE;Mn;230;NSM;;;;;N;;;;;
+1DCA;COMBINING LATIN SMALL LETTER R BELOW;Mn;220;NSM;;;;;N;;;;;
+1DCB;COMBINING BREVE-MACRON;Mn;230;NSM;;;;;N;;;;;
+1DCC;COMBINING MACRON-BREVE;Mn;230;NSM;;;;;N;;;;;
+1DCD;COMBINING DOUBLE CIRCUMFLEX ABOVE;Mn;234;NSM;;;;;N;;;;;
+1DCE;COMBINING OGONEK ABOVE;Mn;214;NSM;;;;;N;;;;;
+1DCF;COMBINING ZIGZAG BELOW;Mn;220;NSM;;;;;N;;;;;
+1DD0;COMBINING IS BELOW;Mn;202;NSM;;;;;N;;;;;
+1DD1;COMBINING UR ABOVE;Mn;230;NSM;;;;;N;;;;;
+1DD2;COMBINING US ABOVE;Mn;230;NSM;;;;;N;;;;;
+1DD3;COMBINING LATIN SMALL LETTER FLATTENED OPEN A ABOVE;Mn;230;NSM;;;;;N;;;;;
+1DD4;COMBINING LATIN SMALL LETTER AE;Mn;230;NSM;;;;;N;;;;;
+1DD5;COMBINING LATIN SMALL LETTER AO;Mn;230;NSM;;;;;N;;;;;
+1DD6;COMBINING LATIN SMALL LETTER AV;Mn;230;NSM;;;;;N;;;;;
+1DD7;COMBINING LATIN SMALL LETTER C CEDILLA;Mn;230;NSM;;;;;N;;;;;
+1DD8;COMBINING LATIN SMALL LETTER INSULAR D;Mn;230;NSM;;;;;N;;;;;
+1DD9;COMBINING LATIN SMALL LETTER ETH;Mn;230;NSM;;;;;N;;;;;
+1DDA;COMBINING LATIN SMALL LETTER G;Mn;230;NSM;;;;;N;;;;;
+1DDB;COMBINING LATIN LETTER SMALL CAPITAL G;Mn;230;NSM;;;;;N;;;;;
+1DDC;COMBINING LATIN SMALL LETTER K;Mn;230;NSM;;;;;N;;;;;
+1DDD;COMBINING LATIN SMALL LETTER L;Mn;230;NSM;;;;;N;;;;;
+1DDE;COMBINING LATIN LETTER SMALL CAPITAL L;Mn;230;NSM;;;;;N;;;;;
+1DDF;COMBINING LATIN LETTER SMALL CAPITAL M;Mn;230;NSM;;;;;N;;;;;
+1DE0;COMBINING LATIN SMALL LETTER N;Mn;230;NSM;;;;;N;;;;;
+1DE1;COMBINING LATIN LETTER SMALL CAPITAL N;Mn;230;NSM;;;;;N;;;;;
+1DE2;COMBINING LATIN LETTER SMALL CAPITAL R;Mn;230;NSM;;;;;N;;;;;
+1DE3;COMBINING LATIN SMALL LETTER R ROTUNDA;Mn;230;NSM;;;;;N;;;;;
+1DE4;COMBINING LATIN SMALL LETTER S;Mn;230;NSM;;;;;N;;;;;
+1DE5;COMBINING LATIN SMALL LETTER LONG S;Mn;230;NSM;;;;;N;;;;;
+1DE6;COMBINING LATIN SMALL LETTER Z;Mn;230;NSM;;;;;N;;;;;
+1DFC;COMBINING DOUBLE INVERTED BREVE BELOW;Mn;233;NSM;;;;;N;;;;;
+1DFD;COMBINING ALMOST EQUAL TO BELOW;Mn;220;NSM;;;;;N;;;;;
+1DFE;COMBINING LEFT ARROWHEAD ABOVE;Mn;230;NSM;;;;;N;;;;;
+1DFF;COMBINING RIGHT ARROWHEAD AND DOWN ARROWHEAD BELOW;Mn;220;NSM;;;;;N;;;;;
+1E00;LATIN CAPITAL LETTER A WITH RING BELOW;Lu;0;L;0041 0325;;;;N;;;;1E01;
+1E01;LATIN SMALL LETTER A WITH RING BELOW;Ll;0;L;0061 0325;;;;N;;;1E00;;1E00
+1E02;LATIN CAPITAL LETTER B WITH DOT ABOVE;Lu;0;L;0042 0307;;;;N;;;;1E03;
+1E03;LATIN SMALL LETTER B WITH DOT ABOVE;Ll;0;L;0062 0307;;;;N;;;1E02;;1E02
+1E04;LATIN CAPITAL LETTER B WITH DOT BELOW;Lu;0;L;0042 0323;;;;N;;;;1E05;
+1E05;LATIN SMALL LETTER B WITH DOT BELOW;Ll;0;L;0062 0323;;;;N;;;1E04;;1E04
+1E06;LATIN CAPITAL LETTER B WITH LINE BELOW;Lu;0;L;0042 0331;;;;N;;;;1E07;
+1E07;LATIN SMALL LETTER B WITH LINE BELOW;Ll;0;L;0062 0331;;;;N;;;1E06;;1E06
+1E08;LATIN CAPITAL LETTER C WITH CEDILLA AND ACUTE;Lu;0;L;00C7 0301;;;;N;;;;1E09;
+1E09;LATIN SMALL LETTER C WITH CEDILLA AND ACUTE;Ll;0;L;00E7 0301;;;;N;;;1E08;;1E08
+1E0A;LATIN CAPITAL LETTER D WITH DOT ABOVE;Lu;0;L;0044 0307;;;;N;;;;1E0B;
+1E0B;LATIN SMALL LETTER D WITH DOT ABOVE;Ll;0;L;0064 0307;;;;N;;;1E0A;;1E0A
+1E0C;LATIN CAPITAL LETTER D WITH DOT BELOW;Lu;0;L;0044 0323;;;;N;;;;1E0D;
+1E0D;LATIN SMALL LETTER D WITH DOT BELOW;Ll;0;L;0064 0323;;;;N;;;1E0C;;1E0C
+1E0E;LATIN CAPITAL LETTER D WITH LINE BELOW;Lu;0;L;0044 0331;;;;N;;;;1E0F;
+1E0F;LATIN SMALL LETTER D WITH LINE BELOW;Ll;0;L;0064 0331;;;;N;;;1E0E;;1E0E
+1E10;LATIN CAPITAL LETTER D WITH CEDILLA;Lu;0;L;0044 0327;;;;N;;;;1E11;
+1E11;LATIN SMALL LETTER D WITH CEDILLA;Ll;0;L;0064 0327;;;;N;;;1E10;;1E10
+1E12;LATIN CAPITAL LETTER D WITH CIRCUMFLEX BELOW;Lu;0;L;0044 032D;;;;N;;;;1E13;
+1E13;LATIN SMALL LETTER D WITH CIRCUMFLEX BELOW;Ll;0;L;0064 032D;;;;N;;;1E12;;1E12
+1E14;LATIN CAPITAL LETTER E WITH MACRON AND GRAVE;Lu;0;L;0112 0300;;;;N;;;;1E15;
+1E15;LATIN SMALL LETTER E WITH MACRON AND GRAVE;Ll;0;L;0113 0300;;;;N;;;1E14;;1E14
+1E16;LATIN CAPITAL LETTER E WITH MACRON AND ACUTE;Lu;0;L;0112 0301;;;;N;;;;1E17;
+1E17;LATIN SMALL LETTER E WITH MACRON AND ACUTE;Ll;0;L;0113 0301;;;;N;;;1E16;;1E16
+1E18;LATIN CAPITAL LETTER E WITH CIRCUMFLEX BELOW;Lu;0;L;0045 032D;;;;N;;;;1E19;
+1E19;LATIN SMALL LETTER E WITH CIRCUMFLEX BELOW;Ll;0;L;0065 032D;;;;N;;;1E18;;1E18
+1E1A;LATIN CAPITAL LETTER E WITH TILDE BELOW;Lu;0;L;0045 0330;;;;N;;;;1E1B;
+1E1B;LATIN SMALL LETTER E WITH TILDE BELOW;Ll;0;L;0065 0330;;;;N;;;1E1A;;1E1A
+1E1C;LATIN CAPITAL LETTER E WITH CEDILLA AND BREVE;Lu;0;L;0228 0306;;;;N;;;;1E1D;
+1E1D;LATIN SMALL LETTER E WITH CEDILLA AND BREVE;Ll;0;L;0229 0306;;;;N;;;1E1C;;1E1C
+1E1E;LATIN CAPITAL LETTER F WITH DOT ABOVE;Lu;0;L;0046 0307;;;;N;;;;1E1F;
+1E1F;LATIN SMALL LETTER F WITH DOT ABOVE;Ll;0;L;0066 0307;;;;N;;;1E1E;;1E1E
+1E20;LATIN CAPITAL LETTER G WITH MACRON;Lu;0;L;0047 0304;;;;N;;;;1E21;
+1E21;LATIN SMALL LETTER G WITH MACRON;Ll;0;L;0067 0304;;;;N;;;1E20;;1E20
+1E22;LATIN CAPITAL LETTER H WITH DOT ABOVE;Lu;0;L;0048 0307;;;;N;;;;1E23;
+1E23;LATIN SMALL LETTER H WITH DOT ABOVE;Ll;0;L;0068 0307;;;;N;;;1E22;;1E22
+1E24;LATIN CAPITAL LETTER H WITH DOT BELOW;Lu;0;L;0048 0323;;;;N;;;;1E25;
+1E25;LATIN SMALL LETTER H WITH DOT BELOW;Ll;0;L;0068 0323;;;;N;;;1E24;;1E24
+1E26;LATIN CAPITAL LETTER H WITH DIAERESIS;Lu;0;L;0048 0308;;;;N;;;;1E27;
+1E27;LATIN SMALL LETTER H WITH DIAERESIS;Ll;0;L;0068 0308;;;;N;;;1E26;;1E26
+1E28;LATIN CAPITAL LETTER H WITH CEDILLA;Lu;0;L;0048 0327;;;;N;;;;1E29;
+1E29;LATIN SMALL LETTER H WITH CEDILLA;Ll;0;L;0068 0327;;;;N;;;1E28;;1E28
+1E2A;LATIN CAPITAL LETTER H WITH BREVE BELOW;Lu;0;L;0048 032E;;;;N;;;;1E2B;
+1E2B;LATIN SMALL LETTER H WITH BREVE BELOW;Ll;0;L;0068 032E;;;;N;;;1E2A;;1E2A
+1E2C;LATIN CAPITAL LETTER I WITH TILDE BELOW;Lu;0;L;0049 0330;;;;N;;;;1E2D;
+1E2D;LATIN SMALL LETTER I WITH TILDE BELOW;Ll;0;L;0069 0330;;;;N;;;1E2C;;1E2C
+1E2E;LATIN CAPITAL LETTER I WITH DIAERESIS AND ACUTE;Lu;0;L;00CF 0301;;;;N;;;;1E2F;
+1E2F;LATIN SMALL LETTER I WITH DIAERESIS AND ACUTE;Ll;0;L;00EF 0301;;;;N;;;1E2E;;1E2E
+1E30;LATIN CAPITAL LETTER K WITH ACUTE;Lu;0;L;004B 0301;;;;N;;;;1E31;
+1E31;LATIN SMALL LETTER K WITH ACUTE;Ll;0;L;006B 0301;;;;N;;;1E30;;1E30
+1E32;LATIN CAPITAL LETTER K WITH DOT BELOW;Lu;0;L;004B 0323;;;;N;;;;1E33;
+1E33;LATIN SMALL LETTER K WITH DOT BELOW;Ll;0;L;006B 0323;;;;N;;;1E32;;1E32
+1E34;LATIN CAPITAL LETTER K WITH LINE BELOW;Lu;0;L;004B 0331;;;;N;;;;1E35;
+1E35;LATIN SMALL LETTER K WITH LINE BELOW;Ll;0;L;006B 0331;;;;N;;;1E34;;1E34
+1E36;LATIN CAPITAL LETTER L WITH DOT BELOW;Lu;0;L;004C 0323;;;;N;;;;1E37;
+1E37;LATIN SMALL LETTER L WITH DOT BELOW;Ll;0;L;006C 0323;;;;N;;;1E36;;1E36
+1E38;LATIN CAPITAL LETTER L WITH DOT BELOW AND MACRON;Lu;0;L;1E36 0304;;;;N;;;;1E39;
+1E39;LATIN SMALL LETTER L WITH DOT BELOW AND MACRON;Ll;0;L;1E37 0304;;;;N;;;1E38;;1E38
+1E3A;LATIN CAPITAL LETTER L WITH LINE BELOW;Lu;0;L;004C 0331;;;;N;;;;1E3B;
+1E3B;LATIN SMALL LETTER L WITH LINE BELOW;Ll;0;L;006C 0331;;;;N;;;1E3A;;1E3A
+1E3C;LATIN CAPITAL LETTER L WITH CIRCUMFLEX BELOW;Lu;0;L;004C 032D;;;;N;;;;1E3D;
+1E3D;LATIN SMALL LETTER L WITH CIRCUMFLEX BELOW;Ll;0;L;006C 032D;;;;N;;;1E3C;;1E3C
+1E3E;LATIN CAPITAL LETTER M WITH ACUTE;Lu;0;L;004D 0301;;;;N;;;;1E3F;
+1E3F;LATIN SMALL LETTER M WITH ACUTE;Ll;0;L;006D 0301;;;;N;;;1E3E;;1E3E
+1E40;LATIN CAPITAL LETTER M WITH DOT ABOVE;Lu;0;L;004D 0307;;;;N;;;;1E41;
+1E41;LATIN SMALL LETTER M WITH DOT ABOVE;Ll;0;L;006D 0307;;;;N;;;1E40;;1E40
+1E42;LATIN CAPITAL LETTER M WITH DOT BELOW;Lu;0;L;004D 0323;;;;N;;;;1E43;
+1E43;LATIN SMALL LETTER M WITH DOT BELOW;Ll;0;L;006D 0323;;;;N;;;1E42;;1E42
+1E44;LATIN CAPITAL LETTER N WITH DOT ABOVE;Lu;0;L;004E 0307;;;;N;;;;1E45;
+1E45;LATIN SMALL LETTER N WITH DOT ABOVE;Ll;0;L;006E 0307;;;;N;;;1E44;;1E44
+1E46;LATIN CAPITAL LETTER N WITH DOT BELOW;Lu;0;L;004E 0323;;;;N;;;;1E47;
+1E47;LATIN SMALL LETTER N WITH DOT BELOW;Ll;0;L;006E 0323;;;;N;;;1E46;;1E46
+1E48;LATIN CAPITAL LETTER N WITH LINE BELOW;Lu;0;L;004E 0331;;;;N;;;;1E49;
+1E49;LATIN SMALL LETTER N WITH LINE BELOW;Ll;0;L;006E 0331;;;;N;;;1E48;;1E48
+1E4A;LATIN CAPITAL LETTER N WITH CIRCUMFLEX BELOW;Lu;0;L;004E 032D;;;;N;;;;1E4B;
+1E4B;LATIN SMALL LETTER N WITH CIRCUMFLEX BELOW;Ll;0;L;006E 032D;;;;N;;;1E4A;;1E4A
+1E4C;LATIN CAPITAL LETTER O WITH TILDE AND ACUTE;Lu;0;L;00D5 0301;;;;N;;;;1E4D;
+1E4D;LATIN SMALL LETTER O WITH TILDE AND ACUTE;Ll;0;L;00F5 0301;;;;N;;;1E4C;;1E4C
+1E4E;LATIN CAPITAL LETTER O WITH TILDE AND DIAERESIS;Lu;0;L;00D5 0308;;;;N;;;;1E4F;
+1E4F;LATIN SMALL LETTER O WITH TILDE AND DIAERESIS;Ll;0;L;00F5 0308;;;;N;;;1E4E;;1E4E
+1E50;LATIN CAPITAL LETTER O WITH MACRON AND GRAVE;Lu;0;L;014C 0300;;;;N;;;;1E51;
+1E51;LATIN SMALL LETTER O WITH MACRON AND GRAVE;Ll;0;L;014D 0300;;;;N;;;1E50;;1E50
+1E52;LATIN CAPITAL LETTER O WITH MACRON AND ACUTE;Lu;0;L;014C 0301;;;;N;;;;1E53;
+1E53;LATIN SMALL LETTER O WITH MACRON AND ACUTE;Ll;0;L;014D 0301;;;;N;;;1E52;;1E52
+1E54;LATIN CAPITAL LETTER P WITH ACUTE;Lu;0;L;0050 0301;;;;N;;;;1E55;
+1E55;LATIN SMALL LETTER P WITH ACUTE;Ll;0;L;0070 0301;;;;N;;;1E54;;1E54
+1E56;LATIN CAPITAL LETTER P WITH DOT ABOVE;Lu;0;L;0050 0307;;;;N;;;;1E57;
+1E57;LATIN SMALL LETTER P WITH DOT ABOVE;Ll;0;L;0070 0307;;;;N;;;1E56;;1E56
+1E58;LATIN CAPITAL LETTER R WITH DOT ABOVE;Lu;0;L;0052 0307;;;;N;;;;1E59;
+1E59;LATIN SMALL LETTER R WITH DOT ABOVE;Ll;0;L;0072 0307;;;;N;;;1E58;;1E58
+1E5A;LATIN CAPITAL LETTER R WITH DOT BELOW;Lu;0;L;0052 0323;;;;N;;;;1E5B;
+1E5B;LATIN SMALL LETTER R WITH DOT BELOW;Ll;0;L;0072 0323;;;;N;;;1E5A;;1E5A
+1E5C;LATIN CAPITAL LETTER R WITH DOT BELOW AND MACRON;Lu;0;L;1E5A 0304;;;;N;;;;1E5D;
+1E5D;LATIN SMALL LETTER R WITH DOT BELOW AND MACRON;Ll;0;L;1E5B 0304;;;;N;;;1E5C;;1E5C
+1E5E;LATIN CAPITAL LETTER R WITH LINE BELOW;Lu;0;L;0052 0331;;;;N;;;;1E5F;
+1E5F;LATIN SMALL LETTER R WITH LINE BELOW;Ll;0;L;0072 0331;;;;N;;;1E5E;;1E5E
+1E60;LATIN CAPITAL LETTER S WITH DOT ABOVE;Lu;0;L;0053 0307;;;;N;;;;1E61;
+1E61;LATIN SMALL LETTER S WITH DOT ABOVE;Ll;0;L;0073 0307;;;;N;;;1E60;;1E60
+1E62;LATIN CAPITAL LETTER S WITH DOT BELOW;Lu;0;L;0053 0323;;;;N;;;;1E63;
+1E63;LATIN SMALL LETTER S WITH DOT BELOW;Ll;0;L;0073 0323;;;;N;;;1E62;;1E62
+1E64;LATIN CAPITAL LETTER S WITH ACUTE AND DOT ABOVE;Lu;0;L;015A 0307;;;;N;;;;1E65;
+1E65;LATIN SMALL LETTER S WITH ACUTE AND DOT ABOVE;Ll;0;L;015B 0307;;;;N;;;1E64;;1E64
+1E66;LATIN CAPITAL LETTER S WITH CARON AND DOT ABOVE;Lu;0;L;0160 0307;;;;N;;;;1E67;
+1E67;LATIN SMALL LETTER S WITH CARON AND DOT ABOVE;Ll;0;L;0161 0307;;;;N;;;1E66;;1E66
+1E68;LATIN CAPITAL LETTER S WITH DOT BELOW AND DOT ABOVE;Lu;0;L;1E62 0307;;;;N;;;;1E69;
+1E69;LATIN SMALL LETTER S WITH DOT BELOW AND DOT ABOVE;Ll;0;L;1E63 0307;;;;N;;;1E68;;1E68
+1E6A;LATIN CAPITAL LETTER T WITH DOT ABOVE;Lu;0;L;0054 0307;;;;N;;;;1E6B;
+1E6B;LATIN SMALL LETTER T WITH DOT ABOVE;Ll;0;L;0074 0307;;;;N;;;1E6A;;1E6A
+1E6C;LATIN CAPITAL LETTER T WITH DOT BELOW;Lu;0;L;0054 0323;;;;N;;;;1E6D;
+1E6D;LATIN SMALL LETTER T WITH DOT BELOW;Ll;0;L;0074 0323;;;;N;;;1E6C;;1E6C
+1E6E;LATIN CAPITAL LETTER T WITH LINE BELOW;Lu;0;L;0054 0331;;;;N;;;;1E6F;
+1E6F;LATIN SMALL LETTER T WITH LINE BELOW;Ll;0;L;0074 0331;;;;N;;;1E6E;;1E6E
+1E70;LATIN CAPITAL LETTER T WITH CIRCUMFLEX BELOW;Lu;0;L;0054 032D;;;;N;;;;1E71;
+1E71;LATIN SMALL LETTER T WITH CIRCUMFLEX BELOW;Ll;0;L;0074 032D;;;;N;;;1E70;;1E70
+1E72;LATIN CAPITAL LETTER U WITH DIAERESIS BELOW;Lu;0;L;0055 0324;;;;N;;;;1E73;
+1E73;LATIN SMALL LETTER U WITH DIAERESIS BELOW;Ll;0;L;0075 0324;;;;N;;;1E72;;1E72
+1E74;LATIN CAPITAL LETTER U WITH TILDE BELOW;Lu;0;L;0055 0330;;;;N;;;;1E75;
+1E75;LATIN SMALL LETTER U WITH TILDE BELOW;Ll;0;L;0075 0330;;;;N;;;1E74;;1E74
+1E76;LATIN CAPITAL LETTER U WITH CIRCUMFLEX BELOW;Lu;0;L;0055 032D;;;;N;;;;1E77;
+1E77;LATIN SMALL LETTER U WITH CIRCUMFLEX BELOW;Ll;0;L;0075 032D;;;;N;;;1E76;;1E76
+1E78;LATIN CAPITAL LETTER U WITH TILDE AND ACUTE;Lu;0;L;0168 0301;;;;N;;;;1E79;
+1E79;LATIN SMALL LETTER U WITH TILDE AND ACUTE;Ll;0;L;0169 0301;;;;N;;;1E78;;1E78
+1E7A;LATIN CAPITAL LETTER U WITH MACRON AND DIAERESIS;Lu;0;L;016A 0308;;;;N;;;;1E7B;
+1E7B;LATIN SMALL LETTER U WITH MACRON AND DIAERESIS;Ll;0;L;016B 0308;;;;N;;;1E7A;;1E7A
+1E7C;LATIN CAPITAL LETTER V WITH TILDE;Lu;0;L;0056 0303;;;;N;;;;1E7D;
+1E7D;LATIN SMALL LETTER V WITH TILDE;Ll;0;L;0076 0303;;;;N;;;1E7C;;1E7C
+1E7E;LATIN CAPITAL LETTER V WITH DOT BELOW;Lu;0;L;0056 0323;;;;N;;;;1E7F;
+1E7F;LATIN SMALL LETTER V WITH DOT BELOW;Ll;0;L;0076 0323;;;;N;;;1E7E;;1E7E
+1E80;LATIN CAPITAL LETTER W WITH GRAVE;Lu;0;L;0057 0300;;;;N;;;;1E81;
+1E81;LATIN SMALL LETTER W WITH GRAVE;Ll;0;L;0077 0300;;;;N;;;1E80;;1E80
+1E82;LATIN CAPITAL LETTER W WITH ACUTE;Lu;0;L;0057 0301;;;;N;;;;1E83;
+1E83;LATIN SMALL LETTER W WITH ACUTE;Ll;0;L;0077 0301;;;;N;;;1E82;;1E82
+1E84;LATIN CAPITAL LETTER W WITH DIAERESIS;Lu;0;L;0057 0308;;;;N;;;;1E85;
+1E85;LATIN SMALL LETTER W WITH DIAERESIS;Ll;0;L;0077 0308;;;;N;;;1E84;;1E84
+1E86;LATIN CAPITAL LETTER W WITH DOT ABOVE;Lu;0;L;0057 0307;;;;N;;;;1E87;
+1E87;LATIN SMALL LETTER W WITH DOT ABOVE;Ll;0;L;0077 0307;;;;N;;;1E86;;1E86
+1E88;LATIN CAPITAL LETTER W WITH DOT BELOW;Lu;0;L;0057 0323;;;;N;;;;1E89;
+1E89;LATIN SMALL LETTER W WITH DOT BELOW;Ll;0;L;0077 0323;;;;N;;;1E88;;1E88
+1E8A;LATIN CAPITAL LETTER X WITH DOT ABOVE;Lu;0;L;0058 0307;;;;N;;;;1E8B;
+1E8B;LATIN SMALL LETTER X WITH DOT ABOVE;Ll;0;L;0078 0307;;;;N;;;1E8A;;1E8A
+1E8C;LATIN CAPITAL LETTER X WITH DIAERESIS;Lu;0;L;0058 0308;;;;N;;;;1E8D;
+1E8D;LATIN SMALL LETTER X WITH DIAERESIS;Ll;0;L;0078 0308;;;;N;;;1E8C;;1E8C
+1E8E;LATIN CAPITAL LETTER Y WITH DOT ABOVE;Lu;0;L;0059 0307;;;;N;;;;1E8F;
+1E8F;LATIN SMALL LETTER Y WITH DOT ABOVE;Ll;0;L;0079 0307;;;;N;;;1E8E;;1E8E
+1E90;LATIN CAPITAL LETTER Z WITH CIRCUMFLEX;Lu;0;L;005A 0302;;;;N;;;;1E91;
+1E91;LATIN SMALL LETTER Z WITH CIRCUMFLEX;Ll;0;L;007A 0302;;;;N;;;1E90;;1E90
+1E92;LATIN CAPITAL LETTER Z WITH DOT BELOW;Lu;0;L;005A 0323;;;;N;;;;1E93;
+1E93;LATIN SMALL LETTER Z WITH DOT BELOW;Ll;0;L;007A 0323;;;;N;;;1E92;;1E92
+1E94;LATIN CAPITAL LETTER Z WITH LINE BELOW;Lu;0;L;005A 0331;;;;N;;;;1E95;
+1E95;LATIN SMALL LETTER Z WITH LINE BELOW;Ll;0;L;007A 0331;;;;N;;;1E94;;1E94
+1E96;LATIN SMALL LETTER H WITH LINE BELOW;Ll;0;L;0068 0331;;;;N;;;;;
+1E97;LATIN SMALL LETTER T WITH DIAERESIS;Ll;0;L;0074 0308;;;;N;;;;;
+1E98;LATIN SMALL LETTER W WITH RING ABOVE;Ll;0;L;0077 030A;;;;N;;;;;
+1E99;LATIN SMALL LETTER Y WITH RING ABOVE;Ll;0;L;0079 030A;;;;N;;;;;
+1E9A;LATIN SMALL LETTER A WITH RIGHT HALF RING;Ll;0;L;<compat> 0061 02BE;;;;N;;;;;
+1E9B;LATIN SMALL LETTER LONG S WITH DOT ABOVE;Ll;0;L;017F 0307;;;;N;;;1E60;;1E60
+1E9C;LATIN SMALL LETTER LONG S WITH DIAGONAL STROKE;Ll;0;L;;;;;N;;;;;
+1E9D;LATIN SMALL LETTER LONG S WITH HIGH STROKE;Ll;0;L;;;;;N;;;;;
+1E9E;LATIN CAPITAL LETTER SHARP S;Lu;0;L;;;;;N;;;;00DF;
+1E9F;LATIN SMALL LETTER DELTA;Ll;0;L;;;;;N;;;;;
+1EA0;LATIN CAPITAL LETTER A WITH DOT BELOW;Lu;0;L;0041 0323;;;;N;;;;1EA1;
+1EA1;LATIN SMALL LETTER A WITH DOT BELOW;Ll;0;L;0061 0323;;;;N;;;1EA0;;1EA0
+1EA2;LATIN CAPITAL LETTER A WITH HOOK ABOVE;Lu;0;L;0041 0309;;;;N;;;;1EA3;
+1EA3;LATIN SMALL LETTER A WITH HOOK ABOVE;Ll;0;L;0061 0309;;;;N;;;1EA2;;1EA2
+1EA4;LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND ACUTE;Lu;0;L;00C2 0301;;;;N;;;;1EA5;
+1EA5;LATIN SMALL LETTER A WITH CIRCUMFLEX AND ACUTE;Ll;0;L;00E2 0301;;;;N;;;1EA4;;1EA4
+1EA6;LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND GRAVE;Lu;0;L;00C2 0300;;;;N;;;;1EA7;
+1EA7;LATIN SMALL LETTER A WITH CIRCUMFLEX AND GRAVE;Ll;0;L;00E2 0300;;;;N;;;1EA6;;1EA6
+1EA8;LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE;Lu;0;L;00C2 0309;;;;N;;;;1EA9;
+1EA9;LATIN SMALL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE;Ll;0;L;00E2 0309;;;;N;;;1EA8;;1EA8
+1EAA;LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND TILDE;Lu;0;L;00C2 0303;;;;N;;;;1EAB;
+1EAB;LATIN SMALL LETTER A WITH CIRCUMFLEX AND TILDE;Ll;0;L;00E2 0303;;;;N;;;1EAA;;1EAA
+1EAC;LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND DOT BELOW;Lu;0;L;1EA0 0302;;;;N;;;;1EAD;
+1EAD;LATIN SMALL LETTER A WITH CIRCUMFLEX AND DOT BELOW;Ll;0;L;1EA1 0302;;;;N;;;1EAC;;1EAC
+1EAE;LATIN CAPITAL LETTER A WITH BREVE AND ACUTE;Lu;0;L;0102 0301;;;;N;;;;1EAF;
+1EAF;LATIN SMALL LETTER A WITH BREVE AND ACUTE;Ll;0;L;0103 0301;;;;N;;;1EAE;;1EAE
+1EB0;LATIN CAPITAL LETTER A WITH BREVE AND GRAVE;Lu;0;L;0102 0300;;;;N;;;;1EB1;
+1EB1;LATIN SMALL LETTER A WITH BREVE AND GRAVE;Ll;0;L;0103 0300;;;;N;;;1EB0;;1EB0
+1EB2;LATIN CAPITAL LETTER A WITH BREVE AND HOOK ABOVE;Lu;0;L;0102 0309;;;;N;;;;1EB3;
+1EB3;LATIN SMALL LETTER A WITH BREVE AND HOOK ABOVE;Ll;0;L;0103 0309;;;;N;;;1EB2;;1EB2
+1EB4;LATIN CAPITAL LETTER A WITH BREVE AND TILDE;Lu;0;L;0102 0303;;;;N;;;;1EB5;
+1EB5;LATIN SMALL LETTER A WITH BREVE AND TILDE;Ll;0;L;0103 0303;;;;N;;;1EB4;;1EB4
+1EB6;LATIN CAPITAL LETTER A WITH BREVE AND DOT BELOW;Lu;0;L;1EA0 0306;;;;N;;;;1EB7;
+1EB7;LATIN SMALL LETTER A WITH BREVE AND DOT BELOW;Ll;0;L;1EA1 0306;;;;N;;;1EB6;;1EB6
+1EB8;LATIN CAPITAL LETTER E WITH DOT BELOW;Lu;0;L;0045 0323;;;;N;;;;1EB9;
+1EB9;LATIN SMALL LETTER E WITH DOT BELOW;Ll;0;L;0065 0323;;;;N;;;1EB8;;1EB8
+1EBA;LATIN CAPITAL LETTER E WITH HOOK ABOVE;Lu;0;L;0045 0309;;;;N;;;;1EBB;
+1EBB;LATIN SMALL LETTER E WITH HOOK ABOVE;Ll;0;L;0065 0309;;;;N;;;1EBA;;1EBA
+1EBC;LATIN CAPITAL LETTER E WITH TILDE;Lu;0;L;0045 0303;;;;N;;;;1EBD;
+1EBD;LATIN SMALL LETTER E WITH TILDE;Ll;0;L;0065 0303;;;;N;;;1EBC;;1EBC
+1EBE;LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND ACUTE;Lu;0;L;00CA 0301;;;;N;;;;1EBF;
+1EBF;LATIN SMALL LETTER E WITH CIRCUMFLEX AND ACUTE;Ll;0;L;00EA 0301;;;;N;;;1EBE;;1EBE
+1EC0;LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND GRAVE;Lu;0;L;00CA 0300;;;;N;;;;1EC1;
+1EC1;LATIN SMALL LETTER E WITH CIRCUMFLEX AND GRAVE;Ll;0;L;00EA 0300;;;;N;;;1EC0;;1EC0
+1EC2;LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE;Lu;0;L;00CA 0309;;;;N;;;;1EC3;
+1EC3;LATIN SMALL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE;Ll;0;L;00EA 0309;;;;N;;;1EC2;;1EC2
+1EC4;LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND TILDE;Lu;0;L;00CA 0303;;;;N;;;;1EC5;
+1EC5;LATIN SMALL LETTER E WITH CIRCUMFLEX AND TILDE;Ll;0;L;00EA 0303;;;;N;;;1EC4;;1EC4
+1EC6;LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND DOT BELOW;Lu;0;L;1EB8 0302;;;;N;;;;1EC7;
+1EC7;LATIN SMALL LETTER E WITH CIRCUMFLEX AND DOT BELOW;Ll;0;L;1EB9 0302;;;;N;;;1EC6;;1EC6
+1EC8;LATIN CAPITAL LETTER I WITH HOOK ABOVE;Lu;0;L;0049 0309;;;;N;;;;1EC9;
+1EC9;LATIN SMALL LETTER I WITH HOOK ABOVE;Ll;0;L;0069 0309;;;;N;;;1EC8;;1EC8
+1ECA;LATIN CAPITAL LETTER I WITH DOT BELOW;Lu;0;L;0049 0323;;;;N;;;;1ECB;
+1ECB;LATIN SMALL LETTER I WITH DOT BELOW;Ll;0;L;0069 0323;;;;N;;;1ECA;;1ECA
+1ECC;LATIN CAPITAL LETTER O WITH DOT BELOW;Lu;0;L;004F 0323;;;;N;;;;1ECD;
+1ECD;LATIN SMALL LETTER O WITH DOT BELOW;Ll;0;L;006F 0323;;;;N;;;1ECC;;1ECC
+1ECE;LATIN CAPITAL LETTER O WITH HOOK ABOVE;Lu;0;L;004F 0309;;;;N;;;;1ECF;
+1ECF;LATIN SMALL LETTER O WITH HOOK ABOVE;Ll;0;L;006F 0309;;;;N;;;1ECE;;1ECE
+1ED0;LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND ACUTE;Lu;0;L;00D4 0301;;;;N;;;;1ED1;
+1ED1;LATIN SMALL LETTER O WITH CIRCUMFLEX AND ACUTE;Ll;0;L;00F4 0301;;;;N;;;1ED0;;1ED0
+1ED2;LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND GRAVE;Lu;0;L;00D4 0300;;;;N;;;;1ED3;
+1ED3;LATIN SMALL LETTER O WITH CIRCUMFLEX AND GRAVE;Ll;0;L;00F4 0300;;;;N;;;1ED2;;1ED2
+1ED4;LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE;Lu;0;L;00D4 0309;;;;N;;;;1ED5;
+1ED5;LATIN SMALL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE;Ll;0;L;00F4 0309;;;;N;;;1ED4;;1ED4
+1ED6;LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND TILDE;Lu;0;L;00D4 0303;;;;N;;;;1ED7;
+1ED7;LATIN SMALL LETTER O WITH CIRCUMFLEX AND TILDE;Ll;0;L;00F4 0303;;;;N;;;1ED6;;1ED6
+1ED8;LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND DOT BELOW;Lu;0;L;1ECC 0302;;;;N;;;;1ED9;
+1ED9;LATIN SMALL LETTER O WITH CIRCUMFLEX AND DOT BELOW;Ll;0;L;1ECD 0302;;;;N;;;1ED8;;1ED8
+1EDA;LATIN CAPITAL LETTER O WITH HORN AND ACUTE;Lu;0;L;01A0 0301;;;;N;;;;1EDB;
+1EDB;LATIN SMALL LETTER O WITH HORN AND ACUTE;Ll;0;L;01A1 0301;;;;N;;;1EDA;;1EDA
+1EDC;LATIN CAPITAL LETTER O WITH HORN AND GRAVE;Lu;0;L;01A0 0300;;;;N;;;;1EDD;
+1EDD;LATIN SMALL LETTER O WITH HORN AND GRAVE;Ll;0;L;01A1 0300;;;;N;;;1EDC;;1EDC
+1EDE;LATIN CAPITAL LETTER O WITH HORN AND HOOK ABOVE;Lu;0;L;01A0 0309;;;;N;;;;1EDF;
+1EDF;LATIN SMALL LETTER O WITH HORN AND HOOK ABOVE;Ll;0;L;01A1 0309;;;;N;;;1EDE;;1EDE
+1EE0;LATIN CAPITAL LETTER O WITH HORN AND TILDE;Lu;0;L;01A0 0303;;;;N;;;;1EE1;
+1EE1;LATIN SMALL LETTER O WITH HORN AND TILDE;Ll;0;L;01A1 0303;;;;N;;;1EE0;;1EE0
+1EE2;LATIN CAPITAL LETTER O WITH HORN AND DOT BELOW;Lu;0;L;01A0 0323;;;;N;;;;1EE3;
+1EE3;LATIN SMALL LETTER O WITH HORN AND DOT BELOW;Ll;0;L;01A1 0323;;;;N;;;1EE2;;1EE2
+1EE4;LATIN CAPITAL LETTER U WITH DOT BELOW;Lu;0;L;0055 0323;;;;N;;;;1EE5;
+1EE5;LATIN SMALL LETTER U WITH DOT BELOW;Ll;0;L;0075 0323;;;;N;;;1EE4;;1EE4
+1EE6;LATIN CAPITAL LETTER U WITH HOOK ABOVE;Lu;0;L;0055 0309;;;;N;;;;1EE7;
+1EE7;LATIN SMALL LETTER U WITH HOOK ABOVE;Ll;0;L;0075 0309;;;;N;;;1EE6;;1EE6
+1EE8;LATIN CAPITAL LETTER U WITH HORN AND ACUTE;Lu;0;L;01AF 0301;;;;N;;;;1EE9;
+1EE9;LATIN SMALL LETTER U WITH HORN AND ACUTE;Ll;0;L;01B0 0301;;;;N;;;1EE8;;1EE8
+1EEA;LATIN CAPITAL LETTER U WITH HORN AND GRAVE;Lu;0;L;01AF 0300;;;;N;;;;1EEB;
+1EEB;LATIN SMALL LETTER U WITH HORN AND GRAVE;Ll;0;L;01B0 0300;;;;N;;;1EEA;;1EEA
+1EEC;LATIN CAPITAL LETTER U WITH HORN AND HOOK ABOVE;Lu;0;L;01AF 0309;;;;N;;;;1EED;
+1EED;LATIN SMALL LETTER U WITH HORN AND HOOK ABOVE;Ll;0;L;01B0 0309;;;;N;;;1EEC;;1EEC
+1EEE;LATIN CAPITAL LETTER U WITH HORN AND TILDE;Lu;0;L;01AF 0303;;;;N;;;;1EEF;
+1EEF;LATIN SMALL LETTER U WITH HORN AND TILDE;Ll;0;L;01B0 0303;;;;N;;;1EEE;;1EEE
+1EF0;LATIN CAPITAL LETTER U WITH HORN AND DOT BELOW;Lu;0;L;01AF 0323;;;;N;;;;1EF1;
+1EF1;LATIN SMALL LETTER U WITH HORN AND DOT BELOW;Ll;0;L;01B0 0323;;;;N;;;1EF0;;1EF0
+1EF2;LATIN CAPITAL LETTER Y WITH GRAVE;Lu;0;L;0059 0300;;;;N;;;;1EF3;
+1EF3;LATIN SMALL LETTER Y WITH GRAVE;Ll;0;L;0079 0300;;;;N;;;1EF2;;1EF2
+1EF4;LATIN CAPITAL LETTER Y WITH DOT BELOW;Lu;0;L;0059 0323;;;;N;;;;1EF5;
+1EF5;LATIN SMALL LETTER Y WITH DOT BELOW;Ll;0;L;0079 0323;;;;N;;;1EF4;;1EF4
+1EF6;LATIN CAPITAL LETTER Y WITH HOOK ABOVE;Lu;0;L;0059 0309;;;;N;;;;1EF7;
+1EF7;LATIN SMALL LETTER Y WITH HOOK ABOVE;Ll;0;L;0079 0309;;;;N;;;1EF6;;1EF6
+1EF8;LATIN CAPITAL LETTER Y WITH TILDE;Lu;0;L;0059 0303;;;;N;;;;1EF9;
+1EF9;LATIN SMALL LETTER Y WITH TILDE;Ll;0;L;0079 0303;;;;N;;;1EF8;;1EF8
+1EFA;LATIN CAPITAL LETTER MIDDLE-WELSH LL;Lu;0;L;;;;;N;;;;1EFB;
+1EFB;LATIN SMALL LETTER MIDDLE-WELSH LL;Ll;0;L;;;;;N;;;1EFA;;1EFA
+1EFC;LATIN CAPITAL LETTER MIDDLE-WELSH V;Lu;0;L;;;;;N;;;;1EFD;
+1EFD;LATIN SMALL LETTER MIDDLE-WELSH V;Ll;0;L;;;;;N;;;1EFC;;1EFC
+1EFE;LATIN CAPITAL LETTER Y WITH LOOP;Lu;0;L;;;;;N;;;;1EFF;
+1EFF;LATIN SMALL LETTER Y WITH LOOP;Ll;0;L;;;;;N;;;1EFE;;1EFE
+1F00;GREEK SMALL LETTER ALPHA WITH PSILI;Ll;0;L;03B1 0313;;;;N;;;1F08;;1F08
+1F01;GREEK SMALL LETTER ALPHA WITH DASIA;Ll;0;L;03B1 0314;;;;N;;;1F09;;1F09
+1F02;GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA;Ll;0;L;1F00 0300;;;;N;;;1F0A;;1F0A
+1F03;GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA;Ll;0;L;1F01 0300;;;;N;;;1F0B;;1F0B
+1F04;GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA;Ll;0;L;1F00 0301;;;;N;;;1F0C;;1F0C
+1F05;GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA;Ll;0;L;1F01 0301;;;;N;;;1F0D;;1F0D
+1F06;GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI;Ll;0;L;1F00 0342;;;;N;;;1F0E;;1F0E
+1F07;GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI;Ll;0;L;1F01 0342;;;;N;;;1F0F;;1F0F
+1F08;GREEK CAPITAL LETTER ALPHA WITH PSILI;Lu;0;L;0391 0313;;;;N;;;;1F00;
+1F09;GREEK CAPITAL LETTER ALPHA WITH DASIA;Lu;0;L;0391 0314;;;;N;;;;1F01;
+1F0A;GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA;Lu;0;L;1F08 0300;;;;N;;;;1F02;
+1F0B;GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA;Lu;0;L;1F09 0300;;;;N;;;;1F03;
+1F0C;GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA;Lu;0;L;1F08 0301;;;;N;;;;1F04;
+1F0D;GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA;Lu;0;L;1F09 0301;;;;N;;;;1F05;
+1F0E;GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI;Lu;0;L;1F08 0342;;;;N;;;;1F06;
+1F0F;GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI;Lu;0;L;1F09 0342;;;;N;;;;1F07;
+1F10;GREEK SMALL LETTER EPSILON WITH PSILI;Ll;0;L;03B5 0313;;;;N;;;1F18;;1F18
+1F11;GREEK SMALL LETTER EPSILON WITH DASIA;Ll;0;L;03B5 0314;;;;N;;;1F19;;1F19
+1F12;GREEK SMALL LETTER EPSILON WITH PSILI AND VARIA;Ll;0;L;1F10 0300;;;;N;;;1F1A;;1F1A
+1F13;GREEK SMALL LETTER EPSILON WITH DASIA AND VARIA;Ll;0;L;1F11 0300;;;;N;;;1F1B;;1F1B
+1F14;GREEK SMALL LETTER EPSILON WITH PSILI AND OXIA;Ll;0;L;1F10 0301;;;;N;;;1F1C;;1F1C
+1F15;GREEK SMALL LETTER EPSILON WITH DASIA AND OXIA;Ll;0;L;1F11 0301;;;;N;;;1F1D;;1F1D
+1F18;GREEK CAPITAL LETTER EPSILON WITH PSILI;Lu;0;L;0395 0313;;;;N;;;;1F10;
+1F19;GREEK CAPITAL LETTER EPSILON WITH DASIA;Lu;0;L;0395 0314;;;;N;;;;1F11;
+1F1A;GREEK CAPITAL LETTER EPSILON WITH PSILI AND VARIA;Lu;0;L;1F18 0300;;;;N;;;;1F12;
+1F1B;GREEK CAPITAL LETTER EPSILON WITH DASIA AND VARIA;Lu;0;L;1F19 0300;;;;N;;;;1F13;
+1F1C;GREEK CAPITAL LETTER EPSILON WITH PSILI AND OXIA;Lu;0;L;1F18 0301;;;;N;;;;1F14;
+1F1D;GREEK CAPITAL LETTER EPSILON WITH DASIA AND OXIA;Lu;0;L;1F19 0301;;;;N;;;;1F15;
+1F20;GREEK SMALL LETTER ETA WITH PSILI;Ll;0;L;03B7 0313;;;;N;;;1F28;;1F28
+1F21;GREEK SMALL LETTER ETA WITH DASIA;Ll;0;L;03B7 0314;;;;N;;;1F29;;1F29
+1F22;GREEK SMALL LETTER ETA WITH PSILI AND VARIA;Ll;0;L;1F20 0300;;;;N;;;1F2A;;1F2A
+1F23;GREEK SMALL LETTER ETA WITH DASIA AND VARIA;Ll;0;L;1F21 0300;;;;N;;;1F2B;;1F2B
+1F24;GREEK SMALL LETTER ETA WITH PSILI AND OXIA;Ll;0;L;1F20 0301;;;;N;;;1F2C;;1F2C
+1F25;GREEK SMALL LETTER ETA WITH DASIA AND OXIA;Ll;0;L;1F21 0301;;;;N;;;1F2D;;1F2D
+1F26;GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI;Ll;0;L;1F20 0342;;;;N;;;1F2E;;1F2E
+1F27;GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI;Ll;0;L;1F21 0342;;;;N;;;1F2F;;1F2F
+1F28;GREEK CAPITAL LETTER ETA WITH PSILI;Lu;0;L;0397 0313;;;;N;;;;1F20;
+1F29;GREEK CAPITAL LETTER ETA WITH DASIA;Lu;0;L;0397 0314;;;;N;;;;1F21;
+1F2A;GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA;Lu;0;L;1F28 0300;;;;N;;;;1F22;
+1F2B;GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA;Lu;0;L;1F29 0300;;;;N;;;;1F23;
+1F2C;GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA;Lu;0;L;1F28 0301;;;;N;;;;1F24;
+1F2D;GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA;Lu;0;L;1F29 0301;;;;N;;;;1F25;
+1F2E;GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI;Lu;0;L;1F28 0342;;;;N;;;;1F26;
+1F2F;GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI;Lu;0;L;1F29 0342;;;;N;;;;1F27;
+1F30;GREEK SMALL LETTER IOTA WITH PSILI;Ll;0;L;03B9 0313;;;;N;;;1F38;;1F38
+1F31;GREEK SMALL LETTER IOTA WITH DASIA;Ll;0;L;03B9 0314;;;;N;;;1F39;;1F39
+1F32;GREEK SMALL LETTER IOTA WITH PSILI AND VARIA;Ll;0;L;1F30 0300;;;;N;;;1F3A;;1F3A
+1F33;GREEK SMALL LETTER IOTA WITH DASIA AND VARIA;Ll;0;L;1F31 0300;;;;N;;;1F3B;;1F3B
+1F34;GREEK SMALL LETTER IOTA WITH PSILI AND OXIA;Ll;0;L;1F30 0301;;;;N;;;1F3C;;1F3C
+1F35;GREEK SMALL LETTER IOTA WITH DASIA AND OXIA;Ll;0;L;1F31 0301;;;;N;;;1F3D;;1F3D
+1F36;GREEK SMALL LETTER IOTA WITH PSILI AND PERISPOMENI;Ll;0;L;1F30 0342;;;;N;;;1F3E;;1F3E
+1F37;GREEK SMALL LETTER IOTA WITH DASIA AND PERISPOMENI;Ll;0;L;1F31 0342;;;;N;;;1F3F;;1F3F
+1F38;GREEK CAPITAL LETTER IOTA WITH PSILI;Lu;0;L;0399 0313;;;;N;;;;1F30;
+1F39;GREEK CAPITAL LETTER IOTA WITH DASIA;Lu;0;L;0399 0314;;;;N;;;;1F31;
+1F3A;GREEK CAPITAL LETTER IOTA WITH PSILI AND VARIA;Lu;0;L;1F38 0300;;;;N;;;;1F32;
+1F3B;GREEK CAPITAL LETTER IOTA WITH DASIA AND VARIA;Lu;0;L;1F39 0300;;;;N;;;;1F33;
+1F3C;GREEK CAPITAL LETTER IOTA WITH PSILI AND OXIA;Lu;0;L;1F38 0301;;;;N;;;;1F34;
+1F3D;GREEK CAPITAL LETTER IOTA WITH DASIA AND OXIA;Lu;0;L;1F39 0301;;;;N;;;;1F35;
+1F3E;GREEK CAPITAL LETTER IOTA WITH PSILI AND PERISPOMENI;Lu;0;L;1F38 0342;;;;N;;;;1F36;
+1F3F;GREEK CAPITAL LETTER IOTA WITH DASIA AND PERISPOMENI;Lu;0;L;1F39 0342;;;;N;;;;1F37;
+1F40;GREEK SMALL LETTER OMICRON WITH PSILI;Ll;0;L;03BF 0313;;;;N;;;1F48;;1F48
+1F41;GREEK SMALL LETTER OMICRON WITH DASIA;Ll;0;L;03BF 0314;;;;N;;;1F49;;1F49
+1F42;GREEK SMALL LETTER OMICRON WITH PSILI AND VARIA;Ll;0;L;1F40 0300;;;;N;;;1F4A;;1F4A
+1F43;GREEK SMALL LETTER OMICRON WITH DASIA AND VARIA;Ll;0;L;1F41 0300;;;;N;;;1F4B;;1F4B
+1F44;GREEK SMALL LETTER OMICRON WITH PSILI AND OXIA;Ll;0;L;1F40 0301;;;;N;;;1F4C;;1F4C
+1F45;GREEK SMALL LETTER OMICRON WITH DASIA AND OXIA;Ll;0;L;1F41 0301;;;;N;;;1F4D;;1F4D
+1F48;GREEK CAPITAL LETTER OMICRON WITH PSILI;Lu;0;L;039F 0313;;;;N;;;;1F40;
+1F49;GREEK CAPITAL LETTER OMICRON WITH DASIA;Lu;0;L;039F 0314;;;;N;;;;1F41;
+1F4A;GREEK CAPITAL LETTER OMICRON WITH PSILI AND VARIA;Lu;0;L;1F48 0300;;;;N;;;;1F42;
+1F4B;GREEK CAPITAL LETTER OMICRON WITH DASIA AND VARIA;Lu;0;L;1F49 0300;;;;N;;;;1F43;
+1F4C;GREEK CAPITAL LETTER OMICRON WITH PSILI AND OXIA;Lu;0;L;1F48 0301;;;;N;;;;1F44;
+1F4D;GREEK CAPITAL LETTER OMICRON WITH DASIA AND OXIA;Lu;0;L;1F49 0301;;;;N;;;;1F45;
+1F50;GREEK SMALL LETTER UPSILON WITH PSILI;Ll;0;L;03C5 0313;;;;N;;;;;
+1F51;GREEK SMALL LETTER UPSILON WITH DASIA;Ll;0;L;03C5 0314;;;;N;;;1F59;;1F59
+1F52;GREEK SMALL LETTER UPSILON WITH PSILI AND VARIA;Ll;0;L;1F50 0300;;;;N;;;;;
+1F53;GREEK SMALL LETTER UPSILON WITH DASIA AND VARIA;Ll;0;L;1F51 0300;;;;N;;;1F5B;;1F5B
+1F54;GREEK SMALL LETTER UPSILON WITH PSILI AND OXIA;Ll;0;L;1F50 0301;;;;N;;;;;
+1F55;GREEK SMALL LETTER UPSILON WITH DASIA AND OXIA;Ll;0;L;1F51 0301;;;;N;;;1F5D;;1F5D
+1F56;GREEK SMALL LETTER UPSILON WITH PSILI AND PERISPOMENI;Ll;0;L;1F50 0342;;;;N;;;;;
+1F57;GREEK SMALL LETTER UPSILON WITH DASIA AND PERISPOMENI;Ll;0;L;1F51 0342;;;;N;;;1F5F;;1F5F
+1F59;GREEK CAPITAL LETTER UPSILON WITH DASIA;Lu;0;L;03A5 0314;;;;N;;;;1F51;
+1F5B;GREEK CAPITAL LETTER UPSILON WITH DASIA AND VARIA;Lu;0;L;1F59 0300;;;;N;;;;1F53;
+1F5D;GREEK CAPITAL LETTER UPSILON WITH DASIA AND OXIA;Lu;0;L;1F59 0301;;;;N;;;;1F55;
+1F5F;GREEK CAPITAL LETTER UPSILON WITH DASIA AND PERISPOMENI;Lu;0;L;1F59 0342;;;;N;;;;1F57;
+1F60;GREEK SMALL LETTER OMEGA WITH PSILI;Ll;0;L;03C9 0313;;;;N;;;1F68;;1F68
+1F61;GREEK SMALL LETTER OMEGA WITH DASIA;Ll;0;L;03C9 0314;;;;N;;;1F69;;1F69
+1F62;GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA;Ll;0;L;1F60 0300;;;;N;;;1F6A;;1F6A
+1F63;GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA;Ll;0;L;1F61 0300;;;;N;;;1F6B;;1F6B
+1F64;GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA;Ll;0;L;1F60 0301;;;;N;;;1F6C;;1F6C
+1F65;GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA;Ll;0;L;1F61 0301;;;;N;;;1F6D;;1F6D
+1F66;GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI;Ll;0;L;1F60 0342;;;;N;;;1F6E;;1F6E
+1F67;GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI;Ll;0;L;1F61 0342;;;;N;;;1F6F;;1F6F
+1F68;GREEK CAPITAL LETTER OMEGA WITH PSILI;Lu;0;L;03A9 0313;;;;N;;;;1F60;
+1F69;GREEK CAPITAL LETTER OMEGA WITH DASIA;Lu;0;L;03A9 0314;;;;N;;;;1F61;
+1F6A;GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA;Lu;0;L;1F68 0300;;;;N;;;;1F62;
+1F6B;GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA;Lu;0;L;1F69 0300;;;;N;;;;1F63;
+1F6C;GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA;Lu;0;L;1F68 0301;;;;N;;;;1F64;
+1F6D;GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA;Lu;0;L;1F69 0301;;;;N;;;;1F65;
+1F6E;GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI;Lu;0;L;1F68 0342;;;;N;;;;1F66;
+1F6F;GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI;Lu;0;L;1F69 0342;;;;N;;;;1F67;
+1F70;GREEK SMALL LETTER ALPHA WITH VARIA;Ll;0;L;03B1 0300;;;;N;;;1FBA;;1FBA
+1F71;GREEK SMALL LETTER ALPHA WITH OXIA;Ll;0;L;03AC;;;;N;;;1FBB;;1FBB
+1F72;GREEK SMALL LETTER EPSILON WITH VARIA;Ll;0;L;03B5 0300;;;;N;;;1FC8;;1FC8
+1F73;GREEK SMALL LETTER EPSILON WITH OXIA;Ll;0;L;03AD;;;;N;;;1FC9;;1FC9
+1F74;GREEK SMALL LETTER ETA WITH VARIA;Ll;0;L;03B7 0300;;;;N;;;1FCA;;1FCA
+1F75;GREEK SMALL LETTER ETA WITH OXIA;Ll;0;L;03AE;;;;N;;;1FCB;;1FCB
+1F76;GREEK SMALL LETTER IOTA WITH VARIA;Ll;0;L;03B9 0300;;;;N;;;1FDA;;1FDA
+1F77;GREEK SMALL LETTER IOTA WITH OXIA;Ll;0;L;03AF;;;;N;;;1FDB;;1FDB
+1F78;GREEK SMALL LETTER OMICRON WITH VARIA;Ll;0;L;03BF 0300;;;;N;;;1FF8;;1FF8
+1F79;GREEK SMALL LETTER OMICRON WITH OXIA;Ll;0;L;03CC;;;;N;;;1FF9;;1FF9
+1F7A;GREEK SMALL LETTER UPSILON WITH VARIA;Ll;0;L;03C5 0300;;;;N;;;1FEA;;1FEA
+1F7B;GREEK SMALL LETTER UPSILON WITH OXIA;Ll;0;L;03CD;;;;N;;;1FEB;;1FEB
+1F7C;GREEK SMALL LETTER OMEGA WITH VARIA;Ll;0;L;03C9 0300;;;;N;;;1FFA;;1FFA
+1F7D;GREEK SMALL LETTER OMEGA WITH OXIA;Ll;0;L;03CE;;;;N;;;1FFB;;1FFB
+1F80;GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI;Ll;0;L;1F00 0345;;;;N;;;1F88;;1F88
+1F81;GREEK SMALL LETTER ALPHA WITH DASIA AND YPOGEGRAMMENI;Ll;0;L;1F01 0345;;;;N;;;1F89;;1F89
+1F82;GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA AND YPOGEGRAMMENI;Ll;0;L;1F02 0345;;;;N;;;1F8A;;1F8A
+1F83;GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA AND YPOGEGRAMMENI;Ll;0;L;1F03 0345;;;;N;;;1F8B;;1F8B
+1F84;GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA AND YPOGEGRAMMENI;Ll;0;L;1F04 0345;;;;N;;;1F8C;;1F8C
+1F85;GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA AND YPOGEGRAMMENI;Ll;0;L;1F05 0345;;;;N;;;1F8D;;1F8D
+1F86;GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1F06 0345;;;;N;;;1F8E;;1F8E
+1F87;GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1F07 0345;;;;N;;;1F8F;;1F8F
+1F88;GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI;Lt;0;L;1F08 0345;;;;N;;;;1F80;
+1F89;GREEK CAPITAL LETTER ALPHA WITH DASIA AND PROSGEGRAMMENI;Lt;0;L;1F09 0345;;;;N;;;;1F81;
+1F8A;GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA AND PROSGEGRAMMENI;Lt;0;L;1F0A 0345;;;;N;;;;1F82;
+1F8B;GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA AND PROSGEGRAMMENI;Lt;0;L;1F0B 0345;;;;N;;;;1F83;
+1F8C;GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA AND PROSGEGRAMMENI;Lt;0;L;1F0C 0345;;;;N;;;;1F84;
+1F8D;GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA AND PROSGEGRAMMENI;Lt;0;L;1F0D 0345;;;;N;;;;1F85;
+1F8E;GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI;Lt;0;L;1F0E 0345;;;;N;;;;1F86;
+1F8F;GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI;Lt;0;L;1F0F 0345;;;;N;;;;1F87;
+1F90;GREEK SMALL LETTER ETA WITH PSILI AND YPOGEGRAMMENI;Ll;0;L;1F20 0345;;;;N;;;1F98;;1F98
+1F91;GREEK SMALL LETTER ETA WITH DASIA AND YPOGEGRAMMENI;Ll;0;L;1F21 0345;;;;N;;;1F99;;1F99
+1F92;GREEK SMALL LETTER ETA WITH PSILI AND VARIA AND YPOGEGRAMMENI;Ll;0;L;1F22 0345;;;;N;;;1F9A;;1F9A
+1F93;GREEK SMALL LETTER ETA WITH DASIA AND VARIA AND YPOGEGRAMMENI;Ll;0;L;1F23 0345;;;;N;;;1F9B;;1F9B
+1F94;GREEK SMALL LETTER ETA WITH PSILI AND OXIA AND YPOGEGRAMMENI;Ll;0;L;1F24 0345;;;;N;;;1F9C;;1F9C
+1F95;GREEK SMALL LETTER ETA WITH DASIA AND OXIA AND YPOGEGRAMMENI;Ll;0;L;1F25 0345;;;;N;;;1F9D;;1F9D
+1F96;GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1F26 0345;;;;N;;;1F9E;;1F9E
+1F97;GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1F27 0345;;;;N;;;1F9F;;1F9F
+1F98;GREEK CAPITAL LETTER ETA WITH PSILI AND PROSGEGRAMMENI;Lt;0;L;1F28 0345;;;;N;;;;1F90;
+1F99;GREEK CAPITAL LETTER ETA WITH DASIA AND PROSGEGRAMMENI;Lt;0;L;1F29 0345;;;;N;;;;1F91;
+1F9A;GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA AND PROSGEGRAMMENI;Lt;0;L;1F2A 0345;;;;N;;;;1F92;
+1F9B;GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA AND PROSGEGRAMMENI;Lt;0;L;1F2B 0345;;;;N;;;;1F93;
+1F9C;GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA AND PROSGEGRAMMENI;Lt;0;L;1F2C 0345;;;;N;;;;1F94;
+1F9D;GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA AND PROSGEGRAMMENI;Lt;0;L;1F2D 0345;;;;N;;;;1F95;
+1F9E;GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI;Lt;0;L;1F2E 0345;;;;N;;;;1F96;
+1F9F;GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI;Lt;0;L;1F2F 0345;;;;N;;;;1F97;
+1FA0;GREEK SMALL LETTER OMEGA WITH PSILI AND YPOGEGRAMMENI;Ll;0;L;1F60 0345;;;;N;;;1FA8;;1FA8
+1FA1;GREEK SMALL LETTER OMEGA WITH DASIA AND YPOGEGRAMMENI;Ll;0;L;1F61 0345;;;;N;;;1FA9;;1FA9
+1FA2;GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA AND YPOGEGRAMMENI;Ll;0;L;1F62 0345;;;;N;;;1FAA;;1FAA
+1FA3;GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA AND YPOGEGRAMMENI;Ll;0;L;1F63 0345;;;;N;;;1FAB;;1FAB
+1FA4;GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA AND YPOGEGRAMMENI;Ll;0;L;1F64 0345;;;;N;;;1FAC;;1FAC
+1FA5;GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA AND YPOGEGRAMMENI;Ll;0;L;1F65 0345;;;;N;;;1FAD;;1FAD
+1FA6;GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1F66 0345;;;;N;;;1FAE;;1FAE
+1FA7;GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1F67 0345;;;;N;;;1FAF;;1FAF
+1FA8;GREEK CAPITAL LETTER OMEGA WITH PSILI AND PROSGEGRAMMENI;Lt;0;L;1F68 0345;;;;N;;;;1FA0;
+1FA9;GREEK CAPITAL LETTER OMEGA WITH DASIA AND PROSGEGRAMMENI;Lt;0;L;1F69 0345;;;;N;;;;1FA1;
+1FAA;GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA AND PROSGEGRAMMENI;Lt;0;L;1F6A 0345;;;;N;;;;1FA2;
+1FAB;GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA AND PROSGEGRAMMENI;Lt;0;L;1F6B 0345;;;;N;;;;1FA3;
+1FAC;GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA AND PROSGEGRAMMENI;Lt;0;L;1F6C 0345;;;;N;;;;1FA4;
+1FAD;GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA AND PROSGEGRAMMENI;Lt;0;L;1F6D 0345;;;;N;;;;1FA5;
+1FAE;GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI;Lt;0;L;1F6E 0345;;;;N;;;;1FA6;
+1FAF;GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI;Lt;0;L;1F6F 0345;;;;N;;;;1FA7;
+1FB0;GREEK SMALL LETTER ALPHA WITH VRACHY;Ll;0;L;03B1 0306;;;;N;;;1FB8;;1FB8
+1FB1;GREEK SMALL LETTER ALPHA WITH MACRON;Ll;0;L;03B1 0304;;;;N;;;1FB9;;1FB9
+1FB2;GREEK SMALL LETTER ALPHA WITH VARIA AND YPOGEGRAMMENI;Ll;0;L;1F70 0345;;;;N;;;;;
+1FB3;GREEK SMALL LETTER ALPHA WITH YPOGEGRAMMENI;Ll;0;L;03B1 0345;;;;N;;;1FBC;;1FBC
+1FB4;GREEK SMALL LETTER ALPHA WITH OXIA AND YPOGEGRAMMENI;Ll;0;L;03AC 0345;;;;N;;;;;
+1FB6;GREEK SMALL LETTER ALPHA WITH PERISPOMENI;Ll;0;L;03B1 0342;;;;N;;;;;
+1FB7;GREEK SMALL LETTER ALPHA WITH PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1FB6 0345;;;;N;;;;;
+1FB8;GREEK CAPITAL LETTER ALPHA WITH VRACHY;Lu;0;L;0391 0306;;;;N;;;;1FB0;
+1FB9;GREEK CAPITAL LETTER ALPHA WITH MACRON;Lu;0;L;0391 0304;;;;N;;;;1FB1;
+1FBA;GREEK CAPITAL LETTER ALPHA WITH VARIA;Lu;0;L;0391 0300;;;;N;;;;1F70;
+1FBB;GREEK CAPITAL LETTER ALPHA WITH OXIA;Lu;0;L;0386;;;;N;;;;1F71;
+1FBC;GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI;Lt;0;L;0391 0345;;;;N;;;;1FB3;
+1FBD;GREEK KORONIS;Sk;0;ON;<compat> 0020 0313;;;;N;;;;;
+1FBE;GREEK PROSGEGRAMMENI;Ll;0;L;03B9;;;;N;;;0399;;0399
+1FBF;GREEK PSILI;Sk;0;ON;<compat> 0020 0313;;;;N;;;;;
+1FC0;GREEK PERISPOMENI;Sk;0;ON;<compat> 0020 0342;;;;N;;;;;
+1FC1;GREEK DIALYTIKA AND PERISPOMENI;Sk;0;ON;00A8 0342;;;;N;;;;;
+1FC2;GREEK SMALL LETTER ETA WITH VARIA AND YPOGEGRAMMENI;Ll;0;L;1F74 0345;;;;N;;;;;
+1FC3;GREEK SMALL LETTER ETA WITH YPOGEGRAMMENI;Ll;0;L;03B7 0345;;;;N;;;1FCC;;1FCC
+1FC4;GREEK SMALL LETTER ETA WITH OXIA AND YPOGEGRAMMENI;Ll;0;L;03AE 0345;;;;N;;;;;
+1FC6;GREEK SMALL LETTER ETA WITH PERISPOMENI;Ll;0;L;03B7 0342;;;;N;;;;;
+1FC7;GREEK SMALL LETTER ETA WITH PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1FC6 0345;;;;N;;;;;
+1FC8;GREEK CAPITAL LETTER EPSILON WITH VARIA;Lu;0;L;0395 0300;;;;N;;;;1F72;
+1FC9;GREEK CAPITAL LETTER EPSILON WITH OXIA;Lu;0;L;0388;;;;N;;;;1F73;
+1FCA;GREEK CAPITAL LETTER ETA WITH VARIA;Lu;0;L;0397 0300;;;;N;;;;1F74;
+1FCB;GREEK CAPITAL LETTER ETA WITH OXIA;Lu;0;L;0389;;;;N;;;;1F75;
+1FCC;GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI;Lt;0;L;0397 0345;;;;N;;;;1FC3;
+1FCD;GREEK PSILI AND VARIA;Sk;0;ON;1FBF 0300;;;;N;;;;;
+1FCE;GREEK PSILI AND OXIA;Sk;0;ON;1FBF 0301;;;;N;;;;;
+1FCF;GREEK PSILI AND PERISPOMENI;Sk;0;ON;1FBF 0342;;;;N;;;;;
+1FD0;GREEK SMALL LETTER IOTA WITH VRACHY;Ll;0;L;03B9 0306;;;;N;;;1FD8;;1FD8
+1FD1;GREEK SMALL LETTER IOTA WITH MACRON;Ll;0;L;03B9 0304;;;;N;;;1FD9;;1FD9
+1FD2;GREEK SMALL LETTER IOTA WITH DIALYTIKA AND VARIA;Ll;0;L;03CA 0300;;;;N;;;;;
+1FD3;GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA;Ll;0;L;0390;;;;N;;;;;
+1FD6;GREEK SMALL LETTER IOTA WITH PERISPOMENI;Ll;0;L;03B9 0342;;;;N;;;;;
+1FD7;GREEK SMALL LETTER IOTA WITH DIALYTIKA AND PERISPOMENI;Ll;0;L;03CA 0342;;;;N;;;;;
+1FD8;GREEK CAPITAL LETTER IOTA WITH VRACHY;Lu;0;L;0399 0306;;;;N;;;;1FD0;
+1FD9;GREEK CAPITAL LETTER IOTA WITH MACRON;Lu;0;L;0399 0304;;;;N;;;;1FD1;
+1FDA;GREEK CAPITAL LETTER IOTA WITH VARIA;Lu;0;L;0399 0300;;;;N;;;;1F76;
+1FDB;GREEK CAPITAL LETTER IOTA WITH OXIA;Lu;0;L;038A;;;;N;;;;1F77;
+1FDD;GREEK DASIA AND VARIA;Sk;0;ON;1FFE 0300;;;;N;;;;;
+1FDE;GREEK DASIA AND OXIA;Sk;0;ON;1FFE 0301;;;;N;;;;;
+1FDF;GREEK DASIA AND PERISPOMENI;Sk;0;ON;1FFE 0342;;;;N;;;;;
+1FE0;GREEK SMALL LETTER UPSILON WITH VRACHY;Ll;0;L;03C5 0306;;;;N;;;1FE8;;1FE8
+1FE1;GREEK SMALL LETTER UPSILON WITH MACRON;Ll;0;L;03C5 0304;;;;N;;;1FE9;;1FE9
+1FE2;GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND VARIA;Ll;0;L;03CB 0300;;;;N;;;;;
+1FE3;GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND OXIA;Ll;0;L;03B0;;;;N;;;;;
+1FE4;GREEK SMALL LETTER RHO WITH PSILI;Ll;0;L;03C1 0313;;;;N;;;;;
+1FE5;GREEK SMALL LETTER RHO WITH DASIA;Ll;0;L;03C1 0314;;;;N;;;1FEC;;1FEC
+1FE6;GREEK SMALL LETTER UPSILON WITH PERISPOMENI;Ll;0;L;03C5 0342;;;;N;;;;;
+1FE7;GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND PERISPOMENI;Ll;0;L;03CB 0342;;;;N;;;;;
+1FE8;GREEK CAPITAL LETTER UPSILON WITH VRACHY;Lu;0;L;03A5 0306;;;;N;;;;1FE0;
+1FE9;GREEK CAPITAL LETTER UPSILON WITH MACRON;Lu;0;L;03A5 0304;;;;N;;;;1FE1;
+1FEA;GREEK CAPITAL LETTER UPSILON WITH VARIA;Lu;0;L;03A5 0300;;;;N;;;;1F7A;
+1FEB;GREEK CAPITAL LETTER UPSILON WITH OXIA;Lu;0;L;038E;;;;N;;;;1F7B;
+1FEC;GREEK CAPITAL LETTER RHO WITH DASIA;Lu;0;L;03A1 0314;;;;N;;;;1FE5;
+1FED;GREEK DIALYTIKA AND VARIA;Sk;0;ON;00A8 0300;;;;N;;;;;
+1FEE;GREEK DIALYTIKA AND OXIA;Sk;0;ON;0385;;;;N;;;;;
+1FEF;GREEK VARIA;Sk;0;ON;0060;;;;N;;;;;
+1FF2;GREEK SMALL LETTER OMEGA WITH VARIA AND YPOGEGRAMMENI;Ll;0;L;1F7C 0345;;;;N;;;;;
+1FF3;GREEK SMALL LETTER OMEGA WITH YPOGEGRAMMENI;Ll;0;L;03C9 0345;;;;N;;;1FFC;;1FFC
+1FF4;GREEK SMALL LETTER OMEGA WITH OXIA AND YPOGEGRAMMENI;Ll;0;L;03CE 0345;;;;N;;;;;
+1FF6;GREEK SMALL LETTER OMEGA WITH PERISPOMENI;Ll;0;L;03C9 0342;;;;N;;;;;
+1FF7;GREEK SMALL LETTER OMEGA WITH PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1FF6 0345;;;;N;;;;;
+1FF8;GREEK CAPITAL LETTER OMICRON WITH VARIA;Lu;0;L;039F 0300;;;;N;;;;1F78;
+1FF9;GREEK CAPITAL LETTER OMICRON WITH OXIA;Lu;0;L;038C;;;;N;;;;1F79;
+1FFA;GREEK CAPITAL LETTER OMEGA WITH VARIA;Lu;0;L;03A9 0300;;;;N;;;;1F7C;
+1FFB;GREEK CAPITAL LETTER OMEGA WITH OXIA;Lu;0;L;038F;;;;N;;;;1F7D;
+1FFC;GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI;Lt;0;L;03A9 0345;;;;N;;;;1FF3;
+1FFD;GREEK OXIA;Sk;0;ON;00B4;;;;N;;;;;
+1FFE;GREEK DASIA;Sk;0;ON;<compat> 0020 0314;;;;N;;;;;
+2000;EN QUAD;Zs;0;WS;2002;;;;N;;;;;
+2001;EM QUAD;Zs;0;WS;2003;;;;N;;;;;
+2002;EN SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;
+2003;EM SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;
+2004;THREE-PER-EM SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;
+2005;FOUR-PER-EM SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;
+2006;SIX-PER-EM SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;
+2007;FIGURE SPACE;Zs;0;WS;<noBreak> 0020;;;;N;;;;;
+2008;PUNCTUATION SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;
+2009;THIN SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;
+200A;HAIR SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;
+200B;ZERO WIDTH SPACE;Cf;0;BN;;;;;N;;;;;
+200C;ZERO WIDTH NON-JOINER;Cf;0;BN;;;;;N;;;;;
+200D;ZERO WIDTH JOINER;Cf;0;BN;;;;;N;;;;;
+200E;LEFT-TO-RIGHT MARK;Cf;0;L;;;;;N;;;;;
+200F;RIGHT-TO-LEFT MARK;Cf;0;R;;;;;N;;;;;
+2010;HYPHEN;Pd;0;ON;;;;;N;;;;;
+2011;NON-BREAKING HYPHEN;Pd;0;ON;<noBreak> 2010;;;;N;;;;;
+2012;FIGURE DASH;Pd;0;ON;;;;;N;;;;;
+2013;EN DASH;Pd;0;ON;;;;;N;;;;;
+2014;EM DASH;Pd;0;ON;;;;;N;;;;;
+2015;HORIZONTAL BAR;Pd;0;ON;;;;;N;QUOTATION DASH;;;;
+2016;DOUBLE VERTICAL LINE;Po;0;ON;;;;;N;DOUBLE VERTICAL BAR;;;;
+2017;DOUBLE LOW LINE;Po;0;ON;<compat> 0020 0333;;;;N;SPACING DOUBLE UNDERSCORE;;;;
+2018;LEFT SINGLE QUOTATION MARK;Pi;0;ON;;;;;N;SINGLE TURNED COMMA QUOTATION MARK;;;;
+2019;RIGHT SINGLE QUOTATION MARK;Pf;0;ON;;;;;N;SINGLE COMMA QUOTATION MARK;;;;
+201A;SINGLE LOW-9 QUOTATION MARK;Ps;0;ON;;;;;N;LOW SINGLE COMMA QUOTATION MARK;;;;
+201B;SINGLE HIGH-REVERSED-9 QUOTATION MARK;Pi;0;ON;;;;;N;SINGLE REVERSED COMMA QUOTATION MARK;;;;
+201C;LEFT DOUBLE QUOTATION MARK;Pi;0;ON;;;;;N;DOUBLE TURNED COMMA QUOTATION MARK;;;;
+201D;RIGHT DOUBLE QUOTATION MARK;Pf;0;ON;;;;;N;DOUBLE COMMA QUOTATION MARK;;;;
+201E;DOUBLE LOW-9 QUOTATION MARK;Ps;0;ON;;;;;N;LOW DOUBLE COMMA QUOTATION MARK;;;;
+201F;DOUBLE HIGH-REVERSED-9 QUOTATION MARK;Pi;0;ON;;;;;N;DOUBLE REVERSED COMMA QUOTATION MARK;;;;
+2020;DAGGER;Po;0;ON;;;;;N;;;;;
+2021;DOUBLE DAGGER;Po;0;ON;;;;;N;;;;;
+2022;BULLET;Po;0;ON;;;;;N;;;;;
+2023;TRIANGULAR BULLET;Po;0;ON;;;;;N;;;;;
+2024;ONE DOT LEADER;Po;0;ON;<compat> 002E;;;;N;;;;;
+2025;TWO DOT LEADER;Po;0;ON;<compat> 002E 002E;;;;N;;;;;
+2026;HORIZONTAL ELLIPSIS;Po;0;ON;<compat> 002E 002E 002E;;;;N;;;;;
+2027;HYPHENATION POINT;Po;0;ON;;;;;N;;;;;
+2028;LINE SEPARATOR;Zl;0;WS;;;;;N;;;;;
+2029;PARAGRAPH SEPARATOR;Zp;0;B;;;;;N;;;;;
+202A;LEFT-TO-RIGHT EMBEDDING;Cf;0;LRE;;;;;N;;;;;
+202B;RIGHT-TO-LEFT EMBEDDING;Cf;0;RLE;;;;;N;;;;;
+202C;POP DIRECTIONAL FORMATTING;Cf;0;PDF;;;;;N;;;;;
+202D;LEFT-TO-RIGHT OVERRIDE;Cf;0;LRO;;;;;N;;;;;
+202E;RIGHT-TO-LEFT OVERRIDE;Cf;0;RLO;;;;;N;;;;;
+202F;NARROW NO-BREAK SPACE;Zs;0;CS;<noBreak> 0020;;;;N;;;;;
+2030;PER MILLE SIGN;Po;0;ET;;;;;N;;;;;
+2031;PER TEN THOUSAND SIGN;Po;0;ET;;;;;N;;;;;
+2032;PRIME;Po;0;ET;;;;;N;;;;;
+2033;DOUBLE PRIME;Po;0;ET;<compat> 2032 2032;;;;N;;;;;
+2034;TRIPLE PRIME;Po;0;ET;<compat> 2032 2032 2032;;;;N;;;;;
+2035;REVERSED PRIME;Po;0;ON;;;;;N;;;;;
+2036;REVERSED DOUBLE PRIME;Po;0;ON;<compat> 2035 2035;;;;N;;;;;
+2037;REVERSED TRIPLE PRIME;Po;0;ON;<compat> 2035 2035 2035;;;;N;;;;;
+2038;CARET;Po;0;ON;;;;;N;;;;;
+2039;SINGLE LEFT-POINTING ANGLE QUOTATION MARK;Pi;0;ON;;;;;Y;LEFT POINTING SINGLE GUILLEMET;;;;
+203A;SINGLE RIGHT-POINTING ANGLE QUOTATION MARK;Pf;0;ON;;;;;Y;RIGHT POINTING SINGLE GUILLEMET;;;;
+203B;REFERENCE MARK;Po;0;ON;;;;;N;;;;;
+203C;DOUBLE EXCLAMATION MARK;Po;0;ON;<compat> 0021 0021;;;;N;;;;;
+203D;INTERROBANG;Po;0;ON;;;;;N;;;;;
+203E;OVERLINE;Po;0;ON;<compat> 0020 0305;;;;N;SPACING OVERSCORE;;;;
+203F;UNDERTIE;Pc;0;ON;;;;;N;;;;;
+2040;CHARACTER TIE;Pc;0;ON;;;;;N;;;;;
+2041;CARET INSERTION POINT;Po;0;ON;;;;;N;;;;;
+2042;ASTERISM;Po;0;ON;;;;;N;;;;;
+2043;HYPHEN BULLET;Po;0;ON;;;;;N;;;;;
+2044;FRACTION SLASH;Sm;0;CS;;;;;N;;;;;
+2045;LEFT SQUARE BRACKET WITH QUILL;Ps;0;ON;;;;;Y;;;;;
+2046;RIGHT SQUARE BRACKET WITH QUILL;Pe;0;ON;;;;;Y;;;;;
+2047;DOUBLE QUESTION MARK;Po;0;ON;<compat> 003F 003F;;;;N;;;;;
+2048;QUESTION EXCLAMATION MARK;Po;0;ON;<compat> 003F 0021;;;;N;;;;;
+2049;EXCLAMATION QUESTION MARK;Po;0;ON;<compat> 0021 003F;;;;N;;;;;
+204A;TIRONIAN SIGN ET;Po;0;ON;;;;;N;;;;;
+204B;REVERSED PILCROW SIGN;Po;0;ON;;;;;N;;;;;
+204C;BLACK LEFTWARDS BULLET;Po;0;ON;;;;;N;;;;;
+204D;BLACK RIGHTWARDS BULLET;Po;0;ON;;;;;N;;;;;
+204E;LOW ASTERISK;Po;0;ON;;;;;N;;;;;
+204F;REVERSED SEMICOLON;Po;0;ON;;;;;N;;;;;
+2050;CLOSE UP;Po;0;ON;;;;;N;;;;;
+2051;TWO ASTERISKS ALIGNED VERTICALLY;Po;0;ON;;;;;N;;;;;
+2052;COMMERCIAL MINUS SIGN;Sm;0;ON;;;;;N;;;;;
+2053;SWUNG DASH;Po;0;ON;;;;;N;;;;;
+2054;INVERTED UNDERTIE;Pc;0;ON;;;;;N;;;;;
+2055;FLOWER PUNCTUATION MARK;Po;0;ON;;;;;N;;;;;
+2056;THREE DOT PUNCTUATION;Po;0;ON;;;;;N;;;;;
+2057;QUADRUPLE PRIME;Po;0;ON;<compat> 2032 2032 2032 2032;;;;N;;;;;
+2058;FOUR DOT PUNCTUATION;Po;0;ON;;;;;N;;;;;
+2059;FIVE DOT PUNCTUATION;Po;0;ON;;;;;N;;;;;
+205A;TWO DOT PUNCTUATION;Po;0;ON;;;;;N;;;;;
+205B;FOUR DOT MARK;Po;0;ON;;;;;N;;;;;
+205C;DOTTED CROSS;Po;0;ON;;;;;N;;;;;
+205D;TRICOLON;Po;0;ON;;;;;N;;;;;
+205E;VERTICAL FOUR DOTS;Po;0;ON;;;;;N;;;;;
+205F;MEDIUM MATHEMATICAL SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;
+2060;WORD JOINER;Cf;0;BN;;;;;N;;;;;
+2061;FUNCTION APPLICATION;Cf;0;BN;;;;;N;;;;;
+2062;INVISIBLE TIMES;Cf;0;BN;;;;;N;;;;;
+2063;INVISIBLE SEPARATOR;Cf;0;BN;;;;;N;;;;;
+2064;INVISIBLE PLUS;Cf;0;BN;;;;;N;;;;;
+206A;INHIBIT SYMMETRIC SWAPPING;Cf;0;BN;;;;;N;;;;;
+206B;ACTIVATE SYMMETRIC SWAPPING;Cf;0;BN;;;;;N;;;;;
+206C;INHIBIT ARABIC FORM SHAPING;Cf;0;BN;;;;;N;;;;;
+206D;ACTIVATE ARABIC FORM SHAPING;Cf;0;BN;;;;;N;;;;;
+206E;NATIONAL DIGIT SHAPES;Cf;0;BN;;;;;N;;;;;
+206F;NOMINAL DIGIT SHAPES;Cf;0;BN;;;;;N;;;;;
+2070;SUPERSCRIPT ZERO;No;0;EN;<super> 0030;;0;0;N;SUPERSCRIPT DIGIT ZERO;;;;
+2071;SUPERSCRIPT LATIN SMALL LETTER I;Lm;0;L;<super> 0069;;;;N;;;;;
+2074;SUPERSCRIPT FOUR;No;0;EN;<super> 0034;;4;4;N;SUPERSCRIPT DIGIT FOUR;;;;
+2075;SUPERSCRIPT FIVE;No;0;EN;<super> 0035;;5;5;N;SUPERSCRIPT DIGIT FIVE;;;;
+2076;SUPERSCRIPT SIX;No;0;EN;<super> 0036;;6;6;N;SUPERSCRIPT DIGIT SIX;;;;
+2077;SUPERSCRIPT SEVEN;No;0;EN;<super> 0037;;7;7;N;SUPERSCRIPT DIGIT SEVEN;;;;
+2078;SUPERSCRIPT EIGHT;No;0;EN;<super> 0038;;8;8;N;SUPERSCRIPT DIGIT EIGHT;;;;
+2079;SUPERSCRIPT NINE;No;0;EN;<super> 0039;;9;9;N;SUPERSCRIPT DIGIT NINE;;;;
+207A;SUPERSCRIPT PLUS SIGN;Sm;0;ES;<super> 002B;;;;N;;;;;
+207B;SUPERSCRIPT MINUS;Sm;0;ES;<super> 2212;;;;N;SUPERSCRIPT HYPHEN-MINUS;;;;
+207C;SUPERSCRIPT EQUALS SIGN;Sm;0;ON;<super> 003D;;;;N;;;;;
+207D;SUPERSCRIPT LEFT PARENTHESIS;Ps;0;ON;<super> 0028;;;;Y;SUPERSCRIPT OPENING PARENTHESIS;;;;
+207E;SUPERSCRIPT RIGHT PARENTHESIS;Pe;0;ON;<super> 0029;;;;Y;SUPERSCRIPT CLOSING PARENTHESIS;;;;
+207F;SUPERSCRIPT LATIN SMALL LETTER N;Lm;0;L;<super> 006E;;;;N;;;;;
+2080;SUBSCRIPT ZERO;No;0;EN;<sub> 0030;;0;0;N;SUBSCRIPT DIGIT ZERO;;;;
+2081;SUBSCRIPT ONE;No;0;EN;<sub> 0031;;1;1;N;SUBSCRIPT DIGIT ONE;;;;
+2082;SUBSCRIPT TWO;No;0;EN;<sub> 0032;;2;2;N;SUBSCRIPT DIGIT TWO;;;;
+2083;SUBSCRIPT THREE;No;0;EN;<sub> 0033;;3;3;N;SUBSCRIPT DIGIT THREE;;;;
+2084;SUBSCRIPT FOUR;No;0;EN;<sub> 0034;;4;4;N;SUBSCRIPT DIGIT FOUR;;;;
+2085;SUBSCRIPT FIVE;No;0;EN;<sub> 0035;;5;5;N;SUBSCRIPT DIGIT FIVE;;;;
+2086;SUBSCRIPT SIX;No;0;EN;<sub> 0036;;6;6;N;SUBSCRIPT DIGIT SIX;;;;
+2087;SUBSCRIPT SEVEN;No;0;EN;<sub> 0037;;7;7;N;SUBSCRIPT DIGIT SEVEN;;;;
+2088;SUBSCRIPT EIGHT;No;0;EN;<sub> 0038;;8;8;N;SUBSCRIPT DIGIT EIGHT;;;;
+2089;SUBSCRIPT NINE;No;0;EN;<sub> 0039;;9;9;N;SUBSCRIPT DIGIT NINE;;;;
+208A;SUBSCRIPT PLUS SIGN;Sm;0;ES;<sub> 002B;;;;N;;;;;
+208B;SUBSCRIPT MINUS;Sm;0;ES;<sub> 2212;;;;N;SUBSCRIPT HYPHEN-MINUS;;;;
+208C;SUBSCRIPT EQUALS SIGN;Sm;0;ON;<sub> 003D;;;;N;;;;;
+208D;SUBSCRIPT LEFT PARENTHESIS;Ps;0;ON;<sub> 0028;;;;Y;SUBSCRIPT OPENING PARENTHESIS;;;;
+208E;SUBSCRIPT RIGHT PARENTHESIS;Pe;0;ON;<sub> 0029;;;;Y;SUBSCRIPT CLOSING PARENTHESIS;;;;
+2090;LATIN SUBSCRIPT SMALL LETTER A;Lm;0;L;<sub> 0061;;;;N;;;;;
+2091;LATIN SUBSCRIPT SMALL LETTER E;Lm;0;L;<sub> 0065;;;;N;;;;;
+2092;LATIN SUBSCRIPT SMALL LETTER O;Lm;0;L;<sub> 006F;;;;N;;;;;
+2093;LATIN SUBSCRIPT SMALL LETTER X;Lm;0;L;<sub> 0078;;;;N;;;;;
+2094;LATIN SUBSCRIPT SMALL LETTER SCHWA;Lm;0;L;<sub> 0259;;;;N;;;;;
+2095;LATIN SUBSCRIPT SMALL LETTER H;Lm;0;L;<sub> 0068;;;;N;;;;;
+2096;LATIN SUBSCRIPT SMALL LETTER K;Lm;0;L;<sub> 006B;;;;N;;;;;
+2097;LATIN SUBSCRIPT SMALL LETTER L;Lm;0;L;<sub> 006C;;;;N;;;;;
+2098;LATIN SUBSCRIPT SMALL LETTER M;Lm;0;L;<sub> 006D;;;;N;;;;;
+2099;LATIN SUBSCRIPT SMALL LETTER N;Lm;0;L;<sub> 006E;;;;N;;;;;
+209A;LATIN SUBSCRIPT SMALL LETTER P;Lm;0;L;<sub> 0070;;;;N;;;;;
+209B;LATIN SUBSCRIPT SMALL LETTER S;Lm;0;L;<sub> 0073;;;;N;;;;;
+209C;LATIN SUBSCRIPT SMALL LETTER T;Lm;0;L;<sub> 0074;;;;N;;;;;
+20A0;EURO-CURRENCY SIGN;Sc;0;ET;;;;;N;;;;;
+20A1;COLON SIGN;Sc;0;ET;;;;;N;;;;;
+20A2;CRUZEIRO SIGN;Sc;0;ET;;;;;N;;;;;
+20A3;FRENCH FRANC SIGN;Sc;0;ET;;;;;N;;;;;
+20A4;LIRA SIGN;Sc;0;ET;;;;;N;;;;;
+20A5;MILL SIGN;Sc;0;ET;;;;;N;;;;;
+20A6;NAIRA SIGN;Sc;0;ET;;;;;N;;;;;
+20A7;PESETA SIGN;Sc;0;ET;;;;;N;;;;;
+20A8;RUPEE SIGN;Sc;0;ET;<compat> 0052 0073;;;;N;;;;;
+20A9;WON SIGN;Sc;0;ET;;;;;N;;;;;
+20AA;NEW SHEQEL SIGN;Sc;0;ET;;;;;N;;;;;
+20AB;DONG SIGN;Sc;0;ET;;;;;N;;;;;
+20AC;EURO SIGN;Sc;0;ET;;;;;N;;;;;
+20AD;KIP SIGN;Sc;0;ET;;;;;N;;;;;
+20AE;TUGRIK SIGN;Sc;0;ET;;;;;N;;;;;
+20AF;DRACHMA SIGN;Sc;0;ET;;;;;N;;;;;
+20B0;GERMAN PENNY SIGN;Sc;0;ET;;;;;N;;;;;
+20B1;PESO SIGN;Sc;0;ET;;;;;N;;;;;
+20B2;GUARANI SIGN;Sc;0;ET;;;;;N;;;;;
+20B3;AUSTRAL SIGN;Sc;0;ET;;;;;N;;;;;
+20B4;HRYVNIA SIGN;Sc;0;ET;;;;;N;;;;;
+20B5;CEDI SIGN;Sc;0;ET;;;;;N;;;;;
+20B6;LIVRE TOURNOIS SIGN;Sc;0;ET;;;;;N;;;;;
+20B7;SPESMILO SIGN;Sc;0;ET;;;;;N;;;;;
+20B8;TENGE SIGN;Sc;0;ET;;;;;N;;;;;
+20B9;INDIAN RUPEE SIGN;Sc;0;ET;;;;;N;;;;;
+20D0;COMBINING LEFT HARPOON ABOVE;Mn;230;NSM;;;;;N;NON-SPACING LEFT HARPOON ABOVE;;;;
+20D1;COMBINING RIGHT HARPOON ABOVE;Mn;230;NSM;;;;;N;NON-SPACING RIGHT HARPOON ABOVE;;;;
+20D2;COMBINING LONG VERTICAL LINE OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING LONG VERTICAL BAR OVERLAY;;;;
+20D3;COMBINING SHORT VERTICAL LINE OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING SHORT VERTICAL BAR OVERLAY;;;;
+20D4;COMBINING ANTICLOCKWISE ARROW ABOVE;Mn;230;NSM;;;;;N;NON-SPACING ANTICLOCKWISE ARROW ABOVE;;;;
+20D5;COMBINING CLOCKWISE ARROW ABOVE;Mn;230;NSM;;;;;N;NON-SPACING CLOCKWISE ARROW ABOVE;;;;
+20D6;COMBINING LEFT ARROW ABOVE;Mn;230;NSM;;;;;N;NON-SPACING LEFT ARROW ABOVE;;;;
+20D7;COMBINING RIGHT ARROW ABOVE;Mn;230;NSM;;;;;N;NON-SPACING RIGHT ARROW ABOVE;;;;
+20D8;COMBINING RING OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING RING OVERLAY;;;;
+20D9;COMBINING CLOCKWISE RING OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING CLOCKWISE RING OVERLAY;;;;
+20DA;COMBINING ANTICLOCKWISE RING OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING ANTICLOCKWISE RING OVERLAY;;;;
+20DB;COMBINING THREE DOTS ABOVE;Mn;230;NSM;;;;;N;NON-SPACING THREE DOTS ABOVE;;;;
+20DC;COMBINING FOUR DOTS ABOVE;Mn;230;NSM;;;;;N;NON-SPACING FOUR DOTS ABOVE;;;;
+20DD;COMBINING ENCLOSING CIRCLE;Me;0;NSM;;;;;N;ENCLOSING CIRCLE;;;;
+20DE;COMBINING ENCLOSING SQUARE;Me;0;NSM;;;;;N;ENCLOSING SQUARE;;;;
+20DF;COMBINING ENCLOSING DIAMOND;Me;0;NSM;;;;;N;ENCLOSING DIAMOND;;;;
+20E0;COMBINING ENCLOSING CIRCLE BACKSLASH;Me;0;NSM;;;;;N;ENCLOSING CIRCLE SLASH;;;;
+20E1;COMBINING LEFT RIGHT ARROW ABOVE;Mn;230;NSM;;;;;N;NON-SPACING LEFT RIGHT ARROW ABOVE;;;;
+20E2;COMBINING ENCLOSING SCREEN;Me;0;NSM;;;;;N;;;;;
+20E3;COMBINING ENCLOSING KEYCAP;Me;0;NSM;;;;;N;;;;;
+20E4;COMBINING ENCLOSING UPWARD POINTING TRIANGLE;Me;0;NSM;;;;;N;;;;;
+20E5;COMBINING REVERSE SOLIDUS OVERLAY;Mn;1;NSM;;;;;N;;;;;
+20E6;COMBINING DOUBLE VERTICAL STROKE OVERLAY;Mn;1;NSM;;;;;N;;;;;
+20E7;COMBINING ANNUITY SYMBOL;Mn;230;NSM;;;;;N;;;;;
+20E8;COMBINING TRIPLE UNDERDOT;Mn;220;NSM;;;;;N;;;;;
+20E9;COMBINING WIDE BRIDGE ABOVE;Mn;230;NSM;;;;;N;;;;;
+20EA;COMBINING LEFTWARDS ARROW OVERLAY;Mn;1;NSM;;;;;N;;;;;
+20EB;COMBINING LONG DOUBLE SOLIDUS OVERLAY;Mn;1;NSM;;;;;N;;;;;
+20EC;COMBINING RIGHTWARDS HARPOON WITH BARB DOWNWARDS;Mn;220;NSM;;;;;N;;;;;
+20ED;COMBINING LEFTWARDS HARPOON WITH BARB DOWNWARDS;Mn;220;NSM;;;;;N;;;;;
+20EE;COMBINING LEFT ARROW BELOW;Mn;220;NSM;;;;;N;;;;;
+20EF;COMBINING RIGHT ARROW BELOW;Mn;220;NSM;;;;;N;;;;;
+20F0;COMBINING ASTERISK ABOVE;Mn;230;NSM;;;;;N;;;;;
+2100;ACCOUNT OF;So;0;ON;<compat> 0061 002F 0063;;;;N;;;;;
+2101;ADDRESSED TO THE SUBJECT;So;0;ON;<compat> 0061 002F 0073;;;;N;;;;;
+2102;DOUBLE-STRUCK CAPITAL C;Lu;0;L;<font> 0043;;;;N;DOUBLE-STRUCK C;;;;
+2103;DEGREE CELSIUS;So;0;ON;<compat> 00B0 0043;;;;N;DEGREES CENTIGRADE;;;;
+2104;CENTRE LINE SYMBOL;So;0;ON;;;;;N;C L SYMBOL;;;;
+2105;CARE OF;So;0;ON;<compat> 0063 002F 006F;;;;N;;;;;
+2106;CADA UNA;So;0;ON;<compat> 0063 002F 0075;;;;N;;;;;
+2107;EULER CONSTANT;Lu;0;L;<compat> 0190;;;;N;EULERS;;;;
+2108;SCRUPLE;So;0;ON;;;;;N;;;;;
+2109;DEGREE FAHRENHEIT;So;0;ON;<compat> 00B0 0046;;;;N;DEGREES FAHRENHEIT;;;;
+210A;SCRIPT SMALL G;Ll;0;L;<font> 0067;;;;N;;;;;
+210B;SCRIPT CAPITAL H;Lu;0;L;<font> 0048;;;;N;SCRIPT H;;;;
+210C;BLACK-LETTER CAPITAL H;Lu;0;L;<font> 0048;;;;N;BLACK-LETTER H;;;;
+210D;DOUBLE-STRUCK CAPITAL H;Lu;0;L;<font> 0048;;;;N;DOUBLE-STRUCK H;;;;
+210E;PLANCK CONSTANT;Ll;0;L;<font> 0068;;;;N;;;;;
+210F;PLANCK CONSTANT OVER TWO PI;Ll;0;L;<font> 0127;;;;N;PLANCK CONSTANT OVER 2 PI;;;;
+2110;SCRIPT CAPITAL I;Lu;0;L;<font> 0049;;;;N;SCRIPT I;;;;
+2111;BLACK-LETTER CAPITAL I;Lu;0;L;<font> 0049;;;;N;BLACK-LETTER I;;;;
+2112;SCRIPT CAPITAL L;Lu;0;L;<font> 004C;;;;N;SCRIPT L;;;;
+2113;SCRIPT SMALL L;Ll;0;L;<font> 006C;;;;N;;;;;
+2114;L B BAR SYMBOL;So;0;ON;;;;;N;;;;;
+2115;DOUBLE-STRUCK CAPITAL N;Lu;0;L;<font> 004E;;;;N;DOUBLE-STRUCK N;;;;
+2116;NUMERO SIGN;So;0;ON;<compat> 004E 006F;;;;N;NUMERO;;;;
+2117;SOUND RECORDING COPYRIGHT;So;0;ON;;;;;N;;;;;
+2118;SCRIPT CAPITAL P;Sm;0;ON;;;;;N;SCRIPT P;;;;
+2119;DOUBLE-STRUCK CAPITAL P;Lu;0;L;<font> 0050;;;;N;DOUBLE-STRUCK P;;;;
+211A;DOUBLE-STRUCK CAPITAL Q;Lu;0;L;<font> 0051;;;;N;DOUBLE-STRUCK Q;;;;
+211B;SCRIPT CAPITAL R;Lu;0;L;<font> 0052;;;;N;SCRIPT R;;;;
+211C;BLACK-LETTER CAPITAL R;Lu;0;L;<font> 0052;;;;N;BLACK-LETTER R;;;;
+211D;DOUBLE-STRUCK CAPITAL R;Lu;0;L;<font> 0052;;;;N;DOUBLE-STRUCK R;;;;
+211E;PRESCRIPTION TAKE;So;0;ON;;;;;N;;;;;
+211F;RESPONSE;So;0;ON;;;;;N;;;;;
+2120;SERVICE MARK;So;0;ON;<super> 0053 004D;;;;N;;;;;
+2121;TELEPHONE SIGN;So;0;ON;<compat> 0054 0045 004C;;;;N;T E L SYMBOL;;;;
+2122;TRADE MARK SIGN;So;0;ON;<super> 0054 004D;;;;N;TRADEMARK;;;;
+2123;VERSICLE;So;0;ON;;;;;N;;;;;
+2124;DOUBLE-STRUCK CAPITAL Z;Lu;0;L;<font> 005A;;;;N;DOUBLE-STRUCK Z;;;;
+2125;OUNCE SIGN;So;0;ON;;;;;N;OUNCE;;;;
+2126;OHM SIGN;Lu;0;L;03A9;;;;N;OHM;;;03C9;
+2127;INVERTED OHM SIGN;So;0;ON;;;;;N;MHO;;;;
+2128;BLACK-LETTER CAPITAL Z;Lu;0;L;<font> 005A;;;;N;BLACK-LETTER Z;;;;
+2129;TURNED GREEK SMALL LETTER IOTA;So;0;ON;;;;;N;;;;;
+212A;KELVIN SIGN;Lu;0;L;004B;;;;N;DEGREES KELVIN;;;006B;
+212B;ANGSTROM SIGN;Lu;0;L;00C5;;;;N;ANGSTROM UNIT;;;00E5;
+212C;SCRIPT CAPITAL B;Lu;0;L;<font> 0042;;;;N;SCRIPT B;;;;
+212D;BLACK-LETTER CAPITAL C;Lu;0;L;<font> 0043;;;;N;BLACK-LETTER C;;;;
+212E;ESTIMATED SYMBOL;So;0;ET;;;;;N;;;;;
+212F;SCRIPT SMALL E;Ll;0;L;<font> 0065;;;;N;;;;;
+2130;SCRIPT CAPITAL E;Lu;0;L;<font> 0045;;;;N;SCRIPT E;;;;
+2131;SCRIPT CAPITAL F;Lu;0;L;<font> 0046;;;;N;SCRIPT F;;;;
+2132;TURNED CAPITAL F;Lu;0;L;;;;;N;TURNED F;;;214E;
+2133;SCRIPT CAPITAL M;Lu;0;L;<font> 004D;;;;N;SCRIPT M;;;;
+2134;SCRIPT SMALL O;Ll;0;L;<font> 006F;;;;N;;;;;
+2135;ALEF SYMBOL;Lo;0;L;<compat> 05D0;;;;N;FIRST TRANSFINITE CARDINAL;;;;
+2136;BET SYMBOL;Lo;0;L;<compat> 05D1;;;;N;SECOND TRANSFINITE CARDINAL;;;;
+2137;GIMEL SYMBOL;Lo;0;L;<compat> 05D2;;;;N;THIRD TRANSFINITE CARDINAL;;;;
+2138;DALET SYMBOL;Lo;0;L;<compat> 05D3;;;;N;FOURTH TRANSFINITE CARDINAL;;;;
+2139;INFORMATION SOURCE;Ll;0;L;<font> 0069;;;;N;;;;;
+213A;ROTATED CAPITAL Q;So;0;ON;;;;;N;;;;;
+213B;FACSIMILE SIGN;So;0;ON;<compat> 0046 0041 0058;;;;N;;;;;
+213C;DOUBLE-STRUCK SMALL PI;Ll;0;L;<font> 03C0;;;;N;;;;;
+213D;DOUBLE-STRUCK SMALL GAMMA;Ll;0;L;<font> 03B3;;;;N;;;;;
+213E;DOUBLE-STRUCK CAPITAL GAMMA;Lu;0;L;<font> 0393;;;;N;;;;;
+213F;DOUBLE-STRUCK CAPITAL PI;Lu;0;L;<font> 03A0;;;;N;;;;;
+2140;DOUBLE-STRUCK N-ARY SUMMATION;Sm;0;ON;<font> 2211;;;;Y;;;;;
+2141;TURNED SANS-SERIF CAPITAL G;Sm;0;ON;;;;;N;;;;;
+2142;TURNED SANS-SERIF CAPITAL L;Sm;0;ON;;;;;N;;;;;
+2143;REVERSED SANS-SERIF CAPITAL L;Sm;0;ON;;;;;N;;;;;
+2144;TURNED SANS-SERIF CAPITAL Y;Sm;0;ON;;;;;N;;;;;
+2145;DOUBLE-STRUCK ITALIC CAPITAL D;Lu;0;L;<font> 0044;;;;N;;;;;
+2146;DOUBLE-STRUCK ITALIC SMALL D;Ll;0;L;<font> 0064;;;;N;;;;;
+2147;DOUBLE-STRUCK ITALIC SMALL E;Ll;0;L;<font> 0065;;;;N;;;;;
+2148;DOUBLE-STRUCK ITALIC SMALL I;Ll;0;L;<font> 0069;;;;N;;;;;
+2149;DOUBLE-STRUCK ITALIC SMALL J;Ll;0;L;<font> 006A;;;;N;;;;;
+214A;PROPERTY LINE;So;0;ON;;;;;N;;;;;
+214B;TURNED AMPERSAND;Sm;0;ON;;;;;N;;;;;
+214C;PER SIGN;So;0;ON;;;;;N;;;;;
+214D;AKTIESELSKAB;So;0;ON;;;;;N;;;;;
+214E;TURNED SMALL F;Ll;0;L;;;;;N;;;2132;;2132
+214F;SYMBOL FOR SAMARITAN SOURCE;So;0;L;;;;;N;;;;;
+2150;VULGAR FRACTION ONE SEVENTH;No;0;ON;<fraction> 0031 2044 0037;;;1/7;N;;;;;
+2151;VULGAR FRACTION ONE NINTH;No;0;ON;<fraction> 0031 2044 0039;;;1/9;N;;;;;
+2152;VULGAR FRACTION ONE TENTH;No;0;ON;<fraction> 0031 2044 0031 0030;;;1/10;N;;;;;
+2153;VULGAR FRACTION ONE THIRD;No;0;ON;<fraction> 0031 2044 0033;;;1/3;N;FRACTION ONE THIRD;;;;
+2154;VULGAR FRACTION TWO THIRDS;No;0;ON;<fraction> 0032 2044 0033;;;2/3;N;FRACTION TWO THIRDS;;;;
+2155;VULGAR FRACTION ONE FIFTH;No;0;ON;<fraction> 0031 2044 0035;;;1/5;N;FRACTION ONE FIFTH;;;;
+2156;VULGAR FRACTION TWO FIFTHS;No;0;ON;<fraction> 0032 2044 0035;;;2/5;N;FRACTION TWO FIFTHS;;;;
+2157;VULGAR FRACTION THREE FIFTHS;No;0;ON;<fraction> 0033 2044 0035;;;3/5;N;FRACTION THREE FIFTHS;;;;
+2158;VULGAR FRACTION FOUR FIFTHS;No;0;ON;<fraction> 0034 2044 0035;;;4/5;N;FRACTION FOUR FIFTHS;;;;
+2159;VULGAR FRACTION ONE SIXTH;No;0;ON;<fraction> 0031 2044 0036;;;1/6;N;FRACTION ONE SIXTH;;;;
+215A;VULGAR FRACTION FIVE SIXTHS;No;0;ON;<fraction> 0035 2044 0036;;;5/6;N;FRACTION FIVE SIXTHS;;;;
+215B;VULGAR FRACTION ONE EIGHTH;No;0;ON;<fraction> 0031 2044 0038;;;1/8;N;FRACTION ONE EIGHTH;;;;
+215C;VULGAR FRACTION THREE EIGHTHS;No;0;ON;<fraction> 0033 2044 0038;;;3/8;N;FRACTION THREE EIGHTHS;;;;
+215D;VULGAR FRACTION FIVE EIGHTHS;No;0;ON;<fraction> 0035 2044 0038;;;5/8;N;FRACTION FIVE EIGHTHS;;;;
+215E;VULGAR FRACTION SEVEN EIGHTHS;No;0;ON;<fraction> 0037 2044 0038;;;7/8;N;FRACTION SEVEN EIGHTHS;;;;
+215F;FRACTION NUMERATOR ONE;No;0;ON;<fraction> 0031 2044;;;1;N;;;;;
+2160;ROMAN NUMERAL ONE;Nl;0;L;<compat> 0049;;;1;N;;;;2170;
+2161;ROMAN NUMERAL TWO;Nl;0;L;<compat> 0049 0049;;;2;N;;;;2171;
+2162;ROMAN NUMERAL THREE;Nl;0;L;<compat> 0049 0049 0049;;;3;N;;;;2172;
+2163;ROMAN NUMERAL FOUR;Nl;0;L;<compat> 0049 0056;;;4;N;;;;2173;
+2164;ROMAN NUMERAL FIVE;Nl;0;L;<compat> 0056;;;5;N;;;;2174;
+2165;ROMAN NUMERAL SIX;Nl;0;L;<compat> 0056 0049;;;6;N;;;;2175;
+2166;ROMAN NUMERAL SEVEN;Nl;0;L;<compat> 0056 0049 0049;;;7;N;;;;2176;
+2167;ROMAN NUMERAL EIGHT;Nl;0;L;<compat> 0056 0049 0049 0049;;;8;N;;;;2177;
+2168;ROMAN NUMERAL NINE;Nl;0;L;<compat> 0049 0058;;;9;N;;;;2178;
+2169;ROMAN NUMERAL TEN;Nl;0;L;<compat> 0058;;;10;N;;;;2179;
+216A;ROMAN NUMERAL ELEVEN;Nl;0;L;<compat> 0058 0049;;;11;N;;;;217A;
+216B;ROMAN NUMERAL TWELVE;Nl;0;L;<compat> 0058 0049 0049;;;12;N;;;;217B;
+216C;ROMAN NUMERAL FIFTY;Nl;0;L;<compat> 004C;;;50;N;;;;217C;
+216D;ROMAN NUMERAL ONE HUNDRED;Nl;0;L;<compat> 0043;;;100;N;;;;217D;
+216E;ROMAN NUMERAL FIVE HUNDRED;Nl;0;L;<compat> 0044;;;500;N;;;;217E;
+216F;ROMAN NUMERAL ONE THOUSAND;Nl;0;L;<compat> 004D;;;1000;N;;;;217F;
+2170;SMALL ROMAN NUMERAL ONE;Nl;0;L;<compat> 0069;;;1;N;;;2160;;2160
+2171;SMALL ROMAN NUMERAL TWO;Nl;0;L;<compat> 0069 0069;;;2;N;;;2161;;2161
+2172;SMALL ROMAN NUMERAL THREE;Nl;0;L;<compat> 0069 0069 0069;;;3;N;;;2162;;2162
+2173;SMALL ROMAN NUMERAL FOUR;Nl;0;L;<compat> 0069 0076;;;4;N;;;2163;;2163
+2174;SMALL ROMAN NUMERAL FIVE;Nl;0;L;<compat> 0076;;;5;N;;;2164;;2164
+2175;SMALL ROMAN NUMERAL SIX;Nl;0;L;<compat> 0076 0069;;;6;N;;;2165;;2165
+2176;SMALL ROMAN NUMERAL SEVEN;Nl;0;L;<compat> 0076 0069 0069;;;7;N;;;2166;;2166
+2177;SMALL ROMAN NUMERAL EIGHT;Nl;0;L;<compat> 0076 0069 0069 0069;;;8;N;;;2167;;2167
+2178;SMALL ROMAN NUMERAL NINE;Nl;0;L;<compat> 0069 0078;;;9;N;;;2168;;2168
+2179;SMALL ROMAN NUMERAL TEN;Nl;0;L;<compat> 0078;;;10;N;;;2169;;2169
+217A;SMALL ROMAN NUMERAL ELEVEN;Nl;0;L;<compat> 0078 0069;;;11;N;;;216A;;216A
+217B;SMALL ROMAN NUMERAL TWELVE;Nl;0;L;<compat> 0078 0069 0069;;;12;N;;;216B;;216B
+217C;SMALL ROMAN NUMERAL FIFTY;Nl;0;L;<compat> 006C;;;50;N;;;216C;;216C
+217D;SMALL ROMAN NUMERAL ONE HUNDRED;Nl;0;L;<compat> 0063;;;100;N;;;216D;;216D
+217E;SMALL ROMAN NUMERAL FIVE HUNDRED;Nl;0;L;<compat> 0064;;;500;N;;;216E;;216E
+217F;SMALL ROMAN NUMERAL ONE THOUSAND;Nl;0;L;<compat> 006D;;;1000;N;;;216F;;216F
+2180;ROMAN NUMERAL ONE THOUSAND C D;Nl;0;L;;;;1000;N;;;;;
+2181;ROMAN NUMERAL FIVE THOUSAND;Nl;0;L;;;;5000;N;;;;;
+2182;ROMAN NUMERAL TEN THOUSAND;Nl;0;L;;;;10000;N;;;;;
+2183;ROMAN NUMERAL REVERSED ONE HUNDRED;Lu;0;L;;;;;N;;;;2184;
+2184;LATIN SMALL LETTER REVERSED C;Ll;0;L;;;;;N;;;2183;;2183
+2185;ROMAN NUMERAL SIX LATE FORM;Nl;0;L;;;;6;N;;;;;
+2186;ROMAN NUMERAL FIFTY EARLY FORM;Nl;0;L;;;;50;N;;;;;
+2187;ROMAN NUMERAL FIFTY THOUSAND;Nl;0;L;;;;50000;N;;;;;
+2188;ROMAN NUMERAL ONE HUNDRED THOUSAND;Nl;0;L;;;;100000;N;;;;;
+2189;VULGAR FRACTION ZERO THIRDS;No;0;ON;<fraction> 0030 2044 0033;;;0;N;;;;;
+2190;LEFTWARDS ARROW;Sm;0;ON;;;;;N;LEFT ARROW;;;;
+2191;UPWARDS ARROW;Sm;0;ON;;;;;N;UP ARROW;;;;
+2192;RIGHTWARDS ARROW;Sm;0;ON;;;;;N;RIGHT ARROW;;;;
+2193;DOWNWARDS ARROW;Sm;0;ON;;;;;N;DOWN ARROW;;;;
+2194;LEFT RIGHT ARROW;Sm;0;ON;;;;;N;;;;;
+2195;UP DOWN ARROW;So;0;ON;;;;;N;;;;;
+2196;NORTH WEST ARROW;So;0;ON;;;;;N;UPPER LEFT ARROW;;;;
+2197;NORTH EAST ARROW;So;0;ON;;;;;N;UPPER RIGHT ARROW;;;;
+2198;SOUTH EAST ARROW;So;0;ON;;;;;N;LOWER RIGHT ARROW;;;;
+2199;SOUTH WEST ARROW;So;0;ON;;;;;N;LOWER LEFT ARROW;;;;
+219A;LEFTWARDS ARROW WITH STROKE;Sm;0;ON;2190 0338;;;;N;LEFT ARROW WITH STROKE;;;;
+219B;RIGHTWARDS ARROW WITH STROKE;Sm;0;ON;2192 0338;;;;N;RIGHT ARROW WITH STROKE;;;;
+219C;LEFTWARDS WAVE ARROW;So;0;ON;;;;;N;LEFT WAVE ARROW;;;;
+219D;RIGHTWARDS WAVE ARROW;So;0;ON;;;;;N;RIGHT WAVE ARROW;;;;
+219E;LEFTWARDS TWO HEADED ARROW;So;0;ON;;;;;N;LEFT TWO HEADED ARROW;;;;
+219F;UPWARDS TWO HEADED ARROW;So;0;ON;;;;;N;UP TWO HEADED ARROW;;;;
+21A0;RIGHTWARDS TWO HEADED ARROW;Sm;0;ON;;;;;N;RIGHT TWO HEADED ARROW;;;;
+21A1;DOWNWARDS TWO HEADED ARROW;So;0;ON;;;;;N;DOWN TWO HEADED ARROW;;;;
+21A2;LEFTWARDS ARROW WITH TAIL;So;0;ON;;;;;N;LEFT ARROW WITH TAIL;;;;
+21A3;RIGHTWARDS ARROW WITH TAIL;Sm;0;ON;;;;;N;RIGHT ARROW WITH TAIL;;;;
+21A4;LEFTWARDS ARROW FROM BAR;So;0;ON;;;;;N;LEFT ARROW FROM BAR;;;;
+21A5;UPWARDS ARROW FROM BAR;So;0;ON;;;;;N;UP ARROW FROM BAR;;;;
+21A6;RIGHTWARDS ARROW FROM BAR;Sm;0;ON;;;;;N;RIGHT ARROW FROM BAR;;;;
+21A7;DOWNWARDS ARROW FROM BAR;So;0;ON;;;;;N;DOWN ARROW FROM BAR;;;;
+21A8;UP DOWN ARROW WITH BASE;So;0;ON;;;;;N;;;;;
+21A9;LEFTWARDS ARROW WITH HOOK;So;0;ON;;;;;N;LEFT ARROW WITH HOOK;;;;
+21AA;RIGHTWARDS ARROW WITH HOOK;So;0;ON;;;;;N;RIGHT ARROW WITH HOOK;;;;
+21AB;LEFTWARDS ARROW WITH LOOP;So;0;ON;;;;;N;LEFT ARROW WITH LOOP;;;;
+21AC;RIGHTWARDS ARROW WITH LOOP;So;0;ON;;;;;N;RIGHT ARROW WITH LOOP;;;;
+21AD;LEFT RIGHT WAVE ARROW;So;0;ON;;;;;N;;;;;
+21AE;LEFT RIGHT ARROW WITH STROKE;Sm;0;ON;2194 0338;;;;N;;;;;
+21AF;DOWNWARDS ZIGZAG ARROW;So;0;ON;;;;;N;DOWN ZIGZAG ARROW;;;;
+21B0;UPWARDS ARROW WITH TIP LEFTWARDS;So;0;ON;;;;;N;UP ARROW WITH TIP LEFT;;;;
+21B1;UPWARDS ARROW WITH TIP RIGHTWARDS;So;0;ON;;;;;N;UP ARROW WITH TIP RIGHT;;;;
+21B2;DOWNWARDS ARROW WITH TIP LEFTWARDS;So;0;ON;;;;;N;DOWN ARROW WITH TIP LEFT;;;;
+21B3;DOWNWARDS ARROW WITH TIP RIGHTWARDS;So;0;ON;;;;;N;DOWN ARROW WITH TIP RIGHT;;;;
+21B4;RIGHTWARDS ARROW WITH CORNER DOWNWARDS;So;0;ON;;;;;N;RIGHT ARROW WITH CORNER DOWN;;;;
+21B5;DOWNWARDS ARROW WITH CORNER LEFTWARDS;So;0;ON;;;;;N;DOWN ARROW WITH CORNER LEFT;;;;
+21B6;ANTICLOCKWISE TOP SEMICIRCLE ARROW;So;0;ON;;;;;N;;;;;
+21B7;CLOCKWISE TOP SEMICIRCLE ARROW;So;0;ON;;;;;N;;;;;
+21B8;NORTH WEST ARROW TO LONG BAR;So;0;ON;;;;;N;UPPER LEFT ARROW TO LONG BAR;;;;
+21B9;LEFTWARDS ARROW TO BAR OVER RIGHTWARDS ARROW TO BAR;So;0;ON;;;;;N;LEFT ARROW TO BAR OVER RIGHT ARROW TO BAR;;;;
+21BA;ANTICLOCKWISE OPEN CIRCLE ARROW;So;0;ON;;;;;N;;;;;
+21BB;CLOCKWISE OPEN CIRCLE ARROW;So;0;ON;;;;;N;;;;;
+21BC;LEFTWARDS HARPOON WITH BARB UPWARDS;So;0;ON;;;;;N;LEFT HARPOON WITH BARB UP;;;;
+21BD;LEFTWARDS HARPOON WITH BARB DOWNWARDS;So;0;ON;;;;;N;LEFT HARPOON WITH BARB DOWN;;;;
+21BE;UPWARDS HARPOON WITH BARB RIGHTWARDS;So;0;ON;;;;;N;UP HARPOON WITH BARB RIGHT;;;;
+21BF;UPWARDS HARPOON WITH BARB LEFTWARDS;So;0;ON;;;;;N;UP HARPOON WITH BARB LEFT;;;;
+21C0;RIGHTWARDS HARPOON WITH BARB UPWARDS;So;0;ON;;;;;N;RIGHT HARPOON WITH BARB UP;;;;
+21C1;RIGHTWARDS HARPOON WITH BARB DOWNWARDS;So;0;ON;;;;;N;RIGHT HARPOON WITH BARB DOWN;;;;
+21C2;DOWNWARDS HARPOON WITH BARB RIGHTWARDS;So;0;ON;;;;;N;DOWN HARPOON WITH BARB RIGHT;;;;
+21C3;DOWNWARDS HARPOON WITH BARB LEFTWARDS;So;0;ON;;;;;N;DOWN HARPOON WITH BARB LEFT;;;;
+21C4;RIGHTWARDS ARROW OVER LEFTWARDS ARROW;So;0;ON;;;;;N;RIGHT ARROW OVER LEFT ARROW;;;;
+21C5;UPWARDS ARROW LEFTWARDS OF DOWNWARDS ARROW;So;0;ON;;;;;N;UP ARROW LEFT OF DOWN ARROW;;;;
+21C6;LEFTWARDS ARROW OVER RIGHTWARDS ARROW;So;0;ON;;;;;N;LEFT ARROW OVER RIGHT ARROW;;;;
+21C7;LEFTWARDS PAIRED ARROWS;So;0;ON;;;;;N;LEFT PAIRED ARROWS;;;;
+21C8;UPWARDS PAIRED ARROWS;So;0;ON;;;;;N;UP PAIRED ARROWS;;;;
+21C9;RIGHTWARDS PAIRED ARROWS;So;0;ON;;;;;N;RIGHT PAIRED ARROWS;;;;
+21CA;DOWNWARDS PAIRED ARROWS;So;0;ON;;;;;N;DOWN PAIRED ARROWS;;;;
+21CB;LEFTWARDS HARPOON OVER RIGHTWARDS HARPOON;So;0;ON;;;;;N;LEFT HARPOON OVER RIGHT HARPOON;;;;
+21CC;RIGHTWARDS HARPOON OVER LEFTWARDS HARPOON;So;0;ON;;;;;N;RIGHT HARPOON OVER LEFT HARPOON;;;;
+21CD;LEFTWARDS DOUBLE ARROW WITH STROKE;So;0;ON;21D0 0338;;;;N;LEFT DOUBLE ARROW WITH STROKE;;;;
+21CE;LEFT RIGHT DOUBLE ARROW WITH STROKE;Sm;0;ON;21D4 0338;;;;N;;;;;
+21CF;RIGHTWARDS DOUBLE ARROW WITH STROKE;Sm;0;ON;21D2 0338;;;;N;RIGHT DOUBLE ARROW WITH STROKE;;;;
+21D0;LEFTWARDS DOUBLE ARROW;So;0;ON;;;;;N;LEFT DOUBLE ARROW;;;;
+21D1;UPWARDS DOUBLE ARROW;So;0;ON;;;;;N;UP DOUBLE ARROW;;;;
+21D2;RIGHTWARDS DOUBLE ARROW;Sm;0;ON;;;;;N;RIGHT DOUBLE ARROW;;;;
+21D3;DOWNWARDS DOUBLE ARROW;So;0;ON;;;;;N;DOWN DOUBLE ARROW;;;;
+21D4;LEFT RIGHT DOUBLE ARROW;Sm;0;ON;;;;;N;;;;;
+21D5;UP DOWN DOUBLE ARROW;So;0;ON;;;;;N;;;;;
+21D6;NORTH WEST DOUBLE ARROW;So;0;ON;;;;;N;UPPER LEFT DOUBLE ARROW;;;;
+21D7;NORTH EAST DOUBLE ARROW;So;0;ON;;;;;N;UPPER RIGHT DOUBLE ARROW;;;;
+21D8;SOUTH EAST DOUBLE ARROW;So;0;ON;;;;;N;LOWER RIGHT DOUBLE ARROW;;;;
+21D9;SOUTH WEST DOUBLE ARROW;So;0;ON;;;;;N;LOWER LEFT DOUBLE ARROW;;;;
+21DA;LEFTWARDS TRIPLE ARROW;So;0;ON;;;;;N;LEFT TRIPLE ARROW;;;;
+21DB;RIGHTWARDS TRIPLE ARROW;So;0;ON;;;;;N;RIGHT TRIPLE ARROW;;;;
+21DC;LEFTWARDS SQUIGGLE ARROW;So;0;ON;;;;;N;LEFT SQUIGGLE ARROW;;;;
+21DD;RIGHTWARDS SQUIGGLE ARROW;So;0;ON;;;;;N;RIGHT SQUIGGLE ARROW;;;;
+21DE;UPWARDS ARROW WITH DOUBLE STROKE;So;0;ON;;;;;N;UP ARROW WITH DOUBLE STROKE;;;;
+21DF;DOWNWARDS ARROW WITH DOUBLE STROKE;So;0;ON;;;;;N;DOWN ARROW WITH DOUBLE STROKE;;;;
+21E0;LEFTWARDS DASHED ARROW;So;0;ON;;;;;N;LEFT DASHED ARROW;;;;
+21E1;UPWARDS DASHED ARROW;So;0;ON;;;;;N;UP DASHED ARROW;;;;
+21E2;RIGHTWARDS DASHED ARROW;So;0;ON;;;;;N;RIGHT DASHED ARROW;;;;
+21E3;DOWNWARDS DASHED ARROW;So;0;ON;;;;;N;DOWN DASHED ARROW;;;;
+21E4;LEFTWARDS ARROW TO BAR;So;0;ON;;;;;N;LEFT ARROW TO BAR;;;;
+21E5;RIGHTWARDS ARROW TO BAR;So;0;ON;;;;;N;RIGHT ARROW TO BAR;;;;
+21E6;LEFTWARDS WHITE ARROW;So;0;ON;;;;;N;WHITE LEFT ARROW;;;;
+21E7;UPWARDS WHITE ARROW;So;0;ON;;;;;N;WHITE UP ARROW;;;;
+21E8;RIGHTWARDS WHITE ARROW;So;0;ON;;;;;N;WHITE RIGHT ARROW;;;;
+21E9;DOWNWARDS WHITE ARROW;So;0;ON;;;;;N;WHITE DOWN ARROW;;;;
+21EA;UPWARDS WHITE ARROW FROM BAR;So;0;ON;;;;;N;WHITE UP ARROW FROM BAR;;;;
+21EB;UPWARDS WHITE ARROW ON PEDESTAL;So;0;ON;;;;;N;;;;;
+21EC;UPWARDS WHITE ARROW ON PEDESTAL WITH HORIZONTAL BAR;So;0;ON;;;;;N;;;;;
+21ED;UPWARDS WHITE ARROW ON PEDESTAL WITH VERTICAL BAR;So;0;ON;;;;;N;;;;;
+21EE;UPWARDS WHITE DOUBLE ARROW;So;0;ON;;;;;N;;;;;
+21EF;UPWARDS WHITE DOUBLE ARROW ON PEDESTAL;So;0;ON;;;;;N;;;;;
+21F0;RIGHTWARDS WHITE ARROW FROM WALL;So;0;ON;;;;;N;;;;;
+21F1;NORTH WEST ARROW TO CORNER;So;0;ON;;;;;N;;;;;
+21F2;SOUTH EAST ARROW TO CORNER;So;0;ON;;;;;N;;;;;
+21F3;UP DOWN WHITE ARROW;So;0;ON;;;;;N;;;;;
+21F4;RIGHT ARROW WITH SMALL CIRCLE;Sm;0;ON;;;;;N;;;;;
+21F5;DOWNWARDS ARROW LEFTWARDS OF UPWARDS ARROW;Sm;0;ON;;;;;N;;;;;
+21F6;THREE RIGHTWARDS ARROWS;Sm;0;ON;;;;;N;;;;;
+21F7;LEFTWARDS ARROW WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;
+21F8;RIGHTWARDS ARROW WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;
+21F9;LEFT RIGHT ARROW WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;
+21FA;LEFTWARDS ARROW WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;
+21FB;RIGHTWARDS ARROW WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;
+21FC;LEFT RIGHT ARROW WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;
+21FD;LEFTWARDS OPEN-HEADED ARROW;Sm;0;ON;;;;;N;;;;;
+21FE;RIGHTWARDS OPEN-HEADED ARROW;Sm;0;ON;;;;;N;;;;;
+21FF;LEFT RIGHT OPEN-HEADED ARROW;Sm;0;ON;;;;;N;;;;;
+2200;FOR ALL;Sm;0;ON;;;;;N;;;;;
+2201;COMPLEMENT;Sm;0;ON;;;;;Y;;;;;
+2202;PARTIAL DIFFERENTIAL;Sm;0;ON;;;;;Y;;;;;
+2203;THERE EXISTS;Sm;0;ON;;;;;Y;;;;;
+2204;THERE DOES NOT EXIST;Sm;0;ON;2203 0338;;;;Y;;;;;
+2205;EMPTY SET;Sm;0;ON;;;;;N;;;;;
+2206;INCREMENT;Sm;0;ON;;;;;N;;;;;
+2207;NABLA;Sm;0;ON;;;;;N;;;;;
+2208;ELEMENT OF;Sm;0;ON;;;;;Y;;;;;
+2209;NOT AN ELEMENT OF;Sm;0;ON;2208 0338;;;;Y;;;;;
+220A;SMALL ELEMENT OF;Sm;0;ON;;;;;Y;;;;;
+220B;CONTAINS AS MEMBER;Sm;0;ON;;;;;Y;;;;;
+220C;DOES NOT CONTAIN AS MEMBER;Sm;0;ON;220B 0338;;;;Y;;;;;
+220D;SMALL CONTAINS AS MEMBER;Sm;0;ON;;;;;Y;;;;;
+220E;END OF PROOF;Sm;0;ON;;;;;N;;;;;
+220F;N-ARY PRODUCT;Sm;0;ON;;;;;N;;;;;
+2210;N-ARY COPRODUCT;Sm;0;ON;;;;;N;;;;;
+2211;N-ARY SUMMATION;Sm;0;ON;;;;;Y;;;;;
+2212;MINUS SIGN;Sm;0;ES;;;;;N;;;;;
+2213;MINUS-OR-PLUS SIGN;Sm;0;ET;;;;;N;;;;;
+2214;DOT PLUS;Sm;0;ON;;;;;N;;;;;
+2215;DIVISION SLASH;Sm;0;ON;;;;;Y;;;;;
+2216;SET MINUS;Sm;0;ON;;;;;Y;;;;;
+2217;ASTERISK OPERATOR;Sm;0;ON;;;;;N;;;;;
+2218;RING OPERATOR;Sm;0;ON;;;;;N;;;;;
+2219;BULLET OPERATOR;Sm;0;ON;;;;;N;;;;;
+221A;SQUARE ROOT;Sm;0;ON;;;;;Y;;;;;
+221B;CUBE ROOT;Sm;0;ON;;;;;Y;;;;;
+221C;FOURTH ROOT;Sm;0;ON;;;;;Y;;;;;
+221D;PROPORTIONAL TO;Sm;0;ON;;;;;Y;;;;;
+221E;INFINITY;Sm;0;ON;;;;;N;;;;;
+221F;RIGHT ANGLE;Sm;0;ON;;;;;Y;;;;;
+2220;ANGLE;Sm;0;ON;;;;;Y;;;;;
+2221;MEASURED ANGLE;Sm;0;ON;;;;;Y;;;;;
+2222;SPHERICAL ANGLE;Sm;0;ON;;;;;Y;;;;;
+2223;DIVIDES;Sm;0;ON;;;;;N;;;;;
+2224;DOES NOT DIVIDE;Sm;0;ON;2223 0338;;;;Y;;;;;
+2225;PARALLEL TO;Sm;0;ON;;;;;N;;;;;
+2226;NOT PARALLEL TO;Sm;0;ON;2225 0338;;;;Y;;;;;
+2227;LOGICAL AND;Sm;0;ON;;;;;N;;;;;
+2228;LOGICAL OR;Sm;0;ON;;;;;N;;;;;
+2229;INTERSECTION;Sm;0;ON;;;;;N;;;;;
+222A;UNION;Sm;0;ON;;;;;N;;;;;
+222B;INTEGRAL;Sm;0;ON;;;;;Y;;;;;
+222C;DOUBLE INTEGRAL;Sm;0;ON;<compat> 222B 222B;;;;Y;;;;;
+222D;TRIPLE INTEGRAL;Sm;0;ON;<compat> 222B 222B 222B;;;;Y;;;;;
+222E;CONTOUR INTEGRAL;Sm;0;ON;;;;;Y;;;;;
+222F;SURFACE INTEGRAL;Sm;0;ON;<compat> 222E 222E;;;;Y;;;;;
+2230;VOLUME INTEGRAL;Sm;0;ON;<compat> 222E 222E 222E;;;;Y;;;;;
+2231;CLOCKWISE INTEGRAL;Sm;0;ON;;;;;Y;;;;;
+2232;CLOCKWISE CONTOUR INTEGRAL;Sm;0;ON;;;;;Y;;;;;
+2233;ANTICLOCKWISE CONTOUR INTEGRAL;Sm;0;ON;;;;;Y;;;;;
+2234;THEREFORE;Sm;0;ON;;;;;N;;;;;
+2235;BECAUSE;Sm;0;ON;;;;;N;;;;;
+2236;RATIO;Sm;0;ON;;;;;N;;;;;
+2237;PROPORTION;Sm;0;ON;;;;;N;;;;;
+2238;DOT MINUS;Sm;0;ON;;;;;N;;;;;
+2239;EXCESS;Sm;0;ON;;;;;Y;;;;;
+223A;GEOMETRIC PROPORTION;Sm;0;ON;;;;;N;;;;;
+223B;HOMOTHETIC;Sm;0;ON;;;;;Y;;;;;
+223C;TILDE OPERATOR;Sm;0;ON;;;;;Y;;;;;
+223D;REVERSED TILDE;Sm;0;ON;;;;;Y;;;;;
+223E;INVERTED LAZY S;Sm;0;ON;;;;;Y;;;;;
+223F;SINE WAVE;Sm;0;ON;;;;;Y;;;;;
+2240;WREATH PRODUCT;Sm;0;ON;;;;;Y;;;;;
+2241;NOT TILDE;Sm;0;ON;223C 0338;;;;Y;;;;;
+2242;MINUS TILDE;Sm;0;ON;;;;;Y;;;;;
+2243;ASYMPTOTICALLY EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+2244;NOT ASYMPTOTICALLY EQUAL TO;Sm;0;ON;2243 0338;;;;Y;;;;;
+2245;APPROXIMATELY EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+2246;APPROXIMATELY BUT NOT ACTUALLY EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+2247;NEITHER APPROXIMATELY NOR ACTUALLY EQUAL TO;Sm;0;ON;2245 0338;;;;Y;;;;;
+2248;ALMOST EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+2249;NOT ALMOST EQUAL TO;Sm;0;ON;2248 0338;;;;Y;;;;;
+224A;ALMOST EQUAL OR EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+224B;TRIPLE TILDE;Sm;0;ON;;;;;Y;;;;;
+224C;ALL EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+224D;EQUIVALENT TO;Sm;0;ON;;;;;N;;;;;
+224E;GEOMETRICALLY EQUIVALENT TO;Sm;0;ON;;;;;N;;;;;
+224F;DIFFERENCE BETWEEN;Sm;0;ON;;;;;N;;;;;
+2250;APPROACHES THE LIMIT;Sm;0;ON;;;;;N;;;;;
+2251;GEOMETRICALLY EQUAL TO;Sm;0;ON;;;;;N;;;;;
+2252;APPROXIMATELY EQUAL TO OR THE IMAGE OF;Sm;0;ON;;;;;Y;;;;;
+2253;IMAGE OF OR APPROXIMATELY EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+2254;COLON EQUALS;Sm;0;ON;;;;;Y;COLON EQUAL;;;;
+2255;EQUALS COLON;Sm;0;ON;;;;;Y;EQUAL COLON;;;;
+2256;RING IN EQUAL TO;Sm;0;ON;;;;;N;;;;;
+2257;RING EQUAL TO;Sm;0;ON;;;;;N;;;;;
+2258;CORRESPONDS TO;Sm;0;ON;;;;;N;;;;;
+2259;ESTIMATES;Sm;0;ON;;;;;N;;;;;
+225A;EQUIANGULAR TO;Sm;0;ON;;;;;N;;;;;
+225B;STAR EQUALS;Sm;0;ON;;;;;N;;;;;
+225C;DELTA EQUAL TO;Sm;0;ON;;;;;N;;;;;
+225D;EQUAL TO BY DEFINITION;Sm;0;ON;;;;;N;;;;;
+225E;MEASURED BY;Sm;0;ON;;;;;N;;;;;
+225F;QUESTIONED EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+2260;NOT EQUAL TO;Sm;0;ON;003D 0338;;;;Y;;;;;
+2261;IDENTICAL TO;Sm;0;ON;;;;;N;;;;;
+2262;NOT IDENTICAL TO;Sm;0;ON;2261 0338;;;;Y;;;;;
+2263;STRICTLY EQUIVALENT TO;Sm;0;ON;;;;;N;;;;;
+2264;LESS-THAN OR EQUAL TO;Sm;0;ON;;;;;Y;LESS THAN OR EQUAL TO;;;;
+2265;GREATER-THAN OR EQUAL TO;Sm;0;ON;;;;;Y;GREATER THAN OR EQUAL TO;;;;
+2266;LESS-THAN OVER EQUAL TO;Sm;0;ON;;;;;Y;LESS THAN OVER EQUAL TO;;;;
+2267;GREATER-THAN OVER EQUAL TO;Sm;0;ON;;;;;Y;GREATER THAN OVER EQUAL TO;;;;
+2268;LESS-THAN BUT NOT EQUAL TO;Sm;0;ON;;;;;Y;LESS THAN BUT NOT EQUAL TO;;;;
+2269;GREATER-THAN BUT NOT EQUAL TO;Sm;0;ON;;;;;Y;GREATER THAN BUT NOT EQUAL TO;;;;
+226A;MUCH LESS-THAN;Sm;0;ON;;;;;Y;MUCH LESS THAN;;;;
+226B;MUCH GREATER-THAN;Sm;0;ON;;;;;Y;MUCH GREATER THAN;;;;
+226C;BETWEEN;Sm;0;ON;;;;;N;;;;;
+226D;NOT EQUIVALENT TO;Sm;0;ON;224D 0338;;;;N;;;;;
+226E;NOT LESS-THAN;Sm;0;ON;003C 0338;;;;Y;NOT LESS THAN;;;;
+226F;NOT GREATER-THAN;Sm;0;ON;003E 0338;;;;Y;NOT GREATER THAN;;;;
+2270;NEITHER LESS-THAN NOR EQUAL TO;Sm;0;ON;2264 0338;;;;Y;NEITHER LESS THAN NOR EQUAL TO;;;;
+2271;NEITHER GREATER-THAN NOR EQUAL TO;Sm;0;ON;2265 0338;;;;Y;NEITHER GREATER THAN NOR EQUAL TO;;;;
+2272;LESS-THAN OR EQUIVALENT TO;Sm;0;ON;;;;;Y;LESS THAN OR EQUIVALENT TO;;;;
+2273;GREATER-THAN OR EQUIVALENT TO;Sm;0;ON;;;;;Y;GREATER THAN OR EQUIVALENT TO;;;;
+2274;NEITHER LESS-THAN NOR EQUIVALENT TO;Sm;0;ON;2272 0338;;;;Y;NEITHER LESS THAN NOR EQUIVALENT TO;;;;
+2275;NEITHER GREATER-THAN NOR EQUIVALENT TO;Sm;0;ON;2273 0338;;;;Y;NEITHER GREATER THAN NOR EQUIVALENT TO;;;;
+2276;LESS-THAN OR GREATER-THAN;Sm;0;ON;;;;;Y;LESS THAN OR GREATER THAN;;;;
+2277;GREATER-THAN OR LESS-THAN;Sm;0;ON;;;;;Y;GREATER THAN OR LESS THAN;;;;
+2278;NEITHER LESS-THAN NOR GREATER-THAN;Sm;0;ON;2276 0338;;;;Y;NEITHER LESS THAN NOR GREATER THAN;;;;
+2279;NEITHER GREATER-THAN NOR LESS-THAN;Sm;0;ON;2277 0338;;;;Y;NEITHER GREATER THAN NOR LESS THAN;;;;
+227A;PRECEDES;Sm;0;ON;;;;;Y;;;;;
+227B;SUCCEEDS;Sm;0;ON;;;;;Y;;;;;
+227C;PRECEDES OR EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+227D;SUCCEEDS OR EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+227E;PRECEDES OR EQUIVALENT TO;Sm;0;ON;;;;;Y;;;;;
+227F;SUCCEEDS OR EQUIVALENT TO;Sm;0;ON;;;;;Y;;;;;
+2280;DOES NOT PRECEDE;Sm;0;ON;227A 0338;;;;Y;;;;;
+2281;DOES NOT SUCCEED;Sm;0;ON;227B 0338;;;;Y;;;;;
+2282;SUBSET OF;Sm;0;ON;;;;;Y;;;;;
+2283;SUPERSET OF;Sm;0;ON;;;;;Y;;;;;
+2284;NOT A SUBSET OF;Sm;0;ON;2282 0338;;;;Y;;;;;
+2285;NOT A SUPERSET OF;Sm;0;ON;2283 0338;;;;Y;;;;;
+2286;SUBSET OF OR EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+2287;SUPERSET OF OR EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+2288;NEITHER A SUBSET OF NOR EQUAL TO;Sm;0;ON;2286 0338;;;;Y;;;;;
+2289;NEITHER A SUPERSET OF NOR EQUAL TO;Sm;0;ON;2287 0338;;;;Y;;;;;
+228A;SUBSET OF WITH NOT EQUAL TO;Sm;0;ON;;;;;Y;SUBSET OF OR NOT EQUAL TO;;;;
+228B;SUPERSET OF WITH NOT EQUAL TO;Sm;0;ON;;;;;Y;SUPERSET OF OR NOT EQUAL TO;;;;
+228C;MULTISET;Sm;0;ON;;;;;Y;;;;;
+228D;MULTISET MULTIPLICATION;Sm;0;ON;;;;;N;;;;;
+228E;MULTISET UNION;Sm;0;ON;;;;;N;;;;;
+228F;SQUARE IMAGE OF;Sm;0;ON;;;;;Y;;;;;
+2290;SQUARE ORIGINAL OF;Sm;0;ON;;;;;Y;;;;;
+2291;SQUARE IMAGE OF OR EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+2292;SQUARE ORIGINAL OF OR EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+2293;SQUARE CAP;Sm;0;ON;;;;;N;;;;;
+2294;SQUARE CUP;Sm;0;ON;;;;;N;;;;;
+2295;CIRCLED PLUS;Sm;0;ON;;;;;N;;;;;
+2296;CIRCLED MINUS;Sm;0;ON;;;;;N;;;;;
+2297;CIRCLED TIMES;Sm;0;ON;;;;;N;;;;;
+2298;CIRCLED DIVISION SLASH;Sm;0;ON;;;;;Y;;;;;
+2299;CIRCLED DOT OPERATOR;Sm;0;ON;;;;;N;;;;;
+229A;CIRCLED RING OPERATOR;Sm;0;ON;;;;;N;;;;;
+229B;CIRCLED ASTERISK OPERATOR;Sm;0;ON;;;;;N;;;;;
+229C;CIRCLED EQUALS;Sm;0;ON;;;;;N;;;;;
+229D;CIRCLED DASH;Sm;0;ON;;;;;N;;;;;
+229E;SQUARED PLUS;Sm;0;ON;;;;;N;;;;;
+229F;SQUARED MINUS;Sm;0;ON;;;;;N;;;;;
+22A0;SQUARED TIMES;Sm;0;ON;;;;;N;;;;;
+22A1;SQUARED DOT OPERATOR;Sm;0;ON;;;;;N;;;;;
+22A2;RIGHT TACK;Sm;0;ON;;;;;Y;;;;;
+22A3;LEFT TACK;Sm;0;ON;;;;;Y;;;;;
+22A4;DOWN TACK;Sm;0;ON;;;;;N;;;;;
+22A5;UP TACK;Sm;0;ON;;;;;N;;;;;
+22A6;ASSERTION;Sm;0;ON;;;;;Y;;;;;
+22A7;MODELS;Sm;0;ON;;;;;Y;;;;;
+22A8;TRUE;Sm;0;ON;;;;;Y;;;;;
+22A9;FORCES;Sm;0;ON;;;;;Y;;;;;
+22AA;TRIPLE VERTICAL BAR RIGHT TURNSTILE;Sm;0;ON;;;;;Y;;;;;
+22AB;DOUBLE VERTICAL BAR DOUBLE RIGHT TURNSTILE;Sm;0;ON;;;;;Y;;;;;
+22AC;DOES NOT PROVE;Sm;0;ON;22A2 0338;;;;Y;;;;;
+22AD;NOT TRUE;Sm;0;ON;22A8 0338;;;;Y;;;;;
+22AE;DOES NOT FORCE;Sm;0;ON;22A9 0338;;;;Y;;;;;
+22AF;NEGATED DOUBLE VERTICAL BAR DOUBLE RIGHT TURNSTILE;Sm;0;ON;22AB 0338;;;;Y;;;;;
+22B0;PRECEDES UNDER RELATION;Sm;0;ON;;;;;Y;;;;;
+22B1;SUCCEEDS UNDER RELATION;Sm;0;ON;;;;;Y;;;;;
+22B2;NORMAL SUBGROUP OF;Sm;0;ON;;;;;Y;;;;;
+22B3;CONTAINS AS NORMAL SUBGROUP;Sm;0;ON;;;;;Y;;;;;
+22B4;NORMAL SUBGROUP OF OR EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+22B5;CONTAINS AS NORMAL SUBGROUP OR EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+22B6;ORIGINAL OF;Sm;0;ON;;;;;Y;;;;;
+22B7;IMAGE OF;Sm;0;ON;;;;;Y;;;;;
+22B8;MULTIMAP;Sm;0;ON;;;;;Y;;;;;
+22B9;HERMITIAN CONJUGATE MATRIX;Sm;0;ON;;;;;N;;;;;
+22BA;INTERCALATE;Sm;0;ON;;;;;N;;;;;
+22BB;XOR;Sm;0;ON;;;;;N;;;;;
+22BC;NAND;Sm;0;ON;;;;;N;;;;;
+22BD;NOR;Sm;0;ON;;;;;N;;;;;
+22BE;RIGHT ANGLE WITH ARC;Sm;0;ON;;;;;Y;;;;;
+22BF;RIGHT TRIANGLE;Sm;0;ON;;;;;Y;;;;;
+22C0;N-ARY LOGICAL AND;Sm;0;ON;;;;;N;;;;;
+22C1;N-ARY LOGICAL OR;Sm;0;ON;;;;;N;;;;;
+22C2;N-ARY INTERSECTION;Sm;0;ON;;;;;N;;;;;
+22C3;N-ARY UNION;Sm;0;ON;;;;;N;;;;;
+22C4;DIAMOND OPERATOR;Sm;0;ON;;;;;N;;;;;
+22C5;DOT OPERATOR;Sm;0;ON;;;;;N;;;;;
+22C6;STAR OPERATOR;Sm;0;ON;;;;;N;;;;;
+22C7;DIVISION TIMES;Sm;0;ON;;;;;N;;;;;
+22C8;BOWTIE;Sm;0;ON;;;;;N;;;;;
+22C9;LEFT NORMAL FACTOR SEMIDIRECT PRODUCT;Sm;0;ON;;;;;Y;;;;;
+22CA;RIGHT NORMAL FACTOR SEMIDIRECT PRODUCT;Sm;0;ON;;;;;Y;;;;;
+22CB;LEFT SEMIDIRECT PRODUCT;Sm;0;ON;;;;;Y;;;;;
+22CC;RIGHT SEMIDIRECT PRODUCT;Sm;0;ON;;;;;Y;;;;;
+22CD;REVERSED TILDE EQUALS;Sm;0;ON;;;;;Y;;;;;
+22CE;CURLY LOGICAL OR;Sm;0;ON;;;;;N;;;;;
+22CF;CURLY LOGICAL AND;Sm;0;ON;;;;;N;;;;;
+22D0;DOUBLE SUBSET;Sm;0;ON;;;;;Y;;;;;
+22D1;DOUBLE SUPERSET;Sm;0;ON;;;;;Y;;;;;
+22D2;DOUBLE INTERSECTION;Sm;0;ON;;;;;N;;;;;
+22D3;DOUBLE UNION;Sm;0;ON;;;;;N;;;;;
+22D4;PITCHFORK;Sm;0;ON;;;;;N;;;;;
+22D5;EQUAL AND PARALLEL TO;Sm;0;ON;;;;;N;;;;;
+22D6;LESS-THAN WITH DOT;Sm;0;ON;;;;;Y;LESS THAN WITH DOT;;;;
+22D7;GREATER-THAN WITH DOT;Sm;0;ON;;;;;Y;GREATER THAN WITH DOT;;;;
+22D8;VERY MUCH LESS-THAN;Sm;0;ON;;;;;Y;VERY MUCH LESS THAN;;;;
+22D9;VERY MUCH GREATER-THAN;Sm;0;ON;;;;;Y;VERY MUCH GREATER THAN;;;;
+22DA;LESS-THAN EQUAL TO OR GREATER-THAN;Sm;0;ON;;;;;Y;LESS THAN EQUAL TO OR GREATER THAN;;;;
+22DB;GREATER-THAN EQUAL TO OR LESS-THAN;Sm;0;ON;;;;;Y;GREATER THAN EQUAL TO OR LESS THAN;;;;
+22DC;EQUAL TO OR LESS-THAN;Sm;0;ON;;;;;Y;EQUAL TO OR LESS THAN;;;;
+22DD;EQUAL TO OR GREATER-THAN;Sm;0;ON;;;;;Y;EQUAL TO OR GREATER THAN;;;;
+22DE;EQUAL TO OR PRECEDES;Sm;0;ON;;;;;Y;;;;;
+22DF;EQUAL TO OR SUCCEEDS;Sm;0;ON;;;;;Y;;;;;
+22E0;DOES NOT PRECEDE OR EQUAL;Sm;0;ON;227C 0338;;;;Y;;;;;
+22E1;DOES NOT SUCCEED OR EQUAL;Sm;0;ON;227D 0338;;;;Y;;;;;
+22E2;NOT SQUARE IMAGE OF OR EQUAL TO;Sm;0;ON;2291 0338;;;;Y;;;;;
+22E3;NOT SQUARE ORIGINAL OF OR EQUAL TO;Sm;0;ON;2292 0338;;;;Y;;;;;
+22E4;SQUARE IMAGE OF OR NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+22E5;SQUARE ORIGINAL OF OR NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+22E6;LESS-THAN BUT NOT EQUIVALENT TO;Sm;0;ON;;;;;Y;LESS THAN BUT NOT EQUIVALENT TO;;;;
+22E7;GREATER-THAN BUT NOT EQUIVALENT TO;Sm;0;ON;;;;;Y;GREATER THAN BUT NOT EQUIVALENT TO;;;;
+22E8;PRECEDES BUT NOT EQUIVALENT TO;Sm;0;ON;;;;;Y;;;;;
+22E9;SUCCEEDS BUT NOT EQUIVALENT TO;Sm;0;ON;;;;;Y;;;;;
+22EA;NOT NORMAL SUBGROUP OF;Sm;0;ON;22B2 0338;;;;Y;;;;;
+22EB;DOES NOT CONTAIN AS NORMAL SUBGROUP;Sm;0;ON;22B3 0338;;;;Y;;;;;
+22EC;NOT NORMAL SUBGROUP OF OR EQUAL TO;Sm;0;ON;22B4 0338;;;;Y;;;;;
+22ED;DOES NOT CONTAIN AS NORMAL SUBGROUP OR EQUAL;Sm;0;ON;22B5 0338;;;;Y;;;;;
+22EE;VERTICAL ELLIPSIS;Sm;0;ON;;;;;N;;;;;
+22EF;MIDLINE HORIZONTAL ELLIPSIS;Sm;0;ON;;;;;N;;;;;
+22F0;UP RIGHT DIAGONAL ELLIPSIS;Sm;0;ON;;;;;Y;;;;;
+22F1;DOWN RIGHT DIAGONAL ELLIPSIS;Sm;0;ON;;;;;Y;;;;;
+22F2;ELEMENT OF WITH LONG HORIZONTAL STROKE;Sm;0;ON;;;;;Y;;;;;
+22F3;ELEMENT OF WITH VERTICAL BAR AT END OF HORIZONTAL STROKE;Sm;0;ON;;;;;Y;;;;;
+22F4;SMALL ELEMENT OF WITH VERTICAL BAR AT END OF HORIZONTAL STROKE;Sm;0;ON;;;;;Y;;;;;
+22F5;ELEMENT OF WITH DOT ABOVE;Sm;0;ON;;;;;Y;;;;;
+22F6;ELEMENT OF WITH OVERBAR;Sm;0;ON;;;;;Y;;;;;
+22F7;SMALL ELEMENT OF WITH OVERBAR;Sm;0;ON;;;;;Y;;;;;
+22F8;ELEMENT OF WITH UNDERBAR;Sm;0;ON;;;;;Y;;;;;
+22F9;ELEMENT OF WITH TWO HORIZONTAL STROKES;Sm;0;ON;;;;;Y;;;;;
+22FA;CONTAINS WITH LONG HORIZONTAL STROKE;Sm;0;ON;;;;;Y;;;;;
+22FB;CONTAINS WITH VERTICAL BAR AT END OF HORIZONTAL STROKE;Sm;0;ON;;;;;Y;;;;;
+22FC;SMALL CONTAINS WITH VERTICAL BAR AT END OF HORIZONTAL STROKE;Sm;0;ON;;;;;Y;;;;;
+22FD;CONTAINS WITH OVERBAR;Sm;0;ON;;;;;Y;;;;;
+22FE;SMALL CONTAINS WITH OVERBAR;Sm;0;ON;;;;;Y;;;;;
+22FF;Z NOTATION BAG MEMBERSHIP;Sm;0;ON;;;;;Y;;;;;
+2300;DIAMETER SIGN;So;0;ON;;;;;N;;;;;
+2301;ELECTRIC ARROW;So;0;ON;;;;;N;;;;;
+2302;HOUSE;So;0;ON;;;;;N;;;;;
+2303;UP ARROWHEAD;So;0;ON;;;;;N;;;;;
+2304;DOWN ARROWHEAD;So;0;ON;;;;;N;;;;;
+2305;PROJECTIVE;So;0;ON;;;;;N;;;;;
+2306;PERSPECTIVE;So;0;ON;;;;;N;;;;;
+2307;WAVY LINE;So;0;ON;;;;;N;;;;;
+2308;LEFT CEILING;Sm;0;ON;;;;;Y;;;;;
+2309;RIGHT CEILING;Sm;0;ON;;;;;Y;;;;;
+230A;LEFT FLOOR;Sm;0;ON;;;;;Y;;;;;
+230B;RIGHT FLOOR;Sm;0;ON;;;;;Y;;;;;
+230C;BOTTOM RIGHT CROP;So;0;ON;;;;;N;;;;;
+230D;BOTTOM LEFT CROP;So;0;ON;;;;;N;;;;;
+230E;TOP RIGHT CROP;So;0;ON;;;;;N;;;;;
+230F;TOP LEFT CROP;So;0;ON;;;;;N;;;;;
+2310;REVERSED NOT SIGN;So;0;ON;;;;;N;;;;;
+2311;SQUARE LOZENGE;So;0;ON;;;;;N;;;;;
+2312;ARC;So;0;ON;;;;;N;;;;;
+2313;SEGMENT;So;0;ON;;;;;N;;;;;
+2314;SECTOR;So;0;ON;;;;;N;;;;;
+2315;TELEPHONE RECORDER;So;0;ON;;;;;N;;;;;
+2316;POSITION INDICATOR;So;0;ON;;;;;N;;;;;
+2317;VIEWDATA SQUARE;So;0;ON;;;;;N;;;;;
+2318;PLACE OF INTEREST SIGN;So;0;ON;;;;;N;COMMAND KEY;;;;
+2319;TURNED NOT SIGN;So;0;ON;;;;;N;;;;;
+231A;WATCH;So;0;ON;;;;;N;;;;;
+231B;HOURGLASS;So;0;ON;;;;;N;;;;;
+231C;TOP LEFT CORNER;So;0;ON;;;;;N;;;;;
+231D;TOP RIGHT CORNER;So;0;ON;;;;;N;;;;;
+231E;BOTTOM LEFT CORNER;So;0;ON;;;;;N;;;;;
+231F;BOTTOM RIGHT CORNER;So;0;ON;;;;;N;;;;;
+2320;TOP HALF INTEGRAL;Sm;0;ON;;;;;Y;;;;;
+2321;BOTTOM HALF INTEGRAL;Sm;0;ON;;;;;Y;;;;;
+2322;FROWN;So;0;ON;;;;;N;;;;;
+2323;SMILE;So;0;ON;;;;;N;;;;;
+2324;UP ARROWHEAD BETWEEN TWO HORIZONTAL BARS;So;0;ON;;;;;N;ENTER KEY;;;;
+2325;OPTION KEY;So;0;ON;;;;;N;;;;;
+2326;ERASE TO THE RIGHT;So;0;ON;;;;;N;DELETE TO THE RIGHT KEY;;;;
+2327;X IN A RECTANGLE BOX;So;0;ON;;;;;N;CLEAR KEY;;;;
+2328;KEYBOARD;So;0;ON;;;;;N;;;;;
+2329;LEFT-POINTING ANGLE BRACKET;Ps;0;ON;3008;;;;Y;BRA;;;;
+232A;RIGHT-POINTING ANGLE BRACKET;Pe;0;ON;3009;;;;Y;KET;;;;
+232B;ERASE TO THE LEFT;So;0;ON;;;;;N;DELETE TO THE LEFT KEY;;;;
+232C;BENZENE RING;So;0;ON;;;;;N;;;;;
+232D;CYLINDRICITY;So;0;ON;;;;;N;;;;;
+232E;ALL AROUND-PROFILE;So;0;ON;;;;;N;;;;;
+232F;SYMMETRY;So;0;ON;;;;;N;;;;;
+2330;TOTAL RUNOUT;So;0;ON;;;;;N;;;;;
+2331;DIMENSION ORIGIN;So;0;ON;;;;;N;;;;;
+2332;CONICAL TAPER;So;0;ON;;;;;N;;;;;
+2333;SLOPE;So;0;ON;;;;;N;;;;;
+2334;COUNTERBORE;So;0;ON;;;;;N;;;;;
+2335;COUNTERSINK;So;0;ON;;;;;N;;;;;
+2336;APL FUNCTIONAL SYMBOL I-BEAM;So;0;L;;;;;N;;;;;
+2337;APL FUNCTIONAL SYMBOL SQUISH QUAD;So;0;L;;;;;N;;;;;
+2338;APL FUNCTIONAL SYMBOL QUAD EQUAL;So;0;L;;;;;N;;;;;
+2339;APL FUNCTIONAL SYMBOL QUAD DIVIDE;So;0;L;;;;;N;;;;;
+233A;APL FUNCTIONAL SYMBOL QUAD DIAMOND;So;0;L;;;;;N;;;;;
+233B;APL FUNCTIONAL SYMBOL QUAD JOT;So;0;L;;;;;N;;;;;
+233C;APL FUNCTIONAL SYMBOL QUAD CIRCLE;So;0;L;;;;;N;;;;;
+233D;APL FUNCTIONAL SYMBOL CIRCLE STILE;So;0;L;;;;;N;;;;;
+233E;APL FUNCTIONAL SYMBOL CIRCLE JOT;So;0;L;;;;;N;;;;;
+233F;APL FUNCTIONAL SYMBOL SLASH BAR;So;0;L;;;;;N;;;;;
+2340;APL FUNCTIONAL SYMBOL BACKSLASH BAR;So;0;L;;;;;N;;;;;
+2341;APL FUNCTIONAL SYMBOL QUAD SLASH;So;0;L;;;;;N;;;;;
+2342;APL FUNCTIONAL SYMBOL QUAD BACKSLASH;So;0;L;;;;;N;;;;;
+2343;APL FUNCTIONAL SYMBOL QUAD LESS-THAN;So;0;L;;;;;N;;;;;
+2344;APL FUNCTIONAL SYMBOL QUAD GREATER-THAN;So;0;L;;;;;N;;;;;
+2345;APL FUNCTIONAL SYMBOL LEFTWARDS VANE;So;0;L;;;;;N;;;;;
+2346;APL FUNCTIONAL SYMBOL RIGHTWARDS VANE;So;0;L;;;;;N;;;;;
+2347;APL FUNCTIONAL SYMBOL QUAD LEFTWARDS ARROW;So;0;L;;;;;N;;;;;
+2348;APL FUNCTIONAL SYMBOL QUAD RIGHTWARDS ARROW;So;0;L;;;;;N;;;;;
+2349;APL FUNCTIONAL SYMBOL CIRCLE BACKSLASH;So;0;L;;;;;N;;;;;
+234A;APL FUNCTIONAL SYMBOL DOWN TACK UNDERBAR;So;0;L;;;;;N;;;;;
+234B;APL FUNCTIONAL SYMBOL DELTA STILE;So;0;L;;;;;N;;;;;
+234C;APL FUNCTIONAL SYMBOL QUAD DOWN CARET;So;0;L;;;;;N;;;;;
+234D;APL FUNCTIONAL SYMBOL QUAD DELTA;So;0;L;;;;;N;;;;;
+234E;APL FUNCTIONAL SYMBOL DOWN TACK JOT;So;0;L;;;;;N;;;;;
+234F;APL FUNCTIONAL SYMBOL UPWARDS VANE;So;0;L;;;;;N;;;;;
+2350;APL FUNCTIONAL SYMBOL QUAD UPWARDS ARROW;So;0;L;;;;;N;;;;;
+2351;APL FUNCTIONAL SYMBOL UP TACK OVERBAR;So;0;L;;;;;N;;;;;
+2352;APL FUNCTIONAL SYMBOL DEL STILE;So;0;L;;;;;N;;;;;
+2353;APL FUNCTIONAL SYMBOL QUAD UP CARET;So;0;L;;;;;N;;;;;
+2354;APL FUNCTIONAL SYMBOL QUAD DEL;So;0;L;;;;;N;;;;;
+2355;APL FUNCTIONAL SYMBOL UP TACK JOT;So;0;L;;;;;N;;;;;
+2356;APL FUNCTIONAL SYMBOL DOWNWARDS VANE;So;0;L;;;;;N;;;;;
+2357;APL FUNCTIONAL SYMBOL QUAD DOWNWARDS ARROW;So;0;L;;;;;N;;;;;
+2358;APL FUNCTIONAL SYMBOL QUOTE UNDERBAR;So;0;L;;;;;N;;;;;
+2359;APL FUNCTIONAL SYMBOL DELTA UNDERBAR;So;0;L;;;;;N;;;;;
+235A;APL FUNCTIONAL SYMBOL DIAMOND UNDERBAR;So;0;L;;;;;N;;;;;
+235B;APL FUNCTIONAL SYMBOL JOT UNDERBAR;So;0;L;;;;;N;;;;;
+235C;APL FUNCTIONAL SYMBOL CIRCLE UNDERBAR;So;0;L;;;;;N;;;;;
+235D;APL FUNCTIONAL SYMBOL UP SHOE JOT;So;0;L;;;;;N;;;;;
+235E;APL FUNCTIONAL SYMBOL QUOTE QUAD;So;0;L;;;;;N;;;;;
+235F;APL FUNCTIONAL SYMBOL CIRCLE STAR;So;0;L;;;;;N;;;;;
+2360;APL FUNCTIONAL SYMBOL QUAD COLON;So;0;L;;;;;N;;;;;
+2361;APL FUNCTIONAL SYMBOL UP TACK DIAERESIS;So;0;L;;;;;N;;;;;
+2362;APL FUNCTIONAL SYMBOL DEL DIAERESIS;So;0;L;;;;;N;;;;;
+2363;APL FUNCTIONAL SYMBOL STAR DIAERESIS;So;0;L;;;;;N;;;;;
+2364;APL FUNCTIONAL SYMBOL JOT DIAERESIS;So;0;L;;;;;N;;;;;
+2365;APL FUNCTIONAL SYMBOL CIRCLE DIAERESIS;So;0;L;;;;;N;;;;;
+2366;APL FUNCTIONAL SYMBOL DOWN SHOE STILE;So;0;L;;;;;N;;;;;
+2367;APL FUNCTIONAL SYMBOL LEFT SHOE STILE;So;0;L;;;;;N;;;;;
+2368;APL FUNCTIONAL SYMBOL TILDE DIAERESIS;So;0;L;;;;;N;;;;;
+2369;APL FUNCTIONAL SYMBOL GREATER-THAN DIAERESIS;So;0;L;;;;;N;;;;;
+236A;APL FUNCTIONAL SYMBOL COMMA BAR;So;0;L;;;;;N;;;;;
+236B;APL FUNCTIONAL SYMBOL DEL TILDE;So;0;L;;;;;N;;;;;
+236C;APL FUNCTIONAL SYMBOL ZILDE;So;0;L;;;;;N;;;;;
+236D;APL FUNCTIONAL SYMBOL STILE TILDE;So;0;L;;;;;N;;;;;
+236E;APL FUNCTIONAL SYMBOL SEMICOLON UNDERBAR;So;0;L;;;;;N;;;;;
+236F;APL FUNCTIONAL SYMBOL QUAD NOT EQUAL;So;0;L;;;;;N;;;;;
+2370;APL FUNCTIONAL SYMBOL QUAD QUESTION;So;0;L;;;;;N;;;;;
+2371;APL FUNCTIONAL SYMBOL DOWN CARET TILDE;So;0;L;;;;;N;;;;;
+2372;APL FUNCTIONAL SYMBOL UP CARET TILDE;So;0;L;;;;;N;;;;;
+2373;APL FUNCTIONAL SYMBOL IOTA;So;0;L;;;;;N;;;;;
+2374;APL FUNCTIONAL SYMBOL RHO;So;0;L;;;;;N;;;;;
+2375;APL FUNCTIONAL SYMBOL OMEGA;So;0;L;;;;;N;;;;;
+2376;APL FUNCTIONAL SYMBOL ALPHA UNDERBAR;So;0;L;;;;;N;;;;;
+2377;APL FUNCTIONAL SYMBOL EPSILON UNDERBAR;So;0;L;;;;;N;;;;;
+2378;APL FUNCTIONAL SYMBOL IOTA UNDERBAR;So;0;L;;;;;N;;;;;
+2379;APL FUNCTIONAL SYMBOL OMEGA UNDERBAR;So;0;L;;;;;N;;;;;
+237A;APL FUNCTIONAL SYMBOL ALPHA;So;0;L;;;;;N;;;;;
+237B;NOT CHECK MARK;So;0;ON;;;;;N;;;;;
+237C;RIGHT ANGLE WITH DOWNWARDS ZIGZAG ARROW;Sm;0;ON;;;;;N;;;;;
+237D;SHOULDERED OPEN BOX;So;0;ON;;;;;N;;;;;
+237E;BELL SYMBOL;So;0;ON;;;;;N;;;;;
+237F;VERTICAL LINE WITH MIDDLE DOT;So;0;ON;;;;;N;;;;;
+2380;INSERTION SYMBOL;So;0;ON;;;;;N;;;;;
+2381;CONTINUOUS UNDERLINE SYMBOL;So;0;ON;;;;;N;;;;;
+2382;DISCONTINUOUS UNDERLINE SYMBOL;So;0;ON;;;;;N;;;;;
+2383;EMPHASIS SYMBOL;So;0;ON;;;;;N;;;;;
+2384;COMPOSITION SYMBOL;So;0;ON;;;;;N;;;;;
+2385;WHITE SQUARE WITH CENTRE VERTICAL LINE;So;0;ON;;;;;N;;;;;
+2386;ENTER SYMBOL;So;0;ON;;;;;N;;;;;
+2387;ALTERNATIVE KEY SYMBOL;So;0;ON;;;;;N;;;;;
+2388;HELM SYMBOL;So;0;ON;;;;;N;;;;;
+2389;CIRCLED HORIZONTAL BAR WITH NOTCH;So;0;ON;;;;;N;;;;;
+238A;CIRCLED TRIANGLE DOWN;So;0;ON;;;;;N;;;;;
+238B;BROKEN CIRCLE WITH NORTHWEST ARROW;So;0;ON;;;;;N;;;;;
+238C;UNDO SYMBOL;So;0;ON;;;;;N;;;;;
+238D;MONOSTABLE SYMBOL;So;0;ON;;;;;N;;;;;
+238E;HYSTERESIS SYMBOL;So;0;ON;;;;;N;;;;;
+238F;OPEN-CIRCUIT-OUTPUT H-TYPE SYMBOL;So;0;ON;;;;;N;;;;;
+2390;OPEN-CIRCUIT-OUTPUT L-TYPE SYMBOL;So;0;ON;;;;;N;;;;;
+2391;PASSIVE-PULL-DOWN-OUTPUT SYMBOL;So;0;ON;;;;;N;;;;;
+2392;PASSIVE-PULL-UP-OUTPUT SYMBOL;So;0;ON;;;;;N;;;;;
+2393;DIRECT CURRENT SYMBOL FORM TWO;So;0;ON;;;;;N;;;;;
+2394;SOFTWARE-FUNCTION SYMBOL;So;0;ON;;;;;N;;;;;
+2395;APL FUNCTIONAL SYMBOL QUAD;So;0;L;;;;;N;;;;;
+2396;DECIMAL SEPARATOR KEY SYMBOL;So;0;ON;;;;;N;;;;;
+2397;PREVIOUS PAGE;So;0;ON;;;;;N;;;;;
+2398;NEXT PAGE;So;0;ON;;;;;N;;;;;
+2399;PRINT SCREEN SYMBOL;So;0;ON;;;;;N;;;;;
+239A;CLEAR SCREEN SYMBOL;So;0;ON;;;;;N;;;;;
+239B;LEFT PARENTHESIS UPPER HOOK;Sm;0;ON;;;;;N;;;;;
+239C;LEFT PARENTHESIS EXTENSION;Sm;0;ON;;;;;N;;;;;
+239D;LEFT PARENTHESIS LOWER HOOK;Sm;0;ON;;;;;N;;;;;
+239E;RIGHT PARENTHESIS UPPER HOOK;Sm;0;ON;;;;;N;;;;;
+239F;RIGHT PARENTHESIS EXTENSION;Sm;0;ON;;;;;N;;;;;
+23A0;RIGHT PARENTHESIS LOWER HOOK;Sm;0;ON;;;;;N;;;;;
+23A1;LEFT SQUARE BRACKET UPPER CORNER;Sm;0;ON;;;;;N;;;;;
+23A2;LEFT SQUARE BRACKET EXTENSION;Sm;0;ON;;;;;N;;;;;
+23A3;LEFT SQUARE BRACKET LOWER CORNER;Sm;0;ON;;;;;N;;;;;
+23A4;RIGHT SQUARE BRACKET UPPER CORNER;Sm;0;ON;;;;;N;;;;;
+23A5;RIGHT SQUARE BRACKET EXTENSION;Sm;0;ON;;;;;N;;;;;
+23A6;RIGHT SQUARE BRACKET LOWER CORNER;Sm;0;ON;;;;;N;;;;;
+23A7;LEFT CURLY BRACKET UPPER HOOK;Sm;0;ON;;;;;N;;;;;
+23A8;LEFT CURLY BRACKET MIDDLE PIECE;Sm;0;ON;;;;;N;;;;;
+23A9;LEFT CURLY BRACKET LOWER HOOK;Sm;0;ON;;;;;N;;;;;
+23AA;CURLY BRACKET EXTENSION;Sm;0;ON;;;;;N;;;;;
+23AB;RIGHT CURLY BRACKET UPPER HOOK;Sm;0;ON;;;;;N;;;;;
+23AC;RIGHT CURLY BRACKET MIDDLE PIECE;Sm;0;ON;;;;;N;;;;;
+23AD;RIGHT CURLY BRACKET LOWER HOOK;Sm;0;ON;;;;;N;;;;;
+23AE;INTEGRAL EXTENSION;Sm;0;ON;;;;;N;;;;;
+23AF;HORIZONTAL LINE EXTENSION;Sm;0;ON;;;;;N;;;;;
+23B0;UPPER LEFT OR LOWER RIGHT CURLY BRACKET SECTION;Sm;0;ON;;;;;N;;;;;
+23B1;UPPER RIGHT OR LOWER LEFT CURLY BRACKET SECTION;Sm;0;ON;;;;;N;;;;;
+23B2;SUMMATION TOP;Sm;0;ON;;;;;N;;;;;
+23B3;SUMMATION BOTTOM;Sm;0;ON;;;;;N;;;;;
+23B4;TOP SQUARE BRACKET;So;0;ON;;;;;N;;;;;
+23B5;BOTTOM SQUARE BRACKET;So;0;ON;;;;;N;;;;;
+23B6;BOTTOM SQUARE BRACKET OVER TOP SQUARE BRACKET;So;0;ON;;;;;N;;;;;
+23B7;RADICAL SYMBOL BOTTOM;So;0;ON;;;;;N;;;;;
+23B8;LEFT VERTICAL BOX LINE;So;0;ON;;;;;N;;;;;
+23B9;RIGHT VERTICAL BOX LINE;So;0;ON;;;;;N;;;;;
+23BA;HORIZONTAL SCAN LINE-1;So;0;ON;;;;;N;;;;;
+23BB;HORIZONTAL SCAN LINE-3;So;0;ON;;;;;N;;;;;
+23BC;HORIZONTAL SCAN LINE-7;So;0;ON;;;;;N;;;;;
+23BD;HORIZONTAL SCAN LINE-9;So;0;ON;;;;;N;;;;;
+23BE;DENTISTRY SYMBOL LIGHT VERTICAL AND TOP RIGHT;So;0;ON;;;;;N;;;;;
+23BF;DENTISTRY SYMBOL LIGHT VERTICAL AND BOTTOM RIGHT;So;0;ON;;;;;N;;;;;
+23C0;DENTISTRY SYMBOL LIGHT VERTICAL WITH CIRCLE;So;0;ON;;;;;N;;;;;
+23C1;DENTISTRY SYMBOL LIGHT DOWN AND HORIZONTAL WITH CIRCLE;So;0;ON;;;;;N;;;;;
+23C2;DENTISTRY SYMBOL LIGHT UP AND HORIZONTAL WITH CIRCLE;So;0;ON;;;;;N;;;;;
+23C3;DENTISTRY SYMBOL LIGHT VERTICAL WITH TRIANGLE;So;0;ON;;;;;N;;;;;
+23C4;DENTISTRY SYMBOL LIGHT DOWN AND HORIZONTAL WITH TRIANGLE;So;0;ON;;;;;N;;;;;
+23C5;DENTISTRY SYMBOL LIGHT UP AND HORIZONTAL WITH TRIANGLE;So;0;ON;;;;;N;;;;;
+23C6;DENTISTRY SYMBOL LIGHT VERTICAL AND WAVE;So;0;ON;;;;;N;;;;;
+23C7;DENTISTRY SYMBOL LIGHT DOWN AND HORIZONTAL WITH WAVE;So;0;ON;;;;;N;;;;;
+23C8;DENTISTRY SYMBOL LIGHT UP AND HORIZONTAL WITH WAVE;So;0;ON;;;;;N;;;;;
+23C9;DENTISTRY SYMBOL LIGHT DOWN AND HORIZONTAL;So;0;ON;;;;;N;;;;;
+23CA;DENTISTRY SYMBOL LIGHT UP AND HORIZONTAL;So;0;ON;;;;;N;;;;;
+23CB;DENTISTRY SYMBOL LIGHT VERTICAL AND TOP LEFT;So;0;ON;;;;;N;;;;;
+23CC;DENTISTRY SYMBOL LIGHT VERTICAL AND BOTTOM LEFT;So;0;ON;;;;;N;;;;;
+23CD;SQUARE FOOT;So;0;ON;;;;;N;;;;;
+23CE;RETURN SYMBOL;So;0;ON;;;;;N;;;;;
+23CF;EJECT SYMBOL;So;0;ON;;;;;N;;;;;
+23D0;VERTICAL LINE EXTENSION;So;0;ON;;;;;N;;;;;
+23D1;METRICAL BREVE;So;0;ON;;;;;N;;;;;
+23D2;METRICAL LONG OVER SHORT;So;0;ON;;;;;N;;;;;
+23D3;METRICAL SHORT OVER LONG;So;0;ON;;;;;N;;;;;
+23D4;METRICAL LONG OVER TWO SHORTS;So;0;ON;;;;;N;;;;;
+23D5;METRICAL TWO SHORTS OVER LONG;So;0;ON;;;;;N;;;;;
+23D6;METRICAL TWO SHORTS JOINED;So;0;ON;;;;;N;;;;;
+23D7;METRICAL TRISEME;So;0;ON;;;;;N;;;;;
+23D8;METRICAL TETRASEME;So;0;ON;;;;;N;;;;;
+23D9;METRICAL PENTASEME;So;0;ON;;;;;N;;;;;
+23DA;EARTH GROUND;So;0;ON;;;;;N;;;;;
+23DB;FUSE;So;0;ON;;;;;N;;;;;
+23DC;TOP PARENTHESIS;Sm;0;ON;;;;;N;;;;;
+23DD;BOTTOM PARENTHESIS;Sm;0;ON;;;;;N;;;;;
+23DE;TOP CURLY BRACKET;Sm;0;ON;;;;;N;;;;;
+23DF;BOTTOM CURLY BRACKET;Sm;0;ON;;;;;N;;;;;
+23E0;TOP TORTOISE SHELL BRACKET;Sm;0;ON;;;;;N;;;;;
+23E1;BOTTOM TORTOISE SHELL BRACKET;Sm;0;ON;;;;;N;;;;;
+23E2;WHITE TRAPEZIUM;So;0;ON;;;;;N;;;;;
+23E3;BENZENE RING WITH CIRCLE;So;0;ON;;;;;N;;;;;
+23E4;STRAIGHTNESS;So;0;ON;;;;;N;;;;;
+23E5;FLATNESS;So;0;ON;;;;;N;;;;;
+23E6;AC CURRENT;So;0;ON;;;;;N;;;;;
+23E7;ELECTRICAL INTERSECTION;So;0;ON;;;;;N;;;;;
+23E8;DECIMAL EXPONENT SYMBOL;So;0;ON;;;;;N;;;;;
+23E9;BLACK RIGHT-POINTING DOUBLE TRIANGLE;So;0;ON;;;;;N;;;;;
+23EA;BLACK LEFT-POINTING DOUBLE TRIANGLE;So;0;ON;;;;;N;;;;;
+23EB;BLACK UP-POINTING DOUBLE TRIANGLE;So;0;ON;;;;;N;;;;;
+23EC;BLACK DOWN-POINTING DOUBLE TRIANGLE;So;0;ON;;;;;N;;;;;
+23ED;BLACK RIGHT-POINTING DOUBLE TRIANGLE WITH VERTICAL BAR;So;0;ON;;;;;N;;;;;
+23EE;BLACK LEFT-POINTING DOUBLE TRIANGLE WITH VERTICAL BAR;So;0;ON;;;;;N;;;;;
+23EF;BLACK RIGHT-POINTING TRIANGLE WITH DOUBLE VERTICAL BAR;So;0;ON;;;;;N;;;;;
+23F0;ALARM CLOCK;So;0;ON;;;;;N;;;;;
+23F1;STOPWATCH;So;0;ON;;;;;N;;;;;
+23F2;TIMER CLOCK;So;0;ON;;;;;N;;;;;
+23F3;HOURGLASS WITH FLOWING SAND;So;0;ON;;;;;N;;;;;
+2400;SYMBOL FOR NULL;So;0;ON;;;;;N;GRAPHIC FOR NULL;;;;
+2401;SYMBOL FOR START OF HEADING;So;0;ON;;;;;N;GRAPHIC FOR START OF HEADING;;;;
+2402;SYMBOL FOR START OF TEXT;So;0;ON;;;;;N;GRAPHIC FOR START OF TEXT;;;;
+2403;SYMBOL FOR END OF TEXT;So;0;ON;;;;;N;GRAPHIC FOR END OF TEXT;;;;
+2404;SYMBOL FOR END OF TRANSMISSION;So;0;ON;;;;;N;GRAPHIC FOR END OF TRANSMISSION;;;;
+2405;SYMBOL FOR ENQUIRY;So;0;ON;;;;;N;GRAPHIC FOR ENQUIRY;;;;
+2406;SYMBOL FOR ACKNOWLEDGE;So;0;ON;;;;;N;GRAPHIC FOR ACKNOWLEDGE;;;;
+2407;SYMBOL FOR BELL;So;0;ON;;;;;N;GRAPHIC FOR BELL;;;;
+2408;SYMBOL FOR BACKSPACE;So;0;ON;;;;;N;GRAPHIC FOR BACKSPACE;;;;
+2409;SYMBOL FOR HORIZONTAL TABULATION;So;0;ON;;;;;N;GRAPHIC FOR HORIZONTAL TABULATION;;;;
+240A;SYMBOL FOR LINE FEED;So;0;ON;;;;;N;GRAPHIC FOR LINE FEED;;;;
+240B;SYMBOL FOR VERTICAL TABULATION;So;0;ON;;;;;N;GRAPHIC FOR VERTICAL TABULATION;;;;
+240C;SYMBOL FOR FORM FEED;So;0;ON;;;;;N;GRAPHIC FOR FORM FEED;;;;
+240D;SYMBOL FOR CARRIAGE RETURN;So;0;ON;;;;;N;GRAPHIC FOR CARRIAGE RETURN;;;;
+240E;SYMBOL FOR SHIFT OUT;So;0;ON;;;;;N;GRAPHIC FOR SHIFT OUT;;;;
+240F;SYMBOL FOR SHIFT IN;So;0;ON;;;;;N;GRAPHIC FOR SHIFT IN;;;;
+2410;SYMBOL FOR DATA LINK ESCAPE;So;0;ON;;;;;N;GRAPHIC FOR DATA LINK ESCAPE;;;;
+2411;SYMBOL FOR DEVICE CONTROL ONE;So;0;ON;;;;;N;GRAPHIC FOR DEVICE CONTROL ONE;;;;
+2412;SYMBOL FOR DEVICE CONTROL TWO;So;0;ON;;;;;N;GRAPHIC FOR DEVICE CONTROL TWO;;;;
+2413;SYMBOL FOR DEVICE CONTROL THREE;So;0;ON;;;;;N;GRAPHIC FOR DEVICE CONTROL THREE;;;;
+2414;SYMBOL FOR DEVICE CONTROL FOUR;So;0;ON;;;;;N;GRAPHIC FOR DEVICE CONTROL FOUR;;;;
+2415;SYMBOL FOR NEGATIVE ACKNOWLEDGE;So;0;ON;;;;;N;GRAPHIC FOR NEGATIVE ACKNOWLEDGE;;;;
+2416;SYMBOL FOR SYNCHRONOUS IDLE;So;0;ON;;;;;N;GRAPHIC FOR SYNCHRONOUS IDLE;;;;
+2417;SYMBOL FOR END OF TRANSMISSION BLOCK;So;0;ON;;;;;N;GRAPHIC FOR END OF TRANSMISSION BLOCK;;;;
+2418;SYMBOL FOR CANCEL;So;0;ON;;;;;N;GRAPHIC FOR CANCEL;;;;
+2419;SYMBOL FOR END OF MEDIUM;So;0;ON;;;;;N;GRAPHIC FOR END OF MEDIUM;;;;
+241A;SYMBOL FOR SUBSTITUTE;So;0;ON;;;;;N;GRAPHIC FOR SUBSTITUTE;;;;
+241B;SYMBOL FOR ESCAPE;So;0;ON;;;;;N;GRAPHIC FOR ESCAPE;;;;
+241C;SYMBOL FOR FILE SEPARATOR;So;0;ON;;;;;N;GRAPHIC FOR FILE SEPARATOR;;;;
+241D;SYMBOL FOR GROUP SEPARATOR;So;0;ON;;;;;N;GRAPHIC FOR GROUP SEPARATOR;;;;
+241E;SYMBOL FOR RECORD SEPARATOR;So;0;ON;;;;;N;GRAPHIC FOR RECORD SEPARATOR;;;;
+241F;SYMBOL FOR UNIT SEPARATOR;So;0;ON;;;;;N;GRAPHIC FOR UNIT SEPARATOR;;;;
+2420;SYMBOL FOR SPACE;So;0;ON;;;;;N;GRAPHIC FOR SPACE;;;;
+2421;SYMBOL FOR DELETE;So;0;ON;;;;;N;GRAPHIC FOR DELETE;;;;
+2422;BLANK SYMBOL;So;0;ON;;;;;N;BLANK;;;;
+2423;OPEN BOX;So;0;ON;;;;;N;;;;;
+2424;SYMBOL FOR NEWLINE;So;0;ON;;;;;N;GRAPHIC FOR NEWLINE;;;;
+2425;SYMBOL FOR DELETE FORM TWO;So;0;ON;;;;;N;;;;;
+2426;SYMBOL FOR SUBSTITUTE FORM TWO;So;0;ON;;;;;N;;;;;
+2440;OCR HOOK;So;0;ON;;;;;N;;;;;
+2441;OCR CHAIR;So;0;ON;;;;;N;;;;;
+2442;OCR FORK;So;0;ON;;;;;N;;;;;
+2443;OCR INVERTED FORK;So;0;ON;;;;;N;;;;;
+2444;OCR BELT BUCKLE;So;0;ON;;;;;N;;;;;
+2445;OCR BOW TIE;So;0;ON;;;;;N;;;;;
+2446;OCR BRANCH BANK IDENTIFICATION;So;0;ON;;;;;N;;;;;
+2447;OCR AMOUNT OF CHECK;So;0;ON;;;;;N;;;;;
+2448;OCR DASH;So;0;ON;;;;;N;;;;;
+2449;OCR CUSTOMER ACCOUNT NUMBER;So;0;ON;;;;;N;;;;;
+244A;OCR DOUBLE BACKSLASH;So;0;ON;;;;;N;;;;;
+2460;CIRCLED DIGIT ONE;No;0;ON;<circle> 0031;;1;1;N;;;;;
+2461;CIRCLED DIGIT TWO;No;0;ON;<circle> 0032;;2;2;N;;;;;
+2462;CIRCLED DIGIT THREE;No;0;ON;<circle> 0033;;3;3;N;;;;;
+2463;CIRCLED DIGIT FOUR;No;0;ON;<circle> 0034;;4;4;N;;;;;
+2464;CIRCLED DIGIT FIVE;No;0;ON;<circle> 0035;;5;5;N;;;;;
+2465;CIRCLED DIGIT SIX;No;0;ON;<circle> 0036;;6;6;N;;;;;
+2466;CIRCLED DIGIT SEVEN;No;0;ON;<circle> 0037;;7;7;N;;;;;
+2467;CIRCLED DIGIT EIGHT;No;0;ON;<circle> 0038;;8;8;N;;;;;
+2468;CIRCLED DIGIT NINE;No;0;ON;<circle> 0039;;9;9;N;;;;;
+2469;CIRCLED NUMBER TEN;No;0;ON;<circle> 0031 0030;;;10;N;;;;;
+246A;CIRCLED NUMBER ELEVEN;No;0;ON;<circle> 0031 0031;;;11;N;;;;;
+246B;CIRCLED NUMBER TWELVE;No;0;ON;<circle> 0031 0032;;;12;N;;;;;
+246C;CIRCLED NUMBER THIRTEEN;No;0;ON;<circle> 0031 0033;;;13;N;;;;;
+246D;CIRCLED NUMBER FOURTEEN;No;0;ON;<circle> 0031 0034;;;14;N;;;;;
+246E;CIRCLED NUMBER FIFTEEN;No;0;ON;<circle> 0031 0035;;;15;N;;;;;
+246F;CIRCLED NUMBER SIXTEEN;No;0;ON;<circle> 0031 0036;;;16;N;;;;;
+2470;CIRCLED NUMBER SEVENTEEN;No;0;ON;<circle> 0031 0037;;;17;N;;;;;
+2471;CIRCLED NUMBER EIGHTEEN;No;0;ON;<circle> 0031 0038;;;18;N;;;;;
+2472;CIRCLED NUMBER NINETEEN;No;0;ON;<circle> 0031 0039;;;19;N;;;;;
+2473;CIRCLED NUMBER TWENTY;No;0;ON;<circle> 0032 0030;;;20;N;;;;;
+2474;PARENTHESIZED DIGIT ONE;No;0;ON;<compat> 0028 0031 0029;;1;1;N;;;;;
+2475;PARENTHESIZED DIGIT TWO;No;0;ON;<compat> 0028 0032 0029;;2;2;N;;;;;
+2476;PARENTHESIZED DIGIT THREE;No;0;ON;<compat> 0028 0033 0029;;3;3;N;;;;;
+2477;PARENTHESIZED DIGIT FOUR;No;0;ON;<compat> 0028 0034 0029;;4;4;N;;;;;
+2478;PARENTHESIZED DIGIT FIVE;No;0;ON;<compat> 0028 0035 0029;;5;5;N;;;;;
+2479;PARENTHESIZED DIGIT SIX;No;0;ON;<compat> 0028 0036 0029;;6;6;N;;;;;
+247A;PARENTHESIZED DIGIT SEVEN;No;0;ON;<compat> 0028 0037 0029;;7;7;N;;;;;
+247B;PARENTHESIZED DIGIT EIGHT;No;0;ON;<compat> 0028 0038 0029;;8;8;N;;;;;
+247C;PARENTHESIZED DIGIT NINE;No;0;ON;<compat> 0028 0039 0029;;9;9;N;;;;;
+247D;PARENTHESIZED NUMBER TEN;No;0;ON;<compat> 0028 0031 0030 0029;;;10;N;;;;;
+247E;PARENTHESIZED NUMBER ELEVEN;No;0;ON;<compat> 0028 0031 0031 0029;;;11;N;;;;;
+247F;PARENTHESIZED NUMBER TWELVE;No;0;ON;<compat> 0028 0031 0032 0029;;;12;N;;;;;
+2480;PARENTHESIZED NUMBER THIRTEEN;No;0;ON;<compat> 0028 0031 0033 0029;;;13;N;;;;;
+2481;PARENTHESIZED NUMBER FOURTEEN;No;0;ON;<compat> 0028 0031 0034 0029;;;14;N;;;;;
+2482;PARENTHESIZED NUMBER FIFTEEN;No;0;ON;<compat> 0028 0031 0035 0029;;;15;N;;;;;
+2483;PARENTHESIZED NUMBER SIXTEEN;No;0;ON;<compat> 0028 0031 0036 0029;;;16;N;;;;;
+2484;PARENTHESIZED NUMBER SEVENTEEN;No;0;ON;<compat> 0028 0031 0037 0029;;;17;N;;;;;
+2485;PARENTHESIZED NUMBER EIGHTEEN;No;0;ON;<compat> 0028 0031 0038 0029;;;18;N;;;;;
+2486;PARENTHESIZED NUMBER NINETEEN;No;0;ON;<compat> 0028 0031 0039 0029;;;19;N;;;;;
+2487;PARENTHESIZED NUMBER TWENTY;No;0;ON;<compat> 0028 0032 0030 0029;;;20;N;;;;;
+2488;DIGIT ONE FULL STOP;No;0;EN;<compat> 0031 002E;;1;1;N;DIGIT ONE PERIOD;;;;
+2489;DIGIT TWO FULL STOP;No;0;EN;<compat> 0032 002E;;2;2;N;DIGIT TWO PERIOD;;;;
+248A;DIGIT THREE FULL STOP;No;0;EN;<compat> 0033 002E;;3;3;N;DIGIT THREE PERIOD;;;;
+248B;DIGIT FOUR FULL STOP;No;0;EN;<compat> 0034 002E;;4;4;N;DIGIT FOUR PERIOD;;;;
+248C;DIGIT FIVE FULL STOP;No;0;EN;<compat> 0035 002E;;5;5;N;DIGIT FIVE PERIOD;;;;
+248D;DIGIT SIX FULL STOP;No;0;EN;<compat> 0036 002E;;6;6;N;DIGIT SIX PERIOD;;;;
+248E;DIGIT SEVEN FULL STOP;No;0;EN;<compat> 0037 002E;;7;7;N;DIGIT SEVEN PERIOD;;;;
+248F;DIGIT EIGHT FULL STOP;No;0;EN;<compat> 0038 002E;;8;8;N;DIGIT EIGHT PERIOD;;;;
+2490;DIGIT NINE FULL STOP;No;0;EN;<compat> 0039 002E;;9;9;N;DIGIT NINE PERIOD;;;;
+2491;NUMBER TEN FULL STOP;No;0;EN;<compat> 0031 0030 002E;;;10;N;NUMBER TEN PERIOD;;;;
+2492;NUMBER ELEVEN FULL STOP;No;0;EN;<compat> 0031 0031 002E;;;11;N;NUMBER ELEVEN PERIOD;;;;
+2493;NUMBER TWELVE FULL STOP;No;0;EN;<compat> 0031 0032 002E;;;12;N;NUMBER TWELVE PERIOD;;;;
+2494;NUMBER THIRTEEN FULL STOP;No;0;EN;<compat> 0031 0033 002E;;;13;N;NUMBER THIRTEEN PERIOD;;;;
+2495;NUMBER FOURTEEN FULL STOP;No;0;EN;<compat> 0031 0034 002E;;;14;N;NUMBER FOURTEEN PERIOD;;;;
+2496;NUMBER FIFTEEN FULL STOP;No;0;EN;<compat> 0031 0035 002E;;;15;N;NUMBER FIFTEEN PERIOD;;;;
+2497;NUMBER SIXTEEN FULL STOP;No;0;EN;<compat> 0031 0036 002E;;;16;N;NUMBER SIXTEEN PERIOD;;;;
+2498;NUMBER SEVENTEEN FULL STOP;No;0;EN;<compat> 0031 0037 002E;;;17;N;NUMBER SEVENTEEN PERIOD;;;;
+2499;NUMBER EIGHTEEN FULL STOP;No;0;EN;<compat> 0031 0038 002E;;;18;N;NUMBER EIGHTEEN PERIOD;;;;
+249A;NUMBER NINETEEN FULL STOP;No;0;EN;<compat> 0031 0039 002E;;;19;N;NUMBER NINETEEN PERIOD;;;;
+249B;NUMBER TWENTY FULL STOP;No;0;EN;<compat> 0032 0030 002E;;;20;N;NUMBER TWENTY PERIOD;;;;
+249C;PARENTHESIZED LATIN SMALL LETTER A;So;0;L;<compat> 0028 0061 0029;;;;N;;;;;
+249D;PARENTHESIZED LATIN SMALL LETTER B;So;0;L;<compat> 0028 0062 0029;;;;N;;;;;
+249E;PARENTHESIZED LATIN SMALL LETTER C;So;0;L;<compat> 0028 0063 0029;;;;N;;;;;
+249F;PARENTHESIZED LATIN SMALL LETTER D;So;0;L;<compat> 0028 0064 0029;;;;N;;;;;
+24A0;PARENTHESIZED LATIN SMALL LETTER E;So;0;L;<compat> 0028 0065 0029;;;;N;;;;;
+24A1;PARENTHESIZED LATIN SMALL LETTER F;So;0;L;<compat> 0028 0066 0029;;;;N;;;;;
+24A2;PARENTHESIZED LATIN SMALL LETTER G;So;0;L;<compat> 0028 0067 0029;;;;N;;;;;
+24A3;PARENTHESIZED LATIN SMALL LETTER H;So;0;L;<compat> 0028 0068 0029;;;;N;;;;;
+24A4;PARENTHESIZED LATIN SMALL LETTER I;So;0;L;<compat> 0028 0069 0029;;;;N;;;;;
+24A5;PARENTHESIZED LATIN SMALL LETTER J;So;0;L;<compat> 0028 006A 0029;;;;N;;;;;
+24A6;PARENTHESIZED LATIN SMALL LETTER K;So;0;L;<compat> 0028 006B 0029;;;;N;;;;;
+24A7;PARENTHESIZED LATIN SMALL LETTER L;So;0;L;<compat> 0028 006C 0029;;;;N;;;;;
+24A8;PARENTHESIZED LATIN SMALL LETTER M;So;0;L;<compat> 0028 006D 0029;;;;N;;;;;
+24A9;PARENTHESIZED LATIN SMALL LETTER N;So;0;L;<compat> 0028 006E 0029;;;;N;;;;;
+24AA;PARENTHESIZED LATIN SMALL LETTER O;So;0;L;<compat> 0028 006F 0029;;;;N;;;;;
+24AB;PARENTHESIZED LATIN SMALL LETTER P;So;0;L;<compat> 0028 0070 0029;;;;N;;;;;
+24AC;PARENTHESIZED LATIN SMALL LETTER Q;So;0;L;<compat> 0028 0071 0029;;;;N;;;;;
+24AD;PARENTHESIZED LATIN SMALL LETTER R;So;0;L;<compat> 0028 0072 0029;;;;N;;;;;
+24AE;PARENTHESIZED LATIN SMALL LETTER S;So;0;L;<compat> 0028 0073 0029;;;;N;;;;;
+24AF;PARENTHESIZED LATIN SMALL LETTER T;So;0;L;<compat> 0028 0074 0029;;;;N;;;;;
+24B0;PARENTHESIZED LATIN SMALL LETTER U;So;0;L;<compat> 0028 0075 0029;;;;N;;;;;
+24B1;PARENTHESIZED LATIN SMALL LETTER V;So;0;L;<compat> 0028 0076 0029;;;;N;;;;;
+24B2;PARENTHESIZED LATIN SMALL LETTER W;So;0;L;<compat> 0028 0077 0029;;;;N;;;;;
+24B3;PARENTHESIZED LATIN SMALL LETTER X;So;0;L;<compat> 0028 0078 0029;;;;N;;;;;
+24B4;PARENTHESIZED LATIN SMALL LETTER Y;So;0;L;<compat> 0028 0079 0029;;;;N;;;;;
+24B5;PARENTHESIZED LATIN SMALL LETTER Z;So;0;L;<compat> 0028 007A 0029;;;;N;;;;;
+24B6;CIRCLED LATIN CAPITAL LETTER A;So;0;L;<circle> 0041;;;;N;;;;24D0;
+24B7;CIRCLED LATIN CAPITAL LETTER B;So;0;L;<circle> 0042;;;;N;;;;24D1;
+24B8;CIRCLED LATIN CAPITAL LETTER C;So;0;L;<circle> 0043;;;;N;;;;24D2;
+24B9;CIRCLED LATIN CAPITAL LETTER D;So;0;L;<circle> 0044;;;;N;;;;24D3;
+24BA;CIRCLED LATIN CAPITAL LETTER E;So;0;L;<circle> 0045;;;;N;;;;24D4;
+24BB;CIRCLED LATIN CAPITAL LETTER F;So;0;L;<circle> 0046;;;;N;;;;24D5;
+24BC;CIRCLED LATIN CAPITAL LETTER G;So;0;L;<circle> 0047;;;;N;;;;24D6;
+24BD;CIRCLED LATIN CAPITAL LETTER H;So;0;L;<circle> 0048;;;;N;;;;24D7;
+24BE;CIRCLED LATIN CAPITAL LETTER I;So;0;L;<circle> 0049;;;;N;;;;24D8;
+24BF;CIRCLED LATIN CAPITAL LETTER J;So;0;L;<circle> 004A;;;;N;;;;24D9;
+24C0;CIRCLED LATIN CAPITAL LETTER K;So;0;L;<circle> 004B;;;;N;;;;24DA;
+24C1;CIRCLED LATIN CAPITAL LETTER L;So;0;L;<circle> 004C;;;;N;;;;24DB;
+24C2;CIRCLED LATIN CAPITAL LETTER M;So;0;L;<circle> 004D;;;;N;;;;24DC;
+24C3;CIRCLED LATIN CAPITAL LETTER N;So;0;L;<circle> 004E;;;;N;;;;24DD;
+24C4;CIRCLED LATIN CAPITAL LETTER O;So;0;L;<circle> 004F;;;;N;;;;24DE;
+24C5;CIRCLED LATIN CAPITAL LETTER P;So;0;L;<circle> 0050;;;;N;;;;24DF;
+24C6;CIRCLED LATIN CAPITAL LETTER Q;So;0;L;<circle> 0051;;;;N;;;;24E0;
+24C7;CIRCLED LATIN CAPITAL LETTER R;So;0;L;<circle> 0052;;;;N;;;;24E1;
+24C8;CIRCLED LATIN CAPITAL LETTER S;So;0;L;<circle> 0053;;;;N;;;;24E2;
+24C9;CIRCLED LATIN CAPITAL LETTER T;So;0;L;<circle> 0054;;;;N;;;;24E3;
+24CA;CIRCLED LATIN CAPITAL LETTER U;So;0;L;<circle> 0055;;;;N;;;;24E4;
+24CB;CIRCLED LATIN CAPITAL LETTER V;So;0;L;<circle> 0056;;;;N;;;;24E5;
+24CC;CIRCLED LATIN CAPITAL LETTER W;So;0;L;<circle> 0057;;;;N;;;;24E6;
+24CD;CIRCLED LATIN CAPITAL LETTER X;So;0;L;<circle> 0058;;;;N;;;;24E7;
+24CE;CIRCLED LATIN CAPITAL LETTER Y;So;0;L;<circle> 0059;;;;N;;;;24E8;
+24CF;CIRCLED LATIN CAPITAL LETTER Z;So;0;L;<circle> 005A;;;;N;;;;24E9;
+24D0;CIRCLED LATIN SMALL LETTER A;So;0;L;<circle> 0061;;;;N;;;24B6;;24B6
+24D1;CIRCLED LATIN SMALL LETTER B;So;0;L;<circle> 0062;;;;N;;;24B7;;24B7
+24D2;CIRCLED LATIN SMALL LETTER C;So;0;L;<circle> 0063;;;;N;;;24B8;;24B8
+24D3;CIRCLED LATIN SMALL LETTER D;So;0;L;<circle> 0064;;;;N;;;24B9;;24B9
+24D4;CIRCLED LATIN SMALL LETTER E;So;0;L;<circle> 0065;;;;N;;;24BA;;24BA
+24D5;CIRCLED LATIN SMALL LETTER F;So;0;L;<circle> 0066;;;;N;;;24BB;;24BB
+24D6;CIRCLED LATIN SMALL LETTER G;So;0;L;<circle> 0067;;;;N;;;24BC;;24BC
+24D7;CIRCLED LATIN SMALL LETTER H;So;0;L;<circle> 0068;;;;N;;;24BD;;24BD
+24D8;CIRCLED LATIN SMALL LETTER I;So;0;L;<circle> 0069;;;;N;;;24BE;;24BE
+24D9;CIRCLED LATIN SMALL LETTER J;So;0;L;<circle> 006A;;;;N;;;24BF;;24BF
+24DA;CIRCLED LATIN SMALL LETTER K;So;0;L;<circle> 006B;;;;N;;;24C0;;24C0
+24DB;CIRCLED LATIN SMALL LETTER L;So;0;L;<circle> 006C;;;;N;;;24C1;;24C1
+24DC;CIRCLED LATIN SMALL LETTER M;So;0;L;<circle> 006D;;;;N;;;24C2;;24C2
+24DD;CIRCLED LATIN SMALL LETTER N;So;0;L;<circle> 006E;;;;N;;;24C3;;24C3
+24DE;CIRCLED LATIN SMALL LETTER O;So;0;L;<circle> 006F;;;;N;;;24C4;;24C4
+24DF;CIRCLED LATIN SMALL LETTER P;So;0;L;<circle> 0070;;;;N;;;24C5;;24C5
+24E0;CIRCLED LATIN SMALL LETTER Q;So;0;L;<circle> 0071;;;;N;;;24C6;;24C6
+24E1;CIRCLED LATIN SMALL LETTER R;So;0;L;<circle> 0072;;;;N;;;24C7;;24C7
+24E2;CIRCLED LATIN SMALL LETTER S;So;0;L;<circle> 0073;;;;N;;;24C8;;24C8
+24E3;CIRCLED LATIN SMALL LETTER T;So;0;L;<circle> 0074;;;;N;;;24C9;;24C9
+24E4;CIRCLED LATIN SMALL LETTER U;So;0;L;<circle> 0075;;;;N;;;24CA;;24CA
+24E5;CIRCLED LATIN SMALL LETTER V;So;0;L;<circle> 0076;;;;N;;;24CB;;24CB
+24E6;CIRCLED LATIN SMALL LETTER W;So;0;L;<circle> 0077;;;;N;;;24CC;;24CC
+24E7;CIRCLED LATIN SMALL LETTER X;So;0;L;<circle> 0078;;;;N;;;24CD;;24CD
+24E8;CIRCLED LATIN SMALL LETTER Y;So;0;L;<circle> 0079;;;;N;;;24CE;;24CE
+24E9;CIRCLED LATIN SMALL LETTER Z;So;0;L;<circle> 007A;;;;N;;;24CF;;24CF
+24EA;CIRCLED DIGIT ZERO;No;0;ON;<circle> 0030;;0;0;N;;;;;
+24EB;NEGATIVE CIRCLED NUMBER ELEVEN;No;0;ON;;;;11;N;;;;;
+24EC;NEGATIVE CIRCLED NUMBER TWELVE;No;0;ON;;;;12;N;;;;;
+24ED;NEGATIVE CIRCLED NUMBER THIRTEEN;No;0;ON;;;;13;N;;;;;
+24EE;NEGATIVE CIRCLED NUMBER FOURTEEN;No;0;ON;;;;14;N;;;;;
+24EF;NEGATIVE CIRCLED NUMBER FIFTEEN;No;0;ON;;;;15;N;;;;;
+24F0;NEGATIVE CIRCLED NUMBER SIXTEEN;No;0;ON;;;;16;N;;;;;
+24F1;NEGATIVE CIRCLED NUMBER SEVENTEEN;No;0;ON;;;;17;N;;;;;
+24F2;NEGATIVE CIRCLED NUMBER EIGHTEEN;No;0;ON;;;;18;N;;;;;
+24F3;NEGATIVE CIRCLED NUMBER NINETEEN;No;0;ON;;;;19;N;;;;;
+24F4;NEGATIVE CIRCLED NUMBER TWENTY;No;0;ON;;;;20;N;;;;;
+24F5;DOUBLE CIRCLED DIGIT ONE;No;0;ON;;;1;1;N;;;;;
+24F6;DOUBLE CIRCLED DIGIT TWO;No;0;ON;;;2;2;N;;;;;
+24F7;DOUBLE CIRCLED DIGIT THREE;No;0;ON;;;3;3;N;;;;;
+24F8;DOUBLE CIRCLED DIGIT FOUR;No;0;ON;;;4;4;N;;;;;
+24F9;DOUBLE CIRCLED DIGIT FIVE;No;0;ON;;;5;5;N;;;;;
+24FA;DOUBLE CIRCLED DIGIT SIX;No;0;ON;;;6;6;N;;;;;
+24FB;DOUBLE CIRCLED DIGIT SEVEN;No;0;ON;;;7;7;N;;;;;
+24FC;DOUBLE CIRCLED DIGIT EIGHT;No;0;ON;;;8;8;N;;;;;
+24FD;DOUBLE CIRCLED DIGIT NINE;No;0;ON;;;9;9;N;;;;;
+24FE;DOUBLE CIRCLED NUMBER TEN;No;0;ON;;;;10;N;;;;;
+24FF;NEGATIVE CIRCLED DIGIT ZERO;No;0;ON;;;0;0;N;;;;;
+2500;BOX DRAWINGS LIGHT HORIZONTAL;So;0;ON;;;;;N;FORMS LIGHT HORIZONTAL;;;;
+2501;BOX DRAWINGS HEAVY HORIZONTAL;So;0;ON;;;;;N;FORMS HEAVY HORIZONTAL;;;;
+2502;BOX DRAWINGS LIGHT VERTICAL;So;0;ON;;;;;N;FORMS LIGHT VERTICAL;;;;
+2503;BOX DRAWINGS HEAVY VERTICAL;So;0;ON;;;;;N;FORMS HEAVY VERTICAL;;;;
+2504;BOX DRAWINGS LIGHT TRIPLE DASH HORIZONTAL;So;0;ON;;;;;N;FORMS LIGHT TRIPLE DASH HORIZONTAL;;;;
+2505;BOX DRAWINGS HEAVY TRIPLE DASH HORIZONTAL;So;0;ON;;;;;N;FORMS HEAVY TRIPLE DASH HORIZONTAL;;;;
+2506;BOX DRAWINGS LIGHT TRIPLE DASH VERTICAL;So;0;ON;;;;;N;FORMS LIGHT TRIPLE DASH VERTICAL;;;;
+2507;BOX DRAWINGS HEAVY TRIPLE DASH VERTICAL;So;0;ON;;;;;N;FORMS HEAVY TRIPLE DASH VERTICAL;;;;
+2508;BOX DRAWINGS LIGHT QUADRUPLE DASH HORIZONTAL;So;0;ON;;;;;N;FORMS LIGHT QUADRUPLE DASH HORIZONTAL;;;;
+2509;BOX DRAWINGS HEAVY QUADRUPLE DASH HORIZONTAL;So;0;ON;;;;;N;FORMS HEAVY QUADRUPLE DASH HORIZONTAL;;;;
+250A;BOX DRAWINGS LIGHT QUADRUPLE DASH VERTICAL;So;0;ON;;;;;N;FORMS LIGHT QUADRUPLE DASH VERTICAL;;;;
+250B;BOX DRAWINGS HEAVY QUADRUPLE DASH VERTICAL;So;0;ON;;;;;N;FORMS HEAVY QUADRUPLE DASH VERTICAL;;;;
+250C;BOX DRAWINGS LIGHT DOWN AND RIGHT;So;0;ON;;;;;N;FORMS LIGHT DOWN AND RIGHT;;;;
+250D;BOX DRAWINGS DOWN LIGHT AND RIGHT HEAVY;So;0;ON;;;;;N;FORMS DOWN LIGHT AND RIGHT HEAVY;;;;
+250E;BOX DRAWINGS DOWN HEAVY AND RIGHT LIGHT;So;0;ON;;;;;N;FORMS DOWN HEAVY AND RIGHT LIGHT;;;;
+250F;BOX DRAWINGS HEAVY DOWN AND RIGHT;So;0;ON;;;;;N;FORMS HEAVY DOWN AND RIGHT;;;;
+2510;BOX DRAWINGS LIGHT DOWN AND LEFT;So;0;ON;;;;;N;FORMS LIGHT DOWN AND LEFT;;;;
+2511;BOX DRAWINGS DOWN LIGHT AND LEFT HEAVY;So;0;ON;;;;;N;FORMS DOWN LIGHT AND LEFT HEAVY;;;;
+2512;BOX DRAWINGS DOWN HEAVY AND LEFT LIGHT;So;0;ON;;;;;N;FORMS DOWN HEAVY AND LEFT LIGHT;;;;
+2513;BOX DRAWINGS HEAVY DOWN AND LEFT;So;0;ON;;;;;N;FORMS HEAVY DOWN AND LEFT;;;;
+2514;BOX DRAWINGS LIGHT UP AND RIGHT;So;0;ON;;;;;N;FORMS LIGHT UP AND RIGHT;;;;
+2515;BOX DRAWINGS UP LIGHT AND RIGHT HEAVY;So;0;ON;;;;;N;FORMS UP LIGHT AND RIGHT HEAVY;;;;
+2516;BOX DRAWINGS UP HEAVY AND RIGHT LIGHT;So;0;ON;;;;;N;FORMS UP HEAVY AND RIGHT LIGHT;;;;
+2517;BOX DRAWINGS HEAVY UP AND RIGHT;So;0;ON;;;;;N;FORMS HEAVY UP AND RIGHT;;;;
+2518;BOX DRAWINGS LIGHT UP AND LEFT;So;0;ON;;;;;N;FORMS LIGHT UP AND LEFT;;;;
+2519;BOX DRAWINGS UP LIGHT AND LEFT HEAVY;So;0;ON;;;;;N;FORMS UP LIGHT AND LEFT HEAVY;;;;
+251A;BOX DRAWINGS UP HEAVY AND LEFT LIGHT;So;0;ON;;;;;N;FORMS UP HEAVY AND LEFT LIGHT;;;;
+251B;BOX DRAWINGS HEAVY UP AND LEFT;So;0;ON;;;;;N;FORMS HEAVY UP AND LEFT;;;;
+251C;BOX DRAWINGS LIGHT VERTICAL AND RIGHT;So;0;ON;;;;;N;FORMS LIGHT VERTICAL AND RIGHT;;;;
+251D;BOX DRAWINGS VERTICAL LIGHT AND RIGHT HEAVY;So;0;ON;;;;;N;FORMS VERTICAL LIGHT AND RIGHT HEAVY;;;;
+251E;BOX DRAWINGS UP HEAVY AND RIGHT DOWN LIGHT;So;0;ON;;;;;N;FORMS UP HEAVY AND RIGHT DOWN LIGHT;;;;
+251F;BOX DRAWINGS DOWN HEAVY AND RIGHT UP LIGHT;So;0;ON;;;;;N;FORMS DOWN HEAVY AND RIGHT UP LIGHT;;;;
+2520;BOX DRAWINGS VERTICAL HEAVY AND RIGHT LIGHT;So;0;ON;;;;;N;FORMS VERTICAL HEAVY AND RIGHT LIGHT;;;;
+2521;BOX DRAWINGS DOWN LIGHT AND RIGHT UP HEAVY;So;0;ON;;;;;N;FORMS DOWN LIGHT AND RIGHT UP HEAVY;;;;
+2522;BOX DRAWINGS UP LIGHT AND RIGHT DOWN HEAVY;So;0;ON;;;;;N;FORMS UP LIGHT AND RIGHT DOWN HEAVY;;;;
+2523;BOX DRAWINGS HEAVY VERTICAL AND RIGHT;So;0;ON;;;;;N;FORMS HEAVY VERTICAL AND RIGHT;;;;
+2524;BOX DRAWINGS LIGHT VERTICAL AND LEFT;So;0;ON;;;;;N;FORMS LIGHT VERTICAL AND LEFT;;;;
+2525;BOX DRAWINGS VERTICAL LIGHT AND LEFT HEAVY;So;0;ON;;;;;N;FORMS VERTICAL LIGHT AND LEFT HEAVY;;;;
+2526;BOX DRAWINGS UP HEAVY AND LEFT DOWN LIGHT;So;0;ON;;;;;N;FORMS UP HEAVY AND LEFT DOWN LIGHT;;;;
+2527;BOX DRAWINGS DOWN HEAVY AND LEFT UP LIGHT;So;0;ON;;;;;N;FORMS DOWN HEAVY AND LEFT UP LIGHT;;;;
+2528;BOX DRAWINGS VERTICAL HEAVY AND LEFT LIGHT;So;0;ON;;;;;N;FORMS VERTICAL HEAVY AND LEFT LIGHT;;;;
+2529;BOX DRAWINGS DOWN LIGHT AND LEFT UP HEAVY;So;0;ON;;;;;N;FORMS DOWN LIGHT AND LEFT UP HEAVY;;;;
+252A;BOX DRAWINGS UP LIGHT AND LEFT DOWN HEAVY;So;0;ON;;;;;N;FORMS UP LIGHT AND LEFT DOWN HEAVY;;;;
+252B;BOX DRAWINGS HEAVY VERTICAL AND LEFT;So;0;ON;;;;;N;FORMS HEAVY VERTICAL AND LEFT;;;;
+252C;BOX DRAWINGS LIGHT DOWN AND HORIZONTAL;So;0;ON;;;;;N;FORMS LIGHT DOWN AND HORIZONTAL;;;;
+252D;BOX DRAWINGS LEFT HEAVY AND RIGHT DOWN LIGHT;So;0;ON;;;;;N;FORMS LEFT HEAVY AND RIGHT DOWN LIGHT;;;;
+252E;BOX DRAWINGS RIGHT HEAVY AND LEFT DOWN LIGHT;So;0;ON;;;;;N;FORMS RIGHT HEAVY AND LEFT DOWN LIGHT;;;;
+252F;BOX DRAWINGS DOWN LIGHT AND HORIZONTAL HEAVY;So;0;ON;;;;;N;FORMS DOWN LIGHT AND HORIZONTAL HEAVY;;;;
+2530;BOX DRAWINGS DOWN HEAVY AND HORIZONTAL LIGHT;So;0;ON;;;;;N;FORMS DOWN HEAVY AND HORIZONTAL LIGHT;;;;
+2531;BOX DRAWINGS RIGHT LIGHT AND LEFT DOWN HEAVY;So;0;ON;;;;;N;FORMS RIGHT LIGHT AND LEFT DOWN HEAVY;;;;
+2532;BOX DRAWINGS LEFT LIGHT AND RIGHT DOWN HEAVY;So;0;ON;;;;;N;FORMS LEFT LIGHT AND RIGHT DOWN HEAVY;;;;
+2533;BOX DRAWINGS HEAVY DOWN AND HORIZONTAL;So;0;ON;;;;;N;FORMS HEAVY DOWN AND HORIZONTAL;;;;
+2534;BOX DRAWINGS LIGHT UP AND HORIZONTAL;So;0;ON;;;;;N;FORMS LIGHT UP AND HORIZONTAL;;;;
+2535;BOX DRAWINGS LEFT HEAVY AND RIGHT UP LIGHT;So;0;ON;;;;;N;FORMS LEFT HEAVY AND RIGHT UP LIGHT;;;;
+2536;BOX DRAWINGS RIGHT HEAVY AND LEFT UP LIGHT;So;0;ON;;;;;N;FORMS RIGHT HEAVY AND LEFT UP LIGHT;;;;
+2537;BOX DRAWINGS UP LIGHT AND HORIZONTAL HEAVY;So;0;ON;;;;;N;FORMS UP LIGHT AND HORIZONTAL HEAVY;;;;
+2538;BOX DRAWINGS UP HEAVY AND HORIZONTAL LIGHT;So;0;ON;;;;;N;FORMS UP HEAVY AND HORIZONTAL LIGHT;;;;
+2539;BOX DRAWINGS RIGHT LIGHT AND LEFT UP HEAVY;So;0;ON;;;;;N;FORMS RIGHT LIGHT AND LEFT UP HEAVY;;;;
+253A;BOX DRAWINGS LEFT LIGHT AND RIGHT UP HEAVY;So;0;ON;;;;;N;FORMS LEFT LIGHT AND RIGHT UP HEAVY;;;;
+253B;BOX DRAWINGS HEAVY UP AND HORIZONTAL;So;0;ON;;;;;N;FORMS HEAVY UP AND HORIZONTAL;;;;
+253C;BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL;So;0;ON;;;;;N;FORMS LIGHT VERTICAL AND HORIZONTAL;;;;
+253D;BOX DRAWINGS LEFT HEAVY AND RIGHT VERTICAL LIGHT;So;0;ON;;;;;N;FORMS LEFT HEAVY AND RIGHT VERTICAL LIGHT;;;;
+253E;BOX DRAWINGS RIGHT HEAVY AND LEFT VERTICAL LIGHT;So;0;ON;;;;;N;FORMS RIGHT HEAVY AND LEFT VERTICAL LIGHT;;;;
+253F;BOX DRAWINGS VERTICAL LIGHT AND HORIZONTAL HEAVY;So;0;ON;;;;;N;FORMS VERTICAL LIGHT AND HORIZONTAL HEAVY;;;;
+2540;BOX DRAWINGS UP HEAVY AND DOWN HORIZONTAL LIGHT;So;0;ON;;;;;N;FORMS UP HEAVY AND DOWN HORIZONTAL LIGHT;;;;
+2541;BOX DRAWINGS DOWN HEAVY AND UP HORIZONTAL LIGHT;So;0;ON;;;;;N;FORMS DOWN HEAVY AND UP HORIZONTAL LIGHT;;;;
+2542;BOX DRAWINGS VERTICAL HEAVY AND HORIZONTAL LIGHT;So;0;ON;;;;;N;FORMS VERTICAL HEAVY AND HORIZONTAL LIGHT;;;;
+2543;BOX DRAWINGS LEFT UP HEAVY AND RIGHT DOWN LIGHT;So;0;ON;;;;;N;FORMS LEFT UP HEAVY AND RIGHT DOWN LIGHT;;;;
+2544;BOX DRAWINGS RIGHT UP HEAVY AND LEFT DOWN LIGHT;So;0;ON;;;;;N;FORMS RIGHT UP HEAVY AND LEFT DOWN LIGHT;;;;
+2545;BOX DRAWINGS LEFT DOWN HEAVY AND RIGHT UP LIGHT;So;0;ON;;;;;N;FORMS LEFT DOWN HEAVY AND RIGHT UP LIGHT;;;;
+2546;BOX DRAWINGS RIGHT DOWN HEAVY AND LEFT UP LIGHT;So;0;ON;;;;;N;FORMS RIGHT DOWN HEAVY AND LEFT UP LIGHT;;;;
+2547;BOX DRAWINGS DOWN LIGHT AND UP HORIZONTAL HEAVY;So;0;ON;;;;;N;FORMS DOWN LIGHT AND UP HORIZONTAL HEAVY;;;;
+2548;BOX DRAWINGS UP LIGHT AND DOWN HORIZONTAL HEAVY;So;0;ON;;;;;N;FORMS UP LIGHT AND DOWN HORIZONTAL HEAVY;;;;
+2549;BOX DRAWINGS RIGHT LIGHT AND LEFT VERTICAL HEAVY;So;0;ON;;;;;N;FORMS RIGHT LIGHT AND LEFT VERTICAL HEAVY;;;;
+254A;BOX DRAWINGS LEFT LIGHT AND RIGHT VERTICAL HEAVY;So;0;ON;;;;;N;FORMS LEFT LIGHT AND RIGHT VERTICAL HEAVY;;;;
+254B;BOX DRAWINGS HEAVY VERTICAL AND HORIZONTAL;So;0;ON;;;;;N;FORMS HEAVY VERTICAL AND HORIZONTAL;;;;
+254C;BOX DRAWINGS LIGHT DOUBLE DASH HORIZONTAL;So;0;ON;;;;;N;FORMS LIGHT DOUBLE DASH HORIZONTAL;;;;
+254D;BOX DRAWINGS HEAVY DOUBLE DASH HORIZONTAL;So;0;ON;;;;;N;FORMS HEAVY DOUBLE DASH HORIZONTAL;;;;
+254E;BOX DRAWINGS LIGHT DOUBLE DASH VERTICAL;So;0;ON;;;;;N;FORMS LIGHT DOUBLE DASH VERTICAL;;;;
+254F;BOX DRAWINGS HEAVY DOUBLE DASH VERTICAL;So;0;ON;;;;;N;FORMS HEAVY DOUBLE DASH VERTICAL;;;;
+2550;BOX DRAWINGS DOUBLE HORIZONTAL;So;0;ON;;;;;N;FORMS DOUBLE HORIZONTAL;;;;
+2551;BOX DRAWINGS DOUBLE VERTICAL;So;0;ON;;;;;N;FORMS DOUBLE VERTICAL;;;;
+2552;BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE;So;0;ON;;;;;N;FORMS DOWN SINGLE AND RIGHT DOUBLE;;;;
+2553;BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE;So;0;ON;;;;;N;FORMS DOWN DOUBLE AND RIGHT SINGLE;;;;
+2554;BOX DRAWINGS DOUBLE DOWN AND RIGHT;So;0;ON;;;;;N;FORMS DOUBLE DOWN AND RIGHT;;;;
+2555;BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE;So;0;ON;;;;;N;FORMS DOWN SINGLE AND LEFT DOUBLE;;;;
+2556;BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE;So;0;ON;;;;;N;FORMS DOWN DOUBLE AND LEFT SINGLE;;;;
+2557;BOX DRAWINGS DOUBLE DOWN AND LEFT;So;0;ON;;;;;N;FORMS DOUBLE DOWN AND LEFT;;;;
+2558;BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE;So;0;ON;;;;;N;FORMS UP SINGLE AND RIGHT DOUBLE;;;;
+2559;BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE;So;0;ON;;;;;N;FORMS UP DOUBLE AND RIGHT SINGLE;;;;
+255A;BOX DRAWINGS DOUBLE UP AND RIGHT;So;0;ON;;;;;N;FORMS DOUBLE UP AND RIGHT;;;;
+255B;BOX DRAWINGS UP SINGLE AND LEFT DOUBLE;So;0;ON;;;;;N;FORMS UP SINGLE AND LEFT DOUBLE;;;;
+255C;BOX DRAWINGS UP DOUBLE AND LEFT SINGLE;So;0;ON;;;;;N;FORMS UP DOUBLE AND LEFT SINGLE;;;;
+255D;BOX DRAWINGS DOUBLE UP AND LEFT;So;0;ON;;;;;N;FORMS DOUBLE UP AND LEFT;;;;
+255E;BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE;So;0;ON;;;;;N;FORMS VERTICAL SINGLE AND RIGHT DOUBLE;;;;
+255F;BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE;So;0;ON;;;;;N;FORMS VERTICAL DOUBLE AND RIGHT SINGLE;;;;
+2560;BOX DRAWINGS DOUBLE VERTICAL AND RIGHT;So;0;ON;;;;;N;FORMS DOUBLE VERTICAL AND RIGHT;;;;
+2561;BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE;So;0;ON;;;;;N;FORMS VERTICAL SINGLE AND LEFT DOUBLE;;;;
+2562;BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE;So;0;ON;;;;;N;FORMS VERTICAL DOUBLE AND LEFT SINGLE;;;;
+2563;BOX DRAWINGS DOUBLE VERTICAL AND LEFT;So;0;ON;;;;;N;FORMS DOUBLE VERTICAL AND LEFT;;;;
+2564;BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE;So;0;ON;;;;;N;FORMS DOWN SINGLE AND HORIZONTAL DOUBLE;;;;
+2565;BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE;So;0;ON;;;;;N;FORMS DOWN DOUBLE AND HORIZONTAL SINGLE;;;;
+2566;BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL;So;0;ON;;;;;N;FORMS DOUBLE DOWN AND HORIZONTAL;;;;
+2567;BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE;So;0;ON;;;;;N;FORMS UP SINGLE AND HORIZONTAL DOUBLE;;;;
+2568;BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE;So;0;ON;;;;;N;FORMS UP DOUBLE AND HORIZONTAL SINGLE;;;;
+2569;BOX DRAWINGS DOUBLE UP AND HORIZONTAL;So;0;ON;;;;;N;FORMS DOUBLE UP AND HORIZONTAL;;;;
+256A;BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE;So;0;ON;;;;;N;FORMS VERTICAL SINGLE AND HORIZONTAL DOUBLE;;;;
+256B;BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE;So;0;ON;;;;;N;FORMS VERTICAL DOUBLE AND HORIZONTAL SINGLE;;;;
+256C;BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL;So;0;ON;;;;;N;FORMS DOUBLE VERTICAL AND HORIZONTAL;;;;
+256D;BOX DRAWINGS LIGHT ARC DOWN AND RIGHT;So;0;ON;;;;;N;FORMS LIGHT ARC DOWN AND RIGHT;;;;
+256E;BOX DRAWINGS LIGHT ARC DOWN AND LEFT;So;0;ON;;;;;N;FORMS LIGHT ARC DOWN AND LEFT;;;;
+256F;BOX DRAWINGS LIGHT ARC UP AND LEFT;So;0;ON;;;;;N;FORMS LIGHT ARC UP AND LEFT;;;;
+2570;BOX DRAWINGS LIGHT ARC UP AND RIGHT;So;0;ON;;;;;N;FORMS LIGHT ARC UP AND RIGHT;;;;
+2571;BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT;So;0;ON;;;;;N;FORMS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT;;;;
+2572;BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT;So;0;ON;;;;;N;FORMS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT;;;;
+2573;BOX DRAWINGS LIGHT DIAGONAL CROSS;So;0;ON;;;;;N;FORMS LIGHT DIAGONAL CROSS;;;;
+2574;BOX DRAWINGS LIGHT LEFT;So;0;ON;;;;;N;FORMS LIGHT LEFT;;;;
+2575;BOX DRAWINGS LIGHT UP;So;0;ON;;;;;N;FORMS LIGHT UP;;;;
+2576;BOX DRAWINGS LIGHT RIGHT;So;0;ON;;;;;N;FORMS LIGHT RIGHT;;;;
+2577;BOX DRAWINGS LIGHT DOWN;So;0;ON;;;;;N;FORMS LIGHT DOWN;;;;
+2578;BOX DRAWINGS HEAVY LEFT;So;0;ON;;;;;N;FORMS HEAVY LEFT;;;;
+2579;BOX DRAWINGS HEAVY UP;So;0;ON;;;;;N;FORMS HEAVY UP;;;;
+257A;BOX DRAWINGS HEAVY RIGHT;So;0;ON;;;;;N;FORMS HEAVY RIGHT;;;;
+257B;BOX DRAWINGS HEAVY DOWN;So;0;ON;;;;;N;FORMS HEAVY DOWN;;;;
+257C;BOX DRAWINGS LIGHT LEFT AND HEAVY RIGHT;So;0;ON;;;;;N;FORMS LIGHT LEFT AND HEAVY RIGHT;;;;
+257D;BOX DRAWINGS LIGHT UP AND HEAVY DOWN;So;0;ON;;;;;N;FORMS LIGHT UP AND HEAVY DOWN;;;;
+257E;BOX DRAWINGS HEAVY LEFT AND LIGHT RIGHT;So;0;ON;;;;;N;FORMS HEAVY LEFT AND LIGHT RIGHT;;;;
+257F;BOX DRAWINGS HEAVY UP AND LIGHT DOWN;So;0;ON;;;;;N;FORMS HEAVY UP AND LIGHT DOWN;;;;
+2580;UPPER HALF BLOCK;So;0;ON;;;;;N;;;;;
+2581;LOWER ONE EIGHTH BLOCK;So;0;ON;;;;;N;;;;;
+2582;LOWER ONE QUARTER BLOCK;So;0;ON;;;;;N;;;;;
+2583;LOWER THREE EIGHTHS BLOCK;So;0;ON;;;;;N;;;;;
+2584;LOWER HALF BLOCK;So;0;ON;;;;;N;;;;;
+2585;LOWER FIVE EIGHTHS BLOCK;So;0;ON;;;;;N;;;;;
+2586;LOWER THREE QUARTERS BLOCK;So;0;ON;;;;;N;LOWER THREE QUARTER BLOCK;;;;
+2587;LOWER SEVEN EIGHTHS BLOCK;So;0;ON;;;;;N;;;;;
+2588;FULL BLOCK;So;0;ON;;;;;N;;;;;
+2589;LEFT SEVEN EIGHTHS BLOCK;So;0;ON;;;;;N;;;;;
+258A;LEFT THREE QUARTERS BLOCK;So;0;ON;;;;;N;LEFT THREE QUARTER BLOCK;;;;
+258B;LEFT FIVE EIGHTHS BLOCK;So;0;ON;;;;;N;;;;;
+258C;LEFT HALF BLOCK;So;0;ON;;;;;N;;;;;
+258D;LEFT THREE EIGHTHS BLOCK;So;0;ON;;;;;N;;;;;
+258E;LEFT ONE QUARTER BLOCK;So;0;ON;;;;;N;;;;;
+258F;LEFT ONE EIGHTH BLOCK;So;0;ON;;;;;N;;;;;
+2590;RIGHT HALF BLOCK;So;0;ON;;;;;N;;;;;
+2591;LIGHT SHADE;So;0;ON;;;;;N;;;;;
+2592;MEDIUM SHADE;So;0;ON;;;;;N;;;;;
+2593;DARK SHADE;So;0;ON;;;;;N;;;;;
+2594;UPPER ONE EIGHTH BLOCK;So;0;ON;;;;;N;;;;;
+2595;RIGHT ONE EIGHTH BLOCK;So;0;ON;;;;;N;;;;;
+2596;QUADRANT LOWER LEFT;So;0;ON;;;;;N;;;;;
+2597;QUADRANT LOWER RIGHT;So;0;ON;;;;;N;;;;;
+2598;QUADRANT UPPER LEFT;So;0;ON;;;;;N;;;;;
+2599;QUADRANT UPPER LEFT AND LOWER LEFT AND LOWER RIGHT;So;0;ON;;;;;N;;;;;
+259A;QUADRANT UPPER LEFT AND LOWER RIGHT;So;0;ON;;;;;N;;;;;
+259B;QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER LEFT;So;0;ON;;;;;N;;;;;
+259C;QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER RIGHT;So;0;ON;;;;;N;;;;;
+259D;QUADRANT UPPER RIGHT;So;0;ON;;;;;N;;;;;
+259E;QUADRANT UPPER RIGHT AND LOWER LEFT;So;0;ON;;;;;N;;;;;
+259F;QUADRANT UPPER RIGHT AND LOWER LEFT AND LOWER RIGHT;So;0;ON;;;;;N;;;;;
+25A0;BLACK SQUARE;So;0;ON;;;;;N;;;;;
+25A1;WHITE SQUARE;So;0;ON;;;;;N;;;;;
+25A2;WHITE SQUARE WITH ROUNDED CORNERS;So;0;ON;;;;;N;;;;;
+25A3;WHITE SQUARE CONTAINING BLACK SMALL SQUARE;So;0;ON;;;;;N;;;;;
+25A4;SQUARE WITH HORIZONTAL FILL;So;0;ON;;;;;N;;;;;
+25A5;SQUARE WITH VERTICAL FILL;So;0;ON;;;;;N;;;;;
+25A6;SQUARE WITH ORTHOGONAL CROSSHATCH FILL;So;0;ON;;;;;N;;;;;
+25A7;SQUARE WITH UPPER LEFT TO LOWER RIGHT FILL;So;0;ON;;;;;N;;;;;
+25A8;SQUARE WITH UPPER RIGHT TO LOWER LEFT FILL;So;0;ON;;;;;N;;;;;
+25A9;SQUARE WITH DIAGONAL CROSSHATCH FILL;So;0;ON;;;;;N;;;;;
+25AA;BLACK SMALL SQUARE;So;0;ON;;;;;N;;;;;
+25AB;WHITE SMALL SQUARE;So;0;ON;;;;;N;;;;;
+25AC;BLACK RECTANGLE;So;0;ON;;;;;N;;;;;
+25AD;WHITE RECTANGLE;So;0;ON;;;;;N;;;;;
+25AE;BLACK VERTICAL RECTANGLE;So;0;ON;;;;;N;;;;;
+25AF;WHITE VERTICAL RECTANGLE;So;0;ON;;;;;N;;;;;
+25B0;BLACK PARALLELOGRAM;So;0;ON;;;;;N;;;;;
+25B1;WHITE PARALLELOGRAM;So;0;ON;;;;;N;;;;;
+25B2;BLACK UP-POINTING TRIANGLE;So;0;ON;;;;;N;BLACK UP POINTING TRIANGLE;;;;
+25B3;WHITE UP-POINTING TRIANGLE;So;0;ON;;;;;N;WHITE UP POINTING TRIANGLE;;;;
+25B4;BLACK UP-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;BLACK UP POINTING SMALL TRIANGLE;;;;
+25B5;WHITE UP-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;WHITE UP POINTING SMALL TRIANGLE;;;;
+25B6;BLACK RIGHT-POINTING TRIANGLE;So;0;ON;;;;;N;BLACK RIGHT POINTING TRIANGLE;;;;
+25B7;WHITE RIGHT-POINTING TRIANGLE;Sm;0;ON;;;;;N;WHITE RIGHT POINTING TRIANGLE;;;;
+25B8;BLACK RIGHT-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;BLACK RIGHT POINTING SMALL TRIANGLE;;;;
+25B9;WHITE RIGHT-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;WHITE RIGHT POINTING SMALL TRIANGLE;;;;
+25BA;BLACK RIGHT-POINTING POINTER;So;0;ON;;;;;N;BLACK RIGHT POINTING POINTER;;;;
+25BB;WHITE RIGHT-POINTING POINTER;So;0;ON;;;;;N;WHITE RIGHT POINTING POINTER;;;;
+25BC;BLACK DOWN-POINTING TRIANGLE;So;0;ON;;;;;N;BLACK DOWN POINTING TRIANGLE;;;;
+25BD;WHITE DOWN-POINTING TRIANGLE;So;0;ON;;;;;N;WHITE DOWN POINTING TRIANGLE;;;;
+25BE;BLACK DOWN-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;BLACK DOWN POINTING SMALL TRIANGLE;;;;
+25BF;WHITE DOWN-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;WHITE DOWN POINTING SMALL TRIANGLE;;;;
+25C0;BLACK LEFT-POINTING TRIANGLE;So;0;ON;;;;;N;BLACK LEFT POINTING TRIANGLE;;;;
+25C1;WHITE LEFT-POINTING TRIANGLE;Sm;0;ON;;;;;N;WHITE LEFT POINTING TRIANGLE;;;;
+25C2;BLACK LEFT-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;BLACK LEFT POINTING SMALL TRIANGLE;;;;
+25C3;WHITE LEFT-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;WHITE LEFT POINTING SMALL TRIANGLE;;;;
+25C4;BLACK LEFT-POINTING POINTER;So;0;ON;;;;;N;BLACK LEFT POINTING POINTER;;;;
+25C5;WHITE LEFT-POINTING POINTER;So;0;ON;;;;;N;WHITE LEFT POINTING POINTER;;;;
+25C6;BLACK DIAMOND;So;0;ON;;;;;N;;;;;
+25C7;WHITE DIAMOND;So;0;ON;;;;;N;;;;;
+25C8;WHITE DIAMOND CONTAINING BLACK SMALL DIAMOND;So;0;ON;;;;;N;;;;;
+25C9;FISHEYE;So;0;ON;;;;;N;;;;;
+25CA;LOZENGE;So;0;ON;;;;;N;;;;;
+25CB;WHITE CIRCLE;So;0;ON;;;;;N;;;;;
+25CC;DOTTED CIRCLE;So;0;ON;;;;;N;;;;;
+25CD;CIRCLE WITH VERTICAL FILL;So;0;ON;;;;;N;;;;;
+25CE;BULLSEYE;So;0;ON;;;;;N;;;;;
+25CF;BLACK CIRCLE;So;0;ON;;;;;N;;;;;
+25D0;CIRCLE WITH LEFT HALF BLACK;So;0;ON;;;;;N;;;;;
+25D1;CIRCLE WITH RIGHT HALF BLACK;So;0;ON;;;;;N;;;;;
+25D2;CIRCLE WITH LOWER HALF BLACK;So;0;ON;;;;;N;;;;;
+25D3;CIRCLE WITH UPPER HALF BLACK;So;0;ON;;;;;N;;;;;
+25D4;CIRCLE WITH UPPER RIGHT QUADRANT BLACK;So;0;ON;;;;;N;;;;;
+25D5;CIRCLE WITH ALL BUT UPPER LEFT QUADRANT BLACK;So;0;ON;;;;;N;;;;;
+25D6;LEFT HALF BLACK CIRCLE;So;0;ON;;;;;N;;;;;
+25D7;RIGHT HALF BLACK CIRCLE;So;0;ON;;;;;N;;;;;
+25D8;INVERSE BULLET;So;0;ON;;;;;N;;;;;
+25D9;INVERSE WHITE CIRCLE;So;0;ON;;;;;N;;;;;
+25DA;UPPER HALF INVERSE WHITE CIRCLE;So;0;ON;;;;;N;;;;;
+25DB;LOWER HALF INVERSE WHITE CIRCLE;So;0;ON;;;;;N;;;;;
+25DC;UPPER LEFT QUADRANT CIRCULAR ARC;So;0;ON;;;;;N;;;;;
+25DD;UPPER RIGHT QUADRANT CIRCULAR ARC;So;0;ON;;;;;N;;;;;
+25DE;LOWER RIGHT QUADRANT CIRCULAR ARC;So;0;ON;;;;;N;;;;;
+25DF;LOWER LEFT QUADRANT CIRCULAR ARC;So;0;ON;;;;;N;;;;;
+25E0;UPPER HALF CIRCLE;So;0;ON;;;;;N;;;;;
+25E1;LOWER HALF CIRCLE;So;0;ON;;;;;N;;;;;
+25E2;BLACK LOWER RIGHT TRIANGLE;So;0;ON;;;;;N;;;;;
+25E3;BLACK LOWER LEFT TRIANGLE;So;0;ON;;;;;N;;;;;
+25E4;BLACK UPPER LEFT TRIANGLE;So;0;ON;;;;;N;;;;;
+25E5;BLACK UPPER RIGHT TRIANGLE;So;0;ON;;;;;N;;;;;
+25E6;WHITE BULLET;So;0;ON;;;;;N;;;;;
+25E7;SQUARE WITH LEFT HALF BLACK;So;0;ON;;;;;N;;;;;
+25E8;SQUARE WITH RIGHT HALF BLACK;So;0;ON;;;;;N;;;;;
+25E9;SQUARE WITH UPPER LEFT DIAGONAL HALF BLACK;So;0;ON;;;;;N;;;;;
+25EA;SQUARE WITH LOWER RIGHT DIAGONAL HALF BLACK;So;0;ON;;;;;N;;;;;
+25EB;WHITE SQUARE WITH VERTICAL BISECTING LINE;So;0;ON;;;;;N;;;;;
+25EC;WHITE UP-POINTING TRIANGLE WITH DOT;So;0;ON;;;;;N;WHITE UP POINTING TRIANGLE WITH DOT;;;;
+25ED;UP-POINTING TRIANGLE WITH LEFT HALF BLACK;So;0;ON;;;;;N;UP POINTING TRIANGLE WITH LEFT HALF BLACK;;;;
+25EE;UP-POINTING TRIANGLE WITH RIGHT HALF BLACK;So;0;ON;;;;;N;UP POINTING TRIANGLE WITH RIGHT HALF BLACK;;;;
+25EF;LARGE CIRCLE;So;0;ON;;;;;N;;;;;
+25F0;WHITE SQUARE WITH UPPER LEFT QUADRANT;So;0;ON;;;;;N;;;;;
+25F1;WHITE SQUARE WITH LOWER LEFT QUADRANT;So;0;ON;;;;;N;;;;;
+25F2;WHITE SQUARE WITH LOWER RIGHT QUADRANT;So;0;ON;;;;;N;;;;;
+25F3;WHITE SQUARE WITH UPPER RIGHT QUADRANT;So;0;ON;;;;;N;;;;;
+25F4;WHITE CIRCLE WITH UPPER LEFT QUADRANT;So;0;ON;;;;;N;;;;;
+25F5;WHITE CIRCLE WITH LOWER LEFT QUADRANT;So;0;ON;;;;;N;;;;;
+25F6;WHITE CIRCLE WITH LOWER RIGHT QUADRANT;So;0;ON;;;;;N;;;;;
+25F7;WHITE CIRCLE WITH UPPER RIGHT QUADRANT;So;0;ON;;;;;N;;;;;
+25F8;UPPER LEFT TRIANGLE;Sm;0;ON;;;;;N;;;;;
+25F9;UPPER RIGHT TRIANGLE;Sm;0;ON;;;;;N;;;;;
+25FA;LOWER LEFT TRIANGLE;Sm;0;ON;;;;;N;;;;;
+25FB;WHITE MEDIUM SQUARE;Sm;0;ON;;;;;N;;;;;
+25FC;BLACK MEDIUM SQUARE;Sm;0;ON;;;;;N;;;;;
+25FD;WHITE MEDIUM SMALL SQUARE;Sm;0;ON;;;;;N;;;;;
+25FE;BLACK MEDIUM SMALL SQUARE;Sm;0;ON;;;;;N;;;;;
+25FF;LOWER RIGHT TRIANGLE;Sm;0;ON;;;;;N;;;;;
+2600;BLACK SUN WITH RAYS;So;0;ON;;;;;N;;;;;
+2601;CLOUD;So;0;ON;;;;;N;;;;;
+2602;UMBRELLA;So;0;ON;;;;;N;;;;;
+2603;SNOWMAN;So;0;ON;;;;;N;;;;;
+2604;COMET;So;0;ON;;;;;N;;;;;
+2605;BLACK STAR;So;0;ON;;;;;N;;;;;
+2606;WHITE STAR;So;0;ON;;;;;N;;;;;
+2607;LIGHTNING;So;0;ON;;;;;N;;;;;
+2608;THUNDERSTORM;So;0;ON;;;;;N;;;;;
+2609;SUN;So;0;ON;;;;;N;;;;;
+260A;ASCENDING NODE;So;0;ON;;;;;N;;;;;
+260B;DESCENDING NODE;So;0;ON;;;;;N;;;;;
+260C;CONJUNCTION;So;0;ON;;;;;N;;;;;
+260D;OPPOSITION;So;0;ON;;;;;N;;;;;
+260E;BLACK TELEPHONE;So;0;ON;;;;;N;;;;;
+260F;WHITE TELEPHONE;So;0;ON;;;;;N;;;;;
+2610;BALLOT BOX;So;0;ON;;;;;N;;;;;
+2611;BALLOT BOX WITH CHECK;So;0;ON;;;;;N;;;;;
+2612;BALLOT BOX WITH X;So;0;ON;;;;;N;;;;;
+2613;SALTIRE;So;0;ON;;;;;N;;;;;
+2614;UMBRELLA WITH RAIN DROPS;So;0;ON;;;;;N;;;;;
+2615;HOT BEVERAGE;So;0;ON;;;;;N;;;;;
+2616;WHITE SHOGI PIECE;So;0;ON;;;;;N;;;;;
+2617;BLACK SHOGI PIECE;So;0;ON;;;;;N;;;;;
+2618;SHAMROCK;So;0;ON;;;;;N;;;;;
+2619;REVERSED ROTATED FLORAL HEART BULLET;So;0;ON;;;;;N;;;;;
+261A;BLACK LEFT POINTING INDEX;So;0;ON;;;;;N;;;;;
+261B;BLACK RIGHT POINTING INDEX;So;0;ON;;;;;N;;;;;
+261C;WHITE LEFT POINTING INDEX;So;0;ON;;;;;N;;;;;
+261D;WHITE UP POINTING INDEX;So;0;ON;;;;;N;;;;;
+261E;WHITE RIGHT POINTING INDEX;So;0;ON;;;;;N;;;;;
+261F;WHITE DOWN POINTING INDEX;So;0;ON;;;;;N;;;;;
+2620;SKULL AND CROSSBONES;So;0;ON;;;;;N;;;;;
+2621;CAUTION SIGN;So;0;ON;;;;;N;;;;;
+2622;RADIOACTIVE SIGN;So;0;ON;;;;;N;;;;;
+2623;BIOHAZARD SIGN;So;0;ON;;;;;N;;;;;
+2624;CADUCEUS;So;0;ON;;;;;N;;;;;
+2625;ANKH;So;0;ON;;;;;N;;;;;
+2626;ORTHODOX CROSS;So;0;ON;;;;;N;;;;;
+2627;CHI RHO;So;0;ON;;;;;N;;;;;
+2628;CROSS OF LORRAINE;So;0;ON;;;;;N;;;;;
+2629;CROSS OF JERUSALEM;So;0;ON;;;;;N;;;;;
+262A;STAR AND CRESCENT;So;0;ON;;;;;N;;;;;
+262B;FARSI SYMBOL;So;0;ON;;;;;N;SYMBOL OF IRAN;;;;
+262C;ADI SHAKTI;So;0;ON;;;;;N;;;;;
+262D;HAMMER AND SICKLE;So;0;ON;;;;;N;;;;;
+262E;PEACE SYMBOL;So;0;ON;;;;;N;;;;;
+262F;YIN YANG;So;0;ON;;;;;N;;;;;
+2630;TRIGRAM FOR HEAVEN;So;0;ON;;;;;N;;;;;
+2631;TRIGRAM FOR LAKE;So;0;ON;;;;;N;;;;;
+2632;TRIGRAM FOR FIRE;So;0;ON;;;;;N;;;;;
+2633;TRIGRAM FOR THUNDER;So;0;ON;;;;;N;;;;;
+2634;TRIGRAM FOR WIND;So;0;ON;;;;;N;;;;;
+2635;TRIGRAM FOR WATER;So;0;ON;;;;;N;;;;;
+2636;TRIGRAM FOR MOUNTAIN;So;0;ON;;;;;N;;;;;
+2637;TRIGRAM FOR EARTH;So;0;ON;;;;;N;;;;;
+2638;WHEEL OF DHARMA;So;0;ON;;;;;N;;;;;
+2639;WHITE FROWNING FACE;So;0;ON;;;;;N;;;;;
+263A;WHITE SMILING FACE;So;0;ON;;;;;N;;;;;
+263B;BLACK SMILING FACE;So;0;ON;;;;;N;;;;;
+263C;WHITE SUN WITH RAYS;So;0;ON;;;;;N;;;;;
+263D;FIRST QUARTER MOON;So;0;ON;;;;;N;;;;;
+263E;LAST QUARTER MOON;So;0;ON;;;;;N;;;;;
+263F;MERCURY;So;0;ON;;;;;N;;;;;
+2640;FEMALE SIGN;So;0;ON;;;;;N;;;;;
+2641;EARTH;So;0;ON;;;;;N;;;;;
+2642;MALE SIGN;So;0;ON;;;;;N;;;;;
+2643;JUPITER;So;0;ON;;;;;N;;;;;
+2644;SATURN;So;0;ON;;;;;N;;;;;
+2645;URANUS;So;0;ON;;;;;N;;;;;
+2646;NEPTUNE;So;0;ON;;;;;N;;;;;
+2647;PLUTO;So;0;ON;;;;;N;;;;;
+2648;ARIES;So;0;ON;;;;;N;;;;;
+2649;TAURUS;So;0;ON;;;;;N;;;;;
+264A;GEMINI;So;0;ON;;;;;N;;;;;
+264B;CANCER;So;0;ON;;;;;N;;;;;
+264C;LEO;So;0;ON;;;;;N;;;;;
+264D;VIRGO;So;0;ON;;;;;N;;;;;
+264E;LIBRA;So;0;ON;;;;;N;;;;;
+264F;SCORPIUS;So;0;ON;;;;;N;;;;;
+2650;SAGITTARIUS;So;0;ON;;;;;N;;;;;
+2651;CAPRICORN;So;0;ON;;;;;N;;;;;
+2652;AQUARIUS;So;0;ON;;;;;N;;;;;
+2653;PISCES;So;0;ON;;;;;N;;;;;
+2654;WHITE CHESS KING;So;0;ON;;;;;N;;;;;
+2655;WHITE CHESS QUEEN;So;0;ON;;;;;N;;;;;
+2656;WHITE CHESS ROOK;So;0;ON;;;;;N;;;;;
+2657;WHITE CHESS BISHOP;So;0;ON;;;;;N;;;;;
+2658;WHITE CHESS KNIGHT;So;0;ON;;;;;N;;;;;
+2659;WHITE CHESS PAWN;So;0;ON;;;;;N;;;;;
+265A;BLACK CHESS KING;So;0;ON;;;;;N;;;;;
+265B;BLACK CHESS QUEEN;So;0;ON;;;;;N;;;;;
+265C;BLACK CHESS ROOK;So;0;ON;;;;;N;;;;;
+265D;BLACK CHESS BISHOP;So;0;ON;;;;;N;;;;;
+265E;BLACK CHESS KNIGHT;So;0;ON;;;;;N;;;;;
+265F;BLACK CHESS PAWN;So;0;ON;;;;;N;;;;;
+2660;BLACK SPADE SUIT;So;0;ON;;;;;N;;;;;
+2661;WHITE HEART SUIT;So;0;ON;;;;;N;;;;;
+2662;WHITE DIAMOND SUIT;So;0;ON;;;;;N;;;;;
+2663;BLACK CLUB SUIT;So;0;ON;;;;;N;;;;;
+2664;WHITE SPADE SUIT;So;0;ON;;;;;N;;;;;
+2665;BLACK HEART SUIT;So;0;ON;;;;;N;;;;;
+2666;BLACK DIAMOND SUIT;So;0;ON;;;;;N;;;;;
+2667;WHITE CLUB SUIT;So;0;ON;;;;;N;;;;;
+2668;HOT SPRINGS;So;0;ON;;;;;N;;;;;
+2669;QUARTER NOTE;So;0;ON;;;;;N;;;;;
+266A;EIGHTH NOTE;So;0;ON;;;;;N;;;;;
+266B;BEAMED EIGHTH NOTES;So;0;ON;;;;;N;BARRED EIGHTH NOTES;;;;
+266C;BEAMED SIXTEENTH NOTES;So;0;ON;;;;;N;BARRED SIXTEENTH NOTES;;;;
+266D;MUSIC FLAT SIGN;So;0;ON;;;;;N;FLAT;;;;
+266E;MUSIC NATURAL SIGN;So;0;ON;;;;;N;NATURAL;;;;
+266F;MUSIC SHARP SIGN;Sm;0;ON;;;;;N;SHARP;;;;
+2670;WEST SYRIAC CROSS;So;0;ON;;;;;N;;;;;
+2671;EAST SYRIAC CROSS;So;0;ON;;;;;N;;;;;
+2672;UNIVERSAL RECYCLING SYMBOL;So;0;ON;;;;;N;;;;;
+2673;RECYCLING SYMBOL FOR TYPE-1 PLASTICS;So;0;ON;;;;;N;;;;;
+2674;RECYCLING SYMBOL FOR TYPE-2 PLASTICS;So;0;ON;;;;;N;;;;;
+2675;RECYCLING SYMBOL FOR TYPE-3 PLASTICS;So;0;ON;;;;;N;;;;;
+2676;RECYCLING SYMBOL FOR TYPE-4 PLASTICS;So;0;ON;;;;;N;;;;;
+2677;RECYCLING SYMBOL FOR TYPE-5 PLASTICS;So;0;ON;;;;;N;;;;;
+2678;RECYCLING SYMBOL FOR TYPE-6 PLASTICS;So;0;ON;;;;;N;;;;;
+2679;RECYCLING SYMBOL FOR TYPE-7 PLASTICS;So;0;ON;;;;;N;;;;;
+267A;RECYCLING SYMBOL FOR GENERIC MATERIALS;So;0;ON;;;;;N;;;;;
+267B;BLACK UNIVERSAL RECYCLING SYMBOL;So;0;ON;;;;;N;;;;;
+267C;RECYCLED PAPER SYMBOL;So;0;ON;;;;;N;;;;;
+267D;PARTIALLY-RECYCLED PAPER SYMBOL;So;0;ON;;;;;N;;;;;
+267E;PERMANENT PAPER SIGN;So;0;ON;;;;;N;;;;;
+267F;WHEELCHAIR SYMBOL;So;0;ON;;;;;N;;;;;
+2680;DIE FACE-1;So;0;ON;;;;;N;;;;;
+2681;DIE FACE-2;So;0;ON;;;;;N;;;;;
+2682;DIE FACE-3;So;0;ON;;;;;N;;;;;
+2683;DIE FACE-4;So;0;ON;;;;;N;;;;;
+2684;DIE FACE-5;So;0;ON;;;;;N;;;;;
+2685;DIE FACE-6;So;0;ON;;;;;N;;;;;
+2686;WHITE CIRCLE WITH DOT RIGHT;So;0;ON;;;;;N;;;;;
+2687;WHITE CIRCLE WITH TWO DOTS;So;0;ON;;;;;N;;;;;
+2688;BLACK CIRCLE WITH WHITE DOT RIGHT;So;0;ON;;;;;N;;;;;
+2689;BLACK CIRCLE WITH TWO WHITE DOTS;So;0;ON;;;;;N;;;;;
+268A;MONOGRAM FOR YANG;So;0;ON;;;;;N;;;;;
+268B;MONOGRAM FOR YIN;So;0;ON;;;;;N;;;;;
+268C;DIGRAM FOR GREATER YANG;So;0;ON;;;;;N;;;;;
+268D;DIGRAM FOR LESSER YIN;So;0;ON;;;;;N;;;;;
+268E;DIGRAM FOR LESSER YANG;So;0;ON;;;;;N;;;;;
+268F;DIGRAM FOR GREATER YIN;So;0;ON;;;;;N;;;;;
+2690;WHITE FLAG;So;0;ON;;;;;N;;;;;
+2691;BLACK FLAG;So;0;ON;;;;;N;;;;;
+2692;HAMMER AND PICK;So;0;ON;;;;;N;;;;;
+2693;ANCHOR;So;0;ON;;;;;N;;;;;
+2694;CROSSED SWORDS;So;0;ON;;;;;N;;;;;
+2695;STAFF OF AESCULAPIUS;So;0;ON;;;;;N;;;;;
+2696;SCALES;So;0;ON;;;;;N;;;;;
+2697;ALEMBIC;So;0;ON;;;;;N;;;;;
+2698;FLOWER;So;0;ON;;;;;N;;;;;
+2699;GEAR;So;0;ON;;;;;N;;;;;
+269A;STAFF OF HERMES;So;0;ON;;;;;N;;;;;
+269B;ATOM SYMBOL;So;0;ON;;;;;N;;;;;
+269C;FLEUR-DE-LIS;So;0;ON;;;;;N;;;;;
+269D;OUTLINED WHITE STAR;So;0;ON;;;;;N;;;;;
+269E;THREE LINES CONVERGING RIGHT;So;0;ON;;;;;N;;;;;
+269F;THREE LINES CONVERGING LEFT;So;0;ON;;;;;N;;;;;
+26A0;WARNING SIGN;So;0;ON;;;;;N;;;;;
+26A1;HIGH VOLTAGE SIGN;So;0;ON;;;;;N;;;;;
+26A2;DOUBLED FEMALE SIGN;So;0;ON;;;;;N;;;;;
+26A3;DOUBLED MALE SIGN;So;0;ON;;;;;N;;;;;
+26A4;INTERLOCKED FEMALE AND MALE SIGN;So;0;ON;;;;;N;;;;;
+26A5;MALE AND FEMALE SIGN;So;0;ON;;;;;N;;;;;
+26A6;MALE WITH STROKE SIGN;So;0;ON;;;;;N;;;;;
+26A7;MALE WITH STROKE AND MALE AND FEMALE SIGN;So;0;ON;;;;;N;;;;;
+26A8;VERTICAL MALE WITH STROKE SIGN;So;0;ON;;;;;N;;;;;
+26A9;HORIZONTAL MALE WITH STROKE SIGN;So;0;ON;;;;;N;;;;;
+26AA;MEDIUM WHITE CIRCLE;So;0;ON;;;;;N;;;;;
+26AB;MEDIUM BLACK CIRCLE;So;0;ON;;;;;N;;;;;
+26AC;MEDIUM SMALL WHITE CIRCLE;So;0;L;;;;;N;;;;;
+26AD;MARRIAGE SYMBOL;So;0;ON;;;;;N;;;;;
+26AE;DIVORCE SYMBOL;So;0;ON;;;;;N;;;;;
+26AF;UNMARRIED PARTNERSHIP SYMBOL;So;0;ON;;;;;N;;;;;
+26B0;COFFIN;So;0;ON;;;;;N;;;;;
+26B1;FUNERAL URN;So;0;ON;;;;;N;;;;;
+26B2;NEUTER;So;0;ON;;;;;N;;;;;
+26B3;CERES;So;0;ON;;;;;N;;;;;
+26B4;PALLAS;So;0;ON;;;;;N;;;;;
+26B5;JUNO;So;0;ON;;;;;N;;;;;
+26B6;VESTA;So;0;ON;;;;;N;;;;;
+26B7;CHIRON;So;0;ON;;;;;N;;;;;
+26B8;BLACK MOON LILITH;So;0;ON;;;;;N;;;;;
+26B9;SEXTILE;So;0;ON;;;;;N;;;;;
+26BA;SEMISEXTILE;So;0;ON;;;;;N;;;;;
+26BB;QUINCUNX;So;0;ON;;;;;N;;;;;
+26BC;SESQUIQUADRATE;So;0;ON;;;;;N;;;;;
+26BD;SOCCER BALL;So;0;ON;;;;;N;;;;;
+26BE;BASEBALL;So;0;ON;;;;;N;;;;;
+26BF;SQUARED KEY;So;0;ON;;;;;N;;;;;
+26C0;WHITE DRAUGHTS MAN;So;0;ON;;;;;N;;;;;
+26C1;WHITE DRAUGHTS KING;So;0;ON;;;;;N;;;;;
+26C2;BLACK DRAUGHTS MAN;So;0;ON;;;;;N;;;;;
+26C3;BLACK DRAUGHTS KING;So;0;ON;;;;;N;;;;;
+26C4;SNOWMAN WITHOUT SNOW;So;0;ON;;;;;N;;;;;
+26C5;SUN BEHIND CLOUD;So;0;ON;;;;;N;;;;;
+26C6;RAIN;So;0;ON;;;;;N;;;;;
+26C7;BLACK SNOWMAN;So;0;ON;;;;;N;;;;;
+26C8;THUNDER CLOUD AND RAIN;So;0;ON;;;;;N;;;;;
+26C9;TURNED WHITE SHOGI PIECE;So;0;ON;;;;;N;;;;;
+26CA;TURNED BLACK SHOGI PIECE;So;0;ON;;;;;N;;;;;
+26CB;WHITE DIAMOND IN SQUARE;So;0;ON;;;;;N;;;;;
+26CC;CROSSING LANES;So;0;ON;;;;;N;;;;;
+26CD;DISABLED CAR;So;0;ON;;;;;N;;;;;
+26CE;OPHIUCHUS;So;0;ON;;;;;N;;;;;
+26CF;PICK;So;0;ON;;;;;N;;;;;
+26D0;CAR SLIDING;So;0;ON;;;;;N;;;;;
+26D1;HELMET WITH WHITE CROSS;So;0;ON;;;;;N;;;;;
+26D2;CIRCLED CROSSING LANES;So;0;ON;;;;;N;;;;;
+26D3;CHAINS;So;0;ON;;;;;N;;;;;
+26D4;NO ENTRY;So;0;ON;;;;;N;;;;;
+26D5;ALTERNATE ONE-WAY LEFT WAY TRAFFIC;So;0;ON;;;;;N;;;;;
+26D6;BLACK TWO-WAY LEFT WAY TRAFFIC;So;0;ON;;;;;N;;;;;
+26D7;WHITE TWO-WAY LEFT WAY TRAFFIC;So;0;ON;;;;;N;;;;;
+26D8;BLACK LEFT LANE MERGE;So;0;ON;;;;;N;;;;;
+26D9;WHITE LEFT LANE MERGE;So;0;ON;;;;;N;;;;;
+26DA;DRIVE SLOW SIGN;So;0;ON;;;;;N;;;;;
+26DB;HEAVY WHITE DOWN-POINTING TRIANGLE;So;0;ON;;;;;N;;;;;
+26DC;LEFT CLOSED ENTRY;So;0;ON;;;;;N;;;;;
+26DD;SQUARED SALTIRE;So;0;ON;;;;;N;;;;;
+26DE;FALLING DIAGONAL IN WHITE CIRCLE IN BLACK SQUARE;So;0;ON;;;;;N;;;;;
+26DF;BLACK TRUCK;So;0;ON;;;;;N;;;;;
+26E0;RESTRICTED LEFT ENTRY-1;So;0;ON;;;;;N;;;;;
+26E1;RESTRICTED LEFT ENTRY-2;So;0;ON;;;;;N;;;;;
+26E2;ASTRONOMICAL SYMBOL FOR URANUS;So;0;ON;;;;;N;;;;;
+26E3;HEAVY CIRCLE WITH STROKE AND TWO DOTS ABOVE;So;0;ON;;;;;N;;;;;
+26E4;PENTAGRAM;So;0;ON;;;;;N;;;;;
+26E5;RIGHT-HANDED INTERLACED PENTAGRAM;So;0;ON;;;;;N;;;;;
+26E6;LEFT-HANDED INTERLACED PENTAGRAM;So;0;ON;;;;;N;;;;;
+26E7;INVERTED PENTAGRAM;So;0;ON;;;;;N;;;;;
+26E8;BLACK CROSS ON SHIELD;So;0;ON;;;;;N;;;;;
+26E9;SHINTO SHRINE;So;0;ON;;;;;N;;;;;
+26EA;CHURCH;So;0;ON;;;;;N;;;;;
+26EB;CASTLE;So;0;ON;;;;;N;;;;;
+26EC;HISTORIC SITE;So;0;ON;;;;;N;;;;;
+26ED;GEAR WITHOUT HUB;So;0;ON;;;;;N;;;;;
+26EE;GEAR WITH HANDLES;So;0;ON;;;;;N;;;;;
+26EF;MAP SYMBOL FOR LIGHTHOUSE;So;0;ON;;;;;N;;;;;
+26F0;MOUNTAIN;So;0;ON;;;;;N;;;;;
+26F1;UMBRELLA ON GROUND;So;0;ON;;;;;N;;;;;
+26F2;FOUNTAIN;So;0;ON;;;;;N;;;;;
+26F3;FLAG IN HOLE;So;0;ON;;;;;N;;;;;
+26F4;FERRY;So;0;ON;;;;;N;;;;;
+26F5;SAILBOAT;So;0;ON;;;;;N;;;;;
+26F6;SQUARE FOUR CORNERS;So;0;ON;;;;;N;;;;;
+26F7;SKIER;So;0;ON;;;;;N;;;;;
+26F8;ICE SKATE;So;0;ON;;;;;N;;;;;
+26F9;PERSON WITH BALL;So;0;ON;;;;;N;;;;;
+26FA;TENT;So;0;ON;;;;;N;;;;;
+26FB;JAPANESE BANK SYMBOL;So;0;ON;;;;;N;;;;;
+26FC;HEADSTONE GRAVEYARD SYMBOL;So;0;ON;;;;;N;;;;;
+26FD;FUEL PUMP;So;0;ON;;;;;N;;;;;
+26FE;CUP ON BLACK SQUARE;So;0;ON;;;;;N;;;;;
+26FF;WHITE FLAG WITH HORIZONTAL MIDDLE BLACK STRIPE;So;0;ON;;;;;N;;;;;
+2701;UPPER BLADE SCISSORS;So;0;ON;;;;;N;;;;;
+2702;BLACK SCISSORS;So;0;ON;;;;;N;;;;;
+2703;LOWER BLADE SCISSORS;So;0;ON;;;;;N;;;;;
+2704;WHITE SCISSORS;So;0;ON;;;;;N;;;;;
+2705;WHITE HEAVY CHECK MARK;So;0;ON;;;;;N;;;;;
+2706;TELEPHONE LOCATION SIGN;So;0;ON;;;;;N;;;;;
+2707;TAPE DRIVE;So;0;ON;;;;;N;;;;;
+2708;AIRPLANE;So;0;ON;;;;;N;;;;;
+2709;ENVELOPE;So;0;ON;;;;;N;;;;;
+270A;RAISED FIST;So;0;ON;;;;;N;;;;;
+270B;RAISED HAND;So;0;ON;;;;;N;;;;;
+270C;VICTORY HAND;So;0;ON;;;;;N;;;;;
+270D;WRITING HAND;So;0;ON;;;;;N;;;;;
+270E;LOWER RIGHT PENCIL;So;0;ON;;;;;N;;;;;
+270F;PENCIL;So;0;ON;;;;;N;;;;;
+2710;UPPER RIGHT PENCIL;So;0;ON;;;;;N;;;;;
+2711;WHITE NIB;So;0;ON;;;;;N;;;;;
+2712;BLACK NIB;So;0;ON;;;;;N;;;;;
+2713;CHECK MARK;So;0;ON;;;;;N;;;;;
+2714;HEAVY CHECK MARK;So;0;ON;;;;;N;;;;;
+2715;MULTIPLICATION X;So;0;ON;;;;;N;;;;;
+2716;HEAVY MULTIPLICATION X;So;0;ON;;;;;N;;;;;
+2717;BALLOT X;So;0;ON;;;;;N;;;;;
+2718;HEAVY BALLOT X;So;0;ON;;;;;N;;;;;
+2719;OUTLINED GREEK CROSS;So;0;ON;;;;;N;;;;;
+271A;HEAVY GREEK CROSS;So;0;ON;;;;;N;;;;;
+271B;OPEN CENTRE CROSS;So;0;ON;;;;;N;OPEN CENTER CROSS;;;;
+271C;HEAVY OPEN CENTRE CROSS;So;0;ON;;;;;N;HEAVY OPEN CENTER CROSS;;;;
+271D;LATIN CROSS;So;0;ON;;;;;N;;;;;
+271E;SHADOWED WHITE LATIN CROSS;So;0;ON;;;;;N;;;;;
+271F;OUTLINED LATIN CROSS;So;0;ON;;;;;N;;;;;
+2720;MALTESE CROSS;So;0;ON;;;;;N;;;;;
+2721;STAR OF DAVID;So;0;ON;;;;;N;;;;;
+2722;FOUR TEARDROP-SPOKED ASTERISK;So;0;ON;;;;;N;;;;;
+2723;FOUR BALLOON-SPOKED ASTERISK;So;0;ON;;;;;N;;;;;
+2724;HEAVY FOUR BALLOON-SPOKED ASTERISK;So;0;ON;;;;;N;;;;;
+2725;FOUR CLUB-SPOKED ASTERISK;So;0;ON;;;;;N;;;;;
+2726;BLACK FOUR POINTED STAR;So;0;ON;;;;;N;;;;;
+2727;WHITE FOUR POINTED STAR;So;0;ON;;;;;N;;;;;
+2728;SPARKLES;So;0;ON;;;;;N;;;;;
+2729;STRESS OUTLINED WHITE STAR;So;0;ON;;;;;N;;;;;
+272A;CIRCLED WHITE STAR;So;0;ON;;;;;N;;;;;
+272B;OPEN CENTRE BLACK STAR;So;0;ON;;;;;N;OPEN CENTER BLACK STAR;;;;
+272C;BLACK CENTRE WHITE STAR;So;0;ON;;;;;N;BLACK CENTER WHITE STAR;;;;
+272D;OUTLINED BLACK STAR;So;0;ON;;;;;N;;;;;
+272E;HEAVY OUTLINED BLACK STAR;So;0;ON;;;;;N;;;;;
+272F;PINWHEEL STAR;So;0;ON;;;;;N;;;;;
+2730;SHADOWED WHITE STAR;So;0;ON;;;;;N;;;;;
+2731;HEAVY ASTERISK;So;0;ON;;;;;N;;;;;
+2732;OPEN CENTRE ASTERISK;So;0;ON;;;;;N;OPEN CENTER ASTERISK;;;;
+2733;EIGHT SPOKED ASTERISK;So;0;ON;;;;;N;;;;;
+2734;EIGHT POINTED BLACK STAR;So;0;ON;;;;;N;;;;;
+2735;EIGHT POINTED PINWHEEL STAR;So;0;ON;;;;;N;;;;;
+2736;SIX POINTED BLACK STAR;So;0;ON;;;;;N;;;;;
+2737;EIGHT POINTED RECTILINEAR BLACK STAR;So;0;ON;;;;;N;;;;;
+2738;HEAVY EIGHT POINTED RECTILINEAR BLACK STAR;So;0;ON;;;;;N;;;;;
+2739;TWELVE POINTED BLACK STAR;So;0;ON;;;;;N;;;;;
+273A;SIXTEEN POINTED ASTERISK;So;0;ON;;;;;N;;;;;
+273B;TEARDROP-SPOKED ASTERISK;So;0;ON;;;;;N;;;;;
+273C;OPEN CENTRE TEARDROP-SPOKED ASTERISK;So;0;ON;;;;;N;OPEN CENTER TEARDROP-SPOKED ASTERISK;;;;
+273D;HEAVY TEARDROP-SPOKED ASTERISK;So;0;ON;;;;;N;;;;;
+273E;SIX PETALLED BLACK AND WHITE FLORETTE;So;0;ON;;;;;N;;;;;
+273F;BLACK FLORETTE;So;0;ON;;;;;N;;;;;
+2740;WHITE FLORETTE;So;0;ON;;;;;N;;;;;
+2741;EIGHT PETALLED OUTLINED BLACK FLORETTE;So;0;ON;;;;;N;;;;;
+2742;CIRCLED OPEN CENTRE EIGHT POINTED STAR;So;0;ON;;;;;N;CIRCLED OPEN CENTER EIGHT POINTED STAR;;;;
+2743;HEAVY TEARDROP-SPOKED PINWHEEL ASTERISK;So;0;ON;;;;;N;;;;;
+2744;SNOWFLAKE;So;0;ON;;;;;N;;;;;
+2745;TIGHT TRIFOLIATE SNOWFLAKE;So;0;ON;;;;;N;;;;;
+2746;HEAVY CHEVRON SNOWFLAKE;So;0;ON;;;;;N;;;;;
+2747;SPARKLE;So;0;ON;;;;;N;;;;;
+2748;HEAVY SPARKLE;So;0;ON;;;;;N;;;;;
+2749;BALLOON-SPOKED ASTERISK;So;0;ON;;;;;N;;;;;
+274A;EIGHT TEARDROP-SPOKED PROPELLER ASTERISK;So;0;ON;;;;;N;;;;;
+274B;HEAVY EIGHT TEARDROP-SPOKED PROPELLER ASTERISK;So;0;ON;;;;;N;;;;;
+274C;CROSS MARK;So;0;ON;;;;;N;;;;;
+274D;SHADOWED WHITE CIRCLE;So;0;ON;;;;;N;;;;;
+274E;NEGATIVE SQUARED CROSS MARK;So;0;ON;;;;;N;;;;;
+274F;LOWER RIGHT DROP-SHADOWED WHITE SQUARE;So;0;ON;;;;;N;;;;;
+2750;UPPER RIGHT DROP-SHADOWED WHITE SQUARE;So;0;ON;;;;;N;;;;;
+2751;LOWER RIGHT SHADOWED WHITE SQUARE;So;0;ON;;;;;N;;;;;
+2752;UPPER RIGHT SHADOWED WHITE SQUARE;So;0;ON;;;;;N;;;;;
+2753;BLACK QUESTION MARK ORNAMENT;So;0;ON;;;;;N;;;;;
+2754;WHITE QUESTION MARK ORNAMENT;So;0;ON;;;;;N;;;;;
+2755;WHITE EXCLAMATION MARK ORNAMENT;So;0;ON;;;;;N;;;;;
+2756;BLACK DIAMOND MINUS WHITE X;So;0;ON;;;;;N;;;;;
+2757;HEAVY EXCLAMATION MARK SYMBOL;So;0;ON;;;;;N;;;;;
+2758;LIGHT VERTICAL BAR;So;0;ON;;;;;N;;;;;
+2759;MEDIUM VERTICAL BAR;So;0;ON;;;;;N;;;;;
+275A;HEAVY VERTICAL BAR;So;0;ON;;;;;N;;;;;
+275B;HEAVY SINGLE TURNED COMMA QUOTATION MARK ORNAMENT;So;0;ON;;;;;N;;;;;
+275C;HEAVY SINGLE COMMA QUOTATION MARK ORNAMENT;So;0;ON;;;;;N;;;;;
+275D;HEAVY DOUBLE TURNED COMMA QUOTATION MARK ORNAMENT;So;0;ON;;;;;N;;;;;
+275E;HEAVY DOUBLE COMMA QUOTATION MARK ORNAMENT;So;0;ON;;;;;N;;;;;
+275F;HEAVY LOW SINGLE COMMA QUOTATION MARK ORNAMENT;So;0;ON;;;;;N;;;;;
+2760;HEAVY LOW DOUBLE COMMA QUOTATION MARK ORNAMENT;So;0;ON;;;;;N;;;;;
+2761;CURVED STEM PARAGRAPH SIGN ORNAMENT;So;0;ON;;;;;N;;;;;
+2762;HEAVY EXCLAMATION MARK ORNAMENT;So;0;ON;;;;;N;;;;;
+2763;HEAVY HEART EXCLAMATION MARK ORNAMENT;So;0;ON;;;;;N;;;;;
+2764;HEAVY BLACK HEART;So;0;ON;;;;;N;;;;;
+2765;ROTATED HEAVY BLACK HEART BULLET;So;0;ON;;;;;N;;;;;
+2766;FLORAL HEART;So;0;ON;;;;;N;;;;;
+2767;ROTATED FLORAL HEART BULLET;So;0;ON;;;;;N;;;;;
+2768;MEDIUM LEFT PARENTHESIS ORNAMENT;Ps;0;ON;;;;;Y;;;;;
+2769;MEDIUM RIGHT PARENTHESIS ORNAMENT;Pe;0;ON;;;;;Y;;;;;
+276A;MEDIUM FLATTENED LEFT PARENTHESIS ORNAMENT;Ps;0;ON;;;;;Y;;;;;
+276B;MEDIUM FLATTENED RIGHT PARENTHESIS ORNAMENT;Pe;0;ON;;;;;Y;;;;;
+276C;MEDIUM LEFT-POINTING ANGLE BRACKET ORNAMENT;Ps;0;ON;;;;;Y;;;;;
+276D;MEDIUM RIGHT-POINTING ANGLE BRACKET ORNAMENT;Pe;0;ON;;;;;Y;;;;;
+276E;HEAVY LEFT-POINTING ANGLE QUOTATION MARK ORNAMENT;Ps;0;ON;;;;;Y;;;;;
+276F;HEAVY RIGHT-POINTING ANGLE QUOTATION MARK ORNAMENT;Pe;0;ON;;;;;Y;;;;;
+2770;HEAVY LEFT-POINTING ANGLE BRACKET ORNAMENT;Ps;0;ON;;;;;Y;;;;;
+2771;HEAVY RIGHT-POINTING ANGLE BRACKET ORNAMENT;Pe;0;ON;;;;;Y;;;;;
+2772;LIGHT LEFT TORTOISE SHELL BRACKET ORNAMENT;Ps;0;ON;;;;;Y;;;;;
+2773;LIGHT RIGHT TORTOISE SHELL BRACKET ORNAMENT;Pe;0;ON;;;;;Y;;;;;
+2774;MEDIUM LEFT CURLY BRACKET ORNAMENT;Ps;0;ON;;;;;Y;;;;;
+2775;MEDIUM RIGHT CURLY BRACKET ORNAMENT;Pe;0;ON;;;;;Y;;;;;
+2776;DINGBAT NEGATIVE CIRCLED DIGIT ONE;No;0;ON;;;1;1;N;INVERSE CIRCLED DIGIT ONE;;;;
+2777;DINGBAT NEGATIVE CIRCLED DIGIT TWO;No;0;ON;;;2;2;N;INVERSE CIRCLED DIGIT TWO;;;;
+2778;DINGBAT NEGATIVE CIRCLED DIGIT THREE;No;0;ON;;;3;3;N;INVERSE CIRCLED DIGIT THREE;;;;
+2779;DINGBAT NEGATIVE CIRCLED DIGIT FOUR;No;0;ON;;;4;4;N;INVERSE CIRCLED DIGIT FOUR;;;;
+277A;DINGBAT NEGATIVE CIRCLED DIGIT FIVE;No;0;ON;;;5;5;N;INVERSE CIRCLED DIGIT FIVE;;;;
+277B;DINGBAT NEGATIVE CIRCLED DIGIT SIX;No;0;ON;;;6;6;N;INVERSE CIRCLED DIGIT SIX;;;;
+277C;DINGBAT NEGATIVE CIRCLED DIGIT SEVEN;No;0;ON;;;7;7;N;INVERSE CIRCLED DIGIT SEVEN;;;;
+277D;DINGBAT NEGATIVE CIRCLED DIGIT EIGHT;No;0;ON;;;8;8;N;INVERSE CIRCLED DIGIT EIGHT;;;;
+277E;DINGBAT NEGATIVE CIRCLED DIGIT NINE;No;0;ON;;;9;9;N;INVERSE CIRCLED DIGIT NINE;;;;
+277F;DINGBAT NEGATIVE CIRCLED NUMBER TEN;No;0;ON;;;;10;N;INVERSE CIRCLED NUMBER TEN;;;;
+2780;DINGBAT CIRCLED SANS-SERIF DIGIT ONE;No;0;ON;;;1;1;N;CIRCLED SANS-SERIF DIGIT ONE;;;;
+2781;DINGBAT CIRCLED SANS-SERIF DIGIT TWO;No;0;ON;;;2;2;N;CIRCLED SANS-SERIF DIGIT TWO;;;;
+2782;DINGBAT CIRCLED SANS-SERIF DIGIT THREE;No;0;ON;;;3;3;N;CIRCLED SANS-SERIF DIGIT THREE;;;;
+2783;DINGBAT CIRCLED SANS-SERIF DIGIT FOUR;No;0;ON;;;4;4;N;CIRCLED SANS-SERIF DIGIT FOUR;;;;
+2784;DINGBAT CIRCLED SANS-SERIF DIGIT FIVE;No;0;ON;;;5;5;N;CIRCLED SANS-SERIF DIGIT FIVE;;;;
+2785;DINGBAT CIRCLED SANS-SERIF DIGIT SIX;No;0;ON;;;6;6;N;CIRCLED SANS-SERIF DIGIT SIX;;;;
+2786;DINGBAT CIRCLED SANS-SERIF DIGIT SEVEN;No;0;ON;;;7;7;N;CIRCLED SANS-SERIF DIGIT SEVEN;;;;
+2787;DINGBAT CIRCLED SANS-SERIF DIGIT EIGHT;No;0;ON;;;8;8;N;CIRCLED SANS-SERIF DIGIT EIGHT;;;;
+2788;DINGBAT CIRCLED SANS-SERIF DIGIT NINE;No;0;ON;;;9;9;N;CIRCLED SANS-SERIF DIGIT NINE;;;;
+2789;DINGBAT CIRCLED SANS-SERIF NUMBER TEN;No;0;ON;;;;10;N;CIRCLED SANS-SERIF NUMBER TEN;;;;
+278A;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT ONE;No;0;ON;;;1;1;N;INVERSE CIRCLED SANS-SERIF DIGIT ONE;;;;
+278B;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT TWO;No;0;ON;;;2;2;N;INVERSE CIRCLED SANS-SERIF DIGIT TWO;;;;
+278C;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT THREE;No;0;ON;;;3;3;N;INVERSE CIRCLED SANS-SERIF DIGIT THREE;;;;
+278D;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT FOUR;No;0;ON;;;4;4;N;INVERSE CIRCLED SANS-SERIF DIGIT FOUR;;;;
+278E;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT FIVE;No;0;ON;;;5;5;N;INVERSE CIRCLED SANS-SERIF DIGIT FIVE;;;;
+278F;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT SIX;No;0;ON;;;6;6;N;INVERSE CIRCLED SANS-SERIF DIGIT SIX;;;;
+2790;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT SEVEN;No;0;ON;;;7;7;N;INVERSE CIRCLED SANS-SERIF DIGIT SEVEN;;;;
+2791;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT EIGHT;No;0;ON;;;8;8;N;INVERSE CIRCLED SANS-SERIF DIGIT EIGHT;;;;
+2792;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT NINE;No;0;ON;;;9;9;N;INVERSE CIRCLED SANS-SERIF DIGIT NINE;;;;
+2793;DINGBAT NEGATIVE CIRCLED SANS-SERIF NUMBER TEN;No;0;ON;;;;10;N;INVERSE CIRCLED SANS-SERIF NUMBER TEN;;;;
+2794;HEAVY WIDE-HEADED RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY WIDE-HEADED RIGHT ARROW;;;;
+2795;HEAVY PLUS SIGN;So;0;ON;;;;;N;;;;;
+2796;HEAVY MINUS SIGN;So;0;ON;;;;;N;;;;;
+2797;HEAVY DIVISION SIGN;So;0;ON;;;;;N;;;;;
+2798;HEAVY SOUTH EAST ARROW;So;0;ON;;;;;N;HEAVY LOWER RIGHT ARROW;;;;
+2799;HEAVY RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY RIGHT ARROW;;;;
+279A;HEAVY NORTH EAST ARROW;So;0;ON;;;;;N;HEAVY UPPER RIGHT ARROW;;;;
+279B;DRAFTING POINT RIGHTWARDS ARROW;So;0;ON;;;;;N;DRAFTING POINT RIGHT ARROW;;;;
+279C;HEAVY ROUND-TIPPED RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY ROUND-TIPPED RIGHT ARROW;;;;
+279D;TRIANGLE-HEADED RIGHTWARDS ARROW;So;0;ON;;;;;N;TRIANGLE-HEADED RIGHT ARROW;;;;
+279E;HEAVY TRIANGLE-HEADED RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY TRIANGLE-HEADED RIGHT ARROW;;;;
+279F;DASHED TRIANGLE-HEADED RIGHTWARDS ARROW;So;0;ON;;;;;N;DASHED TRIANGLE-HEADED RIGHT ARROW;;;;
+27A0;HEAVY DASHED TRIANGLE-HEADED RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY DASHED TRIANGLE-HEADED RIGHT ARROW;;;;
+27A1;BLACK RIGHTWARDS ARROW;So;0;ON;;;;;N;BLACK RIGHT ARROW;;;;
+27A2;THREE-D TOP-LIGHTED RIGHTWARDS ARROWHEAD;So;0;ON;;;;;N;THREE-D TOP-LIGHTED RIGHT ARROWHEAD;;;;
+27A3;THREE-D BOTTOM-LIGHTED RIGHTWARDS ARROWHEAD;So;0;ON;;;;;N;THREE-D BOTTOM-LIGHTED RIGHT ARROWHEAD;;;;
+27A4;BLACK RIGHTWARDS ARROWHEAD;So;0;ON;;;;;N;BLACK RIGHT ARROWHEAD;;;;
+27A5;HEAVY BLACK CURVED DOWNWARDS AND RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY BLACK CURVED DOWN AND RIGHT ARROW;;;;
+27A6;HEAVY BLACK CURVED UPWARDS AND RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY BLACK CURVED UP AND RIGHT ARROW;;;;
+27A7;SQUAT BLACK RIGHTWARDS ARROW;So;0;ON;;;;;N;SQUAT BLACK RIGHT ARROW;;;;
+27A8;HEAVY CONCAVE-POINTED BLACK RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY CONCAVE-POINTED BLACK RIGHT ARROW;;;;
+27A9;RIGHT-SHADED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;RIGHT-SHADED WHITE RIGHT ARROW;;;;
+27AA;LEFT-SHADED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;LEFT-SHADED WHITE RIGHT ARROW;;;;
+27AB;BACK-TILTED SHADOWED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;BACK-TILTED SHADOWED WHITE RIGHT ARROW;;;;
+27AC;FRONT-TILTED SHADOWED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;FRONT-TILTED SHADOWED WHITE RIGHT ARROW;;;;
+27AD;HEAVY LOWER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY LOWER RIGHT-SHADOWED WHITE RIGHT ARROW;;;;
+27AE;HEAVY UPPER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY UPPER RIGHT-SHADOWED WHITE RIGHT ARROW;;;;
+27AF;NOTCHED LOWER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;NOTCHED LOWER RIGHT-SHADOWED WHITE RIGHT ARROW;;;;
+27B0;CURLY LOOP;So;0;ON;;;;;N;;;;;
+27B1;NOTCHED UPPER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;NOTCHED UPPER RIGHT-SHADOWED WHITE RIGHT ARROW;;;;
+27B2;CIRCLED HEAVY WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;CIRCLED HEAVY WHITE RIGHT ARROW;;;;
+27B3;WHITE-FEATHERED RIGHTWARDS ARROW;So;0;ON;;;;;N;WHITE-FEATHERED RIGHT ARROW;;;;
+27B4;BLACK-FEATHERED SOUTH EAST ARROW;So;0;ON;;;;;N;BLACK-FEATHERED LOWER RIGHT ARROW;;;;
+27B5;BLACK-FEATHERED RIGHTWARDS ARROW;So;0;ON;;;;;N;BLACK-FEATHERED RIGHT ARROW;;;;
+27B6;BLACK-FEATHERED NORTH EAST ARROW;So;0;ON;;;;;N;BLACK-FEATHERED UPPER RIGHT ARROW;;;;
+27B7;HEAVY BLACK-FEATHERED SOUTH EAST ARROW;So;0;ON;;;;;N;HEAVY BLACK-FEATHERED LOWER RIGHT ARROW;;;;
+27B8;HEAVY BLACK-FEATHERED RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY BLACK-FEATHERED RIGHT ARROW;;;;
+27B9;HEAVY BLACK-FEATHERED NORTH EAST ARROW;So;0;ON;;;;;N;HEAVY BLACK-FEATHERED UPPER RIGHT ARROW;;;;
+27BA;TEARDROP-BARBED RIGHTWARDS ARROW;So;0;ON;;;;;N;TEARDROP-BARBED RIGHT ARROW;;;;
+27BB;HEAVY TEARDROP-SHANKED RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY TEARDROP-SHANKED RIGHT ARROW;;;;
+27BC;WEDGE-TAILED RIGHTWARDS ARROW;So;0;ON;;;;;N;WEDGE-TAILED RIGHT ARROW;;;;
+27BD;HEAVY WEDGE-TAILED RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY WEDGE-TAILED RIGHT ARROW;;;;
+27BE;OPEN-OUTLINED RIGHTWARDS ARROW;So;0;ON;;;;;N;OPEN-OUTLINED RIGHT ARROW;;;;
+27BF;DOUBLE CURLY LOOP;So;0;ON;;;;;N;;;;;
+27C0;THREE DIMENSIONAL ANGLE;Sm;0;ON;;;;;Y;;;;;
+27C1;WHITE TRIANGLE CONTAINING SMALL WHITE TRIANGLE;Sm;0;ON;;;;;N;;;;;
+27C2;PERPENDICULAR;Sm;0;ON;;;;;N;;;;;
+27C3;OPEN SUBSET;Sm;0;ON;;;;;Y;;;;;
+27C4;OPEN SUPERSET;Sm;0;ON;;;;;Y;;;;;
+27C5;LEFT S-SHAPED BAG DELIMITER;Ps;0;ON;;;;;Y;;;;;
+27C6;RIGHT S-SHAPED BAG DELIMITER;Pe;0;ON;;;;;Y;;;;;
+27C7;OR WITH DOT INSIDE;Sm;0;ON;;;;;N;;;;;
+27C8;REVERSE SOLIDUS PRECEDING SUBSET;Sm;0;ON;;;;;Y;;;;;
+27C9;SUPERSET PRECEDING SOLIDUS;Sm;0;ON;;;;;Y;;;;;
+27CA;VERTICAL BAR WITH HORIZONTAL STROKE;Sm;0;ON;;;;;N;;;;;
+27CC;LONG DIVISION;Sm;0;ON;;;;;Y;;;;;
+27CE;SQUARED LOGICAL AND;Sm;0;ON;;;;;N;;;;;
+27CF;SQUARED LOGICAL OR;Sm;0;ON;;;;;N;;;;;
+27D0;WHITE DIAMOND WITH CENTRED DOT;Sm;0;ON;;;;;N;;;;;
+27D1;AND WITH DOT;Sm;0;ON;;;;;N;;;;;
+27D2;ELEMENT OF OPENING UPWARDS;Sm;0;ON;;;;;N;;;;;
+27D3;LOWER RIGHT CORNER WITH DOT;Sm;0;ON;;;;;Y;;;;;
+27D4;UPPER LEFT CORNER WITH DOT;Sm;0;ON;;;;;Y;;;;;
+27D5;LEFT OUTER JOIN;Sm;0;ON;;;;;Y;;;;;
+27D6;RIGHT OUTER JOIN;Sm;0;ON;;;;;Y;;;;;
+27D7;FULL OUTER JOIN;Sm;0;ON;;;;;N;;;;;
+27D8;LARGE UP TACK;Sm;0;ON;;;;;N;;;;;
+27D9;LARGE DOWN TACK;Sm;0;ON;;;;;N;;;;;
+27DA;LEFT AND RIGHT DOUBLE TURNSTILE;Sm;0;ON;;;;;N;;;;;
+27DB;LEFT AND RIGHT TACK;Sm;0;ON;;;;;N;;;;;
+27DC;LEFT MULTIMAP;Sm;0;ON;;;;;Y;;;;;
+27DD;LONG RIGHT TACK;Sm;0;ON;;;;;Y;;;;;
+27DE;LONG LEFT TACK;Sm;0;ON;;;;;Y;;;;;
+27DF;UP TACK WITH CIRCLE ABOVE;Sm;0;ON;;;;;N;;;;;
+27E0;LOZENGE DIVIDED BY HORIZONTAL RULE;Sm;0;ON;;;;;N;;;;;
+27E1;WHITE CONCAVE-SIDED DIAMOND;Sm;0;ON;;;;;N;;;;;
+27E2;WHITE CONCAVE-SIDED DIAMOND WITH LEFTWARDS TICK;Sm;0;ON;;;;;Y;;;;;
+27E3;WHITE CONCAVE-SIDED DIAMOND WITH RIGHTWARDS TICK;Sm;0;ON;;;;;Y;;;;;
+27E4;WHITE SQUARE WITH LEFTWARDS TICK;Sm;0;ON;;;;;Y;;;;;
+27E5;WHITE SQUARE WITH RIGHTWARDS TICK;Sm;0;ON;;;;;Y;;;;;
+27E6;MATHEMATICAL LEFT WHITE SQUARE BRACKET;Ps;0;ON;;;;;Y;;;;;
+27E7;MATHEMATICAL RIGHT WHITE SQUARE BRACKET;Pe;0;ON;;;;;Y;;;;;
+27E8;MATHEMATICAL LEFT ANGLE BRACKET;Ps;0;ON;;;;;Y;;;;;
+27E9;MATHEMATICAL RIGHT ANGLE BRACKET;Pe;0;ON;;;;;Y;;;;;
+27EA;MATHEMATICAL LEFT DOUBLE ANGLE BRACKET;Ps;0;ON;;;;;Y;;;;;
+27EB;MATHEMATICAL RIGHT DOUBLE ANGLE BRACKET;Pe;0;ON;;;;;Y;;;;;
+27EC;MATHEMATICAL LEFT WHITE TORTOISE SHELL BRACKET;Ps;0;ON;;;;;Y;;;;;
+27ED;MATHEMATICAL RIGHT WHITE TORTOISE SHELL BRACKET;Pe;0;ON;;;;;Y;;;;;
+27EE;MATHEMATICAL LEFT FLATTENED PARENTHESIS;Ps;0;ON;;;;;Y;;;;;
+27EF;MATHEMATICAL RIGHT FLATTENED PARENTHESIS;Pe;0;ON;;;;;Y;;;;;
+27F0;UPWARDS QUADRUPLE ARROW;Sm;0;ON;;;;;N;;;;;
+27F1;DOWNWARDS QUADRUPLE ARROW;Sm;0;ON;;;;;N;;;;;
+27F2;ANTICLOCKWISE GAPPED CIRCLE ARROW;Sm;0;ON;;;;;N;;;;;
+27F3;CLOCKWISE GAPPED CIRCLE ARROW;Sm;0;ON;;;;;N;;;;;
+27F4;RIGHT ARROW WITH CIRCLED PLUS;Sm;0;ON;;;;;N;;;;;
+27F5;LONG LEFTWARDS ARROW;Sm;0;ON;;;;;N;;;;;
+27F6;LONG RIGHTWARDS ARROW;Sm;0;ON;;;;;N;;;;;
+27F7;LONG LEFT RIGHT ARROW;Sm;0;ON;;;;;N;;;;;
+27F8;LONG LEFTWARDS DOUBLE ARROW;Sm;0;ON;;;;;N;;;;;
+27F9;LONG RIGHTWARDS DOUBLE ARROW;Sm;0;ON;;;;;N;;;;;
+27FA;LONG LEFT RIGHT DOUBLE ARROW;Sm;0;ON;;;;;N;;;;;
+27FB;LONG LEFTWARDS ARROW FROM BAR;Sm;0;ON;;;;;N;;;;;
+27FC;LONG RIGHTWARDS ARROW FROM BAR;Sm;0;ON;;;;;N;;;;;
+27FD;LONG LEFTWARDS DOUBLE ARROW FROM BAR;Sm;0;ON;;;;;N;;;;;
+27FE;LONG RIGHTWARDS DOUBLE ARROW FROM BAR;Sm;0;ON;;;;;N;;;;;
+27FF;LONG RIGHTWARDS SQUIGGLE ARROW;Sm;0;ON;;;;;N;;;;;
+2800;BRAILLE PATTERN BLANK;So;0;L;;;;;N;;;;;
+2801;BRAILLE PATTERN DOTS-1;So;0;L;;;;;N;;;;;
+2802;BRAILLE PATTERN DOTS-2;So;0;L;;;;;N;;;;;
+2803;BRAILLE PATTERN DOTS-12;So;0;L;;;;;N;;;;;
+2804;BRAILLE PATTERN DOTS-3;So;0;L;;;;;N;;;;;
+2805;BRAILLE PATTERN DOTS-13;So;0;L;;;;;N;;;;;
+2806;BRAILLE PATTERN DOTS-23;So;0;L;;;;;N;;;;;
+2807;BRAILLE PATTERN DOTS-123;So;0;L;;;;;N;;;;;
+2808;BRAILLE PATTERN DOTS-4;So;0;L;;;;;N;;;;;
+2809;BRAILLE PATTERN DOTS-14;So;0;L;;;;;N;;;;;
+280A;BRAILLE PATTERN DOTS-24;So;0;L;;;;;N;;;;;
+280B;BRAILLE PATTERN DOTS-124;So;0;L;;;;;N;;;;;
+280C;BRAILLE PATTERN DOTS-34;So;0;L;;;;;N;;;;;
+280D;BRAILLE PATTERN DOTS-134;So;0;L;;;;;N;;;;;
+280E;BRAILLE PATTERN DOTS-234;So;0;L;;;;;N;;;;;
+280F;BRAILLE PATTERN DOTS-1234;So;0;L;;;;;N;;;;;
+2810;BRAILLE PATTERN DOTS-5;So;0;L;;;;;N;;;;;
+2811;BRAILLE PATTERN DOTS-15;So;0;L;;;;;N;;;;;
+2812;BRAILLE PATTERN DOTS-25;So;0;L;;;;;N;;;;;
+2813;BRAILLE PATTERN DOTS-125;So;0;L;;;;;N;;;;;
+2814;BRAILLE PATTERN DOTS-35;So;0;L;;;;;N;;;;;
+2815;BRAILLE PATTERN DOTS-135;So;0;L;;;;;N;;;;;
+2816;BRAILLE PATTERN DOTS-235;So;0;L;;;;;N;;;;;
+2817;BRAILLE PATTERN DOTS-1235;So;0;L;;;;;N;;;;;
+2818;BRAILLE PATTERN DOTS-45;So;0;L;;;;;N;;;;;
+2819;BRAILLE PATTERN DOTS-145;So;0;L;;;;;N;;;;;
+281A;BRAILLE PATTERN DOTS-245;So;0;L;;;;;N;;;;;
+281B;BRAILLE PATTERN DOTS-1245;So;0;L;;;;;N;;;;;
+281C;BRAILLE PATTERN DOTS-345;So;0;L;;;;;N;;;;;
+281D;BRAILLE PATTERN DOTS-1345;So;0;L;;;;;N;;;;;
+281E;BRAILLE PATTERN DOTS-2345;So;0;L;;;;;N;;;;;
+281F;BRAILLE PATTERN DOTS-12345;So;0;L;;;;;N;;;;;
+2820;BRAILLE PATTERN DOTS-6;So;0;L;;;;;N;;;;;
+2821;BRAILLE PATTERN DOTS-16;So;0;L;;;;;N;;;;;
+2822;BRAILLE PATTERN DOTS-26;So;0;L;;;;;N;;;;;
+2823;BRAILLE PATTERN DOTS-126;So;0;L;;;;;N;;;;;
+2824;BRAILLE PATTERN DOTS-36;So;0;L;;;;;N;;;;;
+2825;BRAILLE PATTERN DOTS-136;So;0;L;;;;;N;;;;;
+2826;BRAILLE PATTERN DOTS-236;So;0;L;;;;;N;;;;;
+2827;BRAILLE PATTERN DOTS-1236;So;0;L;;;;;N;;;;;
+2828;BRAILLE PATTERN DOTS-46;So;0;L;;;;;N;;;;;
+2829;BRAILLE PATTERN DOTS-146;So;0;L;;;;;N;;;;;
+282A;BRAILLE PATTERN DOTS-246;So;0;L;;;;;N;;;;;
+282B;BRAILLE PATTERN DOTS-1246;So;0;L;;;;;N;;;;;
+282C;BRAILLE PATTERN DOTS-346;So;0;L;;;;;N;;;;;
+282D;BRAILLE PATTERN DOTS-1346;So;0;L;;;;;N;;;;;
+282E;BRAILLE PATTERN DOTS-2346;So;0;L;;;;;N;;;;;
+282F;BRAILLE PATTERN DOTS-12346;So;0;L;;;;;N;;;;;
+2830;BRAILLE PATTERN DOTS-56;So;0;L;;;;;N;;;;;
+2831;BRAILLE PATTERN DOTS-156;So;0;L;;;;;N;;;;;
+2832;BRAILLE PATTERN DOTS-256;So;0;L;;;;;N;;;;;
+2833;BRAILLE PATTERN DOTS-1256;So;0;L;;;;;N;;;;;
+2834;BRAILLE PATTERN DOTS-356;So;0;L;;;;;N;;;;;
+2835;BRAILLE PATTERN DOTS-1356;So;0;L;;;;;N;;;;;
+2836;BRAILLE PATTERN DOTS-2356;So;0;L;;;;;N;;;;;
+2837;BRAILLE PATTERN DOTS-12356;So;0;L;;;;;N;;;;;
+2838;BRAILLE PATTERN DOTS-456;So;0;L;;;;;N;;;;;
+2839;BRAILLE PATTERN DOTS-1456;So;0;L;;;;;N;;;;;
+283A;BRAILLE PATTERN DOTS-2456;So;0;L;;;;;N;;;;;
+283B;BRAILLE PATTERN DOTS-12456;So;0;L;;;;;N;;;;;
+283C;BRAILLE PATTERN DOTS-3456;So;0;L;;;;;N;;;;;
+283D;BRAILLE PATTERN DOTS-13456;So;0;L;;;;;N;;;;;
+283E;BRAILLE PATTERN DOTS-23456;So;0;L;;;;;N;;;;;
+283F;BRAILLE PATTERN DOTS-123456;So;0;L;;;;;N;;;;;
+2840;BRAILLE PATTERN DOTS-7;So;0;L;;;;;N;;;;;
+2841;BRAILLE PATTERN DOTS-17;So;0;L;;;;;N;;;;;
+2842;BRAILLE PATTERN DOTS-27;So;0;L;;;;;N;;;;;
+2843;BRAILLE PATTERN DOTS-127;So;0;L;;;;;N;;;;;
+2844;BRAILLE PATTERN DOTS-37;So;0;L;;;;;N;;;;;
+2845;BRAILLE PATTERN DOTS-137;So;0;L;;;;;N;;;;;
+2846;BRAILLE PATTERN DOTS-237;So;0;L;;;;;N;;;;;
+2847;BRAILLE PATTERN DOTS-1237;So;0;L;;;;;N;;;;;
+2848;BRAILLE PATTERN DOTS-47;So;0;L;;;;;N;;;;;
+2849;BRAILLE PATTERN DOTS-147;So;0;L;;;;;N;;;;;
+284A;BRAILLE PATTERN DOTS-247;So;0;L;;;;;N;;;;;
+284B;BRAILLE PATTERN DOTS-1247;So;0;L;;;;;N;;;;;
+284C;BRAILLE PATTERN DOTS-347;So;0;L;;;;;N;;;;;
+284D;BRAILLE PATTERN DOTS-1347;So;0;L;;;;;N;;;;;
+284E;BRAILLE PATTERN DOTS-2347;So;0;L;;;;;N;;;;;
+284F;BRAILLE PATTERN DOTS-12347;So;0;L;;;;;N;;;;;
+2850;BRAILLE PATTERN DOTS-57;So;0;L;;;;;N;;;;;
+2851;BRAILLE PATTERN DOTS-157;So;0;L;;;;;N;;;;;
+2852;BRAILLE PATTERN DOTS-257;So;0;L;;;;;N;;;;;
+2853;BRAILLE PATTERN DOTS-1257;So;0;L;;;;;N;;;;;
+2854;BRAILLE PATTERN DOTS-357;So;0;L;;;;;N;;;;;
+2855;BRAILLE PATTERN DOTS-1357;So;0;L;;;;;N;;;;;
+2856;BRAILLE PATTERN DOTS-2357;So;0;L;;;;;N;;;;;
+2857;BRAILLE PATTERN DOTS-12357;So;0;L;;;;;N;;;;;
+2858;BRAILLE PATTERN DOTS-457;So;0;L;;;;;N;;;;;
+2859;BRAILLE PATTERN DOTS-1457;So;0;L;;;;;N;;;;;
+285A;BRAILLE PATTERN DOTS-2457;So;0;L;;;;;N;;;;;
+285B;BRAILLE PATTERN DOTS-12457;So;0;L;;;;;N;;;;;
+285C;BRAILLE PATTERN DOTS-3457;So;0;L;;;;;N;;;;;
+285D;BRAILLE PATTERN DOTS-13457;So;0;L;;;;;N;;;;;
+285E;BRAILLE PATTERN DOTS-23457;So;0;L;;;;;N;;;;;
+285F;BRAILLE PATTERN DOTS-123457;So;0;L;;;;;N;;;;;
+2860;BRAILLE PATTERN DOTS-67;So;0;L;;;;;N;;;;;
+2861;BRAILLE PATTERN DOTS-167;So;0;L;;;;;N;;;;;
+2862;BRAILLE PATTERN DOTS-267;So;0;L;;;;;N;;;;;
+2863;BRAILLE PATTERN DOTS-1267;So;0;L;;;;;N;;;;;
+2864;BRAILLE PATTERN DOTS-367;So;0;L;;;;;N;;;;;
+2865;BRAILLE PATTERN DOTS-1367;So;0;L;;;;;N;;;;;
+2866;BRAILLE PATTERN DOTS-2367;So;0;L;;;;;N;;;;;
+2867;BRAILLE PATTERN DOTS-12367;So;0;L;;;;;N;;;;;
+2868;BRAILLE PATTERN DOTS-467;So;0;L;;;;;N;;;;;
+2869;BRAILLE PATTERN DOTS-1467;So;0;L;;;;;N;;;;;
+286A;BRAILLE PATTERN DOTS-2467;So;0;L;;;;;N;;;;;
+286B;BRAILLE PATTERN DOTS-12467;So;0;L;;;;;N;;;;;
+286C;BRAILLE PATTERN DOTS-3467;So;0;L;;;;;N;;;;;
+286D;BRAILLE PATTERN DOTS-13467;So;0;L;;;;;N;;;;;
+286E;BRAILLE PATTERN DOTS-23467;So;0;L;;;;;N;;;;;
+286F;BRAILLE PATTERN DOTS-123467;So;0;L;;;;;N;;;;;
+2870;BRAILLE PATTERN DOTS-567;So;0;L;;;;;N;;;;;
+2871;BRAILLE PATTERN DOTS-1567;So;0;L;;;;;N;;;;;
+2872;BRAILLE PATTERN DOTS-2567;So;0;L;;;;;N;;;;;
+2873;BRAILLE PATTERN DOTS-12567;So;0;L;;;;;N;;;;;
+2874;BRAILLE PATTERN DOTS-3567;So;0;L;;;;;N;;;;;
+2875;BRAILLE PATTERN DOTS-13567;So;0;L;;;;;N;;;;;
+2876;BRAILLE PATTERN DOTS-23567;So;0;L;;;;;N;;;;;
+2877;BRAILLE PATTERN DOTS-123567;So;0;L;;;;;N;;;;;
+2878;BRAILLE PATTERN DOTS-4567;So;0;L;;;;;N;;;;;
+2879;BRAILLE PATTERN DOTS-14567;So;0;L;;;;;N;;;;;
+287A;BRAILLE PATTERN DOTS-24567;So;0;L;;;;;N;;;;;
+287B;BRAILLE PATTERN DOTS-124567;So;0;L;;;;;N;;;;;
+287C;BRAILLE PATTERN DOTS-34567;So;0;L;;;;;N;;;;;
+287D;BRAILLE PATTERN DOTS-134567;So;0;L;;;;;N;;;;;
+287E;BRAILLE PATTERN DOTS-234567;So;0;L;;;;;N;;;;;
+287F;BRAILLE PATTERN DOTS-1234567;So;0;L;;;;;N;;;;;
+2880;BRAILLE PATTERN DOTS-8;So;0;L;;;;;N;;;;;
+2881;BRAILLE PATTERN DOTS-18;So;0;L;;;;;N;;;;;
+2882;BRAILLE PATTERN DOTS-28;So;0;L;;;;;N;;;;;
+2883;BRAILLE PATTERN DOTS-128;So;0;L;;;;;N;;;;;
+2884;BRAILLE PATTERN DOTS-38;So;0;L;;;;;N;;;;;
+2885;BRAILLE PATTERN DOTS-138;So;0;L;;;;;N;;;;;
+2886;BRAILLE PATTERN DOTS-238;So;0;L;;;;;N;;;;;
+2887;BRAILLE PATTERN DOTS-1238;So;0;L;;;;;N;;;;;
+2888;BRAILLE PATTERN DOTS-48;So;0;L;;;;;N;;;;;
+2889;BRAILLE PATTERN DOTS-148;So;0;L;;;;;N;;;;;
+288A;BRAILLE PATTERN DOTS-248;So;0;L;;;;;N;;;;;
+288B;BRAILLE PATTERN DOTS-1248;So;0;L;;;;;N;;;;;
+288C;BRAILLE PATTERN DOTS-348;So;0;L;;;;;N;;;;;
+288D;BRAILLE PATTERN DOTS-1348;So;0;L;;;;;N;;;;;
+288E;BRAILLE PATTERN DOTS-2348;So;0;L;;;;;N;;;;;
+288F;BRAILLE PATTERN DOTS-12348;So;0;L;;;;;N;;;;;
+2890;BRAILLE PATTERN DOTS-58;So;0;L;;;;;N;;;;;
+2891;BRAILLE PATTERN DOTS-158;So;0;L;;;;;N;;;;;
+2892;BRAILLE PATTERN DOTS-258;So;0;L;;;;;N;;;;;
+2893;BRAILLE PATTERN DOTS-1258;So;0;L;;;;;N;;;;;
+2894;BRAILLE PATTERN DOTS-358;So;0;L;;;;;N;;;;;
+2895;BRAILLE PATTERN DOTS-1358;So;0;L;;;;;N;;;;;
+2896;BRAILLE PATTERN DOTS-2358;So;0;L;;;;;N;;;;;
+2897;BRAILLE PATTERN DOTS-12358;So;0;L;;;;;N;;;;;
+2898;BRAILLE PATTERN DOTS-458;So;0;L;;;;;N;;;;;
+2899;BRAILLE PATTERN DOTS-1458;So;0;L;;;;;N;;;;;
+289A;BRAILLE PATTERN DOTS-2458;So;0;L;;;;;N;;;;;
+289B;BRAILLE PATTERN DOTS-12458;So;0;L;;;;;N;;;;;
+289C;BRAILLE PATTERN DOTS-3458;So;0;L;;;;;N;;;;;
+289D;BRAILLE PATTERN DOTS-13458;So;0;L;;;;;N;;;;;
+289E;BRAILLE PATTERN DOTS-23458;So;0;L;;;;;N;;;;;
+289F;BRAILLE PATTERN DOTS-123458;So;0;L;;;;;N;;;;;
+28A0;BRAILLE PATTERN DOTS-68;So;0;L;;;;;N;;;;;
+28A1;BRAILLE PATTERN DOTS-168;So;0;L;;;;;N;;;;;
+28A2;BRAILLE PATTERN DOTS-268;So;0;L;;;;;N;;;;;
+28A3;BRAILLE PATTERN DOTS-1268;So;0;L;;;;;N;;;;;
+28A4;BRAILLE PATTERN DOTS-368;So;0;L;;;;;N;;;;;
+28A5;BRAILLE PATTERN DOTS-1368;So;0;L;;;;;N;;;;;
+28A6;BRAILLE PATTERN DOTS-2368;So;0;L;;;;;N;;;;;
+28A7;BRAILLE PATTERN DOTS-12368;So;0;L;;;;;N;;;;;
+28A8;BRAILLE PATTERN DOTS-468;So;0;L;;;;;N;;;;;
+28A9;BRAILLE PATTERN DOTS-1468;So;0;L;;;;;N;;;;;
+28AA;BRAILLE PATTERN DOTS-2468;So;0;L;;;;;N;;;;;
+28AB;BRAILLE PATTERN DOTS-12468;So;0;L;;;;;N;;;;;
+28AC;BRAILLE PATTERN DOTS-3468;So;0;L;;;;;N;;;;;
+28AD;BRAILLE PATTERN DOTS-13468;So;0;L;;;;;N;;;;;
+28AE;BRAILLE PATTERN DOTS-23468;So;0;L;;;;;N;;;;;
+28AF;BRAILLE PATTERN DOTS-123468;So;0;L;;;;;N;;;;;
+28B0;BRAILLE PATTERN DOTS-568;So;0;L;;;;;N;;;;;
+28B1;BRAILLE PATTERN DOTS-1568;So;0;L;;;;;N;;;;;
+28B2;BRAILLE PATTERN DOTS-2568;So;0;L;;;;;N;;;;;
+28B3;BRAILLE PATTERN DOTS-12568;So;0;L;;;;;N;;;;;
+28B4;BRAILLE PATTERN DOTS-3568;So;0;L;;;;;N;;;;;
+28B5;BRAILLE PATTERN DOTS-13568;So;0;L;;;;;N;;;;;
+28B6;BRAILLE PATTERN DOTS-23568;So;0;L;;;;;N;;;;;
+28B7;BRAILLE PATTERN DOTS-123568;So;0;L;;;;;N;;;;;
+28B8;BRAILLE PATTERN DOTS-4568;So;0;L;;;;;N;;;;;
+28B9;BRAILLE PATTERN DOTS-14568;So;0;L;;;;;N;;;;;
+28BA;BRAILLE PATTERN DOTS-24568;So;0;L;;;;;N;;;;;
+28BB;BRAILLE PATTERN DOTS-124568;So;0;L;;;;;N;;;;;
+28BC;BRAILLE PATTERN DOTS-34568;So;0;L;;;;;N;;;;;
+28BD;BRAILLE PATTERN DOTS-134568;So;0;L;;;;;N;;;;;
+28BE;BRAILLE PATTERN DOTS-234568;So;0;L;;;;;N;;;;;
+28BF;BRAILLE PATTERN DOTS-1234568;So;0;L;;;;;N;;;;;
+28C0;BRAILLE PATTERN DOTS-78;So;0;L;;;;;N;;;;;
+28C1;BRAILLE PATTERN DOTS-178;So;0;L;;;;;N;;;;;
+28C2;BRAILLE PATTERN DOTS-278;So;0;L;;;;;N;;;;;
+28C3;BRAILLE PATTERN DOTS-1278;So;0;L;;;;;N;;;;;
+28C4;BRAILLE PATTERN DOTS-378;So;0;L;;;;;N;;;;;
+28C5;BRAILLE PATTERN DOTS-1378;So;0;L;;;;;N;;;;;
+28C6;BRAILLE PATTERN DOTS-2378;So;0;L;;;;;N;;;;;
+28C7;BRAILLE PATTERN DOTS-12378;So;0;L;;;;;N;;;;;
+28C8;BRAILLE PATTERN DOTS-478;So;0;L;;;;;N;;;;;
+28C9;BRAILLE PATTERN DOTS-1478;So;0;L;;;;;N;;;;;
+28CA;BRAILLE PATTERN DOTS-2478;So;0;L;;;;;N;;;;;
+28CB;BRAILLE PATTERN DOTS-12478;So;0;L;;;;;N;;;;;
+28CC;BRAILLE PATTERN DOTS-3478;So;0;L;;;;;N;;;;;
+28CD;BRAILLE PATTERN DOTS-13478;So;0;L;;;;;N;;;;;
+28CE;BRAILLE PATTERN DOTS-23478;So;0;L;;;;;N;;;;;
+28CF;BRAILLE PATTERN DOTS-123478;So;0;L;;;;;N;;;;;
+28D0;BRAILLE PATTERN DOTS-578;So;0;L;;;;;N;;;;;
+28D1;BRAILLE PATTERN DOTS-1578;So;0;L;;;;;N;;;;;
+28D2;BRAILLE PATTERN DOTS-2578;So;0;L;;;;;N;;;;;
+28D3;BRAILLE PATTERN DOTS-12578;So;0;L;;;;;N;;;;;
+28D4;BRAILLE PATTERN DOTS-3578;So;0;L;;;;;N;;;;;
+28D5;BRAILLE PATTERN DOTS-13578;So;0;L;;;;;N;;;;;
+28D6;BRAILLE PATTERN DOTS-23578;So;0;L;;;;;N;;;;;
+28D7;BRAILLE PATTERN DOTS-123578;So;0;L;;;;;N;;;;;
+28D8;BRAILLE PATTERN DOTS-4578;So;0;L;;;;;N;;;;;
+28D9;BRAILLE PATTERN DOTS-14578;So;0;L;;;;;N;;;;;
+28DA;BRAILLE PATTERN DOTS-24578;So;0;L;;;;;N;;;;;
+28DB;BRAILLE PATTERN DOTS-124578;So;0;L;;;;;N;;;;;
+28DC;BRAILLE PATTERN DOTS-34578;So;0;L;;;;;N;;;;;
+28DD;BRAILLE PATTERN DOTS-134578;So;0;L;;;;;N;;;;;
+28DE;BRAILLE PATTERN DOTS-234578;So;0;L;;;;;N;;;;;
+28DF;BRAILLE PATTERN DOTS-1234578;So;0;L;;;;;N;;;;;
+28E0;BRAILLE PATTERN DOTS-678;So;0;L;;;;;N;;;;;
+28E1;BRAILLE PATTERN DOTS-1678;So;0;L;;;;;N;;;;;
+28E2;BRAILLE PATTERN DOTS-2678;So;0;L;;;;;N;;;;;
+28E3;BRAILLE PATTERN DOTS-12678;So;0;L;;;;;N;;;;;
+28E4;BRAILLE PATTERN DOTS-3678;So;0;L;;;;;N;;;;;
+28E5;BRAILLE PATTERN DOTS-13678;So;0;L;;;;;N;;;;;
+28E6;BRAILLE PATTERN DOTS-23678;So;0;L;;;;;N;;;;;
+28E7;BRAILLE PATTERN DOTS-123678;So;0;L;;;;;N;;;;;
+28E8;BRAILLE PATTERN DOTS-4678;So;0;L;;;;;N;;;;;
+28E9;BRAILLE PATTERN DOTS-14678;So;0;L;;;;;N;;;;;
+28EA;BRAILLE PATTERN DOTS-24678;So;0;L;;;;;N;;;;;
+28EB;BRAILLE PATTERN DOTS-124678;So;0;L;;;;;N;;;;;
+28EC;BRAILLE PATTERN DOTS-34678;So;0;L;;;;;N;;;;;
+28ED;BRAILLE PATTERN DOTS-134678;So;0;L;;;;;N;;;;;
+28EE;BRAILLE PATTERN DOTS-234678;So;0;L;;;;;N;;;;;
+28EF;BRAILLE PATTERN DOTS-1234678;So;0;L;;;;;N;;;;;
+28F0;BRAILLE PATTERN DOTS-5678;So;0;L;;;;;N;;;;;
+28F1;BRAILLE PATTERN DOTS-15678;So;0;L;;;;;N;;;;;
+28F2;BRAILLE PATTERN DOTS-25678;So;0;L;;;;;N;;;;;
+28F3;BRAILLE PATTERN DOTS-125678;So;0;L;;;;;N;;;;;
+28F4;BRAILLE PATTERN DOTS-35678;So;0;L;;;;;N;;;;;
+28F5;BRAILLE PATTERN DOTS-135678;So;0;L;;;;;N;;;;;
+28F6;BRAILLE PATTERN DOTS-235678;So;0;L;;;;;N;;;;;
+28F7;BRAILLE PATTERN DOTS-1235678;So;0;L;;;;;N;;;;;
+28F8;BRAILLE PATTERN DOTS-45678;So;0;L;;;;;N;;;;;
+28F9;BRAILLE PATTERN DOTS-145678;So;0;L;;;;;N;;;;;
+28FA;BRAILLE PATTERN DOTS-245678;So;0;L;;;;;N;;;;;
+28FB;BRAILLE PATTERN DOTS-1245678;So;0;L;;;;;N;;;;;
+28FC;BRAILLE PATTERN DOTS-345678;So;0;L;;;;;N;;;;;
+28FD;BRAILLE PATTERN DOTS-1345678;So;0;L;;;;;N;;;;;
+28FE;BRAILLE PATTERN DOTS-2345678;So;0;L;;;;;N;;;;;
+28FF;BRAILLE PATTERN DOTS-12345678;So;0;L;;;;;N;;;;;
+2900;RIGHTWARDS TWO-HEADED ARROW WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;
+2901;RIGHTWARDS TWO-HEADED ARROW WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;
+2902;LEFTWARDS DOUBLE ARROW WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;
+2903;RIGHTWARDS DOUBLE ARROW WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;
+2904;LEFT RIGHT DOUBLE ARROW WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;
+2905;RIGHTWARDS TWO-HEADED ARROW FROM BAR;Sm;0;ON;;;;;N;;;;;
+2906;LEFTWARDS DOUBLE ARROW FROM BAR;Sm;0;ON;;;;;N;;;;;
+2907;RIGHTWARDS DOUBLE ARROW FROM BAR;Sm;0;ON;;;;;N;;;;;
+2908;DOWNWARDS ARROW WITH HORIZONTAL STROKE;Sm;0;ON;;;;;N;;;;;
+2909;UPWARDS ARROW WITH HORIZONTAL STROKE;Sm;0;ON;;;;;N;;;;;
+290A;UPWARDS TRIPLE ARROW;Sm;0;ON;;;;;N;;;;;
+290B;DOWNWARDS TRIPLE ARROW;Sm;0;ON;;;;;N;;;;;
+290C;LEFTWARDS DOUBLE DASH ARROW;Sm;0;ON;;;;;N;;;;;
+290D;RIGHTWARDS DOUBLE DASH ARROW;Sm;0;ON;;;;;N;;;;;
+290E;LEFTWARDS TRIPLE DASH ARROW;Sm;0;ON;;;;;N;;;;;
+290F;RIGHTWARDS TRIPLE DASH ARROW;Sm;0;ON;;;;;N;;;;;
+2910;RIGHTWARDS TWO-HEADED TRIPLE DASH ARROW;Sm;0;ON;;;;;N;;;;;
+2911;RIGHTWARDS ARROW WITH DOTTED STEM;Sm;0;ON;;;;;N;;;;;
+2912;UPWARDS ARROW TO BAR;Sm;0;ON;;;;;N;;;;;
+2913;DOWNWARDS ARROW TO BAR;Sm;0;ON;;;;;N;;;;;
+2914;RIGHTWARDS ARROW WITH TAIL WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;
+2915;RIGHTWARDS ARROW WITH TAIL WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;
+2916;RIGHTWARDS TWO-HEADED ARROW WITH TAIL;Sm;0;ON;;;;;N;;;;;
+2917;RIGHTWARDS TWO-HEADED ARROW WITH TAIL WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;
+2918;RIGHTWARDS TWO-HEADED ARROW WITH TAIL WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;
+2919;LEFTWARDS ARROW-TAIL;Sm;0;ON;;;;;N;;;;;
+291A;RIGHTWARDS ARROW-TAIL;Sm;0;ON;;;;;N;;;;;
+291B;LEFTWARDS DOUBLE ARROW-TAIL;Sm;0;ON;;;;;N;;;;;
+291C;RIGHTWARDS DOUBLE ARROW-TAIL;Sm;0;ON;;;;;N;;;;;
+291D;LEFTWARDS ARROW TO BLACK DIAMOND;Sm;0;ON;;;;;N;;;;;
+291E;RIGHTWARDS ARROW TO BLACK DIAMOND;Sm;0;ON;;;;;N;;;;;
+291F;LEFTWARDS ARROW FROM BAR TO BLACK DIAMOND;Sm;0;ON;;;;;N;;;;;
+2920;RIGHTWARDS ARROW FROM BAR TO BLACK DIAMOND;Sm;0;ON;;;;;N;;;;;
+2921;NORTH WEST AND SOUTH EAST ARROW;Sm;0;ON;;;;;N;;;;;
+2922;NORTH EAST AND SOUTH WEST ARROW;Sm;0;ON;;;;;N;;;;;
+2923;NORTH WEST ARROW WITH HOOK;Sm;0;ON;;;;;N;;;;;
+2924;NORTH EAST ARROW WITH HOOK;Sm;0;ON;;;;;N;;;;;
+2925;SOUTH EAST ARROW WITH HOOK;Sm;0;ON;;;;;N;;;;;
+2926;SOUTH WEST ARROW WITH HOOK;Sm;0;ON;;;;;N;;;;;
+2927;NORTH WEST ARROW AND NORTH EAST ARROW;Sm;0;ON;;;;;N;;;;;
+2928;NORTH EAST ARROW AND SOUTH EAST ARROW;Sm;0;ON;;;;;N;;;;;
+2929;SOUTH EAST ARROW AND SOUTH WEST ARROW;Sm;0;ON;;;;;N;;;;;
+292A;SOUTH WEST ARROW AND NORTH WEST ARROW;Sm;0;ON;;;;;N;;;;;
+292B;RISING DIAGONAL CROSSING FALLING DIAGONAL;Sm;0;ON;;;;;N;;;;;
+292C;FALLING DIAGONAL CROSSING RISING DIAGONAL;Sm;0;ON;;;;;N;;;;;
+292D;SOUTH EAST ARROW CROSSING NORTH EAST ARROW;Sm;0;ON;;;;;N;;;;;
+292E;NORTH EAST ARROW CROSSING SOUTH EAST ARROW;Sm;0;ON;;;;;N;;;;;
+292F;FALLING DIAGONAL CROSSING NORTH EAST ARROW;Sm;0;ON;;;;;N;;;;;
+2930;RISING DIAGONAL CROSSING SOUTH EAST ARROW;Sm;0;ON;;;;;N;;;;;
+2931;NORTH EAST ARROW CROSSING NORTH WEST ARROW;Sm;0;ON;;;;;N;;;;;
+2932;NORTH WEST ARROW CROSSING NORTH EAST ARROW;Sm;0;ON;;;;;N;;;;;
+2933;WAVE ARROW POINTING DIRECTLY RIGHT;Sm;0;ON;;;;;N;;;;;
+2934;ARROW POINTING RIGHTWARDS THEN CURVING UPWARDS;Sm;0;ON;;;;;N;;;;;
+2935;ARROW POINTING RIGHTWARDS THEN CURVING DOWNWARDS;Sm;0;ON;;;;;N;;;;;
+2936;ARROW POINTING DOWNWARDS THEN CURVING LEFTWARDS;Sm;0;ON;;;;;N;;;;;
+2937;ARROW POINTING DOWNWARDS THEN CURVING RIGHTWARDS;Sm;0;ON;;;;;N;;;;;
+2938;RIGHT-SIDE ARC CLOCKWISE ARROW;Sm;0;ON;;;;;N;;;;;
+2939;LEFT-SIDE ARC ANTICLOCKWISE ARROW;Sm;0;ON;;;;;N;;;;;
+293A;TOP ARC ANTICLOCKWISE ARROW;Sm;0;ON;;;;;N;;;;;
+293B;BOTTOM ARC ANTICLOCKWISE ARROW;Sm;0;ON;;;;;N;;;;;
+293C;TOP ARC CLOCKWISE ARROW WITH MINUS;Sm;0;ON;;;;;N;;;;;
+293D;TOP ARC ANTICLOCKWISE ARROW WITH PLUS;Sm;0;ON;;;;;N;;;;;
+293E;LOWER RIGHT SEMICIRCULAR CLOCKWISE ARROW;Sm;0;ON;;;;;N;;;;;
+293F;LOWER LEFT SEMICIRCULAR ANTICLOCKWISE ARROW;Sm;0;ON;;;;;N;;;;;
+2940;ANTICLOCKWISE CLOSED CIRCLE ARROW;Sm;0;ON;;;;;N;;;;;
+2941;CLOCKWISE CLOSED CIRCLE ARROW;Sm;0;ON;;;;;N;;;;;
+2942;RIGHTWARDS ARROW ABOVE SHORT LEFTWARDS ARROW;Sm;0;ON;;;;;N;;;;;
+2943;LEFTWARDS ARROW ABOVE SHORT RIGHTWARDS ARROW;Sm;0;ON;;;;;N;;;;;
+2944;SHORT RIGHTWARDS ARROW ABOVE LEFTWARDS ARROW;Sm;0;ON;;;;;N;;;;;
+2945;RIGHTWARDS ARROW WITH PLUS BELOW;Sm;0;ON;;;;;N;;;;;
+2946;LEFTWARDS ARROW WITH PLUS BELOW;Sm;0;ON;;;;;N;;;;;
+2947;RIGHTWARDS ARROW THROUGH X;Sm;0;ON;;;;;N;;;;;
+2948;LEFT RIGHT ARROW THROUGH SMALL CIRCLE;Sm;0;ON;;;;;N;;;;;
+2949;UPWARDS TWO-HEADED ARROW FROM SMALL CIRCLE;Sm;0;ON;;;;;N;;;;;
+294A;LEFT BARB UP RIGHT BARB DOWN HARPOON;Sm;0;ON;;;;;N;;;;;
+294B;LEFT BARB DOWN RIGHT BARB UP HARPOON;Sm;0;ON;;;;;N;;;;;
+294C;UP BARB RIGHT DOWN BARB LEFT HARPOON;Sm;0;ON;;;;;N;;;;;
+294D;UP BARB LEFT DOWN BARB RIGHT HARPOON;Sm;0;ON;;;;;N;;;;;
+294E;LEFT BARB UP RIGHT BARB UP HARPOON;Sm;0;ON;;;;;N;;;;;
+294F;UP BARB RIGHT DOWN BARB RIGHT HARPOON;Sm;0;ON;;;;;N;;;;;
+2950;LEFT BARB DOWN RIGHT BARB DOWN HARPOON;Sm;0;ON;;;;;N;;;;;
+2951;UP BARB LEFT DOWN BARB LEFT HARPOON;Sm;0;ON;;;;;N;;;;;
+2952;LEFTWARDS HARPOON WITH BARB UP TO BAR;Sm;0;ON;;;;;N;;;;;
+2953;RIGHTWARDS HARPOON WITH BARB UP TO BAR;Sm;0;ON;;;;;N;;;;;
+2954;UPWARDS HARPOON WITH BARB RIGHT TO BAR;Sm;0;ON;;;;;N;;;;;
+2955;DOWNWARDS HARPOON WITH BARB RIGHT TO BAR;Sm;0;ON;;;;;N;;;;;
+2956;LEFTWARDS HARPOON WITH BARB DOWN TO BAR;Sm;0;ON;;;;;N;;;;;
+2957;RIGHTWARDS HARPOON WITH BARB DOWN TO BAR;Sm;0;ON;;;;;N;;;;;
+2958;UPWARDS HARPOON WITH BARB LEFT TO BAR;Sm;0;ON;;;;;N;;;;;
+2959;DOWNWARDS HARPOON WITH BARB LEFT TO BAR;Sm;0;ON;;;;;N;;;;;
+295A;LEFTWARDS HARPOON WITH BARB UP FROM BAR;Sm;0;ON;;;;;N;;;;;
+295B;RIGHTWARDS HARPOON WITH BARB UP FROM BAR;Sm;0;ON;;;;;N;;;;;
+295C;UPWARDS HARPOON WITH BARB RIGHT FROM BAR;Sm;0;ON;;;;;N;;;;;
+295D;DOWNWARDS HARPOON WITH BARB RIGHT FROM BAR;Sm;0;ON;;;;;N;;;;;
+295E;LEFTWARDS HARPOON WITH BARB DOWN FROM BAR;Sm;0;ON;;;;;N;;;;;
+295F;RIGHTWARDS HARPOON WITH BARB DOWN FROM BAR;Sm;0;ON;;;;;N;;;;;
+2960;UPWARDS HARPOON WITH BARB LEFT FROM BAR;Sm;0;ON;;;;;N;;;;;
+2961;DOWNWARDS HARPOON WITH BARB LEFT FROM BAR;Sm;0;ON;;;;;N;;;;;
+2962;LEFTWARDS HARPOON WITH BARB UP ABOVE LEFTWARDS HARPOON WITH BARB DOWN;Sm;0;ON;;;;;N;;;;;
+2963;UPWARDS HARPOON WITH BARB LEFT BESIDE UPWARDS HARPOON WITH BARB RIGHT;Sm;0;ON;;;;;N;;;;;
+2964;RIGHTWARDS HARPOON WITH BARB UP ABOVE RIGHTWARDS HARPOON WITH BARB DOWN;Sm;0;ON;;;;;N;;;;;
+2965;DOWNWARDS HARPOON WITH BARB LEFT BESIDE DOWNWARDS HARPOON WITH BARB RIGHT;Sm;0;ON;;;;;N;;;;;
+2966;LEFTWARDS HARPOON WITH BARB UP ABOVE RIGHTWARDS HARPOON WITH BARB UP;Sm;0;ON;;;;;N;;;;;
+2967;LEFTWARDS HARPOON WITH BARB DOWN ABOVE RIGHTWARDS HARPOON WITH BARB DOWN;Sm;0;ON;;;;;N;;;;;
+2968;RIGHTWARDS HARPOON WITH BARB UP ABOVE LEFTWARDS HARPOON WITH BARB UP;Sm;0;ON;;;;;N;;;;;
+2969;RIGHTWARDS HARPOON WITH BARB DOWN ABOVE LEFTWARDS HARPOON WITH BARB DOWN;Sm;0;ON;;;;;N;;;;;
+296A;LEFTWARDS HARPOON WITH BARB UP ABOVE LONG DASH;Sm;0;ON;;;;;N;;;;;
+296B;LEFTWARDS HARPOON WITH BARB DOWN BELOW LONG DASH;Sm;0;ON;;;;;N;;;;;
+296C;RIGHTWARDS HARPOON WITH BARB UP ABOVE LONG DASH;Sm;0;ON;;;;;N;;;;;
+296D;RIGHTWARDS HARPOON WITH BARB DOWN BELOW LONG DASH;Sm;0;ON;;;;;N;;;;;
+296E;UPWARDS HARPOON WITH BARB LEFT BESIDE DOWNWARDS HARPOON WITH BARB RIGHT;Sm;0;ON;;;;;N;;;;;
+296F;DOWNWARDS HARPOON WITH BARB LEFT BESIDE UPWARDS HARPOON WITH BARB RIGHT;Sm;0;ON;;;;;N;;;;;
+2970;RIGHT DOUBLE ARROW WITH ROUNDED HEAD;Sm;0;ON;;;;;N;;;;;
+2971;EQUALS SIGN ABOVE RIGHTWARDS ARROW;Sm;0;ON;;;;;N;;;;;
+2972;TILDE OPERATOR ABOVE RIGHTWARDS ARROW;Sm;0;ON;;;;;N;;;;;
+2973;LEFTWARDS ARROW ABOVE TILDE OPERATOR;Sm;0;ON;;;;;N;;;;;
+2974;RIGHTWARDS ARROW ABOVE TILDE OPERATOR;Sm;0;ON;;;;;N;;;;;
+2975;RIGHTWARDS ARROW ABOVE ALMOST EQUAL TO;Sm;0;ON;;;;;N;;;;;
+2976;LESS-THAN ABOVE LEFTWARDS ARROW;Sm;0;ON;;;;;N;;;;;
+2977;LEFTWARDS ARROW THROUGH LESS-THAN;Sm;0;ON;;;;;N;;;;;
+2978;GREATER-THAN ABOVE RIGHTWARDS ARROW;Sm;0;ON;;;;;N;;;;;
+2979;SUBSET ABOVE RIGHTWARDS ARROW;Sm;0;ON;;;;;N;;;;;
+297A;LEFTWARDS ARROW THROUGH SUBSET;Sm;0;ON;;;;;N;;;;;
+297B;SUPERSET ABOVE LEFTWARDS ARROW;Sm;0;ON;;;;;N;;;;;
+297C;LEFT FISH TAIL;Sm;0;ON;;;;;N;;;;;
+297D;RIGHT FISH TAIL;Sm;0;ON;;;;;N;;;;;
+297E;UP FISH TAIL;Sm;0;ON;;;;;N;;;;;
+297F;DOWN FISH TAIL;Sm;0;ON;;;;;N;;;;;
+2980;TRIPLE VERTICAL BAR DELIMITER;Sm;0;ON;;;;;N;;;;;
+2981;Z NOTATION SPOT;Sm;0;ON;;;;;N;;;;;
+2982;Z NOTATION TYPE COLON;Sm;0;ON;;;;;N;;;;;
+2983;LEFT WHITE CURLY BRACKET;Ps;0;ON;;;;;Y;;;;;
+2984;RIGHT WHITE CURLY BRACKET;Pe;0;ON;;;;;Y;;;;;
+2985;LEFT WHITE PARENTHESIS;Ps;0;ON;;;;;Y;;;;;
+2986;RIGHT WHITE PARENTHESIS;Pe;0;ON;;;;;Y;;;;;
+2987;Z NOTATION LEFT IMAGE BRACKET;Ps;0;ON;;;;;Y;;;;;
+2988;Z NOTATION RIGHT IMAGE BRACKET;Pe;0;ON;;;;;Y;;;;;
+2989;Z NOTATION LEFT BINDING BRACKET;Ps;0;ON;;;;;Y;;;;;
+298A;Z NOTATION RIGHT BINDING BRACKET;Pe;0;ON;;;;;Y;;;;;
+298B;LEFT SQUARE BRACKET WITH UNDERBAR;Ps;0;ON;;;;;Y;;;;;
+298C;RIGHT SQUARE BRACKET WITH UNDERBAR;Pe;0;ON;;;;;Y;;;;;
+298D;LEFT SQUARE BRACKET WITH TICK IN TOP CORNER;Ps;0;ON;;;;;Y;;;;;
+298E;RIGHT SQUARE BRACKET WITH TICK IN BOTTOM CORNER;Pe;0;ON;;;;;Y;;;;;
+298F;LEFT SQUARE BRACKET WITH TICK IN BOTTOM CORNER;Ps;0;ON;;;;;Y;;;;;
+2990;RIGHT SQUARE BRACKET WITH TICK IN TOP CORNER;Pe;0;ON;;;;;Y;;;;;
+2991;LEFT ANGLE BRACKET WITH DOT;Ps;0;ON;;;;;Y;;;;;
+2992;RIGHT ANGLE BRACKET WITH DOT;Pe;0;ON;;;;;Y;;;;;
+2993;LEFT ARC LESS-THAN BRACKET;Ps;0;ON;;;;;Y;;;;;
+2994;RIGHT ARC GREATER-THAN BRACKET;Pe;0;ON;;;;;Y;;;;;
+2995;DOUBLE LEFT ARC GREATER-THAN BRACKET;Ps;0;ON;;;;;Y;;;;;
+2996;DOUBLE RIGHT ARC LESS-THAN BRACKET;Pe;0;ON;;;;;Y;;;;;
+2997;LEFT BLACK TORTOISE SHELL BRACKET;Ps;0;ON;;;;;Y;;;;;
+2998;RIGHT BLACK TORTOISE SHELL BRACKET;Pe;0;ON;;;;;Y;;;;;
+2999;DOTTED FENCE;Sm;0;ON;;;;;N;;;;;
+299A;VERTICAL ZIGZAG LINE;Sm;0;ON;;;;;N;;;;;
+299B;MEASURED ANGLE OPENING LEFT;Sm;0;ON;;;;;Y;;;;;
+299C;RIGHT ANGLE VARIANT WITH SQUARE;Sm;0;ON;;;;;Y;;;;;
+299D;MEASURED RIGHT ANGLE WITH DOT;Sm;0;ON;;;;;Y;;;;;
+299E;ANGLE WITH S INSIDE;Sm;0;ON;;;;;Y;;;;;
+299F;ACUTE ANGLE;Sm;0;ON;;;;;Y;;;;;
+29A0;SPHERICAL ANGLE OPENING LEFT;Sm;0;ON;;;;;Y;;;;;
+29A1;SPHERICAL ANGLE OPENING UP;Sm;0;ON;;;;;Y;;;;;
+29A2;TURNED ANGLE;Sm;0;ON;;;;;Y;;;;;
+29A3;REVERSED ANGLE;Sm;0;ON;;;;;Y;;;;;
+29A4;ANGLE WITH UNDERBAR;Sm;0;ON;;;;;Y;;;;;
+29A5;REVERSED ANGLE WITH UNDERBAR;Sm;0;ON;;;;;Y;;;;;
+29A6;OBLIQUE ANGLE OPENING UP;Sm;0;ON;;;;;Y;;;;;
+29A7;OBLIQUE ANGLE OPENING DOWN;Sm;0;ON;;;;;Y;;;;;
+29A8;MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING UP AND RIGHT;Sm;0;ON;;;;;Y;;;;;
+29A9;MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING UP AND LEFT;Sm;0;ON;;;;;Y;;;;;
+29AA;MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING DOWN AND RIGHT;Sm;0;ON;;;;;Y;;;;;
+29AB;MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING DOWN AND LEFT;Sm;0;ON;;;;;Y;;;;;
+29AC;MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING RIGHT AND UP;Sm;0;ON;;;;;Y;;;;;
+29AD;MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING LEFT AND UP;Sm;0;ON;;;;;Y;;;;;
+29AE;MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING RIGHT AND DOWN;Sm;0;ON;;;;;Y;;;;;
+29AF;MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING LEFT AND DOWN;Sm;0;ON;;;;;Y;;;;;
+29B0;REVERSED EMPTY SET;Sm;0;ON;;;;;N;;;;;
+29B1;EMPTY SET WITH OVERBAR;Sm;0;ON;;;;;N;;;;;
+29B2;EMPTY SET WITH SMALL CIRCLE ABOVE;Sm;0;ON;;;;;N;;;;;
+29B3;EMPTY SET WITH RIGHT ARROW ABOVE;Sm;0;ON;;;;;N;;;;;
+29B4;EMPTY SET WITH LEFT ARROW ABOVE;Sm;0;ON;;;;;N;;;;;
+29B5;CIRCLE WITH HORIZONTAL BAR;Sm;0;ON;;;;;N;;;;;
+29B6;CIRCLED VERTICAL BAR;Sm;0;ON;;;;;N;;;;;
+29B7;CIRCLED PARALLEL;Sm;0;ON;;;;;N;;;;;
+29B8;CIRCLED REVERSE SOLIDUS;Sm;0;ON;;;;;Y;;;;;
+29B9;CIRCLED PERPENDICULAR;Sm;0;ON;;;;;N;;;;;
+29BA;CIRCLE DIVIDED BY HORIZONTAL BAR AND TOP HALF DIVIDED BY VERTICAL BAR;Sm;0;ON;;;;;N;;;;;
+29BB;CIRCLE WITH SUPERIMPOSED X;Sm;0;ON;;;;;N;;;;;
+29BC;CIRCLED ANTICLOCKWISE-ROTATED DIVISION SIGN;Sm;0;ON;;;;;N;;;;;
+29BD;UP ARROW THROUGH CIRCLE;Sm;0;ON;;;;;N;;;;;
+29BE;CIRCLED WHITE BULLET;Sm;0;ON;;;;;N;;;;;
+29BF;CIRCLED BULLET;Sm;0;ON;;;;;N;;;;;
+29C0;CIRCLED LESS-THAN;Sm;0;ON;;;;;Y;;;;;
+29C1;CIRCLED GREATER-THAN;Sm;0;ON;;;;;Y;;;;;
+29C2;CIRCLE WITH SMALL CIRCLE TO THE RIGHT;Sm;0;ON;;;;;Y;;;;;
+29C3;CIRCLE WITH TWO HORIZONTAL STROKES TO THE RIGHT;Sm;0;ON;;;;;Y;;;;;
+29C4;SQUARED RISING DIAGONAL SLASH;Sm;0;ON;;;;;Y;;;;;
+29C5;SQUARED FALLING DIAGONAL SLASH;Sm;0;ON;;;;;Y;;;;;
+29C6;SQUARED ASTERISK;Sm;0;ON;;;;;N;;;;;
+29C7;SQUARED SMALL CIRCLE;Sm;0;ON;;;;;N;;;;;
+29C8;SQUARED SQUARE;Sm;0;ON;;;;;N;;;;;
+29C9;TWO JOINED SQUARES;Sm;0;ON;;;;;Y;;;;;
+29CA;TRIANGLE WITH DOT ABOVE;Sm;0;ON;;;;;N;;;;;
+29CB;TRIANGLE WITH UNDERBAR;Sm;0;ON;;;;;N;;;;;
+29CC;S IN TRIANGLE;Sm;0;ON;;;;;N;;;;;
+29CD;TRIANGLE WITH SERIFS AT BOTTOM;Sm;0;ON;;;;;N;;;;;
+29CE;RIGHT TRIANGLE ABOVE LEFT TRIANGLE;Sm;0;ON;;;;;Y;;;;;
+29CF;LEFT TRIANGLE BESIDE VERTICAL BAR;Sm;0;ON;;;;;Y;;;;;
+29D0;VERTICAL BAR BESIDE RIGHT TRIANGLE;Sm;0;ON;;;;;Y;;;;;
+29D1;BOWTIE WITH LEFT HALF BLACK;Sm;0;ON;;;;;Y;;;;;
+29D2;BOWTIE WITH RIGHT HALF BLACK;Sm;0;ON;;;;;Y;;;;;
+29D3;BLACK BOWTIE;Sm;0;ON;;;;;N;;;;;
+29D4;TIMES WITH LEFT HALF BLACK;Sm;0;ON;;;;;Y;;;;;
+29D5;TIMES WITH RIGHT HALF BLACK;Sm;0;ON;;;;;Y;;;;;
+29D6;WHITE HOURGLASS;Sm;0;ON;;;;;N;;;;;
+29D7;BLACK HOURGLASS;Sm;0;ON;;;;;N;;;;;
+29D8;LEFT WIGGLY FENCE;Ps;0;ON;;;;;Y;;;;;
+29D9;RIGHT WIGGLY FENCE;Pe;0;ON;;;;;Y;;;;;
+29DA;LEFT DOUBLE WIGGLY FENCE;Ps;0;ON;;;;;Y;;;;;
+29DB;RIGHT DOUBLE WIGGLY FENCE;Pe;0;ON;;;;;Y;;;;;
+29DC;INCOMPLETE INFINITY;Sm;0;ON;;;;;Y;;;;;
+29DD;TIE OVER INFINITY;Sm;0;ON;;;;;N;;;;;
+29DE;INFINITY NEGATED WITH VERTICAL BAR;Sm;0;ON;;;;;N;;;;;
+29DF;DOUBLE-ENDED MULTIMAP;Sm;0;ON;;;;;N;;;;;
+29E0;SQUARE WITH CONTOURED OUTLINE;Sm;0;ON;;;;;N;;;;;
+29E1;INCREASES AS;Sm;0;ON;;;;;Y;;;;;
+29E2;SHUFFLE PRODUCT;Sm;0;ON;;;;;N;;;;;
+29E3;EQUALS SIGN AND SLANTED PARALLEL;Sm;0;ON;;;;;Y;;;;;
+29E4;EQUALS SIGN AND SLANTED PARALLEL WITH TILDE ABOVE;Sm;0;ON;;;;;Y;;;;;
+29E5;IDENTICAL TO AND SLANTED PARALLEL;Sm;0;ON;;;;;Y;;;;;
+29E6;GLEICH STARK;Sm;0;ON;;;;;N;;;;;
+29E7;THERMODYNAMIC;Sm;0;ON;;;;;N;;;;;
+29E8;DOWN-POINTING TRIANGLE WITH LEFT HALF BLACK;Sm;0;ON;;;;;Y;;;;;
+29E9;DOWN-POINTING TRIANGLE WITH RIGHT HALF BLACK;Sm;0;ON;;;;;Y;;;;;
+29EA;BLACK DIAMOND WITH DOWN ARROW;Sm;0;ON;;;;;N;;;;;
+29EB;BLACK LOZENGE;Sm;0;ON;;;;;N;;;;;
+29EC;WHITE CIRCLE WITH DOWN ARROW;Sm;0;ON;;;;;N;;;;;
+29ED;BLACK CIRCLE WITH DOWN ARROW;Sm;0;ON;;;;;N;;;;;
+29EE;ERROR-BARRED WHITE SQUARE;Sm;0;ON;;;;;N;;;;;
+29EF;ERROR-BARRED BLACK SQUARE;Sm;0;ON;;;;;N;;;;;
+29F0;ERROR-BARRED WHITE DIAMOND;Sm;0;ON;;;;;N;;;;;
+29F1;ERROR-BARRED BLACK DIAMOND;Sm;0;ON;;;;;N;;;;;
+29F2;ERROR-BARRED WHITE CIRCLE;Sm;0;ON;;;;;N;;;;;
+29F3;ERROR-BARRED BLACK CIRCLE;Sm;0;ON;;;;;N;;;;;
+29F4;RULE-DELAYED;Sm;0;ON;;;;;Y;;;;;
+29F5;REVERSE SOLIDUS OPERATOR;Sm;0;ON;;;;;Y;;;;;
+29F6;SOLIDUS WITH OVERBAR;Sm;0;ON;;;;;Y;;;;;
+29F7;REVERSE SOLIDUS WITH HORIZONTAL STROKE;Sm;0;ON;;;;;Y;;;;;
+29F8;BIG SOLIDUS;Sm;0;ON;;;;;Y;;;;;
+29F9;BIG REVERSE SOLIDUS;Sm;0;ON;;;;;Y;;;;;
+29FA;DOUBLE PLUS;Sm;0;ON;;;;;N;;;;;
+29FB;TRIPLE PLUS;Sm;0;ON;;;;;N;;;;;
+29FC;LEFT-POINTING CURVED ANGLE BRACKET;Ps;0;ON;;;;;Y;;;;;
+29FD;RIGHT-POINTING CURVED ANGLE BRACKET;Pe;0;ON;;;;;Y;;;;;
+29FE;TINY;Sm;0;ON;;;;;N;;;;;
+29FF;MINY;Sm;0;ON;;;;;N;;;;;
+2A00;N-ARY CIRCLED DOT OPERATOR;Sm;0;ON;;;;;N;;;;;
+2A01;N-ARY CIRCLED PLUS OPERATOR;Sm;0;ON;;;;;N;;;;;
+2A02;N-ARY CIRCLED TIMES OPERATOR;Sm;0;ON;;;;;N;;;;;
+2A03;N-ARY UNION OPERATOR WITH DOT;Sm;0;ON;;;;;N;;;;;
+2A04;N-ARY UNION OPERATOR WITH PLUS;Sm;0;ON;;;;;N;;;;;
+2A05;N-ARY SQUARE INTERSECTION OPERATOR;Sm;0;ON;;;;;N;;;;;
+2A06;N-ARY SQUARE UNION OPERATOR;Sm;0;ON;;;;;N;;;;;
+2A07;TWO LOGICAL AND OPERATOR;Sm;0;ON;;;;;N;;;;;
+2A08;TWO LOGICAL OR OPERATOR;Sm;0;ON;;;;;N;;;;;
+2A09;N-ARY TIMES OPERATOR;Sm;0;ON;;;;;N;;;;;
+2A0A;MODULO TWO SUM;Sm;0;ON;;;;;Y;;;;;
+2A0B;SUMMATION WITH INTEGRAL;Sm;0;ON;;;;;Y;;;;;
+2A0C;QUADRUPLE INTEGRAL OPERATOR;Sm;0;ON;<compat> 222B 222B 222B 222B;;;;Y;;;;;
+2A0D;FINITE PART INTEGRAL;Sm;0;ON;;;;;Y;;;;;
+2A0E;INTEGRAL WITH DOUBLE STROKE;Sm;0;ON;;;;;Y;;;;;
+2A0F;INTEGRAL AVERAGE WITH SLASH;Sm;0;ON;;;;;Y;;;;;
+2A10;CIRCULATION FUNCTION;Sm;0;ON;;;;;Y;;;;;
+2A11;ANTICLOCKWISE INTEGRATION;Sm;0;ON;;;;;Y;;;;;
+2A12;LINE INTEGRATION WITH RECTANGULAR PATH AROUND POLE;Sm;0;ON;;;;;Y;;;;;
+2A13;LINE INTEGRATION WITH SEMICIRCULAR PATH AROUND POLE;Sm;0;ON;;;;;Y;;;;;
+2A14;LINE INTEGRATION NOT INCLUDING THE POLE;Sm;0;ON;;;;;Y;;;;;
+2A15;INTEGRAL AROUND A POINT OPERATOR;Sm;0;ON;;;;;Y;;;;;
+2A16;QUATERNION INTEGRAL OPERATOR;Sm;0;ON;;;;;Y;;;;;
+2A17;INTEGRAL WITH LEFTWARDS ARROW WITH HOOK;Sm;0;ON;;;;;Y;;;;;
+2A18;INTEGRAL WITH TIMES SIGN;Sm;0;ON;;;;;Y;;;;;
+2A19;INTEGRAL WITH INTERSECTION;Sm;0;ON;;;;;Y;;;;;
+2A1A;INTEGRAL WITH UNION;Sm;0;ON;;;;;Y;;;;;
+2A1B;INTEGRAL WITH OVERBAR;Sm;0;ON;;;;;Y;;;;;
+2A1C;INTEGRAL WITH UNDERBAR;Sm;0;ON;;;;;Y;;;;;
+2A1D;JOIN;Sm;0;ON;;;;;N;;;;;
+2A1E;LARGE LEFT TRIANGLE OPERATOR;Sm;0;ON;;;;;Y;;;;;
+2A1F;Z NOTATION SCHEMA COMPOSITION;Sm;0;ON;;;;;Y;;;;;
+2A20;Z NOTATION SCHEMA PIPING;Sm;0;ON;;;;;Y;;;;;
+2A21;Z NOTATION SCHEMA PROJECTION;Sm;0;ON;;;;;Y;;;;;
+2A22;PLUS SIGN WITH SMALL CIRCLE ABOVE;Sm;0;ON;;;;;N;;;;;
+2A23;PLUS SIGN WITH CIRCUMFLEX ACCENT ABOVE;Sm;0;ON;;;;;N;;;;;
+2A24;PLUS SIGN WITH TILDE ABOVE;Sm;0;ON;;;;;Y;;;;;
+2A25;PLUS SIGN WITH DOT BELOW;Sm;0;ON;;;;;N;;;;;
+2A26;PLUS SIGN WITH TILDE BELOW;Sm;0;ON;;;;;Y;;;;;
+2A27;PLUS SIGN WITH SUBSCRIPT TWO;Sm;0;ON;;;;;N;;;;;
+2A28;PLUS SIGN WITH BLACK TRIANGLE;Sm;0;ON;;;;;N;;;;;
+2A29;MINUS SIGN WITH COMMA ABOVE;Sm;0;ON;;;;;Y;;;;;
+2A2A;MINUS SIGN WITH DOT BELOW;Sm;0;ON;;;;;N;;;;;
+2A2B;MINUS SIGN WITH FALLING DOTS;Sm;0;ON;;;;;Y;;;;;
+2A2C;MINUS SIGN WITH RISING DOTS;Sm;0;ON;;;;;Y;;;;;
+2A2D;PLUS SIGN IN LEFT HALF CIRCLE;Sm;0;ON;;;;;Y;;;;;
+2A2E;PLUS SIGN IN RIGHT HALF CIRCLE;Sm;0;ON;;;;;Y;;;;;
+2A2F;VECTOR OR CROSS PRODUCT;Sm;0;ON;;;;;N;;;;;
+2A30;MULTIPLICATION SIGN WITH DOT ABOVE;Sm;0;ON;;;;;N;;;;;
+2A31;MULTIPLICATION SIGN WITH UNDERBAR;Sm;0;ON;;;;;N;;;;;
+2A32;SEMIDIRECT PRODUCT WITH BOTTOM CLOSED;Sm;0;ON;;;;;N;;;;;
+2A33;SMASH PRODUCT;Sm;0;ON;;;;;N;;;;;
+2A34;MULTIPLICATION SIGN IN LEFT HALF CIRCLE;Sm;0;ON;;;;;Y;;;;;
+2A35;MULTIPLICATION SIGN IN RIGHT HALF CIRCLE;Sm;0;ON;;;;;Y;;;;;
+2A36;CIRCLED MULTIPLICATION SIGN WITH CIRCUMFLEX ACCENT;Sm;0;ON;;;;;N;;;;;
+2A37;MULTIPLICATION SIGN IN DOUBLE CIRCLE;Sm;0;ON;;;;;N;;;;;
+2A38;CIRCLED DIVISION SIGN;Sm;0;ON;;;;;N;;;;;
+2A39;PLUS SIGN IN TRIANGLE;Sm;0;ON;;;;;N;;;;;
+2A3A;MINUS SIGN IN TRIANGLE;Sm;0;ON;;;;;N;;;;;
+2A3B;MULTIPLICATION SIGN IN TRIANGLE;Sm;0;ON;;;;;N;;;;;
+2A3C;INTERIOR PRODUCT;Sm;0;ON;;;;;Y;;;;;
+2A3D;RIGHTHAND INTERIOR PRODUCT;Sm;0;ON;;;;;Y;;;;;
+2A3E;Z NOTATION RELATIONAL COMPOSITION;Sm;0;ON;;;;;Y;;;;;
+2A3F;AMALGAMATION OR COPRODUCT;Sm;0;ON;;;;;N;;;;;
+2A40;INTERSECTION WITH DOT;Sm;0;ON;;;;;N;;;;;
+2A41;UNION WITH MINUS SIGN;Sm;0;ON;;;;;N;;;;;
+2A42;UNION WITH OVERBAR;Sm;0;ON;;;;;N;;;;;
+2A43;INTERSECTION WITH OVERBAR;Sm;0;ON;;;;;N;;;;;
+2A44;INTERSECTION WITH LOGICAL AND;Sm;0;ON;;;;;N;;;;;
+2A45;UNION WITH LOGICAL OR;Sm;0;ON;;;;;N;;;;;
+2A46;UNION ABOVE INTERSECTION;Sm;0;ON;;;;;N;;;;;
+2A47;INTERSECTION ABOVE UNION;Sm;0;ON;;;;;N;;;;;
+2A48;UNION ABOVE BAR ABOVE INTERSECTION;Sm;0;ON;;;;;N;;;;;
+2A49;INTERSECTION ABOVE BAR ABOVE UNION;Sm;0;ON;;;;;N;;;;;
+2A4A;UNION BESIDE AND JOINED WITH UNION;Sm;0;ON;;;;;N;;;;;
+2A4B;INTERSECTION BESIDE AND JOINED WITH INTERSECTION;Sm;0;ON;;;;;N;;;;;
+2A4C;CLOSED UNION WITH SERIFS;Sm;0;ON;;;;;N;;;;;
+2A4D;CLOSED INTERSECTION WITH SERIFS;Sm;0;ON;;;;;N;;;;;
+2A4E;DOUBLE SQUARE INTERSECTION;Sm;0;ON;;;;;N;;;;;
+2A4F;DOUBLE SQUARE UNION;Sm;0;ON;;;;;N;;;;;
+2A50;CLOSED UNION WITH SERIFS AND SMASH PRODUCT;Sm;0;ON;;;;;N;;;;;
+2A51;LOGICAL AND WITH DOT ABOVE;Sm;0;ON;;;;;N;;;;;
+2A52;LOGICAL OR WITH DOT ABOVE;Sm;0;ON;;;;;N;;;;;
+2A53;DOUBLE LOGICAL AND;Sm;0;ON;;;;;N;;;;;
+2A54;DOUBLE LOGICAL OR;Sm;0;ON;;;;;N;;;;;
+2A55;TWO INTERSECTING LOGICAL AND;Sm;0;ON;;;;;N;;;;;
+2A56;TWO INTERSECTING LOGICAL OR;Sm;0;ON;;;;;N;;;;;
+2A57;SLOPING LARGE OR;Sm;0;ON;;;;;Y;;;;;
+2A58;SLOPING LARGE AND;Sm;0;ON;;;;;Y;;;;;
+2A59;LOGICAL OR OVERLAPPING LOGICAL AND;Sm;0;ON;;;;;N;;;;;
+2A5A;LOGICAL AND WITH MIDDLE STEM;Sm;0;ON;;;;;N;;;;;
+2A5B;LOGICAL OR WITH MIDDLE STEM;Sm;0;ON;;;;;N;;;;;
+2A5C;LOGICAL AND WITH HORIZONTAL DASH;Sm;0;ON;;;;;N;;;;;
+2A5D;LOGICAL OR WITH HORIZONTAL DASH;Sm;0;ON;;;;;N;;;;;
+2A5E;LOGICAL AND WITH DOUBLE OVERBAR;Sm;0;ON;;;;;N;;;;;
+2A5F;LOGICAL AND WITH UNDERBAR;Sm;0;ON;;;;;N;;;;;
+2A60;LOGICAL AND WITH DOUBLE UNDERBAR;Sm;0;ON;;;;;N;;;;;
+2A61;SMALL VEE WITH UNDERBAR;Sm;0;ON;;;;;N;;;;;
+2A62;LOGICAL OR WITH DOUBLE OVERBAR;Sm;0;ON;;;;;N;;;;;
+2A63;LOGICAL OR WITH DOUBLE UNDERBAR;Sm;0;ON;;;;;N;;;;;
+2A64;Z NOTATION DOMAIN ANTIRESTRICTION;Sm;0;ON;;;;;Y;;;;;
+2A65;Z NOTATION RANGE ANTIRESTRICTION;Sm;0;ON;;;;;Y;;;;;
+2A66;EQUALS SIGN WITH DOT BELOW;Sm;0;ON;;;;;N;;;;;
+2A67;IDENTICAL WITH DOT ABOVE;Sm;0;ON;;;;;N;;;;;
+2A68;TRIPLE HORIZONTAL BAR WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;
+2A69;TRIPLE HORIZONTAL BAR WITH TRIPLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;
+2A6A;TILDE OPERATOR WITH DOT ABOVE;Sm;0;ON;;;;;Y;;;;;
+2A6B;TILDE OPERATOR WITH RISING DOTS;Sm;0;ON;;;;;Y;;;;;
+2A6C;SIMILAR MINUS SIMILAR;Sm;0;ON;;;;;Y;;;;;
+2A6D;CONGRUENT WITH DOT ABOVE;Sm;0;ON;;;;;Y;;;;;
+2A6E;EQUALS WITH ASTERISK;Sm;0;ON;;;;;N;;;;;
+2A6F;ALMOST EQUAL TO WITH CIRCUMFLEX ACCENT;Sm;0;ON;;;;;Y;;;;;
+2A70;APPROXIMATELY EQUAL OR EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+2A71;EQUALS SIGN ABOVE PLUS SIGN;Sm;0;ON;;;;;N;;;;;
+2A72;PLUS SIGN ABOVE EQUALS SIGN;Sm;0;ON;;;;;N;;;;;
+2A73;EQUALS SIGN ABOVE TILDE OPERATOR;Sm;0;ON;;;;;Y;;;;;
+2A74;DOUBLE COLON EQUAL;Sm;0;ON;<compat> 003A 003A 003D;;;;Y;;;;;
+2A75;TWO CONSECUTIVE EQUALS SIGNS;Sm;0;ON;<compat> 003D 003D;;;;N;;;;;
+2A76;THREE CONSECUTIVE EQUALS SIGNS;Sm;0;ON;<compat> 003D 003D 003D;;;;N;;;;;
+2A77;EQUALS SIGN WITH TWO DOTS ABOVE AND TWO DOTS BELOW;Sm;0;ON;;;;;N;;;;;
+2A78;EQUIVALENT WITH FOUR DOTS ABOVE;Sm;0;ON;;;;;N;;;;;
+2A79;LESS-THAN WITH CIRCLE INSIDE;Sm;0;ON;;;;;Y;;;;;
+2A7A;GREATER-THAN WITH CIRCLE INSIDE;Sm;0;ON;;;;;Y;;;;;
+2A7B;LESS-THAN WITH QUESTION MARK ABOVE;Sm;0;ON;;;;;Y;;;;;
+2A7C;GREATER-THAN WITH QUESTION MARK ABOVE;Sm;0;ON;;;;;Y;;;;;
+2A7D;LESS-THAN OR SLANTED EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+2A7E;GREATER-THAN OR SLANTED EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+2A7F;LESS-THAN OR SLANTED EQUAL TO WITH DOT INSIDE;Sm;0;ON;;;;;Y;;;;;
+2A80;GREATER-THAN OR SLANTED EQUAL TO WITH DOT INSIDE;Sm;0;ON;;;;;Y;;;;;
+2A81;LESS-THAN OR SLANTED EQUAL TO WITH DOT ABOVE;Sm;0;ON;;;;;Y;;;;;
+2A82;GREATER-THAN OR SLANTED EQUAL TO WITH DOT ABOVE;Sm;0;ON;;;;;Y;;;;;
+2A83;LESS-THAN OR SLANTED EQUAL TO WITH DOT ABOVE RIGHT;Sm;0;ON;;;;;Y;;;;;
+2A84;GREATER-THAN OR SLANTED EQUAL TO WITH DOT ABOVE LEFT;Sm;0;ON;;;;;Y;;;;;
+2A85;LESS-THAN OR APPROXIMATE;Sm;0;ON;;;;;Y;;;;;
+2A86;GREATER-THAN OR APPROXIMATE;Sm;0;ON;;;;;Y;;;;;
+2A87;LESS-THAN AND SINGLE-LINE NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+2A88;GREATER-THAN AND SINGLE-LINE NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+2A89;LESS-THAN AND NOT APPROXIMATE;Sm;0;ON;;;;;Y;;;;;
+2A8A;GREATER-THAN AND NOT APPROXIMATE;Sm;0;ON;;;;;Y;;;;;
+2A8B;LESS-THAN ABOVE DOUBLE-LINE EQUAL ABOVE GREATER-THAN;Sm;0;ON;;;;;Y;;;;;
+2A8C;GREATER-THAN ABOVE DOUBLE-LINE EQUAL ABOVE LESS-THAN;Sm;0;ON;;;;;Y;;;;;
+2A8D;LESS-THAN ABOVE SIMILAR OR EQUAL;Sm;0;ON;;;;;Y;;;;;
+2A8E;GREATER-THAN ABOVE SIMILAR OR EQUAL;Sm;0;ON;;;;;Y;;;;;
+2A8F;LESS-THAN ABOVE SIMILAR ABOVE GREATER-THAN;Sm;0;ON;;;;;Y;;;;;
+2A90;GREATER-THAN ABOVE SIMILAR ABOVE LESS-THAN;Sm;0;ON;;;;;Y;;;;;
+2A91;LESS-THAN ABOVE GREATER-THAN ABOVE DOUBLE-LINE EQUAL;Sm;0;ON;;;;;Y;;;;;
+2A92;GREATER-THAN ABOVE LESS-THAN ABOVE DOUBLE-LINE EQUAL;Sm;0;ON;;;;;Y;;;;;
+2A93;LESS-THAN ABOVE SLANTED EQUAL ABOVE GREATER-THAN ABOVE SLANTED EQUAL;Sm;0;ON;;;;;Y;;;;;
+2A94;GREATER-THAN ABOVE SLANTED EQUAL ABOVE LESS-THAN ABOVE SLANTED EQUAL;Sm;0;ON;;;;;Y;;;;;
+2A95;SLANTED EQUAL TO OR LESS-THAN;Sm;0;ON;;;;;Y;;;;;
+2A96;SLANTED EQUAL TO OR GREATER-THAN;Sm;0;ON;;;;;Y;;;;;
+2A97;SLANTED EQUAL TO OR LESS-THAN WITH DOT INSIDE;Sm;0;ON;;;;;Y;;;;;
+2A98;SLANTED EQUAL TO OR GREATER-THAN WITH DOT INSIDE;Sm;0;ON;;;;;Y;;;;;
+2A99;DOUBLE-LINE EQUAL TO OR LESS-THAN;Sm;0;ON;;;;;Y;;;;;
+2A9A;DOUBLE-LINE EQUAL TO OR GREATER-THAN;Sm;0;ON;;;;;Y;;;;;
+2A9B;DOUBLE-LINE SLANTED EQUAL TO OR LESS-THAN;Sm;0;ON;;;;;Y;;;;;
+2A9C;DOUBLE-LINE SLANTED EQUAL TO OR GREATER-THAN;Sm;0;ON;;;;;Y;;;;;
+2A9D;SIMILAR OR LESS-THAN;Sm;0;ON;;;;;Y;;;;;
+2A9E;SIMILAR OR GREATER-THAN;Sm;0;ON;;;;;Y;;;;;
+2A9F;SIMILAR ABOVE LESS-THAN ABOVE EQUALS SIGN;Sm;0;ON;;;;;Y;;;;;
+2AA0;SIMILAR ABOVE GREATER-THAN ABOVE EQUALS SIGN;Sm;0;ON;;;;;Y;;;;;
+2AA1;DOUBLE NESTED LESS-THAN;Sm;0;ON;;;;;Y;;;;;
+2AA2;DOUBLE NESTED GREATER-THAN;Sm;0;ON;;;;;Y;;;;;
+2AA3;DOUBLE NESTED LESS-THAN WITH UNDERBAR;Sm;0;ON;;;;;Y;;;;;
+2AA4;GREATER-THAN OVERLAPPING LESS-THAN;Sm;0;ON;;;;;N;;;;;
+2AA5;GREATER-THAN BESIDE LESS-THAN;Sm;0;ON;;;;;N;;;;;
+2AA6;LESS-THAN CLOSED BY CURVE;Sm;0;ON;;;;;Y;;;;;
+2AA7;GREATER-THAN CLOSED BY CURVE;Sm;0;ON;;;;;Y;;;;;
+2AA8;LESS-THAN CLOSED BY CURVE ABOVE SLANTED EQUAL;Sm;0;ON;;;;;Y;;;;;
+2AA9;GREATER-THAN CLOSED BY CURVE ABOVE SLANTED EQUAL;Sm;0;ON;;;;;Y;;;;;
+2AAA;SMALLER THAN;Sm;0;ON;;;;;Y;;;;;
+2AAB;LARGER THAN;Sm;0;ON;;;;;Y;;;;;
+2AAC;SMALLER THAN OR EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+2AAD;LARGER THAN OR EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+2AAE;EQUALS SIGN WITH BUMPY ABOVE;Sm;0;ON;;;;;N;;;;;
+2AAF;PRECEDES ABOVE SINGLE-LINE EQUALS SIGN;Sm;0;ON;;;;;Y;;;;;
+2AB0;SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN;Sm;0;ON;;;;;Y;;;;;
+2AB1;PRECEDES ABOVE SINGLE-LINE NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+2AB2;SUCCEEDS ABOVE SINGLE-LINE NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+2AB3;PRECEDES ABOVE EQUALS SIGN;Sm;0;ON;;;;;Y;;;;;
+2AB4;SUCCEEDS ABOVE EQUALS SIGN;Sm;0;ON;;;;;Y;;;;;
+2AB5;PRECEDES ABOVE NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+2AB6;SUCCEEDS ABOVE NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+2AB7;PRECEDES ABOVE ALMOST EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+2AB8;SUCCEEDS ABOVE ALMOST EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+2AB9;PRECEDES ABOVE NOT ALMOST EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+2ABA;SUCCEEDS ABOVE NOT ALMOST EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+2ABB;DOUBLE PRECEDES;Sm;0;ON;;;;;Y;;;;;
+2ABC;DOUBLE SUCCEEDS;Sm;0;ON;;;;;Y;;;;;
+2ABD;SUBSET WITH DOT;Sm;0;ON;;;;;Y;;;;;
+2ABE;SUPERSET WITH DOT;Sm;0;ON;;;;;Y;;;;;
+2ABF;SUBSET WITH PLUS SIGN BELOW;Sm;0;ON;;;;;Y;;;;;
+2AC0;SUPERSET WITH PLUS SIGN BELOW;Sm;0;ON;;;;;Y;;;;;
+2AC1;SUBSET WITH MULTIPLICATION SIGN BELOW;Sm;0;ON;;;;;Y;;;;;
+2AC2;SUPERSET WITH MULTIPLICATION SIGN BELOW;Sm;0;ON;;;;;Y;;;;;
+2AC3;SUBSET OF OR EQUAL TO WITH DOT ABOVE;Sm;0;ON;;;;;Y;;;;;
+2AC4;SUPERSET OF OR EQUAL TO WITH DOT ABOVE;Sm;0;ON;;;;;Y;;;;;
+2AC5;SUBSET OF ABOVE EQUALS SIGN;Sm;0;ON;;;;;Y;;;;;
+2AC6;SUPERSET OF ABOVE EQUALS SIGN;Sm;0;ON;;;;;Y;;;;;
+2AC7;SUBSET OF ABOVE TILDE OPERATOR;Sm;0;ON;;;;;Y;;;;;
+2AC8;SUPERSET OF ABOVE TILDE OPERATOR;Sm;0;ON;;;;;Y;;;;;
+2AC9;SUBSET OF ABOVE ALMOST EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+2ACA;SUPERSET OF ABOVE ALMOST EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+2ACB;SUBSET OF ABOVE NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+2ACC;SUPERSET OF ABOVE NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+2ACD;SQUARE LEFT OPEN BOX OPERATOR;Sm;0;ON;;;;;Y;;;;;
+2ACE;SQUARE RIGHT OPEN BOX OPERATOR;Sm;0;ON;;;;;Y;;;;;
+2ACF;CLOSED SUBSET;Sm;0;ON;;;;;Y;;;;;
+2AD0;CLOSED SUPERSET;Sm;0;ON;;;;;Y;;;;;
+2AD1;CLOSED SUBSET OR EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+2AD2;CLOSED SUPERSET OR EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+2AD3;SUBSET ABOVE SUPERSET;Sm;0;ON;;;;;Y;;;;;
+2AD4;SUPERSET ABOVE SUBSET;Sm;0;ON;;;;;Y;;;;;
+2AD5;SUBSET ABOVE SUBSET;Sm;0;ON;;;;;Y;;;;;
+2AD6;SUPERSET ABOVE SUPERSET;Sm;0;ON;;;;;Y;;;;;
+2AD7;SUPERSET BESIDE SUBSET;Sm;0;ON;;;;;N;;;;;
+2AD8;SUPERSET BESIDE AND JOINED BY DASH WITH SUBSET;Sm;0;ON;;;;;N;;;;;
+2AD9;ELEMENT OF OPENING DOWNWARDS;Sm;0;ON;;;;;N;;;;;
+2ADA;PITCHFORK WITH TEE TOP;Sm;0;ON;;;;;N;;;;;
+2ADB;TRANSVERSAL INTERSECTION;Sm;0;ON;;;;;N;;;;;
+2ADC;FORKING;Sm;0;ON;2ADD 0338;;;;Y;;;;;
+2ADD;NONFORKING;Sm;0;ON;;;;;N;;;;;
+2ADE;SHORT LEFT TACK;Sm;0;ON;;;;;Y;;;;;
+2ADF;SHORT DOWN TACK;Sm;0;ON;;;;;N;;;;;
+2AE0;SHORT UP TACK;Sm;0;ON;;;;;N;;;;;
+2AE1;PERPENDICULAR WITH S;Sm;0;ON;;;;;N;;;;;
+2AE2;VERTICAL BAR TRIPLE RIGHT TURNSTILE;Sm;0;ON;;;;;Y;;;;;
+2AE3;DOUBLE VERTICAL BAR LEFT TURNSTILE;Sm;0;ON;;;;;Y;;;;;
+2AE4;VERTICAL BAR DOUBLE LEFT TURNSTILE;Sm;0;ON;;;;;Y;;;;;
+2AE5;DOUBLE VERTICAL BAR DOUBLE LEFT TURNSTILE;Sm;0;ON;;;;;Y;;;;;
+2AE6;LONG DASH FROM LEFT MEMBER OF DOUBLE VERTICAL;Sm;0;ON;;;;;Y;;;;;
+2AE7;SHORT DOWN TACK WITH OVERBAR;Sm;0;ON;;;;;N;;;;;
+2AE8;SHORT UP TACK WITH UNDERBAR;Sm;0;ON;;;;;N;;;;;
+2AE9;SHORT UP TACK ABOVE SHORT DOWN TACK;Sm;0;ON;;;;;N;;;;;
+2AEA;DOUBLE DOWN TACK;Sm;0;ON;;;;;N;;;;;
+2AEB;DOUBLE UP TACK;Sm;0;ON;;;;;N;;;;;
+2AEC;DOUBLE STROKE NOT SIGN;Sm;0;ON;;;;;Y;;;;;
+2AED;REVERSED DOUBLE STROKE NOT SIGN;Sm;0;ON;;;;;Y;;;;;
+2AEE;DOES NOT DIVIDE WITH REVERSED NEGATION SLASH;Sm;0;ON;;;;;Y;;;;;
+2AEF;VERTICAL LINE WITH CIRCLE ABOVE;Sm;0;ON;;;;;N;;;;;
+2AF0;VERTICAL LINE WITH CIRCLE BELOW;Sm;0;ON;;;;;N;;;;;
+2AF1;DOWN TACK WITH CIRCLE BELOW;Sm;0;ON;;;;;N;;;;;
+2AF2;PARALLEL WITH HORIZONTAL STROKE;Sm;0;ON;;;;;N;;;;;
+2AF3;PARALLEL WITH TILDE OPERATOR;Sm;0;ON;;;;;Y;;;;;
+2AF4;TRIPLE VERTICAL BAR BINARY RELATION;Sm;0;ON;;;;;N;;;;;
+2AF5;TRIPLE VERTICAL BAR WITH HORIZONTAL STROKE;Sm;0;ON;;;;;N;;;;;
+2AF6;TRIPLE COLON OPERATOR;Sm;0;ON;;;;;N;;;;;
+2AF7;TRIPLE NESTED LESS-THAN;Sm;0;ON;;;;;Y;;;;;
+2AF8;TRIPLE NESTED GREATER-THAN;Sm;0;ON;;;;;Y;;;;;
+2AF9;DOUBLE-LINE SLANTED LESS-THAN OR EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+2AFA;DOUBLE-LINE SLANTED GREATER-THAN OR EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+2AFB;TRIPLE SOLIDUS BINARY RELATION;Sm;0;ON;;;;;Y;;;;;
+2AFC;LARGE TRIPLE VERTICAL BAR OPERATOR;Sm;0;ON;;;;;N;;;;;
+2AFD;DOUBLE SOLIDUS OPERATOR;Sm;0;ON;;;;;Y;;;;;
+2AFE;WHITE VERTICAL BAR;Sm;0;ON;;;;;N;;;;;
+2AFF;N-ARY WHITE VERTICAL BAR;Sm;0;ON;;;;;N;;;;;
+2B00;NORTH EAST WHITE ARROW;So;0;ON;;;;;N;;;;;
+2B01;NORTH WEST WHITE ARROW;So;0;ON;;;;;N;;;;;
+2B02;SOUTH EAST WHITE ARROW;So;0;ON;;;;;N;;;;;
+2B03;SOUTH WEST WHITE ARROW;So;0;ON;;;;;N;;;;;
+2B04;LEFT RIGHT WHITE ARROW;So;0;ON;;;;;N;;;;;
+2B05;LEFTWARDS BLACK ARROW;So;0;ON;;;;;N;;;;;
+2B06;UPWARDS BLACK ARROW;So;0;ON;;;;;N;;;;;
+2B07;DOWNWARDS BLACK ARROW;So;0;ON;;;;;N;;;;;
+2B08;NORTH EAST BLACK ARROW;So;0;ON;;;;;N;;;;;
+2B09;NORTH WEST BLACK ARROW;So;0;ON;;;;;N;;;;;
+2B0A;SOUTH EAST BLACK ARROW;So;0;ON;;;;;N;;;;;
+2B0B;SOUTH WEST BLACK ARROW;So;0;ON;;;;;N;;;;;
+2B0C;LEFT RIGHT BLACK ARROW;So;0;ON;;;;;N;;;;;
+2B0D;UP DOWN BLACK ARROW;So;0;ON;;;;;N;;;;;
+2B0E;RIGHTWARDS ARROW WITH TIP DOWNWARDS;So;0;ON;;;;;N;;;;;
+2B0F;RIGHTWARDS ARROW WITH TIP UPWARDS;So;0;ON;;;;;N;;;;;
+2B10;LEFTWARDS ARROW WITH TIP DOWNWARDS;So;0;ON;;;;;N;;;;;
+2B11;LEFTWARDS ARROW WITH TIP UPWARDS;So;0;ON;;;;;N;;;;;
+2B12;SQUARE WITH TOP HALF BLACK;So;0;ON;;;;;N;;;;;
+2B13;SQUARE WITH BOTTOM HALF BLACK;So;0;ON;;;;;N;;;;;
+2B14;SQUARE WITH UPPER RIGHT DIAGONAL HALF BLACK;So;0;ON;;;;;N;;;;;
+2B15;SQUARE WITH LOWER LEFT DIAGONAL HALF BLACK;So;0;ON;;;;;N;;;;;
+2B16;DIAMOND WITH LEFT HALF BLACK;So;0;ON;;;;;N;;;;;
+2B17;DIAMOND WITH RIGHT HALF BLACK;So;0;ON;;;;;N;;;;;
+2B18;DIAMOND WITH TOP HALF BLACK;So;0;ON;;;;;N;;;;;
+2B19;DIAMOND WITH BOTTOM HALF BLACK;So;0;ON;;;;;N;;;;;
+2B1A;DOTTED SQUARE;So;0;ON;;;;;N;;;;;
+2B1B;BLACK LARGE SQUARE;So;0;ON;;;;;N;;;;;
+2B1C;WHITE LARGE SQUARE;So;0;ON;;;;;N;;;;;
+2B1D;BLACK VERY SMALL SQUARE;So;0;ON;;;;;N;;;;;
+2B1E;WHITE VERY SMALL SQUARE;So;0;ON;;;;;N;;;;;
+2B1F;BLACK PENTAGON;So;0;ON;;;;;N;;;;;
+2B20;WHITE PENTAGON;So;0;ON;;;;;N;;;;;
+2B21;WHITE HEXAGON;So;0;ON;;;;;N;;;;;
+2B22;BLACK HEXAGON;So;0;ON;;;;;N;;;;;
+2B23;HORIZONTAL BLACK HEXAGON;So;0;ON;;;;;N;;;;;
+2B24;BLACK LARGE CIRCLE;So;0;ON;;;;;N;;;;;
+2B25;BLACK MEDIUM DIAMOND;So;0;ON;;;;;N;;;;;
+2B26;WHITE MEDIUM DIAMOND;So;0;ON;;;;;N;;;;;
+2B27;BLACK MEDIUM LOZENGE;So;0;ON;;;;;N;;;;;
+2B28;WHITE MEDIUM LOZENGE;So;0;ON;;;;;N;;;;;
+2B29;BLACK SMALL DIAMOND;So;0;ON;;;;;N;;;;;
+2B2A;BLACK SMALL LOZENGE;So;0;ON;;;;;N;;;;;
+2B2B;WHITE SMALL LOZENGE;So;0;ON;;;;;N;;;;;
+2B2C;BLACK HORIZONTAL ELLIPSE;So;0;ON;;;;;N;;;;;
+2B2D;WHITE HORIZONTAL ELLIPSE;So;0;ON;;;;;N;;;;;
+2B2E;BLACK VERTICAL ELLIPSE;So;0;ON;;;;;N;;;;;
+2B2F;WHITE VERTICAL ELLIPSE;So;0;ON;;;;;N;;;;;
+2B30;LEFT ARROW WITH SMALL CIRCLE;Sm;0;ON;;;;;N;;;;;
+2B31;THREE LEFTWARDS ARROWS;Sm;0;ON;;;;;N;;;;;
+2B32;LEFT ARROW WITH CIRCLED PLUS;Sm;0;ON;;;;;N;;;;;
+2B33;LONG LEFTWARDS SQUIGGLE ARROW;Sm;0;ON;;;;;N;;;;;
+2B34;LEFTWARDS TWO-HEADED ARROW WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;
+2B35;LEFTWARDS TWO-HEADED ARROW WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;
+2B36;LEFTWARDS TWO-HEADED ARROW FROM BAR;Sm;0;ON;;;;;N;;;;;
+2B37;LEFTWARDS TWO-HEADED TRIPLE DASH ARROW;Sm;0;ON;;;;;N;;;;;
+2B38;LEFTWARDS ARROW WITH DOTTED STEM;Sm;0;ON;;;;;N;;;;;
+2B39;LEFTWARDS ARROW WITH TAIL WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;
+2B3A;LEFTWARDS ARROW WITH TAIL WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;
+2B3B;LEFTWARDS TWO-HEADED ARROW WITH TAIL;Sm;0;ON;;;;;N;;;;;
+2B3C;LEFTWARDS TWO-HEADED ARROW WITH TAIL WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;
+2B3D;LEFTWARDS TWO-HEADED ARROW WITH TAIL WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;
+2B3E;LEFTWARDS ARROW THROUGH X;Sm;0;ON;;;;;N;;;;;
+2B3F;WAVE ARROW POINTING DIRECTLY LEFT;Sm;0;ON;;;;;N;;;;;
+2B40;EQUALS SIGN ABOVE LEFTWARDS ARROW;Sm;0;ON;;;;;N;;;;;
+2B41;REVERSE TILDE OPERATOR ABOVE LEFTWARDS ARROW;Sm;0;ON;;;;;N;;;;;
+2B42;LEFTWARDS ARROW ABOVE REVERSE ALMOST EQUAL TO;Sm;0;ON;;;;;N;;;;;
+2B43;RIGHTWARDS ARROW THROUGH GREATER-THAN;Sm;0;ON;;;;;N;;;;;
+2B44;RIGHTWARDS ARROW THROUGH SUPERSET;Sm;0;ON;;;;;N;;;;;
+2B45;LEFTWARDS QUADRUPLE ARROW;So;0;ON;;;;;N;;;;;
+2B46;RIGHTWARDS QUADRUPLE ARROW;So;0;ON;;;;;N;;;;;
+2B47;REVERSE TILDE OPERATOR ABOVE RIGHTWARDS ARROW;Sm;0;ON;;;;;N;;;;;
+2B48;RIGHTWARDS ARROW ABOVE REVERSE ALMOST EQUAL TO;Sm;0;ON;;;;;N;;;;;
+2B49;TILDE OPERATOR ABOVE LEFTWARDS ARROW;Sm;0;ON;;;;;N;;;;;
+2B4A;LEFTWARDS ARROW ABOVE ALMOST EQUAL TO;Sm;0;ON;;;;;N;;;;;
+2B4B;LEFTWARDS ARROW ABOVE REVERSE TILDE OPERATOR;Sm;0;ON;;;;;N;;;;;
+2B4C;RIGHTWARDS ARROW ABOVE REVERSE TILDE OPERATOR;Sm;0;ON;;;;;N;;;;;
+2B50;WHITE MEDIUM STAR;So;0;ON;;;;;N;;;;;
+2B51;BLACK SMALL STAR;So;0;ON;;;;;N;;;;;
+2B52;WHITE SMALL STAR;So;0;ON;;;;;N;;;;;
+2B53;BLACK RIGHT-POINTING PENTAGON;So;0;ON;;;;;N;;;;;
+2B54;WHITE RIGHT-POINTING PENTAGON;So;0;ON;;;;;N;;;;;
+2B55;HEAVY LARGE CIRCLE;So;0;ON;;;;;N;;;;;
+2B56;HEAVY OVAL WITH OVAL INSIDE;So;0;ON;;;;;N;;;;;
+2B57;HEAVY CIRCLE WITH CIRCLE INSIDE;So;0;ON;;;;;N;;;;;
+2B58;HEAVY CIRCLE;So;0;ON;;;;;N;;;;;
+2B59;HEAVY CIRCLED SALTIRE;So;0;ON;;;;;N;;;;;
+2C00;GLAGOLITIC CAPITAL LETTER AZU;Lu;0;L;;;;;N;;;;2C30;
+2C01;GLAGOLITIC CAPITAL LETTER BUKY;Lu;0;L;;;;;N;;;;2C31;
+2C02;GLAGOLITIC CAPITAL LETTER VEDE;Lu;0;L;;;;;N;;;;2C32;
+2C03;GLAGOLITIC CAPITAL LETTER GLAGOLI;Lu;0;L;;;;;N;;;;2C33;
+2C04;GLAGOLITIC CAPITAL LETTER DOBRO;Lu;0;L;;;;;N;;;;2C34;
+2C05;GLAGOLITIC CAPITAL LETTER YESTU;Lu;0;L;;;;;N;;;;2C35;
+2C06;GLAGOLITIC CAPITAL LETTER ZHIVETE;Lu;0;L;;;;;N;;;;2C36;
+2C07;GLAGOLITIC CAPITAL LETTER DZELO;Lu;0;L;;;;;N;;;;2C37;
+2C08;GLAGOLITIC CAPITAL LETTER ZEMLJA;Lu;0;L;;;;;N;;;;2C38;
+2C09;GLAGOLITIC CAPITAL LETTER IZHE;Lu;0;L;;;;;N;;;;2C39;
+2C0A;GLAGOLITIC CAPITAL LETTER INITIAL IZHE;Lu;0;L;;;;;N;;;;2C3A;
+2C0B;GLAGOLITIC CAPITAL LETTER I;Lu;0;L;;;;;N;;;;2C3B;
+2C0C;GLAGOLITIC CAPITAL LETTER DJERVI;Lu;0;L;;;;;N;;;;2C3C;
+2C0D;GLAGOLITIC CAPITAL LETTER KAKO;Lu;0;L;;;;;N;;;;2C3D;
+2C0E;GLAGOLITIC CAPITAL LETTER LJUDIJE;Lu;0;L;;;;;N;;;;2C3E;
+2C0F;GLAGOLITIC CAPITAL LETTER MYSLITE;Lu;0;L;;;;;N;;;;2C3F;
+2C10;GLAGOLITIC CAPITAL LETTER NASHI;Lu;0;L;;;;;N;;;;2C40;
+2C11;GLAGOLITIC CAPITAL LETTER ONU;Lu;0;L;;;;;N;;;;2C41;
+2C12;GLAGOLITIC CAPITAL LETTER POKOJI;Lu;0;L;;;;;N;;;;2C42;
+2C13;GLAGOLITIC CAPITAL LETTER RITSI;Lu;0;L;;;;;N;;;;2C43;
+2C14;GLAGOLITIC CAPITAL LETTER SLOVO;Lu;0;L;;;;;N;;;;2C44;
+2C15;GLAGOLITIC CAPITAL LETTER TVRIDO;Lu;0;L;;;;;N;;;;2C45;
+2C16;GLAGOLITIC CAPITAL LETTER UKU;Lu;0;L;;;;;N;;;;2C46;
+2C17;GLAGOLITIC CAPITAL LETTER FRITU;Lu;0;L;;;;;N;;;;2C47;
+2C18;GLAGOLITIC CAPITAL LETTER HERU;Lu;0;L;;;;;N;;;;2C48;
+2C19;GLAGOLITIC CAPITAL LETTER OTU;Lu;0;L;;;;;N;;;;2C49;
+2C1A;GLAGOLITIC CAPITAL LETTER PE;Lu;0;L;;;;;N;;;;2C4A;
+2C1B;GLAGOLITIC CAPITAL LETTER SHTA;Lu;0;L;;;;;N;;;;2C4B;
+2C1C;GLAGOLITIC CAPITAL LETTER TSI;Lu;0;L;;;;;N;;;;2C4C;
+2C1D;GLAGOLITIC CAPITAL LETTER CHRIVI;Lu;0;L;;;;;N;;;;2C4D;
+2C1E;GLAGOLITIC CAPITAL LETTER SHA;Lu;0;L;;;;;N;;;;2C4E;
+2C1F;GLAGOLITIC CAPITAL LETTER YERU;Lu;0;L;;;;;N;;;;2C4F;
+2C20;GLAGOLITIC CAPITAL LETTER YERI;Lu;0;L;;;;;N;;;;2C50;
+2C21;GLAGOLITIC CAPITAL LETTER YATI;Lu;0;L;;;;;N;;;;2C51;
+2C22;GLAGOLITIC CAPITAL LETTER SPIDERY HA;Lu;0;L;;;;;N;;;;2C52;
+2C23;GLAGOLITIC CAPITAL LETTER YU;Lu;0;L;;;;;N;;;;2C53;
+2C24;GLAGOLITIC CAPITAL LETTER SMALL YUS;Lu;0;L;;;;;N;;;;2C54;
+2C25;GLAGOLITIC CAPITAL LETTER SMALL YUS WITH TAIL;Lu;0;L;;;;;N;;;;2C55;
+2C26;GLAGOLITIC CAPITAL LETTER YO;Lu;0;L;;;;;N;;;;2C56;
+2C27;GLAGOLITIC CAPITAL LETTER IOTATED SMALL YUS;Lu;0;L;;;;;N;;;;2C57;
+2C28;GLAGOLITIC CAPITAL LETTER BIG YUS;Lu;0;L;;;;;N;;;;2C58;
+2C29;GLAGOLITIC CAPITAL LETTER IOTATED BIG YUS;Lu;0;L;;;;;N;;;;2C59;
+2C2A;GLAGOLITIC CAPITAL LETTER FITA;Lu;0;L;;;;;N;;;;2C5A;
+2C2B;GLAGOLITIC CAPITAL LETTER IZHITSA;Lu;0;L;;;;;N;;;;2C5B;
+2C2C;GLAGOLITIC CAPITAL LETTER SHTAPIC;Lu;0;L;;;;;N;;;;2C5C;
+2C2D;GLAGOLITIC CAPITAL LETTER TROKUTASTI A;Lu;0;L;;;;;N;;;;2C5D;
+2C2E;GLAGOLITIC CAPITAL LETTER LATINATE MYSLITE;Lu;0;L;;;;;N;;;;2C5E;
+2C30;GLAGOLITIC SMALL LETTER AZU;Ll;0;L;;;;;N;;;2C00;;2C00
+2C31;GLAGOLITIC SMALL LETTER BUKY;Ll;0;L;;;;;N;;;2C01;;2C01
+2C32;GLAGOLITIC SMALL LETTER VEDE;Ll;0;L;;;;;N;;;2C02;;2C02
+2C33;GLAGOLITIC SMALL LETTER GLAGOLI;Ll;0;L;;;;;N;;;2C03;;2C03
+2C34;GLAGOLITIC SMALL LETTER DOBRO;Ll;0;L;;;;;N;;;2C04;;2C04
+2C35;GLAGOLITIC SMALL LETTER YESTU;Ll;0;L;;;;;N;;;2C05;;2C05
+2C36;GLAGOLITIC SMALL LETTER ZHIVETE;Ll;0;L;;;;;N;;;2C06;;2C06
+2C37;GLAGOLITIC SMALL LETTER DZELO;Ll;0;L;;;;;N;;;2C07;;2C07
+2C38;GLAGOLITIC SMALL LETTER ZEMLJA;Ll;0;L;;;;;N;;;2C08;;2C08
+2C39;GLAGOLITIC SMALL LETTER IZHE;Ll;0;L;;;;;N;;;2C09;;2C09
+2C3A;GLAGOLITIC SMALL LETTER INITIAL IZHE;Ll;0;L;;;;;N;;;2C0A;;2C0A
+2C3B;GLAGOLITIC SMALL LETTER I;Ll;0;L;;;;;N;;;2C0B;;2C0B
+2C3C;GLAGOLITIC SMALL LETTER DJERVI;Ll;0;L;;;;;N;;;2C0C;;2C0C
+2C3D;GLAGOLITIC SMALL LETTER KAKO;Ll;0;L;;;;;N;;;2C0D;;2C0D
+2C3E;GLAGOLITIC SMALL LETTER LJUDIJE;Ll;0;L;;;;;N;;;2C0E;;2C0E
+2C3F;GLAGOLITIC SMALL LETTER MYSLITE;Ll;0;L;;;;;N;;;2C0F;;2C0F
+2C40;GLAGOLITIC SMALL LETTER NASHI;Ll;0;L;;;;;N;;;2C10;;2C10
+2C41;GLAGOLITIC SMALL LETTER ONU;Ll;0;L;;;;;N;;;2C11;;2C11
+2C42;GLAGOLITIC SMALL LETTER POKOJI;Ll;0;L;;;;;N;;;2C12;;2C12
+2C43;GLAGOLITIC SMALL LETTER RITSI;Ll;0;L;;;;;N;;;2C13;;2C13
+2C44;GLAGOLITIC SMALL LETTER SLOVO;Ll;0;L;;;;;N;;;2C14;;2C14
+2C45;GLAGOLITIC SMALL LETTER TVRIDO;Ll;0;L;;;;;N;;;2C15;;2C15
+2C46;GLAGOLITIC SMALL LETTER UKU;Ll;0;L;;;;;N;;;2C16;;2C16
+2C47;GLAGOLITIC SMALL LETTER FRITU;Ll;0;L;;;;;N;;;2C17;;2C17
+2C48;GLAGOLITIC SMALL LETTER HERU;Ll;0;L;;;;;N;;;2C18;;2C18
+2C49;GLAGOLITIC SMALL LETTER OTU;Ll;0;L;;;;;N;;;2C19;;2C19
+2C4A;GLAGOLITIC SMALL LETTER PE;Ll;0;L;;;;;N;;;2C1A;;2C1A
+2C4B;GLAGOLITIC SMALL LETTER SHTA;Ll;0;L;;;;;N;;;2C1B;;2C1B
+2C4C;GLAGOLITIC SMALL LETTER TSI;Ll;0;L;;;;;N;;;2C1C;;2C1C
+2C4D;GLAGOLITIC SMALL LETTER CHRIVI;Ll;0;L;;;;;N;;;2C1D;;2C1D
+2C4E;GLAGOLITIC SMALL LETTER SHA;Ll;0;L;;;;;N;;;2C1E;;2C1E
+2C4F;GLAGOLITIC SMALL LETTER YERU;Ll;0;L;;;;;N;;;2C1F;;2C1F
+2C50;GLAGOLITIC SMALL LETTER YERI;Ll;0;L;;;;;N;;;2C20;;2C20
+2C51;GLAGOLITIC SMALL LETTER YATI;Ll;0;L;;;;;N;;;2C21;;2C21
+2C52;GLAGOLITIC SMALL LETTER SPIDERY HA;Ll;0;L;;;;;N;;;2C22;;2C22
+2C53;GLAGOLITIC SMALL LETTER YU;Ll;0;L;;;;;N;;;2C23;;2C23
+2C54;GLAGOLITIC SMALL LETTER SMALL YUS;Ll;0;L;;;;;N;;;2C24;;2C24
+2C55;GLAGOLITIC SMALL LETTER SMALL YUS WITH TAIL;Ll;0;L;;;;;N;;;2C25;;2C25
+2C56;GLAGOLITIC SMALL LETTER YO;Ll;0;L;;;;;N;;;2C26;;2C26
+2C57;GLAGOLITIC SMALL LETTER IOTATED SMALL YUS;Ll;0;L;;;;;N;;;2C27;;2C27
+2C58;GLAGOLITIC SMALL LETTER BIG YUS;Ll;0;L;;;;;N;;;2C28;;2C28
+2C59;GLAGOLITIC SMALL LETTER IOTATED BIG YUS;Ll;0;L;;;;;N;;;2C29;;2C29
+2C5A;GLAGOLITIC SMALL LETTER FITA;Ll;0;L;;;;;N;;;2C2A;;2C2A
+2C5B;GLAGOLITIC SMALL LETTER IZHITSA;Ll;0;L;;;;;N;;;2C2B;;2C2B
+2C5C;GLAGOLITIC SMALL LETTER SHTAPIC;Ll;0;L;;;;;N;;;2C2C;;2C2C
+2C5D;GLAGOLITIC SMALL LETTER TROKUTASTI A;Ll;0;L;;;;;N;;;2C2D;;2C2D
+2C5E;GLAGOLITIC SMALL LETTER LATINATE MYSLITE;Ll;0;L;;;;;N;;;2C2E;;2C2E
+2C60;LATIN CAPITAL LETTER L WITH DOUBLE BAR;Lu;0;L;;;;;N;;;;2C61;
+2C61;LATIN SMALL LETTER L WITH DOUBLE BAR;Ll;0;L;;;;;N;;;2C60;;2C60
+2C62;LATIN CAPITAL LETTER L WITH MIDDLE TILDE;Lu;0;L;;;;;N;;;;026B;
+2C63;LATIN CAPITAL LETTER P WITH STROKE;Lu;0;L;;;;;N;;;;1D7D;
+2C64;LATIN CAPITAL LETTER R WITH TAIL;Lu;0;L;;;;;N;;;;027D;
+2C65;LATIN SMALL LETTER A WITH STROKE;Ll;0;L;;;;;N;;;023A;;023A
+2C66;LATIN SMALL LETTER T WITH DIAGONAL STROKE;Ll;0;L;;;;;N;;;023E;;023E
+2C67;LATIN CAPITAL LETTER H WITH DESCENDER;Lu;0;L;;;;;N;;;;2C68;
+2C68;LATIN SMALL LETTER H WITH DESCENDER;Ll;0;L;;;;;N;;;2C67;;2C67
+2C69;LATIN CAPITAL LETTER K WITH DESCENDER;Lu;0;L;;;;;N;;;;2C6A;
+2C6A;LATIN SMALL LETTER K WITH DESCENDER;Ll;0;L;;;;;N;;;2C69;;2C69
+2C6B;LATIN CAPITAL LETTER Z WITH DESCENDER;Lu;0;L;;;;;N;;;;2C6C;
+2C6C;LATIN SMALL LETTER Z WITH DESCENDER;Ll;0;L;;;;;N;;;2C6B;;2C6B
+2C6D;LATIN CAPITAL LETTER ALPHA;Lu;0;L;;;;;N;;;;0251;
+2C6E;LATIN CAPITAL LETTER M WITH HOOK;Lu;0;L;;;;;N;;;;0271;
+2C6F;LATIN CAPITAL LETTER TURNED A;Lu;0;L;;;;;N;;;;0250;
+2C70;LATIN CAPITAL LETTER TURNED ALPHA;Lu;0;L;;;;;N;;;;0252;
+2C71;LATIN SMALL LETTER V WITH RIGHT HOOK;Ll;0;L;;;;;N;;;;;
+2C72;LATIN CAPITAL LETTER W WITH HOOK;Lu;0;L;;;;;N;;;;2C73;
+2C73;LATIN SMALL LETTER W WITH HOOK;Ll;0;L;;;;;N;;;2C72;;2C72
+2C74;LATIN SMALL LETTER V WITH CURL;Ll;0;L;;;;;N;;;;;
+2C75;LATIN CAPITAL LETTER HALF H;Lu;0;L;;;;;N;;;;2C76;
+2C76;LATIN SMALL LETTER HALF H;Ll;0;L;;;;;N;;;2C75;;2C75
+2C77;LATIN SMALL LETTER TAILLESS PHI;Ll;0;L;;;;;N;;;;;
+2C78;LATIN SMALL LETTER E WITH NOTCH;Ll;0;L;;;;;N;;;;;
+2C79;LATIN SMALL LETTER TURNED R WITH TAIL;Ll;0;L;;;;;N;;;;;
+2C7A;LATIN SMALL LETTER O WITH LOW RING INSIDE;Ll;0;L;;;;;N;;;;;
+2C7B;LATIN LETTER SMALL CAPITAL TURNED E;Ll;0;L;;;;;N;;;;;
+2C7C;LATIN SUBSCRIPT SMALL LETTER J;Ll;0;L;<sub> 006A;;;;N;;;;;
+2C7D;MODIFIER LETTER CAPITAL V;Lm;0;L;<super> 0056;;;;N;;;;;
+2C7E;LATIN CAPITAL LETTER S WITH SWASH TAIL;Lu;0;L;;;;;N;;;;023F;
+2C7F;LATIN CAPITAL LETTER Z WITH SWASH TAIL;Lu;0;L;;;;;N;;;;0240;
+2C80;COPTIC CAPITAL LETTER ALFA;Lu;0;L;;;;;N;;;;2C81;
+2C81;COPTIC SMALL LETTER ALFA;Ll;0;L;;;;;N;;;2C80;;2C80
+2C82;COPTIC CAPITAL LETTER VIDA;Lu;0;L;;;;;N;;;;2C83;
+2C83;COPTIC SMALL LETTER VIDA;Ll;0;L;;;;;N;;;2C82;;2C82
+2C84;COPTIC CAPITAL LETTER GAMMA;Lu;0;L;;;;;N;;;;2C85;
+2C85;COPTIC SMALL LETTER GAMMA;Ll;0;L;;;;;N;;;2C84;;2C84
+2C86;COPTIC CAPITAL LETTER DALDA;Lu;0;L;;;;;N;;;;2C87;
+2C87;COPTIC SMALL LETTER DALDA;Ll;0;L;;;;;N;;;2C86;;2C86
+2C88;COPTIC CAPITAL LETTER EIE;Lu;0;L;;;;;N;;;;2C89;
+2C89;COPTIC SMALL LETTER EIE;Ll;0;L;;;;;N;;;2C88;;2C88
+2C8A;COPTIC CAPITAL LETTER SOU;Lu;0;L;;;;;N;;;;2C8B;
+2C8B;COPTIC SMALL LETTER SOU;Ll;0;L;;;;;N;;;2C8A;;2C8A
+2C8C;COPTIC CAPITAL LETTER ZATA;Lu;0;L;;;;;N;;;;2C8D;
+2C8D;COPTIC SMALL LETTER ZATA;Ll;0;L;;;;;N;;;2C8C;;2C8C
+2C8E;COPTIC CAPITAL LETTER HATE;Lu;0;L;;;;;N;;;;2C8F;
+2C8F;COPTIC SMALL LETTER HATE;Ll;0;L;;;;;N;;;2C8E;;2C8E
+2C90;COPTIC CAPITAL LETTER THETHE;Lu;0;L;;;;;N;;;;2C91;
+2C91;COPTIC SMALL LETTER THETHE;Ll;0;L;;;;;N;;;2C90;;2C90
+2C92;COPTIC CAPITAL LETTER IAUDA;Lu;0;L;;;;;N;;;;2C93;
+2C93;COPTIC SMALL LETTER IAUDA;Ll;0;L;;;;;N;;;2C92;;2C92
+2C94;COPTIC CAPITAL LETTER KAPA;Lu;0;L;;;;;N;;;;2C95;
+2C95;COPTIC SMALL LETTER KAPA;Ll;0;L;;;;;N;;;2C94;;2C94
+2C96;COPTIC CAPITAL LETTER LAULA;Lu;0;L;;;;;N;;;;2C97;
+2C97;COPTIC SMALL LETTER LAULA;Ll;0;L;;;;;N;;;2C96;;2C96
+2C98;COPTIC CAPITAL LETTER MI;Lu;0;L;;;;;N;;;;2C99;
+2C99;COPTIC SMALL LETTER MI;Ll;0;L;;;;;N;;;2C98;;2C98
+2C9A;COPTIC CAPITAL LETTER NI;Lu;0;L;;;;;N;;;;2C9B;
+2C9B;COPTIC SMALL LETTER NI;Ll;0;L;;;;;N;;;2C9A;;2C9A
+2C9C;COPTIC CAPITAL LETTER KSI;Lu;0;L;;;;;N;;;;2C9D;
+2C9D;COPTIC SMALL LETTER KSI;Ll;0;L;;;;;N;;;2C9C;;2C9C
+2C9E;COPTIC CAPITAL LETTER O;Lu;0;L;;;;;N;;;;2C9F;
+2C9F;COPTIC SMALL LETTER O;Ll;0;L;;;;;N;;;2C9E;;2C9E
+2CA0;COPTIC CAPITAL LETTER PI;Lu;0;L;;;;;N;;;;2CA1;
+2CA1;COPTIC SMALL LETTER PI;Ll;0;L;;;;;N;;;2CA0;;2CA0
+2CA2;COPTIC CAPITAL LETTER RO;Lu;0;L;;;;;N;;;;2CA3;
+2CA3;COPTIC SMALL LETTER RO;Ll;0;L;;;;;N;;;2CA2;;2CA2
+2CA4;COPTIC CAPITAL LETTER SIMA;Lu;0;L;;;;;N;;;;2CA5;
+2CA5;COPTIC SMALL LETTER SIMA;Ll;0;L;;;;;N;;;2CA4;;2CA4
+2CA6;COPTIC CAPITAL LETTER TAU;Lu;0;L;;;;;N;;;;2CA7;
+2CA7;COPTIC SMALL LETTER TAU;Ll;0;L;;;;;N;;;2CA6;;2CA6
+2CA8;COPTIC CAPITAL LETTER UA;Lu;0;L;;;;;N;;;;2CA9;
+2CA9;COPTIC SMALL LETTER UA;Ll;0;L;;;;;N;;;2CA8;;2CA8
+2CAA;COPTIC CAPITAL LETTER FI;Lu;0;L;;;;;N;;;;2CAB;
+2CAB;COPTIC SMALL LETTER FI;Ll;0;L;;;;;N;;;2CAA;;2CAA
+2CAC;COPTIC CAPITAL LETTER KHI;Lu;0;L;;;;;N;;;;2CAD;
+2CAD;COPTIC SMALL LETTER KHI;Ll;0;L;;;;;N;;;2CAC;;2CAC
+2CAE;COPTIC CAPITAL LETTER PSI;Lu;0;L;;;;;N;;;;2CAF;
+2CAF;COPTIC SMALL LETTER PSI;Ll;0;L;;;;;N;;;2CAE;;2CAE
+2CB0;COPTIC CAPITAL LETTER OOU;Lu;0;L;;;;;N;;;;2CB1;
+2CB1;COPTIC SMALL LETTER OOU;Ll;0;L;;;;;N;;;2CB0;;2CB0
+2CB2;COPTIC CAPITAL LETTER DIALECT-P ALEF;Lu;0;L;;;;;N;;;;2CB3;
+2CB3;COPTIC SMALL LETTER DIALECT-P ALEF;Ll;0;L;;;;;N;;;2CB2;;2CB2
+2CB4;COPTIC CAPITAL LETTER OLD COPTIC AIN;Lu;0;L;;;;;N;;;;2CB5;
+2CB5;COPTIC SMALL LETTER OLD COPTIC AIN;Ll;0;L;;;;;N;;;2CB4;;2CB4
+2CB6;COPTIC CAPITAL LETTER CRYPTOGRAMMIC EIE;Lu;0;L;;;;;N;;;;2CB7;
+2CB7;COPTIC SMALL LETTER CRYPTOGRAMMIC EIE;Ll;0;L;;;;;N;;;2CB6;;2CB6
+2CB8;COPTIC CAPITAL LETTER DIALECT-P KAPA;Lu;0;L;;;;;N;;;;2CB9;
+2CB9;COPTIC SMALL LETTER DIALECT-P KAPA;Ll;0;L;;;;;N;;;2CB8;;2CB8
+2CBA;COPTIC CAPITAL LETTER DIALECT-P NI;Lu;0;L;;;;;N;;;;2CBB;
+2CBB;COPTIC SMALL LETTER DIALECT-P NI;Ll;0;L;;;;;N;;;2CBA;;2CBA
+2CBC;COPTIC CAPITAL LETTER CRYPTOGRAMMIC NI;Lu;0;L;;;;;N;;;;2CBD;
+2CBD;COPTIC SMALL LETTER CRYPTOGRAMMIC NI;Ll;0;L;;;;;N;;;2CBC;;2CBC
+2CBE;COPTIC CAPITAL LETTER OLD COPTIC OOU;Lu;0;L;;;;;N;;;;2CBF;
+2CBF;COPTIC SMALL LETTER OLD COPTIC OOU;Ll;0;L;;;;;N;;;2CBE;;2CBE
+2CC0;COPTIC CAPITAL LETTER SAMPI;Lu;0;L;;;;;N;;;;2CC1;
+2CC1;COPTIC SMALL LETTER SAMPI;Ll;0;L;;;;;N;;;2CC0;;2CC0
+2CC2;COPTIC CAPITAL LETTER CROSSED SHEI;Lu;0;L;;;;;N;;;;2CC3;
+2CC3;COPTIC SMALL LETTER CROSSED SHEI;Ll;0;L;;;;;N;;;2CC2;;2CC2
+2CC4;COPTIC CAPITAL LETTER OLD COPTIC SHEI;Lu;0;L;;;;;N;;;;2CC5;
+2CC5;COPTIC SMALL LETTER OLD COPTIC SHEI;Ll;0;L;;;;;N;;;2CC4;;2CC4
+2CC6;COPTIC CAPITAL LETTER OLD COPTIC ESH;Lu;0;L;;;;;N;;;;2CC7;
+2CC7;COPTIC SMALL LETTER OLD COPTIC ESH;Ll;0;L;;;;;N;;;2CC6;;2CC6
+2CC8;COPTIC CAPITAL LETTER AKHMIMIC KHEI;Lu;0;L;;;;;N;;;;2CC9;
+2CC9;COPTIC SMALL LETTER AKHMIMIC KHEI;Ll;0;L;;;;;N;;;2CC8;;2CC8
+2CCA;COPTIC CAPITAL LETTER DIALECT-P HORI;Lu;0;L;;;;;N;;;;2CCB;
+2CCB;COPTIC SMALL LETTER DIALECT-P HORI;Ll;0;L;;;;;N;;;2CCA;;2CCA
+2CCC;COPTIC CAPITAL LETTER OLD COPTIC HORI;Lu;0;L;;;;;N;;;;2CCD;
+2CCD;COPTIC SMALL LETTER OLD COPTIC HORI;Ll;0;L;;;;;N;;;2CCC;;2CCC
+2CCE;COPTIC CAPITAL LETTER OLD COPTIC HA;Lu;0;L;;;;;N;;;;2CCF;
+2CCF;COPTIC SMALL LETTER OLD COPTIC HA;Ll;0;L;;;;;N;;;2CCE;;2CCE
+2CD0;COPTIC CAPITAL LETTER L-SHAPED HA;Lu;0;L;;;;;N;;;;2CD1;
+2CD1;COPTIC SMALL LETTER L-SHAPED HA;Ll;0;L;;;;;N;;;2CD0;;2CD0
+2CD2;COPTIC CAPITAL LETTER OLD COPTIC HEI;Lu;0;L;;;;;N;;;;2CD3;
+2CD3;COPTIC SMALL LETTER OLD COPTIC HEI;Ll;0;L;;;;;N;;;2CD2;;2CD2
+2CD4;COPTIC CAPITAL LETTER OLD COPTIC HAT;Lu;0;L;;;;;N;;;;2CD5;
+2CD5;COPTIC SMALL LETTER OLD COPTIC HAT;Ll;0;L;;;;;N;;;2CD4;;2CD4
+2CD6;COPTIC CAPITAL LETTER OLD COPTIC GANGIA;Lu;0;L;;;;;N;;;;2CD7;
+2CD7;COPTIC SMALL LETTER OLD COPTIC GANGIA;Ll;0;L;;;;;N;;;2CD6;;2CD6
+2CD8;COPTIC CAPITAL LETTER OLD COPTIC DJA;Lu;0;L;;;;;N;;;;2CD9;
+2CD9;COPTIC SMALL LETTER OLD COPTIC DJA;Ll;0;L;;;;;N;;;2CD8;;2CD8
+2CDA;COPTIC CAPITAL LETTER OLD COPTIC SHIMA;Lu;0;L;;;;;N;;;;2CDB;
+2CDB;COPTIC SMALL LETTER OLD COPTIC SHIMA;Ll;0;L;;;;;N;;;2CDA;;2CDA
+2CDC;COPTIC CAPITAL LETTER OLD NUBIAN SHIMA;Lu;0;L;;;;;N;;;;2CDD;
+2CDD;COPTIC SMALL LETTER OLD NUBIAN SHIMA;Ll;0;L;;;;;N;;;2CDC;;2CDC
+2CDE;COPTIC CAPITAL LETTER OLD NUBIAN NGI;Lu;0;L;;;;;N;;;;2CDF;
+2CDF;COPTIC SMALL LETTER OLD NUBIAN NGI;Ll;0;L;;;;;N;;;2CDE;;2CDE
+2CE0;COPTIC CAPITAL LETTER OLD NUBIAN NYI;Lu;0;L;;;;;N;;;;2CE1;
+2CE1;COPTIC SMALL LETTER OLD NUBIAN NYI;Ll;0;L;;;;;N;;;2CE0;;2CE0
+2CE2;COPTIC CAPITAL LETTER OLD NUBIAN WAU;Lu;0;L;;;;;N;;;;2CE3;
+2CE3;COPTIC SMALL LETTER OLD NUBIAN WAU;Ll;0;L;;;;;N;;;2CE2;;2CE2
+2CE4;COPTIC SYMBOL KAI;Ll;0;L;;;;;N;;;;;
+2CE5;COPTIC SYMBOL MI RO;So;0;ON;;;;;N;;;;;
+2CE6;COPTIC SYMBOL PI RO;So;0;ON;;;;;N;;;;;
+2CE7;COPTIC SYMBOL STAUROS;So;0;ON;;;;;N;;;;;
+2CE8;COPTIC SYMBOL TAU RO;So;0;ON;;;;;N;;;;;
+2CE9;COPTIC SYMBOL KHI RO;So;0;ON;;;;;N;;;;;
+2CEA;COPTIC SYMBOL SHIMA SIMA;So;0;ON;;;;;N;;;;;
+2CEB;COPTIC CAPITAL LETTER CRYPTOGRAMMIC SHEI;Lu;0;L;;;;;N;;;;2CEC;
+2CEC;COPTIC SMALL LETTER CRYPTOGRAMMIC SHEI;Ll;0;L;;;;;N;;;2CEB;;2CEB
+2CED;COPTIC CAPITAL LETTER CRYPTOGRAMMIC GANGIA;Lu;0;L;;;;;N;;;;2CEE;
+2CEE;COPTIC SMALL LETTER CRYPTOGRAMMIC GANGIA;Ll;0;L;;;;;N;;;2CED;;2CED
+2CEF;COPTIC COMBINING NI ABOVE;Mn;230;NSM;;;;;N;;;;;
+2CF0;COPTIC COMBINING SPIRITUS ASPER;Mn;230;NSM;;;;;N;;;;;
+2CF1;COPTIC COMBINING SPIRITUS LENIS;Mn;230;NSM;;;;;N;;;;;
+2CF9;COPTIC OLD NUBIAN FULL STOP;Po;0;ON;;;;;N;;;;;
+2CFA;COPTIC OLD NUBIAN DIRECT QUESTION MARK;Po;0;ON;;;;;N;;;;;
+2CFB;COPTIC OLD NUBIAN INDIRECT QUESTION MARK;Po;0;ON;;;;;N;;;;;
+2CFC;COPTIC OLD NUBIAN VERSE DIVIDER;Po;0;ON;;;;;N;;;;;
+2CFD;COPTIC FRACTION ONE HALF;No;0;ON;;;;1/2;N;;;;;
+2CFE;COPTIC FULL STOP;Po;0;ON;;;;;N;;;;;
+2CFF;COPTIC MORPHOLOGICAL DIVIDER;Po;0;ON;;;;;N;;;;;
+2D00;GEORGIAN SMALL LETTER AN;Ll;0;L;;;;;N;;;10A0;;10A0
+2D01;GEORGIAN SMALL LETTER BAN;Ll;0;L;;;;;N;;;10A1;;10A1
+2D02;GEORGIAN SMALL LETTER GAN;Ll;0;L;;;;;N;;;10A2;;10A2
+2D03;GEORGIAN SMALL LETTER DON;Ll;0;L;;;;;N;;;10A3;;10A3
+2D04;GEORGIAN SMALL LETTER EN;Ll;0;L;;;;;N;;;10A4;;10A4
+2D05;GEORGIAN SMALL LETTER VIN;Ll;0;L;;;;;N;;;10A5;;10A5
+2D06;GEORGIAN SMALL LETTER ZEN;Ll;0;L;;;;;N;;;10A6;;10A6
+2D07;GEORGIAN SMALL LETTER TAN;Ll;0;L;;;;;N;;;10A7;;10A7
+2D08;GEORGIAN SMALL LETTER IN;Ll;0;L;;;;;N;;;10A8;;10A8
+2D09;GEORGIAN SMALL LETTER KAN;Ll;0;L;;;;;N;;;10A9;;10A9
+2D0A;GEORGIAN SMALL LETTER LAS;Ll;0;L;;;;;N;;;10AA;;10AA
+2D0B;GEORGIAN SMALL LETTER MAN;Ll;0;L;;;;;N;;;10AB;;10AB
+2D0C;GEORGIAN SMALL LETTER NAR;Ll;0;L;;;;;N;;;10AC;;10AC
+2D0D;GEORGIAN SMALL LETTER ON;Ll;0;L;;;;;N;;;10AD;;10AD
+2D0E;GEORGIAN SMALL LETTER PAR;Ll;0;L;;;;;N;;;10AE;;10AE
+2D0F;GEORGIAN SMALL LETTER ZHAR;Ll;0;L;;;;;N;;;10AF;;10AF
+2D10;GEORGIAN SMALL LETTER RAE;Ll;0;L;;;;;N;;;10B0;;10B0
+2D11;GEORGIAN SMALL LETTER SAN;Ll;0;L;;;;;N;;;10B1;;10B1
+2D12;GEORGIAN SMALL LETTER TAR;Ll;0;L;;;;;N;;;10B2;;10B2
+2D13;GEORGIAN SMALL LETTER UN;Ll;0;L;;;;;N;;;10B3;;10B3
+2D14;GEORGIAN SMALL LETTER PHAR;Ll;0;L;;;;;N;;;10B4;;10B4
+2D15;GEORGIAN SMALL LETTER KHAR;Ll;0;L;;;;;N;;;10B5;;10B5
+2D16;GEORGIAN SMALL LETTER GHAN;Ll;0;L;;;;;N;;;10B6;;10B6
+2D17;GEORGIAN SMALL LETTER QAR;Ll;0;L;;;;;N;;;10B7;;10B7
+2D18;GEORGIAN SMALL LETTER SHIN;Ll;0;L;;;;;N;;;10B8;;10B8
+2D19;GEORGIAN SMALL LETTER CHIN;Ll;0;L;;;;;N;;;10B9;;10B9
+2D1A;GEORGIAN SMALL LETTER CAN;Ll;0;L;;;;;N;;;10BA;;10BA
+2D1B;GEORGIAN SMALL LETTER JIL;Ll;0;L;;;;;N;;;10BB;;10BB
+2D1C;GEORGIAN SMALL LETTER CIL;Ll;0;L;;;;;N;;;10BC;;10BC
+2D1D;GEORGIAN SMALL LETTER CHAR;Ll;0;L;;;;;N;;;10BD;;10BD
+2D1E;GEORGIAN SMALL LETTER XAN;Ll;0;L;;;;;N;;;10BE;;10BE
+2D1F;GEORGIAN SMALL LETTER JHAN;Ll;0;L;;;;;N;;;10BF;;10BF
+2D20;GEORGIAN SMALL LETTER HAE;Ll;0;L;;;;;N;;;10C0;;10C0
+2D21;GEORGIAN SMALL LETTER HE;Ll;0;L;;;;;N;;;10C1;;10C1
+2D22;GEORGIAN SMALL LETTER HIE;Ll;0;L;;;;;N;;;10C2;;10C2
+2D23;GEORGIAN SMALL LETTER WE;Ll;0;L;;;;;N;;;10C3;;10C3
+2D24;GEORGIAN SMALL LETTER HAR;Ll;0;L;;;;;N;;;10C4;;10C4
+2D25;GEORGIAN SMALL LETTER HOE;Ll;0;L;;;;;N;;;10C5;;10C5
+2D30;TIFINAGH LETTER YA;Lo;0;L;;;;;N;;;;;
+2D31;TIFINAGH LETTER YAB;Lo;0;L;;;;;N;;;;;
+2D32;TIFINAGH LETTER YABH;Lo;0;L;;;;;N;;;;;
+2D33;TIFINAGH LETTER YAG;Lo;0;L;;;;;N;;;;;
+2D34;TIFINAGH LETTER YAGHH;Lo;0;L;;;;;N;;;;;
+2D35;TIFINAGH LETTER BERBER ACADEMY YAJ;Lo;0;L;;;;;N;;;;;
+2D36;TIFINAGH LETTER YAJ;Lo;0;L;;;;;N;;;;;
+2D37;TIFINAGH LETTER YAD;Lo;0;L;;;;;N;;;;;
+2D38;TIFINAGH LETTER YADH;Lo;0;L;;;;;N;;;;;
+2D39;TIFINAGH LETTER YADD;Lo;0;L;;;;;N;;;;;
+2D3A;TIFINAGH LETTER YADDH;Lo;0;L;;;;;N;;;;;
+2D3B;TIFINAGH LETTER YEY;Lo;0;L;;;;;N;;;;;
+2D3C;TIFINAGH LETTER YAF;Lo;0;L;;;;;N;;;;;
+2D3D;TIFINAGH LETTER YAK;Lo;0;L;;;;;N;;;;;
+2D3E;TIFINAGH LETTER TUAREG YAK;Lo;0;L;;;;;N;;;;;
+2D3F;TIFINAGH LETTER YAKHH;Lo;0;L;;;;;N;;;;;
+2D40;TIFINAGH LETTER YAH;Lo;0;L;;;;;N;;;;;
+2D41;TIFINAGH LETTER BERBER ACADEMY YAH;Lo;0;L;;;;;N;;;;;
+2D42;TIFINAGH LETTER TUAREG YAH;Lo;0;L;;;;;N;;;;;
+2D43;TIFINAGH LETTER YAHH;Lo;0;L;;;;;N;;;;;
+2D44;TIFINAGH LETTER YAA;Lo;0;L;;;;;N;;;;;
+2D45;TIFINAGH LETTER YAKH;Lo;0;L;;;;;N;;;;;
+2D46;TIFINAGH LETTER TUAREG YAKH;Lo;0;L;;;;;N;;;;;
+2D47;TIFINAGH LETTER YAQ;Lo;0;L;;;;;N;;;;;
+2D48;TIFINAGH LETTER TUAREG YAQ;Lo;0;L;;;;;N;;;;;
+2D49;TIFINAGH LETTER YI;Lo;0;L;;;;;N;;;;;
+2D4A;TIFINAGH LETTER YAZH;Lo;0;L;;;;;N;;;;;
+2D4B;TIFINAGH LETTER AHAGGAR YAZH;Lo;0;L;;;;;N;;;;;
+2D4C;TIFINAGH LETTER TUAREG YAZH;Lo;0;L;;;;;N;;;;;
+2D4D;TIFINAGH LETTER YAL;Lo;0;L;;;;;N;;;;;
+2D4E;TIFINAGH LETTER YAM;Lo;0;L;;;;;N;;;;;
+2D4F;TIFINAGH LETTER YAN;Lo;0;L;;;;;N;;;;;
+2D50;TIFINAGH LETTER TUAREG YAGN;Lo;0;L;;;;;N;;;;;
+2D51;TIFINAGH LETTER TUAREG YANG;Lo;0;L;;;;;N;;;;;
+2D52;TIFINAGH LETTER YAP;Lo;0;L;;;;;N;;;;;
+2D53;TIFINAGH LETTER YU;Lo;0;L;;;;;N;;;;;
+2D54;TIFINAGH LETTER YAR;Lo;0;L;;;;;N;;;;;
+2D55;TIFINAGH LETTER YARR;Lo;0;L;;;;;N;;;;;
+2D56;TIFINAGH LETTER YAGH;Lo;0;L;;;;;N;;;;;
+2D57;TIFINAGH LETTER TUAREG YAGH;Lo;0;L;;;;;N;;;;;
+2D58;TIFINAGH LETTER AYER YAGH;Lo;0;L;;;;;N;;;;;
+2D59;TIFINAGH LETTER YAS;Lo;0;L;;;;;N;;;;;
+2D5A;TIFINAGH LETTER YASS;Lo;0;L;;;;;N;;;;;
+2D5B;TIFINAGH LETTER YASH;Lo;0;L;;;;;N;;;;;
+2D5C;TIFINAGH LETTER YAT;Lo;0;L;;;;;N;;;;;
+2D5D;TIFINAGH LETTER YATH;Lo;0;L;;;;;N;;;;;
+2D5E;TIFINAGH LETTER YACH;Lo;0;L;;;;;N;;;;;
+2D5F;TIFINAGH LETTER YATT;Lo;0;L;;;;;N;;;;;
+2D60;TIFINAGH LETTER YAV;Lo;0;L;;;;;N;;;;;
+2D61;TIFINAGH LETTER YAW;Lo;0;L;;;;;N;;;;;
+2D62;TIFINAGH LETTER YAY;Lo;0;L;;;;;N;;;;;
+2D63;TIFINAGH LETTER YAZ;Lo;0;L;;;;;N;;;;;
+2D64;TIFINAGH LETTER TAWELLEMET YAZ;Lo;0;L;;;;;N;;;;;
+2D65;TIFINAGH LETTER YAZZ;Lo;0;L;;;;;N;;;;;
+2D6F;TIFINAGH MODIFIER LETTER LABIALIZATION MARK;Lm;0;L;<super> 2D61;;;;N;;;;;
+2D70;TIFINAGH SEPARATOR MARK;Po;0;L;;;;;N;;;;;
+2D7F;TIFINAGH CONSONANT JOINER;Mn;9;NSM;;;;;N;;;;;
+2D80;ETHIOPIC SYLLABLE LOA;Lo;0;L;;;;;N;;;;;
+2D81;ETHIOPIC SYLLABLE MOA;Lo;0;L;;;;;N;;;;;
+2D82;ETHIOPIC SYLLABLE ROA;Lo;0;L;;;;;N;;;;;
+2D83;ETHIOPIC SYLLABLE SOA;Lo;0;L;;;;;N;;;;;
+2D84;ETHIOPIC SYLLABLE SHOA;Lo;0;L;;;;;N;;;;;
+2D85;ETHIOPIC SYLLABLE BOA;Lo;0;L;;;;;N;;;;;
+2D86;ETHIOPIC SYLLABLE TOA;Lo;0;L;;;;;N;;;;;
+2D87;ETHIOPIC SYLLABLE COA;Lo;0;L;;;;;N;;;;;
+2D88;ETHIOPIC SYLLABLE NOA;Lo;0;L;;;;;N;;;;;
+2D89;ETHIOPIC SYLLABLE NYOA;Lo;0;L;;;;;N;;;;;
+2D8A;ETHIOPIC SYLLABLE GLOTTAL OA;Lo;0;L;;;;;N;;;;;
+2D8B;ETHIOPIC SYLLABLE ZOA;Lo;0;L;;;;;N;;;;;
+2D8C;ETHIOPIC SYLLABLE DOA;Lo;0;L;;;;;N;;;;;
+2D8D;ETHIOPIC SYLLABLE DDOA;Lo;0;L;;;;;N;;;;;
+2D8E;ETHIOPIC SYLLABLE JOA;Lo;0;L;;;;;N;;;;;
+2D8F;ETHIOPIC SYLLABLE THOA;Lo;0;L;;;;;N;;;;;
+2D90;ETHIOPIC SYLLABLE CHOA;Lo;0;L;;;;;N;;;;;
+2D91;ETHIOPIC SYLLABLE PHOA;Lo;0;L;;;;;N;;;;;
+2D92;ETHIOPIC SYLLABLE POA;Lo;0;L;;;;;N;;;;;
+2D93;ETHIOPIC SYLLABLE GGWA;Lo;0;L;;;;;N;;;;;
+2D94;ETHIOPIC SYLLABLE GGWI;Lo;0;L;;;;;N;;;;;
+2D95;ETHIOPIC SYLLABLE GGWEE;Lo;0;L;;;;;N;;;;;
+2D96;ETHIOPIC SYLLABLE GGWE;Lo;0;L;;;;;N;;;;;
+2DA0;ETHIOPIC SYLLABLE SSA;Lo;0;L;;;;;N;;;;;
+2DA1;ETHIOPIC SYLLABLE SSU;Lo;0;L;;;;;N;;;;;
+2DA2;ETHIOPIC SYLLABLE SSI;Lo;0;L;;;;;N;;;;;
+2DA3;ETHIOPIC SYLLABLE SSAA;Lo;0;L;;;;;N;;;;;
+2DA4;ETHIOPIC SYLLABLE SSEE;Lo;0;L;;;;;N;;;;;
+2DA5;ETHIOPIC SYLLABLE SSE;Lo;0;L;;;;;N;;;;;
+2DA6;ETHIOPIC SYLLABLE SSO;Lo;0;L;;;;;N;;;;;
+2DA8;ETHIOPIC SYLLABLE CCA;Lo;0;L;;;;;N;;;;;
+2DA9;ETHIOPIC SYLLABLE CCU;Lo;0;L;;;;;N;;;;;
+2DAA;ETHIOPIC SYLLABLE CCI;Lo;0;L;;;;;N;;;;;
+2DAB;ETHIOPIC SYLLABLE CCAA;Lo;0;L;;;;;N;;;;;
+2DAC;ETHIOPIC SYLLABLE CCEE;Lo;0;L;;;;;N;;;;;
+2DAD;ETHIOPIC SYLLABLE CCE;Lo;0;L;;;;;N;;;;;
+2DAE;ETHIOPIC SYLLABLE CCO;Lo;0;L;;;;;N;;;;;
+2DB0;ETHIOPIC SYLLABLE ZZA;Lo;0;L;;;;;N;;;;;
+2DB1;ETHIOPIC SYLLABLE ZZU;Lo;0;L;;;;;N;;;;;
+2DB2;ETHIOPIC SYLLABLE ZZI;Lo;0;L;;;;;N;;;;;
+2DB3;ETHIOPIC SYLLABLE ZZAA;Lo;0;L;;;;;N;;;;;
+2DB4;ETHIOPIC SYLLABLE ZZEE;Lo;0;L;;;;;N;;;;;
+2DB5;ETHIOPIC SYLLABLE ZZE;Lo;0;L;;;;;N;;;;;
+2DB6;ETHIOPIC SYLLABLE ZZO;Lo;0;L;;;;;N;;;;;
+2DB8;ETHIOPIC SYLLABLE CCHA;Lo;0;L;;;;;N;;;;;
+2DB9;ETHIOPIC SYLLABLE CCHU;Lo;0;L;;;;;N;;;;;
+2DBA;ETHIOPIC SYLLABLE CCHI;Lo;0;L;;;;;N;;;;;
+2DBB;ETHIOPIC SYLLABLE CCHAA;Lo;0;L;;;;;N;;;;;
+2DBC;ETHIOPIC SYLLABLE CCHEE;Lo;0;L;;;;;N;;;;;
+2DBD;ETHIOPIC SYLLABLE CCHE;Lo;0;L;;;;;N;;;;;
+2DBE;ETHIOPIC SYLLABLE CCHO;Lo;0;L;;;;;N;;;;;
+2DC0;ETHIOPIC SYLLABLE QYA;Lo;0;L;;;;;N;;;;;
+2DC1;ETHIOPIC SYLLABLE QYU;Lo;0;L;;;;;N;;;;;
+2DC2;ETHIOPIC SYLLABLE QYI;Lo;0;L;;;;;N;;;;;
+2DC3;ETHIOPIC SYLLABLE QYAA;Lo;0;L;;;;;N;;;;;
+2DC4;ETHIOPIC SYLLABLE QYEE;Lo;0;L;;;;;N;;;;;
+2DC5;ETHIOPIC SYLLABLE QYE;Lo;0;L;;;;;N;;;;;
+2DC6;ETHIOPIC SYLLABLE QYO;Lo;0;L;;;;;N;;;;;
+2DC8;ETHIOPIC SYLLABLE KYA;Lo;0;L;;;;;N;;;;;
+2DC9;ETHIOPIC SYLLABLE KYU;Lo;0;L;;;;;N;;;;;
+2DCA;ETHIOPIC SYLLABLE KYI;Lo;0;L;;;;;N;;;;;
+2DCB;ETHIOPIC SYLLABLE KYAA;Lo;0;L;;;;;N;;;;;
+2DCC;ETHIOPIC SYLLABLE KYEE;Lo;0;L;;;;;N;;;;;
+2DCD;ETHIOPIC SYLLABLE KYE;Lo;0;L;;;;;N;;;;;
+2DCE;ETHIOPIC SYLLABLE KYO;Lo;0;L;;;;;N;;;;;
+2DD0;ETHIOPIC SYLLABLE XYA;Lo;0;L;;;;;N;;;;;
+2DD1;ETHIOPIC SYLLABLE XYU;Lo;0;L;;;;;N;;;;;
+2DD2;ETHIOPIC SYLLABLE XYI;Lo;0;L;;;;;N;;;;;
+2DD3;ETHIOPIC SYLLABLE XYAA;Lo;0;L;;;;;N;;;;;
+2DD4;ETHIOPIC SYLLABLE XYEE;Lo;0;L;;;;;N;;;;;
+2DD5;ETHIOPIC SYLLABLE XYE;Lo;0;L;;;;;N;;;;;
+2DD6;ETHIOPIC SYLLABLE XYO;Lo;0;L;;;;;N;;;;;
+2DD8;ETHIOPIC SYLLABLE GYA;Lo;0;L;;;;;N;;;;;
+2DD9;ETHIOPIC SYLLABLE GYU;Lo;0;L;;;;;N;;;;;
+2DDA;ETHIOPIC SYLLABLE GYI;Lo;0;L;;;;;N;;;;;
+2DDB;ETHIOPIC SYLLABLE GYAA;Lo;0;L;;;;;N;;;;;
+2DDC;ETHIOPIC SYLLABLE GYEE;Lo;0;L;;;;;N;;;;;
+2DDD;ETHIOPIC SYLLABLE GYE;Lo;0;L;;;;;N;;;;;
+2DDE;ETHIOPIC SYLLABLE GYO;Lo;0;L;;;;;N;;;;;
+2DE0;COMBINING CYRILLIC LETTER BE;Mn;230;NSM;;;;;N;;;;;
+2DE1;COMBINING CYRILLIC LETTER VE;Mn;230;NSM;;;;;N;;;;;
+2DE2;COMBINING CYRILLIC LETTER GHE;Mn;230;NSM;;;;;N;;;;;
+2DE3;COMBINING CYRILLIC LETTER DE;Mn;230;NSM;;;;;N;;;;;
+2DE4;COMBINING CYRILLIC LETTER ZHE;Mn;230;NSM;;;;;N;;;;;
+2DE5;COMBINING CYRILLIC LETTER ZE;Mn;230;NSM;;;;;N;;;;;
+2DE6;COMBINING CYRILLIC LETTER KA;Mn;230;NSM;;;;;N;;;;;
+2DE7;COMBINING CYRILLIC LETTER EL;Mn;230;NSM;;;;;N;;;;;
+2DE8;COMBINING CYRILLIC LETTER EM;Mn;230;NSM;;;;;N;;;;;
+2DE9;COMBINING CYRILLIC LETTER EN;Mn;230;NSM;;;;;N;;;;;
+2DEA;COMBINING CYRILLIC LETTER O;Mn;230;NSM;;;;;N;;;;;
+2DEB;COMBINING CYRILLIC LETTER PE;Mn;230;NSM;;;;;N;;;;;
+2DEC;COMBINING CYRILLIC LETTER ER;Mn;230;NSM;;;;;N;;;;;
+2DED;COMBINING CYRILLIC LETTER ES;Mn;230;NSM;;;;;N;;;;;
+2DEE;COMBINING CYRILLIC LETTER TE;Mn;230;NSM;;;;;N;;;;;
+2DEF;COMBINING CYRILLIC LETTER HA;Mn;230;NSM;;;;;N;;;;;
+2DF0;COMBINING CYRILLIC LETTER TSE;Mn;230;NSM;;;;;N;;;;;
+2DF1;COMBINING CYRILLIC LETTER CHE;Mn;230;NSM;;;;;N;;;;;
+2DF2;COMBINING CYRILLIC LETTER SHA;Mn;230;NSM;;;;;N;;;;;
+2DF3;COMBINING CYRILLIC LETTER SHCHA;Mn;230;NSM;;;;;N;;;;;
+2DF4;COMBINING CYRILLIC LETTER FITA;Mn;230;NSM;;;;;N;;;;;
+2DF5;COMBINING CYRILLIC LETTER ES-TE;Mn;230;NSM;;;;;N;;;;;
+2DF6;COMBINING CYRILLIC LETTER A;Mn;230;NSM;;;;;N;;;;;
+2DF7;COMBINING CYRILLIC LETTER IE;Mn;230;NSM;;;;;N;;;;;
+2DF8;COMBINING CYRILLIC LETTER DJERV;Mn;230;NSM;;;;;N;;;;;
+2DF9;COMBINING CYRILLIC LETTER MONOGRAPH UK;Mn;230;NSM;;;;;N;;;;;
+2DFA;COMBINING CYRILLIC LETTER YAT;Mn;230;NSM;;;;;N;;;;;
+2DFB;COMBINING CYRILLIC LETTER YU;Mn;230;NSM;;;;;N;;;;;
+2DFC;COMBINING CYRILLIC LETTER IOTIFIED A;Mn;230;NSM;;;;;N;;;;;
+2DFD;COMBINING CYRILLIC LETTER LITTLE YUS;Mn;230;NSM;;;;;N;;;;;
+2DFE;COMBINING CYRILLIC LETTER BIG YUS;Mn;230;NSM;;;;;N;;;;;
+2DFF;COMBINING CYRILLIC LETTER IOTIFIED BIG YUS;Mn;230;NSM;;;;;N;;;;;
+2E00;RIGHT ANGLE SUBSTITUTION MARKER;Po;0;ON;;;;;N;;;;;
+2E01;RIGHT ANGLE DOTTED SUBSTITUTION MARKER;Po;0;ON;;;;;N;;;;;
+2E02;LEFT SUBSTITUTION BRACKET;Pi;0;ON;;;;;Y;;;;;
+2E03;RIGHT SUBSTITUTION BRACKET;Pf;0;ON;;;;;Y;;;;;
+2E04;LEFT DOTTED SUBSTITUTION BRACKET;Pi;0;ON;;;;;Y;;;;;
+2E05;RIGHT DOTTED SUBSTITUTION BRACKET;Pf;0;ON;;;;;Y;;;;;
+2E06;RAISED INTERPOLATION MARKER;Po;0;ON;;;;;N;;;;;
+2E07;RAISED DOTTED INTERPOLATION MARKER;Po;0;ON;;;;;N;;;;;
+2E08;DOTTED TRANSPOSITION MARKER;Po;0;ON;;;;;N;;;;;
+2E09;LEFT TRANSPOSITION BRACKET;Pi;0;ON;;;;;Y;;;;;
+2E0A;RIGHT TRANSPOSITION BRACKET;Pf;0;ON;;;;;Y;;;;;
+2E0B;RAISED SQUARE;Po;0;ON;;;;;N;;;;;
+2E0C;LEFT RAISED OMISSION BRACKET;Pi;0;ON;;;;;Y;;;;;
+2E0D;RIGHT RAISED OMISSION BRACKET;Pf;0;ON;;;;;Y;;;;;
+2E0E;EDITORIAL CORONIS;Po;0;ON;;;;;N;;;;;
+2E0F;PARAGRAPHOS;Po;0;ON;;;;;N;;;;;
+2E10;FORKED PARAGRAPHOS;Po;0;ON;;;;;N;;;;;
+2E11;REVERSED FORKED PARAGRAPHOS;Po;0;ON;;;;;N;;;;;
+2E12;HYPODIASTOLE;Po;0;ON;;;;;N;;;;;
+2E13;DOTTED OBELOS;Po;0;ON;;;;;N;;;;;
+2E14;DOWNWARDS ANCORA;Po;0;ON;;;;;N;;;;;
+2E15;UPWARDS ANCORA;Po;0;ON;;;;;N;;;;;
+2E16;DOTTED RIGHT-POINTING ANGLE;Po;0;ON;;;;;N;;;;;
+2E17;DOUBLE OBLIQUE HYPHEN;Pd;0;ON;;;;;N;;;;;
+2E18;INVERTED INTERROBANG;Po;0;ON;;;;;N;;;;;
+2E19;PALM BRANCH;Po;0;ON;;;;;N;;;;;
+2E1A;HYPHEN WITH DIAERESIS;Pd;0;ON;;;;;N;;;;;
+2E1B;TILDE WITH RING ABOVE;Po;0;ON;;;;;N;;;;;
+2E1C;LEFT LOW PARAPHRASE BRACKET;Pi;0;ON;;;;;Y;;;;;
+2E1D;RIGHT LOW PARAPHRASE BRACKET;Pf;0;ON;;;;;Y;;;;;
+2E1E;TILDE WITH DOT ABOVE;Po;0;ON;;;;;N;;;;;
+2E1F;TILDE WITH DOT BELOW;Po;0;ON;;;;;N;;;;;
+2E20;LEFT VERTICAL BAR WITH QUILL;Pi;0;ON;;;;;Y;;;;;
+2E21;RIGHT VERTICAL BAR WITH QUILL;Pf;0;ON;;;;;Y;;;;;
+2E22;TOP LEFT HALF BRACKET;Ps;0;ON;;;;;Y;;;;;
+2E23;TOP RIGHT HALF BRACKET;Pe;0;ON;;;;;Y;;;;;
+2E24;BOTTOM LEFT HALF BRACKET;Ps;0;ON;;;;;Y;;;;;
+2E25;BOTTOM RIGHT HALF BRACKET;Pe;0;ON;;;;;Y;;;;;
+2E26;LEFT SIDEWAYS U BRACKET;Ps;0;ON;;;;;Y;;;;;
+2E27;RIGHT SIDEWAYS U BRACKET;Pe;0;ON;;;;;Y;;;;;
+2E28;LEFT DOUBLE PARENTHESIS;Ps;0;ON;;;;;Y;;;;;
+2E29;RIGHT DOUBLE PARENTHESIS;Pe;0;ON;;;;;Y;;;;;
+2E2A;TWO DOTS OVER ONE DOT PUNCTUATION;Po;0;ON;;;;;N;;;;;
+2E2B;ONE DOT OVER TWO DOTS PUNCTUATION;Po;0;ON;;;;;N;;;;;
+2E2C;SQUARED FOUR DOT PUNCTUATION;Po;0;ON;;;;;N;;;;;
+2E2D;FIVE DOT MARK;Po;0;ON;;;;;N;;;;;
+2E2E;REVERSED QUESTION MARK;Po;0;ON;;;;;N;;;;;
+2E2F;VERTICAL TILDE;Lm;0;ON;;;;;N;;;;;
+2E30;RING POINT;Po;0;ON;;;;;N;;;;;
+2E31;WORD SEPARATOR MIDDLE DOT;Po;0;ON;;;;;N;;;;;
+2E80;CJK RADICAL REPEAT;So;0;ON;;;;;N;;;;;
+2E81;CJK RADICAL CLIFF;So;0;ON;;;;;N;;;;;
+2E82;CJK RADICAL SECOND ONE;So;0;ON;;;;;N;;;;;
+2E83;CJK RADICAL SECOND TWO;So;0;ON;;;;;N;;;;;
+2E84;CJK RADICAL SECOND THREE;So;0;ON;;;;;N;;;;;
+2E85;CJK RADICAL PERSON;So;0;ON;;;;;N;;;;;
+2E86;CJK RADICAL BOX;So;0;ON;;;;;N;;;;;
+2E87;CJK RADICAL TABLE;So;0;ON;;;;;N;;;;;
+2E88;CJK RADICAL KNIFE ONE;So;0;ON;;;;;N;;;;;
+2E89;CJK RADICAL KNIFE TWO;So;0;ON;;;;;N;;;;;
+2E8A;CJK RADICAL DIVINATION;So;0;ON;;;;;N;;;;;
+2E8B;CJK RADICAL SEAL;So;0;ON;;;;;N;;;;;
+2E8C;CJK RADICAL SMALL ONE;So;0;ON;;;;;N;;;;;
+2E8D;CJK RADICAL SMALL TWO;So;0;ON;;;;;N;;;;;
+2E8E;CJK RADICAL LAME ONE;So;0;ON;;;;;N;;;;;
+2E8F;CJK RADICAL LAME TWO;So;0;ON;;;;;N;;;;;
+2E90;CJK RADICAL LAME THREE;So;0;ON;;;;;N;;;;;
+2E91;CJK RADICAL LAME FOUR;So;0;ON;;;;;N;;;;;
+2E92;CJK RADICAL SNAKE;So;0;ON;;;;;N;;;;;
+2E93;CJK RADICAL THREAD;So;0;ON;;;;;N;;;;;
+2E94;CJK RADICAL SNOUT ONE;So;0;ON;;;;;N;;;;;
+2E95;CJK RADICAL SNOUT TWO;So;0;ON;;;;;N;;;;;
+2E96;CJK RADICAL HEART ONE;So;0;ON;;;;;N;;;;;
+2E97;CJK RADICAL HEART TWO;So;0;ON;;;;;N;;;;;
+2E98;CJK RADICAL HAND;So;0;ON;;;;;N;;;;;
+2E99;CJK RADICAL RAP;So;0;ON;;;;;N;;;;;
+2E9B;CJK RADICAL CHOKE;So;0;ON;;;;;N;;;;;
+2E9C;CJK RADICAL SUN;So;0;ON;;;;;N;;;;;
+2E9D;CJK RADICAL MOON;So;0;ON;;;;;N;;;;;
+2E9E;CJK RADICAL DEATH;So;0;ON;;;;;N;;;;;
+2E9F;CJK RADICAL MOTHER;So;0;ON;<compat> 6BCD;;;;N;;;;;
+2EA0;CJK RADICAL CIVILIAN;So;0;ON;;;;;N;;;;;
+2EA1;CJK RADICAL WATER ONE;So;0;ON;;;;;N;;;;;
+2EA2;CJK RADICAL WATER TWO;So;0;ON;;;;;N;;;;;
+2EA3;CJK RADICAL FIRE;So;0;ON;;;;;N;;;;;
+2EA4;CJK RADICAL PAW ONE;So;0;ON;;;;;N;;;;;
+2EA5;CJK RADICAL PAW TWO;So;0;ON;;;;;N;;;;;
+2EA6;CJK RADICAL SIMPLIFIED HALF TREE TRUNK;So;0;ON;;;;;N;;;;;
+2EA7;CJK RADICAL COW;So;0;ON;;;;;N;;;;;
+2EA8;CJK RADICAL DOG;So;0;ON;;;;;N;;;;;
+2EA9;CJK RADICAL JADE;So;0;ON;;;;;N;;;;;
+2EAA;CJK RADICAL BOLT OF CLOTH;So;0;ON;;;;;N;;;;;
+2EAB;CJK RADICAL EYE;So;0;ON;;;;;N;;;;;
+2EAC;CJK RADICAL SPIRIT ONE;So;0;ON;;;;;N;;;;;
+2EAD;CJK RADICAL SPIRIT TWO;So;0;ON;;;;;N;;;;;
+2EAE;CJK RADICAL BAMBOO;So;0;ON;;;;;N;;;;;
+2EAF;CJK RADICAL SILK;So;0;ON;;;;;N;;;;;
+2EB0;CJK RADICAL C-SIMPLIFIED SILK;So;0;ON;;;;;N;;;;;
+2EB1;CJK RADICAL NET ONE;So;0;ON;;;;;N;;;;;
+2EB2;CJK RADICAL NET TWO;So;0;ON;;;;;N;;;;;
+2EB3;CJK RADICAL NET THREE;So;0;ON;;;;;N;;;;;
+2EB4;CJK RADICAL NET FOUR;So;0;ON;;;;;N;;;;;
+2EB5;CJK RADICAL MESH;So;0;ON;;;;;N;;;;;
+2EB6;CJK RADICAL SHEEP;So;0;ON;;;;;N;;;;;
+2EB7;CJK RADICAL RAM;So;0;ON;;;;;N;;;;;
+2EB8;CJK RADICAL EWE;So;0;ON;;;;;N;;;;;
+2EB9;CJK RADICAL OLD;So;0;ON;;;;;N;;;;;
+2EBA;CJK RADICAL BRUSH ONE;So;0;ON;;;;;N;;;;;
+2EBB;CJK RADICAL BRUSH TWO;So;0;ON;;;;;N;;;;;
+2EBC;CJK RADICAL MEAT;So;0;ON;;;;;N;;;;;
+2EBD;CJK RADICAL MORTAR;So;0;ON;;;;;N;;;;;
+2EBE;CJK RADICAL GRASS ONE;So;0;ON;;;;;N;;;;;
+2EBF;CJK RADICAL GRASS TWO;So;0;ON;;;;;N;;;;;
+2EC0;CJK RADICAL GRASS THREE;So;0;ON;;;;;N;;;;;
+2EC1;CJK RADICAL TIGER;So;0;ON;;;;;N;;;;;
+2EC2;CJK RADICAL CLOTHES;So;0;ON;;;;;N;;;;;
+2EC3;CJK RADICAL WEST ONE;So;0;ON;;;;;N;;;;;
+2EC4;CJK RADICAL WEST TWO;So;0;ON;;;;;N;;;;;
+2EC5;CJK RADICAL C-SIMPLIFIED SEE;So;0;ON;;;;;N;;;;;
+2EC6;CJK RADICAL SIMPLIFIED HORN;So;0;ON;;;;;N;;;;;
+2EC7;CJK RADICAL HORN;So;0;ON;;;;;N;;;;;
+2EC8;CJK RADICAL C-SIMPLIFIED SPEECH;So;0;ON;;;;;N;;;;;
+2EC9;CJK RADICAL C-SIMPLIFIED SHELL;So;0;ON;;;;;N;;;;;
+2ECA;CJK RADICAL FOOT;So;0;ON;;;;;N;;;;;
+2ECB;CJK RADICAL C-SIMPLIFIED CART;So;0;ON;;;;;N;;;;;
+2ECC;CJK RADICAL SIMPLIFIED WALK;So;0;ON;;;;;N;;;;;
+2ECD;CJK RADICAL WALK ONE;So;0;ON;;;;;N;;;;;
+2ECE;CJK RADICAL WALK TWO;So;0;ON;;;;;N;;;;;
+2ECF;CJK RADICAL CITY;So;0;ON;;;;;N;;;;;
+2ED0;CJK RADICAL C-SIMPLIFIED GOLD;So;0;ON;;;;;N;;;;;
+2ED1;CJK RADICAL LONG ONE;So;0;ON;;;;;N;;;;;
+2ED2;CJK RADICAL LONG TWO;So;0;ON;;;;;N;;;;;
+2ED3;CJK RADICAL C-SIMPLIFIED LONG;So;0;ON;;;;;N;;;;;
+2ED4;CJK RADICAL C-SIMPLIFIED GATE;So;0;ON;;;;;N;;;;;
+2ED5;CJK RADICAL MOUND ONE;So;0;ON;;;;;N;;;;;
+2ED6;CJK RADICAL MOUND TWO;So;0;ON;;;;;N;;;;;
+2ED7;CJK RADICAL RAIN;So;0;ON;;;;;N;;;;;
+2ED8;CJK RADICAL BLUE;So;0;ON;;;;;N;;;;;
+2ED9;CJK RADICAL C-SIMPLIFIED TANNED LEATHER;So;0;ON;;;;;N;;;;;
+2EDA;CJK RADICAL C-SIMPLIFIED LEAF;So;0;ON;;;;;N;;;;;
+2EDB;CJK RADICAL C-SIMPLIFIED WIND;So;0;ON;;;;;N;;;;;
+2EDC;CJK RADICAL C-SIMPLIFIED FLY;So;0;ON;;;;;N;;;;;
+2EDD;CJK RADICAL EAT ONE;So;0;ON;;;;;N;;;;;
+2EDE;CJK RADICAL EAT TWO;So;0;ON;;;;;N;;;;;
+2EDF;CJK RADICAL EAT THREE;So;0;ON;;;;;N;;;;;
+2EE0;CJK RADICAL C-SIMPLIFIED EAT;So;0;ON;;;;;N;;;;;
+2EE1;CJK RADICAL HEAD;So;0;ON;;;;;N;;;;;
+2EE2;CJK RADICAL C-SIMPLIFIED HORSE;So;0;ON;;;;;N;;;;;
+2EE3;CJK RADICAL BONE;So;0;ON;;;;;N;;;;;
+2EE4;CJK RADICAL GHOST;So;0;ON;;;;;N;;;;;
+2EE5;CJK RADICAL C-SIMPLIFIED FISH;So;0;ON;;;;;N;;;;;
+2EE6;CJK RADICAL C-SIMPLIFIED BIRD;So;0;ON;;;;;N;;;;;
+2EE7;CJK RADICAL C-SIMPLIFIED SALT;So;0;ON;;;;;N;;;;;
+2EE8;CJK RADICAL SIMPLIFIED WHEAT;So;0;ON;;;;;N;;;;;
+2EE9;CJK RADICAL SIMPLIFIED YELLOW;So;0;ON;;;;;N;;;;;
+2EEA;CJK RADICAL C-SIMPLIFIED FROG;So;0;ON;;;;;N;;;;;
+2EEB;CJK RADICAL J-SIMPLIFIED EVEN;So;0;ON;;;;;N;;;;;
+2EEC;CJK RADICAL C-SIMPLIFIED EVEN;So;0;ON;;;;;N;;;;;
+2EED;CJK RADICAL J-SIMPLIFIED TOOTH;So;0;ON;;;;;N;;;;;
+2EEE;CJK RADICAL C-SIMPLIFIED TOOTH;So;0;ON;;;;;N;;;;;
+2EEF;CJK RADICAL J-SIMPLIFIED DRAGON;So;0;ON;;;;;N;;;;;
+2EF0;CJK RADICAL C-SIMPLIFIED DRAGON;So;0;ON;;;;;N;;;;;
+2EF1;CJK RADICAL TURTLE;So;0;ON;;;;;N;;;;;
+2EF2;CJK RADICAL J-SIMPLIFIED TURTLE;So;0;ON;;;;;N;;;;;
+2EF3;CJK RADICAL C-SIMPLIFIED TURTLE;So;0;ON;<compat> 9F9F;;;;N;;;;;
+2F00;KANGXI RADICAL ONE;So;0;ON;<compat> 4E00;;;;N;;;;;
+2F01;KANGXI RADICAL LINE;So;0;ON;<compat> 4E28;;;;N;;;;;
+2F02;KANGXI RADICAL DOT;So;0;ON;<compat> 4E36;;;;N;;;;;
+2F03;KANGXI RADICAL SLASH;So;0;ON;<compat> 4E3F;;;;N;;;;;
+2F04;KANGXI RADICAL SECOND;So;0;ON;<compat> 4E59;;;;N;;;;;
+2F05;KANGXI RADICAL HOOK;So;0;ON;<compat> 4E85;;;;N;;;;;
+2F06;KANGXI RADICAL TWO;So;0;ON;<compat> 4E8C;;;;N;;;;;
+2F07;KANGXI RADICAL LID;So;0;ON;<compat> 4EA0;;;;N;;;;;
+2F08;KANGXI RADICAL MAN;So;0;ON;<compat> 4EBA;;;;N;;;;;
+2F09;KANGXI RADICAL LEGS;So;0;ON;<compat> 513F;;;;N;;;;;
+2F0A;KANGXI RADICAL ENTER;So;0;ON;<compat> 5165;;;;N;;;;;
+2F0B;KANGXI RADICAL EIGHT;So;0;ON;<compat> 516B;;;;N;;;;;
+2F0C;KANGXI RADICAL DOWN BOX;So;0;ON;<compat> 5182;;;;N;;;;;
+2F0D;KANGXI RADICAL COVER;So;0;ON;<compat> 5196;;;;N;;;;;
+2F0E;KANGXI RADICAL ICE;So;0;ON;<compat> 51AB;;;;N;;;;;
+2F0F;KANGXI RADICAL TABLE;So;0;ON;<compat> 51E0;;;;N;;;;;
+2F10;KANGXI RADICAL OPEN BOX;So;0;ON;<compat> 51F5;;;;N;;;;;
+2F11;KANGXI RADICAL KNIFE;So;0;ON;<compat> 5200;;;;N;;;;;
+2F12;KANGXI RADICAL POWER;So;0;ON;<compat> 529B;;;;N;;;;;
+2F13;KANGXI RADICAL WRAP;So;0;ON;<compat> 52F9;;;;N;;;;;
+2F14;KANGXI RADICAL SPOON;So;0;ON;<compat> 5315;;;;N;;;;;
+2F15;KANGXI RADICAL RIGHT OPEN BOX;So;0;ON;<compat> 531A;;;;N;;;;;
+2F16;KANGXI RADICAL HIDING ENCLOSURE;So;0;ON;<compat> 5338;;;;N;;;;;
+2F17;KANGXI RADICAL TEN;So;0;ON;<compat> 5341;;;;N;;;;;
+2F18;KANGXI RADICAL DIVINATION;So;0;ON;<compat> 535C;;;;N;;;;;
+2F19;KANGXI RADICAL SEAL;So;0;ON;<compat> 5369;;;;N;;;;;
+2F1A;KANGXI RADICAL CLIFF;So;0;ON;<compat> 5382;;;;N;;;;;
+2F1B;KANGXI RADICAL PRIVATE;So;0;ON;<compat> 53B6;;;;N;;;;;
+2F1C;KANGXI RADICAL AGAIN;So;0;ON;<compat> 53C8;;;;N;;;;;
+2F1D;KANGXI RADICAL MOUTH;So;0;ON;<compat> 53E3;;;;N;;;;;
+2F1E;KANGXI RADICAL ENCLOSURE;So;0;ON;<compat> 56D7;;;;N;;;;;
+2F1F;KANGXI RADICAL EARTH;So;0;ON;<compat> 571F;;;;N;;;;;
+2F20;KANGXI RADICAL SCHOLAR;So;0;ON;<compat> 58EB;;;;N;;;;;
+2F21;KANGXI RADICAL GO;So;0;ON;<compat> 5902;;;;N;;;;;
+2F22;KANGXI RADICAL GO SLOWLY;So;0;ON;<compat> 590A;;;;N;;;;;
+2F23;KANGXI RADICAL EVENING;So;0;ON;<compat> 5915;;;;N;;;;;
+2F24;KANGXI RADICAL BIG;So;0;ON;<compat> 5927;;;;N;;;;;
+2F25;KANGXI RADICAL WOMAN;So;0;ON;<compat> 5973;;;;N;;;;;
+2F26;KANGXI RADICAL CHILD;So;0;ON;<compat> 5B50;;;;N;;;;;
+2F27;KANGXI RADICAL ROOF;So;0;ON;<compat> 5B80;;;;N;;;;;
+2F28;KANGXI RADICAL INCH;So;0;ON;<compat> 5BF8;;;;N;;;;;
+2F29;KANGXI RADICAL SMALL;So;0;ON;<compat> 5C0F;;;;N;;;;;
+2F2A;KANGXI RADICAL LAME;So;0;ON;<compat> 5C22;;;;N;;;;;
+2F2B;KANGXI RADICAL CORPSE;So;0;ON;<compat> 5C38;;;;N;;;;;
+2F2C;KANGXI RADICAL SPROUT;So;0;ON;<compat> 5C6E;;;;N;;;;;
+2F2D;KANGXI RADICAL MOUNTAIN;So;0;ON;<compat> 5C71;;;;N;;;;;
+2F2E;KANGXI RADICAL RIVER;So;0;ON;<compat> 5DDB;;;;N;;;;;
+2F2F;KANGXI RADICAL WORK;So;0;ON;<compat> 5DE5;;;;N;;;;;
+2F30;KANGXI RADICAL ONESELF;So;0;ON;<compat> 5DF1;;;;N;;;;;
+2F31;KANGXI RADICAL TURBAN;So;0;ON;<compat> 5DFE;;;;N;;;;;
+2F32;KANGXI RADICAL DRY;So;0;ON;<compat> 5E72;;;;N;;;;;
+2F33;KANGXI RADICAL SHORT THREAD;So;0;ON;<compat> 5E7A;;;;N;;;;;
+2F34;KANGXI RADICAL DOTTED CLIFF;So;0;ON;<compat> 5E7F;;;;N;;;;;
+2F35;KANGXI RADICAL LONG STRIDE;So;0;ON;<compat> 5EF4;;;;N;;;;;
+2F36;KANGXI RADICAL TWO HANDS;So;0;ON;<compat> 5EFE;;;;N;;;;;
+2F37;KANGXI RADICAL SHOOT;So;0;ON;<compat> 5F0B;;;;N;;;;;
+2F38;KANGXI RADICAL BOW;So;0;ON;<compat> 5F13;;;;N;;;;;
+2F39;KANGXI RADICAL SNOUT;So;0;ON;<compat> 5F50;;;;N;;;;;
+2F3A;KANGXI RADICAL BRISTLE;So;0;ON;<compat> 5F61;;;;N;;;;;
+2F3B;KANGXI RADICAL STEP;So;0;ON;<compat> 5F73;;;;N;;;;;
+2F3C;KANGXI RADICAL HEART;So;0;ON;<compat> 5FC3;;;;N;;;;;
+2F3D;KANGXI RADICAL HALBERD;So;0;ON;<compat> 6208;;;;N;;;;;
+2F3E;KANGXI RADICAL DOOR;So;0;ON;<compat> 6236;;;;N;;;;;
+2F3F;KANGXI RADICAL HAND;So;0;ON;<compat> 624B;;;;N;;;;;
+2F40;KANGXI RADICAL BRANCH;So;0;ON;<compat> 652F;;;;N;;;;;
+2F41;KANGXI RADICAL RAP;So;0;ON;<compat> 6534;;;;N;;;;;
+2F42;KANGXI RADICAL SCRIPT;So;0;ON;<compat> 6587;;;;N;;;;;
+2F43;KANGXI RADICAL DIPPER;So;0;ON;<compat> 6597;;;;N;;;;;
+2F44;KANGXI RADICAL AXE;So;0;ON;<compat> 65A4;;;;N;;;;;
+2F45;KANGXI RADICAL SQUARE;So;0;ON;<compat> 65B9;;;;N;;;;;
+2F46;KANGXI RADICAL NOT;So;0;ON;<compat> 65E0;;;;N;;;;;
+2F47;KANGXI RADICAL SUN;So;0;ON;<compat> 65E5;;;;N;;;;;
+2F48;KANGXI RADICAL SAY;So;0;ON;<compat> 66F0;;;;N;;;;;
+2F49;KANGXI RADICAL MOON;So;0;ON;<compat> 6708;;;;N;;;;;
+2F4A;KANGXI RADICAL TREE;So;0;ON;<compat> 6728;;;;N;;;;;
+2F4B;KANGXI RADICAL LACK;So;0;ON;<compat> 6B20;;;;N;;;;;
+2F4C;KANGXI RADICAL STOP;So;0;ON;<compat> 6B62;;;;N;;;;;
+2F4D;KANGXI RADICAL DEATH;So;0;ON;<compat> 6B79;;;;N;;;;;
+2F4E;KANGXI RADICAL WEAPON;So;0;ON;<compat> 6BB3;;;;N;;;;;
+2F4F;KANGXI RADICAL DO NOT;So;0;ON;<compat> 6BCB;;;;N;;;;;
+2F50;KANGXI RADICAL COMPARE;So;0;ON;<compat> 6BD4;;;;N;;;;;
+2F51;KANGXI RADICAL FUR;So;0;ON;<compat> 6BDB;;;;N;;;;;
+2F52;KANGXI RADICAL CLAN;So;0;ON;<compat> 6C0F;;;;N;;;;;
+2F53;KANGXI RADICAL STEAM;So;0;ON;<compat> 6C14;;;;N;;;;;
+2F54;KANGXI RADICAL WATER;So;0;ON;<compat> 6C34;;;;N;;;;;
+2F55;KANGXI RADICAL FIRE;So;0;ON;<compat> 706B;;;;N;;;;;
+2F56;KANGXI RADICAL CLAW;So;0;ON;<compat> 722A;;;;N;;;;;
+2F57;KANGXI RADICAL FATHER;So;0;ON;<compat> 7236;;;;N;;;;;
+2F58;KANGXI RADICAL DOUBLE X;So;0;ON;<compat> 723B;;;;N;;;;;
+2F59;KANGXI RADICAL HALF TREE TRUNK;So;0;ON;<compat> 723F;;;;N;;;;;
+2F5A;KANGXI RADICAL SLICE;So;0;ON;<compat> 7247;;;;N;;;;;
+2F5B;KANGXI RADICAL FANG;So;0;ON;<compat> 7259;;;;N;;;;;
+2F5C;KANGXI RADICAL COW;So;0;ON;<compat> 725B;;;;N;;;;;
+2F5D;KANGXI RADICAL DOG;So;0;ON;<compat> 72AC;;;;N;;;;;
+2F5E;KANGXI RADICAL PROFOUND;So;0;ON;<compat> 7384;;;;N;;;;;
+2F5F;KANGXI RADICAL JADE;So;0;ON;<compat> 7389;;;;N;;;;;
+2F60;KANGXI RADICAL MELON;So;0;ON;<compat> 74DC;;;;N;;;;;
+2F61;KANGXI RADICAL TILE;So;0;ON;<compat> 74E6;;;;N;;;;;
+2F62;KANGXI RADICAL SWEET;So;0;ON;<compat> 7518;;;;N;;;;;
+2F63;KANGXI RADICAL LIFE;So;0;ON;<compat> 751F;;;;N;;;;;
+2F64;KANGXI RADICAL USE;So;0;ON;<compat> 7528;;;;N;;;;;
+2F65;KANGXI RADICAL FIELD;So;0;ON;<compat> 7530;;;;N;;;;;
+2F66;KANGXI RADICAL BOLT OF CLOTH;So;0;ON;<compat> 758B;;;;N;;;;;
+2F67;KANGXI RADICAL SICKNESS;So;0;ON;<compat> 7592;;;;N;;;;;
+2F68;KANGXI RADICAL DOTTED TENT;So;0;ON;<compat> 7676;;;;N;;;;;
+2F69;KANGXI RADICAL WHITE;So;0;ON;<compat> 767D;;;;N;;;;;
+2F6A;KANGXI RADICAL SKIN;So;0;ON;<compat> 76AE;;;;N;;;;;
+2F6B;KANGXI RADICAL DISH;So;0;ON;<compat> 76BF;;;;N;;;;;
+2F6C;KANGXI RADICAL EYE;So;0;ON;<compat> 76EE;;;;N;;;;;
+2F6D;KANGXI RADICAL SPEAR;So;0;ON;<compat> 77DB;;;;N;;;;;
+2F6E;KANGXI RADICAL ARROW;So;0;ON;<compat> 77E2;;;;N;;;;;
+2F6F;KANGXI RADICAL STONE;So;0;ON;<compat> 77F3;;;;N;;;;;
+2F70;KANGXI RADICAL SPIRIT;So;0;ON;<compat> 793A;;;;N;;;;;
+2F71;KANGXI RADICAL TRACK;So;0;ON;<compat> 79B8;;;;N;;;;;
+2F72;KANGXI RADICAL GRAIN;So;0;ON;<compat> 79BE;;;;N;;;;;
+2F73;KANGXI RADICAL CAVE;So;0;ON;<compat> 7A74;;;;N;;;;;
+2F74;KANGXI RADICAL STAND;So;0;ON;<compat> 7ACB;;;;N;;;;;
+2F75;KANGXI RADICAL BAMBOO;So;0;ON;<compat> 7AF9;;;;N;;;;;
+2F76;KANGXI RADICAL RICE;So;0;ON;<compat> 7C73;;;;N;;;;;
+2F77;KANGXI RADICAL SILK;So;0;ON;<compat> 7CF8;;;;N;;;;;
+2F78;KANGXI RADICAL JAR;So;0;ON;<compat> 7F36;;;;N;;;;;
+2F79;KANGXI RADICAL NET;So;0;ON;<compat> 7F51;;;;N;;;;;
+2F7A;KANGXI RADICAL SHEEP;So;0;ON;<compat> 7F8A;;;;N;;;;;
+2F7B;KANGXI RADICAL FEATHER;So;0;ON;<compat> 7FBD;;;;N;;;;;
+2F7C;KANGXI RADICAL OLD;So;0;ON;<compat> 8001;;;;N;;;;;
+2F7D;KANGXI RADICAL AND;So;0;ON;<compat> 800C;;;;N;;;;;
+2F7E;KANGXI RADICAL PLOW;So;0;ON;<compat> 8012;;;;N;;;;;
+2F7F;KANGXI RADICAL EAR;So;0;ON;<compat> 8033;;;;N;;;;;
+2F80;KANGXI RADICAL BRUSH;So;0;ON;<compat> 807F;;;;N;;;;;
+2F81;KANGXI RADICAL MEAT;So;0;ON;<compat> 8089;;;;N;;;;;
+2F82;KANGXI RADICAL MINISTER;So;0;ON;<compat> 81E3;;;;N;;;;;
+2F83;KANGXI RADICAL SELF;So;0;ON;<compat> 81EA;;;;N;;;;;
+2F84;KANGXI RADICAL ARRIVE;So;0;ON;<compat> 81F3;;;;N;;;;;
+2F85;KANGXI RADICAL MORTAR;So;0;ON;<compat> 81FC;;;;N;;;;;
+2F86;KANGXI RADICAL TONGUE;So;0;ON;<compat> 820C;;;;N;;;;;
+2F87;KANGXI RADICAL OPPOSE;So;0;ON;<compat> 821B;;;;N;;;;;
+2F88;KANGXI RADICAL BOAT;So;0;ON;<compat> 821F;;;;N;;;;;
+2F89;KANGXI RADICAL STOPPING;So;0;ON;<compat> 826E;;;;N;;;;;
+2F8A;KANGXI RADICAL COLOR;So;0;ON;<compat> 8272;;;;N;;;;;
+2F8B;KANGXI RADICAL GRASS;So;0;ON;<compat> 8278;;;;N;;;;;
+2F8C;KANGXI RADICAL TIGER;So;0;ON;<compat> 864D;;;;N;;;;;
+2F8D;KANGXI RADICAL INSECT;So;0;ON;<compat> 866B;;;;N;;;;;
+2F8E;KANGXI RADICAL BLOOD;So;0;ON;<compat> 8840;;;;N;;;;;
+2F8F;KANGXI RADICAL WALK ENCLOSURE;So;0;ON;<compat> 884C;;;;N;;;;;
+2F90;KANGXI RADICAL CLOTHES;So;0;ON;<compat> 8863;;;;N;;;;;
+2F91;KANGXI RADICAL WEST;So;0;ON;<compat> 897E;;;;N;;;;;
+2F92;KANGXI RADICAL SEE;So;0;ON;<compat> 898B;;;;N;;;;;
+2F93;KANGXI RADICAL HORN;So;0;ON;<compat> 89D2;;;;N;;;;;
+2F94;KANGXI RADICAL SPEECH;So;0;ON;<compat> 8A00;;;;N;;;;;
+2F95;KANGXI RADICAL VALLEY;So;0;ON;<compat> 8C37;;;;N;;;;;
+2F96;KANGXI RADICAL BEAN;So;0;ON;<compat> 8C46;;;;N;;;;;
+2F97;KANGXI RADICAL PIG;So;0;ON;<compat> 8C55;;;;N;;;;;
+2F98;KANGXI RADICAL BADGER;So;0;ON;<compat> 8C78;;;;N;;;;;
+2F99;KANGXI RADICAL SHELL;So;0;ON;<compat> 8C9D;;;;N;;;;;
+2F9A;KANGXI RADICAL RED;So;0;ON;<compat> 8D64;;;;N;;;;;
+2F9B;KANGXI RADICAL RUN;So;0;ON;<compat> 8D70;;;;N;;;;;
+2F9C;KANGXI RADICAL FOOT;So;0;ON;<compat> 8DB3;;;;N;;;;;
+2F9D;KANGXI RADICAL BODY;So;0;ON;<compat> 8EAB;;;;N;;;;;
+2F9E;KANGXI RADICAL CART;So;0;ON;<compat> 8ECA;;;;N;;;;;
+2F9F;KANGXI RADICAL BITTER;So;0;ON;<compat> 8F9B;;;;N;;;;;
+2FA0;KANGXI RADICAL MORNING;So;0;ON;<compat> 8FB0;;;;N;;;;;
+2FA1;KANGXI RADICAL WALK;So;0;ON;<compat> 8FB5;;;;N;;;;;
+2FA2;KANGXI RADICAL CITY;So;0;ON;<compat> 9091;;;;N;;;;;
+2FA3;KANGXI RADICAL WINE;So;0;ON;<compat> 9149;;;;N;;;;;
+2FA4;KANGXI RADICAL DISTINGUISH;So;0;ON;<compat> 91C6;;;;N;;;;;
+2FA5;KANGXI RADICAL VILLAGE;So;0;ON;<compat> 91CC;;;;N;;;;;
+2FA6;KANGXI RADICAL GOLD;So;0;ON;<compat> 91D1;;;;N;;;;;
+2FA7;KANGXI RADICAL LONG;So;0;ON;<compat> 9577;;;;N;;;;;
+2FA8;KANGXI RADICAL GATE;So;0;ON;<compat> 9580;;;;N;;;;;
+2FA9;KANGXI RADICAL MOUND;So;0;ON;<compat> 961C;;;;N;;;;;
+2FAA;KANGXI RADICAL SLAVE;So;0;ON;<compat> 96B6;;;;N;;;;;
+2FAB;KANGXI RADICAL SHORT TAILED BIRD;So;0;ON;<compat> 96B9;;;;N;;;;;
+2FAC;KANGXI RADICAL RAIN;So;0;ON;<compat> 96E8;;;;N;;;;;
+2FAD;KANGXI RADICAL BLUE;So;0;ON;<compat> 9751;;;;N;;;;;
+2FAE;KANGXI RADICAL WRONG;So;0;ON;<compat> 975E;;;;N;;;;;
+2FAF;KANGXI RADICAL FACE;So;0;ON;<compat> 9762;;;;N;;;;;
+2FB0;KANGXI RADICAL LEATHER;So;0;ON;<compat> 9769;;;;N;;;;;
+2FB1;KANGXI RADICAL TANNED LEATHER;So;0;ON;<compat> 97CB;;;;N;;;;;
+2FB2;KANGXI RADICAL LEEK;So;0;ON;<compat> 97ED;;;;N;;;;;
+2FB3;KANGXI RADICAL SOUND;So;0;ON;<compat> 97F3;;;;N;;;;;
+2FB4;KANGXI RADICAL LEAF;So;0;ON;<compat> 9801;;;;N;;;;;
+2FB5;KANGXI RADICAL WIND;So;0;ON;<compat> 98A8;;;;N;;;;;
+2FB6;KANGXI RADICAL FLY;So;0;ON;<compat> 98DB;;;;N;;;;;
+2FB7;KANGXI RADICAL EAT;So;0;ON;<compat> 98DF;;;;N;;;;;
+2FB8;KANGXI RADICAL HEAD;So;0;ON;<compat> 9996;;;;N;;;;;
+2FB9;KANGXI RADICAL FRAGRANT;So;0;ON;<compat> 9999;;;;N;;;;;
+2FBA;KANGXI RADICAL HORSE;So;0;ON;<compat> 99AC;;;;N;;;;;
+2FBB;KANGXI RADICAL BONE;So;0;ON;<compat> 9AA8;;;;N;;;;;
+2FBC;KANGXI RADICAL TALL;So;0;ON;<compat> 9AD8;;;;N;;;;;
+2FBD;KANGXI RADICAL HAIR;So;0;ON;<compat> 9ADF;;;;N;;;;;
+2FBE;KANGXI RADICAL FIGHT;So;0;ON;<compat> 9B25;;;;N;;;;;
+2FBF;KANGXI RADICAL SACRIFICIAL WINE;So;0;ON;<compat> 9B2F;;;;N;;;;;
+2FC0;KANGXI RADICAL CAULDRON;So;0;ON;<compat> 9B32;;;;N;;;;;
+2FC1;KANGXI RADICAL GHOST;So;0;ON;<compat> 9B3C;;;;N;;;;;
+2FC2;KANGXI RADICAL FISH;So;0;ON;<compat> 9B5A;;;;N;;;;;
+2FC3;KANGXI RADICAL BIRD;So;0;ON;<compat> 9CE5;;;;N;;;;;
+2FC4;KANGXI RADICAL SALT;So;0;ON;<compat> 9E75;;;;N;;;;;
+2FC5;KANGXI RADICAL DEER;So;0;ON;<compat> 9E7F;;;;N;;;;;
+2FC6;KANGXI RADICAL WHEAT;So;0;ON;<compat> 9EA5;;;;N;;;;;
+2FC7;KANGXI RADICAL HEMP;So;0;ON;<compat> 9EBB;;;;N;;;;;
+2FC8;KANGXI RADICAL YELLOW;So;0;ON;<compat> 9EC3;;;;N;;;;;
+2FC9;KANGXI RADICAL MILLET;So;0;ON;<compat> 9ECD;;;;N;;;;;
+2FCA;KANGXI RADICAL BLACK;So;0;ON;<compat> 9ED1;;;;N;;;;;
+2FCB;KANGXI RADICAL EMBROIDERY;So;0;ON;<compat> 9EF9;;;;N;;;;;
+2FCC;KANGXI RADICAL FROG;So;0;ON;<compat> 9EFD;;;;N;;;;;
+2FCD;KANGXI RADICAL TRIPOD;So;0;ON;<compat> 9F0E;;;;N;;;;;
+2FCE;KANGXI RADICAL DRUM;So;0;ON;<compat> 9F13;;;;N;;;;;
+2FCF;KANGXI RADICAL RAT;So;0;ON;<compat> 9F20;;;;N;;;;;
+2FD0;KANGXI RADICAL NOSE;So;0;ON;<compat> 9F3B;;;;N;;;;;
+2FD1;KANGXI RADICAL EVEN;So;0;ON;<compat> 9F4A;;;;N;;;;;
+2FD2;KANGXI RADICAL TOOTH;So;0;ON;<compat> 9F52;;;;N;;;;;
+2FD3;KANGXI RADICAL DRAGON;So;0;ON;<compat> 9F8D;;;;N;;;;;
+2FD4;KANGXI RADICAL TURTLE;So;0;ON;<compat> 9F9C;;;;N;;;;;
+2FD5;KANGXI RADICAL FLUTE;So;0;ON;<compat> 9FA0;;;;N;;;;;
+2FF0;IDEOGRAPHIC DESCRIPTION CHARACTER LEFT TO RIGHT;So;0;ON;;;;;N;;;;;
+2FF1;IDEOGRAPHIC DESCRIPTION CHARACTER ABOVE TO BELOW;So;0;ON;;;;;N;;;;;
+2FF2;IDEOGRAPHIC DESCRIPTION CHARACTER LEFT TO MIDDLE AND RIGHT;So;0;ON;;;;;N;;;;;
+2FF3;IDEOGRAPHIC DESCRIPTION CHARACTER ABOVE TO MIDDLE AND BELOW;So;0;ON;;;;;N;;;;;
+2FF4;IDEOGRAPHIC DESCRIPTION CHARACTER FULL SURROUND;So;0;ON;;;;;N;;;;;
+2FF5;IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM ABOVE;So;0;ON;;;;;N;;;;;
+2FF6;IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM BELOW;So;0;ON;;;;;N;;;;;
+2FF7;IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM LEFT;So;0;ON;;;;;N;;;;;
+2FF8;IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM UPPER LEFT;So;0;ON;;;;;N;;;;;
+2FF9;IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM UPPER RIGHT;So;0;ON;;;;;N;;;;;
+2FFA;IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM LOWER LEFT;So;0;ON;;;;;N;;;;;
+2FFB;IDEOGRAPHIC DESCRIPTION CHARACTER OVERLAID;So;0;ON;;;;;N;;;;;
+3000;IDEOGRAPHIC SPACE;Zs;0;WS;<wide> 0020;;;;N;;;;;
+3001;IDEOGRAPHIC COMMA;Po;0;ON;;;;;N;;;;;
+3002;IDEOGRAPHIC FULL STOP;Po;0;ON;;;;;N;IDEOGRAPHIC PERIOD;;;;
+3003;DITTO MARK;Po;0;ON;;;;;N;;;;;
+3004;JAPANESE INDUSTRIAL STANDARD SYMBOL;So;0;ON;;;;;N;;;;;
+3005;IDEOGRAPHIC ITERATION MARK;Lm;0;L;;;;;N;;;;;
+3006;IDEOGRAPHIC CLOSING MARK;Lo;0;L;;;;;N;;;;;
+3007;IDEOGRAPHIC NUMBER ZERO;Nl;0;L;;;;0;N;;;;;
+3008;LEFT ANGLE BRACKET;Ps;0;ON;;;;;Y;OPENING ANGLE BRACKET;;;;
+3009;RIGHT ANGLE BRACKET;Pe;0;ON;;;;;Y;CLOSING ANGLE BRACKET;;;;
+300A;LEFT DOUBLE ANGLE BRACKET;Ps;0;ON;;;;;Y;OPENING DOUBLE ANGLE BRACKET;;;;
+300B;RIGHT DOUBLE ANGLE BRACKET;Pe;0;ON;;;;;Y;CLOSING DOUBLE ANGLE BRACKET;;;;
+300C;LEFT CORNER BRACKET;Ps;0;ON;;;;;Y;OPENING CORNER BRACKET;;;;
+300D;RIGHT CORNER BRACKET;Pe;0;ON;;;;;Y;CLOSING CORNER BRACKET;;;;
+300E;LEFT WHITE CORNER BRACKET;Ps;0;ON;;;;;Y;OPENING WHITE CORNER BRACKET;;;;
+300F;RIGHT WHITE CORNER BRACKET;Pe;0;ON;;;;;Y;CLOSING WHITE CORNER BRACKET;;;;
+3010;LEFT BLACK LENTICULAR BRACKET;Ps;0;ON;;;;;Y;OPENING BLACK LENTICULAR BRACKET;;;;
+3011;RIGHT BLACK LENTICULAR BRACKET;Pe;0;ON;;;;;Y;CLOSING BLACK LENTICULAR BRACKET;;;;
+3012;POSTAL MARK;So;0;ON;;;;;N;;;;;
+3013;GETA MARK;So;0;ON;;;;;N;;;;;
+3014;LEFT TORTOISE SHELL BRACKET;Ps;0;ON;;;;;Y;OPENING TORTOISE SHELL BRACKET;;;;
+3015;RIGHT TORTOISE SHELL BRACKET;Pe;0;ON;;;;;Y;CLOSING TORTOISE SHELL BRACKET;;;;
+3016;LEFT WHITE LENTICULAR BRACKET;Ps;0;ON;;;;;Y;OPENING WHITE LENTICULAR BRACKET;;;;
+3017;RIGHT WHITE LENTICULAR BRACKET;Pe;0;ON;;;;;Y;CLOSING WHITE LENTICULAR BRACKET;;;;
+3018;LEFT WHITE TORTOISE SHELL BRACKET;Ps;0;ON;;;;;Y;OPENING WHITE TORTOISE SHELL BRACKET;;;;
+3019;RIGHT WHITE TORTOISE SHELL BRACKET;Pe;0;ON;;;;;Y;CLOSING WHITE TORTOISE SHELL BRACKET;;;;
+301A;LEFT WHITE SQUARE BRACKET;Ps;0;ON;;;;;Y;OPENING WHITE SQUARE BRACKET;;;;
+301B;RIGHT WHITE SQUARE BRACKET;Pe;0;ON;;;;;Y;CLOSING WHITE SQUARE BRACKET;;;;
+301C;WAVE DASH;Pd;0;ON;;;;;N;;;;;
+301D;REVERSED DOUBLE PRIME QUOTATION MARK;Ps;0;ON;;;;;N;;;;;
+301E;DOUBLE PRIME QUOTATION MARK;Pe;0;ON;;;;;N;;;;;
+301F;LOW DOUBLE PRIME QUOTATION MARK;Pe;0;ON;;;;;N;;;;;
+3020;POSTAL MARK FACE;So;0;ON;;;;;N;;;;;
+3021;HANGZHOU NUMERAL ONE;Nl;0;L;;;;1;N;;;;;
+3022;HANGZHOU NUMERAL TWO;Nl;0;L;;;;2;N;;;;;
+3023;HANGZHOU NUMERAL THREE;Nl;0;L;;;;3;N;;;;;
+3024;HANGZHOU NUMERAL FOUR;Nl;0;L;;;;4;N;;;;;
+3025;HANGZHOU NUMERAL FIVE;Nl;0;L;;;;5;N;;;;;
+3026;HANGZHOU NUMERAL SIX;Nl;0;L;;;;6;N;;;;;
+3027;HANGZHOU NUMERAL SEVEN;Nl;0;L;;;;7;N;;;;;
+3028;HANGZHOU NUMERAL EIGHT;Nl;0;L;;;;8;N;;;;;
+3029;HANGZHOU NUMERAL NINE;Nl;0;L;;;;9;N;;;;;
+302A;IDEOGRAPHIC LEVEL TONE MARK;Mn;218;NSM;;;;;N;;;;;
+302B;IDEOGRAPHIC RISING TONE MARK;Mn;228;NSM;;;;;N;;;;;
+302C;IDEOGRAPHIC DEPARTING TONE MARK;Mn;232;NSM;;;;;N;;;;;
+302D;IDEOGRAPHIC ENTERING TONE MARK;Mn;222;NSM;;;;;N;;;;;
+302E;HANGUL SINGLE DOT TONE MARK;Mn;224;NSM;;;;;N;;;;;
+302F;HANGUL DOUBLE DOT TONE MARK;Mn;224;NSM;;;;;N;;;;;
+3030;WAVY DASH;Pd;0;ON;;;;;N;;;;;
+3031;VERTICAL KANA REPEAT MARK;Lm;0;L;;;;;N;;;;;
+3032;VERTICAL KANA REPEAT WITH VOICED SOUND MARK;Lm;0;L;;;;;N;;;;;
+3033;VERTICAL KANA REPEAT MARK UPPER HALF;Lm;0;L;;;;;N;;;;;
+3034;VERTICAL KANA REPEAT WITH VOICED SOUND MARK UPPER HALF;Lm;0;L;;;;;N;;;;;
+3035;VERTICAL KANA REPEAT MARK LOWER HALF;Lm;0;L;;;;;N;;;;;
+3036;CIRCLED POSTAL MARK;So;0;ON;<compat> 3012;;;;N;;;;;
+3037;IDEOGRAPHIC TELEGRAPH LINE FEED SEPARATOR SYMBOL;So;0;ON;;;;;N;;;;;
+3038;HANGZHOU NUMERAL TEN;Nl;0;L;<compat> 5341;;;10;N;;;;;
+3039;HANGZHOU NUMERAL TWENTY;Nl;0;L;<compat> 5344;;;20;N;;;;;
+303A;HANGZHOU NUMERAL THIRTY;Nl;0;L;<compat> 5345;;;30;N;;;;;
+303B;VERTICAL IDEOGRAPHIC ITERATION MARK;Lm;0;L;;;;;N;;;;;
+303C;MASU MARK;Lo;0;L;;;;;N;;;;;
+303D;PART ALTERNATION MARK;Po;0;ON;;;;;N;;;;;
+303E;IDEOGRAPHIC VARIATION INDICATOR;So;0;ON;;;;;N;;;;;
+303F;IDEOGRAPHIC HALF FILL SPACE;So;0;ON;;;;;N;;;;;
+3041;HIRAGANA LETTER SMALL A;Lo;0;L;;;;;N;;;;;
+3042;HIRAGANA LETTER A;Lo;0;L;;;;;N;;;;;
+3043;HIRAGANA LETTER SMALL I;Lo;0;L;;;;;N;;;;;
+3044;HIRAGANA LETTER I;Lo;0;L;;;;;N;;;;;
+3045;HIRAGANA LETTER SMALL U;Lo;0;L;;;;;N;;;;;
+3046;HIRAGANA LETTER U;Lo;0;L;;;;;N;;;;;
+3047;HIRAGANA LETTER SMALL E;Lo;0;L;;;;;N;;;;;
+3048;HIRAGANA LETTER E;Lo;0;L;;;;;N;;;;;
+3049;HIRAGANA LETTER SMALL O;Lo;0;L;;;;;N;;;;;
+304A;HIRAGANA LETTER O;Lo;0;L;;;;;N;;;;;
+304B;HIRAGANA LETTER KA;Lo;0;L;;;;;N;;;;;
+304C;HIRAGANA LETTER GA;Lo;0;L;304B 3099;;;;N;;;;;
+304D;HIRAGANA LETTER KI;Lo;0;L;;;;;N;;;;;
+304E;HIRAGANA LETTER GI;Lo;0;L;304D 3099;;;;N;;;;;
+304F;HIRAGANA LETTER KU;Lo;0;L;;;;;N;;;;;
+3050;HIRAGANA LETTER GU;Lo;0;L;304F 3099;;;;N;;;;;
+3051;HIRAGANA LETTER KE;Lo;0;L;;;;;N;;;;;
+3052;HIRAGANA LETTER GE;Lo;0;L;3051 3099;;;;N;;;;;
+3053;HIRAGANA LETTER KO;Lo;0;L;;;;;N;;;;;
+3054;HIRAGANA LETTER GO;Lo;0;L;3053 3099;;;;N;;;;;
+3055;HIRAGANA LETTER SA;Lo;0;L;;;;;N;;;;;
+3056;HIRAGANA LETTER ZA;Lo;0;L;3055 3099;;;;N;;;;;
+3057;HIRAGANA LETTER SI;Lo;0;L;;;;;N;;;;;
+3058;HIRAGANA LETTER ZI;Lo;0;L;3057 3099;;;;N;;;;;
+3059;HIRAGANA LETTER SU;Lo;0;L;;;;;N;;;;;
+305A;HIRAGANA LETTER ZU;Lo;0;L;3059 3099;;;;N;;;;;
+305B;HIRAGANA LETTER SE;Lo;0;L;;;;;N;;;;;
+305C;HIRAGANA LETTER ZE;Lo;0;L;305B 3099;;;;N;;;;;
+305D;HIRAGANA LETTER SO;Lo;0;L;;;;;N;;;;;
+305E;HIRAGANA LETTER ZO;Lo;0;L;305D 3099;;;;N;;;;;
+305F;HIRAGANA LETTER TA;Lo;0;L;;;;;N;;;;;
+3060;HIRAGANA LETTER DA;Lo;0;L;305F 3099;;;;N;;;;;
+3061;HIRAGANA LETTER TI;Lo;0;L;;;;;N;;;;;
+3062;HIRAGANA LETTER DI;Lo;0;L;3061 3099;;;;N;;;;;
+3063;HIRAGANA LETTER SMALL TU;Lo;0;L;;;;;N;;;;;
+3064;HIRAGANA LETTER TU;Lo;0;L;;;;;N;;;;;
+3065;HIRAGANA LETTER DU;Lo;0;L;3064 3099;;;;N;;;;;
+3066;HIRAGANA LETTER TE;Lo;0;L;;;;;N;;;;;
+3067;HIRAGANA LETTER DE;Lo;0;L;3066 3099;;;;N;;;;;
+3068;HIRAGANA LETTER TO;Lo;0;L;;;;;N;;;;;
+3069;HIRAGANA LETTER DO;Lo;0;L;3068 3099;;;;N;;;;;
+306A;HIRAGANA LETTER NA;Lo;0;L;;;;;N;;;;;
+306B;HIRAGANA LETTER NI;Lo;0;L;;;;;N;;;;;
+306C;HIRAGANA LETTER NU;Lo;0;L;;;;;N;;;;;
+306D;HIRAGANA LETTER NE;Lo;0;L;;;;;N;;;;;
+306E;HIRAGANA LETTER NO;Lo;0;L;;;;;N;;;;;
+306F;HIRAGANA LETTER HA;Lo;0;L;;;;;N;;;;;
+3070;HIRAGANA LETTER BA;Lo;0;L;306F 3099;;;;N;;;;;
+3071;HIRAGANA LETTER PA;Lo;0;L;306F 309A;;;;N;;;;;
+3072;HIRAGANA LETTER HI;Lo;0;L;;;;;N;;;;;
+3073;HIRAGANA LETTER BI;Lo;0;L;3072 3099;;;;N;;;;;
+3074;HIRAGANA LETTER PI;Lo;0;L;3072 309A;;;;N;;;;;
+3075;HIRAGANA LETTER HU;Lo;0;L;;;;;N;;;;;
+3076;HIRAGANA LETTER BU;Lo;0;L;3075 3099;;;;N;;;;;
+3077;HIRAGANA LETTER PU;Lo;0;L;3075 309A;;;;N;;;;;
+3078;HIRAGANA LETTER HE;Lo;0;L;;;;;N;;;;;
+3079;HIRAGANA LETTER BE;Lo;0;L;3078 3099;;;;N;;;;;
+307A;HIRAGANA LETTER PE;Lo;0;L;3078 309A;;;;N;;;;;
+307B;HIRAGANA LETTER HO;Lo;0;L;;;;;N;;;;;
+307C;HIRAGANA LETTER BO;Lo;0;L;307B 3099;;;;N;;;;;
+307D;HIRAGANA LETTER PO;Lo;0;L;307B 309A;;;;N;;;;;
+307E;HIRAGANA LETTER MA;Lo;0;L;;;;;N;;;;;
+307F;HIRAGANA LETTER MI;Lo;0;L;;;;;N;;;;;
+3080;HIRAGANA LETTER MU;Lo;0;L;;;;;N;;;;;
+3081;HIRAGANA LETTER ME;Lo;0;L;;;;;N;;;;;
+3082;HIRAGANA LETTER MO;Lo;0;L;;;;;N;;;;;
+3083;HIRAGANA LETTER SMALL YA;Lo;0;L;;;;;N;;;;;
+3084;HIRAGANA LETTER YA;Lo;0;L;;;;;N;;;;;
+3085;HIRAGANA LETTER SMALL YU;Lo;0;L;;;;;N;;;;;
+3086;HIRAGANA LETTER YU;Lo;0;L;;;;;N;;;;;
+3087;HIRAGANA LETTER SMALL YO;Lo;0;L;;;;;N;;;;;
+3088;HIRAGANA LETTER YO;Lo;0;L;;;;;N;;;;;
+3089;HIRAGANA LETTER RA;Lo;0;L;;;;;N;;;;;
+308A;HIRAGANA LETTER RI;Lo;0;L;;;;;N;;;;;
+308B;HIRAGANA LETTER RU;Lo;0;L;;;;;N;;;;;
+308C;HIRAGANA LETTER RE;Lo;0;L;;;;;N;;;;;
+308D;HIRAGANA LETTER RO;Lo;0;L;;;;;N;;;;;
+308E;HIRAGANA LETTER SMALL WA;Lo;0;L;;;;;N;;;;;
+308F;HIRAGANA LETTER WA;Lo;0;L;;;;;N;;;;;
+3090;HIRAGANA LETTER WI;Lo;0;L;;;;;N;;;;;
+3091;HIRAGANA LETTER WE;Lo;0;L;;;;;N;;;;;
+3092;HIRAGANA LETTER WO;Lo;0;L;;;;;N;;;;;
+3093;HIRAGANA LETTER N;Lo;0;L;;;;;N;;;;;
+3094;HIRAGANA LETTER VU;Lo;0;L;3046 3099;;;;N;;;;;
+3095;HIRAGANA LETTER SMALL KA;Lo;0;L;;;;;N;;;;;
+3096;HIRAGANA LETTER SMALL KE;Lo;0;L;;;;;N;;;;;
+3099;COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK;Mn;8;NSM;;;;;N;NON-SPACING KATAKANA-HIRAGANA VOICED SOUND MARK;;;;
+309A;COMBINING KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK;Mn;8;NSM;;;;;N;NON-SPACING KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK;;;;
+309B;KATAKANA-HIRAGANA VOICED SOUND MARK;Sk;0;ON;<compat> 0020 3099;;;;N;;;;;
+309C;KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK;Sk;0;ON;<compat> 0020 309A;;;;N;;;;;
+309D;HIRAGANA ITERATION MARK;Lm;0;L;;;;;N;;;;;
+309E;HIRAGANA VOICED ITERATION MARK;Lm;0;L;309D 3099;;;;N;;;;;
+309F;HIRAGANA DIGRAPH YORI;Lo;0;L;<vertical> 3088 308A;;;;N;;;;;
+30A0;KATAKANA-HIRAGANA DOUBLE HYPHEN;Pd;0;ON;;;;;N;;;;;
+30A1;KATAKANA LETTER SMALL A;Lo;0;L;;;;;N;;;;;
+30A2;KATAKANA LETTER A;Lo;0;L;;;;;N;;;;;
+30A3;KATAKANA LETTER SMALL I;Lo;0;L;;;;;N;;;;;
+30A4;KATAKANA LETTER I;Lo;0;L;;;;;N;;;;;
+30A5;KATAKANA LETTER SMALL U;Lo;0;L;;;;;N;;;;;
+30A6;KATAKANA LETTER U;Lo;0;L;;;;;N;;;;;
+30A7;KATAKANA LETTER SMALL E;Lo;0;L;;;;;N;;;;;
+30A8;KATAKANA LETTER E;Lo;0;L;;;;;N;;;;;
+30A9;KATAKANA LETTER SMALL O;Lo;0;L;;;;;N;;;;;
+30AA;KATAKANA LETTER O;Lo;0;L;;;;;N;;;;;
+30AB;KATAKANA LETTER KA;Lo;0;L;;;;;N;;;;;
+30AC;KATAKANA LETTER GA;Lo;0;L;30AB 3099;;;;N;;;;;
+30AD;KATAKANA LETTER KI;Lo;0;L;;;;;N;;;;;
+30AE;KATAKANA LETTER GI;Lo;0;L;30AD 3099;;;;N;;;;;
+30AF;KATAKANA LETTER KU;Lo;0;L;;;;;N;;;;;
+30B0;KATAKANA LETTER GU;Lo;0;L;30AF 3099;;;;N;;;;;
+30B1;KATAKANA LETTER KE;Lo;0;L;;;;;N;;;;;
+30B2;KATAKANA LETTER GE;Lo;0;L;30B1 3099;;;;N;;;;;
+30B3;KATAKANA LETTER KO;Lo;0;L;;;;;N;;;;;
+30B4;KATAKANA LETTER GO;Lo;0;L;30B3 3099;;;;N;;;;;
+30B5;KATAKANA LETTER SA;Lo;0;L;;;;;N;;;;;
+30B6;KATAKANA LETTER ZA;Lo;0;L;30B5 3099;;;;N;;;;;
+30B7;KATAKANA LETTER SI;Lo;0;L;;;;;N;;;;;
+30B8;KATAKANA LETTER ZI;Lo;0;L;30B7 3099;;;;N;;;;;
+30B9;KATAKANA LETTER SU;Lo;0;L;;;;;N;;;;;
+30BA;KATAKANA LETTER ZU;Lo;0;L;30B9 3099;;;;N;;;;;
+30BB;KATAKANA LETTER SE;Lo;0;L;;;;;N;;;;;
+30BC;KATAKANA LETTER ZE;Lo;0;L;30BB 3099;;;;N;;;;;
+30BD;KATAKANA LETTER SO;Lo;0;L;;;;;N;;;;;
+30BE;KATAKANA LETTER ZO;Lo;0;L;30BD 3099;;;;N;;;;;
+30BF;KATAKANA LETTER TA;Lo;0;L;;;;;N;;;;;
+30C0;KATAKANA LETTER DA;Lo;0;L;30BF 3099;;;;N;;;;;
+30C1;KATAKANA LETTER TI;Lo;0;L;;;;;N;;;;;
+30C2;KATAKANA LETTER DI;Lo;0;L;30C1 3099;;;;N;;;;;
+30C3;KATAKANA LETTER SMALL TU;Lo;0;L;;;;;N;;;;;
+30C4;KATAKANA LETTER TU;Lo;0;L;;;;;N;;;;;
+30C5;KATAKANA LETTER DU;Lo;0;L;30C4 3099;;;;N;;;;;
+30C6;KATAKANA LETTER TE;Lo;0;L;;;;;N;;;;;
+30C7;KATAKANA LETTER DE;Lo;0;L;30C6 3099;;;;N;;;;;
+30C8;KATAKANA LETTER TO;Lo;0;L;;;;;N;;;;;
+30C9;KATAKANA LETTER DO;Lo;0;L;30C8 3099;;;;N;;;;;
+30CA;KATAKANA LETTER NA;Lo;0;L;;;;;N;;;;;
+30CB;KATAKANA LETTER NI;Lo;0;L;;;;;N;;;;;
+30CC;KATAKANA LETTER NU;Lo;0;L;;;;;N;;;;;
+30CD;KATAKANA LETTER NE;Lo;0;L;;;;;N;;;;;
+30CE;KATAKANA LETTER NO;Lo;0;L;;;;;N;;;;;
+30CF;KATAKANA LETTER HA;Lo;0;L;;;;;N;;;;;
+30D0;KATAKANA LETTER BA;Lo;0;L;30CF 3099;;;;N;;;;;
+30D1;KATAKANA LETTER PA;Lo;0;L;30CF 309A;;;;N;;;;;
+30D2;KATAKANA LETTER HI;Lo;0;L;;;;;N;;;;;
+30D3;KATAKANA LETTER BI;Lo;0;L;30D2 3099;;;;N;;;;;
+30D4;KATAKANA LETTER PI;Lo;0;L;30D2 309A;;;;N;;;;;
+30D5;KATAKANA LETTER HU;Lo;0;L;;;;;N;;;;;
+30D6;KATAKANA LETTER BU;Lo;0;L;30D5 3099;;;;N;;;;;
+30D7;KATAKANA LETTER PU;Lo;0;L;30D5 309A;;;;N;;;;;
+30D8;KATAKANA LETTER HE;Lo;0;L;;;;;N;;;;;
+30D9;KATAKANA LETTER BE;Lo;0;L;30D8 3099;;;;N;;;;;
+30DA;KATAKANA LETTER PE;Lo;0;L;30D8 309A;;;;N;;;;;
+30DB;KATAKANA LETTER HO;Lo;0;L;;;;;N;;;;;
+30DC;KATAKANA LETTER BO;Lo;0;L;30DB 3099;;;;N;;;;;
+30DD;KATAKANA LETTER PO;Lo;0;L;30DB 309A;;;;N;;;;;
+30DE;KATAKANA LETTER MA;Lo;0;L;;;;;N;;;;;
+30DF;KATAKANA LETTER MI;Lo;0;L;;;;;N;;;;;
+30E0;KATAKANA LETTER MU;Lo;0;L;;;;;N;;;;;
+30E1;KATAKANA LETTER ME;Lo;0;L;;;;;N;;;;;
+30E2;KATAKANA LETTER MO;Lo;0;L;;;;;N;;;;;
+30E3;KATAKANA LETTER SMALL YA;Lo;0;L;;;;;N;;;;;
+30E4;KATAKANA LETTER YA;Lo;0;L;;;;;N;;;;;
+30E5;KATAKANA LETTER SMALL YU;Lo;0;L;;;;;N;;;;;
+30E6;KATAKANA LETTER YU;Lo;0;L;;;;;N;;;;;
+30E7;KATAKANA LETTER SMALL YO;Lo;0;L;;;;;N;;;;;
+30E8;KATAKANA LETTER YO;Lo;0;L;;;;;N;;;;;
+30E9;KATAKANA LETTER RA;Lo;0;L;;;;;N;;;;;
+30EA;KATAKANA LETTER RI;Lo;0;L;;;;;N;;;;;
+30EB;KATAKANA LETTER RU;Lo;0;L;;;;;N;;;;;
+30EC;KATAKANA LETTER RE;Lo;0;L;;;;;N;;;;;
+30ED;KATAKANA LETTER RO;Lo;0;L;;;;;N;;;;;
+30EE;KATAKANA LETTER SMALL WA;Lo;0;L;;;;;N;;;;;
+30EF;KATAKANA LETTER WA;Lo;0;L;;;;;N;;;;;
+30F0;KATAKANA LETTER WI;Lo;0;L;;;;;N;;;;;
+30F1;KATAKANA LETTER WE;Lo;0;L;;;;;N;;;;;
+30F2;KATAKANA LETTER WO;Lo;0;L;;;;;N;;;;;
+30F3;KATAKANA LETTER N;Lo;0;L;;;;;N;;;;;
+30F4;KATAKANA LETTER VU;Lo;0;L;30A6 3099;;;;N;;;;;
+30F5;KATAKANA LETTER SMALL KA;Lo;0;L;;;;;N;;;;;
+30F6;KATAKANA LETTER SMALL KE;Lo;0;L;;;;;N;;;;;
+30F7;KATAKANA LETTER VA;Lo;0;L;30EF 3099;;;;N;;;;;
+30F8;KATAKANA LETTER VI;Lo;0;L;30F0 3099;;;;N;;;;;
+30F9;KATAKANA LETTER VE;Lo;0;L;30F1 3099;;;;N;;;;;
+30FA;KATAKANA LETTER VO;Lo;0;L;30F2 3099;;;;N;;;;;
+30FB;KATAKANA MIDDLE DOT;Po;0;ON;;;;;N;;;;;
+30FC;KATAKANA-HIRAGANA PROLONGED SOUND MARK;Lm;0;L;;;;;N;;;;;
+30FD;KATAKANA ITERATION MARK;Lm;0;L;;;;;N;;;;;
+30FE;KATAKANA VOICED ITERATION MARK;Lm;0;L;30FD 3099;;;;N;;;;;
+30FF;KATAKANA DIGRAPH KOTO;Lo;0;L;<vertical> 30B3 30C8;;;;N;;;;;
+3105;BOPOMOFO LETTER B;Lo;0;L;;;;;N;;;;;
+3106;BOPOMOFO LETTER P;Lo;0;L;;;;;N;;;;;
+3107;BOPOMOFO LETTER M;Lo;0;L;;;;;N;;;;;
+3108;BOPOMOFO LETTER F;Lo;0;L;;;;;N;;;;;
+3109;BOPOMOFO LETTER D;Lo;0;L;;;;;N;;;;;
+310A;BOPOMOFO LETTER T;Lo;0;L;;;;;N;;;;;
+310B;BOPOMOFO LETTER N;Lo;0;L;;;;;N;;;;;
+310C;BOPOMOFO LETTER L;Lo;0;L;;;;;N;;;;;
+310D;BOPOMOFO LETTER G;Lo;0;L;;;;;N;;;;;
+310E;BOPOMOFO LETTER K;Lo;0;L;;;;;N;;;;;
+310F;BOPOMOFO LETTER H;Lo;0;L;;;;;N;;;;;
+3110;BOPOMOFO LETTER J;Lo;0;L;;;;;N;;;;;
+3111;BOPOMOFO LETTER Q;Lo;0;L;;;;;N;;;;;
+3112;BOPOMOFO LETTER X;Lo;0;L;;;;;N;;;;;
+3113;BOPOMOFO LETTER ZH;Lo;0;L;;;;;N;;;;;
+3114;BOPOMOFO LETTER CH;Lo;0;L;;;;;N;;;;;
+3115;BOPOMOFO LETTER SH;Lo;0;L;;;;;N;;;;;
+3116;BOPOMOFO LETTER R;Lo;0;L;;;;;N;;;;;
+3117;BOPOMOFO LETTER Z;Lo;0;L;;;;;N;;;;;
+3118;BOPOMOFO LETTER C;Lo;0;L;;;;;N;;;;;
+3119;BOPOMOFO LETTER S;Lo;0;L;;;;;N;;;;;
+311A;BOPOMOFO LETTER A;Lo;0;L;;;;;N;;;;;
+311B;BOPOMOFO LETTER O;Lo;0;L;;;;;N;;;;;
+311C;BOPOMOFO LETTER E;Lo;0;L;;;;;N;;;;;
+311D;BOPOMOFO LETTER EH;Lo;0;L;;;;;N;;;;;
+311E;BOPOMOFO LETTER AI;Lo;0;L;;;;;N;;;;;
+311F;BOPOMOFO LETTER EI;Lo;0;L;;;;;N;;;;;
+3120;BOPOMOFO LETTER AU;Lo;0;L;;;;;N;;;;;
+3121;BOPOMOFO LETTER OU;Lo;0;L;;;;;N;;;;;
+3122;BOPOMOFO LETTER AN;Lo;0;L;;;;;N;;;;;
+3123;BOPOMOFO LETTER EN;Lo;0;L;;;;;N;;;;;
+3124;BOPOMOFO LETTER ANG;Lo;0;L;;;;;N;;;;;
+3125;BOPOMOFO LETTER ENG;Lo;0;L;;;;;N;;;;;
+3126;BOPOMOFO LETTER ER;Lo;0;L;;;;;N;;;;;
+3127;BOPOMOFO LETTER I;Lo;0;L;;;;;N;;;;;
+3128;BOPOMOFO LETTER U;Lo;0;L;;;;;N;;;;;
+3129;BOPOMOFO LETTER IU;Lo;0;L;;;;;N;;;;;
+312A;BOPOMOFO LETTER V;Lo;0;L;;;;;N;;;;;
+312B;BOPOMOFO LETTER NG;Lo;0;L;;;;;N;;;;;
+312C;BOPOMOFO LETTER GN;Lo;0;L;;;;;N;;;;;
+312D;BOPOMOFO LETTER IH;Lo;0;L;;;;;N;;;;;
+3131;HANGUL LETTER KIYEOK;Lo;0;L;<compat> 1100;;;;N;HANGUL LETTER GIYEOG;;;;
+3132;HANGUL LETTER SSANGKIYEOK;Lo;0;L;<compat> 1101;;;;N;HANGUL LETTER SSANG GIYEOG;;;;
+3133;HANGUL LETTER KIYEOK-SIOS;Lo;0;L;<compat> 11AA;;;;N;HANGUL LETTER GIYEOG SIOS;;;;
+3134;HANGUL LETTER NIEUN;Lo;0;L;<compat> 1102;;;;N;;;;;
+3135;HANGUL LETTER NIEUN-CIEUC;Lo;0;L;<compat> 11AC;;;;N;HANGUL LETTER NIEUN JIEUJ;;;;
+3136;HANGUL LETTER NIEUN-HIEUH;Lo;0;L;<compat> 11AD;;;;N;HANGUL LETTER NIEUN HIEUH;;;;
+3137;HANGUL LETTER TIKEUT;Lo;0;L;<compat> 1103;;;;N;HANGUL LETTER DIGEUD;;;;
+3138;HANGUL LETTER SSANGTIKEUT;Lo;0;L;<compat> 1104;;;;N;HANGUL LETTER SSANG DIGEUD;;;;
+3139;HANGUL LETTER RIEUL;Lo;0;L;<compat> 1105;;;;N;HANGUL LETTER LIEUL;;;;
+313A;HANGUL LETTER RIEUL-KIYEOK;Lo;0;L;<compat> 11B0;;;;N;HANGUL LETTER LIEUL GIYEOG;;;;
+313B;HANGUL LETTER RIEUL-MIEUM;Lo;0;L;<compat> 11B1;;;;N;HANGUL LETTER LIEUL MIEUM;;;;
+313C;HANGUL LETTER RIEUL-PIEUP;Lo;0;L;<compat> 11B2;;;;N;HANGUL LETTER LIEUL BIEUB;;;;
+313D;HANGUL LETTER RIEUL-SIOS;Lo;0;L;<compat> 11B3;;;;N;HANGUL LETTER LIEUL SIOS;;;;
+313E;HANGUL LETTER RIEUL-THIEUTH;Lo;0;L;<compat> 11B4;;;;N;HANGUL LETTER LIEUL TIEUT;;;;
+313F;HANGUL LETTER RIEUL-PHIEUPH;Lo;0;L;<compat> 11B5;;;;N;HANGUL LETTER LIEUL PIEUP;;;;
+3140;HANGUL LETTER RIEUL-HIEUH;Lo;0;L;<compat> 111A;;;;N;HANGUL LETTER LIEUL HIEUH;;;;
+3141;HANGUL LETTER MIEUM;Lo;0;L;<compat> 1106;;;;N;;;;;
+3142;HANGUL LETTER PIEUP;Lo;0;L;<compat> 1107;;;;N;HANGUL LETTER BIEUB;;;;
+3143;HANGUL LETTER SSANGPIEUP;Lo;0;L;<compat> 1108;;;;N;HANGUL LETTER SSANG BIEUB;;;;
+3144;HANGUL LETTER PIEUP-SIOS;Lo;0;L;<compat> 1121;;;;N;HANGUL LETTER BIEUB SIOS;;;;
+3145;HANGUL LETTER SIOS;Lo;0;L;<compat> 1109;;;;N;;;;;
+3146;HANGUL LETTER SSANGSIOS;Lo;0;L;<compat> 110A;;;;N;HANGUL LETTER SSANG SIOS;;;;
+3147;HANGUL LETTER IEUNG;Lo;0;L;<compat> 110B;;;;N;;;;;
+3148;HANGUL LETTER CIEUC;Lo;0;L;<compat> 110C;;;;N;HANGUL LETTER JIEUJ;;;;
+3149;HANGUL LETTER SSANGCIEUC;Lo;0;L;<compat> 110D;;;;N;HANGUL LETTER SSANG JIEUJ;;;;
+314A;HANGUL LETTER CHIEUCH;Lo;0;L;<compat> 110E;;;;N;HANGUL LETTER CIEUC;;;;
+314B;HANGUL LETTER KHIEUKH;Lo;0;L;<compat> 110F;;;;N;HANGUL LETTER KIYEOK;;;;
+314C;HANGUL LETTER THIEUTH;Lo;0;L;<compat> 1110;;;;N;HANGUL LETTER TIEUT;;;;
+314D;HANGUL LETTER PHIEUPH;Lo;0;L;<compat> 1111;;;;N;HANGUL LETTER PIEUP;;;;
+314E;HANGUL LETTER HIEUH;Lo;0;L;<compat> 1112;;;;N;;;;;
+314F;HANGUL LETTER A;Lo;0;L;<compat> 1161;;;;N;;;;;
+3150;HANGUL LETTER AE;Lo;0;L;<compat> 1162;;;;N;;;;;
+3151;HANGUL LETTER YA;Lo;0;L;<compat> 1163;;;;N;;;;;
+3152;HANGUL LETTER YAE;Lo;0;L;<compat> 1164;;;;N;;;;;
+3153;HANGUL LETTER EO;Lo;0;L;<compat> 1165;;;;N;;;;;
+3154;HANGUL LETTER E;Lo;0;L;<compat> 1166;;;;N;;;;;
+3155;HANGUL LETTER YEO;Lo;0;L;<compat> 1167;;;;N;;;;;
+3156;HANGUL LETTER YE;Lo;0;L;<compat> 1168;;;;N;;;;;
+3157;HANGUL LETTER O;Lo;0;L;<compat> 1169;;;;N;;;;;
+3158;HANGUL LETTER WA;Lo;0;L;<compat> 116A;;;;N;;;;;
+3159;HANGUL LETTER WAE;Lo;0;L;<compat> 116B;;;;N;;;;;
+315A;HANGUL LETTER OE;Lo;0;L;<compat> 116C;;;;N;;;;;
+315B;HANGUL LETTER YO;Lo;0;L;<compat> 116D;;;;N;;;;;
+315C;HANGUL LETTER U;Lo;0;L;<compat> 116E;;;;N;;;;;
+315D;HANGUL LETTER WEO;Lo;0;L;<compat> 116F;;;;N;;;;;
+315E;HANGUL LETTER WE;Lo;0;L;<compat> 1170;;;;N;;;;;
+315F;HANGUL LETTER WI;Lo;0;L;<compat> 1171;;;;N;;;;;
+3160;HANGUL LETTER YU;Lo;0;L;<compat> 1172;;;;N;;;;;
+3161;HANGUL LETTER EU;Lo;0;L;<compat> 1173;;;;N;;;;;
+3162;HANGUL LETTER YI;Lo;0;L;<compat> 1174;;;;N;;;;;
+3163;HANGUL LETTER I;Lo;0;L;<compat> 1175;;;;N;;;;;
+3164;HANGUL FILLER;Lo;0;L;<compat> 1160;;;;N;HANGUL CAE OM;;;;
+3165;HANGUL LETTER SSANGNIEUN;Lo;0;L;<compat> 1114;;;;N;HANGUL LETTER SSANG NIEUN;;;;
+3166;HANGUL LETTER NIEUN-TIKEUT;Lo;0;L;<compat> 1115;;;;N;HANGUL LETTER NIEUN DIGEUD;;;;
+3167;HANGUL LETTER NIEUN-SIOS;Lo;0;L;<compat> 11C7;;;;N;HANGUL LETTER NIEUN SIOS;;;;
+3168;HANGUL LETTER NIEUN-PANSIOS;Lo;0;L;<compat> 11C8;;;;N;HANGUL LETTER NIEUN BAN CHI EUM;;;;
+3169;HANGUL LETTER RIEUL-KIYEOK-SIOS;Lo;0;L;<compat> 11CC;;;;N;HANGUL LETTER LIEUL GIYEOG SIOS;;;;
+316A;HANGUL LETTER RIEUL-TIKEUT;Lo;0;L;<compat> 11CE;;;;N;HANGUL LETTER LIEUL DIGEUD;;;;
+316B;HANGUL LETTER RIEUL-PIEUP-SIOS;Lo;0;L;<compat> 11D3;;;;N;HANGUL LETTER LIEUL BIEUB SIOS;;;;
+316C;HANGUL LETTER RIEUL-PANSIOS;Lo;0;L;<compat> 11D7;;;;N;HANGUL LETTER LIEUL BAN CHI EUM;;;;
+316D;HANGUL LETTER RIEUL-YEORINHIEUH;Lo;0;L;<compat> 11D9;;;;N;HANGUL LETTER LIEUL YEOLIN HIEUH;;;;
+316E;HANGUL LETTER MIEUM-PIEUP;Lo;0;L;<compat> 111C;;;;N;HANGUL LETTER MIEUM BIEUB;;;;
+316F;HANGUL LETTER MIEUM-SIOS;Lo;0;L;<compat> 11DD;;;;N;HANGUL LETTER MIEUM SIOS;;;;
+3170;HANGUL LETTER MIEUM-PANSIOS;Lo;0;L;<compat> 11DF;;;;N;HANGUL LETTER BIEUB BAN CHI EUM;;;;
+3171;HANGUL LETTER KAPYEOUNMIEUM;Lo;0;L;<compat> 111D;;;;N;HANGUL LETTER MIEUM SUN GYEONG EUM;;;;
+3172;HANGUL LETTER PIEUP-KIYEOK;Lo;0;L;<compat> 111E;;;;N;HANGUL LETTER BIEUB GIYEOG;;;;
+3173;HANGUL LETTER PIEUP-TIKEUT;Lo;0;L;<compat> 1120;;;;N;HANGUL LETTER BIEUB DIGEUD;;;;
+3174;HANGUL LETTER PIEUP-SIOS-KIYEOK;Lo;0;L;<compat> 1122;;;;N;HANGUL LETTER BIEUB SIOS GIYEOG;;;;
+3175;HANGUL LETTER PIEUP-SIOS-TIKEUT;Lo;0;L;<compat> 1123;;;;N;HANGUL LETTER BIEUB SIOS DIGEUD;;;;
+3176;HANGUL LETTER PIEUP-CIEUC;Lo;0;L;<compat> 1127;;;;N;HANGUL LETTER BIEUB JIEUJ;;;;
+3177;HANGUL LETTER PIEUP-THIEUTH;Lo;0;L;<compat> 1129;;;;N;HANGUL LETTER BIEUB TIEUT;;;;
+3178;HANGUL LETTER KAPYEOUNPIEUP;Lo;0;L;<compat> 112B;;;;N;HANGUL LETTER BIEUB SUN GYEONG EUM;;;;
+3179;HANGUL LETTER KAPYEOUNSSANGPIEUP;Lo;0;L;<compat> 112C;;;;N;HANGUL LETTER SSANG BIEUB SUN GYEONG EUM;;;;
+317A;HANGUL LETTER SIOS-KIYEOK;Lo;0;L;<compat> 112D;;;;N;HANGUL LETTER SIOS GIYEOG;;;;
+317B;HANGUL LETTER SIOS-NIEUN;Lo;0;L;<compat> 112E;;;;N;HANGUL LETTER SIOS NIEUN;;;;
+317C;HANGUL LETTER SIOS-TIKEUT;Lo;0;L;<compat> 112F;;;;N;HANGUL LETTER SIOS DIGEUD;;;;
+317D;HANGUL LETTER SIOS-PIEUP;Lo;0;L;<compat> 1132;;;;N;HANGUL LETTER SIOS BIEUB;;;;
+317E;HANGUL LETTER SIOS-CIEUC;Lo;0;L;<compat> 1136;;;;N;HANGUL LETTER SIOS JIEUJ;;;;
+317F;HANGUL LETTER PANSIOS;Lo;0;L;<compat> 1140;;;;N;HANGUL LETTER BAN CHI EUM;;;;
+3180;HANGUL LETTER SSANGIEUNG;Lo;0;L;<compat> 1147;;;;N;HANGUL LETTER SSANG IEUNG;;;;
+3181;HANGUL LETTER YESIEUNG;Lo;0;L;<compat> 114C;;;;N;HANGUL LETTER NGIEUNG;;;;
+3182;HANGUL LETTER YESIEUNG-SIOS;Lo;0;L;<compat> 11F1;;;;N;HANGUL LETTER NGIEUNG SIOS;;;;
+3183;HANGUL LETTER YESIEUNG-PANSIOS;Lo;0;L;<compat> 11F2;;;;N;HANGUL LETTER NGIEUNG BAN CHI EUM;;;;
+3184;HANGUL LETTER KAPYEOUNPHIEUPH;Lo;0;L;<compat> 1157;;;;N;HANGUL LETTER PIEUP SUN GYEONG EUM;;;;
+3185;HANGUL LETTER SSANGHIEUH;Lo;0;L;<compat> 1158;;;;N;HANGUL LETTER SSANG HIEUH;;;;
+3186;HANGUL LETTER YEORINHIEUH;Lo;0;L;<compat> 1159;;;;N;HANGUL LETTER YEOLIN HIEUH;;;;
+3187;HANGUL LETTER YO-YA;Lo;0;L;<compat> 1184;;;;N;HANGUL LETTER YOYA;;;;
+3188;HANGUL LETTER YO-YAE;Lo;0;L;<compat> 1185;;;;N;HANGUL LETTER YOYAE;;;;
+3189;HANGUL LETTER YO-I;Lo;0;L;<compat> 1188;;;;N;HANGUL LETTER YOI;;;;
+318A;HANGUL LETTER YU-YEO;Lo;0;L;<compat> 1191;;;;N;HANGUL LETTER YUYEO;;;;
+318B;HANGUL LETTER YU-YE;Lo;0;L;<compat> 1192;;;;N;HANGUL LETTER YUYE;;;;
+318C;HANGUL LETTER YU-I;Lo;0;L;<compat> 1194;;;;N;HANGUL LETTER YUI;;;;
+318D;HANGUL LETTER ARAEA;Lo;0;L;<compat> 119E;;;;N;HANGUL LETTER ALAE A;;;;
+318E;HANGUL LETTER ARAEAE;Lo;0;L;<compat> 11A1;;;;N;HANGUL LETTER ALAE AE;;;;
+3190;IDEOGRAPHIC ANNOTATION LINKING MARK;So;0;L;;;;;N;KANBUN TATETEN;;;;
+3191;IDEOGRAPHIC ANNOTATION REVERSE MARK;So;0;L;;;;;N;KAERITEN RE;;;;
+3192;IDEOGRAPHIC ANNOTATION ONE MARK;No;0;L;<super> 4E00;;;1;N;KAERITEN ITI;;;;
+3193;IDEOGRAPHIC ANNOTATION TWO MARK;No;0;L;<super> 4E8C;;;2;N;KAERITEN NI;;;;
+3194;IDEOGRAPHIC ANNOTATION THREE MARK;No;0;L;<super> 4E09;;;3;N;KAERITEN SAN;;;;
+3195;IDEOGRAPHIC ANNOTATION FOUR MARK;No;0;L;<super> 56DB;;;4;N;KAERITEN SI;;;;
+3196;IDEOGRAPHIC ANNOTATION TOP MARK;So;0;L;<super> 4E0A;;;;N;KAERITEN ZYOU;;;;
+3197;IDEOGRAPHIC ANNOTATION MIDDLE MARK;So;0;L;<super> 4E2D;;;;N;KAERITEN TYUU;;;;
+3198;IDEOGRAPHIC ANNOTATION BOTTOM MARK;So;0;L;<super> 4E0B;;;;N;KAERITEN GE;;;;
+3199;IDEOGRAPHIC ANNOTATION FIRST MARK;So;0;L;<super> 7532;;;;N;KAERITEN KOU;;;;
+319A;IDEOGRAPHIC ANNOTATION SECOND MARK;So;0;L;<super> 4E59;;;;N;KAERITEN OTU;;;;
+319B;IDEOGRAPHIC ANNOTATION THIRD MARK;So;0;L;<super> 4E19;;;;N;KAERITEN HEI;;;;
+319C;IDEOGRAPHIC ANNOTATION FOURTH MARK;So;0;L;<super> 4E01;;;;N;KAERITEN TEI;;;;
+319D;IDEOGRAPHIC ANNOTATION HEAVEN MARK;So;0;L;<super> 5929;;;;N;KAERITEN TEN;;;;
+319E;IDEOGRAPHIC ANNOTATION EARTH MARK;So;0;L;<super> 5730;;;;N;KAERITEN TI;;;;
+319F;IDEOGRAPHIC ANNOTATION MAN MARK;So;0;L;<super> 4EBA;;;;N;KAERITEN ZIN;;;;
+31A0;BOPOMOFO LETTER BU;Lo;0;L;;;;;N;;;;;
+31A1;BOPOMOFO LETTER ZI;Lo;0;L;;;;;N;;;;;
+31A2;BOPOMOFO LETTER JI;Lo;0;L;;;;;N;;;;;
+31A3;BOPOMOFO LETTER GU;Lo;0;L;;;;;N;;;;;
+31A4;BOPOMOFO LETTER EE;Lo;0;L;;;;;N;;;;;
+31A5;BOPOMOFO LETTER ENN;Lo;0;L;;;;;N;;;;;
+31A6;BOPOMOFO LETTER OO;Lo;0;L;;;;;N;;;;;
+31A7;BOPOMOFO LETTER ONN;Lo;0;L;;;;;N;;;;;
+31A8;BOPOMOFO LETTER IR;Lo;0;L;;;;;N;;;;;
+31A9;BOPOMOFO LETTER ANN;Lo;0;L;;;;;N;;;;;
+31AA;BOPOMOFO LETTER INN;Lo;0;L;;;;;N;;;;;
+31AB;BOPOMOFO LETTER UNN;Lo;0;L;;;;;N;;;;;
+31AC;BOPOMOFO LETTER IM;Lo;0;L;;;;;N;;;;;
+31AD;BOPOMOFO LETTER NGG;Lo;0;L;;;;;N;;;;;
+31AE;BOPOMOFO LETTER AINN;Lo;0;L;;;;;N;;;;;
+31AF;BOPOMOFO LETTER AUNN;Lo;0;L;;;;;N;;;;;
+31B0;BOPOMOFO LETTER AM;Lo;0;L;;;;;N;;;;;
+31B1;BOPOMOFO LETTER OM;Lo;0;L;;;;;N;;;;;
+31B2;BOPOMOFO LETTER ONG;Lo;0;L;;;;;N;;;;;
+31B3;BOPOMOFO LETTER INNN;Lo;0;L;;;;;N;;;;;
+31B4;BOPOMOFO FINAL LETTER P;Lo;0;L;;;;;N;;;;;
+31B5;BOPOMOFO FINAL LETTER T;Lo;0;L;;;;;N;;;;;
+31B6;BOPOMOFO FINAL LETTER K;Lo;0;L;;;;;N;;;;;
+31B7;BOPOMOFO FINAL LETTER H;Lo;0;L;;;;;N;;;;;
+31B8;BOPOMOFO LETTER GH;Lo;0;L;;;;;N;;;;;
+31B9;BOPOMOFO LETTER LH;Lo;0;L;;;;;N;;;;;
+31BA;BOPOMOFO LETTER ZY;Lo;0;L;;;;;N;;;;;
+31C0;CJK STROKE T;So;0;ON;;;;;N;;;;;
+31C1;CJK STROKE WG;So;0;ON;;;;;N;;;;;
+31C2;CJK STROKE XG;So;0;ON;;;;;N;;;;;
+31C3;CJK STROKE BXG;So;0;ON;;;;;N;;;;;
+31C4;CJK STROKE SW;So;0;ON;;;;;N;;;;;
+31C5;CJK STROKE HZZ;So;0;ON;;;;;N;;;;;
+31C6;CJK STROKE HZG;So;0;ON;;;;;N;;;;;
+31C7;CJK STROKE HP;So;0;ON;;;;;N;;;;;
+31C8;CJK STROKE HZWG;So;0;ON;;;;;N;;;;;
+31C9;CJK STROKE SZWG;So;0;ON;;;;;N;;;;;
+31CA;CJK STROKE HZT;So;0;ON;;;;;N;;;;;
+31CB;CJK STROKE HZZP;So;0;ON;;;;;N;;;;;
+31CC;CJK STROKE HPWG;So;0;ON;;;;;N;;;;;
+31CD;CJK STROKE HZW;So;0;ON;;;;;N;;;;;
+31CE;CJK STROKE HZZZ;So;0;ON;;;;;N;;;;;
+31CF;CJK STROKE N;So;0;ON;;;;;N;;;;;
+31D0;CJK STROKE H;So;0;ON;;;;;N;;;;;
+31D1;CJK STROKE S;So;0;ON;;;;;N;;;;;
+31D2;CJK STROKE P;So;0;ON;;;;;N;;;;;
+31D3;CJK STROKE SP;So;0;ON;;;;;N;;;;;
+31D4;CJK STROKE D;So;0;ON;;;;;N;;;;;
+31D5;CJK STROKE HZ;So;0;ON;;;;;N;;;;;
+31D6;CJK STROKE HG;So;0;ON;;;;;N;;;;;
+31D7;CJK STROKE SZ;So;0;ON;;;;;N;;;;;
+31D8;CJK STROKE SWZ;So;0;ON;;;;;N;;;;;
+31D9;CJK STROKE ST;So;0;ON;;;;;N;;;;;
+31DA;CJK STROKE SG;So;0;ON;;;;;N;;;;;
+31DB;CJK STROKE PD;So;0;ON;;;;;N;;;;;
+31DC;CJK STROKE PZ;So;0;ON;;;;;N;;;;;
+31DD;CJK STROKE TN;So;0;ON;;;;;N;;;;;
+31DE;CJK STROKE SZZ;So;0;ON;;;;;N;;;;;
+31DF;CJK STROKE SWG;So;0;ON;;;;;N;;;;;
+31E0;CJK STROKE HXWG;So;0;ON;;;;;N;;;;;
+31E1;CJK STROKE HZZZG;So;0;ON;;;;;N;;;;;
+31E2;CJK STROKE PG;So;0;ON;;;;;N;;;;;
+31E3;CJK STROKE Q;So;0;ON;;;;;N;;;;;
+31F0;KATAKANA LETTER SMALL KU;Lo;0;L;;;;;N;;;;;
+31F1;KATAKANA LETTER SMALL SI;Lo;0;L;;;;;N;;;;;
+31F2;KATAKANA LETTER SMALL SU;Lo;0;L;;;;;N;;;;;
+31F3;KATAKANA LETTER SMALL TO;Lo;0;L;;;;;N;;;;;
+31F4;KATAKANA LETTER SMALL NU;Lo;0;L;;;;;N;;;;;
+31F5;KATAKANA LETTER SMALL HA;Lo;0;L;;;;;N;;;;;
+31F6;KATAKANA LETTER SMALL HI;Lo;0;L;;;;;N;;;;;
+31F7;KATAKANA LETTER SMALL HU;Lo;0;L;;;;;N;;;;;
+31F8;KATAKANA LETTER SMALL HE;Lo;0;L;;;;;N;;;;;
+31F9;KATAKANA LETTER SMALL HO;Lo;0;L;;;;;N;;;;;
+31FA;KATAKANA LETTER SMALL MU;Lo;0;L;;;;;N;;;;;
+31FB;KATAKANA LETTER SMALL RA;Lo;0;L;;;;;N;;;;;
+31FC;KATAKANA LETTER SMALL RI;Lo;0;L;;;;;N;;;;;
+31FD;KATAKANA LETTER SMALL RU;Lo;0;L;;;;;N;;;;;
+31FE;KATAKANA LETTER SMALL RE;Lo;0;L;;;;;N;;;;;
+31FF;KATAKANA LETTER SMALL RO;Lo;0;L;;;;;N;;;;;
+3200;PARENTHESIZED HANGUL KIYEOK;So;0;L;<compat> 0028 1100 0029;;;;N;PARENTHESIZED HANGUL GIYEOG;;;;
+3201;PARENTHESIZED HANGUL NIEUN;So;0;L;<compat> 0028 1102 0029;;;;N;;;;;
+3202;PARENTHESIZED HANGUL TIKEUT;So;0;L;<compat> 0028 1103 0029;;;;N;PARENTHESIZED HANGUL DIGEUD;;;;
+3203;PARENTHESIZED HANGUL RIEUL;So;0;L;<compat> 0028 1105 0029;;;;N;PARENTHESIZED HANGUL LIEUL;;;;
+3204;PARENTHESIZED HANGUL MIEUM;So;0;L;<compat> 0028 1106 0029;;;;N;;;;;
+3205;PARENTHESIZED HANGUL PIEUP;So;0;L;<compat> 0028 1107 0029;;;;N;PARENTHESIZED HANGUL BIEUB;;;;
+3206;PARENTHESIZED HANGUL SIOS;So;0;L;<compat> 0028 1109 0029;;;;N;;;;;
+3207;PARENTHESIZED HANGUL IEUNG;So;0;L;<compat> 0028 110B 0029;;;;N;;;;;
+3208;PARENTHESIZED HANGUL CIEUC;So;0;L;<compat> 0028 110C 0029;;;;N;PARENTHESIZED HANGUL JIEUJ;;;;
+3209;PARENTHESIZED HANGUL CHIEUCH;So;0;L;<compat> 0028 110E 0029;;;;N;PARENTHESIZED HANGUL CIEUC;;;;
+320A;PARENTHESIZED HANGUL KHIEUKH;So;0;L;<compat> 0028 110F 0029;;;;N;PARENTHESIZED HANGUL KIYEOK;;;;
+320B;PARENTHESIZED HANGUL THIEUTH;So;0;L;<compat> 0028 1110 0029;;;;N;PARENTHESIZED HANGUL TIEUT;;;;
+320C;PARENTHESIZED HANGUL PHIEUPH;So;0;L;<compat> 0028 1111 0029;;;;N;PARENTHESIZED HANGUL PIEUP;;;;
+320D;PARENTHESIZED HANGUL HIEUH;So;0;L;<compat> 0028 1112 0029;;;;N;;;;;
+320E;PARENTHESIZED HANGUL KIYEOK A;So;0;L;<compat> 0028 1100 1161 0029;;;;N;PARENTHESIZED HANGUL GA;;;;
+320F;PARENTHESIZED HANGUL NIEUN A;So;0;L;<compat> 0028 1102 1161 0029;;;;N;PARENTHESIZED HANGUL NA;;;;
+3210;PARENTHESIZED HANGUL TIKEUT A;So;0;L;<compat> 0028 1103 1161 0029;;;;N;PARENTHESIZED HANGUL DA;;;;
+3211;PARENTHESIZED HANGUL RIEUL A;So;0;L;<compat> 0028 1105 1161 0029;;;;N;PARENTHESIZED HANGUL LA;;;;
+3212;PARENTHESIZED HANGUL MIEUM A;So;0;L;<compat> 0028 1106 1161 0029;;;;N;PARENTHESIZED HANGUL MA;;;;
+3213;PARENTHESIZED HANGUL PIEUP A;So;0;L;<compat> 0028 1107 1161 0029;;;;N;PARENTHESIZED HANGUL BA;;;;
+3214;PARENTHESIZED HANGUL SIOS A;So;0;L;<compat> 0028 1109 1161 0029;;;;N;PARENTHESIZED HANGUL SA;;;;
+3215;PARENTHESIZED HANGUL IEUNG A;So;0;L;<compat> 0028 110B 1161 0029;;;;N;PARENTHESIZED HANGUL A;;;;
+3216;PARENTHESIZED HANGUL CIEUC A;So;0;L;<compat> 0028 110C 1161 0029;;;;N;PARENTHESIZED HANGUL JA;;;;
+3217;PARENTHESIZED HANGUL CHIEUCH A;So;0;L;<compat> 0028 110E 1161 0029;;;;N;PARENTHESIZED HANGUL CA;;;;
+3218;PARENTHESIZED HANGUL KHIEUKH A;So;0;L;<compat> 0028 110F 1161 0029;;;;N;PARENTHESIZED HANGUL KA;;;;
+3219;PARENTHESIZED HANGUL THIEUTH A;So;0;L;<compat> 0028 1110 1161 0029;;;;N;PARENTHESIZED HANGUL TA;;;;
+321A;PARENTHESIZED HANGUL PHIEUPH A;So;0;L;<compat> 0028 1111 1161 0029;;;;N;PARENTHESIZED HANGUL PA;;;;
+321B;PARENTHESIZED HANGUL HIEUH A;So;0;L;<compat> 0028 1112 1161 0029;;;;N;PARENTHESIZED HANGUL HA;;;;
+321C;PARENTHESIZED HANGUL CIEUC U;So;0;L;<compat> 0028 110C 116E 0029;;;;N;PARENTHESIZED HANGUL JU;;;;
+321D;PARENTHESIZED KOREAN CHARACTER OJEON;So;0;ON;<compat> 0028 110B 1169 110C 1165 11AB 0029;;;;N;;;;;
+321E;PARENTHESIZED KOREAN CHARACTER O HU;So;0;ON;<compat> 0028 110B 1169 1112 116E 0029;;;;N;;;;;
+3220;PARENTHESIZED IDEOGRAPH ONE;No;0;L;<compat> 0028 4E00 0029;;;1;N;;;;;
+3221;PARENTHESIZED IDEOGRAPH TWO;No;0;L;<compat> 0028 4E8C 0029;;;2;N;;;;;
+3222;PARENTHESIZED IDEOGRAPH THREE;No;0;L;<compat> 0028 4E09 0029;;;3;N;;;;;
+3223;PARENTHESIZED IDEOGRAPH FOUR;No;0;L;<compat> 0028 56DB 0029;;;4;N;;;;;
+3224;PARENTHESIZED IDEOGRAPH FIVE;No;0;L;<compat> 0028 4E94 0029;;;5;N;;;;;
+3225;PARENTHESIZED IDEOGRAPH SIX;No;0;L;<compat> 0028 516D 0029;;;6;N;;;;;
+3226;PARENTHESIZED IDEOGRAPH SEVEN;No;0;L;<compat> 0028 4E03 0029;;;7;N;;;;;
+3227;PARENTHESIZED IDEOGRAPH EIGHT;No;0;L;<compat> 0028 516B 0029;;;8;N;;;;;
+3228;PARENTHESIZED IDEOGRAPH NINE;No;0;L;<compat> 0028 4E5D 0029;;;9;N;;;;;
+3229;PARENTHESIZED IDEOGRAPH TEN;No;0;L;<compat> 0028 5341 0029;;;10;N;;;;;
+322A;PARENTHESIZED IDEOGRAPH MOON;So;0;L;<compat> 0028 6708 0029;;;;N;;;;;
+322B;PARENTHESIZED IDEOGRAPH FIRE;So;0;L;<compat> 0028 706B 0029;;;;N;;;;;
+322C;PARENTHESIZED IDEOGRAPH WATER;So;0;L;<compat> 0028 6C34 0029;;;;N;;;;;
+322D;PARENTHESIZED IDEOGRAPH WOOD;So;0;L;<compat> 0028 6728 0029;;;;N;;;;;
+322E;PARENTHESIZED IDEOGRAPH METAL;So;0;L;<compat> 0028 91D1 0029;;;;N;;;;;
+322F;PARENTHESIZED IDEOGRAPH EARTH;So;0;L;<compat> 0028 571F 0029;;;;N;;;;;
+3230;PARENTHESIZED IDEOGRAPH SUN;So;0;L;<compat> 0028 65E5 0029;;;;N;;;;;
+3231;PARENTHESIZED IDEOGRAPH STOCK;So;0;L;<compat> 0028 682A 0029;;;;N;;;;;
+3232;PARENTHESIZED IDEOGRAPH HAVE;So;0;L;<compat> 0028 6709 0029;;;;N;;;;;
+3233;PARENTHESIZED IDEOGRAPH SOCIETY;So;0;L;<compat> 0028 793E 0029;;;;N;;;;;
+3234;PARENTHESIZED IDEOGRAPH NAME;So;0;L;<compat> 0028 540D 0029;;;;N;;;;;
+3235;PARENTHESIZED IDEOGRAPH SPECIAL;So;0;L;<compat> 0028 7279 0029;;;;N;;;;;
+3236;PARENTHESIZED IDEOGRAPH FINANCIAL;So;0;L;<compat> 0028 8CA1 0029;;;;N;;;;;
+3237;PARENTHESIZED IDEOGRAPH CONGRATULATION;So;0;L;<compat> 0028 795D 0029;;;;N;;;;;
+3238;PARENTHESIZED IDEOGRAPH LABOR;So;0;L;<compat> 0028 52B4 0029;;;;N;;;;;
+3239;PARENTHESIZED IDEOGRAPH REPRESENT;So;0;L;<compat> 0028 4EE3 0029;;;;N;;;;;
+323A;PARENTHESIZED IDEOGRAPH CALL;So;0;L;<compat> 0028 547C 0029;;;;N;;;;;
+323B;PARENTHESIZED IDEOGRAPH STUDY;So;0;L;<compat> 0028 5B66 0029;;;;N;;;;;
+323C;PARENTHESIZED IDEOGRAPH SUPERVISE;So;0;L;<compat> 0028 76E3 0029;;;;N;;;;;
+323D;PARENTHESIZED IDEOGRAPH ENTERPRISE;So;0;L;<compat> 0028 4F01 0029;;;;N;;;;;
+323E;PARENTHESIZED IDEOGRAPH RESOURCE;So;0;L;<compat> 0028 8CC7 0029;;;;N;;;;;
+323F;PARENTHESIZED IDEOGRAPH ALLIANCE;So;0;L;<compat> 0028 5354 0029;;;;N;;;;;
+3240;PARENTHESIZED IDEOGRAPH FESTIVAL;So;0;L;<compat> 0028 796D 0029;;;;N;;;;;
+3241;PARENTHESIZED IDEOGRAPH REST;So;0;L;<compat> 0028 4F11 0029;;;;N;;;;;
+3242;PARENTHESIZED IDEOGRAPH SELF;So;0;L;<compat> 0028 81EA 0029;;;;N;;;;;
+3243;PARENTHESIZED IDEOGRAPH REACH;So;0;L;<compat> 0028 81F3 0029;;;;N;;;;;
+3244;CIRCLED IDEOGRAPH QUESTION;So;0;L;<circle> 554F;;;;N;;;;;
+3245;CIRCLED IDEOGRAPH KINDERGARTEN;So;0;L;<circle> 5E7C;;;;N;;;;;
+3246;CIRCLED IDEOGRAPH SCHOOL;So;0;L;<circle> 6587;;;;N;;;;;
+3247;CIRCLED IDEOGRAPH KOTO;So;0;L;<circle> 7B8F;;;;N;;;;;
+3248;CIRCLED NUMBER TEN ON BLACK SQUARE;So;0;L;;;;;N;;;;;
+3249;CIRCLED NUMBER TWENTY ON BLACK SQUARE;So;0;L;;;;;N;;;;;
+324A;CIRCLED NUMBER THIRTY ON BLACK SQUARE;So;0;L;;;;;N;;;;;
+324B;CIRCLED NUMBER FORTY ON BLACK SQUARE;So;0;L;;;;;N;;;;;
+324C;CIRCLED NUMBER FIFTY ON BLACK SQUARE;So;0;L;;;;;N;;;;;
+324D;CIRCLED NUMBER SIXTY ON BLACK SQUARE;So;0;L;;;;;N;;;;;
+324E;CIRCLED NUMBER SEVENTY ON BLACK SQUARE;So;0;L;;;;;N;;;;;
+324F;CIRCLED NUMBER EIGHTY ON BLACK SQUARE;So;0;L;;;;;N;;;;;
+3250;PARTNERSHIP SIGN;So;0;ON;<square> 0050 0054 0045;;;;N;;;;;
+3251;CIRCLED NUMBER TWENTY ONE;No;0;ON;<circle> 0032 0031;;;21;N;;;;;
+3252;CIRCLED NUMBER TWENTY TWO;No;0;ON;<circle> 0032 0032;;;22;N;;;;;
+3253;CIRCLED NUMBER TWENTY THREE;No;0;ON;<circle> 0032 0033;;;23;N;;;;;
+3254;CIRCLED NUMBER TWENTY FOUR;No;0;ON;<circle> 0032 0034;;;24;N;;;;;
+3255;CIRCLED NUMBER TWENTY FIVE;No;0;ON;<circle> 0032 0035;;;25;N;;;;;
+3256;CIRCLED NUMBER TWENTY SIX;No;0;ON;<circle> 0032 0036;;;26;N;;;;;
+3257;CIRCLED NUMBER TWENTY SEVEN;No;0;ON;<circle> 0032 0037;;;27;N;;;;;
+3258;CIRCLED NUMBER TWENTY EIGHT;No;0;ON;<circle> 0032 0038;;;28;N;;;;;
+3259;CIRCLED NUMBER TWENTY NINE;No;0;ON;<circle> 0032 0039;;;29;N;;;;;
+325A;CIRCLED NUMBER THIRTY;No;0;ON;<circle> 0033 0030;;;30;N;;;;;
+325B;CIRCLED NUMBER THIRTY ONE;No;0;ON;<circle> 0033 0031;;;31;N;;;;;
+325C;CIRCLED NUMBER THIRTY TWO;No;0;ON;<circle> 0033 0032;;;32;N;;;;;
+325D;CIRCLED NUMBER THIRTY THREE;No;0;ON;<circle> 0033 0033;;;33;N;;;;;
+325E;CIRCLED NUMBER THIRTY FOUR;No;0;ON;<circle> 0033 0034;;;34;N;;;;;
+325F;CIRCLED NUMBER THIRTY FIVE;No;0;ON;<circle> 0033 0035;;;35;N;;;;;
+3260;CIRCLED HANGUL KIYEOK;So;0;L;<circle> 1100;;;;N;CIRCLED HANGUL GIYEOG;;;;
+3261;CIRCLED HANGUL NIEUN;So;0;L;<circle> 1102;;;;N;;;;;
+3262;CIRCLED HANGUL TIKEUT;So;0;L;<circle> 1103;;;;N;CIRCLED HANGUL DIGEUD;;;;
+3263;CIRCLED HANGUL RIEUL;So;0;L;<circle> 1105;;;;N;CIRCLED HANGUL LIEUL;;;;
+3264;CIRCLED HANGUL MIEUM;So;0;L;<circle> 1106;;;;N;;;;;
+3265;CIRCLED HANGUL PIEUP;So;0;L;<circle> 1107;;;;N;CIRCLED HANGUL BIEUB;;;;
+3266;CIRCLED HANGUL SIOS;So;0;L;<circle> 1109;;;;N;;;;;
+3267;CIRCLED HANGUL IEUNG;So;0;L;<circle> 110B;;;;N;;;;;
+3268;CIRCLED HANGUL CIEUC;So;0;L;<circle> 110C;;;;N;CIRCLED HANGUL JIEUJ;;;;
+3269;CIRCLED HANGUL CHIEUCH;So;0;L;<circle> 110E;;;;N;CIRCLED HANGUL CIEUC;;;;
+326A;CIRCLED HANGUL KHIEUKH;So;0;L;<circle> 110F;;;;N;CIRCLED HANGUL KIYEOK;;;;
+326B;CIRCLED HANGUL THIEUTH;So;0;L;<circle> 1110;;;;N;CIRCLED HANGUL TIEUT;;;;
+326C;CIRCLED HANGUL PHIEUPH;So;0;L;<circle> 1111;;;;N;CIRCLED HANGUL PIEUP;;;;
+326D;CIRCLED HANGUL HIEUH;So;0;L;<circle> 1112;;;;N;;;;;
+326E;CIRCLED HANGUL KIYEOK A;So;0;L;<circle> 1100 1161;;;;N;CIRCLED HANGUL GA;;;;
+326F;CIRCLED HANGUL NIEUN A;So;0;L;<circle> 1102 1161;;;;N;CIRCLED HANGUL NA;;;;
+3270;CIRCLED HANGUL TIKEUT A;So;0;L;<circle> 1103 1161;;;;N;CIRCLED HANGUL DA;;;;
+3271;CIRCLED HANGUL RIEUL A;So;0;L;<circle> 1105 1161;;;;N;CIRCLED HANGUL LA;;;;
+3272;CIRCLED HANGUL MIEUM A;So;0;L;<circle> 1106 1161;;;;N;CIRCLED HANGUL MA;;;;
+3273;CIRCLED HANGUL PIEUP A;So;0;L;<circle> 1107 1161;;;;N;CIRCLED HANGUL BA;;;;
+3274;CIRCLED HANGUL SIOS A;So;0;L;<circle> 1109 1161;;;;N;CIRCLED HANGUL SA;;;;
+3275;CIRCLED HANGUL IEUNG A;So;0;L;<circle> 110B 1161;;;;N;CIRCLED HANGUL A;;;;
+3276;CIRCLED HANGUL CIEUC A;So;0;L;<circle> 110C 1161;;;;N;CIRCLED HANGUL JA;;;;
+3277;CIRCLED HANGUL CHIEUCH A;So;0;L;<circle> 110E 1161;;;;N;CIRCLED HANGUL CA;;;;
+3278;CIRCLED HANGUL KHIEUKH A;So;0;L;<circle> 110F 1161;;;;N;CIRCLED HANGUL KA;;;;
+3279;CIRCLED HANGUL THIEUTH A;So;0;L;<circle> 1110 1161;;;;N;CIRCLED HANGUL TA;;;;
+327A;CIRCLED HANGUL PHIEUPH A;So;0;L;<circle> 1111 1161;;;;N;CIRCLED HANGUL PA;;;;
+327B;CIRCLED HANGUL HIEUH A;So;0;L;<circle> 1112 1161;;;;N;CIRCLED HANGUL HA;;;;
+327C;CIRCLED KOREAN CHARACTER CHAMKO;So;0;ON;<circle> 110E 1161 11B7 1100 1169;;;;N;;;;;
+327D;CIRCLED KOREAN CHARACTER JUEUI;So;0;ON;<circle> 110C 116E 110B 1174;;;;N;;;;;
+327E;CIRCLED HANGUL IEUNG U;So;0;ON;<circle> 110B 116E;;;;N;;;;;
+327F;KOREAN STANDARD SYMBOL;So;0;L;;;;;N;;;;;
+3280;CIRCLED IDEOGRAPH ONE;No;0;L;<circle> 4E00;;;1;N;;;;;
+3281;CIRCLED IDEOGRAPH TWO;No;0;L;<circle> 4E8C;;;2;N;;;;;
+3282;CIRCLED IDEOGRAPH THREE;No;0;L;<circle> 4E09;;;3;N;;;;;
+3283;CIRCLED IDEOGRAPH FOUR;No;0;L;<circle> 56DB;;;4;N;;;;;
+3284;CIRCLED IDEOGRAPH FIVE;No;0;L;<circle> 4E94;;;5;N;;;;;
+3285;CIRCLED IDEOGRAPH SIX;No;0;L;<circle> 516D;;;6;N;;;;;
+3286;CIRCLED IDEOGRAPH SEVEN;No;0;L;<circle> 4E03;;;7;N;;;;;
+3287;CIRCLED IDEOGRAPH EIGHT;No;0;L;<circle> 516B;;;8;N;;;;;
+3288;CIRCLED IDEOGRAPH NINE;No;0;L;<circle> 4E5D;;;9;N;;;;;
+3289;CIRCLED IDEOGRAPH TEN;No;0;L;<circle> 5341;;;10;N;;;;;
+328A;CIRCLED IDEOGRAPH MOON;So;0;L;<circle> 6708;;;;N;;;;;
+328B;CIRCLED IDEOGRAPH FIRE;So;0;L;<circle> 706B;;;;N;;;;;
+328C;CIRCLED IDEOGRAPH WATER;So;0;L;<circle> 6C34;;;;N;;;;;
+328D;CIRCLED IDEOGRAPH WOOD;So;0;L;<circle> 6728;;;;N;;;;;
+328E;CIRCLED IDEOGRAPH METAL;So;0;L;<circle> 91D1;;;;N;;;;;
+328F;CIRCLED IDEOGRAPH EARTH;So;0;L;<circle> 571F;;;;N;;;;;
+3290;CIRCLED IDEOGRAPH SUN;So;0;L;<circle> 65E5;;;;N;;;;;
+3291;CIRCLED IDEOGRAPH STOCK;So;0;L;<circle> 682A;;;;N;;;;;
+3292;CIRCLED IDEOGRAPH HAVE;So;0;L;<circle> 6709;;;;N;;;;;
+3293;CIRCLED IDEOGRAPH SOCIETY;So;0;L;<circle> 793E;;;;N;;;;;
+3294;CIRCLED IDEOGRAPH NAME;So;0;L;<circle> 540D;;;;N;;;;;
+3295;CIRCLED IDEOGRAPH SPECIAL;So;0;L;<circle> 7279;;;;N;;;;;
+3296;CIRCLED IDEOGRAPH FINANCIAL;So;0;L;<circle> 8CA1;;;;N;;;;;
+3297;CIRCLED IDEOGRAPH CONGRATULATION;So;0;L;<circle> 795D;;;;N;;;;;
+3298;CIRCLED IDEOGRAPH LABOR;So;0;L;<circle> 52B4;;;;N;;;;;
+3299;CIRCLED IDEOGRAPH SECRET;So;0;L;<circle> 79D8;;;;N;;;;;
+329A;CIRCLED IDEOGRAPH MALE;So;0;L;<circle> 7537;;;;N;;;;;
+329B;CIRCLED IDEOGRAPH FEMALE;So;0;L;<circle> 5973;;;;N;;;;;
+329C;CIRCLED IDEOGRAPH SUITABLE;So;0;L;<circle> 9069;;;;N;;;;;
+329D;CIRCLED IDEOGRAPH EXCELLENT;So;0;L;<circle> 512A;;;;N;;;;;
+329E;CIRCLED IDEOGRAPH PRINT;So;0;L;<circle> 5370;;;;N;;;;;
+329F;CIRCLED IDEOGRAPH ATTENTION;So;0;L;<circle> 6CE8;;;;N;;;;;
+32A0;CIRCLED IDEOGRAPH ITEM;So;0;L;<circle> 9805;;;;N;;;;;
+32A1;CIRCLED IDEOGRAPH REST;So;0;L;<circle> 4F11;;;;N;;;;;
+32A2;CIRCLED IDEOGRAPH COPY;So;0;L;<circle> 5199;;;;N;;;;;
+32A3;CIRCLED IDEOGRAPH CORRECT;So;0;L;<circle> 6B63;;;;N;;;;;
+32A4;CIRCLED IDEOGRAPH HIGH;So;0;L;<circle> 4E0A;;;;N;;;;;
+32A5;CIRCLED IDEOGRAPH CENTRE;So;0;L;<circle> 4E2D;;;;N;CIRCLED IDEOGRAPH CENTER;;;;
+32A6;CIRCLED IDEOGRAPH LOW;So;0;L;<circle> 4E0B;;;;N;;;;;
+32A7;CIRCLED IDEOGRAPH LEFT;So;0;L;<circle> 5DE6;;;;N;;;;;
+32A8;CIRCLED IDEOGRAPH RIGHT;So;0;L;<circle> 53F3;;;;N;;;;;
+32A9;CIRCLED IDEOGRAPH MEDICINE;So;0;L;<circle> 533B;;;;N;;;;;
+32AA;CIRCLED IDEOGRAPH RELIGION;So;0;L;<circle> 5B97;;;;N;;;;;
+32AB;CIRCLED IDEOGRAPH STUDY;So;0;L;<circle> 5B66;;;;N;;;;;
+32AC;CIRCLED IDEOGRAPH SUPERVISE;So;0;L;<circle> 76E3;;;;N;;;;;
+32AD;CIRCLED IDEOGRAPH ENTERPRISE;So;0;L;<circle> 4F01;;;;N;;;;;
+32AE;CIRCLED IDEOGRAPH RESOURCE;So;0;L;<circle> 8CC7;;;;N;;;;;
+32AF;CIRCLED IDEOGRAPH ALLIANCE;So;0;L;<circle> 5354;;;;N;;;;;
+32B0;CIRCLED IDEOGRAPH NIGHT;So;0;L;<circle> 591C;;;;N;;;;;
+32B1;CIRCLED NUMBER THIRTY SIX;No;0;ON;<circle> 0033 0036;;;36;N;;;;;
+32B2;CIRCLED NUMBER THIRTY SEVEN;No;0;ON;<circle> 0033 0037;;;37;N;;;;;
+32B3;CIRCLED NUMBER THIRTY EIGHT;No;0;ON;<circle> 0033 0038;;;38;N;;;;;
+32B4;CIRCLED NUMBER THIRTY NINE;No;0;ON;<circle> 0033 0039;;;39;N;;;;;
+32B5;CIRCLED NUMBER FORTY;No;0;ON;<circle> 0034 0030;;;40;N;;;;;
+32B6;CIRCLED NUMBER FORTY ONE;No;0;ON;<circle> 0034 0031;;;41;N;;;;;
+32B7;CIRCLED NUMBER FORTY TWO;No;0;ON;<circle> 0034 0032;;;42;N;;;;;
+32B8;CIRCLED NUMBER FORTY THREE;No;0;ON;<circle> 0034 0033;;;43;N;;;;;
+32B9;CIRCLED NUMBER FORTY FOUR;No;0;ON;<circle> 0034 0034;;;44;N;;;;;
+32BA;CIRCLED NUMBER FORTY FIVE;No;0;ON;<circle> 0034 0035;;;45;N;;;;;
+32BB;CIRCLED NUMBER FORTY SIX;No;0;ON;<circle> 0034 0036;;;46;N;;;;;
+32BC;CIRCLED NUMBER FORTY SEVEN;No;0;ON;<circle> 0034 0037;;;47;N;;;;;
+32BD;CIRCLED NUMBER FORTY EIGHT;No;0;ON;<circle> 0034 0038;;;48;N;;;;;
+32BE;CIRCLED NUMBER FORTY NINE;No;0;ON;<circle> 0034 0039;;;49;N;;;;;
+32BF;CIRCLED NUMBER FIFTY;No;0;ON;<circle> 0035 0030;;;50;N;;;;;
+32C0;IDEOGRAPHIC TELEGRAPH SYMBOL FOR JANUARY;So;0;L;<compat> 0031 6708;;;;N;;;;;
+32C1;IDEOGRAPHIC TELEGRAPH SYMBOL FOR FEBRUARY;So;0;L;<compat> 0032 6708;;;;N;;;;;
+32C2;IDEOGRAPHIC TELEGRAPH SYMBOL FOR MARCH;So;0;L;<compat> 0033 6708;;;;N;;;;;
+32C3;IDEOGRAPHIC TELEGRAPH SYMBOL FOR APRIL;So;0;L;<compat> 0034 6708;;;;N;;;;;
+32C4;IDEOGRAPHIC TELEGRAPH SYMBOL FOR MAY;So;0;L;<compat> 0035 6708;;;;N;;;;;
+32C5;IDEOGRAPHIC TELEGRAPH SYMBOL FOR JUNE;So;0;L;<compat> 0036 6708;;;;N;;;;;
+32C6;IDEOGRAPHIC TELEGRAPH SYMBOL FOR JULY;So;0;L;<compat> 0037 6708;;;;N;;;;;
+32C7;IDEOGRAPHIC TELEGRAPH SYMBOL FOR AUGUST;So;0;L;<compat> 0038 6708;;;;N;;;;;
+32C8;IDEOGRAPHIC TELEGRAPH SYMBOL FOR SEPTEMBER;So;0;L;<compat> 0039 6708;;;;N;;;;;
+32C9;IDEOGRAPHIC TELEGRAPH SYMBOL FOR OCTOBER;So;0;L;<compat> 0031 0030 6708;;;;N;;;;;
+32CA;IDEOGRAPHIC TELEGRAPH SYMBOL FOR NOVEMBER;So;0;L;<compat> 0031 0031 6708;;;;N;;;;;
+32CB;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DECEMBER;So;0;L;<compat> 0031 0032 6708;;;;N;;;;;
+32CC;SQUARE HG;So;0;ON;<square> 0048 0067;;;;N;;;;;
+32CD;SQUARE ERG;So;0;ON;<square> 0065 0072 0067;;;;N;;;;;
+32CE;SQUARE EV;So;0;ON;<square> 0065 0056;;;;N;;;;;
+32CF;LIMITED LIABILITY SIGN;So;0;ON;<square> 004C 0054 0044;;;;N;;;;;
+32D0;CIRCLED KATAKANA A;So;0;L;<circle> 30A2;;;;N;;;;;
+32D1;CIRCLED KATAKANA I;So;0;L;<circle> 30A4;;;;N;;;;;
+32D2;CIRCLED KATAKANA U;So;0;L;<circle> 30A6;;;;N;;;;;
+32D3;CIRCLED KATAKANA E;So;0;L;<circle> 30A8;;;;N;;;;;
+32D4;CIRCLED KATAKANA O;So;0;L;<circle> 30AA;;;;N;;;;;
+32D5;CIRCLED KATAKANA KA;So;0;L;<circle> 30AB;;;;N;;;;;
+32D6;CIRCLED KATAKANA KI;So;0;L;<circle> 30AD;;;;N;;;;;
+32D7;CIRCLED KATAKANA KU;So;0;L;<circle> 30AF;;;;N;;;;;
+32D8;CIRCLED KATAKANA KE;So;0;L;<circle> 30B1;;;;N;;;;;
+32D9;CIRCLED KATAKANA KO;So;0;L;<circle> 30B3;;;;N;;;;;
+32DA;CIRCLED KATAKANA SA;So;0;L;<circle> 30B5;;;;N;;;;;
+32DB;CIRCLED KATAKANA SI;So;0;L;<circle> 30B7;;;;N;;;;;
+32DC;CIRCLED KATAKANA SU;So;0;L;<circle> 30B9;;;;N;;;;;
+32DD;CIRCLED KATAKANA SE;So;0;L;<circle> 30BB;;;;N;;;;;
+32DE;CIRCLED KATAKANA SO;So;0;L;<circle> 30BD;;;;N;;;;;
+32DF;CIRCLED KATAKANA TA;So;0;L;<circle> 30BF;;;;N;;;;;
+32E0;CIRCLED KATAKANA TI;So;0;L;<circle> 30C1;;;;N;;;;;
+32E1;CIRCLED KATAKANA TU;So;0;L;<circle> 30C4;;;;N;;;;;
+32E2;CIRCLED KATAKANA TE;So;0;L;<circle> 30C6;;;;N;;;;;
+32E3;CIRCLED KATAKANA TO;So;0;L;<circle> 30C8;;;;N;;;;;
+32E4;CIRCLED KATAKANA NA;So;0;L;<circle> 30CA;;;;N;;;;;
+32E5;CIRCLED KATAKANA NI;So;0;L;<circle> 30CB;;;;N;;;;;
+32E6;CIRCLED KATAKANA NU;So;0;L;<circle> 30CC;;;;N;;;;;
+32E7;CIRCLED KATAKANA NE;So;0;L;<circle> 30CD;;;;N;;;;;
+32E8;CIRCLED KATAKANA NO;So;0;L;<circle> 30CE;;;;N;;;;;
+32E9;CIRCLED KATAKANA HA;So;0;L;<circle> 30CF;;;;N;;;;;
+32EA;CIRCLED KATAKANA HI;So;0;L;<circle> 30D2;;;;N;;;;;
+32EB;CIRCLED KATAKANA HU;So;0;L;<circle> 30D5;;;;N;;;;;
+32EC;CIRCLED KATAKANA HE;So;0;L;<circle> 30D8;;;;N;;;;;
+32ED;CIRCLED KATAKANA HO;So;0;L;<circle> 30DB;;;;N;;;;;
+32EE;CIRCLED KATAKANA MA;So;0;L;<circle> 30DE;;;;N;;;;;
+32EF;CIRCLED KATAKANA MI;So;0;L;<circle> 30DF;;;;N;;;;;
+32F0;CIRCLED KATAKANA MU;So;0;L;<circle> 30E0;;;;N;;;;;
+32F1;CIRCLED KATAKANA ME;So;0;L;<circle> 30E1;;;;N;;;;;
+32F2;CIRCLED KATAKANA MO;So;0;L;<circle> 30E2;;;;N;;;;;
+32F3;CIRCLED KATAKANA YA;So;0;L;<circle> 30E4;;;;N;;;;;
+32F4;CIRCLED KATAKANA YU;So;0;L;<circle> 30E6;;;;N;;;;;
+32F5;CIRCLED KATAKANA YO;So;0;L;<circle> 30E8;;;;N;;;;;
+32F6;CIRCLED KATAKANA RA;So;0;L;<circle> 30E9;;;;N;;;;;
+32F7;CIRCLED KATAKANA RI;So;0;L;<circle> 30EA;;;;N;;;;;
+32F8;CIRCLED KATAKANA RU;So;0;L;<circle> 30EB;;;;N;;;;;
+32F9;CIRCLED KATAKANA RE;So;0;L;<circle> 30EC;;;;N;;;;;
+32FA;CIRCLED KATAKANA RO;So;0;L;<circle> 30ED;;;;N;;;;;
+32FB;CIRCLED KATAKANA WA;So;0;L;<circle> 30EF;;;;N;;;;;
+32FC;CIRCLED KATAKANA WI;So;0;L;<circle> 30F0;;;;N;;;;;
+32FD;CIRCLED KATAKANA WE;So;0;L;<circle> 30F1;;;;N;;;;;
+32FE;CIRCLED KATAKANA WO;So;0;L;<circle> 30F2;;;;N;;;;;
+3300;SQUARE APAATO;So;0;L;<square> 30A2 30D1 30FC 30C8;;;;N;SQUARED APAATO;;;;
+3301;SQUARE ARUHUA;So;0;L;<square> 30A2 30EB 30D5 30A1;;;;N;SQUARED ARUHUA;;;;
+3302;SQUARE ANPEA;So;0;L;<square> 30A2 30F3 30DA 30A2;;;;N;SQUARED ANPEA;;;;
+3303;SQUARE AARU;So;0;L;<square> 30A2 30FC 30EB;;;;N;SQUARED AARU;;;;
+3304;SQUARE ININGU;So;0;L;<square> 30A4 30CB 30F3 30B0;;;;N;SQUARED ININGU;;;;
+3305;SQUARE INTI;So;0;L;<square> 30A4 30F3 30C1;;;;N;SQUARED INTI;;;;
+3306;SQUARE UON;So;0;L;<square> 30A6 30A9 30F3;;;;N;SQUARED UON;;;;
+3307;SQUARE ESUKUUDO;So;0;L;<square> 30A8 30B9 30AF 30FC 30C9;;;;N;SQUARED ESUKUUDO;;;;
+3308;SQUARE EEKAA;So;0;L;<square> 30A8 30FC 30AB 30FC;;;;N;SQUARED EEKAA;;;;
+3309;SQUARE ONSU;So;0;L;<square> 30AA 30F3 30B9;;;;N;SQUARED ONSU;;;;
+330A;SQUARE OOMU;So;0;L;<square> 30AA 30FC 30E0;;;;N;SQUARED OOMU;;;;
+330B;SQUARE KAIRI;So;0;L;<square> 30AB 30A4 30EA;;;;N;SQUARED KAIRI;;;;
+330C;SQUARE KARATTO;So;0;L;<square> 30AB 30E9 30C3 30C8;;;;N;SQUARED KARATTO;;;;
+330D;SQUARE KARORII;So;0;L;<square> 30AB 30ED 30EA 30FC;;;;N;SQUARED KARORII;;;;
+330E;SQUARE GARON;So;0;L;<square> 30AC 30ED 30F3;;;;N;SQUARED GARON;;;;
+330F;SQUARE GANMA;So;0;L;<square> 30AC 30F3 30DE;;;;N;SQUARED GANMA;;;;
+3310;SQUARE GIGA;So;0;L;<square> 30AE 30AC;;;;N;SQUARED GIGA;;;;
+3311;SQUARE GINII;So;0;L;<square> 30AE 30CB 30FC;;;;N;SQUARED GINII;;;;
+3312;SQUARE KYURII;So;0;L;<square> 30AD 30E5 30EA 30FC;;;;N;SQUARED KYURII;;;;
+3313;SQUARE GIRUDAA;So;0;L;<square> 30AE 30EB 30C0 30FC;;;;N;SQUARED GIRUDAA;;;;
+3314;SQUARE KIRO;So;0;L;<square> 30AD 30ED;;;;N;SQUARED KIRO;;;;
+3315;SQUARE KIROGURAMU;So;0;L;<square> 30AD 30ED 30B0 30E9 30E0;;;;N;SQUARED KIROGURAMU;;;;
+3316;SQUARE KIROMEETORU;So;0;L;<square> 30AD 30ED 30E1 30FC 30C8 30EB;;;;N;SQUARED KIROMEETORU;;;;
+3317;SQUARE KIROWATTO;So;0;L;<square> 30AD 30ED 30EF 30C3 30C8;;;;N;SQUARED KIROWATTO;;;;
+3318;SQUARE GURAMU;So;0;L;<square> 30B0 30E9 30E0;;;;N;SQUARED GURAMU;;;;
+3319;SQUARE GURAMUTON;So;0;L;<square> 30B0 30E9 30E0 30C8 30F3;;;;N;SQUARED GURAMUTON;;;;
+331A;SQUARE KURUZEIRO;So;0;L;<square> 30AF 30EB 30BC 30A4 30ED;;;;N;SQUARED KURUZEIRO;;;;
+331B;SQUARE KUROONE;So;0;L;<square> 30AF 30ED 30FC 30CD;;;;N;SQUARED KUROONE;;;;
+331C;SQUARE KEESU;So;0;L;<square> 30B1 30FC 30B9;;;;N;SQUARED KEESU;;;;
+331D;SQUARE KORUNA;So;0;L;<square> 30B3 30EB 30CA;;;;N;SQUARED KORUNA;;;;
+331E;SQUARE KOOPO;So;0;L;<square> 30B3 30FC 30DD;;;;N;SQUARED KOOPO;;;;
+331F;SQUARE SAIKURU;So;0;L;<square> 30B5 30A4 30AF 30EB;;;;N;SQUARED SAIKURU;;;;
+3320;SQUARE SANTIIMU;So;0;L;<square> 30B5 30F3 30C1 30FC 30E0;;;;N;SQUARED SANTIIMU;;;;
+3321;SQUARE SIRINGU;So;0;L;<square> 30B7 30EA 30F3 30B0;;;;N;SQUARED SIRINGU;;;;
+3322;SQUARE SENTI;So;0;L;<square> 30BB 30F3 30C1;;;;N;SQUARED SENTI;;;;
+3323;SQUARE SENTO;So;0;L;<square> 30BB 30F3 30C8;;;;N;SQUARED SENTO;;;;
+3324;SQUARE DAASU;So;0;L;<square> 30C0 30FC 30B9;;;;N;SQUARED DAASU;;;;
+3325;SQUARE DESI;So;0;L;<square> 30C7 30B7;;;;N;SQUARED DESI;;;;
+3326;SQUARE DORU;So;0;L;<square> 30C9 30EB;;;;N;SQUARED DORU;;;;
+3327;SQUARE TON;So;0;L;<square> 30C8 30F3;;;;N;SQUARED TON;;;;
+3328;SQUARE NANO;So;0;L;<square> 30CA 30CE;;;;N;SQUARED NANO;;;;
+3329;SQUARE NOTTO;So;0;L;<square> 30CE 30C3 30C8;;;;N;SQUARED NOTTO;;;;
+332A;SQUARE HAITU;So;0;L;<square> 30CF 30A4 30C4;;;;N;SQUARED HAITU;;;;
+332B;SQUARE PAASENTO;So;0;L;<square> 30D1 30FC 30BB 30F3 30C8;;;;N;SQUARED PAASENTO;;;;
+332C;SQUARE PAATU;So;0;L;<square> 30D1 30FC 30C4;;;;N;SQUARED PAATU;;;;
+332D;SQUARE BAARERU;So;0;L;<square> 30D0 30FC 30EC 30EB;;;;N;SQUARED BAARERU;;;;
+332E;SQUARE PIASUTORU;So;0;L;<square> 30D4 30A2 30B9 30C8 30EB;;;;N;SQUARED PIASUTORU;;;;
+332F;SQUARE PIKURU;So;0;L;<square> 30D4 30AF 30EB;;;;N;SQUARED PIKURU;;;;
+3330;SQUARE PIKO;So;0;L;<square> 30D4 30B3;;;;N;SQUARED PIKO;;;;
+3331;SQUARE BIRU;So;0;L;<square> 30D3 30EB;;;;N;SQUARED BIRU;;;;
+3332;SQUARE HUARADDO;So;0;L;<square> 30D5 30A1 30E9 30C3 30C9;;;;N;SQUARED HUARADDO;;;;
+3333;SQUARE HUIITO;So;0;L;<square> 30D5 30A3 30FC 30C8;;;;N;SQUARED HUIITO;;;;
+3334;SQUARE BUSSYERU;So;0;L;<square> 30D6 30C3 30B7 30A7 30EB;;;;N;SQUARED BUSSYERU;;;;
+3335;SQUARE HURAN;So;0;L;<square> 30D5 30E9 30F3;;;;N;SQUARED HURAN;;;;
+3336;SQUARE HEKUTAARU;So;0;L;<square> 30D8 30AF 30BF 30FC 30EB;;;;N;SQUARED HEKUTAARU;;;;
+3337;SQUARE PESO;So;0;L;<square> 30DA 30BD;;;;N;SQUARED PESO;;;;
+3338;SQUARE PENIHI;So;0;L;<square> 30DA 30CB 30D2;;;;N;SQUARED PENIHI;;;;
+3339;SQUARE HERUTU;So;0;L;<square> 30D8 30EB 30C4;;;;N;SQUARED HERUTU;;;;
+333A;SQUARE PENSU;So;0;L;<square> 30DA 30F3 30B9;;;;N;SQUARED PENSU;;;;
+333B;SQUARE PEEZI;So;0;L;<square> 30DA 30FC 30B8;;;;N;SQUARED PEEZI;;;;
+333C;SQUARE BEETA;So;0;L;<square> 30D9 30FC 30BF;;;;N;SQUARED BEETA;;;;
+333D;SQUARE POINTO;So;0;L;<square> 30DD 30A4 30F3 30C8;;;;N;SQUARED POINTO;;;;
+333E;SQUARE BORUTO;So;0;L;<square> 30DC 30EB 30C8;;;;N;SQUARED BORUTO;;;;
+333F;SQUARE HON;So;0;L;<square> 30DB 30F3;;;;N;SQUARED HON;;;;
+3340;SQUARE PONDO;So;0;L;<square> 30DD 30F3 30C9;;;;N;SQUARED PONDO;;;;
+3341;SQUARE HOORU;So;0;L;<square> 30DB 30FC 30EB;;;;N;SQUARED HOORU;;;;
+3342;SQUARE HOON;So;0;L;<square> 30DB 30FC 30F3;;;;N;SQUARED HOON;;;;
+3343;SQUARE MAIKURO;So;0;L;<square> 30DE 30A4 30AF 30ED;;;;N;SQUARED MAIKURO;;;;
+3344;SQUARE MAIRU;So;0;L;<square> 30DE 30A4 30EB;;;;N;SQUARED MAIRU;;;;
+3345;SQUARE MAHHA;So;0;L;<square> 30DE 30C3 30CF;;;;N;SQUARED MAHHA;;;;
+3346;SQUARE MARUKU;So;0;L;<square> 30DE 30EB 30AF;;;;N;SQUARED MARUKU;;;;
+3347;SQUARE MANSYON;So;0;L;<square> 30DE 30F3 30B7 30E7 30F3;;;;N;SQUARED MANSYON;;;;
+3348;SQUARE MIKURON;So;0;L;<square> 30DF 30AF 30ED 30F3;;;;N;SQUARED MIKURON;;;;
+3349;SQUARE MIRI;So;0;L;<square> 30DF 30EA;;;;N;SQUARED MIRI;;;;
+334A;SQUARE MIRIBAARU;So;0;L;<square> 30DF 30EA 30D0 30FC 30EB;;;;N;SQUARED MIRIBAARU;;;;
+334B;SQUARE MEGA;So;0;L;<square> 30E1 30AC;;;;N;SQUARED MEGA;;;;
+334C;SQUARE MEGATON;So;0;L;<square> 30E1 30AC 30C8 30F3;;;;N;SQUARED MEGATON;;;;
+334D;SQUARE MEETORU;So;0;L;<square> 30E1 30FC 30C8 30EB;;;;N;SQUARED MEETORU;;;;
+334E;SQUARE YAADO;So;0;L;<square> 30E4 30FC 30C9;;;;N;SQUARED YAADO;;;;
+334F;SQUARE YAARU;So;0;L;<square> 30E4 30FC 30EB;;;;N;SQUARED YAARU;;;;
+3350;SQUARE YUAN;So;0;L;<square> 30E6 30A2 30F3;;;;N;SQUARED YUAN;;;;
+3351;SQUARE RITTORU;So;0;L;<square> 30EA 30C3 30C8 30EB;;;;N;SQUARED RITTORU;;;;
+3352;SQUARE RIRA;So;0;L;<square> 30EA 30E9;;;;N;SQUARED RIRA;;;;
+3353;SQUARE RUPII;So;0;L;<square> 30EB 30D4 30FC;;;;N;SQUARED RUPII;;;;
+3354;SQUARE RUUBURU;So;0;L;<square> 30EB 30FC 30D6 30EB;;;;N;SQUARED RUUBURU;;;;
+3355;SQUARE REMU;So;0;L;<square> 30EC 30E0;;;;N;SQUARED REMU;;;;
+3356;SQUARE RENTOGEN;So;0;L;<square> 30EC 30F3 30C8 30B2 30F3;;;;N;SQUARED RENTOGEN;;;;
+3357;SQUARE WATTO;So;0;L;<square> 30EF 30C3 30C8;;;;N;SQUARED WATTO;;;;
+3358;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR ZERO;So;0;L;<compat> 0030 70B9;;;;N;;;;;
+3359;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR ONE;So;0;L;<compat> 0031 70B9;;;;N;;;;;
+335A;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWO;So;0;L;<compat> 0032 70B9;;;;N;;;;;
+335B;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR THREE;So;0;L;<compat> 0033 70B9;;;;N;;;;;
+335C;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR FOUR;So;0;L;<compat> 0034 70B9;;;;N;;;;;
+335D;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR FIVE;So;0;L;<compat> 0035 70B9;;;;N;;;;;
+335E;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR SIX;So;0;L;<compat> 0036 70B9;;;;N;;;;;
+335F;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR SEVEN;So;0;L;<compat> 0037 70B9;;;;N;;;;;
+3360;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR EIGHT;So;0;L;<compat> 0038 70B9;;;;N;;;;;
+3361;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR NINE;So;0;L;<compat> 0039 70B9;;;;N;;;;;
+3362;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TEN;So;0;L;<compat> 0031 0030 70B9;;;;N;;;;;
+3363;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR ELEVEN;So;0;L;<compat> 0031 0031 70B9;;;;N;;;;;
+3364;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWELVE;So;0;L;<compat> 0031 0032 70B9;;;;N;;;;;
+3365;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR THIRTEEN;So;0;L;<compat> 0031 0033 70B9;;;;N;;;;;
+3366;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR FOURTEEN;So;0;L;<compat> 0031 0034 70B9;;;;N;;;;;
+3367;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR FIFTEEN;So;0;L;<compat> 0031 0035 70B9;;;;N;;;;;
+3368;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR SIXTEEN;So;0;L;<compat> 0031 0036 70B9;;;;N;;;;;
+3369;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR SEVENTEEN;So;0;L;<compat> 0031 0037 70B9;;;;N;;;;;
+336A;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR EIGHTEEN;So;0;L;<compat> 0031 0038 70B9;;;;N;;;;;
+336B;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR NINETEEN;So;0;L;<compat> 0031 0039 70B9;;;;N;;;;;
+336C;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY;So;0;L;<compat> 0032 0030 70B9;;;;N;;;;;
+336D;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY-ONE;So;0;L;<compat> 0032 0031 70B9;;;;N;;;;;
+336E;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY-TWO;So;0;L;<compat> 0032 0032 70B9;;;;N;;;;;
+336F;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY-THREE;So;0;L;<compat> 0032 0033 70B9;;;;N;;;;;
+3370;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY-FOUR;So;0;L;<compat> 0032 0034 70B9;;;;N;;;;;
+3371;SQUARE HPA;So;0;L;<square> 0068 0050 0061;;;;N;;;;;
+3372;SQUARE DA;So;0;L;<square> 0064 0061;;;;N;;;;;
+3373;SQUARE AU;So;0;L;<square> 0041 0055;;;;N;;;;;
+3374;SQUARE BAR;So;0;L;<square> 0062 0061 0072;;;;N;;;;;
+3375;SQUARE OV;So;0;L;<square> 006F 0056;;;;N;;;;;
+3376;SQUARE PC;So;0;L;<square> 0070 0063;;;;N;;;;;
+3377;SQUARE DM;So;0;ON;<square> 0064 006D;;;;N;;;;;
+3378;SQUARE DM SQUARED;So;0;ON;<square> 0064 006D 00B2;;;;N;;;;;
+3379;SQUARE DM CUBED;So;0;ON;<square> 0064 006D 00B3;;;;N;;;;;
+337A;SQUARE IU;So;0;ON;<square> 0049 0055;;;;N;;;;;
+337B;SQUARE ERA NAME HEISEI;So;0;L;<square> 5E73 6210;;;;N;SQUARED TWO IDEOGRAPHS ERA NAME HEISEI;;;;
+337C;SQUARE ERA NAME SYOUWA;So;0;L;<square> 662D 548C;;;;N;SQUARED TWO IDEOGRAPHS ERA NAME SYOUWA;;;;
+337D;SQUARE ERA NAME TAISYOU;So;0;L;<square> 5927 6B63;;;;N;SQUARED TWO IDEOGRAPHS ERA NAME TAISYOU;;;;
+337E;SQUARE ERA NAME MEIZI;So;0;L;<square> 660E 6CBB;;;;N;SQUARED TWO IDEOGRAPHS ERA NAME MEIZI;;;;
+337F;SQUARE CORPORATION;So;0;L;<square> 682A 5F0F 4F1A 793E;;;;N;SQUARED FOUR IDEOGRAPHS CORPORATION;;;;
+3380;SQUARE PA AMPS;So;0;L;<square> 0070 0041;;;;N;SQUARED PA AMPS;;;;
+3381;SQUARE NA;So;0;L;<square> 006E 0041;;;;N;SQUARED NA;;;;
+3382;SQUARE MU A;So;0;L;<square> 03BC 0041;;;;N;SQUARED MU A;;;;
+3383;SQUARE MA;So;0;L;<square> 006D 0041;;;;N;SQUARED MA;;;;
+3384;SQUARE KA;So;0;L;<square> 006B 0041;;;;N;SQUARED KA;;;;
+3385;SQUARE KB;So;0;L;<square> 004B 0042;;;;N;SQUARED KB;;;;
+3386;SQUARE MB;So;0;L;<square> 004D 0042;;;;N;SQUARED MB;;;;
+3387;SQUARE GB;So;0;L;<square> 0047 0042;;;;N;SQUARED GB;;;;
+3388;SQUARE CAL;So;0;L;<square> 0063 0061 006C;;;;N;SQUARED CAL;;;;
+3389;SQUARE KCAL;So;0;L;<square> 006B 0063 0061 006C;;;;N;SQUARED KCAL;;;;
+338A;SQUARE PF;So;0;L;<square> 0070 0046;;;;N;SQUARED PF;;;;
+338B;SQUARE NF;So;0;L;<square> 006E 0046;;;;N;SQUARED NF;;;;
+338C;SQUARE MU F;So;0;L;<square> 03BC 0046;;;;N;SQUARED MU F;;;;
+338D;SQUARE MU G;So;0;L;<square> 03BC 0067;;;;N;SQUARED MU G;;;;
+338E;SQUARE MG;So;0;L;<square> 006D 0067;;;;N;SQUARED MG;;;;
+338F;SQUARE KG;So;0;L;<square> 006B 0067;;;;N;SQUARED KG;;;;
+3390;SQUARE HZ;So;0;L;<square> 0048 007A;;;;N;SQUARED HZ;;;;
+3391;SQUARE KHZ;So;0;L;<square> 006B 0048 007A;;;;N;SQUARED KHZ;;;;
+3392;SQUARE MHZ;So;0;L;<square> 004D 0048 007A;;;;N;SQUARED MHZ;;;;
+3393;SQUARE GHZ;So;0;L;<square> 0047 0048 007A;;;;N;SQUARED GHZ;;;;
+3394;SQUARE THZ;So;0;L;<square> 0054 0048 007A;;;;N;SQUARED THZ;;;;
+3395;SQUARE MU L;So;0;L;<square> 03BC 2113;;;;N;SQUARED MU L;;;;
+3396;SQUARE ML;So;0;L;<square> 006D 2113;;;;N;SQUARED ML;;;;
+3397;SQUARE DL;So;0;L;<square> 0064 2113;;;;N;SQUARED DL;;;;
+3398;SQUARE KL;So;0;L;<square> 006B 2113;;;;N;SQUARED KL;;;;
+3399;SQUARE FM;So;0;L;<square> 0066 006D;;;;N;SQUARED FM;;;;
+339A;SQUARE NM;So;0;L;<square> 006E 006D;;;;N;SQUARED NM;;;;
+339B;SQUARE MU M;So;0;L;<square> 03BC 006D;;;;N;SQUARED MU M;;;;
+339C;SQUARE MM;So;0;L;<square> 006D 006D;;;;N;SQUARED MM;;;;
+339D;SQUARE CM;So;0;L;<square> 0063 006D;;;;N;SQUARED CM;;;;
+339E;SQUARE KM;So;0;L;<square> 006B 006D;;;;N;SQUARED KM;;;;
+339F;SQUARE MM SQUARED;So;0;L;<square> 006D 006D 00B2;;;;N;SQUARED MM SQUARED;;;;
+33A0;SQUARE CM SQUARED;So;0;L;<square> 0063 006D 00B2;;;;N;SQUARED CM SQUARED;;;;
+33A1;SQUARE M SQUARED;So;0;L;<square> 006D 00B2;;;;N;SQUARED M SQUARED;;;;
+33A2;SQUARE KM SQUARED;So;0;L;<square> 006B 006D 00B2;;;;N;SQUARED KM SQUARED;;;;
+33A3;SQUARE MM CUBED;So;0;L;<square> 006D 006D 00B3;;;;N;SQUARED MM CUBED;;;;
+33A4;SQUARE CM CUBED;So;0;L;<square> 0063 006D 00B3;;;;N;SQUARED CM CUBED;;;;
+33A5;SQUARE M CUBED;So;0;L;<square> 006D 00B3;;;;N;SQUARED M CUBED;;;;
+33A6;SQUARE KM CUBED;So;0;L;<square> 006B 006D 00B3;;;;N;SQUARED KM CUBED;;;;
+33A7;SQUARE M OVER S;So;0;L;<square> 006D 2215 0073;;;;N;SQUARED M OVER S;;;;
+33A8;SQUARE M OVER S SQUARED;So;0;L;<square> 006D 2215 0073 00B2;;;;N;SQUARED M OVER S SQUARED;;;;
+33A9;SQUARE PA;So;0;L;<square> 0050 0061;;;;N;SQUARED PA;;;;
+33AA;SQUARE KPA;So;0;L;<square> 006B 0050 0061;;;;N;SQUARED KPA;;;;
+33AB;SQUARE MPA;So;0;L;<square> 004D 0050 0061;;;;N;SQUARED MPA;;;;
+33AC;SQUARE GPA;So;0;L;<square> 0047 0050 0061;;;;N;SQUARED GPA;;;;
+33AD;SQUARE RAD;So;0;L;<square> 0072 0061 0064;;;;N;SQUARED RAD;;;;
+33AE;SQUARE RAD OVER S;So;0;L;<square> 0072 0061 0064 2215 0073;;;;N;SQUARED RAD OVER S;;;;
+33AF;SQUARE RAD OVER S SQUARED;So;0;L;<square> 0072 0061 0064 2215 0073 00B2;;;;N;SQUARED RAD OVER S SQUARED;;;;
+33B0;SQUARE PS;So;0;L;<square> 0070 0073;;;;N;SQUARED PS;;;;
+33B1;SQUARE NS;So;0;L;<square> 006E 0073;;;;N;SQUARED NS;;;;
+33B2;SQUARE MU S;So;0;L;<square> 03BC 0073;;;;N;SQUARED MU S;;;;
+33B3;SQUARE MS;So;0;L;<square> 006D 0073;;;;N;SQUARED MS;;;;
+33B4;SQUARE PV;So;0;L;<square> 0070 0056;;;;N;SQUARED PV;;;;
+33B5;SQUARE NV;So;0;L;<square> 006E 0056;;;;N;SQUARED NV;;;;
+33B6;SQUARE MU V;So;0;L;<square> 03BC 0056;;;;N;SQUARED MU V;;;;
+33B7;SQUARE MV;So;0;L;<square> 006D 0056;;;;N;SQUARED MV;;;;
+33B8;SQUARE KV;So;0;L;<square> 006B 0056;;;;N;SQUARED KV;;;;
+33B9;SQUARE MV MEGA;So;0;L;<square> 004D 0056;;;;N;SQUARED MV MEGA;;;;
+33BA;SQUARE PW;So;0;L;<square> 0070 0057;;;;N;SQUARED PW;;;;
+33BB;SQUARE NW;So;0;L;<square> 006E 0057;;;;N;SQUARED NW;;;;
+33BC;SQUARE MU W;So;0;L;<square> 03BC 0057;;;;N;SQUARED MU W;;;;
+33BD;SQUARE MW;So;0;L;<square> 006D 0057;;;;N;SQUARED MW;;;;
+33BE;SQUARE KW;So;0;L;<square> 006B 0057;;;;N;SQUARED KW;;;;
+33BF;SQUARE MW MEGA;So;0;L;<square> 004D 0057;;;;N;SQUARED MW MEGA;;;;
+33C0;SQUARE K OHM;So;0;L;<square> 006B 03A9;;;;N;SQUARED K OHM;;;;
+33C1;SQUARE M OHM;So;0;L;<square> 004D 03A9;;;;N;SQUARED M OHM;;;;
+33C2;SQUARE AM;So;0;L;<square> 0061 002E 006D 002E;;;;N;SQUARED AM;;;;
+33C3;SQUARE BQ;So;0;L;<square> 0042 0071;;;;N;SQUARED BQ;;;;
+33C4;SQUARE CC;So;0;L;<square> 0063 0063;;;;N;SQUARED CC;;;;
+33C5;SQUARE CD;So;0;L;<square> 0063 0064;;;;N;SQUARED CD;;;;
+33C6;SQUARE C OVER KG;So;0;L;<square> 0043 2215 006B 0067;;;;N;SQUARED C OVER KG;;;;
+33C7;SQUARE CO;So;0;L;<square> 0043 006F 002E;;;;N;SQUARED CO;;;;
+33C8;SQUARE DB;So;0;L;<square> 0064 0042;;;;N;SQUARED DB;;;;
+33C9;SQUARE GY;So;0;L;<square> 0047 0079;;;;N;SQUARED GY;;;;
+33CA;SQUARE HA;So;0;L;<square> 0068 0061;;;;N;SQUARED HA;;;;
+33CB;SQUARE HP;So;0;L;<square> 0048 0050;;;;N;SQUARED HP;;;;
+33CC;SQUARE IN;So;0;L;<square> 0069 006E;;;;N;SQUARED IN;;;;
+33CD;SQUARE KK;So;0;L;<square> 004B 004B;;;;N;SQUARED KK;;;;
+33CE;SQUARE KM CAPITAL;So;0;L;<square> 004B 004D;;;;N;SQUARED KM CAPITAL;;;;
+33CF;SQUARE KT;So;0;L;<square> 006B 0074;;;;N;SQUARED KT;;;;
+33D0;SQUARE LM;So;0;L;<square> 006C 006D;;;;N;SQUARED LM;;;;
+33D1;SQUARE LN;So;0;L;<square> 006C 006E;;;;N;SQUARED LN;;;;
+33D2;SQUARE LOG;So;0;L;<square> 006C 006F 0067;;;;N;SQUARED LOG;;;;
+33D3;SQUARE LX;So;0;L;<square> 006C 0078;;;;N;SQUARED LX;;;;
+33D4;SQUARE MB SMALL;So;0;L;<square> 006D 0062;;;;N;SQUARED MB SMALL;;;;
+33D5;SQUARE MIL;So;0;L;<square> 006D 0069 006C;;;;N;SQUARED MIL;;;;
+33D6;SQUARE MOL;So;0;L;<square> 006D 006F 006C;;;;N;SQUARED MOL;;;;
+33D7;SQUARE PH;So;0;L;<square> 0050 0048;;;;N;SQUARED PH;;;;
+33D8;SQUARE PM;So;0;L;<square> 0070 002E 006D 002E;;;;N;SQUARED PM;;;;
+33D9;SQUARE PPM;So;0;L;<square> 0050 0050 004D;;;;N;SQUARED PPM;;;;
+33DA;SQUARE PR;So;0;L;<square> 0050 0052;;;;N;SQUARED PR;;;;
+33DB;SQUARE SR;So;0;L;<square> 0073 0072;;;;N;SQUARED SR;;;;
+33DC;SQUARE SV;So;0;L;<square> 0053 0076;;;;N;SQUARED SV;;;;
+33DD;SQUARE WB;So;0;L;<square> 0057 0062;;;;N;SQUARED WB;;;;
+33DE;SQUARE V OVER M;So;0;ON;<square> 0056 2215 006D;;;;N;;;;;
+33DF;SQUARE A OVER M;So;0;ON;<square> 0041 2215 006D;;;;N;;;;;
+33E0;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY ONE;So;0;L;<compat> 0031 65E5;;;;N;;;;;
+33E1;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWO;So;0;L;<compat> 0032 65E5;;;;N;;;;;
+33E2;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THREE;So;0;L;<compat> 0033 65E5;;;;N;;;;;
+33E3;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY FOUR;So;0;L;<compat> 0034 65E5;;;;N;;;;;
+33E4;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY FIVE;So;0;L;<compat> 0035 65E5;;;;N;;;;;
+33E5;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY SIX;So;0;L;<compat> 0036 65E5;;;;N;;;;;
+33E6;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY SEVEN;So;0;L;<compat> 0037 65E5;;;;N;;;;;
+33E7;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY EIGHT;So;0;L;<compat> 0038 65E5;;;;N;;;;;
+33E8;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY NINE;So;0;L;<compat> 0039 65E5;;;;N;;;;;
+33E9;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TEN;So;0;L;<compat> 0031 0030 65E5;;;;N;;;;;
+33EA;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY ELEVEN;So;0;L;<compat> 0031 0031 65E5;;;;N;;;;;
+33EB;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWELVE;So;0;L;<compat> 0031 0032 65E5;;;;N;;;;;
+33EC;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THIRTEEN;So;0;L;<compat> 0031 0033 65E5;;;;N;;;;;
+33ED;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY FOURTEEN;So;0;L;<compat> 0031 0034 65E5;;;;N;;;;;
+33EE;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY FIFTEEN;So;0;L;<compat> 0031 0035 65E5;;;;N;;;;;
+33EF;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY SIXTEEN;So;0;L;<compat> 0031 0036 65E5;;;;N;;;;;
+33F0;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY SEVENTEEN;So;0;L;<compat> 0031 0037 65E5;;;;N;;;;;
+33F1;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY EIGHTEEN;So;0;L;<compat> 0031 0038 65E5;;;;N;;;;;
+33F2;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY NINETEEN;So;0;L;<compat> 0031 0039 65E5;;;;N;;;;;
+33F3;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY;So;0;L;<compat> 0032 0030 65E5;;;;N;;;;;
+33F4;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-ONE;So;0;L;<compat> 0032 0031 65E5;;;;N;;;;;
+33F5;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-TWO;So;0;L;<compat> 0032 0032 65E5;;;;N;;;;;
+33F6;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-THREE;So;0;L;<compat> 0032 0033 65E5;;;;N;;;;;
+33F7;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-FOUR;So;0;L;<compat> 0032 0034 65E5;;;;N;;;;;
+33F8;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-FIVE;So;0;L;<compat> 0032 0035 65E5;;;;N;;;;;
+33F9;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-SIX;So;0;L;<compat> 0032 0036 65E5;;;;N;;;;;
+33FA;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-SEVEN;So;0;L;<compat> 0032 0037 65E5;;;;N;;;;;
+33FB;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-EIGHT;So;0;L;<compat> 0032 0038 65E5;;;;N;;;;;
+33FC;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-NINE;So;0;L;<compat> 0032 0039 65E5;;;;N;;;;;
+33FD;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THIRTY;So;0;L;<compat> 0033 0030 65E5;;;;N;;;;;
+33FE;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THIRTY-ONE;So;0;L;<compat> 0033 0031 65E5;;;;N;;;;;
+33FF;SQUARE GAL;So;0;ON;<square> 0067 0061 006C;;;;N;;;;;
+3400;<CJK Ideograph Extension A, First>;Lo;0;L;;;;;N;;;;;
+4DB5;<CJK Ideograph Extension A, Last>;Lo;0;L;;;;;N;;;;;
+4DC0;HEXAGRAM FOR THE CREATIVE HEAVEN;So;0;ON;;;;;N;;;;;
+4DC1;HEXAGRAM FOR THE RECEPTIVE EARTH;So;0;ON;;;;;N;;;;;
+4DC2;HEXAGRAM FOR DIFFICULTY AT THE BEGINNING;So;0;ON;;;;;N;;;;;
+4DC3;HEXAGRAM FOR YOUTHFUL FOLLY;So;0;ON;;;;;N;;;;;
+4DC4;HEXAGRAM FOR WAITING;So;0;ON;;;;;N;;;;;
+4DC5;HEXAGRAM FOR CONFLICT;So;0;ON;;;;;N;;;;;
+4DC6;HEXAGRAM FOR THE ARMY;So;0;ON;;;;;N;;;;;
+4DC7;HEXAGRAM FOR HOLDING TOGETHER;So;0;ON;;;;;N;;;;;
+4DC8;HEXAGRAM FOR SMALL TAMING;So;0;ON;;;;;N;;;;;
+4DC9;HEXAGRAM FOR TREADING;So;0;ON;;;;;N;;;;;
+4DCA;HEXAGRAM FOR PEACE;So;0;ON;;;;;N;;;;;
+4DCB;HEXAGRAM FOR STANDSTILL;So;0;ON;;;;;N;;;;;
+4DCC;HEXAGRAM FOR FELLOWSHIP;So;0;ON;;;;;N;;;;;
+4DCD;HEXAGRAM FOR GREAT POSSESSION;So;0;ON;;;;;N;;;;;
+4DCE;HEXAGRAM FOR MODESTY;So;0;ON;;;;;N;;;;;
+4DCF;HEXAGRAM FOR ENTHUSIASM;So;0;ON;;;;;N;;;;;
+4DD0;HEXAGRAM FOR FOLLOWING;So;0;ON;;;;;N;;;;;
+4DD1;HEXAGRAM FOR WORK ON THE DECAYED;So;0;ON;;;;;N;;;;;
+4DD2;HEXAGRAM FOR APPROACH;So;0;ON;;;;;N;;;;;
+4DD3;HEXAGRAM FOR CONTEMPLATION;So;0;ON;;;;;N;;;;;
+4DD4;HEXAGRAM FOR BITING THROUGH;So;0;ON;;;;;N;;;;;
+4DD5;HEXAGRAM FOR GRACE;So;0;ON;;;;;N;;;;;
+4DD6;HEXAGRAM FOR SPLITTING APART;So;0;ON;;;;;N;;;;;
+4DD7;HEXAGRAM FOR RETURN;So;0;ON;;;;;N;;;;;
+4DD8;HEXAGRAM FOR INNOCENCE;So;0;ON;;;;;N;;;;;
+4DD9;HEXAGRAM FOR GREAT TAMING;So;0;ON;;;;;N;;;;;
+4DDA;HEXAGRAM FOR MOUTH CORNERS;So;0;ON;;;;;N;;;;;
+4DDB;HEXAGRAM FOR GREAT PREPONDERANCE;So;0;ON;;;;;N;;;;;
+4DDC;HEXAGRAM FOR THE ABYSMAL WATER;So;0;ON;;;;;N;;;;;
+4DDD;HEXAGRAM FOR THE CLINGING FIRE;So;0;ON;;;;;N;;;;;
+4DDE;HEXAGRAM FOR INFLUENCE;So;0;ON;;;;;N;;;;;
+4DDF;HEXAGRAM FOR DURATION;So;0;ON;;;;;N;;;;;
+4DE0;HEXAGRAM FOR RETREAT;So;0;ON;;;;;N;;;;;
+4DE1;HEXAGRAM FOR GREAT POWER;So;0;ON;;;;;N;;;;;
+4DE2;HEXAGRAM FOR PROGRESS;So;0;ON;;;;;N;;;;;
+4DE3;HEXAGRAM FOR DARKENING OF THE LIGHT;So;0;ON;;;;;N;;;;;
+4DE4;HEXAGRAM FOR THE FAMILY;So;0;ON;;;;;N;;;;;
+4DE5;HEXAGRAM FOR OPPOSITION;So;0;ON;;;;;N;;;;;
+4DE6;HEXAGRAM FOR OBSTRUCTION;So;0;ON;;;;;N;;;;;
+4DE7;HEXAGRAM FOR DELIVERANCE;So;0;ON;;;;;N;;;;;
+4DE8;HEXAGRAM FOR DECREASE;So;0;ON;;;;;N;;;;;
+4DE9;HEXAGRAM FOR INCREASE;So;0;ON;;;;;N;;;;;
+4DEA;HEXAGRAM FOR BREAKTHROUGH;So;0;ON;;;;;N;;;;;
+4DEB;HEXAGRAM FOR COMING TO MEET;So;0;ON;;;;;N;;;;;
+4DEC;HEXAGRAM FOR GATHERING TOGETHER;So;0;ON;;;;;N;;;;;
+4DED;HEXAGRAM FOR PUSHING UPWARD;So;0;ON;;;;;N;;;;;
+4DEE;HEXAGRAM FOR OPPRESSION;So;0;ON;;;;;N;;;;;
+4DEF;HEXAGRAM FOR THE WELL;So;0;ON;;;;;N;;;;;
+4DF0;HEXAGRAM FOR REVOLUTION;So;0;ON;;;;;N;;;;;
+4DF1;HEXAGRAM FOR THE CAULDRON;So;0;ON;;;;;N;;;;;
+4DF2;HEXAGRAM FOR THE AROUSING THUNDER;So;0;ON;;;;;N;;;;;
+4DF3;HEXAGRAM FOR THE KEEPING STILL MOUNTAIN;So;0;ON;;;;;N;;;;;
+4DF4;HEXAGRAM FOR DEVELOPMENT;So;0;ON;;;;;N;;;;;
+4DF5;HEXAGRAM FOR THE MARRYING MAIDEN;So;0;ON;;;;;N;;;;;
+4DF6;HEXAGRAM FOR ABUNDANCE;So;0;ON;;;;;N;;;;;
+4DF7;HEXAGRAM FOR THE WANDERER;So;0;ON;;;;;N;;;;;
+4DF8;HEXAGRAM FOR THE GENTLE WIND;So;0;ON;;;;;N;;;;;
+4DF9;HEXAGRAM FOR THE JOYOUS LAKE;So;0;ON;;;;;N;;;;;
+4DFA;HEXAGRAM FOR DISPERSION;So;0;ON;;;;;N;;;;;
+4DFB;HEXAGRAM FOR LIMITATION;So;0;ON;;;;;N;;;;;
+4DFC;HEXAGRAM FOR INNER TRUTH;So;0;ON;;;;;N;;;;;
+4DFD;HEXAGRAM FOR SMALL PREPONDERANCE;So;0;ON;;;;;N;;;;;
+4DFE;HEXAGRAM FOR AFTER COMPLETION;So;0;ON;;;;;N;;;;;
+4DFF;HEXAGRAM FOR BEFORE COMPLETION;So;0;ON;;;;;N;;;;;
+4E00;<CJK Ideograph, First>;Lo;0;L;;;;;N;;;;;
+9FCB;<CJK Ideograph, Last>;Lo;0;L;;;;;N;;;;;
+A000;YI SYLLABLE IT;Lo;0;L;;;;;N;;;;;
+A001;YI SYLLABLE IX;Lo;0;L;;;;;N;;;;;
+A002;YI SYLLABLE I;Lo;0;L;;;;;N;;;;;
+A003;YI SYLLABLE IP;Lo;0;L;;;;;N;;;;;
+A004;YI SYLLABLE IET;Lo;0;L;;;;;N;;;;;
+A005;YI SYLLABLE IEX;Lo;0;L;;;;;N;;;;;
+A006;YI SYLLABLE IE;Lo;0;L;;;;;N;;;;;
+A007;YI SYLLABLE IEP;Lo;0;L;;;;;N;;;;;
+A008;YI SYLLABLE AT;Lo;0;L;;;;;N;;;;;
+A009;YI SYLLABLE AX;Lo;0;L;;;;;N;;;;;
+A00A;YI SYLLABLE A;Lo;0;L;;;;;N;;;;;
+A00B;YI SYLLABLE AP;Lo;0;L;;;;;N;;;;;
+A00C;YI SYLLABLE UOX;Lo;0;L;;;;;N;;;;;
+A00D;YI SYLLABLE UO;Lo;0;L;;;;;N;;;;;
+A00E;YI SYLLABLE UOP;Lo;0;L;;;;;N;;;;;
+A00F;YI SYLLABLE OT;Lo;0;L;;;;;N;;;;;
+A010;YI SYLLABLE OX;Lo;0;L;;;;;N;;;;;
+A011;YI SYLLABLE O;Lo;0;L;;;;;N;;;;;
+A012;YI SYLLABLE OP;Lo;0;L;;;;;N;;;;;
+A013;YI SYLLABLE EX;Lo;0;L;;;;;N;;;;;
+A014;YI SYLLABLE E;Lo;0;L;;;;;N;;;;;
+A015;YI SYLLABLE WU;Lm;0;L;;;;;N;;;;;
+A016;YI SYLLABLE BIT;Lo;0;L;;;;;N;;;;;
+A017;YI SYLLABLE BIX;Lo;0;L;;;;;N;;;;;
+A018;YI SYLLABLE BI;Lo;0;L;;;;;N;;;;;
+A019;YI SYLLABLE BIP;Lo;0;L;;;;;N;;;;;
+A01A;YI SYLLABLE BIET;Lo;0;L;;;;;N;;;;;
+A01B;YI SYLLABLE BIEX;Lo;0;L;;;;;N;;;;;
+A01C;YI SYLLABLE BIE;Lo;0;L;;;;;N;;;;;
+A01D;YI SYLLABLE BIEP;Lo;0;L;;;;;N;;;;;
+A01E;YI SYLLABLE BAT;Lo;0;L;;;;;N;;;;;
+A01F;YI SYLLABLE BAX;Lo;0;L;;;;;N;;;;;
+A020;YI SYLLABLE BA;Lo;0;L;;;;;N;;;;;
+A021;YI SYLLABLE BAP;Lo;0;L;;;;;N;;;;;
+A022;YI SYLLABLE BUOX;Lo;0;L;;;;;N;;;;;
+A023;YI SYLLABLE BUO;Lo;0;L;;;;;N;;;;;
+A024;YI SYLLABLE BUOP;Lo;0;L;;;;;N;;;;;
+A025;YI SYLLABLE BOT;Lo;0;L;;;;;N;;;;;
+A026;YI SYLLABLE BOX;Lo;0;L;;;;;N;;;;;
+A027;YI SYLLABLE BO;Lo;0;L;;;;;N;;;;;
+A028;YI SYLLABLE BOP;Lo;0;L;;;;;N;;;;;
+A029;YI SYLLABLE BEX;Lo;0;L;;;;;N;;;;;
+A02A;YI SYLLABLE BE;Lo;0;L;;;;;N;;;;;
+A02B;YI SYLLABLE BEP;Lo;0;L;;;;;N;;;;;
+A02C;YI SYLLABLE BUT;Lo;0;L;;;;;N;;;;;
+A02D;YI SYLLABLE BUX;Lo;0;L;;;;;N;;;;;
+A02E;YI SYLLABLE BU;Lo;0;L;;;;;N;;;;;
+A02F;YI SYLLABLE BUP;Lo;0;L;;;;;N;;;;;
+A030;YI SYLLABLE BURX;Lo;0;L;;;;;N;;;;;
+A031;YI SYLLABLE BUR;Lo;0;L;;;;;N;;;;;
+A032;YI SYLLABLE BYT;Lo;0;L;;;;;N;;;;;
+A033;YI SYLLABLE BYX;Lo;0;L;;;;;N;;;;;
+A034;YI SYLLABLE BY;Lo;0;L;;;;;N;;;;;
+A035;YI SYLLABLE BYP;Lo;0;L;;;;;N;;;;;
+A036;YI SYLLABLE BYRX;Lo;0;L;;;;;N;;;;;
+A037;YI SYLLABLE BYR;Lo;0;L;;;;;N;;;;;
+A038;YI SYLLABLE PIT;Lo;0;L;;;;;N;;;;;
+A039;YI SYLLABLE PIX;Lo;0;L;;;;;N;;;;;
+A03A;YI SYLLABLE PI;Lo;0;L;;;;;N;;;;;
+A03B;YI SYLLABLE PIP;Lo;0;L;;;;;N;;;;;
+A03C;YI SYLLABLE PIEX;Lo;0;L;;;;;N;;;;;
+A03D;YI SYLLABLE PIE;Lo;0;L;;;;;N;;;;;
+A03E;YI SYLLABLE PIEP;Lo;0;L;;;;;N;;;;;
+A03F;YI SYLLABLE PAT;Lo;0;L;;;;;N;;;;;
+A040;YI SYLLABLE PAX;Lo;0;L;;;;;N;;;;;
+A041;YI SYLLABLE PA;Lo;0;L;;;;;N;;;;;
+A042;YI SYLLABLE PAP;Lo;0;L;;;;;N;;;;;
+A043;YI SYLLABLE PUOX;Lo;0;L;;;;;N;;;;;
+A044;YI SYLLABLE PUO;Lo;0;L;;;;;N;;;;;
+A045;YI SYLLABLE PUOP;Lo;0;L;;;;;N;;;;;
+A046;YI SYLLABLE POT;Lo;0;L;;;;;N;;;;;
+A047;YI SYLLABLE POX;Lo;0;L;;;;;N;;;;;
+A048;YI SYLLABLE PO;Lo;0;L;;;;;N;;;;;
+A049;YI SYLLABLE POP;Lo;0;L;;;;;N;;;;;
+A04A;YI SYLLABLE PUT;Lo;0;L;;;;;N;;;;;
+A04B;YI SYLLABLE PUX;Lo;0;L;;;;;N;;;;;
+A04C;YI SYLLABLE PU;Lo;0;L;;;;;N;;;;;
+A04D;YI SYLLABLE PUP;Lo;0;L;;;;;N;;;;;
+A04E;YI SYLLABLE PURX;Lo;0;L;;;;;N;;;;;
+A04F;YI SYLLABLE PUR;Lo;0;L;;;;;N;;;;;
+A050;YI SYLLABLE PYT;Lo;0;L;;;;;N;;;;;
+A051;YI SYLLABLE PYX;Lo;0;L;;;;;N;;;;;
+A052;YI SYLLABLE PY;Lo;0;L;;;;;N;;;;;
+A053;YI SYLLABLE PYP;Lo;0;L;;;;;N;;;;;
+A054;YI SYLLABLE PYRX;Lo;0;L;;;;;N;;;;;
+A055;YI SYLLABLE PYR;Lo;0;L;;;;;N;;;;;
+A056;YI SYLLABLE BBIT;Lo;0;L;;;;;N;;;;;
+A057;YI SYLLABLE BBIX;Lo;0;L;;;;;N;;;;;
+A058;YI SYLLABLE BBI;Lo;0;L;;;;;N;;;;;
+A059;YI SYLLABLE BBIP;Lo;0;L;;;;;N;;;;;
+A05A;YI SYLLABLE BBIET;Lo;0;L;;;;;N;;;;;
+A05B;YI SYLLABLE BBIEX;Lo;0;L;;;;;N;;;;;
+A05C;YI SYLLABLE BBIE;Lo;0;L;;;;;N;;;;;
+A05D;YI SYLLABLE BBIEP;Lo;0;L;;;;;N;;;;;
+A05E;YI SYLLABLE BBAT;Lo;0;L;;;;;N;;;;;
+A05F;YI SYLLABLE BBAX;Lo;0;L;;;;;N;;;;;
+A060;YI SYLLABLE BBA;Lo;0;L;;;;;N;;;;;
+A061;YI SYLLABLE BBAP;Lo;0;L;;;;;N;;;;;
+A062;YI SYLLABLE BBUOX;Lo;0;L;;;;;N;;;;;
+A063;YI SYLLABLE BBUO;Lo;0;L;;;;;N;;;;;
+A064;YI SYLLABLE BBUOP;Lo;0;L;;;;;N;;;;;
+A065;YI SYLLABLE BBOT;Lo;0;L;;;;;N;;;;;
+A066;YI SYLLABLE BBOX;Lo;0;L;;;;;N;;;;;
+A067;YI SYLLABLE BBO;Lo;0;L;;;;;N;;;;;
+A068;YI SYLLABLE BBOP;Lo;0;L;;;;;N;;;;;
+A069;YI SYLLABLE BBEX;Lo;0;L;;;;;N;;;;;
+A06A;YI SYLLABLE BBE;Lo;0;L;;;;;N;;;;;
+A06B;YI SYLLABLE BBEP;Lo;0;L;;;;;N;;;;;
+A06C;YI SYLLABLE BBUT;Lo;0;L;;;;;N;;;;;
+A06D;YI SYLLABLE BBUX;Lo;0;L;;;;;N;;;;;
+A06E;YI SYLLABLE BBU;Lo;0;L;;;;;N;;;;;
+A06F;YI SYLLABLE BBUP;Lo;0;L;;;;;N;;;;;
+A070;YI SYLLABLE BBURX;Lo;0;L;;;;;N;;;;;
+A071;YI SYLLABLE BBUR;Lo;0;L;;;;;N;;;;;
+A072;YI SYLLABLE BBYT;Lo;0;L;;;;;N;;;;;
+A073;YI SYLLABLE BBYX;Lo;0;L;;;;;N;;;;;
+A074;YI SYLLABLE BBY;Lo;0;L;;;;;N;;;;;
+A075;YI SYLLABLE BBYP;Lo;0;L;;;;;N;;;;;
+A076;YI SYLLABLE NBIT;Lo;0;L;;;;;N;;;;;
+A077;YI SYLLABLE NBIX;Lo;0;L;;;;;N;;;;;
+A078;YI SYLLABLE NBI;Lo;0;L;;;;;N;;;;;
+A079;YI SYLLABLE NBIP;Lo;0;L;;;;;N;;;;;
+A07A;YI SYLLABLE NBIEX;Lo;0;L;;;;;N;;;;;
+A07B;YI SYLLABLE NBIE;Lo;0;L;;;;;N;;;;;
+A07C;YI SYLLABLE NBIEP;Lo;0;L;;;;;N;;;;;
+A07D;YI SYLLABLE NBAT;Lo;0;L;;;;;N;;;;;
+A07E;YI SYLLABLE NBAX;Lo;0;L;;;;;N;;;;;
+A07F;YI SYLLABLE NBA;Lo;0;L;;;;;N;;;;;
+A080;YI SYLLABLE NBAP;Lo;0;L;;;;;N;;;;;
+A081;YI SYLLABLE NBOT;Lo;0;L;;;;;N;;;;;
+A082;YI SYLLABLE NBOX;Lo;0;L;;;;;N;;;;;
+A083;YI SYLLABLE NBO;Lo;0;L;;;;;N;;;;;
+A084;YI SYLLABLE NBOP;Lo;0;L;;;;;N;;;;;
+A085;YI SYLLABLE NBUT;Lo;0;L;;;;;N;;;;;
+A086;YI SYLLABLE NBUX;Lo;0;L;;;;;N;;;;;
+A087;YI SYLLABLE NBU;Lo;0;L;;;;;N;;;;;
+A088;YI SYLLABLE NBUP;Lo;0;L;;;;;N;;;;;
+A089;YI SYLLABLE NBURX;Lo;0;L;;;;;N;;;;;
+A08A;YI SYLLABLE NBUR;Lo;0;L;;;;;N;;;;;
+A08B;YI SYLLABLE NBYT;Lo;0;L;;;;;N;;;;;
+A08C;YI SYLLABLE NBYX;Lo;0;L;;;;;N;;;;;
+A08D;YI SYLLABLE NBY;Lo;0;L;;;;;N;;;;;
+A08E;YI SYLLABLE NBYP;Lo;0;L;;;;;N;;;;;
+A08F;YI SYLLABLE NBYRX;Lo;0;L;;;;;N;;;;;
+A090;YI SYLLABLE NBYR;Lo;0;L;;;;;N;;;;;
+A091;YI SYLLABLE HMIT;Lo;0;L;;;;;N;;;;;
+A092;YI SYLLABLE HMIX;Lo;0;L;;;;;N;;;;;
+A093;YI SYLLABLE HMI;Lo;0;L;;;;;N;;;;;
+A094;YI SYLLABLE HMIP;Lo;0;L;;;;;N;;;;;
+A095;YI SYLLABLE HMIEX;Lo;0;L;;;;;N;;;;;
+A096;YI SYLLABLE HMIE;Lo;0;L;;;;;N;;;;;
+A097;YI SYLLABLE HMIEP;Lo;0;L;;;;;N;;;;;
+A098;YI SYLLABLE HMAT;Lo;0;L;;;;;N;;;;;
+A099;YI SYLLABLE HMAX;Lo;0;L;;;;;N;;;;;
+A09A;YI SYLLABLE HMA;Lo;0;L;;;;;N;;;;;
+A09B;YI SYLLABLE HMAP;Lo;0;L;;;;;N;;;;;
+A09C;YI SYLLABLE HMUOX;Lo;0;L;;;;;N;;;;;
+A09D;YI SYLLABLE HMUO;Lo;0;L;;;;;N;;;;;
+A09E;YI SYLLABLE HMUOP;Lo;0;L;;;;;N;;;;;
+A09F;YI SYLLABLE HMOT;Lo;0;L;;;;;N;;;;;
+A0A0;YI SYLLABLE HMOX;Lo;0;L;;;;;N;;;;;
+A0A1;YI SYLLABLE HMO;Lo;0;L;;;;;N;;;;;
+A0A2;YI SYLLABLE HMOP;Lo;0;L;;;;;N;;;;;
+A0A3;YI SYLLABLE HMUT;Lo;0;L;;;;;N;;;;;
+A0A4;YI SYLLABLE HMUX;Lo;0;L;;;;;N;;;;;
+A0A5;YI SYLLABLE HMU;Lo;0;L;;;;;N;;;;;
+A0A6;YI SYLLABLE HMUP;Lo;0;L;;;;;N;;;;;
+A0A7;YI SYLLABLE HMURX;Lo;0;L;;;;;N;;;;;
+A0A8;YI SYLLABLE HMUR;Lo;0;L;;;;;N;;;;;
+A0A9;YI SYLLABLE HMYX;Lo;0;L;;;;;N;;;;;
+A0AA;YI SYLLABLE HMY;Lo;0;L;;;;;N;;;;;
+A0AB;YI SYLLABLE HMYP;Lo;0;L;;;;;N;;;;;
+A0AC;YI SYLLABLE HMYRX;Lo;0;L;;;;;N;;;;;
+A0AD;YI SYLLABLE HMYR;Lo;0;L;;;;;N;;;;;
+A0AE;YI SYLLABLE MIT;Lo;0;L;;;;;N;;;;;
+A0AF;YI SYLLABLE MIX;Lo;0;L;;;;;N;;;;;
+A0B0;YI SYLLABLE MI;Lo;0;L;;;;;N;;;;;
+A0B1;YI SYLLABLE MIP;Lo;0;L;;;;;N;;;;;
+A0B2;YI SYLLABLE MIEX;Lo;0;L;;;;;N;;;;;
+A0B3;YI SYLLABLE MIE;Lo;0;L;;;;;N;;;;;
+A0B4;YI SYLLABLE MIEP;Lo;0;L;;;;;N;;;;;
+A0B5;YI SYLLABLE MAT;Lo;0;L;;;;;N;;;;;
+A0B6;YI SYLLABLE MAX;Lo;0;L;;;;;N;;;;;
+A0B7;YI SYLLABLE MA;Lo;0;L;;;;;N;;;;;
+A0B8;YI SYLLABLE MAP;Lo;0;L;;;;;N;;;;;
+A0B9;YI SYLLABLE MUOT;Lo;0;L;;;;;N;;;;;
+A0BA;YI SYLLABLE MUOX;Lo;0;L;;;;;N;;;;;
+A0BB;YI SYLLABLE MUO;Lo;0;L;;;;;N;;;;;
+A0BC;YI SYLLABLE MUOP;Lo;0;L;;;;;N;;;;;
+A0BD;YI SYLLABLE MOT;Lo;0;L;;;;;N;;;;;
+A0BE;YI SYLLABLE MOX;Lo;0;L;;;;;N;;;;;
+A0BF;YI SYLLABLE MO;Lo;0;L;;;;;N;;;;;
+A0C0;YI SYLLABLE MOP;Lo;0;L;;;;;N;;;;;
+A0C1;YI SYLLABLE MEX;Lo;0;L;;;;;N;;;;;
+A0C2;YI SYLLABLE ME;Lo;0;L;;;;;N;;;;;
+A0C3;YI SYLLABLE MUT;Lo;0;L;;;;;N;;;;;
+A0C4;YI SYLLABLE MUX;Lo;0;L;;;;;N;;;;;
+A0C5;YI SYLLABLE MU;Lo;0;L;;;;;N;;;;;
+A0C6;YI SYLLABLE MUP;Lo;0;L;;;;;N;;;;;
+A0C7;YI SYLLABLE MURX;Lo;0;L;;;;;N;;;;;
+A0C8;YI SYLLABLE MUR;Lo;0;L;;;;;N;;;;;
+A0C9;YI SYLLABLE MYT;Lo;0;L;;;;;N;;;;;
+A0CA;YI SYLLABLE MYX;Lo;0;L;;;;;N;;;;;
+A0CB;YI SYLLABLE MY;Lo;0;L;;;;;N;;;;;
+A0CC;YI SYLLABLE MYP;Lo;0;L;;;;;N;;;;;
+A0CD;YI SYLLABLE FIT;Lo;0;L;;;;;N;;;;;
+A0CE;YI SYLLABLE FIX;Lo;0;L;;;;;N;;;;;
+A0CF;YI SYLLABLE FI;Lo;0;L;;;;;N;;;;;
+A0D0;YI SYLLABLE FIP;Lo;0;L;;;;;N;;;;;
+A0D1;YI SYLLABLE FAT;Lo;0;L;;;;;N;;;;;
+A0D2;YI SYLLABLE FAX;Lo;0;L;;;;;N;;;;;
+A0D3;YI SYLLABLE FA;Lo;0;L;;;;;N;;;;;
+A0D4;YI SYLLABLE FAP;Lo;0;L;;;;;N;;;;;
+A0D5;YI SYLLABLE FOX;Lo;0;L;;;;;N;;;;;
+A0D6;YI SYLLABLE FO;Lo;0;L;;;;;N;;;;;
+A0D7;YI SYLLABLE FOP;Lo;0;L;;;;;N;;;;;
+A0D8;YI SYLLABLE FUT;Lo;0;L;;;;;N;;;;;
+A0D9;YI SYLLABLE FUX;Lo;0;L;;;;;N;;;;;
+A0DA;YI SYLLABLE FU;Lo;0;L;;;;;N;;;;;
+A0DB;YI SYLLABLE FUP;Lo;0;L;;;;;N;;;;;
+A0DC;YI SYLLABLE FURX;Lo;0;L;;;;;N;;;;;
+A0DD;YI SYLLABLE FUR;Lo;0;L;;;;;N;;;;;
+A0DE;YI SYLLABLE FYT;Lo;0;L;;;;;N;;;;;
+A0DF;YI SYLLABLE FYX;Lo;0;L;;;;;N;;;;;
+A0E0;YI SYLLABLE FY;Lo;0;L;;;;;N;;;;;
+A0E1;YI SYLLABLE FYP;Lo;0;L;;;;;N;;;;;
+A0E2;YI SYLLABLE VIT;Lo;0;L;;;;;N;;;;;
+A0E3;YI SYLLABLE VIX;Lo;0;L;;;;;N;;;;;
+A0E4;YI SYLLABLE VI;Lo;0;L;;;;;N;;;;;
+A0E5;YI SYLLABLE VIP;Lo;0;L;;;;;N;;;;;
+A0E6;YI SYLLABLE VIET;Lo;0;L;;;;;N;;;;;
+A0E7;YI SYLLABLE VIEX;Lo;0;L;;;;;N;;;;;
+A0E8;YI SYLLABLE VIE;Lo;0;L;;;;;N;;;;;
+A0E9;YI SYLLABLE VIEP;Lo;0;L;;;;;N;;;;;
+A0EA;YI SYLLABLE VAT;Lo;0;L;;;;;N;;;;;
+A0EB;YI SYLLABLE VAX;Lo;0;L;;;;;N;;;;;
+A0EC;YI SYLLABLE VA;Lo;0;L;;;;;N;;;;;
+A0ED;YI SYLLABLE VAP;Lo;0;L;;;;;N;;;;;
+A0EE;YI SYLLABLE VOT;Lo;0;L;;;;;N;;;;;
+A0EF;YI SYLLABLE VOX;Lo;0;L;;;;;N;;;;;
+A0F0;YI SYLLABLE VO;Lo;0;L;;;;;N;;;;;
+A0F1;YI SYLLABLE VOP;Lo;0;L;;;;;N;;;;;
+A0F2;YI SYLLABLE VEX;Lo;0;L;;;;;N;;;;;
+A0F3;YI SYLLABLE VEP;Lo;0;L;;;;;N;;;;;
+A0F4;YI SYLLABLE VUT;Lo;0;L;;;;;N;;;;;
+A0F5;YI SYLLABLE VUX;Lo;0;L;;;;;N;;;;;
+A0F6;YI SYLLABLE VU;Lo;0;L;;;;;N;;;;;
+A0F7;YI SYLLABLE VUP;Lo;0;L;;;;;N;;;;;
+A0F8;YI SYLLABLE VURX;Lo;0;L;;;;;N;;;;;
+A0F9;YI SYLLABLE VUR;Lo;0;L;;;;;N;;;;;
+A0FA;YI SYLLABLE VYT;Lo;0;L;;;;;N;;;;;
+A0FB;YI SYLLABLE VYX;Lo;0;L;;;;;N;;;;;
+A0FC;YI SYLLABLE VY;Lo;0;L;;;;;N;;;;;
+A0FD;YI SYLLABLE VYP;Lo;0;L;;;;;N;;;;;
+A0FE;YI SYLLABLE VYRX;Lo;0;L;;;;;N;;;;;
+A0FF;YI SYLLABLE VYR;Lo;0;L;;;;;N;;;;;
+A100;YI SYLLABLE DIT;Lo;0;L;;;;;N;;;;;
+A101;YI SYLLABLE DIX;Lo;0;L;;;;;N;;;;;
+A102;YI SYLLABLE DI;Lo;0;L;;;;;N;;;;;
+A103;YI SYLLABLE DIP;Lo;0;L;;;;;N;;;;;
+A104;YI SYLLABLE DIEX;Lo;0;L;;;;;N;;;;;
+A105;YI SYLLABLE DIE;Lo;0;L;;;;;N;;;;;
+A106;YI SYLLABLE DIEP;Lo;0;L;;;;;N;;;;;
+A107;YI SYLLABLE DAT;Lo;0;L;;;;;N;;;;;
+A108;YI SYLLABLE DAX;Lo;0;L;;;;;N;;;;;
+A109;YI SYLLABLE DA;Lo;0;L;;;;;N;;;;;
+A10A;YI SYLLABLE DAP;Lo;0;L;;;;;N;;;;;
+A10B;YI SYLLABLE DUOX;Lo;0;L;;;;;N;;;;;
+A10C;YI SYLLABLE DUO;Lo;0;L;;;;;N;;;;;
+A10D;YI SYLLABLE DOT;Lo;0;L;;;;;N;;;;;
+A10E;YI SYLLABLE DOX;Lo;0;L;;;;;N;;;;;
+A10F;YI SYLLABLE DO;Lo;0;L;;;;;N;;;;;
+A110;YI SYLLABLE DOP;Lo;0;L;;;;;N;;;;;
+A111;YI SYLLABLE DEX;Lo;0;L;;;;;N;;;;;
+A112;YI SYLLABLE DE;Lo;0;L;;;;;N;;;;;
+A113;YI SYLLABLE DEP;Lo;0;L;;;;;N;;;;;
+A114;YI SYLLABLE DUT;Lo;0;L;;;;;N;;;;;
+A115;YI SYLLABLE DUX;Lo;0;L;;;;;N;;;;;
+A116;YI SYLLABLE DU;Lo;0;L;;;;;N;;;;;
+A117;YI SYLLABLE DUP;Lo;0;L;;;;;N;;;;;
+A118;YI SYLLABLE DURX;Lo;0;L;;;;;N;;;;;
+A119;YI SYLLABLE DUR;Lo;0;L;;;;;N;;;;;
+A11A;YI SYLLABLE TIT;Lo;0;L;;;;;N;;;;;
+A11B;YI SYLLABLE TIX;Lo;0;L;;;;;N;;;;;
+A11C;YI SYLLABLE TI;Lo;0;L;;;;;N;;;;;
+A11D;YI SYLLABLE TIP;Lo;0;L;;;;;N;;;;;
+A11E;YI SYLLABLE TIEX;Lo;0;L;;;;;N;;;;;
+A11F;YI SYLLABLE TIE;Lo;0;L;;;;;N;;;;;
+A120;YI SYLLABLE TIEP;Lo;0;L;;;;;N;;;;;
+A121;YI SYLLABLE TAT;Lo;0;L;;;;;N;;;;;
+A122;YI SYLLABLE TAX;Lo;0;L;;;;;N;;;;;
+A123;YI SYLLABLE TA;Lo;0;L;;;;;N;;;;;
+A124;YI SYLLABLE TAP;Lo;0;L;;;;;N;;;;;
+A125;YI SYLLABLE TUOT;Lo;0;L;;;;;N;;;;;
+A126;YI SYLLABLE TUOX;Lo;0;L;;;;;N;;;;;
+A127;YI SYLLABLE TUO;Lo;0;L;;;;;N;;;;;
+A128;YI SYLLABLE TUOP;Lo;0;L;;;;;N;;;;;
+A129;YI SYLLABLE TOT;Lo;0;L;;;;;N;;;;;
+A12A;YI SYLLABLE TOX;Lo;0;L;;;;;N;;;;;
+A12B;YI SYLLABLE TO;Lo;0;L;;;;;N;;;;;
+A12C;YI SYLLABLE TOP;Lo;0;L;;;;;N;;;;;
+A12D;YI SYLLABLE TEX;Lo;0;L;;;;;N;;;;;
+A12E;YI SYLLABLE TE;Lo;0;L;;;;;N;;;;;
+A12F;YI SYLLABLE TEP;Lo;0;L;;;;;N;;;;;
+A130;YI SYLLABLE TUT;Lo;0;L;;;;;N;;;;;
+A131;YI SYLLABLE TUX;Lo;0;L;;;;;N;;;;;
+A132;YI SYLLABLE TU;Lo;0;L;;;;;N;;;;;
+A133;YI SYLLABLE TUP;Lo;0;L;;;;;N;;;;;
+A134;YI SYLLABLE TURX;Lo;0;L;;;;;N;;;;;
+A135;YI SYLLABLE TUR;Lo;0;L;;;;;N;;;;;
+A136;YI SYLLABLE DDIT;Lo;0;L;;;;;N;;;;;
+A137;YI SYLLABLE DDIX;Lo;0;L;;;;;N;;;;;
+A138;YI SYLLABLE DDI;Lo;0;L;;;;;N;;;;;
+A139;YI SYLLABLE DDIP;Lo;0;L;;;;;N;;;;;
+A13A;YI SYLLABLE DDIEX;Lo;0;L;;;;;N;;;;;
+A13B;YI SYLLABLE DDIE;Lo;0;L;;;;;N;;;;;
+A13C;YI SYLLABLE DDIEP;Lo;0;L;;;;;N;;;;;
+A13D;YI SYLLABLE DDAT;Lo;0;L;;;;;N;;;;;
+A13E;YI SYLLABLE DDAX;Lo;0;L;;;;;N;;;;;
+A13F;YI SYLLABLE DDA;Lo;0;L;;;;;N;;;;;
+A140;YI SYLLABLE DDAP;Lo;0;L;;;;;N;;;;;
+A141;YI SYLLABLE DDUOX;Lo;0;L;;;;;N;;;;;
+A142;YI SYLLABLE DDUO;Lo;0;L;;;;;N;;;;;
+A143;YI SYLLABLE DDUOP;Lo;0;L;;;;;N;;;;;
+A144;YI SYLLABLE DDOT;Lo;0;L;;;;;N;;;;;
+A145;YI SYLLABLE DDOX;Lo;0;L;;;;;N;;;;;
+A146;YI SYLLABLE DDO;Lo;0;L;;;;;N;;;;;
+A147;YI SYLLABLE DDOP;Lo;0;L;;;;;N;;;;;
+A148;YI SYLLABLE DDEX;Lo;0;L;;;;;N;;;;;
+A149;YI SYLLABLE DDE;Lo;0;L;;;;;N;;;;;
+A14A;YI SYLLABLE DDEP;Lo;0;L;;;;;N;;;;;
+A14B;YI SYLLABLE DDUT;Lo;0;L;;;;;N;;;;;
+A14C;YI SYLLABLE DDUX;Lo;0;L;;;;;N;;;;;
+A14D;YI SYLLABLE DDU;Lo;0;L;;;;;N;;;;;
+A14E;YI SYLLABLE DDUP;Lo;0;L;;;;;N;;;;;
+A14F;YI SYLLABLE DDURX;Lo;0;L;;;;;N;;;;;
+A150;YI SYLLABLE DDUR;Lo;0;L;;;;;N;;;;;
+A151;YI SYLLABLE NDIT;Lo;0;L;;;;;N;;;;;
+A152;YI SYLLABLE NDIX;Lo;0;L;;;;;N;;;;;
+A153;YI SYLLABLE NDI;Lo;0;L;;;;;N;;;;;
+A154;YI SYLLABLE NDIP;Lo;0;L;;;;;N;;;;;
+A155;YI SYLLABLE NDIEX;Lo;0;L;;;;;N;;;;;
+A156;YI SYLLABLE NDIE;Lo;0;L;;;;;N;;;;;
+A157;YI SYLLABLE NDAT;Lo;0;L;;;;;N;;;;;
+A158;YI SYLLABLE NDAX;Lo;0;L;;;;;N;;;;;
+A159;YI SYLLABLE NDA;Lo;0;L;;;;;N;;;;;
+A15A;YI SYLLABLE NDAP;Lo;0;L;;;;;N;;;;;
+A15B;YI SYLLABLE NDOT;Lo;0;L;;;;;N;;;;;
+A15C;YI SYLLABLE NDOX;Lo;0;L;;;;;N;;;;;
+A15D;YI SYLLABLE NDO;Lo;0;L;;;;;N;;;;;
+A15E;YI SYLLABLE NDOP;Lo;0;L;;;;;N;;;;;
+A15F;YI SYLLABLE NDEX;Lo;0;L;;;;;N;;;;;
+A160;YI SYLLABLE NDE;Lo;0;L;;;;;N;;;;;
+A161;YI SYLLABLE NDEP;Lo;0;L;;;;;N;;;;;
+A162;YI SYLLABLE NDUT;Lo;0;L;;;;;N;;;;;
+A163;YI SYLLABLE NDUX;Lo;0;L;;;;;N;;;;;
+A164;YI SYLLABLE NDU;Lo;0;L;;;;;N;;;;;
+A165;YI SYLLABLE NDUP;Lo;0;L;;;;;N;;;;;
+A166;YI SYLLABLE NDURX;Lo;0;L;;;;;N;;;;;
+A167;YI SYLLABLE NDUR;Lo;0;L;;;;;N;;;;;
+A168;YI SYLLABLE HNIT;Lo;0;L;;;;;N;;;;;
+A169;YI SYLLABLE HNIX;Lo;0;L;;;;;N;;;;;
+A16A;YI SYLLABLE HNI;Lo;0;L;;;;;N;;;;;
+A16B;YI SYLLABLE HNIP;Lo;0;L;;;;;N;;;;;
+A16C;YI SYLLABLE HNIET;Lo;0;L;;;;;N;;;;;
+A16D;YI SYLLABLE HNIEX;Lo;0;L;;;;;N;;;;;
+A16E;YI SYLLABLE HNIE;Lo;0;L;;;;;N;;;;;
+A16F;YI SYLLABLE HNIEP;Lo;0;L;;;;;N;;;;;
+A170;YI SYLLABLE HNAT;Lo;0;L;;;;;N;;;;;
+A171;YI SYLLABLE HNAX;Lo;0;L;;;;;N;;;;;
+A172;YI SYLLABLE HNA;Lo;0;L;;;;;N;;;;;
+A173;YI SYLLABLE HNAP;Lo;0;L;;;;;N;;;;;
+A174;YI SYLLABLE HNUOX;Lo;0;L;;;;;N;;;;;
+A175;YI SYLLABLE HNUO;Lo;0;L;;;;;N;;;;;
+A176;YI SYLLABLE HNOT;Lo;0;L;;;;;N;;;;;
+A177;YI SYLLABLE HNOX;Lo;0;L;;;;;N;;;;;
+A178;YI SYLLABLE HNOP;Lo;0;L;;;;;N;;;;;
+A179;YI SYLLABLE HNEX;Lo;0;L;;;;;N;;;;;
+A17A;YI SYLLABLE HNE;Lo;0;L;;;;;N;;;;;
+A17B;YI SYLLABLE HNEP;Lo;0;L;;;;;N;;;;;
+A17C;YI SYLLABLE HNUT;Lo;0;L;;;;;N;;;;;
+A17D;YI SYLLABLE NIT;Lo;0;L;;;;;N;;;;;
+A17E;YI SYLLABLE NIX;Lo;0;L;;;;;N;;;;;
+A17F;YI SYLLABLE NI;Lo;0;L;;;;;N;;;;;
+A180;YI SYLLABLE NIP;Lo;0;L;;;;;N;;;;;
+A181;YI SYLLABLE NIEX;Lo;0;L;;;;;N;;;;;
+A182;YI SYLLABLE NIE;Lo;0;L;;;;;N;;;;;
+A183;YI SYLLABLE NIEP;Lo;0;L;;;;;N;;;;;
+A184;YI SYLLABLE NAX;Lo;0;L;;;;;N;;;;;
+A185;YI SYLLABLE NA;Lo;0;L;;;;;N;;;;;
+A186;YI SYLLABLE NAP;Lo;0;L;;;;;N;;;;;
+A187;YI SYLLABLE NUOX;Lo;0;L;;;;;N;;;;;
+A188;YI SYLLABLE NUO;Lo;0;L;;;;;N;;;;;
+A189;YI SYLLABLE NUOP;Lo;0;L;;;;;N;;;;;
+A18A;YI SYLLABLE NOT;Lo;0;L;;;;;N;;;;;
+A18B;YI SYLLABLE NOX;Lo;0;L;;;;;N;;;;;
+A18C;YI SYLLABLE NO;Lo;0;L;;;;;N;;;;;
+A18D;YI SYLLABLE NOP;Lo;0;L;;;;;N;;;;;
+A18E;YI SYLLABLE NEX;Lo;0;L;;;;;N;;;;;
+A18F;YI SYLLABLE NE;Lo;0;L;;;;;N;;;;;
+A190;YI SYLLABLE NEP;Lo;0;L;;;;;N;;;;;
+A191;YI SYLLABLE NUT;Lo;0;L;;;;;N;;;;;
+A192;YI SYLLABLE NUX;Lo;0;L;;;;;N;;;;;
+A193;YI SYLLABLE NU;Lo;0;L;;;;;N;;;;;
+A194;YI SYLLABLE NUP;Lo;0;L;;;;;N;;;;;
+A195;YI SYLLABLE NURX;Lo;0;L;;;;;N;;;;;
+A196;YI SYLLABLE NUR;Lo;0;L;;;;;N;;;;;
+A197;YI SYLLABLE HLIT;Lo;0;L;;;;;N;;;;;
+A198;YI SYLLABLE HLIX;Lo;0;L;;;;;N;;;;;
+A199;YI SYLLABLE HLI;Lo;0;L;;;;;N;;;;;
+A19A;YI SYLLABLE HLIP;Lo;0;L;;;;;N;;;;;
+A19B;YI SYLLABLE HLIEX;Lo;0;L;;;;;N;;;;;
+A19C;YI SYLLABLE HLIE;Lo;0;L;;;;;N;;;;;
+A19D;YI SYLLABLE HLIEP;Lo;0;L;;;;;N;;;;;
+A19E;YI SYLLABLE HLAT;Lo;0;L;;;;;N;;;;;
+A19F;YI SYLLABLE HLAX;Lo;0;L;;;;;N;;;;;
+A1A0;YI SYLLABLE HLA;Lo;0;L;;;;;N;;;;;
+A1A1;YI SYLLABLE HLAP;Lo;0;L;;;;;N;;;;;
+A1A2;YI SYLLABLE HLUOX;Lo;0;L;;;;;N;;;;;
+A1A3;YI SYLLABLE HLUO;Lo;0;L;;;;;N;;;;;
+A1A4;YI SYLLABLE HLUOP;Lo;0;L;;;;;N;;;;;
+A1A5;YI SYLLABLE HLOX;Lo;0;L;;;;;N;;;;;
+A1A6;YI SYLLABLE HLO;Lo;0;L;;;;;N;;;;;
+A1A7;YI SYLLABLE HLOP;Lo;0;L;;;;;N;;;;;
+A1A8;YI SYLLABLE HLEX;Lo;0;L;;;;;N;;;;;
+A1A9;YI SYLLABLE HLE;Lo;0;L;;;;;N;;;;;
+A1AA;YI SYLLABLE HLEP;Lo;0;L;;;;;N;;;;;
+A1AB;YI SYLLABLE HLUT;Lo;0;L;;;;;N;;;;;
+A1AC;YI SYLLABLE HLUX;Lo;0;L;;;;;N;;;;;
+A1AD;YI SYLLABLE HLU;Lo;0;L;;;;;N;;;;;
+A1AE;YI SYLLABLE HLUP;Lo;0;L;;;;;N;;;;;
+A1AF;YI SYLLABLE HLURX;Lo;0;L;;;;;N;;;;;
+A1B0;YI SYLLABLE HLUR;Lo;0;L;;;;;N;;;;;
+A1B1;YI SYLLABLE HLYT;Lo;0;L;;;;;N;;;;;
+A1B2;YI SYLLABLE HLYX;Lo;0;L;;;;;N;;;;;
+A1B3;YI SYLLABLE HLY;Lo;0;L;;;;;N;;;;;
+A1B4;YI SYLLABLE HLYP;Lo;0;L;;;;;N;;;;;
+A1B5;YI SYLLABLE HLYRX;Lo;0;L;;;;;N;;;;;
+A1B6;YI SYLLABLE HLYR;Lo;0;L;;;;;N;;;;;
+A1B7;YI SYLLABLE LIT;Lo;0;L;;;;;N;;;;;
+A1B8;YI SYLLABLE LIX;Lo;0;L;;;;;N;;;;;
+A1B9;YI SYLLABLE LI;Lo;0;L;;;;;N;;;;;
+A1BA;YI SYLLABLE LIP;Lo;0;L;;;;;N;;;;;
+A1BB;YI SYLLABLE LIET;Lo;0;L;;;;;N;;;;;
+A1BC;YI SYLLABLE LIEX;Lo;0;L;;;;;N;;;;;
+A1BD;YI SYLLABLE LIE;Lo;0;L;;;;;N;;;;;
+A1BE;YI SYLLABLE LIEP;Lo;0;L;;;;;N;;;;;
+A1BF;YI SYLLABLE LAT;Lo;0;L;;;;;N;;;;;
+A1C0;YI SYLLABLE LAX;Lo;0;L;;;;;N;;;;;
+A1C1;YI SYLLABLE LA;Lo;0;L;;;;;N;;;;;
+A1C2;YI SYLLABLE LAP;Lo;0;L;;;;;N;;;;;
+A1C3;YI SYLLABLE LUOT;Lo;0;L;;;;;N;;;;;
+A1C4;YI SYLLABLE LUOX;Lo;0;L;;;;;N;;;;;
+A1C5;YI SYLLABLE LUO;Lo;0;L;;;;;N;;;;;
+A1C6;YI SYLLABLE LUOP;Lo;0;L;;;;;N;;;;;
+A1C7;YI SYLLABLE LOT;Lo;0;L;;;;;N;;;;;
+A1C8;YI SYLLABLE LOX;Lo;0;L;;;;;N;;;;;
+A1C9;YI SYLLABLE LO;Lo;0;L;;;;;N;;;;;
+A1CA;YI SYLLABLE LOP;Lo;0;L;;;;;N;;;;;
+A1CB;YI SYLLABLE LEX;Lo;0;L;;;;;N;;;;;
+A1CC;YI SYLLABLE LE;Lo;0;L;;;;;N;;;;;
+A1CD;YI SYLLABLE LEP;Lo;0;L;;;;;N;;;;;
+A1CE;YI SYLLABLE LUT;Lo;0;L;;;;;N;;;;;
+A1CF;YI SYLLABLE LUX;Lo;0;L;;;;;N;;;;;
+A1D0;YI SYLLABLE LU;Lo;0;L;;;;;N;;;;;
+A1D1;YI SYLLABLE LUP;Lo;0;L;;;;;N;;;;;
+A1D2;YI SYLLABLE LURX;Lo;0;L;;;;;N;;;;;
+A1D3;YI SYLLABLE LUR;Lo;0;L;;;;;N;;;;;
+A1D4;YI SYLLABLE LYT;Lo;0;L;;;;;N;;;;;
+A1D5;YI SYLLABLE LYX;Lo;0;L;;;;;N;;;;;
+A1D6;YI SYLLABLE LY;Lo;0;L;;;;;N;;;;;
+A1D7;YI SYLLABLE LYP;Lo;0;L;;;;;N;;;;;
+A1D8;YI SYLLABLE LYRX;Lo;0;L;;;;;N;;;;;
+A1D9;YI SYLLABLE LYR;Lo;0;L;;;;;N;;;;;
+A1DA;YI SYLLABLE GIT;Lo;0;L;;;;;N;;;;;
+A1DB;YI SYLLABLE GIX;Lo;0;L;;;;;N;;;;;
+A1DC;YI SYLLABLE GI;Lo;0;L;;;;;N;;;;;
+A1DD;YI SYLLABLE GIP;Lo;0;L;;;;;N;;;;;
+A1DE;YI SYLLABLE GIET;Lo;0;L;;;;;N;;;;;
+A1DF;YI SYLLABLE GIEX;Lo;0;L;;;;;N;;;;;
+A1E0;YI SYLLABLE GIE;Lo;0;L;;;;;N;;;;;
+A1E1;YI SYLLABLE GIEP;Lo;0;L;;;;;N;;;;;
+A1E2;YI SYLLABLE GAT;Lo;0;L;;;;;N;;;;;
+A1E3;YI SYLLABLE GAX;Lo;0;L;;;;;N;;;;;
+A1E4;YI SYLLABLE GA;Lo;0;L;;;;;N;;;;;
+A1E5;YI SYLLABLE GAP;Lo;0;L;;;;;N;;;;;
+A1E6;YI SYLLABLE GUOT;Lo;0;L;;;;;N;;;;;
+A1E7;YI SYLLABLE GUOX;Lo;0;L;;;;;N;;;;;
+A1E8;YI SYLLABLE GUO;Lo;0;L;;;;;N;;;;;
+A1E9;YI SYLLABLE GUOP;Lo;0;L;;;;;N;;;;;
+A1EA;YI SYLLABLE GOT;Lo;0;L;;;;;N;;;;;
+A1EB;YI SYLLABLE GOX;Lo;0;L;;;;;N;;;;;
+A1EC;YI SYLLABLE GO;Lo;0;L;;;;;N;;;;;
+A1ED;YI SYLLABLE GOP;Lo;0;L;;;;;N;;;;;
+A1EE;YI SYLLABLE GET;Lo;0;L;;;;;N;;;;;
+A1EF;YI SYLLABLE GEX;Lo;0;L;;;;;N;;;;;
+A1F0;YI SYLLABLE GE;Lo;0;L;;;;;N;;;;;
+A1F1;YI SYLLABLE GEP;Lo;0;L;;;;;N;;;;;
+A1F2;YI SYLLABLE GUT;Lo;0;L;;;;;N;;;;;
+A1F3;YI SYLLABLE GUX;Lo;0;L;;;;;N;;;;;
+A1F4;YI SYLLABLE GU;Lo;0;L;;;;;N;;;;;
+A1F5;YI SYLLABLE GUP;Lo;0;L;;;;;N;;;;;
+A1F6;YI SYLLABLE GURX;Lo;0;L;;;;;N;;;;;
+A1F7;YI SYLLABLE GUR;Lo;0;L;;;;;N;;;;;
+A1F8;YI SYLLABLE KIT;Lo;0;L;;;;;N;;;;;
+A1F9;YI SYLLABLE KIX;Lo;0;L;;;;;N;;;;;
+A1FA;YI SYLLABLE KI;Lo;0;L;;;;;N;;;;;
+A1FB;YI SYLLABLE KIP;Lo;0;L;;;;;N;;;;;
+A1FC;YI SYLLABLE KIEX;Lo;0;L;;;;;N;;;;;
+A1FD;YI SYLLABLE KIE;Lo;0;L;;;;;N;;;;;
+A1FE;YI SYLLABLE KIEP;Lo;0;L;;;;;N;;;;;
+A1FF;YI SYLLABLE KAT;Lo;0;L;;;;;N;;;;;
+A200;YI SYLLABLE KAX;Lo;0;L;;;;;N;;;;;
+A201;YI SYLLABLE KA;Lo;0;L;;;;;N;;;;;
+A202;YI SYLLABLE KAP;Lo;0;L;;;;;N;;;;;
+A203;YI SYLLABLE KUOX;Lo;0;L;;;;;N;;;;;
+A204;YI SYLLABLE KUO;Lo;0;L;;;;;N;;;;;
+A205;YI SYLLABLE KUOP;Lo;0;L;;;;;N;;;;;
+A206;YI SYLLABLE KOT;Lo;0;L;;;;;N;;;;;
+A207;YI SYLLABLE KOX;Lo;0;L;;;;;N;;;;;
+A208;YI SYLLABLE KO;Lo;0;L;;;;;N;;;;;
+A209;YI SYLLABLE KOP;Lo;0;L;;;;;N;;;;;
+A20A;YI SYLLABLE KET;Lo;0;L;;;;;N;;;;;
+A20B;YI SYLLABLE KEX;Lo;0;L;;;;;N;;;;;
+A20C;YI SYLLABLE KE;Lo;0;L;;;;;N;;;;;
+A20D;YI SYLLABLE KEP;Lo;0;L;;;;;N;;;;;
+A20E;YI SYLLABLE KUT;Lo;0;L;;;;;N;;;;;
+A20F;YI SYLLABLE KUX;Lo;0;L;;;;;N;;;;;
+A210;YI SYLLABLE KU;Lo;0;L;;;;;N;;;;;
+A211;YI SYLLABLE KUP;Lo;0;L;;;;;N;;;;;
+A212;YI SYLLABLE KURX;Lo;0;L;;;;;N;;;;;
+A213;YI SYLLABLE KUR;Lo;0;L;;;;;N;;;;;
+A214;YI SYLLABLE GGIT;Lo;0;L;;;;;N;;;;;
+A215;YI SYLLABLE GGIX;Lo;0;L;;;;;N;;;;;
+A216;YI SYLLABLE GGI;Lo;0;L;;;;;N;;;;;
+A217;YI SYLLABLE GGIEX;Lo;0;L;;;;;N;;;;;
+A218;YI SYLLABLE GGIE;Lo;0;L;;;;;N;;;;;
+A219;YI SYLLABLE GGIEP;Lo;0;L;;;;;N;;;;;
+A21A;YI SYLLABLE GGAT;Lo;0;L;;;;;N;;;;;
+A21B;YI SYLLABLE GGAX;Lo;0;L;;;;;N;;;;;
+A21C;YI SYLLABLE GGA;Lo;0;L;;;;;N;;;;;
+A21D;YI SYLLABLE GGAP;Lo;0;L;;;;;N;;;;;
+A21E;YI SYLLABLE GGUOT;Lo;0;L;;;;;N;;;;;
+A21F;YI SYLLABLE GGUOX;Lo;0;L;;;;;N;;;;;
+A220;YI SYLLABLE GGUO;Lo;0;L;;;;;N;;;;;
+A221;YI SYLLABLE GGUOP;Lo;0;L;;;;;N;;;;;
+A222;YI SYLLABLE GGOT;Lo;0;L;;;;;N;;;;;
+A223;YI SYLLABLE GGOX;Lo;0;L;;;;;N;;;;;
+A224;YI SYLLABLE GGO;Lo;0;L;;;;;N;;;;;
+A225;YI SYLLABLE GGOP;Lo;0;L;;;;;N;;;;;
+A226;YI SYLLABLE GGET;Lo;0;L;;;;;N;;;;;
+A227;YI SYLLABLE GGEX;Lo;0;L;;;;;N;;;;;
+A228;YI SYLLABLE GGE;Lo;0;L;;;;;N;;;;;
+A229;YI SYLLABLE GGEP;Lo;0;L;;;;;N;;;;;
+A22A;YI SYLLABLE GGUT;Lo;0;L;;;;;N;;;;;
+A22B;YI SYLLABLE GGUX;Lo;0;L;;;;;N;;;;;
+A22C;YI SYLLABLE GGU;Lo;0;L;;;;;N;;;;;
+A22D;YI SYLLABLE GGUP;Lo;0;L;;;;;N;;;;;
+A22E;YI SYLLABLE GGURX;Lo;0;L;;;;;N;;;;;
+A22F;YI SYLLABLE GGUR;Lo;0;L;;;;;N;;;;;
+A230;YI SYLLABLE MGIEX;Lo;0;L;;;;;N;;;;;
+A231;YI SYLLABLE MGIE;Lo;0;L;;;;;N;;;;;
+A232;YI SYLLABLE MGAT;Lo;0;L;;;;;N;;;;;
+A233;YI SYLLABLE MGAX;Lo;0;L;;;;;N;;;;;
+A234;YI SYLLABLE MGA;Lo;0;L;;;;;N;;;;;
+A235;YI SYLLABLE MGAP;Lo;0;L;;;;;N;;;;;
+A236;YI SYLLABLE MGUOX;Lo;0;L;;;;;N;;;;;
+A237;YI SYLLABLE MGUO;Lo;0;L;;;;;N;;;;;
+A238;YI SYLLABLE MGUOP;Lo;0;L;;;;;N;;;;;
+A239;YI SYLLABLE MGOT;Lo;0;L;;;;;N;;;;;
+A23A;YI SYLLABLE MGOX;Lo;0;L;;;;;N;;;;;
+A23B;YI SYLLABLE MGO;Lo;0;L;;;;;N;;;;;
+A23C;YI SYLLABLE MGOP;Lo;0;L;;;;;N;;;;;
+A23D;YI SYLLABLE MGEX;Lo;0;L;;;;;N;;;;;
+A23E;YI SYLLABLE MGE;Lo;0;L;;;;;N;;;;;
+A23F;YI SYLLABLE MGEP;Lo;0;L;;;;;N;;;;;
+A240;YI SYLLABLE MGUT;Lo;0;L;;;;;N;;;;;
+A241;YI SYLLABLE MGUX;Lo;0;L;;;;;N;;;;;
+A242;YI SYLLABLE MGU;Lo;0;L;;;;;N;;;;;
+A243;YI SYLLABLE MGUP;Lo;0;L;;;;;N;;;;;
+A244;YI SYLLABLE MGURX;Lo;0;L;;;;;N;;;;;
+A245;YI SYLLABLE MGUR;Lo;0;L;;;;;N;;;;;
+A246;YI SYLLABLE HXIT;Lo;0;L;;;;;N;;;;;
+A247;YI SYLLABLE HXIX;Lo;0;L;;;;;N;;;;;
+A248;YI SYLLABLE HXI;Lo;0;L;;;;;N;;;;;
+A249;YI SYLLABLE HXIP;Lo;0;L;;;;;N;;;;;
+A24A;YI SYLLABLE HXIET;Lo;0;L;;;;;N;;;;;
+A24B;YI SYLLABLE HXIEX;Lo;0;L;;;;;N;;;;;
+A24C;YI SYLLABLE HXIE;Lo;0;L;;;;;N;;;;;
+A24D;YI SYLLABLE HXIEP;Lo;0;L;;;;;N;;;;;
+A24E;YI SYLLABLE HXAT;Lo;0;L;;;;;N;;;;;
+A24F;YI SYLLABLE HXAX;Lo;0;L;;;;;N;;;;;
+A250;YI SYLLABLE HXA;Lo;0;L;;;;;N;;;;;
+A251;YI SYLLABLE HXAP;Lo;0;L;;;;;N;;;;;
+A252;YI SYLLABLE HXUOT;Lo;0;L;;;;;N;;;;;
+A253;YI SYLLABLE HXUOX;Lo;0;L;;;;;N;;;;;
+A254;YI SYLLABLE HXUO;Lo;0;L;;;;;N;;;;;
+A255;YI SYLLABLE HXUOP;Lo;0;L;;;;;N;;;;;
+A256;YI SYLLABLE HXOT;Lo;0;L;;;;;N;;;;;
+A257;YI SYLLABLE HXOX;Lo;0;L;;;;;N;;;;;
+A258;YI SYLLABLE HXO;Lo;0;L;;;;;N;;;;;
+A259;YI SYLLABLE HXOP;Lo;0;L;;;;;N;;;;;
+A25A;YI SYLLABLE HXEX;Lo;0;L;;;;;N;;;;;
+A25B;YI SYLLABLE HXE;Lo;0;L;;;;;N;;;;;
+A25C;YI SYLLABLE HXEP;Lo;0;L;;;;;N;;;;;
+A25D;YI SYLLABLE NGIEX;Lo;0;L;;;;;N;;;;;
+A25E;YI SYLLABLE NGIE;Lo;0;L;;;;;N;;;;;
+A25F;YI SYLLABLE NGIEP;Lo;0;L;;;;;N;;;;;
+A260;YI SYLLABLE NGAT;Lo;0;L;;;;;N;;;;;
+A261;YI SYLLABLE NGAX;Lo;0;L;;;;;N;;;;;
+A262;YI SYLLABLE NGA;Lo;0;L;;;;;N;;;;;
+A263;YI SYLLABLE NGAP;Lo;0;L;;;;;N;;;;;
+A264;YI SYLLABLE NGUOT;Lo;0;L;;;;;N;;;;;
+A265;YI SYLLABLE NGUOX;Lo;0;L;;;;;N;;;;;
+A266;YI SYLLABLE NGUO;Lo;0;L;;;;;N;;;;;
+A267;YI SYLLABLE NGOT;Lo;0;L;;;;;N;;;;;
+A268;YI SYLLABLE NGOX;Lo;0;L;;;;;N;;;;;
+A269;YI SYLLABLE NGO;Lo;0;L;;;;;N;;;;;
+A26A;YI SYLLABLE NGOP;Lo;0;L;;;;;N;;;;;
+A26B;YI SYLLABLE NGEX;Lo;0;L;;;;;N;;;;;
+A26C;YI SYLLABLE NGE;Lo;0;L;;;;;N;;;;;
+A26D;YI SYLLABLE NGEP;Lo;0;L;;;;;N;;;;;
+A26E;YI SYLLABLE HIT;Lo;0;L;;;;;N;;;;;
+A26F;YI SYLLABLE HIEX;Lo;0;L;;;;;N;;;;;
+A270;YI SYLLABLE HIE;Lo;0;L;;;;;N;;;;;
+A271;YI SYLLABLE HAT;Lo;0;L;;;;;N;;;;;
+A272;YI SYLLABLE HAX;Lo;0;L;;;;;N;;;;;
+A273;YI SYLLABLE HA;Lo;0;L;;;;;N;;;;;
+A274;YI SYLLABLE HAP;Lo;0;L;;;;;N;;;;;
+A275;YI SYLLABLE HUOT;Lo;0;L;;;;;N;;;;;
+A276;YI SYLLABLE HUOX;Lo;0;L;;;;;N;;;;;
+A277;YI SYLLABLE HUO;Lo;0;L;;;;;N;;;;;
+A278;YI SYLLABLE HUOP;Lo;0;L;;;;;N;;;;;
+A279;YI SYLLABLE HOT;Lo;0;L;;;;;N;;;;;
+A27A;YI SYLLABLE HOX;Lo;0;L;;;;;N;;;;;
+A27B;YI SYLLABLE HO;Lo;0;L;;;;;N;;;;;
+A27C;YI SYLLABLE HOP;Lo;0;L;;;;;N;;;;;
+A27D;YI SYLLABLE HEX;Lo;0;L;;;;;N;;;;;
+A27E;YI SYLLABLE HE;Lo;0;L;;;;;N;;;;;
+A27F;YI SYLLABLE HEP;Lo;0;L;;;;;N;;;;;
+A280;YI SYLLABLE WAT;Lo;0;L;;;;;N;;;;;
+A281;YI SYLLABLE WAX;Lo;0;L;;;;;N;;;;;
+A282;YI SYLLABLE WA;Lo;0;L;;;;;N;;;;;
+A283;YI SYLLABLE WAP;Lo;0;L;;;;;N;;;;;
+A284;YI SYLLABLE WUOX;Lo;0;L;;;;;N;;;;;
+A285;YI SYLLABLE WUO;Lo;0;L;;;;;N;;;;;
+A286;YI SYLLABLE WUOP;Lo;0;L;;;;;N;;;;;
+A287;YI SYLLABLE WOX;Lo;0;L;;;;;N;;;;;
+A288;YI SYLLABLE WO;Lo;0;L;;;;;N;;;;;
+A289;YI SYLLABLE WOP;Lo;0;L;;;;;N;;;;;
+A28A;YI SYLLABLE WEX;Lo;0;L;;;;;N;;;;;
+A28B;YI SYLLABLE WE;Lo;0;L;;;;;N;;;;;
+A28C;YI SYLLABLE WEP;Lo;0;L;;;;;N;;;;;
+A28D;YI SYLLABLE ZIT;Lo;0;L;;;;;N;;;;;
+A28E;YI SYLLABLE ZIX;Lo;0;L;;;;;N;;;;;
+A28F;YI SYLLABLE ZI;Lo;0;L;;;;;N;;;;;
+A290;YI SYLLABLE ZIP;Lo;0;L;;;;;N;;;;;
+A291;YI SYLLABLE ZIEX;Lo;0;L;;;;;N;;;;;
+A292;YI SYLLABLE ZIE;Lo;0;L;;;;;N;;;;;
+A293;YI SYLLABLE ZIEP;Lo;0;L;;;;;N;;;;;
+A294;YI SYLLABLE ZAT;Lo;0;L;;;;;N;;;;;
+A295;YI SYLLABLE ZAX;Lo;0;L;;;;;N;;;;;
+A296;YI SYLLABLE ZA;Lo;0;L;;;;;N;;;;;
+A297;YI SYLLABLE ZAP;Lo;0;L;;;;;N;;;;;
+A298;YI SYLLABLE ZUOX;Lo;0;L;;;;;N;;;;;
+A299;YI SYLLABLE ZUO;Lo;0;L;;;;;N;;;;;
+A29A;YI SYLLABLE ZUOP;Lo;0;L;;;;;N;;;;;
+A29B;YI SYLLABLE ZOT;Lo;0;L;;;;;N;;;;;
+A29C;YI SYLLABLE ZOX;Lo;0;L;;;;;N;;;;;
+A29D;YI SYLLABLE ZO;Lo;0;L;;;;;N;;;;;
+A29E;YI SYLLABLE ZOP;Lo;0;L;;;;;N;;;;;
+A29F;YI SYLLABLE ZEX;Lo;0;L;;;;;N;;;;;
+A2A0;YI SYLLABLE ZE;Lo;0;L;;;;;N;;;;;
+A2A1;YI SYLLABLE ZEP;Lo;0;L;;;;;N;;;;;
+A2A2;YI SYLLABLE ZUT;Lo;0;L;;;;;N;;;;;
+A2A3;YI SYLLABLE ZUX;Lo;0;L;;;;;N;;;;;
+A2A4;YI SYLLABLE ZU;Lo;0;L;;;;;N;;;;;
+A2A5;YI SYLLABLE ZUP;Lo;0;L;;;;;N;;;;;
+A2A6;YI SYLLABLE ZURX;Lo;0;L;;;;;N;;;;;
+A2A7;YI SYLLABLE ZUR;Lo;0;L;;;;;N;;;;;
+A2A8;YI SYLLABLE ZYT;Lo;0;L;;;;;N;;;;;
+A2A9;YI SYLLABLE ZYX;Lo;0;L;;;;;N;;;;;
+A2AA;YI SYLLABLE ZY;Lo;0;L;;;;;N;;;;;
+A2AB;YI SYLLABLE ZYP;Lo;0;L;;;;;N;;;;;
+A2AC;YI SYLLABLE ZYRX;Lo;0;L;;;;;N;;;;;
+A2AD;YI SYLLABLE ZYR;Lo;0;L;;;;;N;;;;;
+A2AE;YI SYLLABLE CIT;Lo;0;L;;;;;N;;;;;
+A2AF;YI SYLLABLE CIX;Lo;0;L;;;;;N;;;;;
+A2B0;YI SYLLABLE CI;Lo;0;L;;;;;N;;;;;
+A2B1;YI SYLLABLE CIP;Lo;0;L;;;;;N;;;;;
+A2B2;YI SYLLABLE CIET;Lo;0;L;;;;;N;;;;;
+A2B3;YI SYLLABLE CIEX;Lo;0;L;;;;;N;;;;;
+A2B4;YI SYLLABLE CIE;Lo;0;L;;;;;N;;;;;
+A2B5;YI SYLLABLE CIEP;Lo;0;L;;;;;N;;;;;
+A2B6;YI SYLLABLE CAT;Lo;0;L;;;;;N;;;;;
+A2B7;YI SYLLABLE CAX;Lo;0;L;;;;;N;;;;;
+A2B8;YI SYLLABLE CA;Lo;0;L;;;;;N;;;;;
+A2B9;YI SYLLABLE CAP;Lo;0;L;;;;;N;;;;;
+A2BA;YI SYLLABLE CUOX;Lo;0;L;;;;;N;;;;;
+A2BB;YI SYLLABLE CUO;Lo;0;L;;;;;N;;;;;
+A2BC;YI SYLLABLE CUOP;Lo;0;L;;;;;N;;;;;
+A2BD;YI SYLLABLE COT;Lo;0;L;;;;;N;;;;;
+A2BE;YI SYLLABLE COX;Lo;0;L;;;;;N;;;;;
+A2BF;YI SYLLABLE CO;Lo;0;L;;;;;N;;;;;
+A2C0;YI SYLLABLE COP;Lo;0;L;;;;;N;;;;;
+A2C1;YI SYLLABLE CEX;Lo;0;L;;;;;N;;;;;
+A2C2;YI SYLLABLE CE;Lo;0;L;;;;;N;;;;;
+A2C3;YI SYLLABLE CEP;Lo;0;L;;;;;N;;;;;
+A2C4;YI SYLLABLE CUT;Lo;0;L;;;;;N;;;;;
+A2C5;YI SYLLABLE CUX;Lo;0;L;;;;;N;;;;;
+A2C6;YI SYLLABLE CU;Lo;0;L;;;;;N;;;;;
+A2C7;YI SYLLABLE CUP;Lo;0;L;;;;;N;;;;;
+A2C8;YI SYLLABLE CURX;Lo;0;L;;;;;N;;;;;
+A2C9;YI SYLLABLE CUR;Lo;0;L;;;;;N;;;;;
+A2CA;YI SYLLABLE CYT;Lo;0;L;;;;;N;;;;;
+A2CB;YI SYLLABLE CYX;Lo;0;L;;;;;N;;;;;
+A2CC;YI SYLLABLE CY;Lo;0;L;;;;;N;;;;;
+A2CD;YI SYLLABLE CYP;Lo;0;L;;;;;N;;;;;
+A2CE;YI SYLLABLE CYRX;Lo;0;L;;;;;N;;;;;
+A2CF;YI SYLLABLE CYR;Lo;0;L;;;;;N;;;;;
+A2D0;YI SYLLABLE ZZIT;Lo;0;L;;;;;N;;;;;
+A2D1;YI SYLLABLE ZZIX;Lo;0;L;;;;;N;;;;;
+A2D2;YI SYLLABLE ZZI;Lo;0;L;;;;;N;;;;;
+A2D3;YI SYLLABLE ZZIP;Lo;0;L;;;;;N;;;;;
+A2D4;YI SYLLABLE ZZIET;Lo;0;L;;;;;N;;;;;
+A2D5;YI SYLLABLE ZZIEX;Lo;0;L;;;;;N;;;;;
+A2D6;YI SYLLABLE ZZIE;Lo;0;L;;;;;N;;;;;
+A2D7;YI SYLLABLE ZZIEP;Lo;0;L;;;;;N;;;;;
+A2D8;YI SYLLABLE ZZAT;Lo;0;L;;;;;N;;;;;
+A2D9;YI SYLLABLE ZZAX;Lo;0;L;;;;;N;;;;;
+A2DA;YI SYLLABLE ZZA;Lo;0;L;;;;;N;;;;;
+A2DB;YI SYLLABLE ZZAP;Lo;0;L;;;;;N;;;;;
+A2DC;YI SYLLABLE ZZOX;Lo;0;L;;;;;N;;;;;
+A2DD;YI SYLLABLE ZZO;Lo;0;L;;;;;N;;;;;
+A2DE;YI SYLLABLE ZZOP;Lo;0;L;;;;;N;;;;;
+A2DF;YI SYLLABLE ZZEX;Lo;0;L;;;;;N;;;;;
+A2E0;YI SYLLABLE ZZE;Lo;0;L;;;;;N;;;;;
+A2E1;YI SYLLABLE ZZEP;Lo;0;L;;;;;N;;;;;
+A2E2;YI SYLLABLE ZZUX;Lo;0;L;;;;;N;;;;;
+A2E3;YI SYLLABLE ZZU;Lo;0;L;;;;;N;;;;;
+A2E4;YI SYLLABLE ZZUP;Lo;0;L;;;;;N;;;;;
+A2E5;YI SYLLABLE ZZURX;Lo;0;L;;;;;N;;;;;
+A2E6;YI SYLLABLE ZZUR;Lo;0;L;;;;;N;;;;;
+A2E7;YI SYLLABLE ZZYT;Lo;0;L;;;;;N;;;;;
+A2E8;YI SYLLABLE ZZYX;Lo;0;L;;;;;N;;;;;
+A2E9;YI SYLLABLE ZZY;Lo;0;L;;;;;N;;;;;
+A2EA;YI SYLLABLE ZZYP;Lo;0;L;;;;;N;;;;;
+A2EB;YI SYLLABLE ZZYRX;Lo;0;L;;;;;N;;;;;
+A2EC;YI SYLLABLE ZZYR;Lo;0;L;;;;;N;;;;;
+A2ED;YI SYLLABLE NZIT;Lo;0;L;;;;;N;;;;;
+A2EE;YI SYLLABLE NZIX;Lo;0;L;;;;;N;;;;;
+A2EF;YI SYLLABLE NZI;Lo;0;L;;;;;N;;;;;
+A2F0;YI SYLLABLE NZIP;Lo;0;L;;;;;N;;;;;
+A2F1;YI SYLLABLE NZIEX;Lo;0;L;;;;;N;;;;;
+A2F2;YI SYLLABLE NZIE;Lo;0;L;;;;;N;;;;;
+A2F3;YI SYLLABLE NZIEP;Lo;0;L;;;;;N;;;;;
+A2F4;YI SYLLABLE NZAT;Lo;0;L;;;;;N;;;;;
+A2F5;YI SYLLABLE NZAX;Lo;0;L;;;;;N;;;;;
+A2F6;YI SYLLABLE NZA;Lo;0;L;;;;;N;;;;;
+A2F7;YI SYLLABLE NZAP;Lo;0;L;;;;;N;;;;;
+A2F8;YI SYLLABLE NZUOX;Lo;0;L;;;;;N;;;;;
+A2F9;YI SYLLABLE NZUO;Lo;0;L;;;;;N;;;;;
+A2FA;YI SYLLABLE NZOX;Lo;0;L;;;;;N;;;;;
+A2FB;YI SYLLABLE NZOP;Lo;0;L;;;;;N;;;;;
+A2FC;YI SYLLABLE NZEX;Lo;0;L;;;;;N;;;;;
+A2FD;YI SYLLABLE NZE;Lo;0;L;;;;;N;;;;;
+A2FE;YI SYLLABLE NZUX;Lo;0;L;;;;;N;;;;;
+A2FF;YI SYLLABLE NZU;Lo;0;L;;;;;N;;;;;
+A300;YI SYLLABLE NZUP;Lo;0;L;;;;;N;;;;;
+A301;YI SYLLABLE NZURX;Lo;0;L;;;;;N;;;;;
+A302;YI SYLLABLE NZUR;Lo;0;L;;;;;N;;;;;
+A303;YI SYLLABLE NZYT;Lo;0;L;;;;;N;;;;;
+A304;YI SYLLABLE NZYX;Lo;0;L;;;;;N;;;;;
+A305;YI SYLLABLE NZY;Lo;0;L;;;;;N;;;;;
+A306;YI SYLLABLE NZYP;Lo;0;L;;;;;N;;;;;
+A307;YI SYLLABLE NZYRX;Lo;0;L;;;;;N;;;;;
+A308;YI SYLLABLE NZYR;Lo;0;L;;;;;N;;;;;
+A309;YI SYLLABLE SIT;Lo;0;L;;;;;N;;;;;
+A30A;YI SYLLABLE SIX;Lo;0;L;;;;;N;;;;;
+A30B;YI SYLLABLE SI;Lo;0;L;;;;;N;;;;;
+A30C;YI SYLLABLE SIP;Lo;0;L;;;;;N;;;;;
+A30D;YI SYLLABLE SIEX;Lo;0;L;;;;;N;;;;;
+A30E;YI SYLLABLE SIE;Lo;0;L;;;;;N;;;;;
+A30F;YI SYLLABLE SIEP;Lo;0;L;;;;;N;;;;;
+A310;YI SYLLABLE SAT;Lo;0;L;;;;;N;;;;;
+A311;YI SYLLABLE SAX;Lo;0;L;;;;;N;;;;;
+A312;YI SYLLABLE SA;Lo;0;L;;;;;N;;;;;
+A313;YI SYLLABLE SAP;Lo;0;L;;;;;N;;;;;
+A314;YI SYLLABLE SUOX;Lo;0;L;;;;;N;;;;;
+A315;YI SYLLABLE SUO;Lo;0;L;;;;;N;;;;;
+A316;YI SYLLABLE SUOP;Lo;0;L;;;;;N;;;;;
+A317;YI SYLLABLE SOT;Lo;0;L;;;;;N;;;;;
+A318;YI SYLLABLE SOX;Lo;0;L;;;;;N;;;;;
+A319;YI SYLLABLE SO;Lo;0;L;;;;;N;;;;;
+A31A;YI SYLLABLE SOP;Lo;0;L;;;;;N;;;;;
+A31B;YI SYLLABLE SEX;Lo;0;L;;;;;N;;;;;
+A31C;YI SYLLABLE SE;Lo;0;L;;;;;N;;;;;
+A31D;YI SYLLABLE SEP;Lo;0;L;;;;;N;;;;;
+A31E;YI SYLLABLE SUT;Lo;0;L;;;;;N;;;;;
+A31F;YI SYLLABLE SUX;Lo;0;L;;;;;N;;;;;
+A320;YI SYLLABLE SU;Lo;0;L;;;;;N;;;;;
+A321;YI SYLLABLE SUP;Lo;0;L;;;;;N;;;;;
+A322;YI SYLLABLE SURX;Lo;0;L;;;;;N;;;;;
+A323;YI SYLLABLE SUR;Lo;0;L;;;;;N;;;;;
+A324;YI SYLLABLE SYT;Lo;0;L;;;;;N;;;;;
+A325;YI SYLLABLE SYX;Lo;0;L;;;;;N;;;;;
+A326;YI SYLLABLE SY;Lo;0;L;;;;;N;;;;;
+A327;YI SYLLABLE SYP;Lo;0;L;;;;;N;;;;;
+A328;YI SYLLABLE SYRX;Lo;0;L;;;;;N;;;;;
+A329;YI SYLLABLE SYR;Lo;0;L;;;;;N;;;;;
+A32A;YI SYLLABLE SSIT;Lo;0;L;;;;;N;;;;;
+A32B;YI SYLLABLE SSIX;Lo;0;L;;;;;N;;;;;
+A32C;YI SYLLABLE SSI;Lo;0;L;;;;;N;;;;;
+A32D;YI SYLLABLE SSIP;Lo;0;L;;;;;N;;;;;
+A32E;YI SYLLABLE SSIEX;Lo;0;L;;;;;N;;;;;
+A32F;YI SYLLABLE SSIE;Lo;0;L;;;;;N;;;;;
+A330;YI SYLLABLE SSIEP;Lo;0;L;;;;;N;;;;;
+A331;YI SYLLABLE SSAT;Lo;0;L;;;;;N;;;;;
+A332;YI SYLLABLE SSAX;Lo;0;L;;;;;N;;;;;
+A333;YI SYLLABLE SSA;Lo;0;L;;;;;N;;;;;
+A334;YI SYLLABLE SSAP;Lo;0;L;;;;;N;;;;;
+A335;YI SYLLABLE SSOT;Lo;0;L;;;;;N;;;;;
+A336;YI SYLLABLE SSOX;Lo;0;L;;;;;N;;;;;
+A337;YI SYLLABLE SSO;Lo;0;L;;;;;N;;;;;
+A338;YI SYLLABLE SSOP;Lo;0;L;;;;;N;;;;;
+A339;YI SYLLABLE SSEX;Lo;0;L;;;;;N;;;;;
+A33A;YI SYLLABLE SSE;Lo;0;L;;;;;N;;;;;
+A33B;YI SYLLABLE SSEP;Lo;0;L;;;;;N;;;;;
+A33C;YI SYLLABLE SSUT;Lo;0;L;;;;;N;;;;;
+A33D;YI SYLLABLE SSUX;Lo;0;L;;;;;N;;;;;
+A33E;YI SYLLABLE SSU;Lo;0;L;;;;;N;;;;;
+A33F;YI SYLLABLE SSUP;Lo;0;L;;;;;N;;;;;
+A340;YI SYLLABLE SSYT;Lo;0;L;;;;;N;;;;;
+A341;YI SYLLABLE SSYX;Lo;0;L;;;;;N;;;;;
+A342;YI SYLLABLE SSY;Lo;0;L;;;;;N;;;;;
+A343;YI SYLLABLE SSYP;Lo;0;L;;;;;N;;;;;
+A344;YI SYLLABLE SSYRX;Lo;0;L;;;;;N;;;;;
+A345;YI SYLLABLE SSYR;Lo;0;L;;;;;N;;;;;
+A346;YI SYLLABLE ZHAT;Lo;0;L;;;;;N;;;;;
+A347;YI SYLLABLE ZHAX;Lo;0;L;;;;;N;;;;;
+A348;YI SYLLABLE ZHA;Lo;0;L;;;;;N;;;;;
+A349;YI SYLLABLE ZHAP;Lo;0;L;;;;;N;;;;;
+A34A;YI SYLLABLE ZHUOX;Lo;0;L;;;;;N;;;;;
+A34B;YI SYLLABLE ZHUO;Lo;0;L;;;;;N;;;;;
+A34C;YI SYLLABLE ZHUOP;Lo;0;L;;;;;N;;;;;
+A34D;YI SYLLABLE ZHOT;Lo;0;L;;;;;N;;;;;
+A34E;YI SYLLABLE ZHOX;Lo;0;L;;;;;N;;;;;
+A34F;YI SYLLABLE ZHO;Lo;0;L;;;;;N;;;;;
+A350;YI SYLLABLE ZHOP;Lo;0;L;;;;;N;;;;;
+A351;YI SYLLABLE ZHET;Lo;0;L;;;;;N;;;;;
+A352;YI SYLLABLE ZHEX;Lo;0;L;;;;;N;;;;;
+A353;YI SYLLABLE ZHE;Lo;0;L;;;;;N;;;;;
+A354;YI SYLLABLE ZHEP;Lo;0;L;;;;;N;;;;;
+A355;YI SYLLABLE ZHUT;Lo;0;L;;;;;N;;;;;
+A356;YI SYLLABLE ZHUX;Lo;0;L;;;;;N;;;;;
+A357;YI SYLLABLE ZHU;Lo;0;L;;;;;N;;;;;
+A358;YI SYLLABLE ZHUP;Lo;0;L;;;;;N;;;;;
+A359;YI SYLLABLE ZHURX;Lo;0;L;;;;;N;;;;;
+A35A;YI SYLLABLE ZHUR;Lo;0;L;;;;;N;;;;;
+A35B;YI SYLLABLE ZHYT;Lo;0;L;;;;;N;;;;;
+A35C;YI SYLLABLE ZHYX;Lo;0;L;;;;;N;;;;;
+A35D;YI SYLLABLE ZHY;Lo;0;L;;;;;N;;;;;
+A35E;YI SYLLABLE ZHYP;Lo;0;L;;;;;N;;;;;
+A35F;YI SYLLABLE ZHYRX;Lo;0;L;;;;;N;;;;;
+A360;YI SYLLABLE ZHYR;Lo;0;L;;;;;N;;;;;
+A361;YI SYLLABLE CHAT;Lo;0;L;;;;;N;;;;;
+A362;YI SYLLABLE CHAX;Lo;0;L;;;;;N;;;;;
+A363;YI SYLLABLE CHA;Lo;0;L;;;;;N;;;;;
+A364;YI SYLLABLE CHAP;Lo;0;L;;;;;N;;;;;
+A365;YI SYLLABLE CHUOT;Lo;0;L;;;;;N;;;;;
+A366;YI SYLLABLE CHUOX;Lo;0;L;;;;;N;;;;;
+A367;YI SYLLABLE CHUO;Lo;0;L;;;;;N;;;;;
+A368;YI SYLLABLE CHUOP;Lo;0;L;;;;;N;;;;;
+A369;YI SYLLABLE CHOT;Lo;0;L;;;;;N;;;;;
+A36A;YI SYLLABLE CHOX;Lo;0;L;;;;;N;;;;;
+A36B;YI SYLLABLE CHO;Lo;0;L;;;;;N;;;;;
+A36C;YI SYLLABLE CHOP;Lo;0;L;;;;;N;;;;;
+A36D;YI SYLLABLE CHET;Lo;0;L;;;;;N;;;;;
+A36E;YI SYLLABLE CHEX;Lo;0;L;;;;;N;;;;;
+A36F;YI SYLLABLE CHE;Lo;0;L;;;;;N;;;;;
+A370;YI SYLLABLE CHEP;Lo;0;L;;;;;N;;;;;
+A371;YI SYLLABLE CHUX;Lo;0;L;;;;;N;;;;;
+A372;YI SYLLABLE CHU;Lo;0;L;;;;;N;;;;;
+A373;YI SYLLABLE CHUP;Lo;0;L;;;;;N;;;;;
+A374;YI SYLLABLE CHURX;Lo;0;L;;;;;N;;;;;
+A375;YI SYLLABLE CHUR;Lo;0;L;;;;;N;;;;;
+A376;YI SYLLABLE CHYT;Lo;0;L;;;;;N;;;;;
+A377;YI SYLLABLE CHYX;Lo;0;L;;;;;N;;;;;
+A378;YI SYLLABLE CHY;Lo;0;L;;;;;N;;;;;
+A379;YI SYLLABLE CHYP;Lo;0;L;;;;;N;;;;;
+A37A;YI SYLLABLE CHYRX;Lo;0;L;;;;;N;;;;;
+A37B;YI SYLLABLE CHYR;Lo;0;L;;;;;N;;;;;
+A37C;YI SYLLABLE RRAX;Lo;0;L;;;;;N;;;;;
+A37D;YI SYLLABLE RRA;Lo;0;L;;;;;N;;;;;
+A37E;YI SYLLABLE RRUOX;Lo;0;L;;;;;N;;;;;
+A37F;YI SYLLABLE RRUO;Lo;0;L;;;;;N;;;;;
+A380;YI SYLLABLE RROT;Lo;0;L;;;;;N;;;;;
+A381;YI SYLLABLE RROX;Lo;0;L;;;;;N;;;;;
+A382;YI SYLLABLE RRO;Lo;0;L;;;;;N;;;;;
+A383;YI SYLLABLE RROP;Lo;0;L;;;;;N;;;;;
+A384;YI SYLLABLE RRET;Lo;0;L;;;;;N;;;;;
+A385;YI SYLLABLE RREX;Lo;0;L;;;;;N;;;;;
+A386;YI SYLLABLE RRE;Lo;0;L;;;;;N;;;;;
+A387;YI SYLLABLE RREP;Lo;0;L;;;;;N;;;;;
+A388;YI SYLLABLE RRUT;Lo;0;L;;;;;N;;;;;
+A389;YI SYLLABLE RRUX;Lo;0;L;;;;;N;;;;;
+A38A;YI SYLLABLE RRU;Lo;0;L;;;;;N;;;;;
+A38B;YI SYLLABLE RRUP;Lo;0;L;;;;;N;;;;;
+A38C;YI SYLLABLE RRURX;Lo;0;L;;;;;N;;;;;
+A38D;YI SYLLABLE RRUR;Lo;0;L;;;;;N;;;;;
+A38E;YI SYLLABLE RRYT;Lo;0;L;;;;;N;;;;;
+A38F;YI SYLLABLE RRYX;Lo;0;L;;;;;N;;;;;
+A390;YI SYLLABLE RRY;Lo;0;L;;;;;N;;;;;
+A391;YI SYLLABLE RRYP;Lo;0;L;;;;;N;;;;;
+A392;YI SYLLABLE RRYRX;Lo;0;L;;;;;N;;;;;
+A393;YI SYLLABLE RRYR;Lo;0;L;;;;;N;;;;;
+A394;YI SYLLABLE NRAT;Lo;0;L;;;;;N;;;;;
+A395;YI SYLLABLE NRAX;Lo;0;L;;;;;N;;;;;
+A396;YI SYLLABLE NRA;Lo;0;L;;;;;N;;;;;
+A397;YI SYLLABLE NRAP;Lo;0;L;;;;;N;;;;;
+A398;YI SYLLABLE NROX;Lo;0;L;;;;;N;;;;;
+A399;YI SYLLABLE NRO;Lo;0;L;;;;;N;;;;;
+A39A;YI SYLLABLE NROP;Lo;0;L;;;;;N;;;;;
+A39B;YI SYLLABLE NRET;Lo;0;L;;;;;N;;;;;
+A39C;YI SYLLABLE NREX;Lo;0;L;;;;;N;;;;;
+A39D;YI SYLLABLE NRE;Lo;0;L;;;;;N;;;;;
+A39E;YI SYLLABLE NREP;Lo;0;L;;;;;N;;;;;
+A39F;YI SYLLABLE NRUT;Lo;0;L;;;;;N;;;;;
+A3A0;YI SYLLABLE NRUX;Lo;0;L;;;;;N;;;;;
+A3A1;YI SYLLABLE NRU;Lo;0;L;;;;;N;;;;;
+A3A2;YI SYLLABLE NRUP;Lo;0;L;;;;;N;;;;;
+A3A3;YI SYLLABLE NRURX;Lo;0;L;;;;;N;;;;;
+A3A4;YI SYLLABLE NRUR;Lo;0;L;;;;;N;;;;;
+A3A5;YI SYLLABLE NRYT;Lo;0;L;;;;;N;;;;;
+A3A6;YI SYLLABLE NRYX;Lo;0;L;;;;;N;;;;;
+A3A7;YI SYLLABLE NRY;Lo;0;L;;;;;N;;;;;
+A3A8;YI SYLLABLE NRYP;Lo;0;L;;;;;N;;;;;
+A3A9;YI SYLLABLE NRYRX;Lo;0;L;;;;;N;;;;;
+A3AA;YI SYLLABLE NRYR;Lo;0;L;;;;;N;;;;;
+A3AB;YI SYLLABLE SHAT;Lo;0;L;;;;;N;;;;;
+A3AC;YI SYLLABLE SHAX;Lo;0;L;;;;;N;;;;;
+A3AD;YI SYLLABLE SHA;Lo;0;L;;;;;N;;;;;
+A3AE;YI SYLLABLE SHAP;Lo;0;L;;;;;N;;;;;
+A3AF;YI SYLLABLE SHUOX;Lo;0;L;;;;;N;;;;;
+A3B0;YI SYLLABLE SHUO;Lo;0;L;;;;;N;;;;;
+A3B1;YI SYLLABLE SHUOP;Lo;0;L;;;;;N;;;;;
+A3B2;YI SYLLABLE SHOT;Lo;0;L;;;;;N;;;;;
+A3B3;YI SYLLABLE SHOX;Lo;0;L;;;;;N;;;;;
+A3B4;YI SYLLABLE SHO;Lo;0;L;;;;;N;;;;;
+A3B5;YI SYLLABLE SHOP;Lo;0;L;;;;;N;;;;;
+A3B6;YI SYLLABLE SHET;Lo;0;L;;;;;N;;;;;
+A3B7;YI SYLLABLE SHEX;Lo;0;L;;;;;N;;;;;
+A3B8;YI SYLLABLE SHE;Lo;0;L;;;;;N;;;;;
+A3B9;YI SYLLABLE SHEP;Lo;0;L;;;;;N;;;;;
+A3BA;YI SYLLABLE SHUT;Lo;0;L;;;;;N;;;;;
+A3BB;YI SYLLABLE SHUX;Lo;0;L;;;;;N;;;;;
+A3BC;YI SYLLABLE SHU;Lo;0;L;;;;;N;;;;;
+A3BD;YI SYLLABLE SHUP;Lo;0;L;;;;;N;;;;;
+A3BE;YI SYLLABLE SHURX;Lo;0;L;;;;;N;;;;;
+A3BF;YI SYLLABLE SHUR;Lo;0;L;;;;;N;;;;;
+A3C0;YI SYLLABLE SHYT;Lo;0;L;;;;;N;;;;;
+A3C1;YI SYLLABLE SHYX;Lo;0;L;;;;;N;;;;;
+A3C2;YI SYLLABLE SHY;Lo;0;L;;;;;N;;;;;
+A3C3;YI SYLLABLE SHYP;Lo;0;L;;;;;N;;;;;
+A3C4;YI SYLLABLE SHYRX;Lo;0;L;;;;;N;;;;;
+A3C5;YI SYLLABLE SHYR;Lo;0;L;;;;;N;;;;;
+A3C6;YI SYLLABLE RAT;Lo;0;L;;;;;N;;;;;
+A3C7;YI SYLLABLE RAX;Lo;0;L;;;;;N;;;;;
+A3C8;YI SYLLABLE RA;Lo;0;L;;;;;N;;;;;
+A3C9;YI SYLLABLE RAP;Lo;0;L;;;;;N;;;;;
+A3CA;YI SYLLABLE RUOX;Lo;0;L;;;;;N;;;;;
+A3CB;YI SYLLABLE RUO;Lo;0;L;;;;;N;;;;;
+A3CC;YI SYLLABLE RUOP;Lo;0;L;;;;;N;;;;;
+A3CD;YI SYLLABLE ROT;Lo;0;L;;;;;N;;;;;
+A3CE;YI SYLLABLE ROX;Lo;0;L;;;;;N;;;;;
+A3CF;YI SYLLABLE RO;Lo;0;L;;;;;N;;;;;
+A3D0;YI SYLLABLE ROP;Lo;0;L;;;;;N;;;;;
+A3D1;YI SYLLABLE REX;Lo;0;L;;;;;N;;;;;
+A3D2;YI SYLLABLE RE;Lo;0;L;;;;;N;;;;;
+A3D3;YI SYLLABLE REP;Lo;0;L;;;;;N;;;;;
+A3D4;YI SYLLABLE RUT;Lo;0;L;;;;;N;;;;;
+A3D5;YI SYLLABLE RUX;Lo;0;L;;;;;N;;;;;
+A3D6;YI SYLLABLE RU;Lo;0;L;;;;;N;;;;;
+A3D7;YI SYLLABLE RUP;Lo;0;L;;;;;N;;;;;
+A3D8;YI SYLLABLE RURX;Lo;0;L;;;;;N;;;;;
+A3D9;YI SYLLABLE RUR;Lo;0;L;;;;;N;;;;;
+A3DA;YI SYLLABLE RYT;Lo;0;L;;;;;N;;;;;
+A3DB;YI SYLLABLE RYX;Lo;0;L;;;;;N;;;;;
+A3DC;YI SYLLABLE RY;Lo;0;L;;;;;N;;;;;
+A3DD;YI SYLLABLE RYP;Lo;0;L;;;;;N;;;;;
+A3DE;YI SYLLABLE RYRX;Lo;0;L;;;;;N;;;;;
+A3DF;YI SYLLABLE RYR;Lo;0;L;;;;;N;;;;;
+A3E0;YI SYLLABLE JIT;Lo;0;L;;;;;N;;;;;
+A3E1;YI SYLLABLE JIX;Lo;0;L;;;;;N;;;;;
+A3E2;YI SYLLABLE JI;Lo;0;L;;;;;N;;;;;
+A3E3;YI SYLLABLE JIP;Lo;0;L;;;;;N;;;;;
+A3E4;YI SYLLABLE JIET;Lo;0;L;;;;;N;;;;;
+A3E5;YI SYLLABLE JIEX;Lo;0;L;;;;;N;;;;;
+A3E6;YI SYLLABLE JIE;Lo;0;L;;;;;N;;;;;
+A3E7;YI SYLLABLE JIEP;Lo;0;L;;;;;N;;;;;
+A3E8;YI SYLLABLE JUOT;Lo;0;L;;;;;N;;;;;
+A3E9;YI SYLLABLE JUOX;Lo;0;L;;;;;N;;;;;
+A3EA;YI SYLLABLE JUO;Lo;0;L;;;;;N;;;;;
+A3EB;YI SYLLABLE JUOP;Lo;0;L;;;;;N;;;;;
+A3EC;YI SYLLABLE JOT;Lo;0;L;;;;;N;;;;;
+A3ED;YI SYLLABLE JOX;Lo;0;L;;;;;N;;;;;
+A3EE;YI SYLLABLE JO;Lo;0;L;;;;;N;;;;;
+A3EF;YI SYLLABLE JOP;Lo;0;L;;;;;N;;;;;
+A3F0;YI SYLLABLE JUT;Lo;0;L;;;;;N;;;;;
+A3F1;YI SYLLABLE JUX;Lo;0;L;;;;;N;;;;;
+A3F2;YI SYLLABLE JU;Lo;0;L;;;;;N;;;;;
+A3F3;YI SYLLABLE JUP;Lo;0;L;;;;;N;;;;;
+A3F4;YI SYLLABLE JURX;Lo;0;L;;;;;N;;;;;
+A3F5;YI SYLLABLE JUR;Lo;0;L;;;;;N;;;;;
+A3F6;YI SYLLABLE JYT;Lo;0;L;;;;;N;;;;;
+A3F7;YI SYLLABLE JYX;Lo;0;L;;;;;N;;;;;
+A3F8;YI SYLLABLE JY;Lo;0;L;;;;;N;;;;;
+A3F9;YI SYLLABLE JYP;Lo;0;L;;;;;N;;;;;
+A3FA;YI SYLLABLE JYRX;Lo;0;L;;;;;N;;;;;
+A3FB;YI SYLLABLE JYR;Lo;0;L;;;;;N;;;;;
+A3FC;YI SYLLABLE QIT;Lo;0;L;;;;;N;;;;;
+A3FD;YI SYLLABLE QIX;Lo;0;L;;;;;N;;;;;
+A3FE;YI SYLLABLE QI;Lo;0;L;;;;;N;;;;;
+A3FF;YI SYLLABLE QIP;Lo;0;L;;;;;N;;;;;
+A400;YI SYLLABLE QIET;Lo;0;L;;;;;N;;;;;
+A401;YI SYLLABLE QIEX;Lo;0;L;;;;;N;;;;;
+A402;YI SYLLABLE QIE;Lo;0;L;;;;;N;;;;;
+A403;YI SYLLABLE QIEP;Lo;0;L;;;;;N;;;;;
+A404;YI SYLLABLE QUOT;Lo;0;L;;;;;N;;;;;
+A405;YI SYLLABLE QUOX;Lo;0;L;;;;;N;;;;;
+A406;YI SYLLABLE QUO;Lo;0;L;;;;;N;;;;;
+A407;YI SYLLABLE QUOP;Lo;0;L;;;;;N;;;;;
+A408;YI SYLLABLE QOT;Lo;0;L;;;;;N;;;;;
+A409;YI SYLLABLE QOX;Lo;0;L;;;;;N;;;;;
+A40A;YI SYLLABLE QO;Lo;0;L;;;;;N;;;;;
+A40B;YI SYLLABLE QOP;Lo;0;L;;;;;N;;;;;
+A40C;YI SYLLABLE QUT;Lo;0;L;;;;;N;;;;;
+A40D;YI SYLLABLE QUX;Lo;0;L;;;;;N;;;;;
+A40E;YI SYLLABLE QU;Lo;0;L;;;;;N;;;;;
+A40F;YI SYLLABLE QUP;Lo;0;L;;;;;N;;;;;
+A410;YI SYLLABLE QURX;Lo;0;L;;;;;N;;;;;
+A411;YI SYLLABLE QUR;Lo;0;L;;;;;N;;;;;
+A412;YI SYLLABLE QYT;Lo;0;L;;;;;N;;;;;
+A413;YI SYLLABLE QYX;Lo;0;L;;;;;N;;;;;
+A414;YI SYLLABLE QY;Lo;0;L;;;;;N;;;;;
+A415;YI SYLLABLE QYP;Lo;0;L;;;;;N;;;;;
+A416;YI SYLLABLE QYRX;Lo;0;L;;;;;N;;;;;
+A417;YI SYLLABLE QYR;Lo;0;L;;;;;N;;;;;
+A418;YI SYLLABLE JJIT;Lo;0;L;;;;;N;;;;;
+A419;YI SYLLABLE JJIX;Lo;0;L;;;;;N;;;;;
+A41A;YI SYLLABLE JJI;Lo;0;L;;;;;N;;;;;
+A41B;YI SYLLABLE JJIP;Lo;0;L;;;;;N;;;;;
+A41C;YI SYLLABLE JJIET;Lo;0;L;;;;;N;;;;;
+A41D;YI SYLLABLE JJIEX;Lo;0;L;;;;;N;;;;;
+A41E;YI SYLLABLE JJIE;Lo;0;L;;;;;N;;;;;
+A41F;YI SYLLABLE JJIEP;Lo;0;L;;;;;N;;;;;
+A420;YI SYLLABLE JJUOX;Lo;0;L;;;;;N;;;;;
+A421;YI SYLLABLE JJUO;Lo;0;L;;;;;N;;;;;
+A422;YI SYLLABLE JJUOP;Lo;0;L;;;;;N;;;;;
+A423;YI SYLLABLE JJOT;Lo;0;L;;;;;N;;;;;
+A424;YI SYLLABLE JJOX;Lo;0;L;;;;;N;;;;;
+A425;YI SYLLABLE JJO;Lo;0;L;;;;;N;;;;;
+A426;YI SYLLABLE JJOP;Lo;0;L;;;;;N;;;;;
+A427;YI SYLLABLE JJUT;Lo;0;L;;;;;N;;;;;
+A428;YI SYLLABLE JJUX;Lo;0;L;;;;;N;;;;;
+A429;YI SYLLABLE JJU;Lo;0;L;;;;;N;;;;;
+A42A;YI SYLLABLE JJUP;Lo;0;L;;;;;N;;;;;
+A42B;YI SYLLABLE JJURX;Lo;0;L;;;;;N;;;;;
+A42C;YI SYLLABLE JJUR;Lo;0;L;;;;;N;;;;;
+A42D;YI SYLLABLE JJYT;Lo;0;L;;;;;N;;;;;
+A42E;YI SYLLABLE JJYX;Lo;0;L;;;;;N;;;;;
+A42F;YI SYLLABLE JJY;Lo;0;L;;;;;N;;;;;
+A430;YI SYLLABLE JJYP;Lo;0;L;;;;;N;;;;;
+A431;YI SYLLABLE NJIT;Lo;0;L;;;;;N;;;;;
+A432;YI SYLLABLE NJIX;Lo;0;L;;;;;N;;;;;
+A433;YI SYLLABLE NJI;Lo;0;L;;;;;N;;;;;
+A434;YI SYLLABLE NJIP;Lo;0;L;;;;;N;;;;;
+A435;YI SYLLABLE NJIET;Lo;0;L;;;;;N;;;;;
+A436;YI SYLLABLE NJIEX;Lo;0;L;;;;;N;;;;;
+A437;YI SYLLABLE NJIE;Lo;0;L;;;;;N;;;;;
+A438;YI SYLLABLE NJIEP;Lo;0;L;;;;;N;;;;;
+A439;YI SYLLABLE NJUOX;Lo;0;L;;;;;N;;;;;
+A43A;YI SYLLABLE NJUO;Lo;0;L;;;;;N;;;;;
+A43B;YI SYLLABLE NJOT;Lo;0;L;;;;;N;;;;;
+A43C;YI SYLLABLE NJOX;Lo;0;L;;;;;N;;;;;
+A43D;YI SYLLABLE NJO;Lo;0;L;;;;;N;;;;;
+A43E;YI SYLLABLE NJOP;Lo;0;L;;;;;N;;;;;
+A43F;YI SYLLABLE NJUX;Lo;0;L;;;;;N;;;;;
+A440;YI SYLLABLE NJU;Lo;0;L;;;;;N;;;;;
+A441;YI SYLLABLE NJUP;Lo;0;L;;;;;N;;;;;
+A442;YI SYLLABLE NJURX;Lo;0;L;;;;;N;;;;;
+A443;YI SYLLABLE NJUR;Lo;0;L;;;;;N;;;;;
+A444;YI SYLLABLE NJYT;Lo;0;L;;;;;N;;;;;
+A445;YI SYLLABLE NJYX;Lo;0;L;;;;;N;;;;;
+A446;YI SYLLABLE NJY;Lo;0;L;;;;;N;;;;;
+A447;YI SYLLABLE NJYP;Lo;0;L;;;;;N;;;;;
+A448;YI SYLLABLE NJYRX;Lo;0;L;;;;;N;;;;;
+A449;YI SYLLABLE NJYR;Lo;0;L;;;;;N;;;;;
+A44A;YI SYLLABLE NYIT;Lo;0;L;;;;;N;;;;;
+A44B;YI SYLLABLE NYIX;Lo;0;L;;;;;N;;;;;
+A44C;YI SYLLABLE NYI;Lo;0;L;;;;;N;;;;;
+A44D;YI SYLLABLE NYIP;Lo;0;L;;;;;N;;;;;
+A44E;YI SYLLABLE NYIET;Lo;0;L;;;;;N;;;;;
+A44F;YI SYLLABLE NYIEX;Lo;0;L;;;;;N;;;;;
+A450;YI SYLLABLE NYIE;Lo;0;L;;;;;N;;;;;
+A451;YI SYLLABLE NYIEP;Lo;0;L;;;;;N;;;;;
+A452;YI SYLLABLE NYUOX;Lo;0;L;;;;;N;;;;;
+A453;YI SYLLABLE NYUO;Lo;0;L;;;;;N;;;;;
+A454;YI SYLLABLE NYUOP;Lo;0;L;;;;;N;;;;;
+A455;YI SYLLABLE NYOT;Lo;0;L;;;;;N;;;;;
+A456;YI SYLLABLE NYOX;Lo;0;L;;;;;N;;;;;
+A457;YI SYLLABLE NYO;Lo;0;L;;;;;N;;;;;
+A458;YI SYLLABLE NYOP;Lo;0;L;;;;;N;;;;;
+A459;YI SYLLABLE NYUT;Lo;0;L;;;;;N;;;;;
+A45A;YI SYLLABLE NYUX;Lo;0;L;;;;;N;;;;;
+A45B;YI SYLLABLE NYU;Lo;0;L;;;;;N;;;;;
+A45C;YI SYLLABLE NYUP;Lo;0;L;;;;;N;;;;;
+A45D;YI SYLLABLE XIT;Lo;0;L;;;;;N;;;;;
+A45E;YI SYLLABLE XIX;Lo;0;L;;;;;N;;;;;
+A45F;YI SYLLABLE XI;Lo;0;L;;;;;N;;;;;
+A460;YI SYLLABLE XIP;Lo;0;L;;;;;N;;;;;
+A461;YI SYLLABLE XIET;Lo;0;L;;;;;N;;;;;
+A462;YI SYLLABLE XIEX;Lo;0;L;;;;;N;;;;;
+A463;YI SYLLABLE XIE;Lo;0;L;;;;;N;;;;;
+A464;YI SYLLABLE XIEP;Lo;0;L;;;;;N;;;;;
+A465;YI SYLLABLE XUOX;Lo;0;L;;;;;N;;;;;
+A466;YI SYLLABLE XUO;Lo;0;L;;;;;N;;;;;
+A467;YI SYLLABLE XOT;Lo;0;L;;;;;N;;;;;
+A468;YI SYLLABLE XOX;Lo;0;L;;;;;N;;;;;
+A469;YI SYLLABLE XO;Lo;0;L;;;;;N;;;;;
+A46A;YI SYLLABLE XOP;Lo;0;L;;;;;N;;;;;
+A46B;YI SYLLABLE XYT;Lo;0;L;;;;;N;;;;;
+A46C;YI SYLLABLE XYX;Lo;0;L;;;;;N;;;;;
+A46D;YI SYLLABLE XY;Lo;0;L;;;;;N;;;;;
+A46E;YI SYLLABLE XYP;Lo;0;L;;;;;N;;;;;
+A46F;YI SYLLABLE XYRX;Lo;0;L;;;;;N;;;;;
+A470;YI SYLLABLE XYR;Lo;0;L;;;;;N;;;;;
+A471;YI SYLLABLE YIT;Lo;0;L;;;;;N;;;;;
+A472;YI SYLLABLE YIX;Lo;0;L;;;;;N;;;;;
+A473;YI SYLLABLE YI;Lo;0;L;;;;;N;;;;;
+A474;YI SYLLABLE YIP;Lo;0;L;;;;;N;;;;;
+A475;YI SYLLABLE YIET;Lo;0;L;;;;;N;;;;;
+A476;YI SYLLABLE YIEX;Lo;0;L;;;;;N;;;;;
+A477;YI SYLLABLE YIE;Lo;0;L;;;;;N;;;;;
+A478;YI SYLLABLE YIEP;Lo;0;L;;;;;N;;;;;
+A479;YI SYLLABLE YUOT;Lo;0;L;;;;;N;;;;;
+A47A;YI SYLLABLE YUOX;Lo;0;L;;;;;N;;;;;
+A47B;YI SYLLABLE YUO;Lo;0;L;;;;;N;;;;;
+A47C;YI SYLLABLE YUOP;Lo;0;L;;;;;N;;;;;
+A47D;YI SYLLABLE YOT;Lo;0;L;;;;;N;;;;;
+A47E;YI SYLLABLE YOX;Lo;0;L;;;;;N;;;;;
+A47F;YI SYLLABLE YO;Lo;0;L;;;;;N;;;;;
+A480;YI SYLLABLE YOP;Lo;0;L;;;;;N;;;;;
+A481;YI SYLLABLE YUT;Lo;0;L;;;;;N;;;;;
+A482;YI SYLLABLE YUX;Lo;0;L;;;;;N;;;;;
+A483;YI SYLLABLE YU;Lo;0;L;;;;;N;;;;;
+A484;YI SYLLABLE YUP;Lo;0;L;;;;;N;;;;;
+A485;YI SYLLABLE YURX;Lo;0;L;;;;;N;;;;;
+A486;YI SYLLABLE YUR;Lo;0;L;;;;;N;;;;;
+A487;YI SYLLABLE YYT;Lo;0;L;;;;;N;;;;;
+A488;YI SYLLABLE YYX;Lo;0;L;;;;;N;;;;;
+A489;YI SYLLABLE YY;Lo;0;L;;;;;N;;;;;
+A48A;YI SYLLABLE YYP;Lo;0;L;;;;;N;;;;;
+A48B;YI SYLLABLE YYRX;Lo;0;L;;;;;N;;;;;
+A48C;YI SYLLABLE YYR;Lo;0;L;;;;;N;;;;;
+A490;YI RADICAL QOT;So;0;ON;;;;;N;;;;;
+A491;YI RADICAL LI;So;0;ON;;;;;N;;;;;
+A492;YI RADICAL KIT;So;0;ON;;;;;N;;;;;
+A493;YI RADICAL NYIP;So;0;ON;;;;;N;;;;;
+A494;YI RADICAL CYP;So;0;ON;;;;;N;;;;;
+A495;YI RADICAL SSI;So;0;ON;;;;;N;;;;;
+A496;YI RADICAL GGOP;So;0;ON;;;;;N;;;;;
+A497;YI RADICAL GEP;So;0;ON;;;;;N;;;;;
+A498;YI RADICAL MI;So;0;ON;;;;;N;;;;;
+A499;YI RADICAL HXIT;So;0;ON;;;;;N;;;;;
+A49A;YI RADICAL LYR;So;0;ON;;;;;N;;;;;
+A49B;YI RADICAL BBUT;So;0;ON;;;;;N;;;;;
+A49C;YI RADICAL MOP;So;0;ON;;;;;N;;;;;
+A49D;YI RADICAL YO;So;0;ON;;;;;N;;;;;
+A49E;YI RADICAL PUT;So;0;ON;;;;;N;;;;;
+A49F;YI RADICAL HXUO;So;0;ON;;;;;N;;;;;
+A4A0;YI RADICAL TAT;So;0;ON;;;;;N;;;;;
+A4A1;YI RADICAL GA;So;0;ON;;;;;N;;;;;
+A4A2;YI RADICAL ZUP;So;0;ON;;;;;N;;;;;
+A4A3;YI RADICAL CYT;So;0;ON;;;;;N;;;;;
+A4A4;YI RADICAL DDUR;So;0;ON;;;;;N;;;;;
+A4A5;YI RADICAL BUR;So;0;ON;;;;;N;;;;;
+A4A6;YI RADICAL GGUO;So;0;ON;;;;;N;;;;;
+A4A7;YI RADICAL NYOP;So;0;ON;;;;;N;;;;;
+A4A8;YI RADICAL TU;So;0;ON;;;;;N;;;;;
+A4A9;YI RADICAL OP;So;0;ON;;;;;N;;;;;
+A4AA;YI RADICAL JJUT;So;0;ON;;;;;N;;;;;
+A4AB;YI RADICAL ZOT;So;0;ON;;;;;N;;;;;
+A4AC;YI RADICAL PYT;So;0;ON;;;;;N;;;;;
+A4AD;YI RADICAL HMO;So;0;ON;;;;;N;;;;;
+A4AE;YI RADICAL YIT;So;0;ON;;;;;N;;;;;
+A4AF;YI RADICAL VUR;So;0;ON;;;;;N;;;;;
+A4B0;YI RADICAL SHY;So;0;ON;;;;;N;;;;;
+A4B1;YI RADICAL VEP;So;0;ON;;;;;N;;;;;
+A4B2;YI RADICAL ZA;So;0;ON;;;;;N;;;;;
+A4B3;YI RADICAL JO;So;0;ON;;;;;N;;;;;
+A4B4;YI RADICAL NZUP;So;0;ON;;;;;N;;;;;
+A4B5;YI RADICAL JJY;So;0;ON;;;;;N;;;;;
+A4B6;YI RADICAL GOT;So;0;ON;;;;;N;;;;;
+A4B7;YI RADICAL JJIE;So;0;ON;;;;;N;;;;;
+A4B8;YI RADICAL WO;So;0;ON;;;;;N;;;;;
+A4B9;YI RADICAL DU;So;0;ON;;;;;N;;;;;
+A4BA;YI RADICAL SHUR;So;0;ON;;;;;N;;;;;
+A4BB;YI RADICAL LIE;So;0;ON;;;;;N;;;;;
+A4BC;YI RADICAL CY;So;0;ON;;;;;N;;;;;
+A4BD;YI RADICAL CUOP;So;0;ON;;;;;N;;;;;
+A4BE;YI RADICAL CIP;So;0;ON;;;;;N;;;;;
+A4BF;YI RADICAL HXOP;So;0;ON;;;;;N;;;;;
+A4C0;YI RADICAL SHAT;So;0;ON;;;;;N;;;;;
+A4C1;YI RADICAL ZUR;So;0;ON;;;;;N;;;;;
+A4C2;YI RADICAL SHOP;So;0;ON;;;;;N;;;;;
+A4C3;YI RADICAL CHE;So;0;ON;;;;;N;;;;;
+A4C4;YI RADICAL ZZIET;So;0;ON;;;;;N;;;;;
+A4C5;YI RADICAL NBIE;So;0;ON;;;;;N;;;;;
+A4C6;YI RADICAL KE;So;0;ON;;;;;N;;;;;
+A4D0;LISU LETTER BA;Lo;0;L;;;;;N;;;;;
+A4D1;LISU LETTER PA;Lo;0;L;;;;;N;;;;;
+A4D2;LISU LETTER PHA;Lo;0;L;;;;;N;;;;;
+A4D3;LISU LETTER DA;Lo;0;L;;;;;N;;;;;
+A4D4;LISU LETTER TA;Lo;0;L;;;;;N;;;;;
+A4D5;LISU LETTER THA;Lo;0;L;;;;;N;;;;;
+A4D6;LISU LETTER GA;Lo;0;L;;;;;N;;;;;
+A4D7;LISU LETTER KA;Lo;0;L;;;;;N;;;;;
+A4D8;LISU LETTER KHA;Lo;0;L;;;;;N;;;;;
+A4D9;LISU LETTER JA;Lo;0;L;;;;;N;;;;;
+A4DA;LISU LETTER CA;Lo;0;L;;;;;N;;;;;
+A4DB;LISU LETTER CHA;Lo;0;L;;;;;N;;;;;
+A4DC;LISU LETTER DZA;Lo;0;L;;;;;N;;;;;
+A4DD;LISU LETTER TSA;Lo;0;L;;;;;N;;;;;
+A4DE;LISU LETTER TSHA;Lo;0;L;;;;;N;;;;;
+A4DF;LISU LETTER MA;Lo;0;L;;;;;N;;;;;
+A4E0;LISU LETTER NA;Lo;0;L;;;;;N;;;;;
+A4E1;LISU LETTER LA;Lo;0;L;;;;;N;;;;;
+A4E2;LISU LETTER SA;Lo;0;L;;;;;N;;;;;
+A4E3;LISU LETTER ZHA;Lo;0;L;;;;;N;;;;;
+A4E4;LISU LETTER ZA;Lo;0;L;;;;;N;;;;;
+A4E5;LISU LETTER NGA;Lo;0;L;;;;;N;;;;;
+A4E6;LISU LETTER HA;Lo;0;L;;;;;N;;;;;
+A4E7;LISU LETTER XA;Lo;0;L;;;;;N;;;;;
+A4E8;LISU LETTER HHA;Lo;0;L;;;;;N;;;;;
+A4E9;LISU LETTER FA;Lo;0;L;;;;;N;;;;;
+A4EA;LISU LETTER WA;Lo;0;L;;;;;N;;;;;
+A4EB;LISU LETTER SHA;Lo;0;L;;;;;N;;;;;
+A4EC;LISU LETTER YA;Lo;0;L;;;;;N;;;;;
+A4ED;LISU LETTER GHA;Lo;0;L;;;;;N;;;;;
+A4EE;LISU LETTER A;Lo;0;L;;;;;N;;;;;
+A4EF;LISU LETTER AE;Lo;0;L;;;;;N;;;;;
+A4F0;LISU LETTER E;Lo;0;L;;;;;N;;;;;
+A4F1;LISU LETTER EU;Lo;0;L;;;;;N;;;;;
+A4F2;LISU LETTER I;Lo;0;L;;;;;N;;;;;
+A4F3;LISU LETTER O;Lo;0;L;;;;;N;;;;;
+A4F4;LISU LETTER U;Lo;0;L;;;;;N;;;;;
+A4F5;LISU LETTER UE;Lo;0;L;;;;;N;;;;;
+A4F6;LISU LETTER UH;Lo;0;L;;;;;N;;;;;
+A4F7;LISU LETTER OE;Lo;0;L;;;;;N;;;;;
+A4F8;LISU LETTER TONE MYA TI;Lm;0;L;;;;;N;;;;;
+A4F9;LISU LETTER TONE NA PO;Lm;0;L;;;;;N;;;;;
+A4FA;LISU LETTER TONE MYA CYA;Lm;0;L;;;;;N;;;;;
+A4FB;LISU LETTER TONE MYA BO;Lm;0;L;;;;;N;;;;;
+A4FC;LISU LETTER TONE MYA NA;Lm;0;L;;;;;N;;;;;
+A4FD;LISU LETTER TONE MYA JEU;Lm;0;L;;;;;N;;;;;
+A4FE;LISU PUNCTUATION COMMA;Po;0;L;;;;;N;;;;;
+A4FF;LISU PUNCTUATION FULL STOP;Po;0;L;;;;;N;;;;;
+A500;VAI SYLLABLE EE;Lo;0;L;;;;;N;;;;;
+A501;VAI SYLLABLE EEN;Lo;0;L;;;;;N;;;;;
+A502;VAI SYLLABLE HEE;Lo;0;L;;;;;N;;;;;
+A503;VAI SYLLABLE WEE;Lo;0;L;;;;;N;;;;;
+A504;VAI SYLLABLE WEEN;Lo;0;L;;;;;N;;;;;
+A505;VAI SYLLABLE PEE;Lo;0;L;;;;;N;;;;;
+A506;VAI SYLLABLE BHEE;Lo;0;L;;;;;N;;;;;
+A507;VAI SYLLABLE BEE;Lo;0;L;;;;;N;;;;;
+A508;VAI SYLLABLE MBEE;Lo;0;L;;;;;N;;;;;
+A509;VAI SYLLABLE KPEE;Lo;0;L;;;;;N;;;;;
+A50A;VAI SYLLABLE MGBEE;Lo;0;L;;;;;N;;;;;
+A50B;VAI SYLLABLE GBEE;Lo;0;L;;;;;N;;;;;
+A50C;VAI SYLLABLE FEE;Lo;0;L;;;;;N;;;;;
+A50D;VAI SYLLABLE VEE;Lo;0;L;;;;;N;;;;;
+A50E;VAI SYLLABLE TEE;Lo;0;L;;;;;N;;;;;
+A50F;VAI SYLLABLE THEE;Lo;0;L;;;;;N;;;;;
+A510;VAI SYLLABLE DHEE;Lo;0;L;;;;;N;;;;;
+A511;VAI SYLLABLE DHHEE;Lo;0;L;;;;;N;;;;;
+A512;VAI SYLLABLE LEE;Lo;0;L;;;;;N;;;;;
+A513;VAI SYLLABLE REE;Lo;0;L;;;;;N;;;;;
+A514;VAI SYLLABLE DEE;Lo;0;L;;;;;N;;;;;
+A515;VAI SYLLABLE NDEE;Lo;0;L;;;;;N;;;;;
+A516;VAI SYLLABLE SEE;Lo;0;L;;;;;N;;;;;
+A517;VAI SYLLABLE SHEE;Lo;0;L;;;;;N;;;;;
+A518;VAI SYLLABLE ZEE;Lo;0;L;;;;;N;;;;;
+A519;VAI SYLLABLE ZHEE;Lo;0;L;;;;;N;;;;;
+A51A;VAI SYLLABLE CEE;Lo;0;L;;;;;N;;;;;
+A51B;VAI SYLLABLE JEE;Lo;0;L;;;;;N;;;;;
+A51C;VAI SYLLABLE NJEE;Lo;0;L;;;;;N;;;;;
+A51D;VAI SYLLABLE YEE;Lo;0;L;;;;;N;;;;;
+A51E;VAI SYLLABLE KEE;Lo;0;L;;;;;N;;;;;
+A51F;VAI SYLLABLE NGGEE;Lo;0;L;;;;;N;;;;;
+A520;VAI SYLLABLE GEE;Lo;0;L;;;;;N;;;;;
+A521;VAI SYLLABLE MEE;Lo;0;L;;;;;N;;;;;
+A522;VAI SYLLABLE NEE;Lo;0;L;;;;;N;;;;;
+A523;VAI SYLLABLE NYEE;Lo;0;L;;;;;N;;;;;
+A524;VAI SYLLABLE I;Lo;0;L;;;;;N;;;;;
+A525;VAI SYLLABLE IN;Lo;0;L;;;;;N;;;;;
+A526;VAI SYLLABLE HI;Lo;0;L;;;;;N;;;;;
+A527;VAI SYLLABLE HIN;Lo;0;L;;;;;N;;;;;
+A528;VAI SYLLABLE WI;Lo;0;L;;;;;N;;;;;
+A529;VAI SYLLABLE WIN;Lo;0;L;;;;;N;;;;;
+A52A;VAI SYLLABLE PI;Lo;0;L;;;;;N;;;;;
+A52B;VAI SYLLABLE BHI;Lo;0;L;;;;;N;;;;;
+A52C;VAI SYLLABLE BI;Lo;0;L;;;;;N;;;;;
+A52D;VAI SYLLABLE MBI;Lo;0;L;;;;;N;;;;;
+A52E;VAI SYLLABLE KPI;Lo;0;L;;;;;N;;;;;
+A52F;VAI SYLLABLE MGBI;Lo;0;L;;;;;N;;;;;
+A530;VAI SYLLABLE GBI;Lo;0;L;;;;;N;;;;;
+A531;VAI SYLLABLE FI;Lo;0;L;;;;;N;;;;;
+A532;VAI SYLLABLE VI;Lo;0;L;;;;;N;;;;;
+A533;VAI SYLLABLE TI;Lo;0;L;;;;;N;;;;;
+A534;VAI SYLLABLE THI;Lo;0;L;;;;;N;;;;;
+A535;VAI SYLLABLE DHI;Lo;0;L;;;;;N;;;;;
+A536;VAI SYLLABLE DHHI;Lo;0;L;;;;;N;;;;;
+A537;VAI SYLLABLE LI;Lo;0;L;;;;;N;;;;;
+A538;VAI SYLLABLE RI;Lo;0;L;;;;;N;;;;;
+A539;VAI SYLLABLE DI;Lo;0;L;;;;;N;;;;;
+A53A;VAI SYLLABLE NDI;Lo;0;L;;;;;N;;;;;
+A53B;VAI SYLLABLE SI;Lo;0;L;;;;;N;;;;;
+A53C;VAI SYLLABLE SHI;Lo;0;L;;;;;N;;;;;
+A53D;VAI SYLLABLE ZI;Lo;0;L;;;;;N;;;;;
+A53E;VAI SYLLABLE ZHI;Lo;0;L;;;;;N;;;;;
+A53F;VAI SYLLABLE CI;Lo;0;L;;;;;N;;;;;
+A540;VAI SYLLABLE JI;Lo;0;L;;;;;N;;;;;
+A541;VAI SYLLABLE NJI;Lo;0;L;;;;;N;;;;;
+A542;VAI SYLLABLE YI;Lo;0;L;;;;;N;;;;;
+A543;VAI SYLLABLE KI;Lo;0;L;;;;;N;;;;;
+A544;VAI SYLLABLE NGGI;Lo;0;L;;;;;N;;;;;
+A545;VAI SYLLABLE GI;Lo;0;L;;;;;N;;;;;
+A546;VAI SYLLABLE MI;Lo;0;L;;;;;N;;;;;
+A547;VAI SYLLABLE NI;Lo;0;L;;;;;N;;;;;
+A548;VAI SYLLABLE NYI;Lo;0;L;;;;;N;;;;;
+A549;VAI SYLLABLE A;Lo;0;L;;;;;N;;;;;
+A54A;VAI SYLLABLE AN;Lo;0;L;;;;;N;;;;;
+A54B;VAI SYLLABLE NGAN;Lo;0;L;;;;;N;;;;;
+A54C;VAI SYLLABLE HA;Lo;0;L;;;;;N;;;;;
+A54D;VAI SYLLABLE HAN;Lo;0;L;;;;;N;;;;;
+A54E;VAI SYLLABLE WA;Lo;0;L;;;;;N;;;;;
+A54F;VAI SYLLABLE WAN;Lo;0;L;;;;;N;;;;;
+A550;VAI SYLLABLE PA;Lo;0;L;;;;;N;;;;;
+A551;VAI SYLLABLE BHA;Lo;0;L;;;;;N;;;;;
+A552;VAI SYLLABLE BA;Lo;0;L;;;;;N;;;;;
+A553;VAI SYLLABLE MBA;Lo;0;L;;;;;N;;;;;
+A554;VAI SYLLABLE KPA;Lo;0;L;;;;;N;;;;;
+A555;VAI SYLLABLE KPAN;Lo;0;L;;;;;N;;;;;
+A556;VAI SYLLABLE MGBA;Lo;0;L;;;;;N;;;;;
+A557;VAI SYLLABLE GBA;Lo;0;L;;;;;N;;;;;
+A558;VAI SYLLABLE FA;Lo;0;L;;;;;N;;;;;
+A559;VAI SYLLABLE VA;Lo;0;L;;;;;N;;;;;
+A55A;VAI SYLLABLE TA;Lo;0;L;;;;;N;;;;;
+A55B;VAI SYLLABLE THA;Lo;0;L;;;;;N;;;;;
+A55C;VAI SYLLABLE DHA;Lo;0;L;;;;;N;;;;;
+A55D;VAI SYLLABLE DHHA;Lo;0;L;;;;;N;;;;;
+A55E;VAI SYLLABLE LA;Lo;0;L;;;;;N;;;;;
+A55F;VAI SYLLABLE RA;Lo;0;L;;;;;N;;;;;
+A560;VAI SYLLABLE DA;Lo;0;L;;;;;N;;;;;
+A561;VAI SYLLABLE NDA;Lo;0;L;;;;;N;;;;;
+A562;VAI SYLLABLE SA;Lo;0;L;;;;;N;;;;;
+A563;VAI SYLLABLE SHA;Lo;0;L;;;;;N;;;;;
+A564;VAI SYLLABLE ZA;Lo;0;L;;;;;N;;;;;
+A565;VAI SYLLABLE ZHA;Lo;0;L;;;;;N;;;;;
+A566;VAI SYLLABLE CA;Lo;0;L;;;;;N;;;;;
+A567;VAI SYLLABLE JA;Lo;0;L;;;;;N;;;;;
+A568;VAI SYLLABLE NJA;Lo;0;L;;;;;N;;;;;
+A569;VAI SYLLABLE YA;Lo;0;L;;;;;N;;;;;
+A56A;VAI SYLLABLE KA;Lo;0;L;;;;;N;;;;;
+A56B;VAI SYLLABLE KAN;Lo;0;L;;;;;N;;;;;
+A56C;VAI SYLLABLE NGGA;Lo;0;L;;;;;N;;;;;
+A56D;VAI SYLLABLE GA;Lo;0;L;;;;;N;;;;;
+A56E;VAI SYLLABLE MA;Lo;0;L;;;;;N;;;;;
+A56F;VAI SYLLABLE NA;Lo;0;L;;;;;N;;;;;
+A570;VAI SYLLABLE NYA;Lo;0;L;;;;;N;;;;;
+A571;VAI SYLLABLE OO;Lo;0;L;;;;;N;;;;;
+A572;VAI SYLLABLE OON;Lo;0;L;;;;;N;;;;;
+A573;VAI SYLLABLE HOO;Lo;0;L;;;;;N;;;;;
+A574;VAI SYLLABLE WOO;Lo;0;L;;;;;N;;;;;
+A575;VAI SYLLABLE WOON;Lo;0;L;;;;;N;;;;;
+A576;VAI SYLLABLE POO;Lo;0;L;;;;;N;;;;;
+A577;VAI SYLLABLE BHOO;Lo;0;L;;;;;N;;;;;
+A578;VAI SYLLABLE BOO;Lo;0;L;;;;;N;;;;;
+A579;VAI SYLLABLE MBOO;Lo;0;L;;;;;N;;;;;
+A57A;VAI SYLLABLE KPOO;Lo;0;L;;;;;N;;;;;
+A57B;VAI SYLLABLE MGBOO;Lo;0;L;;;;;N;;;;;
+A57C;VAI SYLLABLE GBOO;Lo;0;L;;;;;N;;;;;
+A57D;VAI SYLLABLE FOO;Lo;0;L;;;;;N;;;;;
+A57E;VAI SYLLABLE VOO;Lo;0;L;;;;;N;;;;;
+A57F;VAI SYLLABLE TOO;Lo;0;L;;;;;N;;;;;
+A580;VAI SYLLABLE THOO;Lo;0;L;;;;;N;;;;;
+A581;VAI SYLLABLE DHOO;Lo;0;L;;;;;N;;;;;
+A582;VAI SYLLABLE DHHOO;Lo;0;L;;;;;N;;;;;
+A583;VAI SYLLABLE LOO;Lo;0;L;;;;;N;;;;;
+A584;VAI SYLLABLE ROO;Lo;0;L;;;;;N;;;;;
+A585;VAI SYLLABLE DOO;Lo;0;L;;;;;N;;;;;
+A586;VAI SYLLABLE NDOO;Lo;0;L;;;;;N;;;;;
+A587;VAI SYLLABLE SOO;Lo;0;L;;;;;N;;;;;
+A588;VAI SYLLABLE SHOO;Lo;0;L;;;;;N;;;;;
+A589;VAI SYLLABLE ZOO;Lo;0;L;;;;;N;;;;;
+A58A;VAI SYLLABLE ZHOO;Lo;0;L;;;;;N;;;;;
+A58B;VAI SYLLABLE COO;Lo;0;L;;;;;N;;;;;
+A58C;VAI SYLLABLE JOO;Lo;0;L;;;;;N;;;;;
+A58D;VAI SYLLABLE NJOO;Lo;0;L;;;;;N;;;;;
+A58E;VAI SYLLABLE YOO;Lo;0;L;;;;;N;;;;;
+A58F;VAI SYLLABLE KOO;Lo;0;L;;;;;N;;;;;
+A590;VAI SYLLABLE NGGOO;Lo;0;L;;;;;N;;;;;
+A591;VAI SYLLABLE GOO;Lo;0;L;;;;;N;;;;;
+A592;VAI SYLLABLE MOO;Lo;0;L;;;;;N;;;;;
+A593;VAI SYLLABLE NOO;Lo;0;L;;;;;N;;;;;
+A594;VAI SYLLABLE NYOO;Lo;0;L;;;;;N;;;;;
+A595;VAI SYLLABLE U;Lo;0;L;;;;;N;;;;;
+A596;VAI SYLLABLE UN;Lo;0;L;;;;;N;;;;;
+A597;VAI SYLLABLE HU;Lo;0;L;;;;;N;;;;;
+A598;VAI SYLLABLE HUN;Lo;0;L;;;;;N;;;;;
+A599;VAI SYLLABLE WU;Lo;0;L;;;;;N;;;;;
+A59A;VAI SYLLABLE WUN;Lo;0;L;;;;;N;;;;;
+A59B;VAI SYLLABLE PU;Lo;0;L;;;;;N;;;;;
+A59C;VAI SYLLABLE BHU;Lo;0;L;;;;;N;;;;;
+A59D;VAI SYLLABLE BU;Lo;0;L;;;;;N;;;;;
+A59E;VAI SYLLABLE MBU;Lo;0;L;;;;;N;;;;;
+A59F;VAI SYLLABLE KPU;Lo;0;L;;;;;N;;;;;
+A5A0;VAI SYLLABLE MGBU;Lo;0;L;;;;;N;;;;;
+A5A1;VAI SYLLABLE GBU;Lo;0;L;;;;;N;;;;;
+A5A2;VAI SYLLABLE FU;Lo;0;L;;;;;N;;;;;
+A5A3;VAI SYLLABLE VU;Lo;0;L;;;;;N;;;;;
+A5A4;VAI SYLLABLE TU;Lo;0;L;;;;;N;;;;;
+A5A5;VAI SYLLABLE THU;Lo;0;L;;;;;N;;;;;
+A5A6;VAI SYLLABLE DHU;Lo;0;L;;;;;N;;;;;
+A5A7;VAI SYLLABLE DHHU;Lo;0;L;;;;;N;;;;;
+A5A8;VAI SYLLABLE LU;Lo;0;L;;;;;N;;;;;
+A5A9;VAI SYLLABLE RU;Lo;0;L;;;;;N;;;;;
+A5AA;VAI SYLLABLE DU;Lo;0;L;;;;;N;;;;;
+A5AB;VAI SYLLABLE NDU;Lo;0;L;;;;;N;;;;;
+A5AC;VAI SYLLABLE SU;Lo;0;L;;;;;N;;;;;
+A5AD;VAI SYLLABLE SHU;Lo;0;L;;;;;N;;;;;
+A5AE;VAI SYLLABLE ZU;Lo;0;L;;;;;N;;;;;
+A5AF;VAI SYLLABLE ZHU;Lo;0;L;;;;;N;;;;;
+A5B0;VAI SYLLABLE CU;Lo;0;L;;;;;N;;;;;
+A5B1;VAI SYLLABLE JU;Lo;0;L;;;;;N;;;;;
+A5B2;VAI SYLLABLE NJU;Lo;0;L;;;;;N;;;;;
+A5B3;VAI SYLLABLE YU;Lo;0;L;;;;;N;;;;;
+A5B4;VAI SYLLABLE KU;Lo;0;L;;;;;N;;;;;
+A5B5;VAI SYLLABLE NGGU;Lo;0;L;;;;;N;;;;;
+A5B6;VAI SYLLABLE GU;Lo;0;L;;;;;N;;;;;
+A5B7;VAI SYLLABLE MU;Lo;0;L;;;;;N;;;;;
+A5B8;VAI SYLLABLE NU;Lo;0;L;;;;;N;;;;;
+A5B9;VAI SYLLABLE NYU;Lo;0;L;;;;;N;;;;;
+A5BA;VAI SYLLABLE O;Lo;0;L;;;;;N;;;;;
+A5BB;VAI SYLLABLE ON;Lo;0;L;;;;;N;;;;;
+A5BC;VAI SYLLABLE NGON;Lo;0;L;;;;;N;;;;;
+A5BD;VAI SYLLABLE HO;Lo;0;L;;;;;N;;;;;
+A5BE;VAI SYLLABLE HON;Lo;0;L;;;;;N;;;;;
+A5BF;VAI SYLLABLE WO;Lo;0;L;;;;;N;;;;;
+A5C0;VAI SYLLABLE WON;Lo;0;L;;;;;N;;;;;
+A5C1;VAI SYLLABLE PO;Lo;0;L;;;;;N;;;;;
+A5C2;VAI SYLLABLE BHO;Lo;0;L;;;;;N;;;;;
+A5C3;VAI SYLLABLE BO;Lo;0;L;;;;;N;;;;;
+A5C4;VAI SYLLABLE MBO;Lo;0;L;;;;;N;;;;;
+A5C5;VAI SYLLABLE KPO;Lo;0;L;;;;;N;;;;;
+A5C6;VAI SYLLABLE MGBO;Lo;0;L;;;;;N;;;;;
+A5C7;VAI SYLLABLE GBO;Lo;0;L;;;;;N;;;;;
+A5C8;VAI SYLLABLE GBON;Lo;0;L;;;;;N;;;;;
+A5C9;VAI SYLLABLE FO;Lo;0;L;;;;;N;;;;;
+A5CA;VAI SYLLABLE VO;Lo;0;L;;;;;N;;;;;
+A5CB;VAI SYLLABLE TO;Lo;0;L;;;;;N;;;;;
+A5CC;VAI SYLLABLE THO;Lo;0;L;;;;;N;;;;;
+A5CD;VAI SYLLABLE DHO;Lo;0;L;;;;;N;;;;;
+A5CE;VAI SYLLABLE DHHO;Lo;0;L;;;;;N;;;;;
+A5CF;VAI SYLLABLE LO;Lo;0;L;;;;;N;;;;;
+A5D0;VAI SYLLABLE RO;Lo;0;L;;;;;N;;;;;
+A5D1;VAI SYLLABLE DO;Lo;0;L;;;;;N;;;;;
+A5D2;VAI SYLLABLE NDO;Lo;0;L;;;;;N;;;;;
+A5D3;VAI SYLLABLE SO;Lo;0;L;;;;;N;;;;;
+A5D4;VAI SYLLABLE SHO;Lo;0;L;;;;;N;;;;;
+A5D5;VAI SYLLABLE ZO;Lo;0;L;;;;;N;;;;;
+A5D6;VAI SYLLABLE ZHO;Lo;0;L;;;;;N;;;;;
+A5D7;VAI SYLLABLE CO;Lo;0;L;;;;;N;;;;;
+A5D8;VAI SYLLABLE JO;Lo;0;L;;;;;N;;;;;
+A5D9;VAI SYLLABLE NJO;Lo;0;L;;;;;N;;;;;
+A5DA;VAI SYLLABLE YO;Lo;0;L;;;;;N;;;;;
+A5DB;VAI SYLLABLE KO;Lo;0;L;;;;;N;;;;;
+A5DC;VAI SYLLABLE NGGO;Lo;0;L;;;;;N;;;;;
+A5DD;VAI SYLLABLE GO;Lo;0;L;;;;;N;;;;;
+A5DE;VAI SYLLABLE MO;Lo;0;L;;;;;N;;;;;
+A5DF;VAI SYLLABLE NO;Lo;0;L;;;;;N;;;;;
+A5E0;VAI SYLLABLE NYO;Lo;0;L;;;;;N;;;;;
+A5E1;VAI SYLLABLE E;Lo;0;L;;;;;N;;;;;
+A5E2;VAI SYLLABLE EN;Lo;0;L;;;;;N;;;;;
+A5E3;VAI SYLLABLE NGEN;Lo;0;L;;;;;N;;;;;
+A5E4;VAI SYLLABLE HE;Lo;0;L;;;;;N;;;;;
+A5E5;VAI SYLLABLE HEN;Lo;0;L;;;;;N;;;;;
+A5E6;VAI SYLLABLE WE;Lo;0;L;;;;;N;;;;;
+A5E7;VAI SYLLABLE WEN;Lo;0;L;;;;;N;;;;;
+A5E8;VAI SYLLABLE PE;Lo;0;L;;;;;N;;;;;
+A5E9;VAI SYLLABLE BHE;Lo;0;L;;;;;N;;;;;
+A5EA;VAI SYLLABLE BE;Lo;0;L;;;;;N;;;;;
+A5EB;VAI SYLLABLE MBE;Lo;0;L;;;;;N;;;;;
+A5EC;VAI SYLLABLE KPE;Lo;0;L;;;;;N;;;;;
+A5ED;VAI SYLLABLE KPEN;Lo;0;L;;;;;N;;;;;
+A5EE;VAI SYLLABLE MGBE;Lo;0;L;;;;;N;;;;;
+A5EF;VAI SYLLABLE GBE;Lo;0;L;;;;;N;;;;;
+A5F0;VAI SYLLABLE GBEN;Lo;0;L;;;;;N;;;;;
+A5F1;VAI SYLLABLE FE;Lo;0;L;;;;;N;;;;;
+A5F2;VAI SYLLABLE VE;Lo;0;L;;;;;N;;;;;
+A5F3;VAI SYLLABLE TE;Lo;0;L;;;;;N;;;;;
+A5F4;VAI SYLLABLE THE;Lo;0;L;;;;;N;;;;;
+A5F5;VAI SYLLABLE DHE;Lo;0;L;;;;;N;;;;;
+A5F6;VAI SYLLABLE DHHE;Lo;0;L;;;;;N;;;;;
+A5F7;VAI SYLLABLE LE;Lo;0;L;;;;;N;;;;;
+A5F8;VAI SYLLABLE RE;Lo;0;L;;;;;N;;;;;
+A5F9;VAI SYLLABLE DE;Lo;0;L;;;;;N;;;;;
+A5FA;VAI SYLLABLE NDE;Lo;0;L;;;;;N;;;;;
+A5FB;VAI SYLLABLE SE;Lo;0;L;;;;;N;;;;;
+A5FC;VAI SYLLABLE SHE;Lo;0;L;;;;;N;;;;;
+A5FD;VAI SYLLABLE ZE;Lo;0;L;;;;;N;;;;;
+A5FE;VAI SYLLABLE ZHE;Lo;0;L;;;;;N;;;;;
+A5FF;VAI SYLLABLE CE;Lo;0;L;;;;;N;;;;;
+A600;VAI SYLLABLE JE;Lo;0;L;;;;;N;;;;;
+A601;VAI SYLLABLE NJE;Lo;0;L;;;;;N;;;;;
+A602;VAI SYLLABLE YE;Lo;0;L;;;;;N;;;;;
+A603;VAI SYLLABLE KE;Lo;0;L;;;;;N;;;;;
+A604;VAI SYLLABLE NGGE;Lo;0;L;;;;;N;;;;;
+A605;VAI SYLLABLE NGGEN;Lo;0;L;;;;;N;;;;;
+A606;VAI SYLLABLE GE;Lo;0;L;;;;;N;;;;;
+A607;VAI SYLLABLE GEN;Lo;0;L;;;;;N;;;;;
+A608;VAI SYLLABLE ME;Lo;0;L;;;;;N;;;;;
+A609;VAI SYLLABLE NE;Lo;0;L;;;;;N;;;;;
+A60A;VAI SYLLABLE NYE;Lo;0;L;;;;;N;;;;;
+A60B;VAI SYLLABLE NG;Lo;0;L;;;;;N;;;;;
+A60C;VAI SYLLABLE LENGTHENER;Lm;0;L;;;;;N;;;;;
+A60D;VAI COMMA;Po;0;ON;;;;;N;;;;;
+A60E;VAI FULL STOP;Po;0;ON;;;;;N;;;;;
+A60F;VAI QUESTION MARK;Po;0;ON;;;;;N;;;;;
+A610;VAI SYLLABLE NDOLE FA;Lo;0;L;;;;;N;;;;;
+A611;VAI SYLLABLE NDOLE KA;Lo;0;L;;;;;N;;;;;
+A612;VAI SYLLABLE NDOLE SOO;Lo;0;L;;;;;N;;;;;
+A613;VAI SYMBOL FEENG;Lo;0;L;;;;;N;;;;;
+A614;VAI SYMBOL KEENG;Lo;0;L;;;;;N;;;;;
+A615;VAI SYMBOL TING;Lo;0;L;;;;;N;;;;;
+A616;VAI SYMBOL NII;Lo;0;L;;;;;N;;;;;
+A617;VAI SYMBOL BANG;Lo;0;L;;;;;N;;;;;
+A618;VAI SYMBOL FAA;Lo;0;L;;;;;N;;;;;
+A619;VAI SYMBOL TAA;Lo;0;L;;;;;N;;;;;
+A61A;VAI SYMBOL DANG;Lo;0;L;;;;;N;;;;;
+A61B;VAI SYMBOL DOONG;Lo;0;L;;;;;N;;;;;
+A61C;VAI SYMBOL KUNG;Lo;0;L;;;;;N;;;;;
+A61D;VAI SYMBOL TONG;Lo;0;L;;;;;N;;;;;
+A61E;VAI SYMBOL DO-O;Lo;0;L;;;;;N;;;;;
+A61F;VAI SYMBOL JONG;Lo;0;L;;;;;N;;;;;
+A620;VAI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+A621;VAI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+A622;VAI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+A623;VAI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+A624;VAI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+A625;VAI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+A626;VAI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+A627;VAI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+A628;VAI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+A629;VAI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+A62A;VAI SYLLABLE NDOLE MA;Lo;0;L;;;;;N;;;;;
+A62B;VAI SYLLABLE NDOLE DO;Lo;0;L;;;;;N;;;;;
+A640;CYRILLIC CAPITAL LETTER ZEMLYA;Lu;0;L;;;;;N;;;;A641;
+A641;CYRILLIC SMALL LETTER ZEMLYA;Ll;0;L;;;;;N;;;A640;;A640
+A642;CYRILLIC CAPITAL LETTER DZELO;Lu;0;L;;;;;N;;;;A643;
+A643;CYRILLIC SMALL LETTER DZELO;Ll;0;L;;;;;N;;;A642;;A642
+A644;CYRILLIC CAPITAL LETTER REVERSED DZE;Lu;0;L;;;;;N;;;;A645;
+A645;CYRILLIC SMALL LETTER REVERSED DZE;Ll;0;L;;;;;N;;;A644;;A644
+A646;CYRILLIC CAPITAL LETTER IOTA;Lu;0;L;;;;;N;;;;A647;
+A647;CYRILLIC SMALL LETTER IOTA;Ll;0;L;;;;;N;;;A646;;A646
+A648;CYRILLIC CAPITAL LETTER DJERV;Lu;0;L;;;;;N;;;;A649;
+A649;CYRILLIC SMALL LETTER DJERV;Ll;0;L;;;;;N;;;A648;;A648
+A64A;CYRILLIC CAPITAL LETTER MONOGRAPH UK;Lu;0;L;;;;;N;;;;A64B;
+A64B;CYRILLIC SMALL LETTER MONOGRAPH UK;Ll;0;L;;;;;N;;;A64A;;A64A
+A64C;CYRILLIC CAPITAL LETTER BROAD OMEGA;Lu;0;L;;;;;N;;;;A64D;
+A64D;CYRILLIC SMALL LETTER BROAD OMEGA;Ll;0;L;;;;;N;;;A64C;;A64C
+A64E;CYRILLIC CAPITAL LETTER NEUTRAL YER;Lu;0;L;;;;;N;;;;A64F;
+A64F;CYRILLIC SMALL LETTER NEUTRAL YER;Ll;0;L;;;;;N;;;A64E;;A64E
+A650;CYRILLIC CAPITAL LETTER YERU WITH BACK YER;Lu;0;L;;;;;N;;;;A651;
+A651;CYRILLIC SMALL LETTER YERU WITH BACK YER;Ll;0;L;;;;;N;;;A650;;A650
+A652;CYRILLIC CAPITAL LETTER IOTIFIED YAT;Lu;0;L;;;;;N;;;;A653;
+A653;CYRILLIC SMALL LETTER IOTIFIED YAT;Ll;0;L;;;;;N;;;A652;;A652
+A654;CYRILLIC CAPITAL LETTER REVERSED YU;Lu;0;L;;;;;N;;;;A655;
+A655;CYRILLIC SMALL LETTER REVERSED YU;Ll;0;L;;;;;N;;;A654;;A654
+A656;CYRILLIC CAPITAL LETTER IOTIFIED A;Lu;0;L;;;;;N;;;;A657;
+A657;CYRILLIC SMALL LETTER IOTIFIED A;Ll;0;L;;;;;N;;;A656;;A656
+A658;CYRILLIC CAPITAL LETTER CLOSED LITTLE YUS;Lu;0;L;;;;;N;;;;A659;
+A659;CYRILLIC SMALL LETTER CLOSED LITTLE YUS;Ll;0;L;;;;;N;;;A658;;A658
+A65A;CYRILLIC CAPITAL LETTER BLENDED YUS;Lu;0;L;;;;;N;;;;A65B;
+A65B;CYRILLIC SMALL LETTER BLENDED YUS;Ll;0;L;;;;;N;;;A65A;;A65A
+A65C;CYRILLIC CAPITAL LETTER IOTIFIED CLOSED LITTLE YUS;Lu;0;L;;;;;N;;;;A65D;
+A65D;CYRILLIC SMALL LETTER IOTIFIED CLOSED LITTLE YUS;Ll;0;L;;;;;N;;;A65C;;A65C
+A65E;CYRILLIC CAPITAL LETTER YN;Lu;0;L;;;;;N;;;;A65F;
+A65F;CYRILLIC SMALL LETTER YN;Ll;0;L;;;;;N;;;A65E;;A65E
+A660;CYRILLIC CAPITAL LETTER REVERSED TSE;Lu;0;L;;;;;N;;;;A661;
+A661;CYRILLIC SMALL LETTER REVERSED TSE;Ll;0;L;;;;;N;;;A660;;A660
+A662;CYRILLIC CAPITAL LETTER SOFT DE;Lu;0;L;;;;;N;;;;A663;
+A663;CYRILLIC SMALL LETTER SOFT DE;Ll;0;L;;;;;N;;;A662;;A662
+A664;CYRILLIC CAPITAL LETTER SOFT EL;Lu;0;L;;;;;N;;;;A665;
+A665;CYRILLIC SMALL LETTER SOFT EL;Ll;0;L;;;;;N;;;A664;;A664
+A666;CYRILLIC CAPITAL LETTER SOFT EM;Lu;0;L;;;;;N;;;;A667;
+A667;CYRILLIC SMALL LETTER SOFT EM;Ll;0;L;;;;;N;;;A666;;A666
+A668;CYRILLIC CAPITAL LETTER MONOCULAR O;Lu;0;L;;;;;N;;;;A669;
+A669;CYRILLIC SMALL LETTER MONOCULAR O;Ll;0;L;;;;;N;;;A668;;A668
+A66A;CYRILLIC CAPITAL LETTER BINOCULAR O;Lu;0;L;;;;;N;;;;A66B;
+A66B;CYRILLIC SMALL LETTER BINOCULAR O;Ll;0;L;;;;;N;;;A66A;;A66A
+A66C;CYRILLIC CAPITAL LETTER DOUBLE MONOCULAR O;Lu;0;L;;;;;N;;;;A66D;
+A66D;CYRILLIC SMALL LETTER DOUBLE MONOCULAR O;Ll;0;L;;;;;N;;;A66C;;A66C
+A66E;CYRILLIC LETTER MULTIOCULAR O;Lo;0;L;;;;;N;;;;;
+A66F;COMBINING CYRILLIC VZMET;Mn;230;NSM;;;;;N;;;;;
+A670;COMBINING CYRILLIC TEN MILLIONS SIGN;Me;0;NSM;;;;;N;;;;;
+A671;COMBINING CYRILLIC HUNDRED MILLIONS SIGN;Me;0;NSM;;;;;N;;;;;
+A672;COMBINING CYRILLIC THOUSAND MILLIONS SIGN;Me;0;NSM;;;;;N;;;;;
+A673;SLAVONIC ASTERISK;Po;0;ON;;;;;N;;;;;
+A67C;COMBINING CYRILLIC KAVYKA;Mn;230;NSM;;;;;N;;;;;
+A67D;COMBINING CYRILLIC PAYEROK;Mn;230;NSM;;;;;N;;;;;
+A67E;CYRILLIC KAVYKA;Po;0;ON;;;;;N;;;;;
+A67F;CYRILLIC PAYEROK;Lm;0;ON;;;;;N;;;;;
+A680;CYRILLIC CAPITAL LETTER DWE;Lu;0;L;;;;;N;;;;A681;
+A681;CYRILLIC SMALL LETTER DWE;Ll;0;L;;;;;N;;;A680;;A680
+A682;CYRILLIC CAPITAL LETTER DZWE;Lu;0;L;;;;;N;;;;A683;
+A683;CYRILLIC SMALL LETTER DZWE;Ll;0;L;;;;;N;;;A682;;A682
+A684;CYRILLIC CAPITAL LETTER ZHWE;Lu;0;L;;;;;N;;;;A685;
+A685;CYRILLIC SMALL LETTER ZHWE;Ll;0;L;;;;;N;;;A684;;A684
+A686;CYRILLIC CAPITAL LETTER CCHE;Lu;0;L;;;;;N;;;;A687;
+A687;CYRILLIC SMALL LETTER CCHE;Ll;0;L;;;;;N;;;A686;;A686
+A688;CYRILLIC CAPITAL LETTER DZZE;Lu;0;L;;;;;N;;;;A689;
+A689;CYRILLIC SMALL LETTER DZZE;Ll;0;L;;;;;N;;;A688;;A688
+A68A;CYRILLIC CAPITAL LETTER TE WITH MIDDLE HOOK;Lu;0;L;;;;;N;;;;A68B;
+A68B;CYRILLIC SMALL LETTER TE WITH MIDDLE HOOK;Ll;0;L;;;;;N;;;A68A;;A68A
+A68C;CYRILLIC CAPITAL LETTER TWE;Lu;0;L;;;;;N;;;;A68D;
+A68D;CYRILLIC SMALL LETTER TWE;Ll;0;L;;;;;N;;;A68C;;A68C
+A68E;CYRILLIC CAPITAL LETTER TSWE;Lu;0;L;;;;;N;;;;A68F;
+A68F;CYRILLIC SMALL LETTER TSWE;Ll;0;L;;;;;N;;;A68E;;A68E
+A690;CYRILLIC CAPITAL LETTER TSSE;Lu;0;L;;;;;N;;;;A691;
+A691;CYRILLIC SMALL LETTER TSSE;Ll;0;L;;;;;N;;;A690;;A690
+A692;CYRILLIC CAPITAL LETTER TCHE;Lu;0;L;;;;;N;;;;A693;
+A693;CYRILLIC SMALL LETTER TCHE;Ll;0;L;;;;;N;;;A692;;A692
+A694;CYRILLIC CAPITAL LETTER HWE;Lu;0;L;;;;;N;;;;A695;
+A695;CYRILLIC SMALL LETTER HWE;Ll;0;L;;;;;N;;;A694;;A694
+A696;CYRILLIC CAPITAL LETTER SHWE;Lu;0;L;;;;;N;;;;A697;
+A697;CYRILLIC SMALL LETTER SHWE;Ll;0;L;;;;;N;;;A696;;A696
+A6A0;BAMUM LETTER A;Lo;0;L;;;;;N;;;;;
+A6A1;BAMUM LETTER KA;Lo;0;L;;;;;N;;;;;
+A6A2;BAMUM LETTER U;Lo;0;L;;;;;N;;;;;
+A6A3;BAMUM LETTER KU;Lo;0;L;;;;;N;;;;;
+A6A4;BAMUM LETTER EE;Lo;0;L;;;;;N;;;;;
+A6A5;BAMUM LETTER REE;Lo;0;L;;;;;N;;;;;
+A6A6;BAMUM LETTER TAE;Lo;0;L;;;;;N;;;;;
+A6A7;BAMUM LETTER O;Lo;0;L;;;;;N;;;;;
+A6A8;BAMUM LETTER NYI;Lo;0;L;;;;;N;;;;;
+A6A9;BAMUM LETTER I;Lo;0;L;;;;;N;;;;;
+A6AA;BAMUM LETTER LA;Lo;0;L;;;;;N;;;;;
+A6AB;BAMUM LETTER PA;Lo;0;L;;;;;N;;;;;
+A6AC;BAMUM LETTER RII;Lo;0;L;;;;;N;;;;;
+A6AD;BAMUM LETTER RIEE;Lo;0;L;;;;;N;;;;;
+A6AE;BAMUM LETTER LEEEE;Lo;0;L;;;;;N;;;;;
+A6AF;BAMUM LETTER MEEEE;Lo;0;L;;;;;N;;;;;
+A6B0;BAMUM LETTER TAA;Lo;0;L;;;;;N;;;;;
+A6B1;BAMUM LETTER NDAA;Lo;0;L;;;;;N;;;;;
+A6B2;BAMUM LETTER NJAEM;Lo;0;L;;;;;N;;;;;
+A6B3;BAMUM LETTER M;Lo;0;L;;;;;N;;;;;
+A6B4;BAMUM LETTER SUU;Lo;0;L;;;;;N;;;;;
+A6B5;BAMUM LETTER MU;Lo;0;L;;;;;N;;;;;
+A6B6;BAMUM LETTER SHII;Lo;0;L;;;;;N;;;;;
+A6B7;BAMUM LETTER SI;Lo;0;L;;;;;N;;;;;
+A6B8;BAMUM LETTER SHEUX;Lo;0;L;;;;;N;;;;;
+A6B9;BAMUM LETTER SEUX;Lo;0;L;;;;;N;;;;;
+A6BA;BAMUM LETTER KYEE;Lo;0;L;;;;;N;;;;;
+A6BB;BAMUM LETTER KET;Lo;0;L;;;;;N;;;;;
+A6BC;BAMUM LETTER NUAE;Lo;0;L;;;;;N;;;;;
+A6BD;BAMUM LETTER NU;Lo;0;L;;;;;N;;;;;
+A6BE;BAMUM LETTER NJUAE;Lo;0;L;;;;;N;;;;;
+A6BF;BAMUM LETTER YOQ;Lo;0;L;;;;;N;;;;;
+A6C0;BAMUM LETTER SHU;Lo;0;L;;;;;N;;;;;
+A6C1;BAMUM LETTER YUQ;Lo;0;L;;;;;N;;;;;
+A6C2;BAMUM LETTER YA;Lo;0;L;;;;;N;;;;;
+A6C3;BAMUM LETTER NSHA;Lo;0;L;;;;;N;;;;;
+A6C4;BAMUM LETTER KEUX;Lo;0;L;;;;;N;;;;;
+A6C5;BAMUM LETTER PEUX;Lo;0;L;;;;;N;;;;;
+A6C6;BAMUM LETTER NJEE;Lo;0;L;;;;;N;;;;;
+A6C7;BAMUM LETTER NTEE;Lo;0;L;;;;;N;;;;;
+A6C8;BAMUM LETTER PUE;Lo;0;L;;;;;N;;;;;
+A6C9;BAMUM LETTER WUE;Lo;0;L;;;;;N;;;;;
+A6CA;BAMUM LETTER PEE;Lo;0;L;;;;;N;;;;;
+A6CB;BAMUM LETTER FEE;Lo;0;L;;;;;N;;;;;
+A6CC;BAMUM LETTER RU;Lo;0;L;;;;;N;;;;;
+A6CD;BAMUM LETTER LU;Lo;0;L;;;;;N;;;;;
+A6CE;BAMUM LETTER MI;Lo;0;L;;;;;N;;;;;
+A6CF;BAMUM LETTER NI;Lo;0;L;;;;;N;;;;;
+A6D0;BAMUM LETTER REUX;Lo;0;L;;;;;N;;;;;
+A6D1;BAMUM LETTER RAE;Lo;0;L;;;;;N;;;;;
+A6D2;BAMUM LETTER KEN;Lo;0;L;;;;;N;;;;;
+A6D3;BAMUM LETTER NGKWAEN;Lo;0;L;;;;;N;;;;;
+A6D4;BAMUM LETTER NGGA;Lo;0;L;;;;;N;;;;;
+A6D5;BAMUM LETTER NGA;Lo;0;L;;;;;N;;;;;
+A6D6;BAMUM LETTER SHO;Lo;0;L;;;;;N;;;;;
+A6D7;BAMUM LETTER PUAE;Lo;0;L;;;;;N;;;;;
+A6D8;BAMUM LETTER FU;Lo;0;L;;;;;N;;;;;
+A6D9;BAMUM LETTER FOM;Lo;0;L;;;;;N;;;;;
+A6DA;BAMUM LETTER WA;Lo;0;L;;;;;N;;;;;
+A6DB;BAMUM LETTER NA;Lo;0;L;;;;;N;;;;;
+A6DC;BAMUM LETTER LI;Lo;0;L;;;;;N;;;;;
+A6DD;BAMUM LETTER PI;Lo;0;L;;;;;N;;;;;
+A6DE;BAMUM LETTER LOQ;Lo;0;L;;;;;N;;;;;
+A6DF;BAMUM LETTER KO;Lo;0;L;;;;;N;;;;;
+A6E0;BAMUM LETTER MBEN;Lo;0;L;;;;;N;;;;;
+A6E1;BAMUM LETTER REN;Lo;0;L;;;;;N;;;;;
+A6E2;BAMUM LETTER MEN;Lo;0;L;;;;;N;;;;;
+A6E3;BAMUM LETTER MA;Lo;0;L;;;;;N;;;;;
+A6E4;BAMUM LETTER TI;Lo;0;L;;;;;N;;;;;
+A6E5;BAMUM LETTER KI;Lo;0;L;;;;;N;;;;;
+A6E6;BAMUM LETTER MO;Nl;0;L;;;;1;N;;;;;
+A6E7;BAMUM LETTER MBAA;Nl;0;L;;;;2;N;;;;;
+A6E8;BAMUM LETTER TET;Nl;0;L;;;;3;N;;;;;
+A6E9;BAMUM LETTER KPA;Nl;0;L;;;;4;N;;;;;
+A6EA;BAMUM LETTER TEN;Nl;0;L;;;;5;N;;;;;
+A6EB;BAMUM LETTER NTUU;Nl;0;L;;;;6;N;;;;;
+A6EC;BAMUM LETTER SAMBA;Nl;0;L;;;;7;N;;;;;
+A6ED;BAMUM LETTER FAAMAE;Nl;0;L;;;;8;N;;;;;
+A6EE;BAMUM LETTER KOVUU;Nl;0;L;;;;9;N;;;;;
+A6EF;BAMUM LETTER KOGHOM;Nl;0;L;;;;0;N;;;;;
+A6F0;BAMUM COMBINING MARK KOQNDON;Mn;230;NSM;;;;;N;;;;;
+A6F1;BAMUM COMBINING MARK TUKWENTIS;Mn;230;NSM;;;;;N;;;;;
+A6F2;BAMUM NJAEMLI;Po;0;L;;;;;N;;;;;
+A6F3;BAMUM FULL STOP;Po;0;L;;;;;N;;;;;
+A6F4;BAMUM COLON;Po;0;L;;;;;N;;;;;
+A6F5;BAMUM COMMA;Po;0;L;;;;;N;;;;;
+A6F6;BAMUM SEMICOLON;Po;0;L;;;;;N;;;;;
+A6F7;BAMUM QUESTION MARK;Po;0;L;;;;;N;;;;;
+A700;MODIFIER LETTER CHINESE TONE YIN PING;Sk;0;ON;;;;;N;;;;;
+A701;MODIFIER LETTER CHINESE TONE YANG PING;Sk;0;ON;;;;;N;;;;;
+A702;MODIFIER LETTER CHINESE TONE YIN SHANG;Sk;0;ON;;;;;N;;;;;
+A703;MODIFIER LETTER CHINESE TONE YANG SHANG;Sk;0;ON;;;;;N;;;;;
+A704;MODIFIER LETTER CHINESE TONE YIN QU;Sk;0;ON;;;;;N;;;;;
+A705;MODIFIER LETTER CHINESE TONE YANG QU;Sk;0;ON;;;;;N;;;;;
+A706;MODIFIER LETTER CHINESE TONE YIN RU;Sk;0;ON;;;;;N;;;;;
+A707;MODIFIER LETTER CHINESE TONE YANG RU;Sk;0;ON;;;;;N;;;;;
+A708;MODIFIER LETTER EXTRA-HIGH DOTTED TONE BAR;Sk;0;ON;;;;;N;;;;;
+A709;MODIFIER LETTER HIGH DOTTED TONE BAR;Sk;0;ON;;;;;N;;;;;
+A70A;MODIFIER LETTER MID DOTTED TONE BAR;Sk;0;ON;;;;;N;;;;;
+A70B;MODIFIER LETTER LOW DOTTED TONE BAR;Sk;0;ON;;;;;N;;;;;
+A70C;MODIFIER LETTER EXTRA-LOW DOTTED TONE BAR;Sk;0;ON;;;;;N;;;;;
+A70D;MODIFIER LETTER EXTRA-HIGH DOTTED LEFT-STEM TONE BAR;Sk;0;ON;;;;;N;;;;;
+A70E;MODIFIER LETTER HIGH DOTTED LEFT-STEM TONE BAR;Sk;0;ON;;;;;N;;;;;
+A70F;MODIFIER LETTER MID DOTTED LEFT-STEM TONE BAR;Sk;0;ON;;;;;N;;;;;
+A710;MODIFIER LETTER LOW DOTTED LEFT-STEM TONE BAR;Sk;0;ON;;;;;N;;;;;
+A711;MODIFIER LETTER EXTRA-LOW DOTTED LEFT-STEM TONE BAR;Sk;0;ON;;;;;N;;;;;
+A712;MODIFIER LETTER EXTRA-HIGH LEFT-STEM TONE BAR;Sk;0;ON;;;;;N;;;;;
+A713;MODIFIER LETTER HIGH LEFT-STEM TONE BAR;Sk;0;ON;;;;;N;;;;;
+A714;MODIFIER LETTER MID LEFT-STEM TONE BAR;Sk;0;ON;;;;;N;;;;;
+A715;MODIFIER LETTER LOW LEFT-STEM TONE BAR;Sk;0;ON;;;;;N;;;;;
+A716;MODIFIER LETTER EXTRA-LOW LEFT-STEM TONE BAR;Sk;0;ON;;;;;N;;;;;
+A717;MODIFIER LETTER DOT VERTICAL BAR;Lm;0;ON;;;;;N;;;;;
+A718;MODIFIER LETTER DOT SLASH;Lm;0;ON;;;;;N;;;;;
+A719;MODIFIER LETTER DOT HORIZONTAL BAR;Lm;0;ON;;;;;N;;;;;
+A71A;MODIFIER LETTER LOWER RIGHT CORNER ANGLE;Lm;0;ON;;;;;N;;;;;
+A71B;MODIFIER LETTER RAISED UP ARROW;Lm;0;ON;;;;;N;;;;;
+A71C;MODIFIER LETTER RAISED DOWN ARROW;Lm;0;ON;;;;;N;;;;;
+A71D;MODIFIER LETTER RAISED EXCLAMATION MARK;Lm;0;ON;;;;;N;;;;;
+A71E;MODIFIER LETTER RAISED INVERTED EXCLAMATION MARK;Lm;0;ON;;;;;N;;;;;
+A71F;MODIFIER LETTER LOW INVERTED EXCLAMATION MARK;Lm;0;ON;;;;;N;;;;;
+A720;MODIFIER LETTER STRESS AND HIGH TONE;Sk;0;ON;;;;;N;;;;;
+A721;MODIFIER LETTER STRESS AND LOW TONE;Sk;0;ON;;;;;N;;;;;
+A722;LATIN CAPITAL LETTER EGYPTOLOGICAL ALEF;Lu;0;L;;;;;N;;;;A723;
+A723;LATIN SMALL LETTER EGYPTOLOGICAL ALEF;Ll;0;L;;;;;N;;;A722;;A722
+A724;LATIN CAPITAL LETTER EGYPTOLOGICAL AIN;Lu;0;L;;;;;N;;;;A725;
+A725;LATIN SMALL LETTER EGYPTOLOGICAL AIN;Ll;0;L;;;;;N;;;A724;;A724
+A726;LATIN CAPITAL LETTER HENG;Lu;0;L;;;;;N;;;;A727;
+A727;LATIN SMALL LETTER HENG;Ll;0;L;;;;;N;;;A726;;A726
+A728;LATIN CAPITAL LETTER TZ;Lu;0;L;;;;;N;;;;A729;
+A729;LATIN SMALL LETTER TZ;Ll;0;L;;;;;N;;;A728;;A728
+A72A;LATIN CAPITAL LETTER TRESILLO;Lu;0;L;;;;;N;;;;A72B;
+A72B;LATIN SMALL LETTER TRESILLO;Ll;0;L;;;;;N;;;A72A;;A72A
+A72C;LATIN CAPITAL LETTER CUATRILLO;Lu;0;L;;;;;N;;;;A72D;
+A72D;LATIN SMALL LETTER CUATRILLO;Ll;0;L;;;;;N;;;A72C;;A72C
+A72E;LATIN CAPITAL LETTER CUATRILLO WITH COMMA;Lu;0;L;;;;;N;;;;A72F;
+A72F;LATIN SMALL LETTER CUATRILLO WITH COMMA;Ll;0;L;;;;;N;;;A72E;;A72E
+A730;LATIN LETTER SMALL CAPITAL F;Ll;0;L;;;;;N;;;;;
+A731;LATIN LETTER SMALL CAPITAL S;Ll;0;L;;;;;N;;;;;
+A732;LATIN CAPITAL LETTER AA;Lu;0;L;;;;;N;;;;A733;
+A733;LATIN SMALL LETTER AA;Ll;0;L;;;;;N;;;A732;;A732
+A734;LATIN CAPITAL LETTER AO;Lu;0;L;;;;;N;;;;A735;
+A735;LATIN SMALL LETTER AO;Ll;0;L;;;;;N;;;A734;;A734
+A736;LATIN CAPITAL LETTER AU;Lu;0;L;;;;;N;;;;A737;
+A737;LATIN SMALL LETTER AU;Ll;0;L;;;;;N;;;A736;;A736
+A738;LATIN CAPITAL LETTER AV;Lu;0;L;;;;;N;;;;A739;
+A739;LATIN SMALL LETTER AV;Ll;0;L;;;;;N;;;A738;;A738
+A73A;LATIN CAPITAL LETTER AV WITH HORIZONTAL BAR;Lu;0;L;;;;;N;;;;A73B;
+A73B;LATIN SMALL LETTER AV WITH HORIZONTAL BAR;Ll;0;L;;;;;N;;;A73A;;A73A
+A73C;LATIN CAPITAL LETTER AY;Lu;0;L;;;;;N;;;;A73D;
+A73D;LATIN SMALL LETTER AY;Ll;0;L;;;;;N;;;A73C;;A73C
+A73E;LATIN CAPITAL LETTER REVERSED C WITH DOT;Lu;0;L;;;;;N;;;;A73F;
+A73F;LATIN SMALL LETTER REVERSED C WITH DOT;Ll;0;L;;;;;N;;;A73E;;A73E
+A740;LATIN CAPITAL LETTER K WITH STROKE;Lu;0;L;;;;;N;;;;A741;
+A741;LATIN SMALL LETTER K WITH STROKE;Ll;0;L;;;;;N;;;A740;;A740
+A742;LATIN CAPITAL LETTER K WITH DIAGONAL STROKE;Lu;0;L;;;;;N;;;;A743;
+A743;LATIN SMALL LETTER K WITH DIAGONAL STROKE;Ll;0;L;;;;;N;;;A742;;A742
+A744;LATIN CAPITAL LETTER K WITH STROKE AND DIAGONAL STROKE;Lu;0;L;;;;;N;;;;A745;
+A745;LATIN SMALL LETTER K WITH STROKE AND DIAGONAL STROKE;Ll;0;L;;;;;N;;;A744;;A744
+A746;LATIN CAPITAL LETTER BROKEN L;Lu;0;L;;;;;N;;;;A747;
+A747;LATIN SMALL LETTER BROKEN L;Ll;0;L;;;;;N;;;A746;;A746
+A748;LATIN CAPITAL LETTER L WITH HIGH STROKE;Lu;0;L;;;;;N;;;;A749;
+A749;LATIN SMALL LETTER L WITH HIGH STROKE;Ll;0;L;;;;;N;;;A748;;A748
+A74A;LATIN CAPITAL LETTER O WITH LONG STROKE OVERLAY;Lu;0;L;;;;;N;;;;A74B;
+A74B;LATIN SMALL LETTER O WITH LONG STROKE OVERLAY;Ll;0;L;;;;;N;;;A74A;;A74A
+A74C;LATIN CAPITAL LETTER O WITH LOOP;Lu;0;L;;;;;N;;;;A74D;
+A74D;LATIN SMALL LETTER O WITH LOOP;Ll;0;L;;;;;N;;;A74C;;A74C
+A74E;LATIN CAPITAL LETTER OO;Lu;0;L;;;;;N;;;;A74F;
+A74F;LATIN SMALL LETTER OO;Ll;0;L;;;;;N;;;A74E;;A74E
+A750;LATIN CAPITAL LETTER P WITH STROKE THROUGH DESCENDER;Lu;0;L;;;;;N;;;;A751;
+A751;LATIN SMALL LETTER P WITH STROKE THROUGH DESCENDER;Ll;0;L;;;;;N;;;A750;;A750
+A752;LATIN CAPITAL LETTER P WITH FLOURISH;Lu;0;L;;;;;N;;;;A753;
+A753;LATIN SMALL LETTER P WITH FLOURISH;Ll;0;L;;;;;N;;;A752;;A752
+A754;LATIN CAPITAL LETTER P WITH SQUIRREL TAIL;Lu;0;L;;;;;N;;;;A755;
+A755;LATIN SMALL LETTER P WITH SQUIRREL TAIL;Ll;0;L;;;;;N;;;A754;;A754
+A756;LATIN CAPITAL LETTER Q WITH STROKE THROUGH DESCENDER;Lu;0;L;;;;;N;;;;A757;
+A757;LATIN SMALL LETTER Q WITH STROKE THROUGH DESCENDER;Ll;0;L;;;;;N;;;A756;;A756
+A758;LATIN CAPITAL LETTER Q WITH DIAGONAL STROKE;Lu;0;L;;;;;N;;;;A759;
+A759;LATIN SMALL LETTER Q WITH DIAGONAL STROKE;Ll;0;L;;;;;N;;;A758;;A758
+A75A;LATIN CAPITAL LETTER R ROTUNDA;Lu;0;L;;;;;N;;;;A75B;
+A75B;LATIN SMALL LETTER R ROTUNDA;Ll;0;L;;;;;N;;;A75A;;A75A
+A75C;LATIN CAPITAL LETTER RUM ROTUNDA;Lu;0;L;;;;;N;;;;A75D;
+A75D;LATIN SMALL LETTER RUM ROTUNDA;Ll;0;L;;;;;N;;;A75C;;A75C
+A75E;LATIN CAPITAL LETTER V WITH DIAGONAL STROKE;Lu;0;L;;;;;N;;;;A75F;
+A75F;LATIN SMALL LETTER V WITH DIAGONAL STROKE;Ll;0;L;;;;;N;;;A75E;;A75E
+A760;LATIN CAPITAL LETTER VY;Lu;0;L;;;;;N;;;;A761;
+A761;LATIN SMALL LETTER VY;Ll;0;L;;;;;N;;;A760;;A760
+A762;LATIN CAPITAL LETTER VISIGOTHIC Z;Lu;0;L;;;;;N;;;;A763;
+A763;LATIN SMALL LETTER VISIGOTHIC Z;Ll;0;L;;;;;N;;;A762;;A762
+A764;LATIN CAPITAL LETTER THORN WITH STROKE;Lu;0;L;;;;;N;;;;A765;
+A765;LATIN SMALL LETTER THORN WITH STROKE;Ll;0;L;;;;;N;;;A764;;A764
+A766;LATIN CAPITAL LETTER THORN WITH STROKE THROUGH DESCENDER;Lu;0;L;;;;;N;;;;A767;
+A767;LATIN SMALL LETTER THORN WITH STROKE THROUGH DESCENDER;Ll;0;L;;;;;N;;;A766;;A766
+A768;LATIN CAPITAL LETTER VEND;Lu;0;L;;;;;N;;;;A769;
+A769;LATIN SMALL LETTER VEND;Ll;0;L;;;;;N;;;A768;;A768
+A76A;LATIN CAPITAL LETTER ET;Lu;0;L;;;;;N;;;;A76B;
+A76B;LATIN SMALL LETTER ET;Ll;0;L;;;;;N;;;A76A;;A76A
+A76C;LATIN CAPITAL LETTER IS;Lu;0;L;;;;;N;;;;A76D;
+A76D;LATIN SMALL LETTER IS;Ll;0;L;;;;;N;;;A76C;;A76C
+A76E;LATIN CAPITAL LETTER CON;Lu;0;L;;;;;N;;;;A76F;
+A76F;LATIN SMALL LETTER CON;Ll;0;L;;;;;N;;;A76E;;A76E
+A770;MODIFIER LETTER US;Lm;0;L;<super> A76F;;;;N;;;;;
+A771;LATIN SMALL LETTER DUM;Ll;0;L;;;;;N;;;;;
+A772;LATIN SMALL LETTER LUM;Ll;0;L;;;;;N;;;;;
+A773;LATIN SMALL LETTER MUM;Ll;0;L;;;;;N;;;;;
+A774;LATIN SMALL LETTER NUM;Ll;0;L;;;;;N;;;;;
+A775;LATIN SMALL LETTER RUM;Ll;0;L;;;;;N;;;;;
+A776;LATIN LETTER SMALL CAPITAL RUM;Ll;0;L;;;;;N;;;;;
+A777;LATIN SMALL LETTER TUM;Ll;0;L;;;;;N;;;;;
+A778;LATIN SMALL LETTER UM;Ll;0;L;;;;;N;;;;;
+A779;LATIN CAPITAL LETTER INSULAR D;Lu;0;L;;;;;N;;;;A77A;
+A77A;LATIN SMALL LETTER INSULAR D;Ll;0;L;;;;;N;;;A779;;A779
+A77B;LATIN CAPITAL LETTER INSULAR F;Lu;0;L;;;;;N;;;;A77C;
+A77C;LATIN SMALL LETTER INSULAR F;Ll;0;L;;;;;N;;;A77B;;A77B
+A77D;LATIN CAPITAL LETTER INSULAR G;Lu;0;L;;;;;N;;;;1D79;
+A77E;LATIN CAPITAL LETTER TURNED INSULAR G;Lu;0;L;;;;;N;;;;A77F;
+A77F;LATIN SMALL LETTER TURNED INSULAR G;Ll;0;L;;;;;N;;;A77E;;A77E
+A780;LATIN CAPITAL LETTER TURNED L;Lu;0;L;;;;;N;;;;A781;
+A781;LATIN SMALL LETTER TURNED L;Ll;0;L;;;;;N;;;A780;;A780
+A782;LATIN CAPITAL LETTER INSULAR R;Lu;0;L;;;;;N;;;;A783;
+A783;LATIN SMALL LETTER INSULAR R;Ll;0;L;;;;;N;;;A782;;A782
+A784;LATIN CAPITAL LETTER INSULAR S;Lu;0;L;;;;;N;;;;A785;
+A785;LATIN SMALL LETTER INSULAR S;Ll;0;L;;;;;N;;;A784;;A784
+A786;LATIN CAPITAL LETTER INSULAR T;Lu;0;L;;;;;N;;;;A787;
+A787;LATIN SMALL LETTER INSULAR T;Ll;0;L;;;;;N;;;A786;;A786
+A788;MODIFIER LETTER LOW CIRCUMFLEX ACCENT;Lm;0;ON;;;;;N;;;;;
+A789;MODIFIER LETTER COLON;Sk;0;L;;;;;N;;;;;
+A78A;MODIFIER LETTER SHORT EQUALS SIGN;Sk;0;L;;;;;N;;;;;
+A78B;LATIN CAPITAL LETTER SALTILLO;Lu;0;L;;;;;N;;;;A78C;
+A78C;LATIN SMALL LETTER SALTILLO;Ll;0;L;;;;;N;;;A78B;;A78B
+A78D;LATIN CAPITAL LETTER TURNED H;Lu;0;L;;;;;N;;;;0265;
+A78E;LATIN SMALL LETTER L WITH RETROFLEX HOOK AND BELT;Ll;0;L;;;;;N;;;;;
+A790;LATIN CAPITAL LETTER N WITH DESCENDER;Lu;0;L;;;;;N;;;;A791;
+A791;LATIN SMALL LETTER N WITH DESCENDER;Ll;0;L;;;;;N;;;A790;;A790
+A7A0;LATIN CAPITAL LETTER G WITH OBLIQUE STROKE;Lu;0;L;;;;;N;;;;A7A1;
+A7A1;LATIN SMALL LETTER G WITH OBLIQUE STROKE;Ll;0;L;;;;;N;;;A7A0;;A7A0
+A7A2;LATIN CAPITAL LETTER K WITH OBLIQUE STROKE;Lu;0;L;;;;;N;;;;A7A3;
+A7A3;LATIN SMALL LETTER K WITH OBLIQUE STROKE;Ll;0;L;;;;;N;;;A7A2;;A7A2
+A7A4;LATIN CAPITAL LETTER N WITH OBLIQUE STROKE;Lu;0;L;;;;;N;;;;A7A5;
+A7A5;LATIN SMALL LETTER N WITH OBLIQUE STROKE;Ll;0;L;;;;;N;;;A7A4;;A7A4
+A7A6;LATIN CAPITAL LETTER R WITH OBLIQUE STROKE;Lu;0;L;;;;;N;;;;A7A7;
+A7A7;LATIN SMALL LETTER R WITH OBLIQUE STROKE;Ll;0;L;;;;;N;;;A7A6;;A7A6
+A7A8;LATIN CAPITAL LETTER S WITH OBLIQUE STROKE;Lu;0;L;;;;;N;;;;A7A9;
+A7A9;LATIN SMALL LETTER S WITH OBLIQUE STROKE;Ll;0;L;;;;;N;;;A7A8;;A7A8
+A7FA;LATIN LETTER SMALL CAPITAL TURNED M;Ll;0;L;;;;;N;;;;;
+A7FB;LATIN EPIGRAPHIC LETTER REVERSED F;Lo;0;L;;;;;N;;;;;
+A7FC;LATIN EPIGRAPHIC LETTER REVERSED P;Lo;0;L;;;;;N;;;;;
+A7FD;LATIN EPIGRAPHIC LETTER INVERTED M;Lo;0;L;;;;;N;;;;;
+A7FE;LATIN EPIGRAPHIC LETTER I LONGA;Lo;0;L;;;;;N;;;;;
+A7FF;LATIN EPIGRAPHIC LETTER ARCHAIC M;Lo;0;L;;;;;N;;;;;
+A800;SYLOTI NAGRI LETTER A;Lo;0;L;;;;;N;;;;;
+A801;SYLOTI NAGRI LETTER I;Lo;0;L;;;;;N;;;;;
+A802;SYLOTI NAGRI SIGN DVISVARA;Mn;0;NSM;;;;;N;;;;;
+A803;SYLOTI NAGRI LETTER U;Lo;0;L;;;;;N;;;;;
+A804;SYLOTI NAGRI LETTER E;Lo;0;L;;;;;N;;;;;
+A805;SYLOTI NAGRI LETTER O;Lo;0;L;;;;;N;;;;;
+A806;SYLOTI NAGRI SIGN HASANTA;Mn;9;NSM;;;;;N;;;;;
+A807;SYLOTI NAGRI LETTER KO;Lo;0;L;;;;;N;;;;;
+A808;SYLOTI NAGRI LETTER KHO;Lo;0;L;;;;;N;;;;;
+A809;SYLOTI NAGRI LETTER GO;Lo;0;L;;;;;N;;;;;
+A80A;SYLOTI NAGRI LETTER GHO;Lo;0;L;;;;;N;;;;;
+A80B;SYLOTI NAGRI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;
+A80C;SYLOTI NAGRI LETTER CO;Lo;0;L;;;;;N;;;;;
+A80D;SYLOTI NAGRI LETTER CHO;Lo;0;L;;;;;N;;;;;
+A80E;SYLOTI NAGRI LETTER JO;Lo;0;L;;;;;N;;;;;
+A80F;SYLOTI NAGRI LETTER JHO;Lo;0;L;;;;;N;;;;;
+A810;SYLOTI NAGRI LETTER TTO;Lo;0;L;;;;;N;;;;;
+A811;SYLOTI NAGRI LETTER TTHO;Lo;0;L;;;;;N;;;;;
+A812;SYLOTI NAGRI LETTER DDO;Lo;0;L;;;;;N;;;;;
+A813;SYLOTI NAGRI LETTER DDHO;Lo;0;L;;;;;N;;;;;
+A814;SYLOTI NAGRI LETTER TO;Lo;0;L;;;;;N;;;;;
+A815;SYLOTI NAGRI LETTER THO;Lo;0;L;;;;;N;;;;;
+A816;SYLOTI NAGRI LETTER DO;Lo;0;L;;;;;N;;;;;
+A817;SYLOTI NAGRI LETTER DHO;Lo;0;L;;;;;N;;;;;
+A818;SYLOTI NAGRI LETTER NO;Lo;0;L;;;;;N;;;;;
+A819;SYLOTI NAGRI LETTER PO;Lo;0;L;;;;;N;;;;;
+A81A;SYLOTI NAGRI LETTER PHO;Lo;0;L;;;;;N;;;;;
+A81B;SYLOTI NAGRI LETTER BO;Lo;0;L;;;;;N;;;;;
+A81C;SYLOTI NAGRI LETTER BHO;Lo;0;L;;;;;N;;;;;
+A81D;SYLOTI NAGRI LETTER MO;Lo;0;L;;;;;N;;;;;
+A81E;SYLOTI NAGRI LETTER RO;Lo;0;L;;;;;N;;;;;
+A81F;SYLOTI NAGRI LETTER LO;Lo;0;L;;;;;N;;;;;
+A820;SYLOTI NAGRI LETTER RRO;Lo;0;L;;;;;N;;;;;
+A821;SYLOTI NAGRI LETTER SO;Lo;0;L;;;;;N;;;;;
+A822;SYLOTI NAGRI LETTER HO;Lo;0;L;;;;;N;;;;;
+A823;SYLOTI NAGRI VOWEL SIGN A;Mc;0;L;;;;;N;;;;;
+A824;SYLOTI NAGRI VOWEL SIGN I;Mc;0;L;;;;;N;;;;;
+A825;SYLOTI NAGRI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+A826;SYLOTI NAGRI VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;;
+A827;SYLOTI NAGRI VOWEL SIGN OO;Mc;0;L;;;;;N;;;;;
+A828;SYLOTI NAGRI POETRY MARK-1;So;0;ON;;;;;N;;;;;
+A829;SYLOTI NAGRI POETRY MARK-2;So;0;ON;;;;;N;;;;;
+A82A;SYLOTI NAGRI POETRY MARK-3;So;0;ON;;;;;N;;;;;
+A82B;SYLOTI NAGRI POETRY MARK-4;So;0;ON;;;;;N;;;;;
+A830;NORTH INDIC FRACTION ONE QUARTER;No;0;L;;;;1/4;N;;;;;
+A831;NORTH INDIC FRACTION ONE HALF;No;0;L;;;;1/2;N;;;;;
+A832;NORTH INDIC FRACTION THREE QUARTERS;No;0;L;;;;3/4;N;;;;;
+A833;NORTH INDIC FRACTION ONE SIXTEENTH;No;0;L;;;;1/16;N;;;;;
+A834;NORTH INDIC FRACTION ONE EIGHTH;No;0;L;;;;1/8;N;;;;;
+A835;NORTH INDIC FRACTION THREE SIXTEENTHS;No;0;L;;;;3/16;N;;;;;
+A836;NORTH INDIC QUARTER MARK;So;0;L;;;;;N;;;;;
+A837;NORTH INDIC PLACEHOLDER MARK;So;0;L;;;;;N;;;;;
+A838;NORTH INDIC RUPEE MARK;Sc;0;ET;;;;;N;;;;;
+A839;NORTH INDIC QUANTITY MARK;So;0;ET;;;;;N;;;;;
+A840;PHAGS-PA LETTER KA;Lo;0;L;;;;;N;;;;;
+A841;PHAGS-PA LETTER KHA;Lo;0;L;;;;;N;;;;;
+A842;PHAGS-PA LETTER GA;Lo;0;L;;;;;N;;;;;
+A843;PHAGS-PA LETTER NGA;Lo;0;L;;;;;N;;;;;
+A844;PHAGS-PA LETTER CA;Lo;0;L;;;;;N;;;;;
+A845;PHAGS-PA LETTER CHA;Lo;0;L;;;;;N;;;;;
+A846;PHAGS-PA LETTER JA;Lo;0;L;;;;;N;;;;;
+A847;PHAGS-PA LETTER NYA;Lo;0;L;;;;;N;;;;;
+A848;PHAGS-PA LETTER TA;Lo;0;L;;;;;N;;;;;
+A849;PHAGS-PA LETTER THA;Lo;0;L;;;;;N;;;;;
+A84A;PHAGS-PA LETTER DA;Lo;0;L;;;;;N;;;;;
+A84B;PHAGS-PA LETTER NA;Lo;0;L;;;;;N;;;;;
+A84C;PHAGS-PA LETTER PA;Lo;0;L;;;;;N;;;;;
+A84D;PHAGS-PA LETTER PHA;Lo;0;L;;;;;N;;;;;
+A84E;PHAGS-PA LETTER BA;Lo;0;L;;;;;N;;;;;
+A84F;PHAGS-PA LETTER MA;Lo;0;L;;;;;N;;;;;
+A850;PHAGS-PA LETTER TSA;Lo;0;L;;;;;N;;;;;
+A851;PHAGS-PA LETTER TSHA;Lo;0;L;;;;;N;;;;;
+A852;PHAGS-PA LETTER DZA;Lo;0;L;;;;;N;;;;;
+A853;PHAGS-PA LETTER WA;Lo;0;L;;;;;N;;;;;
+A854;PHAGS-PA LETTER ZHA;Lo;0;L;;;;;N;;;;;
+A855;PHAGS-PA LETTER ZA;Lo;0;L;;;;;N;;;;;
+A856;PHAGS-PA LETTER SMALL A;Lo;0;L;;;;;N;;;;;
+A857;PHAGS-PA LETTER YA;Lo;0;L;;;;;N;;;;;
+A858;PHAGS-PA LETTER RA;Lo;0;L;;;;;N;;;;;
+A859;PHAGS-PA LETTER LA;Lo;0;L;;;;;N;;;;;
+A85A;PHAGS-PA LETTER SHA;Lo;0;L;;;;;N;;;;;
+A85B;PHAGS-PA LETTER SA;Lo;0;L;;;;;N;;;;;
+A85C;PHAGS-PA LETTER HA;Lo;0;L;;;;;N;;;;;
+A85D;PHAGS-PA LETTER A;Lo;0;L;;;;;N;;;;;
+A85E;PHAGS-PA LETTER I;Lo;0;L;;;;;N;;;;;
+A85F;PHAGS-PA LETTER U;Lo;0;L;;;;;N;;;;;
+A860;PHAGS-PA LETTER E;Lo;0;L;;;;;N;;;;;
+A861;PHAGS-PA LETTER O;Lo;0;L;;;;;N;;;;;
+A862;PHAGS-PA LETTER QA;Lo;0;L;;;;;N;;;;;
+A863;PHAGS-PA LETTER XA;Lo;0;L;;;;;N;;;;;
+A864;PHAGS-PA LETTER FA;Lo;0;L;;;;;N;;;;;
+A865;PHAGS-PA LETTER GGA;Lo;0;L;;;;;N;;;;;
+A866;PHAGS-PA LETTER EE;Lo;0;L;;;;;N;;;;;
+A867;PHAGS-PA SUBJOINED LETTER WA;Lo;0;L;;;;;N;;;;;
+A868;PHAGS-PA SUBJOINED LETTER YA;Lo;0;L;;;;;N;;;;;
+A869;PHAGS-PA LETTER TTA;Lo;0;L;;;;;N;;;;;
+A86A;PHAGS-PA LETTER TTHA;Lo;0;L;;;;;N;;;;;
+A86B;PHAGS-PA LETTER DDA;Lo;0;L;;;;;N;;;;;
+A86C;PHAGS-PA LETTER NNA;Lo;0;L;;;;;N;;;;;
+A86D;PHAGS-PA LETTER ALTERNATE YA;Lo;0;L;;;;;N;;;;;
+A86E;PHAGS-PA LETTER VOICELESS SHA;Lo;0;L;;;;;N;;;;;
+A86F;PHAGS-PA LETTER VOICED HA;Lo;0;L;;;;;N;;;;;
+A870;PHAGS-PA LETTER ASPIRATED FA;Lo;0;L;;;;;N;;;;;
+A871;PHAGS-PA SUBJOINED LETTER RA;Lo;0;L;;;;;N;;;;;
+A872;PHAGS-PA SUPERFIXED LETTER RA;Lo;0;L;;;;;N;;;;;
+A873;PHAGS-PA LETTER CANDRABINDU;Lo;0;L;;;;;N;;;;;
+A874;PHAGS-PA SINGLE HEAD MARK;Po;0;ON;;;;;N;;;;;
+A875;PHAGS-PA DOUBLE HEAD MARK;Po;0;ON;;;;;N;;;;;
+A876;PHAGS-PA MARK SHAD;Po;0;ON;;;;;N;;;;;
+A877;PHAGS-PA MARK DOUBLE SHAD;Po;0;ON;;;;;N;;;;;
+A880;SAURASHTRA SIGN ANUSVARA;Mc;0;L;;;;;N;;;;;
+A881;SAURASHTRA SIGN VISARGA;Mc;0;L;;;;;N;;;;;
+A882;SAURASHTRA LETTER A;Lo;0;L;;;;;N;;;;;
+A883;SAURASHTRA LETTER AA;Lo;0;L;;;;;N;;;;;
+A884;SAURASHTRA LETTER I;Lo;0;L;;;;;N;;;;;
+A885;SAURASHTRA LETTER II;Lo;0;L;;;;;N;;;;;
+A886;SAURASHTRA LETTER U;Lo;0;L;;;;;N;;;;;
+A887;SAURASHTRA LETTER UU;Lo;0;L;;;;;N;;;;;
+A888;SAURASHTRA LETTER VOCALIC R;Lo;0;L;;;;;N;;;;;
+A889;SAURASHTRA LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;;
+A88A;SAURASHTRA LETTER VOCALIC L;Lo;0;L;;;;;N;;;;;
+A88B;SAURASHTRA LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;;
+A88C;SAURASHTRA LETTER E;Lo;0;L;;;;;N;;;;;
+A88D;SAURASHTRA LETTER EE;Lo;0;L;;;;;N;;;;;
+A88E;SAURASHTRA LETTER AI;Lo;0;L;;;;;N;;;;;
+A88F;SAURASHTRA LETTER O;Lo;0;L;;;;;N;;;;;
+A890;SAURASHTRA LETTER OO;Lo;0;L;;;;;N;;;;;
+A891;SAURASHTRA LETTER AU;Lo;0;L;;;;;N;;;;;
+A892;SAURASHTRA LETTER KA;Lo;0;L;;;;;N;;;;;
+A893;SAURASHTRA LETTER KHA;Lo;0;L;;;;;N;;;;;
+A894;SAURASHTRA LETTER GA;Lo;0;L;;;;;N;;;;;
+A895;SAURASHTRA LETTER GHA;Lo;0;L;;;;;N;;;;;
+A896;SAURASHTRA LETTER NGA;Lo;0;L;;;;;N;;;;;
+A897;SAURASHTRA LETTER CA;Lo;0;L;;;;;N;;;;;
+A898;SAURASHTRA LETTER CHA;Lo;0;L;;;;;N;;;;;
+A899;SAURASHTRA LETTER JA;Lo;0;L;;;;;N;;;;;
+A89A;SAURASHTRA LETTER JHA;Lo;0;L;;;;;N;;;;;
+A89B;SAURASHTRA LETTER NYA;Lo;0;L;;;;;N;;;;;
+A89C;SAURASHTRA LETTER TTA;Lo;0;L;;;;;N;;;;;
+A89D;SAURASHTRA LETTER TTHA;Lo;0;L;;;;;N;;;;;
+A89E;SAURASHTRA LETTER DDA;Lo;0;L;;;;;N;;;;;
+A89F;SAURASHTRA LETTER DDHA;Lo;0;L;;;;;N;;;;;
+A8A0;SAURASHTRA LETTER NNA;Lo;0;L;;;;;N;;;;;
+A8A1;SAURASHTRA LETTER TA;Lo;0;L;;;;;N;;;;;
+A8A2;SAURASHTRA LETTER THA;Lo;0;L;;;;;N;;;;;
+A8A3;SAURASHTRA LETTER DA;Lo;0;L;;;;;N;;;;;
+A8A4;SAURASHTRA LETTER DHA;Lo;0;L;;;;;N;;;;;
+A8A5;SAURASHTRA LETTER NA;Lo;0;L;;;;;N;;;;;
+A8A6;SAURASHTRA LETTER PA;Lo;0;L;;;;;N;;;;;
+A8A7;SAURASHTRA LETTER PHA;Lo;0;L;;;;;N;;;;;
+A8A8;SAURASHTRA LETTER BA;Lo;0;L;;;;;N;;;;;
+A8A9;SAURASHTRA LETTER BHA;Lo;0;L;;;;;N;;;;;
+A8AA;SAURASHTRA LETTER MA;Lo;0;L;;;;;N;;;;;
+A8AB;SAURASHTRA LETTER YA;Lo;0;L;;;;;N;;;;;
+A8AC;SAURASHTRA LETTER RA;Lo;0;L;;;;;N;;;;;
+A8AD;SAURASHTRA LETTER LA;Lo;0;L;;;;;N;;;;;
+A8AE;SAURASHTRA LETTER VA;Lo;0;L;;;;;N;;;;;
+A8AF;SAURASHTRA LETTER SHA;Lo;0;L;;;;;N;;;;;
+A8B0;SAURASHTRA LETTER SSA;Lo;0;L;;;;;N;;;;;
+A8B1;SAURASHTRA LETTER SA;Lo;0;L;;;;;N;;;;;
+A8B2;SAURASHTRA LETTER HA;Lo;0;L;;;;;N;;;;;
+A8B3;SAURASHTRA LETTER LLA;Lo;0;L;;;;;N;;;;;
+A8B4;SAURASHTRA CONSONANT SIGN HAARU;Mc;0;L;;;;;N;;;;;
+A8B5;SAURASHTRA VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
+A8B6;SAURASHTRA VOWEL SIGN I;Mc;0;L;;;;;N;;;;;
+A8B7;SAURASHTRA VOWEL SIGN II;Mc;0;L;;;;;N;;;;;
+A8B8;SAURASHTRA VOWEL SIGN U;Mc;0;L;;;;;N;;;;;
+A8B9;SAURASHTRA VOWEL SIGN UU;Mc;0;L;;;;;N;;;;;
+A8BA;SAURASHTRA VOWEL SIGN VOCALIC R;Mc;0;L;;;;;N;;;;;
+A8BB;SAURASHTRA VOWEL SIGN VOCALIC RR;Mc;0;L;;;;;N;;;;;
+A8BC;SAURASHTRA VOWEL SIGN VOCALIC L;Mc;0;L;;;;;N;;;;;
+A8BD;SAURASHTRA VOWEL SIGN VOCALIC LL;Mc;0;L;;;;;N;;;;;
+A8BE;SAURASHTRA VOWEL SIGN E;Mc;0;L;;;;;N;;;;;
+A8BF;SAURASHTRA VOWEL SIGN EE;Mc;0;L;;;;;N;;;;;
+A8C0;SAURASHTRA VOWEL SIGN AI;Mc;0;L;;;;;N;;;;;
+A8C1;SAURASHTRA VOWEL SIGN O;Mc;0;L;;;;;N;;;;;
+A8C2;SAURASHTRA VOWEL SIGN OO;Mc;0;L;;;;;N;;;;;
+A8C3;SAURASHTRA VOWEL SIGN AU;Mc;0;L;;;;;N;;;;;
+A8C4;SAURASHTRA SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;
+A8CE;SAURASHTRA DANDA;Po;0;L;;;;;N;;;;;
+A8CF;SAURASHTRA DOUBLE DANDA;Po;0;L;;;;;N;;;;;
+A8D0;SAURASHTRA DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+A8D1;SAURASHTRA DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+A8D2;SAURASHTRA DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+A8D3;SAURASHTRA DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+A8D4;SAURASHTRA DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+A8D5;SAURASHTRA DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+A8D6;SAURASHTRA DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+A8D7;SAURASHTRA DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+A8D8;SAURASHTRA DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+A8D9;SAURASHTRA DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+A8E0;COMBINING DEVANAGARI DIGIT ZERO;Mn;230;NSM;;;;;N;;;;;
+A8E1;COMBINING DEVANAGARI DIGIT ONE;Mn;230;NSM;;;;;N;;;;;
+A8E2;COMBINING DEVANAGARI DIGIT TWO;Mn;230;NSM;;;;;N;;;;;
+A8E3;COMBINING DEVANAGARI DIGIT THREE;Mn;230;NSM;;;;;N;;;;;
+A8E4;COMBINING DEVANAGARI DIGIT FOUR;Mn;230;NSM;;;;;N;;;;;
+A8E5;COMBINING DEVANAGARI DIGIT FIVE;Mn;230;NSM;;;;;N;;;;;
+A8E6;COMBINING DEVANAGARI DIGIT SIX;Mn;230;NSM;;;;;N;;;;;
+A8E7;COMBINING DEVANAGARI DIGIT SEVEN;Mn;230;NSM;;;;;N;;;;;
+A8E8;COMBINING DEVANAGARI DIGIT EIGHT;Mn;230;NSM;;;;;N;;;;;
+A8E9;COMBINING DEVANAGARI DIGIT NINE;Mn;230;NSM;;;;;N;;;;;
+A8EA;COMBINING DEVANAGARI LETTER A;Mn;230;NSM;;;;;N;;;;;
+A8EB;COMBINING DEVANAGARI LETTER U;Mn;230;NSM;;;;;N;;;;;
+A8EC;COMBINING DEVANAGARI LETTER KA;Mn;230;NSM;;;;;N;;;;;
+A8ED;COMBINING DEVANAGARI LETTER NA;Mn;230;NSM;;;;;N;;;;;
+A8EE;COMBINING DEVANAGARI LETTER PA;Mn;230;NSM;;;;;N;;;;;
+A8EF;COMBINING DEVANAGARI LETTER RA;Mn;230;NSM;;;;;N;;;;;
+A8F0;COMBINING DEVANAGARI LETTER VI;Mn;230;NSM;;;;;N;;;;;
+A8F1;COMBINING DEVANAGARI SIGN AVAGRAHA;Mn;230;NSM;;;;;N;;;;;
+A8F2;DEVANAGARI SIGN SPACING CANDRABINDU;Lo;0;L;;;;;N;;;;;
+A8F3;DEVANAGARI SIGN CANDRABINDU VIRAMA;Lo;0;L;;;;;N;;;;;
+A8F4;DEVANAGARI SIGN DOUBLE CANDRABINDU VIRAMA;Lo;0;L;;;;;N;;;;;
+A8F5;DEVANAGARI SIGN CANDRABINDU TWO;Lo;0;L;;;;;N;;;;;
+A8F6;DEVANAGARI SIGN CANDRABINDU THREE;Lo;0;L;;;;;N;;;;;
+A8F7;DEVANAGARI SIGN CANDRABINDU AVAGRAHA;Lo;0;L;;;;;N;;;;;
+A8F8;DEVANAGARI SIGN PUSHPIKA;Po;0;L;;;;;N;;;;;
+A8F9;DEVANAGARI GAP FILLER;Po;0;L;;;;;N;;;;;
+A8FA;DEVANAGARI CARET;Po;0;L;;;;;N;;;;;
+A8FB;DEVANAGARI HEADSTROKE;Lo;0;L;;;;;N;;;;;
+A900;KAYAH LI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+A901;KAYAH LI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+A902;KAYAH LI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+A903;KAYAH LI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+A904;KAYAH LI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+A905;KAYAH LI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+A906;KAYAH LI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+A907;KAYAH LI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+A908;KAYAH LI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+A909;KAYAH LI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+A90A;KAYAH LI LETTER KA;Lo;0;L;;;;;N;;;;;
+A90B;KAYAH LI LETTER KHA;Lo;0;L;;;;;N;;;;;
+A90C;KAYAH LI LETTER GA;Lo;0;L;;;;;N;;;;;
+A90D;KAYAH LI LETTER NGA;Lo;0;L;;;;;N;;;;;
+A90E;KAYAH LI LETTER SA;Lo;0;L;;;;;N;;;;;
+A90F;KAYAH LI LETTER SHA;Lo;0;L;;;;;N;;;;;
+A910;KAYAH LI LETTER ZA;Lo;0;L;;;;;N;;;;;
+A911;KAYAH LI LETTER NYA;Lo;0;L;;;;;N;;;;;
+A912;KAYAH LI LETTER TA;Lo;0;L;;;;;N;;;;;
+A913;KAYAH LI LETTER HTA;Lo;0;L;;;;;N;;;;;
+A914;KAYAH LI LETTER NA;Lo;0;L;;;;;N;;;;;
+A915;KAYAH LI LETTER PA;Lo;0;L;;;;;N;;;;;
+A916;KAYAH LI LETTER PHA;Lo;0;L;;;;;N;;;;;
+A917;KAYAH LI LETTER MA;Lo;0;L;;;;;N;;;;;
+A918;KAYAH LI LETTER DA;Lo;0;L;;;;;N;;;;;
+A919;KAYAH LI LETTER BA;Lo;0;L;;;;;N;;;;;
+A91A;KAYAH LI LETTER RA;Lo;0;L;;;;;N;;;;;
+A91B;KAYAH LI LETTER YA;Lo;0;L;;;;;N;;;;;
+A91C;KAYAH LI LETTER LA;Lo;0;L;;;;;N;;;;;
+A91D;KAYAH LI LETTER WA;Lo;0;L;;;;;N;;;;;
+A91E;KAYAH LI LETTER THA;Lo;0;L;;;;;N;;;;;
+A91F;KAYAH LI LETTER HA;Lo;0;L;;;;;N;;;;;
+A920;KAYAH LI LETTER VA;Lo;0;L;;;;;N;;;;;
+A921;KAYAH LI LETTER CA;Lo;0;L;;;;;N;;;;;
+A922;KAYAH LI LETTER A;Lo;0;L;;;;;N;;;;;
+A923;KAYAH LI LETTER OE;Lo;0;L;;;;;N;;;;;
+A924;KAYAH LI LETTER I;Lo;0;L;;;;;N;;;;;
+A925;KAYAH LI LETTER OO;Lo;0;L;;;;;N;;;;;
+A926;KAYAH LI VOWEL UE;Mn;0;NSM;;;;;N;;;;;
+A927;KAYAH LI VOWEL E;Mn;0;NSM;;;;;N;;;;;
+A928;KAYAH LI VOWEL U;Mn;0;NSM;;;;;N;;;;;
+A929;KAYAH LI VOWEL EE;Mn;0;NSM;;;;;N;;;;;
+A92A;KAYAH LI VOWEL O;Mn;0;NSM;;;;;N;;;;;
+A92B;KAYAH LI TONE PLOPHU;Mn;220;NSM;;;;;N;;;;;
+A92C;KAYAH LI TONE CALYA;Mn;220;NSM;;;;;N;;;;;
+A92D;KAYAH LI TONE CALYA PLOPHU;Mn;220;NSM;;;;;N;;;;;
+A92E;KAYAH LI SIGN CWI;Po;0;L;;;;;N;;;;;
+A92F;KAYAH LI SIGN SHYA;Po;0;L;;;;;N;;;;;
+A930;REJANG LETTER KA;Lo;0;L;;;;;N;;;;;
+A931;REJANG LETTER GA;Lo;0;L;;;;;N;;;;;
+A932;REJANG LETTER NGA;Lo;0;L;;;;;N;;;;;
+A933;REJANG LETTER TA;Lo;0;L;;;;;N;;;;;
+A934;REJANG LETTER DA;Lo;0;L;;;;;N;;;;;
+A935;REJANG LETTER NA;Lo;0;L;;;;;N;;;;;
+A936;REJANG LETTER PA;Lo;0;L;;;;;N;;;;;
+A937;REJANG LETTER BA;Lo;0;L;;;;;N;;;;;
+A938;REJANG LETTER MA;Lo;0;L;;;;;N;;;;;
+A939;REJANG LETTER CA;Lo;0;L;;;;;N;;;;;
+A93A;REJANG LETTER JA;Lo;0;L;;;;;N;;;;;
+A93B;REJANG LETTER NYA;Lo;0;L;;;;;N;;;;;
+A93C;REJANG LETTER SA;Lo;0;L;;;;;N;;;;;
+A93D;REJANG LETTER RA;Lo;0;L;;;;;N;;;;;
+A93E;REJANG LETTER LA;Lo;0;L;;;;;N;;;;;
+A93F;REJANG LETTER YA;Lo;0;L;;;;;N;;;;;
+A940;REJANG LETTER WA;Lo;0;L;;;;;N;;;;;
+A941;REJANG LETTER HA;Lo;0;L;;;;;N;;;;;
+A942;REJANG LETTER MBA;Lo;0;L;;;;;N;;;;;
+A943;REJANG LETTER NGGA;Lo;0;L;;;;;N;;;;;
+A944;REJANG LETTER NDA;Lo;0;L;;;;;N;;;;;
+A945;REJANG LETTER NYJA;Lo;0;L;;;;;N;;;;;
+A946;REJANG LETTER A;Lo;0;L;;;;;N;;;;;
+A947;REJANG VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;
+A948;REJANG VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+A949;REJANG VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;;
+A94A;REJANG VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;;
+A94B;REJANG VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;;
+A94C;REJANG VOWEL SIGN AU;Mn;0;NSM;;;;;N;;;;;
+A94D;REJANG VOWEL SIGN EU;Mn;0;NSM;;;;;N;;;;;
+A94E;REJANG VOWEL SIGN EA;Mn;0;NSM;;;;;N;;;;;
+A94F;REJANG CONSONANT SIGN NG;Mn;0;NSM;;;;;N;;;;;
+A950;REJANG CONSONANT SIGN N;Mn;0;NSM;;;;;N;;;;;
+A951;REJANG CONSONANT SIGN R;Mn;0;NSM;;;;;N;;;;;
+A952;REJANG CONSONANT SIGN H;Mc;0;L;;;;;N;;;;;
+A953;REJANG VIRAMA;Mc;9;L;;;;;N;;;;;
+A95F;REJANG SECTION MARK;Po;0;L;;;;;N;;;;;
+A960;HANGUL CHOSEONG TIKEUT-MIEUM;Lo;0;L;;;;;N;;;;;
+A961;HANGUL CHOSEONG TIKEUT-PIEUP;Lo;0;L;;;;;N;;;;;
+A962;HANGUL CHOSEONG TIKEUT-SIOS;Lo;0;L;;;;;N;;;;;
+A963;HANGUL CHOSEONG TIKEUT-CIEUC;Lo;0;L;;;;;N;;;;;
+A964;HANGUL CHOSEONG RIEUL-KIYEOK;Lo;0;L;;;;;N;;;;;
+A965;HANGUL CHOSEONG RIEUL-SSANGKIYEOK;Lo;0;L;;;;;N;;;;;
+A966;HANGUL CHOSEONG RIEUL-TIKEUT;Lo;0;L;;;;;N;;;;;
+A967;HANGUL CHOSEONG RIEUL-SSANGTIKEUT;Lo;0;L;;;;;N;;;;;
+A968;HANGUL CHOSEONG RIEUL-MIEUM;Lo;0;L;;;;;N;;;;;
+A969;HANGUL CHOSEONG RIEUL-PIEUP;Lo;0;L;;;;;N;;;;;
+A96A;HANGUL CHOSEONG RIEUL-SSANGPIEUP;Lo;0;L;;;;;N;;;;;
+A96B;HANGUL CHOSEONG RIEUL-KAPYEOUNPIEUP;Lo;0;L;;;;;N;;;;;
+A96C;HANGUL CHOSEONG RIEUL-SIOS;Lo;0;L;;;;;N;;;;;
+A96D;HANGUL CHOSEONG RIEUL-CIEUC;Lo;0;L;;;;;N;;;;;
+A96E;HANGUL CHOSEONG RIEUL-KHIEUKH;Lo;0;L;;;;;N;;;;;
+A96F;HANGUL CHOSEONG MIEUM-KIYEOK;Lo;0;L;;;;;N;;;;;
+A970;HANGUL CHOSEONG MIEUM-TIKEUT;Lo;0;L;;;;;N;;;;;
+A971;HANGUL CHOSEONG MIEUM-SIOS;Lo;0;L;;;;;N;;;;;
+A972;HANGUL CHOSEONG PIEUP-SIOS-THIEUTH;Lo;0;L;;;;;N;;;;;
+A973;HANGUL CHOSEONG PIEUP-KHIEUKH;Lo;0;L;;;;;N;;;;;
+A974;HANGUL CHOSEONG PIEUP-HIEUH;Lo;0;L;;;;;N;;;;;
+A975;HANGUL CHOSEONG SSANGSIOS-PIEUP;Lo;0;L;;;;;N;;;;;
+A976;HANGUL CHOSEONG IEUNG-RIEUL;Lo;0;L;;;;;N;;;;;
+A977;HANGUL CHOSEONG IEUNG-HIEUH;Lo;0;L;;;;;N;;;;;
+A978;HANGUL CHOSEONG SSANGCIEUC-HIEUH;Lo;0;L;;;;;N;;;;;
+A979;HANGUL CHOSEONG SSANGTHIEUTH;Lo;0;L;;;;;N;;;;;
+A97A;HANGUL CHOSEONG PHIEUPH-HIEUH;Lo;0;L;;;;;N;;;;;
+A97B;HANGUL CHOSEONG HIEUH-SIOS;Lo;0;L;;;;;N;;;;;
+A97C;HANGUL CHOSEONG SSANGYEORINHIEUH;Lo;0;L;;;;;N;;;;;
+A980;JAVANESE SIGN PANYANGGA;Mn;0;NSM;;;;;N;;;;;
+A981;JAVANESE SIGN CECAK;Mn;0;NSM;;;;;N;;;;;
+A982;JAVANESE SIGN LAYAR;Mn;0;NSM;;;;;N;;;;;
+A983;JAVANESE SIGN WIGNYAN;Mc;0;L;;;;;N;;;;;
+A984;JAVANESE LETTER A;Lo;0;L;;;;;N;;;;;
+A985;JAVANESE LETTER I KAWI;Lo;0;L;;;;;N;;;;;
+A986;JAVANESE LETTER I;Lo;0;L;;;;;N;;;;;
+A987;JAVANESE LETTER II;Lo;0;L;;;;;N;;;;;
+A988;JAVANESE LETTER U;Lo;0;L;;;;;N;;;;;
+A989;JAVANESE LETTER PA CEREK;Lo;0;L;;;;;N;;;;;
+A98A;JAVANESE LETTER NGA LELET;Lo;0;L;;;;;N;;;;;
+A98B;JAVANESE LETTER NGA LELET RASWADI;Lo;0;L;;;;;N;;;;;
+A98C;JAVANESE LETTER E;Lo;0;L;;;;;N;;;;;
+A98D;JAVANESE LETTER AI;Lo;0;L;;;;;N;;;;;
+A98E;JAVANESE LETTER O;Lo;0;L;;;;;N;;;;;
+A98F;JAVANESE LETTER KA;Lo;0;L;;;;;N;;;;;
+A990;JAVANESE LETTER KA SASAK;Lo;0;L;;;;;N;;;;;
+A991;JAVANESE LETTER KA MURDA;Lo;0;L;;;;;N;;;;;
+A992;JAVANESE LETTER GA;Lo;0;L;;;;;N;;;;;
+A993;JAVANESE LETTER GA MURDA;Lo;0;L;;;;;N;;;;;
+A994;JAVANESE LETTER NGA;Lo;0;L;;;;;N;;;;;
+A995;JAVANESE LETTER CA;Lo;0;L;;;;;N;;;;;
+A996;JAVANESE LETTER CA MURDA;Lo;0;L;;;;;N;;;;;
+A997;JAVANESE LETTER JA;Lo;0;L;;;;;N;;;;;
+A998;JAVANESE LETTER NYA MURDA;Lo;0;L;;;;;N;;;;;
+A999;JAVANESE LETTER JA MAHAPRANA;Lo;0;L;;;;;N;;;;;
+A99A;JAVANESE LETTER NYA;Lo;0;L;;;;;N;;;;;
+A99B;JAVANESE LETTER TTA;Lo;0;L;;;;;N;;;;;
+A99C;JAVANESE LETTER TTA MAHAPRANA;Lo;0;L;;;;;N;;;;;
+A99D;JAVANESE LETTER DDA;Lo;0;L;;;;;N;;;;;
+A99E;JAVANESE LETTER DDA MAHAPRANA;Lo;0;L;;;;;N;;;;;
+A99F;JAVANESE LETTER NA MURDA;Lo;0;L;;;;;N;;;;;
+A9A0;JAVANESE LETTER TA;Lo;0;L;;;;;N;;;;;
+A9A1;JAVANESE LETTER TA MURDA;Lo;0;L;;;;;N;;;;;
+A9A2;JAVANESE LETTER DA;Lo;0;L;;;;;N;;;;;
+A9A3;JAVANESE LETTER DA MAHAPRANA;Lo;0;L;;;;;N;;;;;
+A9A4;JAVANESE LETTER NA;Lo;0;L;;;;;N;;;;;
+A9A5;JAVANESE LETTER PA;Lo;0;L;;;;;N;;;;;
+A9A6;JAVANESE LETTER PA MURDA;Lo;0;L;;;;;N;;;;;
+A9A7;JAVANESE LETTER BA;Lo;0;L;;;;;N;;;;;
+A9A8;JAVANESE LETTER BA MURDA;Lo;0;L;;;;;N;;;;;
+A9A9;JAVANESE LETTER MA;Lo;0;L;;;;;N;;;;;
+A9AA;JAVANESE LETTER YA;Lo;0;L;;;;;N;;;;;
+A9AB;JAVANESE LETTER RA;Lo;0;L;;;;;N;;;;;
+A9AC;JAVANESE LETTER RA AGUNG;Lo;0;L;;;;;N;;;;;
+A9AD;JAVANESE LETTER LA;Lo;0;L;;;;;N;;;;;
+A9AE;JAVANESE LETTER WA;Lo;0;L;;;;;N;;;;;
+A9AF;JAVANESE LETTER SA MURDA;Lo;0;L;;;;;N;;;;;
+A9B0;JAVANESE LETTER SA MAHAPRANA;Lo;0;L;;;;;N;;;;;
+A9B1;JAVANESE LETTER SA;Lo;0;L;;;;;N;;;;;
+A9B2;JAVANESE LETTER HA;Lo;0;L;;;;;N;;;;;
+A9B3;JAVANESE SIGN CECAK TELU;Mn;7;NSM;;;;;N;;;;;
+A9B4;JAVANESE VOWEL SIGN TARUNG;Mc;0;L;;;;;N;;;;;
+A9B5;JAVANESE VOWEL SIGN TOLONG;Mc;0;L;;;;;N;;;;;
+A9B6;JAVANESE VOWEL SIGN WULU;Mn;0;NSM;;;;;N;;;;;
+A9B7;JAVANESE VOWEL SIGN WULU MELIK;Mn;0;NSM;;;;;N;;;;;
+A9B8;JAVANESE VOWEL SIGN SUKU;Mn;0;NSM;;;;;N;;;;;
+A9B9;JAVANESE VOWEL SIGN SUKU MENDUT;Mn;0;NSM;;;;;N;;;;;
+A9BA;JAVANESE VOWEL SIGN TALING;Mc;0;L;;;;;N;;;;;
+A9BB;JAVANESE VOWEL SIGN DIRGA MURE;Mc;0;L;;;;;N;;;;;
+A9BC;JAVANESE VOWEL SIGN PEPET;Mn;0;NSM;;;;;N;;;;;
+A9BD;JAVANESE CONSONANT SIGN KERET;Mc;0;L;;;;;N;;;;;
+A9BE;JAVANESE CONSONANT SIGN PENGKAL;Mc;0;L;;;;;N;;;;;
+A9BF;JAVANESE CONSONANT SIGN CAKRA;Mc;0;L;;;;;N;;;;;
+A9C0;JAVANESE PANGKON;Mc;9;L;;;;;N;;;;;
+A9C1;JAVANESE LEFT RERENGGAN;Po;0;L;;;;;N;;;;;
+A9C2;JAVANESE RIGHT RERENGGAN;Po;0;L;;;;;N;;;;;
+A9C3;JAVANESE PADA ANDAP;Po;0;L;;;;;N;;;;;
+A9C4;JAVANESE PADA MADYA;Po;0;L;;;;;N;;;;;
+A9C5;JAVANESE PADA LUHUR;Po;0;L;;;;;N;;;;;
+A9C6;JAVANESE PADA WINDU;Po;0;L;;;;;N;;;;;
+A9C7;JAVANESE PADA PANGKAT;Po;0;L;;;;;N;;;;;
+A9C8;JAVANESE PADA LINGSA;Po;0;L;;;;;N;;;;;
+A9C9;JAVANESE PADA LUNGSI;Po;0;L;;;;;N;;;;;
+A9CA;JAVANESE PADA ADEG;Po;0;L;;;;;N;;;;;
+A9CB;JAVANESE PADA ADEG ADEG;Po;0;L;;;;;N;;;;;
+A9CC;JAVANESE PADA PISELEH;Po;0;L;;;;;N;;;;;
+A9CD;JAVANESE TURNED PADA PISELEH;Po;0;L;;;;;N;;;;;
+A9CF;JAVANESE PANGRANGKEP;Lm;0;L;;;;;N;;;;;
+A9D0;JAVANESE DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+A9D1;JAVANESE DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+A9D2;JAVANESE DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+A9D3;JAVANESE DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+A9D4;JAVANESE DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+A9D5;JAVANESE DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+A9D6;JAVANESE DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+A9D7;JAVANESE DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+A9D8;JAVANESE DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+A9D9;JAVANESE DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+A9DE;JAVANESE PADA TIRTA TUMETES;Po;0;L;;;;;N;;;;;
+A9DF;JAVANESE PADA ISEN-ISEN;Po;0;L;;;;;N;;;;;
+AA00;CHAM LETTER A;Lo;0;L;;;;;N;;;;;
+AA01;CHAM LETTER I;Lo;0;L;;;;;N;;;;;
+AA02;CHAM LETTER U;Lo;0;L;;;;;N;;;;;
+AA03;CHAM LETTER E;Lo;0;L;;;;;N;;;;;
+AA04;CHAM LETTER AI;Lo;0;L;;;;;N;;;;;
+AA05;CHAM LETTER O;Lo;0;L;;;;;N;;;;;
+AA06;CHAM LETTER KA;Lo;0;L;;;;;N;;;;;
+AA07;CHAM LETTER KHA;Lo;0;L;;;;;N;;;;;
+AA08;CHAM LETTER GA;Lo;0;L;;;;;N;;;;;
+AA09;CHAM LETTER GHA;Lo;0;L;;;;;N;;;;;
+AA0A;CHAM LETTER NGUE;Lo;0;L;;;;;N;;;;;
+AA0B;CHAM LETTER NGA;Lo;0;L;;;;;N;;;;;
+AA0C;CHAM LETTER CHA;Lo;0;L;;;;;N;;;;;
+AA0D;CHAM LETTER CHHA;Lo;0;L;;;;;N;;;;;
+AA0E;CHAM LETTER JA;Lo;0;L;;;;;N;;;;;
+AA0F;CHAM LETTER JHA;Lo;0;L;;;;;N;;;;;
+AA10;CHAM LETTER NHUE;Lo;0;L;;;;;N;;;;;
+AA11;CHAM LETTER NHA;Lo;0;L;;;;;N;;;;;
+AA12;CHAM LETTER NHJA;Lo;0;L;;;;;N;;;;;
+AA13;CHAM LETTER TA;Lo;0;L;;;;;N;;;;;
+AA14;CHAM LETTER THA;Lo;0;L;;;;;N;;;;;
+AA15;CHAM LETTER DA;Lo;0;L;;;;;N;;;;;
+AA16;CHAM LETTER DHA;Lo;0;L;;;;;N;;;;;
+AA17;CHAM LETTER NUE;Lo;0;L;;;;;N;;;;;
+AA18;CHAM LETTER NA;Lo;0;L;;;;;N;;;;;
+AA19;CHAM LETTER DDA;Lo;0;L;;;;;N;;;;;
+AA1A;CHAM LETTER PA;Lo;0;L;;;;;N;;;;;
+AA1B;CHAM LETTER PPA;Lo;0;L;;;;;N;;;;;
+AA1C;CHAM LETTER PHA;Lo;0;L;;;;;N;;;;;
+AA1D;CHAM LETTER BA;Lo;0;L;;;;;N;;;;;
+AA1E;CHAM LETTER BHA;Lo;0;L;;;;;N;;;;;
+AA1F;CHAM LETTER MUE;Lo;0;L;;;;;N;;;;;
+AA20;CHAM LETTER MA;Lo;0;L;;;;;N;;;;;
+AA21;CHAM LETTER BBA;Lo;0;L;;;;;N;;;;;
+AA22;CHAM LETTER YA;Lo;0;L;;;;;N;;;;;
+AA23;CHAM LETTER RA;Lo;0;L;;;;;N;;;;;
+AA24;CHAM LETTER LA;Lo;0;L;;;;;N;;;;;
+AA25;CHAM LETTER VA;Lo;0;L;;;;;N;;;;;
+AA26;CHAM LETTER SSA;Lo;0;L;;;;;N;;;;;
+AA27;CHAM LETTER SA;Lo;0;L;;;;;N;;;;;
+AA28;CHAM LETTER HA;Lo;0;L;;;;;N;;;;;
+AA29;CHAM VOWEL SIGN AA;Mn;0;NSM;;;;;N;;;;;
+AA2A;CHAM VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;
+AA2B;CHAM VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;;
+AA2C;CHAM VOWEL SIGN EI;Mn;0;NSM;;;;;N;;;;;
+AA2D;CHAM VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+AA2E;CHAM VOWEL SIGN OE;Mn;0;NSM;;;;;N;;;;;
+AA2F;CHAM VOWEL SIGN O;Mc;0;L;;;;;N;;;;;
+AA30;CHAM VOWEL SIGN AI;Mc;0;L;;;;;N;;;;;
+AA31;CHAM VOWEL SIGN AU;Mn;0;NSM;;;;;N;;;;;
+AA32;CHAM VOWEL SIGN UE;Mn;0;NSM;;;;;N;;;;;
+AA33;CHAM CONSONANT SIGN YA;Mc;0;L;;;;;N;;;;;
+AA34;CHAM CONSONANT SIGN RA;Mc;0;L;;;;;N;;;;;
+AA35;CHAM CONSONANT SIGN LA;Mn;0;NSM;;;;;N;;;;;
+AA36;CHAM CONSONANT SIGN WA;Mn;0;NSM;;;;;N;;;;;
+AA40;CHAM LETTER FINAL K;Lo;0;L;;;;;N;;;;;
+AA41;CHAM LETTER FINAL G;Lo;0;L;;;;;N;;;;;
+AA42;CHAM LETTER FINAL NG;Lo;0;L;;;;;N;;;;;
+AA43;CHAM CONSONANT SIGN FINAL NG;Mn;0;NSM;;;;;N;;;;;
+AA44;CHAM LETTER FINAL CH;Lo;0;L;;;;;N;;;;;
+AA45;CHAM LETTER FINAL T;Lo;0;L;;;;;N;;;;;
+AA46;CHAM LETTER FINAL N;Lo;0;L;;;;;N;;;;;
+AA47;CHAM LETTER FINAL P;Lo;0;L;;;;;N;;;;;
+AA48;CHAM LETTER FINAL Y;Lo;0;L;;;;;N;;;;;
+AA49;CHAM LETTER FINAL R;Lo;0;L;;;;;N;;;;;
+AA4A;CHAM LETTER FINAL L;Lo;0;L;;;;;N;;;;;
+AA4B;CHAM LETTER FINAL SS;Lo;0;L;;;;;N;;;;;
+AA4C;CHAM CONSONANT SIGN FINAL M;Mn;0;NSM;;;;;N;;;;;
+AA4D;CHAM CONSONANT SIGN FINAL H;Mc;0;L;;;;;N;;;;;
+AA50;CHAM DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+AA51;CHAM DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+AA52;CHAM DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+AA53;CHAM DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+AA54;CHAM DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+AA55;CHAM DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+AA56;CHAM DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+AA57;CHAM DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+AA58;CHAM DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+AA59;CHAM DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+AA5C;CHAM PUNCTUATION SPIRAL;Po;0;L;;;;;N;;;;;
+AA5D;CHAM PUNCTUATION DANDA;Po;0;L;;;;;N;;;;;
+AA5E;CHAM PUNCTUATION DOUBLE DANDA;Po;0;L;;;;;N;;;;;
+AA5F;CHAM PUNCTUATION TRIPLE DANDA;Po;0;L;;;;;N;;;;;
+AA60;MYANMAR LETTER KHAMTI GA;Lo;0;L;;;;;N;;;;;
+AA61;MYANMAR LETTER KHAMTI CA;Lo;0;L;;;;;N;;;;;
+AA62;MYANMAR LETTER KHAMTI CHA;Lo;0;L;;;;;N;;;;;
+AA63;MYANMAR LETTER KHAMTI JA;Lo;0;L;;;;;N;;;;;
+AA64;MYANMAR LETTER KHAMTI JHA;Lo;0;L;;;;;N;;;;;
+AA65;MYANMAR LETTER KHAMTI NYA;Lo;0;L;;;;;N;;;;;
+AA66;MYANMAR LETTER KHAMTI TTA;Lo;0;L;;;;;N;;;;;
+AA67;MYANMAR LETTER KHAMTI TTHA;Lo;0;L;;;;;N;;;;;
+AA68;MYANMAR LETTER KHAMTI DDA;Lo;0;L;;;;;N;;;;;
+AA69;MYANMAR LETTER KHAMTI DDHA;Lo;0;L;;;;;N;;;;;
+AA6A;MYANMAR LETTER KHAMTI DHA;Lo;0;L;;;;;N;;;;;
+AA6B;MYANMAR LETTER KHAMTI NA;Lo;0;L;;;;;N;;;;;
+AA6C;MYANMAR LETTER KHAMTI SA;Lo;0;L;;;;;N;;;;;
+AA6D;MYANMAR LETTER KHAMTI HA;Lo;0;L;;;;;N;;;;;
+AA6E;MYANMAR LETTER KHAMTI HHA;Lo;0;L;;;;;N;;;;;
+AA6F;MYANMAR LETTER KHAMTI FA;Lo;0;L;;;;;N;;;;;
+AA70;MYANMAR MODIFIER LETTER KHAMTI REDUPLICATION;Lm;0;L;;;;;N;;;;;
+AA71;MYANMAR LETTER KHAMTI XA;Lo;0;L;;;;;N;;;;;
+AA72;MYANMAR LETTER KHAMTI ZA;Lo;0;L;;;;;N;;;;;
+AA73;MYANMAR LETTER KHAMTI RA;Lo;0;L;;;;;N;;;;;
+AA74;MYANMAR LOGOGRAM KHAMTI OAY;Lo;0;L;;;;;N;;;;;
+AA75;MYANMAR LOGOGRAM KHAMTI QN;Lo;0;L;;;;;N;;;;;
+AA76;MYANMAR LOGOGRAM KHAMTI HM;Lo;0;L;;;;;N;;;;;
+AA77;MYANMAR SYMBOL AITON EXCLAMATION;So;0;L;;;;;N;;;;;
+AA78;MYANMAR SYMBOL AITON ONE;So;0;L;;;;;N;;;;;
+AA79;MYANMAR SYMBOL AITON TWO;So;0;L;;;;;N;;;;;
+AA7A;MYANMAR LETTER AITON RA;Lo;0;L;;;;;N;;;;;
+AA7B;MYANMAR SIGN PAO KAREN TONE;Mc;0;L;;;;;N;;;;;
+AA80;TAI VIET LETTER LOW KO;Lo;0;L;;;;;N;;;;;
+AA81;TAI VIET LETTER HIGH KO;Lo;0;L;;;;;N;;;;;
+AA82;TAI VIET LETTER LOW KHO;Lo;0;L;;;;;N;;;;;
+AA83;TAI VIET LETTER HIGH KHO;Lo;0;L;;;;;N;;;;;
+AA84;TAI VIET LETTER LOW KHHO;Lo;0;L;;;;;N;;;;;
+AA85;TAI VIET LETTER HIGH KHHO;Lo;0;L;;;;;N;;;;;
+AA86;TAI VIET LETTER LOW GO;Lo;0;L;;;;;N;;;;;
+AA87;TAI VIET LETTER HIGH GO;Lo;0;L;;;;;N;;;;;
+AA88;TAI VIET LETTER LOW NGO;Lo;0;L;;;;;N;;;;;
+AA89;TAI VIET LETTER HIGH NGO;Lo;0;L;;;;;N;;;;;
+AA8A;TAI VIET LETTER LOW CO;Lo;0;L;;;;;N;;;;;
+AA8B;TAI VIET LETTER HIGH CO;Lo;0;L;;;;;N;;;;;
+AA8C;TAI VIET LETTER LOW CHO;Lo;0;L;;;;;N;;;;;
+AA8D;TAI VIET LETTER HIGH CHO;Lo;0;L;;;;;N;;;;;
+AA8E;TAI VIET LETTER LOW SO;Lo;0;L;;;;;N;;;;;
+AA8F;TAI VIET LETTER HIGH SO;Lo;0;L;;;;;N;;;;;
+AA90;TAI VIET LETTER LOW NYO;Lo;0;L;;;;;N;;;;;
+AA91;TAI VIET LETTER HIGH NYO;Lo;0;L;;;;;N;;;;;
+AA92;TAI VIET LETTER LOW DO;Lo;0;L;;;;;N;;;;;
+AA93;TAI VIET LETTER HIGH DO;Lo;0;L;;;;;N;;;;;
+AA94;TAI VIET LETTER LOW TO;Lo;0;L;;;;;N;;;;;
+AA95;TAI VIET LETTER HIGH TO;Lo;0;L;;;;;N;;;;;
+AA96;TAI VIET LETTER LOW THO;Lo;0;L;;;;;N;;;;;
+AA97;TAI VIET LETTER HIGH THO;Lo;0;L;;;;;N;;;;;
+AA98;TAI VIET LETTER LOW NO;Lo;0;L;;;;;N;;;;;
+AA99;TAI VIET LETTER HIGH NO;Lo;0;L;;;;;N;;;;;
+AA9A;TAI VIET LETTER LOW BO;Lo;0;L;;;;;N;;;;;
+AA9B;TAI VIET LETTER HIGH BO;Lo;0;L;;;;;N;;;;;
+AA9C;TAI VIET LETTER LOW PO;Lo;0;L;;;;;N;;;;;
+AA9D;TAI VIET LETTER HIGH PO;Lo;0;L;;;;;N;;;;;
+AA9E;TAI VIET LETTER LOW PHO;Lo;0;L;;;;;N;;;;;
+AA9F;TAI VIET LETTER HIGH PHO;Lo;0;L;;;;;N;;;;;
+AAA0;TAI VIET LETTER LOW FO;Lo;0;L;;;;;N;;;;;
+AAA1;TAI VIET LETTER HIGH FO;Lo;0;L;;;;;N;;;;;
+AAA2;TAI VIET LETTER LOW MO;Lo;0;L;;;;;N;;;;;
+AAA3;TAI VIET LETTER HIGH MO;Lo;0;L;;;;;N;;;;;
+AAA4;TAI VIET LETTER LOW YO;Lo;0;L;;;;;N;;;;;
+AAA5;TAI VIET LETTER HIGH YO;Lo;0;L;;;;;N;;;;;
+AAA6;TAI VIET LETTER LOW RO;Lo;0;L;;;;;N;;;;;
+AAA7;TAI VIET LETTER HIGH RO;Lo;0;L;;;;;N;;;;;
+AAA8;TAI VIET LETTER LOW LO;Lo;0;L;;;;;N;;;;;
+AAA9;TAI VIET LETTER HIGH LO;Lo;0;L;;;;;N;;;;;
+AAAA;TAI VIET LETTER LOW VO;Lo;0;L;;;;;N;;;;;
+AAAB;TAI VIET LETTER HIGH VO;Lo;0;L;;;;;N;;;;;
+AAAC;TAI VIET LETTER LOW HO;Lo;0;L;;;;;N;;;;;
+AAAD;TAI VIET LETTER HIGH HO;Lo;0;L;;;;;N;;;;;
+AAAE;TAI VIET LETTER LOW O;Lo;0;L;;;;;N;;;;;
+AAAF;TAI VIET LETTER HIGH O;Lo;0;L;;;;;N;;;;;
+AAB0;TAI VIET MAI KANG;Mn;230;NSM;;;;;N;;;;;
+AAB1;TAI VIET VOWEL AA;Lo;0;L;;;;;N;;;;;
+AAB2;TAI VIET VOWEL I;Mn;230;NSM;;;;;N;;;;;
+AAB3;TAI VIET VOWEL UE;Mn;230;NSM;;;;;N;;;;;
+AAB4;TAI VIET VOWEL U;Mn;220;NSM;;;;;N;;;;;
+AAB5;TAI VIET VOWEL E;Lo;0;L;;;;;N;;;;;
+AAB6;TAI VIET VOWEL O;Lo;0;L;;;;;N;;;;;
+AAB7;TAI VIET MAI KHIT;Mn;230;NSM;;;;;N;;;;;
+AAB8;TAI VIET VOWEL IA;Mn;230;NSM;;;;;N;;;;;
+AAB9;TAI VIET VOWEL UEA;Lo;0;L;;;;;N;;;;;
+AABA;TAI VIET VOWEL UA;Lo;0;L;;;;;N;;;;;
+AABB;TAI VIET VOWEL AUE;Lo;0;L;;;;;N;;;;;
+AABC;TAI VIET VOWEL AY;Lo;0;L;;;;;N;;;;;
+AABD;TAI VIET VOWEL AN;Lo;0;L;;;;;N;;;;;
+AABE;TAI VIET VOWEL AM;Mn;230;NSM;;;;;N;;;;;
+AABF;TAI VIET TONE MAI EK;Mn;230;NSM;;;;;N;;;;;
+AAC0;TAI VIET TONE MAI NUENG;Lo;0;L;;;;;N;;;;;
+AAC1;TAI VIET TONE MAI THO;Mn;230;NSM;;;;;N;;;;;
+AAC2;TAI VIET TONE MAI SONG;Lo;0;L;;;;;N;;;;;
+AADB;TAI VIET SYMBOL KON;Lo;0;L;;;;;N;;;;;
+AADC;TAI VIET SYMBOL NUENG;Lo;0;L;;;;;N;;;;;
+AADD;TAI VIET SYMBOL SAM;Lm;0;L;;;;;N;;;;;
+AADE;TAI VIET SYMBOL HO HOI;Po;0;L;;;;;N;;;;;
+AADF;TAI VIET SYMBOL KOI KOI;Po;0;L;;;;;N;;;;;
+AB01;ETHIOPIC SYLLABLE TTHU;Lo;0;L;;;;;N;;;;;
+AB02;ETHIOPIC SYLLABLE TTHI;Lo;0;L;;;;;N;;;;;
+AB03;ETHIOPIC SYLLABLE TTHAA;Lo;0;L;;;;;N;;;;;
+AB04;ETHIOPIC SYLLABLE TTHEE;Lo;0;L;;;;;N;;;;;
+AB05;ETHIOPIC SYLLABLE TTHE;Lo;0;L;;;;;N;;;;;
+AB06;ETHIOPIC SYLLABLE TTHO;Lo;0;L;;;;;N;;;;;
+AB09;ETHIOPIC SYLLABLE DDHU;Lo;0;L;;;;;N;;;;;
+AB0A;ETHIOPIC SYLLABLE DDHI;Lo;0;L;;;;;N;;;;;
+AB0B;ETHIOPIC SYLLABLE DDHAA;Lo;0;L;;;;;N;;;;;
+AB0C;ETHIOPIC SYLLABLE DDHEE;Lo;0;L;;;;;N;;;;;
+AB0D;ETHIOPIC SYLLABLE DDHE;Lo;0;L;;;;;N;;;;;
+AB0E;ETHIOPIC SYLLABLE DDHO;Lo;0;L;;;;;N;;;;;
+AB11;ETHIOPIC SYLLABLE DZU;Lo;0;L;;;;;N;;;;;
+AB12;ETHIOPIC SYLLABLE DZI;Lo;0;L;;;;;N;;;;;
+AB13;ETHIOPIC SYLLABLE DZAA;Lo;0;L;;;;;N;;;;;
+AB14;ETHIOPIC SYLLABLE DZEE;Lo;0;L;;;;;N;;;;;
+AB15;ETHIOPIC SYLLABLE DZE;Lo;0;L;;;;;N;;;;;
+AB16;ETHIOPIC SYLLABLE DZO;Lo;0;L;;;;;N;;;;;
+AB20;ETHIOPIC SYLLABLE CCHHA;Lo;0;L;;;;;N;;;;;
+AB21;ETHIOPIC SYLLABLE CCHHU;Lo;0;L;;;;;N;;;;;
+AB22;ETHIOPIC SYLLABLE CCHHI;Lo;0;L;;;;;N;;;;;
+AB23;ETHIOPIC SYLLABLE CCHHAA;Lo;0;L;;;;;N;;;;;
+AB24;ETHIOPIC SYLLABLE CCHHEE;Lo;0;L;;;;;N;;;;;
+AB25;ETHIOPIC SYLLABLE CCHHE;Lo;0;L;;;;;N;;;;;
+AB26;ETHIOPIC SYLLABLE CCHHO;Lo;0;L;;;;;N;;;;;
+AB28;ETHIOPIC SYLLABLE BBA;Lo;0;L;;;;;N;;;;;
+AB29;ETHIOPIC SYLLABLE BBU;Lo;0;L;;;;;N;;;;;
+AB2A;ETHIOPIC SYLLABLE BBI;Lo;0;L;;;;;N;;;;;
+AB2B;ETHIOPIC SYLLABLE BBAA;Lo;0;L;;;;;N;;;;;
+AB2C;ETHIOPIC SYLLABLE BBEE;Lo;0;L;;;;;N;;;;;
+AB2D;ETHIOPIC SYLLABLE BBE;Lo;0;L;;;;;N;;;;;
+AB2E;ETHIOPIC SYLLABLE BBO;Lo;0;L;;;;;N;;;;;
+ABC0;MEETEI MAYEK LETTER KOK;Lo;0;L;;;;;N;;;;;
+ABC1;MEETEI MAYEK LETTER SAM;Lo;0;L;;;;;N;;;;;
+ABC2;MEETEI MAYEK LETTER LAI;Lo;0;L;;;;;N;;;;;
+ABC3;MEETEI MAYEK LETTER MIT;Lo;0;L;;;;;N;;;;;
+ABC4;MEETEI MAYEK LETTER PA;Lo;0;L;;;;;N;;;;;
+ABC5;MEETEI MAYEK LETTER NA;Lo;0;L;;;;;N;;;;;
+ABC6;MEETEI MAYEK LETTER CHIL;Lo;0;L;;;;;N;;;;;
+ABC7;MEETEI MAYEK LETTER TIL;Lo;0;L;;;;;N;;;;;
+ABC8;MEETEI MAYEK LETTER KHOU;Lo;0;L;;;;;N;;;;;
+ABC9;MEETEI MAYEK LETTER NGOU;Lo;0;L;;;;;N;;;;;
+ABCA;MEETEI MAYEK LETTER THOU;Lo;0;L;;;;;N;;;;;
+ABCB;MEETEI MAYEK LETTER WAI;Lo;0;L;;;;;N;;;;;
+ABCC;MEETEI MAYEK LETTER YANG;Lo;0;L;;;;;N;;;;;
+ABCD;MEETEI MAYEK LETTER HUK;Lo;0;L;;;;;N;;;;;
+ABCE;MEETEI MAYEK LETTER UN;Lo;0;L;;;;;N;;;;;
+ABCF;MEETEI MAYEK LETTER I;Lo;0;L;;;;;N;;;;;
+ABD0;MEETEI MAYEK LETTER PHAM;Lo;0;L;;;;;N;;;;;
+ABD1;MEETEI MAYEK LETTER ATIYA;Lo;0;L;;;;;N;;;;;
+ABD2;MEETEI MAYEK LETTER GOK;Lo;0;L;;;;;N;;;;;
+ABD3;MEETEI MAYEK LETTER JHAM;Lo;0;L;;;;;N;;;;;
+ABD4;MEETEI MAYEK LETTER RAI;Lo;0;L;;;;;N;;;;;
+ABD5;MEETEI MAYEK LETTER BA;Lo;0;L;;;;;N;;;;;
+ABD6;MEETEI MAYEK LETTER JIL;Lo;0;L;;;;;N;;;;;
+ABD7;MEETEI MAYEK LETTER DIL;Lo;0;L;;;;;N;;;;;
+ABD8;MEETEI MAYEK LETTER GHOU;Lo;0;L;;;;;N;;;;;
+ABD9;MEETEI MAYEK LETTER DHOU;Lo;0;L;;;;;N;;;;;
+ABDA;MEETEI MAYEK LETTER BHAM;Lo;0;L;;;;;N;;;;;
+ABDB;MEETEI MAYEK LETTER KOK LONSUM;Lo;0;L;;;;;N;;;;;
+ABDC;MEETEI MAYEK LETTER LAI LONSUM;Lo;0;L;;;;;N;;;;;
+ABDD;MEETEI MAYEK LETTER MIT LONSUM;Lo;0;L;;;;;N;;;;;
+ABDE;MEETEI MAYEK LETTER PA LONSUM;Lo;0;L;;;;;N;;;;;
+ABDF;MEETEI MAYEK LETTER NA LONSUM;Lo;0;L;;;;;N;;;;;
+ABE0;MEETEI MAYEK LETTER TIL LONSUM;Lo;0;L;;;;;N;;;;;
+ABE1;MEETEI MAYEK LETTER NGOU LONSUM;Lo;0;L;;;;;N;;;;;
+ABE2;MEETEI MAYEK LETTER I LONSUM;Lo;0;L;;;;;N;;;;;
+ABE3;MEETEI MAYEK VOWEL SIGN ONAP;Mc;0;L;;;;;N;;;;;
+ABE4;MEETEI MAYEK VOWEL SIGN INAP;Mc;0;L;;;;;N;;;;;
+ABE5;MEETEI MAYEK VOWEL SIGN ANAP;Mn;0;NSM;;;;;N;;;;;
+ABE6;MEETEI MAYEK VOWEL SIGN YENAP;Mc;0;L;;;;;N;;;;;
+ABE7;MEETEI MAYEK VOWEL SIGN SOUNAP;Mc;0;L;;;;;N;;;;;
+ABE8;MEETEI MAYEK VOWEL SIGN UNAP;Mn;0;NSM;;;;;N;;;;;
+ABE9;MEETEI MAYEK VOWEL SIGN CHEINAP;Mc;0;L;;;;;N;;;;;
+ABEA;MEETEI MAYEK VOWEL SIGN NUNG;Mc;0;L;;;;;N;;;;;
+ABEB;MEETEI MAYEK CHEIKHEI;Po;0;L;;;;;N;;;;;
+ABEC;MEETEI MAYEK LUM IYEK;Mc;0;L;;;;;N;;;;;
+ABED;MEETEI MAYEK APUN IYEK;Mn;9;NSM;;;;;N;;;;;
+ABF0;MEETEI MAYEK DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+ABF1;MEETEI MAYEK DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+ABF2;MEETEI MAYEK DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+ABF3;MEETEI MAYEK DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+ABF4;MEETEI MAYEK DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+ABF5;MEETEI MAYEK DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+ABF6;MEETEI MAYEK DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+ABF7;MEETEI MAYEK DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+ABF8;MEETEI MAYEK DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+ABF9;MEETEI MAYEK DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+AC00;<Hangul Syllable, First>;Lo;0;L;;;;;N;;;;;
+D7A3;<Hangul Syllable, Last>;Lo;0;L;;;;;N;;;;;
+D7B0;HANGUL JUNGSEONG O-YEO;Lo;0;L;;;;;N;;;;;
+D7B1;HANGUL JUNGSEONG O-O-I;Lo;0;L;;;;;N;;;;;
+D7B2;HANGUL JUNGSEONG YO-A;Lo;0;L;;;;;N;;;;;
+D7B3;HANGUL JUNGSEONG YO-AE;Lo;0;L;;;;;N;;;;;
+D7B4;HANGUL JUNGSEONG YO-EO;Lo;0;L;;;;;N;;;;;
+D7B5;HANGUL JUNGSEONG U-YEO;Lo;0;L;;;;;N;;;;;
+D7B6;HANGUL JUNGSEONG U-I-I;Lo;0;L;;;;;N;;;;;
+D7B7;HANGUL JUNGSEONG YU-AE;Lo;0;L;;;;;N;;;;;
+D7B8;HANGUL JUNGSEONG YU-O;Lo;0;L;;;;;N;;;;;
+D7B9;HANGUL JUNGSEONG EU-A;Lo;0;L;;;;;N;;;;;
+D7BA;HANGUL JUNGSEONG EU-EO;Lo;0;L;;;;;N;;;;;
+D7BB;HANGUL JUNGSEONG EU-E;Lo;0;L;;;;;N;;;;;
+D7BC;HANGUL JUNGSEONG EU-O;Lo;0;L;;;;;N;;;;;
+D7BD;HANGUL JUNGSEONG I-YA-O;Lo;0;L;;;;;N;;;;;
+D7BE;HANGUL JUNGSEONG I-YAE;Lo;0;L;;;;;N;;;;;
+D7BF;HANGUL JUNGSEONG I-YEO;Lo;0;L;;;;;N;;;;;
+D7C0;HANGUL JUNGSEONG I-YE;Lo;0;L;;;;;N;;;;;
+D7C1;HANGUL JUNGSEONG I-O-I;Lo;0;L;;;;;N;;;;;
+D7C2;HANGUL JUNGSEONG I-YO;Lo;0;L;;;;;N;;;;;
+D7C3;HANGUL JUNGSEONG I-YU;Lo;0;L;;;;;N;;;;;
+D7C4;HANGUL JUNGSEONG I-I;Lo;0;L;;;;;N;;;;;
+D7C5;HANGUL JUNGSEONG ARAEA-A;Lo;0;L;;;;;N;;;;;
+D7C6;HANGUL JUNGSEONG ARAEA-E;Lo;0;L;;;;;N;;;;;
+D7CB;HANGUL JONGSEONG NIEUN-RIEUL;Lo;0;L;;;;;N;;;;;
+D7CC;HANGUL JONGSEONG NIEUN-CHIEUCH;Lo;0;L;;;;;N;;;;;
+D7CD;HANGUL JONGSEONG SSANGTIKEUT;Lo;0;L;;;;;N;;;;;
+D7CE;HANGUL JONGSEONG SSANGTIKEUT-PIEUP;Lo;0;L;;;;;N;;;;;
+D7CF;HANGUL JONGSEONG TIKEUT-PIEUP;Lo;0;L;;;;;N;;;;;
+D7D0;HANGUL JONGSEONG TIKEUT-SIOS;Lo;0;L;;;;;N;;;;;
+D7D1;HANGUL JONGSEONG TIKEUT-SIOS-KIYEOK;Lo;0;L;;;;;N;;;;;
+D7D2;HANGUL JONGSEONG TIKEUT-CIEUC;Lo;0;L;;;;;N;;;;;
+D7D3;HANGUL JONGSEONG TIKEUT-CHIEUCH;Lo;0;L;;;;;N;;;;;
+D7D4;HANGUL JONGSEONG TIKEUT-THIEUTH;Lo;0;L;;;;;N;;;;;
+D7D5;HANGUL JONGSEONG RIEUL-SSANGKIYEOK;Lo;0;L;;;;;N;;;;;
+D7D6;HANGUL JONGSEONG RIEUL-KIYEOK-HIEUH;Lo;0;L;;;;;N;;;;;
+D7D7;HANGUL JONGSEONG SSANGRIEUL-KHIEUKH;Lo;0;L;;;;;N;;;;;
+D7D8;HANGUL JONGSEONG RIEUL-MIEUM-HIEUH;Lo;0;L;;;;;N;;;;;
+D7D9;HANGUL JONGSEONG RIEUL-PIEUP-TIKEUT;Lo;0;L;;;;;N;;;;;
+D7DA;HANGUL JONGSEONG RIEUL-PIEUP-PHIEUPH;Lo;0;L;;;;;N;;;;;
+D7DB;HANGUL JONGSEONG RIEUL-YESIEUNG;Lo;0;L;;;;;N;;;;;
+D7DC;HANGUL JONGSEONG RIEUL-YEORINHIEUH-HIEUH;Lo;0;L;;;;;N;;;;;
+D7DD;HANGUL JONGSEONG KAPYEOUNRIEUL;Lo;0;L;;;;;N;;;;;
+D7DE;HANGUL JONGSEONG MIEUM-NIEUN;Lo;0;L;;;;;N;;;;;
+D7DF;HANGUL JONGSEONG MIEUM-SSANGNIEUN;Lo;0;L;;;;;N;;;;;
+D7E0;HANGUL JONGSEONG SSANGMIEUM;Lo;0;L;;;;;N;;;;;
+D7E1;HANGUL JONGSEONG MIEUM-PIEUP-SIOS;Lo;0;L;;;;;N;;;;;
+D7E2;HANGUL JONGSEONG MIEUM-CIEUC;Lo;0;L;;;;;N;;;;;
+D7E3;HANGUL JONGSEONG PIEUP-TIKEUT;Lo;0;L;;;;;N;;;;;
+D7E4;HANGUL JONGSEONG PIEUP-RIEUL-PHIEUPH;Lo;0;L;;;;;N;;;;;
+D7E5;HANGUL JONGSEONG PIEUP-MIEUM;Lo;0;L;;;;;N;;;;;
+D7E6;HANGUL JONGSEONG SSANGPIEUP;Lo;0;L;;;;;N;;;;;
+D7E7;HANGUL JONGSEONG PIEUP-SIOS-TIKEUT;Lo;0;L;;;;;N;;;;;
+D7E8;HANGUL JONGSEONG PIEUP-CIEUC;Lo;0;L;;;;;N;;;;;
+D7E9;HANGUL JONGSEONG PIEUP-CHIEUCH;Lo;0;L;;;;;N;;;;;
+D7EA;HANGUL JONGSEONG SIOS-MIEUM;Lo;0;L;;;;;N;;;;;
+D7EB;HANGUL JONGSEONG SIOS-KAPYEOUNPIEUP;Lo;0;L;;;;;N;;;;;
+D7EC;HANGUL JONGSEONG SSANGSIOS-KIYEOK;Lo;0;L;;;;;N;;;;;
+D7ED;HANGUL JONGSEONG SSANGSIOS-TIKEUT;Lo;0;L;;;;;N;;;;;
+D7EE;HANGUL JONGSEONG SIOS-PANSIOS;Lo;0;L;;;;;N;;;;;
+D7EF;HANGUL JONGSEONG SIOS-CIEUC;Lo;0;L;;;;;N;;;;;
+D7F0;HANGUL JONGSEONG SIOS-CHIEUCH;Lo;0;L;;;;;N;;;;;
+D7F1;HANGUL JONGSEONG SIOS-THIEUTH;Lo;0;L;;;;;N;;;;;
+D7F2;HANGUL JONGSEONG SIOS-HIEUH;Lo;0;L;;;;;N;;;;;
+D7F3;HANGUL JONGSEONG PANSIOS-PIEUP;Lo;0;L;;;;;N;;;;;
+D7F4;HANGUL JONGSEONG PANSIOS-KAPYEOUNPIEUP;Lo;0;L;;;;;N;;;;;
+D7F5;HANGUL JONGSEONG YESIEUNG-MIEUM;Lo;0;L;;;;;N;;;;;
+D7F6;HANGUL JONGSEONG YESIEUNG-HIEUH;Lo;0;L;;;;;N;;;;;
+D7F7;HANGUL JONGSEONG CIEUC-PIEUP;Lo;0;L;;;;;N;;;;;
+D7F8;HANGUL JONGSEONG CIEUC-SSANGPIEUP;Lo;0;L;;;;;N;;;;;
+D7F9;HANGUL JONGSEONG SSANGCIEUC;Lo;0;L;;;;;N;;;;;
+D7FA;HANGUL JONGSEONG PHIEUPH-SIOS;Lo;0;L;;;;;N;;;;;
+D7FB;HANGUL JONGSEONG PHIEUPH-THIEUTH;Lo;0;L;;;;;N;;;;;
+D800;<Non Private Use High Surrogate, First>;Cs;0;L;;;;;N;;;;;
+DB7F;<Non Private Use High Surrogate, Last>;Cs;0;L;;;;;N;;;;;
+DB80;<Private Use High Surrogate, First>;Cs;0;L;;;;;N;;;;;
+DBFF;<Private Use High Surrogate, Last>;Cs;0;L;;;;;N;;;;;
+DC00;<Low Surrogate, First>;Cs;0;L;;;;;N;;;;;
+DFFF;<Low Surrogate, Last>;Cs;0;L;;;;;N;;;;;
+E000;<Private Use, First>;Co;0;L;;;;;N;;;;;
+F8FF;<Private Use, Last>;Co;0;L;;;;;N;;;;;
+F900;CJK COMPATIBILITY IDEOGRAPH-F900;Lo;0;L;8C48;;;;N;;;;;
+F901;CJK COMPATIBILITY IDEOGRAPH-F901;Lo;0;L;66F4;;;;N;;;;;
+F902;CJK COMPATIBILITY IDEOGRAPH-F902;Lo;0;L;8ECA;;;;N;;;;;
+F903;CJK COMPATIBILITY IDEOGRAPH-F903;Lo;0;L;8CC8;;;;N;;;;;
+F904;CJK COMPATIBILITY IDEOGRAPH-F904;Lo;0;L;6ED1;;;;N;;;;;
+F905;CJK COMPATIBILITY IDEOGRAPH-F905;Lo;0;L;4E32;;;;N;;;;;
+F906;CJK COMPATIBILITY IDEOGRAPH-F906;Lo;0;L;53E5;;;;N;;;;;
+F907;CJK COMPATIBILITY IDEOGRAPH-F907;Lo;0;L;9F9C;;;;N;;;;;
+F908;CJK COMPATIBILITY IDEOGRAPH-F908;Lo;0;L;9F9C;;;;N;;;;;
+F909;CJK COMPATIBILITY IDEOGRAPH-F909;Lo;0;L;5951;;;;N;;;;;
+F90A;CJK COMPATIBILITY IDEOGRAPH-F90A;Lo;0;L;91D1;;;;N;;;;;
+F90B;CJK COMPATIBILITY IDEOGRAPH-F90B;Lo;0;L;5587;;;;N;;;;;
+F90C;CJK COMPATIBILITY IDEOGRAPH-F90C;Lo;0;L;5948;;;;N;;;;;
+F90D;CJK COMPATIBILITY IDEOGRAPH-F90D;Lo;0;L;61F6;;;;N;;;;;
+F90E;CJK COMPATIBILITY IDEOGRAPH-F90E;Lo;0;L;7669;;;;N;;;;;
+F90F;CJK COMPATIBILITY IDEOGRAPH-F90F;Lo;0;L;7F85;;;;N;;;;;
+F910;CJK COMPATIBILITY IDEOGRAPH-F910;Lo;0;L;863F;;;;N;;;;;
+F911;CJK COMPATIBILITY IDEOGRAPH-F911;Lo;0;L;87BA;;;;N;;;;;
+F912;CJK COMPATIBILITY IDEOGRAPH-F912;Lo;0;L;88F8;;;;N;;;;;
+F913;CJK COMPATIBILITY IDEOGRAPH-F913;Lo;0;L;908F;;;;N;;;;;
+F914;CJK COMPATIBILITY IDEOGRAPH-F914;Lo;0;L;6A02;;;;N;;;;;
+F915;CJK COMPATIBILITY IDEOGRAPH-F915;Lo;0;L;6D1B;;;;N;;;;;
+F916;CJK COMPATIBILITY IDEOGRAPH-F916;Lo;0;L;70D9;;;;N;;;;;
+F917;CJK COMPATIBILITY IDEOGRAPH-F917;Lo;0;L;73DE;;;;N;;;;;
+F918;CJK COMPATIBILITY IDEOGRAPH-F918;Lo;0;L;843D;;;;N;;;;;
+F919;CJK COMPATIBILITY IDEOGRAPH-F919;Lo;0;L;916A;;;;N;;;;;
+F91A;CJK COMPATIBILITY IDEOGRAPH-F91A;Lo;0;L;99F1;;;;N;;;;;
+F91B;CJK COMPATIBILITY IDEOGRAPH-F91B;Lo;0;L;4E82;;;;N;;;;;
+F91C;CJK COMPATIBILITY IDEOGRAPH-F91C;Lo;0;L;5375;;;;N;;;;;
+F91D;CJK COMPATIBILITY IDEOGRAPH-F91D;Lo;0;L;6B04;;;;N;;;;;
+F91E;CJK COMPATIBILITY IDEOGRAPH-F91E;Lo;0;L;721B;;;;N;;;;;
+F91F;CJK COMPATIBILITY IDEOGRAPH-F91F;Lo;0;L;862D;;;;N;;;;;
+F920;CJK COMPATIBILITY IDEOGRAPH-F920;Lo;0;L;9E1E;;;;N;;;;;
+F921;CJK COMPATIBILITY IDEOGRAPH-F921;Lo;0;L;5D50;;;;N;;;;;
+F922;CJK COMPATIBILITY IDEOGRAPH-F922;Lo;0;L;6FEB;;;;N;;;;;
+F923;CJK COMPATIBILITY IDEOGRAPH-F923;Lo;0;L;85CD;;;;N;;;;;
+F924;CJK COMPATIBILITY IDEOGRAPH-F924;Lo;0;L;8964;;;;N;;;;;
+F925;CJK COMPATIBILITY IDEOGRAPH-F925;Lo;0;L;62C9;;;;N;;;;;
+F926;CJK COMPATIBILITY IDEOGRAPH-F926;Lo;0;L;81D8;;;;N;;;;;
+F927;CJK COMPATIBILITY IDEOGRAPH-F927;Lo;0;L;881F;;;;N;;;;;
+F928;CJK COMPATIBILITY IDEOGRAPH-F928;Lo;0;L;5ECA;;;;N;;;;;
+F929;CJK COMPATIBILITY IDEOGRAPH-F929;Lo;0;L;6717;;;;N;;;;;
+F92A;CJK COMPATIBILITY IDEOGRAPH-F92A;Lo;0;L;6D6A;;;;N;;;;;
+F92B;CJK COMPATIBILITY IDEOGRAPH-F92B;Lo;0;L;72FC;;;;N;;;;;
+F92C;CJK COMPATIBILITY IDEOGRAPH-F92C;Lo;0;L;90CE;;;;N;;;;;
+F92D;CJK COMPATIBILITY IDEOGRAPH-F92D;Lo;0;L;4F86;;;;N;;;;;
+F92E;CJK COMPATIBILITY IDEOGRAPH-F92E;Lo;0;L;51B7;;;;N;;;;;
+F92F;CJK COMPATIBILITY IDEOGRAPH-F92F;Lo;0;L;52DE;;;;N;;;;;
+F930;CJK COMPATIBILITY IDEOGRAPH-F930;Lo;0;L;64C4;;;;N;;;;;
+F931;CJK COMPATIBILITY IDEOGRAPH-F931;Lo;0;L;6AD3;;;;N;;;;;
+F932;CJK COMPATIBILITY IDEOGRAPH-F932;Lo;0;L;7210;;;;N;;;;;
+F933;CJK COMPATIBILITY IDEOGRAPH-F933;Lo;0;L;76E7;;;;N;;;;;
+F934;CJK COMPATIBILITY IDEOGRAPH-F934;Lo;0;L;8001;;;;N;;;;;
+F935;CJK COMPATIBILITY IDEOGRAPH-F935;Lo;0;L;8606;;;;N;;;;;
+F936;CJK COMPATIBILITY IDEOGRAPH-F936;Lo;0;L;865C;;;;N;;;;;
+F937;CJK COMPATIBILITY IDEOGRAPH-F937;Lo;0;L;8DEF;;;;N;;;;;
+F938;CJK COMPATIBILITY IDEOGRAPH-F938;Lo;0;L;9732;;;;N;;;;;
+F939;CJK COMPATIBILITY IDEOGRAPH-F939;Lo;0;L;9B6F;;;;N;;;;;
+F93A;CJK COMPATIBILITY IDEOGRAPH-F93A;Lo;0;L;9DFA;;;;N;;;;;
+F93B;CJK COMPATIBILITY IDEOGRAPH-F93B;Lo;0;L;788C;;;;N;;;;;
+F93C;CJK COMPATIBILITY IDEOGRAPH-F93C;Lo;0;L;797F;;;;N;;;;;
+F93D;CJK COMPATIBILITY IDEOGRAPH-F93D;Lo;0;L;7DA0;;;;N;;;;;
+F93E;CJK COMPATIBILITY IDEOGRAPH-F93E;Lo;0;L;83C9;;;;N;;;;;
+F93F;CJK COMPATIBILITY IDEOGRAPH-F93F;Lo;0;L;9304;;;;N;;;;;
+F940;CJK COMPATIBILITY IDEOGRAPH-F940;Lo;0;L;9E7F;;;;N;;;;;
+F941;CJK COMPATIBILITY IDEOGRAPH-F941;Lo;0;L;8AD6;;;;N;;;;;
+F942;CJK COMPATIBILITY IDEOGRAPH-F942;Lo;0;L;58DF;;;;N;;;;;
+F943;CJK COMPATIBILITY IDEOGRAPH-F943;Lo;0;L;5F04;;;;N;;;;;
+F944;CJK COMPATIBILITY IDEOGRAPH-F944;Lo;0;L;7C60;;;;N;;;;;
+F945;CJK COMPATIBILITY IDEOGRAPH-F945;Lo;0;L;807E;;;;N;;;;;
+F946;CJK COMPATIBILITY IDEOGRAPH-F946;Lo;0;L;7262;;;;N;;;;;
+F947;CJK COMPATIBILITY IDEOGRAPH-F947;Lo;0;L;78CA;;;;N;;;;;
+F948;CJK COMPATIBILITY IDEOGRAPH-F948;Lo;0;L;8CC2;;;;N;;;;;
+F949;CJK COMPATIBILITY IDEOGRAPH-F949;Lo;0;L;96F7;;;;N;;;;;
+F94A;CJK COMPATIBILITY IDEOGRAPH-F94A;Lo;0;L;58D8;;;;N;;;;;
+F94B;CJK COMPATIBILITY IDEOGRAPH-F94B;Lo;0;L;5C62;;;;N;;;;;
+F94C;CJK COMPATIBILITY IDEOGRAPH-F94C;Lo;0;L;6A13;;;;N;;;;;
+F94D;CJK COMPATIBILITY IDEOGRAPH-F94D;Lo;0;L;6DDA;;;;N;;;;;
+F94E;CJK COMPATIBILITY IDEOGRAPH-F94E;Lo;0;L;6F0F;;;;N;;;;;
+F94F;CJK COMPATIBILITY IDEOGRAPH-F94F;Lo;0;L;7D2F;;;;N;;;;;
+F950;CJK COMPATIBILITY IDEOGRAPH-F950;Lo;0;L;7E37;;;;N;;;;;
+F951;CJK COMPATIBILITY IDEOGRAPH-F951;Lo;0;L;964B;;;;N;;;;;
+F952;CJK COMPATIBILITY IDEOGRAPH-F952;Lo;0;L;52D2;;;;N;;;;;
+F953;CJK COMPATIBILITY IDEOGRAPH-F953;Lo;0;L;808B;;;;N;;;;;
+F954;CJK COMPATIBILITY IDEOGRAPH-F954;Lo;0;L;51DC;;;;N;;;;;
+F955;CJK COMPATIBILITY IDEOGRAPH-F955;Lo;0;L;51CC;;;;N;;;;;
+F956;CJK COMPATIBILITY IDEOGRAPH-F956;Lo;0;L;7A1C;;;;N;;;;;
+F957;CJK COMPATIBILITY IDEOGRAPH-F957;Lo;0;L;7DBE;;;;N;;;;;
+F958;CJK COMPATIBILITY IDEOGRAPH-F958;Lo;0;L;83F1;;;;N;;;;;
+F959;CJK COMPATIBILITY IDEOGRAPH-F959;Lo;0;L;9675;;;;N;;;;;
+F95A;CJK COMPATIBILITY IDEOGRAPH-F95A;Lo;0;L;8B80;;;;N;;;;;
+F95B;CJK COMPATIBILITY IDEOGRAPH-F95B;Lo;0;L;62CF;;;;N;;;;;
+F95C;CJK COMPATIBILITY IDEOGRAPH-F95C;Lo;0;L;6A02;;;;N;;;;;
+F95D;CJK COMPATIBILITY IDEOGRAPH-F95D;Lo;0;L;8AFE;;;;N;;;;;
+F95E;CJK COMPATIBILITY IDEOGRAPH-F95E;Lo;0;L;4E39;;;;N;;;;;
+F95F;CJK COMPATIBILITY IDEOGRAPH-F95F;Lo;0;L;5BE7;;;;N;;;;;
+F960;CJK COMPATIBILITY IDEOGRAPH-F960;Lo;0;L;6012;;;;N;;;;;
+F961;CJK COMPATIBILITY IDEOGRAPH-F961;Lo;0;L;7387;;;;N;;;;;
+F962;CJK COMPATIBILITY IDEOGRAPH-F962;Lo;0;L;7570;;;;N;;;;;
+F963;CJK COMPATIBILITY IDEOGRAPH-F963;Lo;0;L;5317;;;;N;;;;;
+F964;CJK COMPATIBILITY IDEOGRAPH-F964;Lo;0;L;78FB;;;;N;;;;;
+F965;CJK COMPATIBILITY IDEOGRAPH-F965;Lo;0;L;4FBF;;;;N;;;;;
+F966;CJK COMPATIBILITY IDEOGRAPH-F966;Lo;0;L;5FA9;;;;N;;;;;
+F967;CJK COMPATIBILITY IDEOGRAPH-F967;Lo;0;L;4E0D;;;;N;;;;;
+F968;CJK COMPATIBILITY IDEOGRAPH-F968;Lo;0;L;6CCC;;;;N;;;;;
+F969;CJK COMPATIBILITY IDEOGRAPH-F969;Lo;0;L;6578;;;;N;;;;;
+F96A;CJK COMPATIBILITY IDEOGRAPH-F96A;Lo;0;L;7D22;;;;N;;;;;
+F96B;CJK COMPATIBILITY IDEOGRAPH-F96B;Lo;0;L;53C3;;;3;N;;;;;
+F96C;CJK COMPATIBILITY IDEOGRAPH-F96C;Lo;0;L;585E;;;;N;;;;;
+F96D;CJK COMPATIBILITY IDEOGRAPH-F96D;Lo;0;L;7701;;;;N;;;;;
+F96E;CJK COMPATIBILITY IDEOGRAPH-F96E;Lo;0;L;8449;;;;N;;;;;
+F96F;CJK COMPATIBILITY IDEOGRAPH-F96F;Lo;0;L;8AAA;;;;N;;;;;
+F970;CJK COMPATIBILITY IDEOGRAPH-F970;Lo;0;L;6BBA;;;;N;;;;;
+F971;CJK COMPATIBILITY IDEOGRAPH-F971;Lo;0;L;8FB0;;;;N;;;;;
+F972;CJK COMPATIBILITY IDEOGRAPH-F972;Lo;0;L;6C88;;;;N;;;;;
+F973;CJK COMPATIBILITY IDEOGRAPH-F973;Lo;0;L;62FE;;;10;N;;;;;
+F974;CJK COMPATIBILITY IDEOGRAPH-F974;Lo;0;L;82E5;;;;N;;;;;
+F975;CJK COMPATIBILITY IDEOGRAPH-F975;Lo;0;L;63A0;;;;N;;;;;
+F976;CJK COMPATIBILITY IDEOGRAPH-F976;Lo;0;L;7565;;;;N;;;;;
+F977;CJK COMPATIBILITY IDEOGRAPH-F977;Lo;0;L;4EAE;;;;N;;;;;
+F978;CJK COMPATIBILITY IDEOGRAPH-F978;Lo;0;L;5169;;;2;N;;;;;
+F979;CJK COMPATIBILITY IDEOGRAPH-F979;Lo;0;L;51C9;;;;N;;;;;
+F97A;CJK COMPATIBILITY IDEOGRAPH-F97A;Lo;0;L;6881;;;;N;;;;;
+F97B;CJK COMPATIBILITY IDEOGRAPH-F97B;Lo;0;L;7CE7;;;;N;;;;;
+F97C;CJK COMPATIBILITY IDEOGRAPH-F97C;Lo;0;L;826F;;;;N;;;;;
+F97D;CJK COMPATIBILITY IDEOGRAPH-F97D;Lo;0;L;8AD2;;;;N;;;;;
+F97E;CJK COMPATIBILITY IDEOGRAPH-F97E;Lo;0;L;91CF;;;;N;;;;;
+F97F;CJK COMPATIBILITY IDEOGRAPH-F97F;Lo;0;L;52F5;;;;N;;;;;
+F980;CJK COMPATIBILITY IDEOGRAPH-F980;Lo;0;L;5442;;;;N;;;;;
+F981;CJK COMPATIBILITY IDEOGRAPH-F981;Lo;0;L;5973;;;;N;;;;;
+F982;CJK COMPATIBILITY IDEOGRAPH-F982;Lo;0;L;5EEC;;;;N;;;;;
+F983;CJK COMPATIBILITY IDEOGRAPH-F983;Lo;0;L;65C5;;;;N;;;;;
+F984;CJK COMPATIBILITY IDEOGRAPH-F984;Lo;0;L;6FFE;;;;N;;;;;
+F985;CJK COMPATIBILITY IDEOGRAPH-F985;Lo;0;L;792A;;;;N;;;;;
+F986;CJK COMPATIBILITY IDEOGRAPH-F986;Lo;0;L;95AD;;;;N;;;;;
+F987;CJK COMPATIBILITY IDEOGRAPH-F987;Lo;0;L;9A6A;;;;N;;;;;
+F988;CJK COMPATIBILITY IDEOGRAPH-F988;Lo;0;L;9E97;;;;N;;;;;
+F989;CJK COMPATIBILITY IDEOGRAPH-F989;Lo;0;L;9ECE;;;;N;;;;;
+F98A;CJK COMPATIBILITY IDEOGRAPH-F98A;Lo;0;L;529B;;;;N;;;;;
+F98B;CJK COMPATIBILITY IDEOGRAPH-F98B;Lo;0;L;66C6;;;;N;;;;;
+F98C;CJK COMPATIBILITY IDEOGRAPH-F98C;Lo;0;L;6B77;;;;N;;;;;
+F98D;CJK COMPATIBILITY IDEOGRAPH-F98D;Lo;0;L;8F62;;;;N;;;;;
+F98E;CJK COMPATIBILITY IDEOGRAPH-F98E;Lo;0;L;5E74;;;;N;;;;;
+F98F;CJK COMPATIBILITY IDEOGRAPH-F98F;Lo;0;L;6190;;;;N;;;;;
+F990;CJK COMPATIBILITY IDEOGRAPH-F990;Lo;0;L;6200;;;;N;;;;;
+F991;CJK COMPATIBILITY IDEOGRAPH-F991;Lo;0;L;649A;;;;N;;;;;
+F992;CJK COMPATIBILITY IDEOGRAPH-F992;Lo;0;L;6F23;;;;N;;;;;
+F993;CJK COMPATIBILITY IDEOGRAPH-F993;Lo;0;L;7149;;;;N;;;;;
+F994;CJK COMPATIBILITY IDEOGRAPH-F994;Lo;0;L;7489;;;;N;;;;;
+F995;CJK COMPATIBILITY IDEOGRAPH-F995;Lo;0;L;79CA;;;;N;;;;;
+F996;CJK COMPATIBILITY IDEOGRAPH-F996;Lo;0;L;7DF4;;;;N;;;;;
+F997;CJK COMPATIBILITY IDEOGRAPH-F997;Lo;0;L;806F;;;;N;;;;;
+F998;CJK COMPATIBILITY IDEOGRAPH-F998;Lo;0;L;8F26;;;;N;;;;;
+F999;CJK COMPATIBILITY IDEOGRAPH-F999;Lo;0;L;84EE;;;;N;;;;;
+F99A;CJK COMPATIBILITY IDEOGRAPH-F99A;Lo;0;L;9023;;;;N;;;;;
+F99B;CJK COMPATIBILITY IDEOGRAPH-F99B;Lo;0;L;934A;;;;N;;;;;
+F99C;CJK COMPATIBILITY IDEOGRAPH-F99C;Lo;0;L;5217;;;;N;;;;;
+F99D;CJK COMPATIBILITY IDEOGRAPH-F99D;Lo;0;L;52A3;;;;N;;;;;
+F99E;CJK COMPATIBILITY IDEOGRAPH-F99E;Lo;0;L;54BD;;;;N;;;;;
+F99F;CJK COMPATIBILITY IDEOGRAPH-F99F;Lo;0;L;70C8;;;;N;;;;;
+F9A0;CJK COMPATIBILITY IDEOGRAPH-F9A0;Lo;0;L;88C2;;;;N;;;;;
+F9A1;CJK COMPATIBILITY IDEOGRAPH-F9A1;Lo;0;L;8AAA;;;;N;;;;;
+F9A2;CJK COMPATIBILITY IDEOGRAPH-F9A2;Lo;0;L;5EC9;;;;N;;;;;
+F9A3;CJK COMPATIBILITY IDEOGRAPH-F9A3;Lo;0;L;5FF5;;;;N;;;;;
+F9A4;CJK COMPATIBILITY IDEOGRAPH-F9A4;Lo;0;L;637B;;;;N;;;;;
+F9A5;CJK COMPATIBILITY IDEOGRAPH-F9A5;Lo;0;L;6BAE;;;;N;;;;;
+F9A6;CJK COMPATIBILITY IDEOGRAPH-F9A6;Lo;0;L;7C3E;;;;N;;;;;
+F9A7;CJK COMPATIBILITY IDEOGRAPH-F9A7;Lo;0;L;7375;;;;N;;;;;
+F9A8;CJK COMPATIBILITY IDEOGRAPH-F9A8;Lo;0;L;4EE4;;;;N;;;;;
+F9A9;CJK COMPATIBILITY IDEOGRAPH-F9A9;Lo;0;L;56F9;;;;N;;;;;
+F9AA;CJK COMPATIBILITY IDEOGRAPH-F9AA;Lo;0;L;5BE7;;;;N;;;;;
+F9AB;CJK COMPATIBILITY IDEOGRAPH-F9AB;Lo;0;L;5DBA;;;;N;;;;;
+F9AC;CJK COMPATIBILITY IDEOGRAPH-F9AC;Lo;0;L;601C;;;;N;;;;;
+F9AD;CJK COMPATIBILITY IDEOGRAPH-F9AD;Lo;0;L;73B2;;;;N;;;;;
+F9AE;CJK COMPATIBILITY IDEOGRAPH-F9AE;Lo;0;L;7469;;;;N;;;;;
+F9AF;CJK COMPATIBILITY IDEOGRAPH-F9AF;Lo;0;L;7F9A;;;;N;;;;;
+F9B0;CJK COMPATIBILITY IDEOGRAPH-F9B0;Lo;0;L;8046;;;;N;;;;;
+F9B1;CJK COMPATIBILITY IDEOGRAPH-F9B1;Lo;0;L;9234;;;;N;;;;;
+F9B2;CJK COMPATIBILITY IDEOGRAPH-F9B2;Lo;0;L;96F6;;;0;N;;;;;
+F9B3;CJK COMPATIBILITY IDEOGRAPH-F9B3;Lo;0;L;9748;;;;N;;;;;
+F9B4;CJK COMPATIBILITY IDEOGRAPH-F9B4;Lo;0;L;9818;;;;N;;;;;
+F9B5;CJK COMPATIBILITY IDEOGRAPH-F9B5;Lo;0;L;4F8B;;;;N;;;;;
+F9B6;CJK COMPATIBILITY IDEOGRAPH-F9B6;Lo;0;L;79AE;;;;N;;;;;
+F9B7;CJK COMPATIBILITY IDEOGRAPH-F9B7;Lo;0;L;91B4;;;;N;;;;;
+F9B8;CJK COMPATIBILITY IDEOGRAPH-F9B8;Lo;0;L;96B8;;;;N;;;;;
+F9B9;CJK COMPATIBILITY IDEOGRAPH-F9B9;Lo;0;L;60E1;;;;N;;;;;
+F9BA;CJK COMPATIBILITY IDEOGRAPH-F9BA;Lo;0;L;4E86;;;;N;;;;;
+F9BB;CJK COMPATIBILITY IDEOGRAPH-F9BB;Lo;0;L;50DA;;;;N;;;;;
+F9BC;CJK COMPATIBILITY IDEOGRAPH-F9BC;Lo;0;L;5BEE;;;;N;;;;;
+F9BD;CJK COMPATIBILITY IDEOGRAPH-F9BD;Lo;0;L;5C3F;;;;N;;;;;
+F9BE;CJK COMPATIBILITY IDEOGRAPH-F9BE;Lo;0;L;6599;;;;N;;;;;
+F9BF;CJK COMPATIBILITY IDEOGRAPH-F9BF;Lo;0;L;6A02;;;;N;;;;;
+F9C0;CJK COMPATIBILITY IDEOGRAPH-F9C0;Lo;0;L;71CE;;;;N;;;;;
+F9C1;CJK COMPATIBILITY IDEOGRAPH-F9C1;Lo;0;L;7642;;;;N;;;;;
+F9C2;CJK COMPATIBILITY IDEOGRAPH-F9C2;Lo;0;L;84FC;;;;N;;;;;
+F9C3;CJK COMPATIBILITY IDEOGRAPH-F9C3;Lo;0;L;907C;;;;N;;;;;
+F9C4;CJK COMPATIBILITY IDEOGRAPH-F9C4;Lo;0;L;9F8D;;;;N;;;;;
+F9C5;CJK COMPATIBILITY IDEOGRAPH-F9C5;Lo;0;L;6688;;;;N;;;;;
+F9C6;CJK COMPATIBILITY IDEOGRAPH-F9C6;Lo;0;L;962E;;;;N;;;;;
+F9C7;CJK COMPATIBILITY IDEOGRAPH-F9C7;Lo;0;L;5289;;;;N;;;;;
+F9C8;CJK COMPATIBILITY IDEOGRAPH-F9C8;Lo;0;L;677B;;;;N;;;;;
+F9C9;CJK COMPATIBILITY IDEOGRAPH-F9C9;Lo;0;L;67F3;;;;N;;;;;
+F9CA;CJK COMPATIBILITY IDEOGRAPH-F9CA;Lo;0;L;6D41;;;;N;;;;;
+F9CB;CJK COMPATIBILITY IDEOGRAPH-F9CB;Lo;0;L;6E9C;;;;N;;;;;
+F9CC;CJK COMPATIBILITY IDEOGRAPH-F9CC;Lo;0;L;7409;;;;N;;;;;
+F9CD;CJK COMPATIBILITY IDEOGRAPH-F9CD;Lo;0;L;7559;;;;N;;;;;
+F9CE;CJK COMPATIBILITY IDEOGRAPH-F9CE;Lo;0;L;786B;;;;N;;;;;
+F9CF;CJK COMPATIBILITY IDEOGRAPH-F9CF;Lo;0;L;7D10;;;;N;;;;;
+F9D0;CJK COMPATIBILITY IDEOGRAPH-F9D0;Lo;0;L;985E;;;;N;;;;;
+F9D1;CJK COMPATIBILITY IDEOGRAPH-F9D1;Lo;0;L;516D;;;6;N;;;;;
+F9D2;CJK COMPATIBILITY IDEOGRAPH-F9D2;Lo;0;L;622E;;;;N;;;;;
+F9D3;CJK COMPATIBILITY IDEOGRAPH-F9D3;Lo;0;L;9678;;;6;N;;;;;
+F9D4;CJK COMPATIBILITY IDEOGRAPH-F9D4;Lo;0;L;502B;;;;N;;;;;
+F9D5;CJK COMPATIBILITY IDEOGRAPH-F9D5;Lo;0;L;5D19;;;;N;;;;;
+F9D6;CJK COMPATIBILITY IDEOGRAPH-F9D6;Lo;0;L;6DEA;;;;N;;;;;
+F9D7;CJK COMPATIBILITY IDEOGRAPH-F9D7;Lo;0;L;8F2A;;;;N;;;;;
+F9D8;CJK COMPATIBILITY IDEOGRAPH-F9D8;Lo;0;L;5F8B;;;;N;;;;;
+F9D9;CJK COMPATIBILITY IDEOGRAPH-F9D9;Lo;0;L;6144;;;;N;;;;;
+F9DA;CJK COMPATIBILITY IDEOGRAPH-F9DA;Lo;0;L;6817;;;;N;;;;;
+F9DB;CJK COMPATIBILITY IDEOGRAPH-F9DB;Lo;0;L;7387;;;;N;;;;;
+F9DC;CJK COMPATIBILITY IDEOGRAPH-F9DC;Lo;0;L;9686;;;;N;;;;;
+F9DD;CJK COMPATIBILITY IDEOGRAPH-F9DD;Lo;0;L;5229;;;;N;;;;;
+F9DE;CJK COMPATIBILITY IDEOGRAPH-F9DE;Lo;0;L;540F;;;;N;;;;;
+F9DF;CJK COMPATIBILITY IDEOGRAPH-F9DF;Lo;0;L;5C65;;;;N;;;;;
+F9E0;CJK COMPATIBILITY IDEOGRAPH-F9E0;Lo;0;L;6613;;;;N;;;;;
+F9E1;CJK COMPATIBILITY IDEOGRAPH-F9E1;Lo;0;L;674E;;;;N;;;;;
+F9E2;CJK COMPATIBILITY IDEOGRAPH-F9E2;Lo;0;L;68A8;;;;N;;;;;
+F9E3;CJK COMPATIBILITY IDEOGRAPH-F9E3;Lo;0;L;6CE5;;;;N;;;;;
+F9E4;CJK COMPATIBILITY IDEOGRAPH-F9E4;Lo;0;L;7406;;;;N;;;;;
+F9E5;CJK COMPATIBILITY IDEOGRAPH-F9E5;Lo;0;L;75E2;;;;N;;;;;
+F9E6;CJK COMPATIBILITY IDEOGRAPH-F9E6;Lo;0;L;7F79;;;;N;;;;;
+F9E7;CJK COMPATIBILITY IDEOGRAPH-F9E7;Lo;0;L;88CF;;;;N;;;;;
+F9E8;CJK COMPATIBILITY IDEOGRAPH-F9E8;Lo;0;L;88E1;;;;N;;;;;
+F9E9;CJK COMPATIBILITY IDEOGRAPH-F9E9;Lo;0;L;91CC;;;;N;;;;;
+F9EA;CJK COMPATIBILITY IDEOGRAPH-F9EA;Lo;0;L;96E2;;;;N;;;;;
+F9EB;CJK COMPATIBILITY IDEOGRAPH-F9EB;Lo;0;L;533F;;;;N;;;;;
+F9EC;CJK COMPATIBILITY IDEOGRAPH-F9EC;Lo;0;L;6EBA;;;;N;;;;;
+F9ED;CJK COMPATIBILITY IDEOGRAPH-F9ED;Lo;0;L;541D;;;;N;;;;;
+F9EE;CJK COMPATIBILITY IDEOGRAPH-F9EE;Lo;0;L;71D0;;;;N;;;;;
+F9EF;CJK COMPATIBILITY IDEOGRAPH-F9EF;Lo;0;L;7498;;;;N;;;;;
+F9F0;CJK COMPATIBILITY IDEOGRAPH-F9F0;Lo;0;L;85FA;;;;N;;;;;
+F9F1;CJK COMPATIBILITY IDEOGRAPH-F9F1;Lo;0;L;96A3;;;;N;;;;;
+F9F2;CJK COMPATIBILITY IDEOGRAPH-F9F2;Lo;0;L;9C57;;;;N;;;;;
+F9F3;CJK COMPATIBILITY IDEOGRAPH-F9F3;Lo;0;L;9E9F;;;;N;;;;;
+F9F4;CJK COMPATIBILITY IDEOGRAPH-F9F4;Lo;0;L;6797;;;;N;;;;;
+F9F5;CJK COMPATIBILITY IDEOGRAPH-F9F5;Lo;0;L;6DCB;;;;N;;;;;
+F9F6;CJK COMPATIBILITY IDEOGRAPH-F9F6;Lo;0;L;81E8;;;;N;;;;;
+F9F7;CJK COMPATIBILITY IDEOGRAPH-F9F7;Lo;0;L;7ACB;;;;N;;;;;
+F9F8;CJK COMPATIBILITY IDEOGRAPH-F9F8;Lo;0;L;7B20;;;;N;;;;;
+F9F9;CJK COMPATIBILITY IDEOGRAPH-F9F9;Lo;0;L;7C92;;;;N;;;;;
+F9FA;CJK COMPATIBILITY IDEOGRAPH-F9FA;Lo;0;L;72C0;;;;N;;;;;
+F9FB;CJK COMPATIBILITY IDEOGRAPH-F9FB;Lo;0;L;7099;;;;N;;;;;
+F9FC;CJK COMPATIBILITY IDEOGRAPH-F9FC;Lo;0;L;8B58;;;;N;;;;;
+F9FD;CJK COMPATIBILITY IDEOGRAPH-F9FD;Lo;0;L;4EC0;;;10;N;;;;;
+F9FE;CJK COMPATIBILITY IDEOGRAPH-F9FE;Lo;0;L;8336;;;;N;;;;;
+F9FF;CJK COMPATIBILITY IDEOGRAPH-F9FF;Lo;0;L;523A;;;;N;;;;;
+FA00;CJK COMPATIBILITY IDEOGRAPH-FA00;Lo;0;L;5207;;;;N;;;;;
+FA01;CJK COMPATIBILITY IDEOGRAPH-FA01;Lo;0;L;5EA6;;;;N;;;;;
+FA02;CJK COMPATIBILITY IDEOGRAPH-FA02;Lo;0;L;62D3;;;;N;;;;;
+FA03;CJK COMPATIBILITY IDEOGRAPH-FA03;Lo;0;L;7CD6;;;;N;;;;;
+FA04;CJK COMPATIBILITY IDEOGRAPH-FA04;Lo;0;L;5B85;;;;N;;;;;
+FA05;CJK COMPATIBILITY IDEOGRAPH-FA05;Lo;0;L;6D1E;;;;N;;;;;
+FA06;CJK COMPATIBILITY IDEOGRAPH-FA06;Lo;0;L;66B4;;;;N;;;;;
+FA07;CJK COMPATIBILITY IDEOGRAPH-FA07;Lo;0;L;8F3B;;;;N;;;;;
+FA08;CJK COMPATIBILITY IDEOGRAPH-FA08;Lo;0;L;884C;;;;N;;;;;
+FA09;CJK COMPATIBILITY IDEOGRAPH-FA09;Lo;0;L;964D;;;;N;;;;;
+FA0A;CJK COMPATIBILITY IDEOGRAPH-FA0A;Lo;0;L;898B;;;;N;;;;;
+FA0B;CJK COMPATIBILITY IDEOGRAPH-FA0B;Lo;0;L;5ED3;;;;N;;;;;
+FA0C;CJK COMPATIBILITY IDEOGRAPH-FA0C;Lo;0;L;5140;;;;N;;;;;
+FA0D;CJK COMPATIBILITY IDEOGRAPH-FA0D;Lo;0;L;55C0;;;;N;;;;;
+FA0E;CJK COMPATIBILITY IDEOGRAPH-FA0E;Lo;0;L;;;;;N;;;;;
+FA0F;CJK COMPATIBILITY IDEOGRAPH-FA0F;Lo;0;L;;;;;N;;;;;
+FA10;CJK COMPATIBILITY IDEOGRAPH-FA10;Lo;0;L;585A;;;;N;;;;;
+FA11;CJK COMPATIBILITY IDEOGRAPH-FA11;Lo;0;L;;;;;N;;;;;
+FA12;CJK COMPATIBILITY IDEOGRAPH-FA12;Lo;0;L;6674;;;;N;;;;;
+FA13;CJK COMPATIBILITY IDEOGRAPH-FA13;Lo;0;L;;;;;N;;;;;
+FA14;CJK COMPATIBILITY IDEOGRAPH-FA14;Lo;0;L;;;;;N;;;;;
+FA15;CJK COMPATIBILITY IDEOGRAPH-FA15;Lo;0;L;51DE;;;;N;;;;;
+FA16;CJK COMPATIBILITY IDEOGRAPH-FA16;Lo;0;L;732A;;;;N;;;;;
+FA17;CJK COMPATIBILITY IDEOGRAPH-FA17;Lo;0;L;76CA;;;;N;;;;;
+FA18;CJK COMPATIBILITY IDEOGRAPH-FA18;Lo;0;L;793C;;;;N;;;;;
+FA19;CJK COMPATIBILITY IDEOGRAPH-FA19;Lo;0;L;795E;;;;N;;;;;
+FA1A;CJK COMPATIBILITY IDEOGRAPH-FA1A;Lo;0;L;7965;;;;N;;;;;
+FA1B;CJK COMPATIBILITY IDEOGRAPH-FA1B;Lo;0;L;798F;;;;N;;;;;
+FA1C;CJK COMPATIBILITY IDEOGRAPH-FA1C;Lo;0;L;9756;;;;N;;;;;
+FA1D;CJK COMPATIBILITY IDEOGRAPH-FA1D;Lo;0;L;7CBE;;;;N;;;;;
+FA1E;CJK COMPATIBILITY IDEOGRAPH-FA1E;Lo;0;L;7FBD;;;;N;;;;;
+FA1F;CJK COMPATIBILITY IDEOGRAPH-FA1F;Lo;0;L;;;;;N;;;;;
+FA20;CJK COMPATIBILITY IDEOGRAPH-FA20;Lo;0;L;8612;;;;N;;;;;
+FA21;CJK COMPATIBILITY IDEOGRAPH-FA21;Lo;0;L;;;;;N;;;;;
+FA22;CJK COMPATIBILITY IDEOGRAPH-FA22;Lo;0;L;8AF8;;;;N;;;;;
+FA23;CJK COMPATIBILITY IDEOGRAPH-FA23;Lo;0;L;;;;;N;;;;;
+FA24;CJK COMPATIBILITY IDEOGRAPH-FA24;Lo;0;L;;;;;N;;;;;
+FA25;CJK COMPATIBILITY IDEOGRAPH-FA25;Lo;0;L;9038;;;;N;;;;;
+FA26;CJK COMPATIBILITY IDEOGRAPH-FA26;Lo;0;L;90FD;;;;N;;;;;
+FA27;CJK COMPATIBILITY IDEOGRAPH-FA27;Lo;0;L;;;;;N;;;;;
+FA28;CJK COMPATIBILITY IDEOGRAPH-FA28;Lo;0;L;;;;;N;;;;;
+FA29;CJK COMPATIBILITY IDEOGRAPH-FA29;Lo;0;L;;;;;N;;;;;
+FA2A;CJK COMPATIBILITY IDEOGRAPH-FA2A;Lo;0;L;98EF;;;;N;;;;;
+FA2B;CJK COMPATIBILITY IDEOGRAPH-FA2B;Lo;0;L;98FC;;;;N;;;;;
+FA2C;CJK COMPATIBILITY IDEOGRAPH-FA2C;Lo;0;L;9928;;;;N;;;;;
+FA2D;CJK COMPATIBILITY IDEOGRAPH-FA2D;Lo;0;L;9DB4;;;;N;;;;;
+FA30;CJK COMPATIBILITY IDEOGRAPH-FA30;Lo;0;L;4FAE;;;;N;;;;;
+FA31;CJK COMPATIBILITY IDEOGRAPH-FA31;Lo;0;L;50E7;;;;N;;;;;
+FA32;CJK COMPATIBILITY IDEOGRAPH-FA32;Lo;0;L;514D;;;;N;;;;;
+FA33;CJK COMPATIBILITY IDEOGRAPH-FA33;Lo;0;L;52C9;;;;N;;;;;
+FA34;CJK COMPATIBILITY IDEOGRAPH-FA34;Lo;0;L;52E4;;;;N;;;;;
+FA35;CJK COMPATIBILITY IDEOGRAPH-FA35;Lo;0;L;5351;;;;N;;;;;
+FA36;CJK COMPATIBILITY IDEOGRAPH-FA36;Lo;0;L;559D;;;;N;;;;;
+FA37;CJK COMPATIBILITY IDEOGRAPH-FA37;Lo;0;L;5606;;;;N;;;;;
+FA38;CJK COMPATIBILITY IDEOGRAPH-FA38;Lo;0;L;5668;;;;N;;;;;
+FA39;CJK COMPATIBILITY IDEOGRAPH-FA39;Lo;0;L;5840;;;;N;;;;;
+FA3A;CJK COMPATIBILITY IDEOGRAPH-FA3A;Lo;0;L;58A8;;;;N;;;;;
+FA3B;CJK COMPATIBILITY IDEOGRAPH-FA3B;Lo;0;L;5C64;;;;N;;;;;
+FA3C;CJK COMPATIBILITY IDEOGRAPH-FA3C;Lo;0;L;5C6E;;;;N;;;;;
+FA3D;CJK COMPATIBILITY IDEOGRAPH-FA3D;Lo;0;L;6094;;;;N;;;;;
+FA3E;CJK COMPATIBILITY IDEOGRAPH-FA3E;Lo;0;L;6168;;;;N;;;;;
+FA3F;CJK COMPATIBILITY IDEOGRAPH-FA3F;Lo;0;L;618E;;;;N;;;;;
+FA40;CJK COMPATIBILITY IDEOGRAPH-FA40;Lo;0;L;61F2;;;;N;;;;;
+FA41;CJK COMPATIBILITY IDEOGRAPH-FA41;Lo;0;L;654F;;;;N;;;;;
+FA42;CJK COMPATIBILITY IDEOGRAPH-FA42;Lo;0;L;65E2;;;;N;;;;;
+FA43;CJK COMPATIBILITY IDEOGRAPH-FA43;Lo;0;L;6691;;;;N;;;;;
+FA44;CJK COMPATIBILITY IDEOGRAPH-FA44;Lo;0;L;6885;;;;N;;;;;
+FA45;CJK COMPATIBILITY IDEOGRAPH-FA45;Lo;0;L;6D77;;;;N;;;;;
+FA46;CJK COMPATIBILITY IDEOGRAPH-FA46;Lo;0;L;6E1A;;;;N;;;;;
+FA47;CJK COMPATIBILITY IDEOGRAPH-FA47;Lo;0;L;6F22;;;;N;;;;;
+FA48;CJK COMPATIBILITY IDEOGRAPH-FA48;Lo;0;L;716E;;;;N;;;;;
+FA49;CJK COMPATIBILITY IDEOGRAPH-FA49;Lo;0;L;722B;;;;N;;;;;
+FA4A;CJK COMPATIBILITY IDEOGRAPH-FA4A;Lo;0;L;7422;;;;N;;;;;
+FA4B;CJK COMPATIBILITY IDEOGRAPH-FA4B;Lo;0;L;7891;;;;N;;;;;
+FA4C;CJK COMPATIBILITY IDEOGRAPH-FA4C;Lo;0;L;793E;;;;N;;;;;
+FA4D;CJK COMPATIBILITY IDEOGRAPH-FA4D;Lo;0;L;7949;;;;N;;;;;
+FA4E;CJK COMPATIBILITY IDEOGRAPH-FA4E;Lo;0;L;7948;;;;N;;;;;
+FA4F;CJK COMPATIBILITY IDEOGRAPH-FA4F;Lo;0;L;7950;;;;N;;;;;
+FA50;CJK COMPATIBILITY IDEOGRAPH-FA50;Lo;0;L;7956;;;;N;;;;;
+FA51;CJK COMPATIBILITY IDEOGRAPH-FA51;Lo;0;L;795D;;;;N;;;;;
+FA52;CJK COMPATIBILITY IDEOGRAPH-FA52;Lo;0;L;798D;;;;N;;;;;
+FA53;CJK COMPATIBILITY IDEOGRAPH-FA53;Lo;0;L;798E;;;;N;;;;;
+FA54;CJK COMPATIBILITY IDEOGRAPH-FA54;Lo;0;L;7A40;;;;N;;;;;
+FA55;CJK COMPATIBILITY IDEOGRAPH-FA55;Lo;0;L;7A81;;;;N;;;;;
+FA56;CJK COMPATIBILITY IDEOGRAPH-FA56;Lo;0;L;7BC0;;;;N;;;;;
+FA57;CJK COMPATIBILITY IDEOGRAPH-FA57;Lo;0;L;7DF4;;;;N;;;;;
+FA58;CJK COMPATIBILITY IDEOGRAPH-FA58;Lo;0;L;7E09;;;;N;;;;;
+FA59;CJK COMPATIBILITY IDEOGRAPH-FA59;Lo;0;L;7E41;;;;N;;;;;
+FA5A;CJK COMPATIBILITY IDEOGRAPH-FA5A;Lo;0;L;7F72;;;;N;;;;;
+FA5B;CJK COMPATIBILITY IDEOGRAPH-FA5B;Lo;0;L;8005;;;;N;;;;;
+FA5C;CJK COMPATIBILITY IDEOGRAPH-FA5C;Lo;0;L;81ED;;;;N;;;;;
+FA5D;CJK COMPATIBILITY IDEOGRAPH-FA5D;Lo;0;L;8279;;;;N;;;;;
+FA5E;CJK COMPATIBILITY IDEOGRAPH-FA5E;Lo;0;L;8279;;;;N;;;;;
+FA5F;CJK COMPATIBILITY IDEOGRAPH-FA5F;Lo;0;L;8457;;;;N;;;;;
+FA60;CJK COMPATIBILITY IDEOGRAPH-FA60;Lo;0;L;8910;;;;N;;;;;
+FA61;CJK COMPATIBILITY IDEOGRAPH-FA61;Lo;0;L;8996;;;;N;;;;;
+FA62;CJK COMPATIBILITY IDEOGRAPH-FA62;Lo;0;L;8B01;;;;N;;;;;
+FA63;CJK COMPATIBILITY IDEOGRAPH-FA63;Lo;0;L;8B39;;;;N;;;;;
+FA64;CJK COMPATIBILITY IDEOGRAPH-FA64;Lo;0;L;8CD3;;;;N;;;;;
+FA65;CJK COMPATIBILITY IDEOGRAPH-FA65;Lo;0;L;8D08;;;;N;;;;;
+FA66;CJK COMPATIBILITY IDEOGRAPH-FA66;Lo;0;L;8FB6;;;;N;;;;;
+FA67;CJK COMPATIBILITY IDEOGRAPH-FA67;Lo;0;L;9038;;;;N;;;;;
+FA68;CJK COMPATIBILITY IDEOGRAPH-FA68;Lo;0;L;96E3;;;;N;;;;;
+FA69;CJK COMPATIBILITY IDEOGRAPH-FA69;Lo;0;L;97FF;;;;N;;;;;
+FA6A;CJK COMPATIBILITY IDEOGRAPH-FA6A;Lo;0;L;983B;;;;N;;;;;
+FA6B;CJK COMPATIBILITY IDEOGRAPH-FA6B;Lo;0;L;6075;;;;N;;;;;
+FA6C;CJK COMPATIBILITY IDEOGRAPH-FA6C;Lo;0;L;242EE;;;;N;;;;;
+FA6D;CJK COMPATIBILITY IDEOGRAPH-FA6D;Lo;0;L;8218;;;;N;;;;;
+FA70;CJK COMPATIBILITY IDEOGRAPH-FA70;Lo;0;L;4E26;;;;N;;;;;
+FA71;CJK COMPATIBILITY IDEOGRAPH-FA71;Lo;0;L;51B5;;;;N;;;;;
+FA72;CJK COMPATIBILITY IDEOGRAPH-FA72;Lo;0;L;5168;;;;N;;;;;
+FA73;CJK COMPATIBILITY IDEOGRAPH-FA73;Lo;0;L;4F80;;;;N;;;;;
+FA74;CJK COMPATIBILITY IDEOGRAPH-FA74;Lo;0;L;5145;;;;N;;;;;
+FA75;CJK COMPATIBILITY IDEOGRAPH-FA75;Lo;0;L;5180;;;;N;;;;;
+FA76;CJK COMPATIBILITY IDEOGRAPH-FA76;Lo;0;L;52C7;;;;N;;;;;
+FA77;CJK COMPATIBILITY IDEOGRAPH-FA77;Lo;0;L;52FA;;;;N;;;;;
+FA78;CJK COMPATIBILITY IDEOGRAPH-FA78;Lo;0;L;559D;;;;N;;;;;
+FA79;CJK COMPATIBILITY IDEOGRAPH-FA79;Lo;0;L;5555;;;;N;;;;;
+FA7A;CJK COMPATIBILITY IDEOGRAPH-FA7A;Lo;0;L;5599;;;;N;;;;;
+FA7B;CJK COMPATIBILITY IDEOGRAPH-FA7B;Lo;0;L;55E2;;;;N;;;;;
+FA7C;CJK COMPATIBILITY IDEOGRAPH-FA7C;Lo;0;L;585A;;;;N;;;;;
+FA7D;CJK COMPATIBILITY IDEOGRAPH-FA7D;Lo;0;L;58B3;;;;N;;;;;
+FA7E;CJK COMPATIBILITY IDEOGRAPH-FA7E;Lo;0;L;5944;;;;N;;;;;
+FA7F;CJK COMPATIBILITY IDEOGRAPH-FA7F;Lo;0;L;5954;;;;N;;;;;
+FA80;CJK COMPATIBILITY IDEOGRAPH-FA80;Lo;0;L;5A62;;;;N;;;;;
+FA81;CJK COMPATIBILITY IDEOGRAPH-FA81;Lo;0;L;5B28;;;;N;;;;;
+FA82;CJK COMPATIBILITY IDEOGRAPH-FA82;Lo;0;L;5ED2;;;;N;;;;;
+FA83;CJK COMPATIBILITY IDEOGRAPH-FA83;Lo;0;L;5ED9;;;;N;;;;;
+FA84;CJK COMPATIBILITY IDEOGRAPH-FA84;Lo;0;L;5F69;;;;N;;;;;
+FA85;CJK COMPATIBILITY IDEOGRAPH-FA85;Lo;0;L;5FAD;;;;N;;;;;
+FA86;CJK COMPATIBILITY IDEOGRAPH-FA86;Lo;0;L;60D8;;;;N;;;;;
+FA87;CJK COMPATIBILITY IDEOGRAPH-FA87;Lo;0;L;614E;;;;N;;;;;
+FA88;CJK COMPATIBILITY IDEOGRAPH-FA88;Lo;0;L;6108;;;;N;;;;;
+FA89;CJK COMPATIBILITY IDEOGRAPH-FA89;Lo;0;L;618E;;;;N;;;;;
+FA8A;CJK COMPATIBILITY IDEOGRAPH-FA8A;Lo;0;L;6160;;;;N;;;;;
+FA8B;CJK COMPATIBILITY IDEOGRAPH-FA8B;Lo;0;L;61F2;;;;N;;;;;
+FA8C;CJK COMPATIBILITY IDEOGRAPH-FA8C;Lo;0;L;6234;;;;N;;;;;
+FA8D;CJK COMPATIBILITY IDEOGRAPH-FA8D;Lo;0;L;63C4;;;;N;;;;;
+FA8E;CJK COMPATIBILITY IDEOGRAPH-FA8E;Lo;0;L;641C;;;;N;;;;;
+FA8F;CJK COMPATIBILITY IDEOGRAPH-FA8F;Lo;0;L;6452;;;;N;;;;;
+FA90;CJK COMPATIBILITY IDEOGRAPH-FA90;Lo;0;L;6556;;;;N;;;;;
+FA91;CJK COMPATIBILITY IDEOGRAPH-FA91;Lo;0;L;6674;;;;N;;;;;
+FA92;CJK COMPATIBILITY IDEOGRAPH-FA92;Lo;0;L;6717;;;;N;;;;;
+FA93;CJK COMPATIBILITY IDEOGRAPH-FA93;Lo;0;L;671B;;;;N;;;;;
+FA94;CJK COMPATIBILITY IDEOGRAPH-FA94;Lo;0;L;6756;;;;N;;;;;
+FA95;CJK COMPATIBILITY IDEOGRAPH-FA95;Lo;0;L;6B79;;;;N;;;;;
+FA96;CJK COMPATIBILITY IDEOGRAPH-FA96;Lo;0;L;6BBA;;;;N;;;;;
+FA97;CJK COMPATIBILITY IDEOGRAPH-FA97;Lo;0;L;6D41;;;;N;;;;;
+FA98;CJK COMPATIBILITY IDEOGRAPH-FA98;Lo;0;L;6EDB;;;;N;;;;;
+FA99;CJK COMPATIBILITY IDEOGRAPH-FA99;Lo;0;L;6ECB;;;;N;;;;;
+FA9A;CJK COMPATIBILITY IDEOGRAPH-FA9A;Lo;0;L;6F22;;;;N;;;;;
+FA9B;CJK COMPATIBILITY IDEOGRAPH-FA9B;Lo;0;L;701E;;;;N;;;;;
+FA9C;CJK COMPATIBILITY IDEOGRAPH-FA9C;Lo;0;L;716E;;;;N;;;;;
+FA9D;CJK COMPATIBILITY IDEOGRAPH-FA9D;Lo;0;L;77A7;;;;N;;;;;
+FA9E;CJK COMPATIBILITY IDEOGRAPH-FA9E;Lo;0;L;7235;;;;N;;;;;
+FA9F;CJK COMPATIBILITY IDEOGRAPH-FA9F;Lo;0;L;72AF;;;;N;;;;;
+FAA0;CJK COMPATIBILITY IDEOGRAPH-FAA0;Lo;0;L;732A;;;;N;;;;;
+FAA1;CJK COMPATIBILITY IDEOGRAPH-FAA1;Lo;0;L;7471;;;;N;;;;;
+FAA2;CJK COMPATIBILITY IDEOGRAPH-FAA2;Lo;0;L;7506;;;;N;;;;;
+FAA3;CJK COMPATIBILITY IDEOGRAPH-FAA3;Lo;0;L;753B;;;;N;;;;;
+FAA4;CJK COMPATIBILITY IDEOGRAPH-FAA4;Lo;0;L;761D;;;;N;;;;;
+FAA5;CJK COMPATIBILITY IDEOGRAPH-FAA5;Lo;0;L;761F;;;;N;;;;;
+FAA6;CJK COMPATIBILITY IDEOGRAPH-FAA6;Lo;0;L;76CA;;;;N;;;;;
+FAA7;CJK COMPATIBILITY IDEOGRAPH-FAA7;Lo;0;L;76DB;;;;N;;;;;
+FAA8;CJK COMPATIBILITY IDEOGRAPH-FAA8;Lo;0;L;76F4;;;;N;;;;;
+FAA9;CJK COMPATIBILITY IDEOGRAPH-FAA9;Lo;0;L;774A;;;;N;;;;;
+FAAA;CJK COMPATIBILITY IDEOGRAPH-FAAA;Lo;0;L;7740;;;;N;;;;;
+FAAB;CJK COMPATIBILITY IDEOGRAPH-FAAB;Lo;0;L;78CC;;;;N;;;;;
+FAAC;CJK COMPATIBILITY IDEOGRAPH-FAAC;Lo;0;L;7AB1;;;;N;;;;;
+FAAD;CJK COMPATIBILITY IDEOGRAPH-FAAD;Lo;0;L;7BC0;;;;N;;;;;
+FAAE;CJK COMPATIBILITY IDEOGRAPH-FAAE;Lo;0;L;7C7B;;;;N;;;;;
+FAAF;CJK COMPATIBILITY IDEOGRAPH-FAAF;Lo;0;L;7D5B;;;;N;;;;;
+FAB0;CJK COMPATIBILITY IDEOGRAPH-FAB0;Lo;0;L;7DF4;;;;N;;;;;
+FAB1;CJK COMPATIBILITY IDEOGRAPH-FAB1;Lo;0;L;7F3E;;;;N;;;;;
+FAB2;CJK COMPATIBILITY IDEOGRAPH-FAB2;Lo;0;L;8005;;;;N;;;;;
+FAB3;CJK COMPATIBILITY IDEOGRAPH-FAB3;Lo;0;L;8352;;;;N;;;;;
+FAB4;CJK COMPATIBILITY IDEOGRAPH-FAB4;Lo;0;L;83EF;;;;N;;;;;
+FAB5;CJK COMPATIBILITY IDEOGRAPH-FAB5;Lo;0;L;8779;;;;N;;;;;
+FAB6;CJK COMPATIBILITY IDEOGRAPH-FAB6;Lo;0;L;8941;;;;N;;;;;
+FAB7;CJK COMPATIBILITY IDEOGRAPH-FAB7;Lo;0;L;8986;;;;N;;;;;
+FAB8;CJK COMPATIBILITY IDEOGRAPH-FAB8;Lo;0;L;8996;;;;N;;;;;
+FAB9;CJK COMPATIBILITY IDEOGRAPH-FAB9;Lo;0;L;8ABF;;;;N;;;;;
+FABA;CJK COMPATIBILITY IDEOGRAPH-FABA;Lo;0;L;8AF8;;;;N;;;;;
+FABB;CJK COMPATIBILITY IDEOGRAPH-FABB;Lo;0;L;8ACB;;;;N;;;;;
+FABC;CJK COMPATIBILITY IDEOGRAPH-FABC;Lo;0;L;8B01;;;;N;;;;;
+FABD;CJK COMPATIBILITY IDEOGRAPH-FABD;Lo;0;L;8AFE;;;;N;;;;;
+FABE;CJK COMPATIBILITY IDEOGRAPH-FABE;Lo;0;L;8AED;;;;N;;;;;
+FABF;CJK COMPATIBILITY IDEOGRAPH-FABF;Lo;0;L;8B39;;;;N;;;;;
+FAC0;CJK COMPATIBILITY IDEOGRAPH-FAC0;Lo;0;L;8B8A;;;;N;;;;;
+FAC1;CJK COMPATIBILITY IDEOGRAPH-FAC1;Lo;0;L;8D08;;;;N;;;;;
+FAC2;CJK COMPATIBILITY IDEOGRAPH-FAC2;Lo;0;L;8F38;;;;N;;;;;
+FAC3;CJK COMPATIBILITY IDEOGRAPH-FAC3;Lo;0;L;9072;;;;N;;;;;
+FAC4;CJK COMPATIBILITY IDEOGRAPH-FAC4;Lo;0;L;9199;;;;N;;;;;
+FAC5;CJK COMPATIBILITY IDEOGRAPH-FAC5;Lo;0;L;9276;;;;N;;;;;
+FAC6;CJK COMPATIBILITY IDEOGRAPH-FAC6;Lo;0;L;967C;;;;N;;;;;
+FAC7;CJK COMPATIBILITY IDEOGRAPH-FAC7;Lo;0;L;96E3;;;;N;;;;;
+FAC8;CJK COMPATIBILITY IDEOGRAPH-FAC8;Lo;0;L;9756;;;;N;;;;;
+FAC9;CJK COMPATIBILITY IDEOGRAPH-FAC9;Lo;0;L;97DB;;;;N;;;;;
+FACA;CJK COMPATIBILITY IDEOGRAPH-FACA;Lo;0;L;97FF;;;;N;;;;;
+FACB;CJK COMPATIBILITY IDEOGRAPH-FACB;Lo;0;L;980B;;;;N;;;;;
+FACC;CJK COMPATIBILITY IDEOGRAPH-FACC;Lo;0;L;983B;;;;N;;;;;
+FACD;CJK COMPATIBILITY IDEOGRAPH-FACD;Lo;0;L;9B12;;;;N;;;;;
+FACE;CJK COMPATIBILITY IDEOGRAPH-FACE;Lo;0;L;9F9C;;;;N;;;;;
+FACF;CJK COMPATIBILITY IDEOGRAPH-FACF;Lo;0;L;2284A;;;;N;;;;;
+FAD0;CJK COMPATIBILITY IDEOGRAPH-FAD0;Lo;0;L;22844;;;;N;;;;;
+FAD1;CJK COMPATIBILITY IDEOGRAPH-FAD1;Lo;0;L;233D5;;;;N;;;;;
+FAD2;CJK COMPATIBILITY IDEOGRAPH-FAD2;Lo;0;L;3B9D;;;;N;;;;;
+FAD3;CJK COMPATIBILITY IDEOGRAPH-FAD3;Lo;0;L;4018;;;;N;;;;;
+FAD4;CJK COMPATIBILITY IDEOGRAPH-FAD4;Lo;0;L;4039;;;;N;;;;;
+FAD5;CJK COMPATIBILITY IDEOGRAPH-FAD5;Lo;0;L;25249;;;;N;;;;;
+FAD6;CJK COMPATIBILITY IDEOGRAPH-FAD6;Lo;0;L;25CD0;;;;N;;;;;
+FAD7;CJK COMPATIBILITY IDEOGRAPH-FAD7;Lo;0;L;27ED3;;;;N;;;;;
+FAD8;CJK COMPATIBILITY IDEOGRAPH-FAD8;Lo;0;L;9F43;;;;N;;;;;
+FAD9;CJK COMPATIBILITY IDEOGRAPH-FAD9;Lo;0;L;9F8E;;;;N;;;;;
+FB00;LATIN SMALL LIGATURE FF;Ll;0;L;<compat> 0066 0066;;;;N;;;;;
+FB01;LATIN SMALL LIGATURE FI;Ll;0;L;<compat> 0066 0069;;;;N;;;;;
+FB02;LATIN SMALL LIGATURE FL;Ll;0;L;<compat> 0066 006C;;;;N;;;;;
+FB03;LATIN SMALL LIGATURE FFI;Ll;0;L;<compat> 0066 0066 0069;;;;N;;;;;
+FB04;LATIN SMALL LIGATURE FFL;Ll;0;L;<compat> 0066 0066 006C;;;;N;;;;;
+FB05;LATIN SMALL LIGATURE LONG S T;Ll;0;L;<compat> 017F 0074;;;;N;;;;;
+FB06;LATIN SMALL LIGATURE ST;Ll;0;L;<compat> 0073 0074;;;;N;;;;;
+FB13;ARMENIAN SMALL LIGATURE MEN NOW;Ll;0;L;<compat> 0574 0576;;;;N;;;;;
+FB14;ARMENIAN SMALL LIGATURE MEN ECH;Ll;0;L;<compat> 0574 0565;;;;N;;;;;
+FB15;ARMENIAN SMALL LIGATURE MEN INI;Ll;0;L;<compat> 0574 056B;;;;N;;;;;
+FB16;ARMENIAN SMALL LIGATURE VEW NOW;Ll;0;L;<compat> 057E 0576;;;;N;;;;;
+FB17;ARMENIAN SMALL LIGATURE MEN XEH;Ll;0;L;<compat> 0574 056D;;;;N;;;;;
+FB1D;HEBREW LETTER YOD WITH HIRIQ;Lo;0;R;05D9 05B4;;;;N;;;;;
+FB1E;HEBREW POINT JUDEO-SPANISH VARIKA;Mn;26;NSM;;;;;N;HEBREW POINT VARIKA;;;;
+FB1F;HEBREW LIGATURE YIDDISH YOD YOD PATAH;Lo;0;R;05F2 05B7;;;;N;;;;;
+FB20;HEBREW LETTER ALTERNATIVE AYIN;Lo;0;R;<font> 05E2;;;;N;;;;;
+FB21;HEBREW LETTER WIDE ALEF;Lo;0;R;<font> 05D0;;;;N;;;;;
+FB22;HEBREW LETTER WIDE DALET;Lo;0;R;<font> 05D3;;;;N;;;;;
+FB23;HEBREW LETTER WIDE HE;Lo;0;R;<font> 05D4;;;;N;;;;;
+FB24;HEBREW LETTER WIDE KAF;Lo;0;R;<font> 05DB;;;;N;;;;;
+FB25;HEBREW LETTER WIDE LAMED;Lo;0;R;<font> 05DC;;;;N;;;;;
+FB26;HEBREW LETTER WIDE FINAL MEM;Lo;0;R;<font> 05DD;;;;N;;;;;
+FB27;HEBREW LETTER WIDE RESH;Lo;0;R;<font> 05E8;;;;N;;;;;
+FB28;HEBREW LETTER WIDE TAV;Lo;0;R;<font> 05EA;;;;N;;;;;
+FB29;HEBREW LETTER ALTERNATIVE PLUS SIGN;Sm;0;ES;<font> 002B;;;;N;;;;;
+FB2A;HEBREW LETTER SHIN WITH SHIN DOT;Lo;0;R;05E9 05C1;;;;N;;;;;
+FB2B;HEBREW LETTER SHIN WITH SIN DOT;Lo;0;R;05E9 05C2;;;;N;;;;;
+FB2C;HEBREW LETTER SHIN WITH DAGESH AND SHIN DOT;Lo;0;R;FB49 05C1;;;;N;;;;;
+FB2D;HEBREW LETTER SHIN WITH DAGESH AND SIN DOT;Lo;0;R;FB49 05C2;;;;N;;;;;
+FB2E;HEBREW LETTER ALEF WITH PATAH;Lo;0;R;05D0 05B7;;;;N;;;;;
+FB2F;HEBREW LETTER ALEF WITH QAMATS;Lo;0;R;05D0 05B8;;;;N;;;;;
+FB30;HEBREW LETTER ALEF WITH MAPIQ;Lo;0;R;05D0 05BC;;;;N;;;;;
+FB31;HEBREW LETTER BET WITH DAGESH;Lo;0;R;05D1 05BC;;;;N;;;;;
+FB32;HEBREW LETTER GIMEL WITH DAGESH;Lo;0;R;05D2 05BC;;;;N;;;;;
+FB33;HEBREW LETTER DALET WITH DAGESH;Lo;0;R;05D3 05BC;;;;N;;;;;
+FB34;HEBREW LETTER HE WITH MAPIQ;Lo;0;R;05D4 05BC;;;;N;;;;;
+FB35;HEBREW LETTER VAV WITH DAGESH;Lo;0;R;05D5 05BC;;;;N;;;;;
+FB36;HEBREW LETTER ZAYIN WITH DAGESH;Lo;0;R;05D6 05BC;;;;N;;;;;
+FB38;HEBREW LETTER TET WITH DAGESH;Lo;0;R;05D8 05BC;;;;N;;;;;
+FB39;HEBREW LETTER YOD WITH DAGESH;Lo;0;R;05D9 05BC;;;;N;;;;;
+FB3A;HEBREW LETTER FINAL KAF WITH DAGESH;Lo;0;R;05DA 05BC;;;;N;;;;;
+FB3B;HEBREW LETTER KAF WITH DAGESH;Lo;0;R;05DB 05BC;;;;N;;;;;
+FB3C;HEBREW LETTER LAMED WITH DAGESH;Lo;0;R;05DC 05BC;;;;N;;;;;
+FB3E;HEBREW LETTER MEM WITH DAGESH;Lo;0;R;05DE 05BC;;;;N;;;;;
+FB40;HEBREW LETTER NUN WITH DAGESH;Lo;0;R;05E0 05BC;;;;N;;;;;
+FB41;HEBREW LETTER SAMEKH WITH DAGESH;Lo;0;R;05E1 05BC;;;;N;;;;;
+FB43;HEBREW LETTER FINAL PE WITH DAGESH;Lo;0;R;05E3 05BC;;;;N;;;;;
+FB44;HEBREW LETTER PE WITH DAGESH;Lo;0;R;05E4 05BC;;;;N;;;;;
+FB46;HEBREW LETTER TSADI WITH DAGESH;Lo;0;R;05E6 05BC;;;;N;;;;;
+FB47;HEBREW LETTER QOF WITH DAGESH;Lo;0;R;05E7 05BC;;;;N;;;;;
+FB48;HEBREW LETTER RESH WITH DAGESH;Lo;0;R;05E8 05BC;;;;N;;;;;
+FB49;HEBREW LETTER SHIN WITH DAGESH;Lo;0;R;05E9 05BC;;;;N;;;;;
+FB4A;HEBREW LETTER TAV WITH DAGESH;Lo;0;R;05EA 05BC;;;;N;;;;;
+FB4B;HEBREW LETTER VAV WITH HOLAM;Lo;0;R;05D5 05B9;;;;N;;;;;
+FB4C;HEBREW LETTER BET WITH RAFE;Lo;0;R;05D1 05BF;;;;N;;;;;
+FB4D;HEBREW LETTER KAF WITH RAFE;Lo;0;R;05DB 05BF;;;;N;;;;;
+FB4E;HEBREW LETTER PE WITH RAFE;Lo;0;R;05E4 05BF;;;;N;;;;;
+FB4F;HEBREW LIGATURE ALEF LAMED;Lo;0;R;<compat> 05D0 05DC;;;;N;;;;;
+FB50;ARABIC LETTER ALEF WASLA ISOLATED FORM;Lo;0;AL;<isolated> 0671;;;;N;;;;;
+FB51;ARABIC LETTER ALEF WASLA FINAL FORM;Lo;0;AL;<final> 0671;;;;N;;;;;
+FB52;ARABIC LETTER BEEH ISOLATED FORM;Lo;0;AL;<isolated> 067B;;;;N;;;;;
+FB53;ARABIC LETTER BEEH FINAL FORM;Lo;0;AL;<final> 067B;;;;N;;;;;
+FB54;ARABIC LETTER BEEH INITIAL FORM;Lo;0;AL;<initial> 067B;;;;N;;;;;
+FB55;ARABIC LETTER BEEH MEDIAL FORM;Lo;0;AL;<medial> 067B;;;;N;;;;;
+FB56;ARABIC LETTER PEH ISOLATED FORM;Lo;0;AL;<isolated> 067E;;;;N;;;;;
+FB57;ARABIC LETTER PEH FINAL FORM;Lo;0;AL;<final> 067E;;;;N;;;;;
+FB58;ARABIC LETTER PEH INITIAL FORM;Lo;0;AL;<initial> 067E;;;;N;;;;;
+FB59;ARABIC LETTER PEH MEDIAL FORM;Lo;0;AL;<medial> 067E;;;;N;;;;;
+FB5A;ARABIC LETTER BEHEH ISOLATED FORM;Lo;0;AL;<isolated> 0680;;;;N;;;;;
+FB5B;ARABIC LETTER BEHEH FINAL FORM;Lo;0;AL;<final> 0680;;;;N;;;;;
+FB5C;ARABIC LETTER BEHEH INITIAL FORM;Lo;0;AL;<initial> 0680;;;;N;;;;;
+FB5D;ARABIC LETTER BEHEH MEDIAL FORM;Lo;0;AL;<medial> 0680;;;;N;;;;;
+FB5E;ARABIC LETTER TTEHEH ISOLATED FORM;Lo;0;AL;<isolated> 067A;;;;N;;;;;
+FB5F;ARABIC LETTER TTEHEH FINAL FORM;Lo;0;AL;<final> 067A;;;;N;;;;;
+FB60;ARABIC LETTER TTEHEH INITIAL FORM;Lo;0;AL;<initial> 067A;;;;N;;;;;
+FB61;ARABIC LETTER TTEHEH MEDIAL FORM;Lo;0;AL;<medial> 067A;;;;N;;;;;
+FB62;ARABIC LETTER TEHEH ISOLATED FORM;Lo;0;AL;<isolated> 067F;;;;N;;;;;
+FB63;ARABIC LETTER TEHEH FINAL FORM;Lo;0;AL;<final> 067F;;;;N;;;;;
+FB64;ARABIC LETTER TEHEH INITIAL FORM;Lo;0;AL;<initial> 067F;;;;N;;;;;
+FB65;ARABIC LETTER TEHEH MEDIAL FORM;Lo;0;AL;<medial> 067F;;;;N;;;;;
+FB66;ARABIC LETTER TTEH ISOLATED FORM;Lo;0;AL;<isolated> 0679;;;;N;;;;;
+FB67;ARABIC LETTER TTEH FINAL FORM;Lo;0;AL;<final> 0679;;;;N;;;;;
+FB68;ARABIC LETTER TTEH INITIAL FORM;Lo;0;AL;<initial> 0679;;;;N;;;;;
+FB69;ARABIC LETTER TTEH MEDIAL FORM;Lo;0;AL;<medial> 0679;;;;N;;;;;
+FB6A;ARABIC LETTER VEH ISOLATED FORM;Lo;0;AL;<isolated> 06A4;;;;N;;;;;
+FB6B;ARABIC LETTER VEH FINAL FORM;Lo;0;AL;<final> 06A4;;;;N;;;;;
+FB6C;ARABIC LETTER VEH INITIAL FORM;Lo;0;AL;<initial> 06A4;;;;N;;;;;
+FB6D;ARABIC LETTER VEH MEDIAL FORM;Lo;0;AL;<medial> 06A4;;;;N;;;;;
+FB6E;ARABIC LETTER PEHEH ISOLATED FORM;Lo;0;AL;<isolated> 06A6;;;;N;;;;;
+FB6F;ARABIC LETTER PEHEH FINAL FORM;Lo;0;AL;<final> 06A6;;;;N;;;;;
+FB70;ARABIC LETTER PEHEH INITIAL FORM;Lo;0;AL;<initial> 06A6;;;;N;;;;;
+FB71;ARABIC LETTER PEHEH MEDIAL FORM;Lo;0;AL;<medial> 06A6;;;;N;;;;;
+FB72;ARABIC LETTER DYEH ISOLATED FORM;Lo;0;AL;<isolated> 0684;;;;N;;;;;
+FB73;ARABIC LETTER DYEH FINAL FORM;Lo;0;AL;<final> 0684;;;;N;;;;;
+FB74;ARABIC LETTER DYEH INITIAL FORM;Lo;0;AL;<initial> 0684;;;;N;;;;;
+FB75;ARABIC LETTER DYEH MEDIAL FORM;Lo;0;AL;<medial> 0684;;;;N;;;;;
+FB76;ARABIC LETTER NYEH ISOLATED FORM;Lo;0;AL;<isolated> 0683;;;;N;;;;;
+FB77;ARABIC LETTER NYEH FINAL FORM;Lo;0;AL;<final> 0683;;;;N;;;;;
+FB78;ARABIC LETTER NYEH INITIAL FORM;Lo;0;AL;<initial> 0683;;;;N;;;;;
+FB79;ARABIC LETTER NYEH MEDIAL FORM;Lo;0;AL;<medial> 0683;;;;N;;;;;
+FB7A;ARABIC LETTER TCHEH ISOLATED FORM;Lo;0;AL;<isolated> 0686;;;;N;;;;;
+FB7B;ARABIC LETTER TCHEH FINAL FORM;Lo;0;AL;<final> 0686;;;;N;;;;;
+FB7C;ARABIC LETTER TCHEH INITIAL FORM;Lo;0;AL;<initial> 0686;;;;N;;;;;
+FB7D;ARABIC LETTER TCHEH MEDIAL FORM;Lo;0;AL;<medial> 0686;;;;N;;;;;
+FB7E;ARABIC LETTER TCHEHEH ISOLATED FORM;Lo;0;AL;<isolated> 0687;;;;N;;;;;
+FB7F;ARABIC LETTER TCHEHEH FINAL FORM;Lo;0;AL;<final> 0687;;;;N;;;;;
+FB80;ARABIC LETTER TCHEHEH INITIAL FORM;Lo;0;AL;<initial> 0687;;;;N;;;;;
+FB81;ARABIC LETTER TCHEHEH MEDIAL FORM;Lo;0;AL;<medial> 0687;;;;N;;;;;
+FB82;ARABIC LETTER DDAHAL ISOLATED FORM;Lo;0;AL;<isolated> 068D;;;;N;;;;;
+FB83;ARABIC LETTER DDAHAL FINAL FORM;Lo;0;AL;<final> 068D;;;;N;;;;;
+FB84;ARABIC LETTER DAHAL ISOLATED FORM;Lo;0;AL;<isolated> 068C;;;;N;;;;;
+FB85;ARABIC LETTER DAHAL FINAL FORM;Lo;0;AL;<final> 068C;;;;N;;;;;
+FB86;ARABIC LETTER DUL ISOLATED FORM;Lo;0;AL;<isolated> 068E;;;;N;;;;;
+FB87;ARABIC LETTER DUL FINAL FORM;Lo;0;AL;<final> 068E;;;;N;;;;;
+FB88;ARABIC LETTER DDAL ISOLATED FORM;Lo;0;AL;<isolated> 0688;;;;N;;;;;
+FB89;ARABIC LETTER DDAL FINAL FORM;Lo;0;AL;<final> 0688;;;;N;;;;;
+FB8A;ARABIC LETTER JEH ISOLATED FORM;Lo;0;AL;<isolated> 0698;;;;N;;;;;
+FB8B;ARABIC LETTER JEH FINAL FORM;Lo;0;AL;<final> 0698;;;;N;;;;;
+FB8C;ARABIC LETTER RREH ISOLATED FORM;Lo;0;AL;<isolated> 0691;;;;N;;;;;
+FB8D;ARABIC LETTER RREH FINAL FORM;Lo;0;AL;<final> 0691;;;;N;;;;;
+FB8E;ARABIC LETTER KEHEH ISOLATED FORM;Lo;0;AL;<isolated> 06A9;;;;N;;;;;
+FB8F;ARABIC LETTER KEHEH FINAL FORM;Lo;0;AL;<final> 06A9;;;;N;;;;;
+FB90;ARABIC LETTER KEHEH INITIAL FORM;Lo;0;AL;<initial> 06A9;;;;N;;;;;
+FB91;ARABIC LETTER KEHEH MEDIAL FORM;Lo;0;AL;<medial> 06A9;;;;N;;;;;
+FB92;ARABIC LETTER GAF ISOLATED FORM;Lo;0;AL;<isolated> 06AF;;;;N;;;;;
+FB93;ARABIC LETTER GAF FINAL FORM;Lo;0;AL;<final> 06AF;;;;N;;;;;
+FB94;ARABIC LETTER GAF INITIAL FORM;Lo;0;AL;<initial> 06AF;;;;N;;;;;
+FB95;ARABIC LETTER GAF MEDIAL FORM;Lo;0;AL;<medial> 06AF;;;;N;;;;;
+FB96;ARABIC LETTER GUEH ISOLATED FORM;Lo;0;AL;<isolated> 06B3;;;;N;;;;;
+FB97;ARABIC LETTER GUEH FINAL FORM;Lo;0;AL;<final> 06B3;;;;N;;;;;
+FB98;ARABIC LETTER GUEH INITIAL FORM;Lo;0;AL;<initial> 06B3;;;;N;;;;;
+FB99;ARABIC LETTER GUEH MEDIAL FORM;Lo;0;AL;<medial> 06B3;;;;N;;;;;
+FB9A;ARABIC LETTER NGOEH ISOLATED FORM;Lo;0;AL;<isolated> 06B1;;;;N;;;;;
+FB9B;ARABIC LETTER NGOEH FINAL FORM;Lo;0;AL;<final> 06B1;;;;N;;;;;
+FB9C;ARABIC LETTER NGOEH INITIAL FORM;Lo;0;AL;<initial> 06B1;;;;N;;;;;
+FB9D;ARABIC LETTER NGOEH MEDIAL FORM;Lo;0;AL;<medial> 06B1;;;;N;;;;;
+FB9E;ARABIC LETTER NOON GHUNNA ISOLATED FORM;Lo;0;AL;<isolated> 06BA;;;;N;;;;;
+FB9F;ARABIC LETTER NOON GHUNNA FINAL FORM;Lo;0;AL;<final> 06BA;;;;N;;;;;
+FBA0;ARABIC LETTER RNOON ISOLATED FORM;Lo;0;AL;<isolated> 06BB;;;;N;;;;;
+FBA1;ARABIC LETTER RNOON FINAL FORM;Lo;0;AL;<final> 06BB;;;;N;;;;;
+FBA2;ARABIC LETTER RNOON INITIAL FORM;Lo;0;AL;<initial> 06BB;;;;N;;;;;
+FBA3;ARABIC LETTER RNOON MEDIAL FORM;Lo;0;AL;<medial> 06BB;;;;N;;;;;
+FBA4;ARABIC LETTER HEH WITH YEH ABOVE ISOLATED FORM;Lo;0;AL;<isolated> 06C0;;;;N;;;;;
+FBA5;ARABIC LETTER HEH WITH YEH ABOVE FINAL FORM;Lo;0;AL;<final> 06C0;;;;N;;;;;
+FBA6;ARABIC LETTER HEH GOAL ISOLATED FORM;Lo;0;AL;<isolated> 06C1;;;;N;;;;;
+FBA7;ARABIC LETTER HEH GOAL FINAL FORM;Lo;0;AL;<final> 06C1;;;;N;;;;;
+FBA8;ARABIC LETTER HEH GOAL INITIAL FORM;Lo;0;AL;<initial> 06C1;;;;N;;;;;
+FBA9;ARABIC LETTER HEH GOAL MEDIAL FORM;Lo;0;AL;<medial> 06C1;;;;N;;;;;
+FBAA;ARABIC LETTER HEH DOACHASHMEE ISOLATED FORM;Lo;0;AL;<isolated> 06BE;;;;N;;;;;
+FBAB;ARABIC LETTER HEH DOACHASHMEE FINAL FORM;Lo;0;AL;<final> 06BE;;;;N;;;;;
+FBAC;ARABIC LETTER HEH DOACHASHMEE INITIAL FORM;Lo;0;AL;<initial> 06BE;;;;N;;;;;
+FBAD;ARABIC LETTER HEH DOACHASHMEE MEDIAL FORM;Lo;0;AL;<medial> 06BE;;;;N;;;;;
+FBAE;ARABIC LETTER YEH BARREE ISOLATED FORM;Lo;0;AL;<isolated> 06D2;;;;N;;;;;
+FBAF;ARABIC LETTER YEH BARREE FINAL FORM;Lo;0;AL;<final> 06D2;;;;N;;;;;
+FBB0;ARABIC LETTER YEH BARREE WITH HAMZA ABOVE ISOLATED FORM;Lo;0;AL;<isolated> 06D3;;;;N;;;;;
+FBB1;ARABIC LETTER YEH BARREE WITH HAMZA ABOVE FINAL FORM;Lo;0;AL;<final> 06D3;;;;N;;;;;
+FBB2;ARABIC SYMBOL DOT ABOVE;Sk;0;AL;;;;;N;;;;;
+FBB3;ARABIC SYMBOL DOT BELOW;Sk;0;AL;;;;;N;;;;;
+FBB4;ARABIC SYMBOL TWO DOTS ABOVE;Sk;0;AL;;;;;N;;;;;
+FBB5;ARABIC SYMBOL TWO DOTS BELOW;Sk;0;AL;;;;;N;;;;;
+FBB6;ARABIC SYMBOL THREE DOTS ABOVE;Sk;0;AL;;;;;N;;;;;
+FBB7;ARABIC SYMBOL THREE DOTS BELOW;Sk;0;AL;;;;;N;;;;;
+FBB8;ARABIC SYMBOL THREE DOTS POINTING DOWNWARDS ABOVE;Sk;0;AL;;;;;N;;;;;
+FBB9;ARABIC SYMBOL THREE DOTS POINTING DOWNWARDS BELOW;Sk;0;AL;;;;;N;;;;;
+FBBA;ARABIC SYMBOL FOUR DOTS ABOVE;Sk;0;AL;;;;;N;;;;;
+FBBB;ARABIC SYMBOL FOUR DOTS BELOW;Sk;0;AL;;;;;N;;;;;
+FBBC;ARABIC SYMBOL DOUBLE VERTICAL BAR BELOW;Sk;0;AL;;;;;N;;;;;
+FBBD;ARABIC SYMBOL TWO DOTS VERTICALLY ABOVE;Sk;0;AL;;;;;N;;;;;
+FBBE;ARABIC SYMBOL TWO DOTS VERTICALLY BELOW;Sk;0;AL;;;;;N;;;;;
+FBBF;ARABIC SYMBOL RING;Sk;0;AL;;;;;N;;;;;
+FBC0;ARABIC SYMBOL SMALL TAH ABOVE;Sk;0;AL;;;;;N;;;;;
+FBC1;ARABIC SYMBOL SMALL TAH BELOW;Sk;0;AL;;;;;N;;;;;
+FBD3;ARABIC LETTER NG ISOLATED FORM;Lo;0;AL;<isolated> 06AD;;;;N;;;;;
+FBD4;ARABIC LETTER NG FINAL FORM;Lo;0;AL;<final> 06AD;;;;N;;;;;
+FBD5;ARABIC LETTER NG INITIAL FORM;Lo;0;AL;<initial> 06AD;;;;N;;;;;
+FBD6;ARABIC LETTER NG MEDIAL FORM;Lo;0;AL;<medial> 06AD;;;;N;;;;;
+FBD7;ARABIC LETTER U ISOLATED FORM;Lo;0;AL;<isolated> 06C7;;;;N;;;;;
+FBD8;ARABIC LETTER U FINAL FORM;Lo;0;AL;<final> 06C7;;;;N;;;;;
+FBD9;ARABIC LETTER OE ISOLATED FORM;Lo;0;AL;<isolated> 06C6;;;;N;;;;;
+FBDA;ARABIC LETTER OE FINAL FORM;Lo;0;AL;<final> 06C6;;;;N;;;;;
+FBDB;ARABIC LETTER YU ISOLATED FORM;Lo;0;AL;<isolated> 06C8;;;;N;;;;;
+FBDC;ARABIC LETTER YU FINAL FORM;Lo;0;AL;<final> 06C8;;;;N;;;;;
+FBDD;ARABIC LETTER U WITH HAMZA ABOVE ISOLATED FORM;Lo;0;AL;<isolated> 0677;;;;N;;;;;
+FBDE;ARABIC LETTER VE ISOLATED FORM;Lo;0;AL;<isolated> 06CB;;;;N;;;;;
+FBDF;ARABIC LETTER VE FINAL FORM;Lo;0;AL;<final> 06CB;;;;N;;;;;
+FBE0;ARABIC LETTER KIRGHIZ OE ISOLATED FORM;Lo;0;AL;<isolated> 06C5;;;;N;;;;;
+FBE1;ARABIC LETTER KIRGHIZ OE FINAL FORM;Lo;0;AL;<final> 06C5;;;;N;;;;;
+FBE2;ARABIC LETTER KIRGHIZ YU ISOLATED FORM;Lo;0;AL;<isolated> 06C9;;;;N;;;;;
+FBE3;ARABIC LETTER KIRGHIZ YU FINAL FORM;Lo;0;AL;<final> 06C9;;;;N;;;;;
+FBE4;ARABIC LETTER E ISOLATED FORM;Lo;0;AL;<isolated> 06D0;;;;N;;;;;
+FBE5;ARABIC LETTER E FINAL FORM;Lo;0;AL;<final> 06D0;;;;N;;;;;
+FBE6;ARABIC LETTER E INITIAL FORM;Lo;0;AL;<initial> 06D0;;;;N;;;;;
+FBE7;ARABIC LETTER E MEDIAL FORM;Lo;0;AL;<medial> 06D0;;;;N;;;;;
+FBE8;ARABIC LETTER UIGHUR KAZAKH KIRGHIZ ALEF MAKSURA INITIAL FORM;Lo;0;AL;<initial> 0649;;;;N;;;;;
+FBE9;ARABIC LETTER UIGHUR KAZAKH KIRGHIZ ALEF MAKSURA MEDIAL FORM;Lo;0;AL;<medial> 0649;;;;N;;;;;
+FBEA;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF ISOLATED FORM;Lo;0;AL;<isolated> 0626 0627;;;;N;;;;;
+FBEB;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF FINAL FORM;Lo;0;AL;<final> 0626 0627;;;;N;;;;;
+FBEC;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH AE ISOLATED FORM;Lo;0;AL;<isolated> 0626 06D5;;;;N;;;;;
+FBED;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH AE FINAL FORM;Lo;0;AL;<final> 0626 06D5;;;;N;;;;;
+FBEE;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH WAW ISOLATED FORM;Lo;0;AL;<isolated> 0626 0648;;;;N;;;;;
+FBEF;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH WAW FINAL FORM;Lo;0;AL;<final> 0626 0648;;;;N;;;;;
+FBF0;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH U ISOLATED FORM;Lo;0;AL;<isolated> 0626 06C7;;;;N;;;;;
+FBF1;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH U FINAL FORM;Lo;0;AL;<final> 0626 06C7;;;;N;;;;;
+FBF2;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH OE ISOLATED FORM;Lo;0;AL;<isolated> 0626 06C6;;;;N;;;;;
+FBF3;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH OE FINAL FORM;Lo;0;AL;<final> 0626 06C6;;;;N;;;;;
+FBF4;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH YU ISOLATED FORM;Lo;0;AL;<isolated> 0626 06C8;;;;N;;;;;
+FBF5;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH YU FINAL FORM;Lo;0;AL;<final> 0626 06C8;;;;N;;;;;
+FBF6;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH E ISOLATED FORM;Lo;0;AL;<isolated> 0626 06D0;;;;N;;;;;
+FBF7;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH E FINAL FORM;Lo;0;AL;<final> 0626 06D0;;;;N;;;;;
+FBF8;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH E INITIAL FORM;Lo;0;AL;<initial> 0626 06D0;;;;N;;;;;
+FBF9;ARABIC LIGATURE UIGHUR KIRGHIZ YEH WITH HAMZA ABOVE WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0626 0649;;;;N;;;;;
+FBFA;ARABIC LIGATURE UIGHUR KIRGHIZ YEH WITH HAMZA ABOVE WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0626 0649;;;;N;;;;;
+FBFB;ARABIC LIGATURE UIGHUR KIRGHIZ YEH WITH HAMZA ABOVE WITH ALEF MAKSURA INITIAL FORM;Lo;0;AL;<initial> 0626 0649;;;;N;;;;;
+FBFC;ARABIC LETTER FARSI YEH ISOLATED FORM;Lo;0;AL;<isolated> 06CC;;;;N;;;;;
+FBFD;ARABIC LETTER FARSI YEH FINAL FORM;Lo;0;AL;<final> 06CC;;;;N;;;;;
+FBFE;ARABIC LETTER FARSI YEH INITIAL FORM;Lo;0;AL;<initial> 06CC;;;;N;;;;;
+FBFF;ARABIC LETTER FARSI YEH MEDIAL FORM;Lo;0;AL;<medial> 06CC;;;;N;;;;;
+FC00;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 0626 062C;;;;N;;;;;
+FC01;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 0626 062D;;;;N;;;;;
+FC02;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0626 0645;;;;N;;;;;
+FC03;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0626 0649;;;;N;;;;;
+FC04;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 0626 064A;;;;N;;;;;
+FC05;ARABIC LIGATURE BEH WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 0628 062C;;;;N;;;;;
+FC06;ARABIC LIGATURE BEH WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 0628 062D;;;;N;;;;;
+FC07;ARABIC LIGATURE BEH WITH KHAH ISOLATED FORM;Lo;0;AL;<isolated> 0628 062E;;;;N;;;;;
+FC08;ARABIC LIGATURE BEH WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0628 0645;;;;N;;;;;
+FC09;ARABIC LIGATURE BEH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0628 0649;;;;N;;;;;
+FC0A;ARABIC LIGATURE BEH WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 0628 064A;;;;N;;;;;
+FC0B;ARABIC LIGATURE TEH WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 062A 062C;;;;N;;;;;
+FC0C;ARABIC LIGATURE TEH WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 062A 062D;;;;N;;;;;
+FC0D;ARABIC LIGATURE TEH WITH KHAH ISOLATED FORM;Lo;0;AL;<isolated> 062A 062E;;;;N;;;;;
+FC0E;ARABIC LIGATURE TEH WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 062A 0645;;;;N;;;;;
+FC0F;ARABIC LIGATURE TEH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 062A 0649;;;;N;;;;;
+FC10;ARABIC LIGATURE TEH WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 062A 064A;;;;N;;;;;
+FC11;ARABIC LIGATURE THEH WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 062B 062C;;;;N;;;;;
+FC12;ARABIC LIGATURE THEH WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 062B 0645;;;;N;;;;;
+FC13;ARABIC LIGATURE THEH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 062B 0649;;;;N;;;;;
+FC14;ARABIC LIGATURE THEH WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 062B 064A;;;;N;;;;;
+FC15;ARABIC LIGATURE JEEM WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 062C 062D;;;;N;;;;;
+FC16;ARABIC LIGATURE JEEM WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 062C 0645;;;;N;;;;;
+FC17;ARABIC LIGATURE HAH WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 062D 062C;;;;N;;;;;
+FC18;ARABIC LIGATURE HAH WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 062D 0645;;;;N;;;;;
+FC19;ARABIC LIGATURE KHAH WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 062E 062C;;;;N;;;;;
+FC1A;ARABIC LIGATURE KHAH WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 062E 062D;;;;N;;;;;
+FC1B;ARABIC LIGATURE KHAH WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 062E 0645;;;;N;;;;;
+FC1C;ARABIC LIGATURE SEEN WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 0633 062C;;;;N;;;;;
+FC1D;ARABIC LIGATURE SEEN WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 0633 062D;;;;N;;;;;
+FC1E;ARABIC LIGATURE SEEN WITH KHAH ISOLATED FORM;Lo;0;AL;<isolated> 0633 062E;;;;N;;;;;
+FC1F;ARABIC LIGATURE SEEN WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0633 0645;;;;N;;;;;
+FC20;ARABIC LIGATURE SAD WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 0635 062D;;;;N;;;;;
+FC21;ARABIC LIGATURE SAD WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0635 0645;;;;N;;;;;
+FC22;ARABIC LIGATURE DAD WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 0636 062C;;;;N;;;;;
+FC23;ARABIC LIGATURE DAD WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 0636 062D;;;;N;;;;;
+FC24;ARABIC LIGATURE DAD WITH KHAH ISOLATED FORM;Lo;0;AL;<isolated> 0636 062E;;;;N;;;;;
+FC25;ARABIC LIGATURE DAD WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0636 0645;;;;N;;;;;
+FC26;ARABIC LIGATURE TAH WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 0637 062D;;;;N;;;;;
+FC27;ARABIC LIGATURE TAH WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0637 0645;;;;N;;;;;
+FC28;ARABIC LIGATURE ZAH WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0638 0645;;;;N;;;;;
+FC29;ARABIC LIGATURE AIN WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 0639 062C;;;;N;;;;;
+FC2A;ARABIC LIGATURE AIN WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0639 0645;;;;N;;;;;
+FC2B;ARABIC LIGATURE GHAIN WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 063A 062C;;;;N;;;;;
+FC2C;ARABIC LIGATURE GHAIN WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 063A 0645;;;;N;;;;;
+FC2D;ARABIC LIGATURE FEH WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 0641 062C;;;;N;;;;;
+FC2E;ARABIC LIGATURE FEH WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 0641 062D;;;;N;;;;;
+FC2F;ARABIC LIGATURE FEH WITH KHAH ISOLATED FORM;Lo;0;AL;<isolated> 0641 062E;;;;N;;;;;
+FC30;ARABIC LIGATURE FEH WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0641 0645;;;;N;;;;;
+FC31;ARABIC LIGATURE FEH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0641 0649;;;;N;;;;;
+FC32;ARABIC LIGATURE FEH WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 0641 064A;;;;N;;;;;
+FC33;ARABIC LIGATURE QAF WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 0642 062D;;;;N;;;;;
+FC34;ARABIC LIGATURE QAF WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0642 0645;;;;N;;;;;
+FC35;ARABIC LIGATURE QAF WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0642 0649;;;;N;;;;;
+FC36;ARABIC LIGATURE QAF WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 0642 064A;;;;N;;;;;
+FC37;ARABIC LIGATURE KAF WITH ALEF ISOLATED FORM;Lo;0;AL;<isolated> 0643 0627;;;;N;;;;;
+FC38;ARABIC LIGATURE KAF WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 0643 062C;;;;N;;;;;
+FC39;ARABIC LIGATURE KAF WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 0643 062D;;;;N;;;;;
+FC3A;ARABIC LIGATURE KAF WITH KHAH ISOLATED FORM;Lo;0;AL;<isolated> 0643 062E;;;;N;;;;;
+FC3B;ARABIC LIGATURE KAF WITH LAM ISOLATED FORM;Lo;0;AL;<isolated> 0643 0644;;;;N;;;;;
+FC3C;ARABIC LIGATURE KAF WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0643 0645;;;;N;;;;;
+FC3D;ARABIC LIGATURE KAF WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0643 0649;;;;N;;;;;
+FC3E;ARABIC LIGATURE KAF WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 0643 064A;;;;N;;;;;
+FC3F;ARABIC LIGATURE LAM WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 0644 062C;;;;N;;;;;
+FC40;ARABIC LIGATURE LAM WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 0644 062D;;;;N;;;;;
+FC41;ARABIC LIGATURE LAM WITH KHAH ISOLATED FORM;Lo;0;AL;<isolated> 0644 062E;;;;N;;;;;
+FC42;ARABIC LIGATURE LAM WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0644 0645;;;;N;;;;;
+FC43;ARABIC LIGATURE LAM WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0644 0649;;;;N;;;;;
+FC44;ARABIC LIGATURE LAM WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 0644 064A;;;;N;;;;;
+FC45;ARABIC LIGATURE MEEM WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 0645 062C;;;;N;;;;;
+FC46;ARABIC LIGATURE MEEM WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 0645 062D;;;;N;;;;;
+FC47;ARABIC LIGATURE MEEM WITH KHAH ISOLATED FORM;Lo;0;AL;<isolated> 0645 062E;;;;N;;;;;
+FC48;ARABIC LIGATURE MEEM WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0645 0645;;;;N;;;;;
+FC49;ARABIC LIGATURE MEEM WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0645 0649;;;;N;;;;;
+FC4A;ARABIC LIGATURE MEEM WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 0645 064A;;;;N;;;;;
+FC4B;ARABIC LIGATURE NOON WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 0646 062C;;;;N;;;;;
+FC4C;ARABIC LIGATURE NOON WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 0646 062D;;;;N;;;;;
+FC4D;ARABIC LIGATURE NOON WITH KHAH ISOLATED FORM;Lo;0;AL;<isolated> 0646 062E;;;;N;;;;;
+FC4E;ARABIC LIGATURE NOON WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0646 0645;;;;N;;;;;
+FC4F;ARABIC LIGATURE NOON WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0646 0649;;;;N;;;;;
+FC50;ARABIC LIGATURE NOON WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 0646 064A;;;;N;;;;;
+FC51;ARABIC LIGATURE HEH WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 0647 062C;;;;N;;;;;
+FC52;ARABIC LIGATURE HEH WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0647 0645;;;;N;;;;;
+FC53;ARABIC LIGATURE HEH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0647 0649;;;;N;;;;;
+FC54;ARABIC LIGATURE HEH WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 0647 064A;;;;N;;;;;
+FC55;ARABIC LIGATURE YEH WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 064A 062C;;;;N;;;;;
+FC56;ARABIC LIGATURE YEH WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 064A 062D;;;;N;;;;;
+FC57;ARABIC LIGATURE YEH WITH KHAH ISOLATED FORM;Lo;0;AL;<isolated> 064A 062E;;;;N;;;;;
+FC58;ARABIC LIGATURE YEH WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 064A 0645;;;;N;;;;;
+FC59;ARABIC LIGATURE YEH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 064A 0649;;;;N;;;;;
+FC5A;ARABIC LIGATURE YEH WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 064A 064A;;;;N;;;;;
+FC5B;ARABIC LIGATURE THAL WITH SUPERSCRIPT ALEF ISOLATED FORM;Lo;0;AL;<isolated> 0630 0670;;;;N;;;;;
+FC5C;ARABIC LIGATURE REH WITH SUPERSCRIPT ALEF ISOLATED FORM;Lo;0;AL;<isolated> 0631 0670;;;;N;;;;;
+FC5D;ARABIC LIGATURE ALEF MAKSURA WITH SUPERSCRIPT ALEF ISOLATED FORM;Lo;0;AL;<isolated> 0649 0670;;;;N;;;;;
+FC5E;ARABIC LIGATURE SHADDA WITH DAMMATAN ISOLATED FORM;Lo;0;AL;<isolated> 0020 064C 0651;;;;N;;;;;
+FC5F;ARABIC LIGATURE SHADDA WITH KASRATAN ISOLATED FORM;Lo;0;AL;<isolated> 0020 064D 0651;;;;N;;;;;
+FC60;ARABIC LIGATURE SHADDA WITH FATHA ISOLATED FORM;Lo;0;AL;<isolated> 0020 064E 0651;;;;N;;;;;
+FC61;ARABIC LIGATURE SHADDA WITH DAMMA ISOLATED FORM;Lo;0;AL;<isolated> 0020 064F 0651;;;;N;;;;;
+FC62;ARABIC LIGATURE SHADDA WITH KASRA ISOLATED FORM;Lo;0;AL;<isolated> 0020 0650 0651;;;;N;;;;;
+FC63;ARABIC LIGATURE SHADDA WITH SUPERSCRIPT ALEF ISOLATED FORM;Lo;0;AL;<isolated> 0020 0651 0670;;;;N;;;;;
+FC64;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH REH FINAL FORM;Lo;0;AL;<final> 0626 0631;;;;N;;;;;
+FC65;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ZAIN FINAL FORM;Lo;0;AL;<final> 0626 0632;;;;N;;;;;
+FC66;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH MEEM FINAL FORM;Lo;0;AL;<final> 0626 0645;;;;N;;;;;
+FC67;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH NOON FINAL FORM;Lo;0;AL;<final> 0626 0646;;;;N;;;;;
+FC68;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0626 0649;;;;N;;;;;
+FC69;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH YEH FINAL FORM;Lo;0;AL;<final> 0626 064A;;;;N;;;;;
+FC6A;ARABIC LIGATURE BEH WITH REH FINAL FORM;Lo;0;AL;<final> 0628 0631;;;;N;;;;;
+FC6B;ARABIC LIGATURE BEH WITH ZAIN FINAL FORM;Lo;0;AL;<final> 0628 0632;;;;N;;;;;
+FC6C;ARABIC LIGATURE BEH WITH MEEM FINAL FORM;Lo;0;AL;<final> 0628 0645;;;;N;;;;;
+FC6D;ARABIC LIGATURE BEH WITH NOON FINAL FORM;Lo;0;AL;<final> 0628 0646;;;;N;;;;;
+FC6E;ARABIC LIGATURE BEH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0628 0649;;;;N;;;;;
+FC6F;ARABIC LIGATURE BEH WITH YEH FINAL FORM;Lo;0;AL;<final> 0628 064A;;;;N;;;;;
+FC70;ARABIC LIGATURE TEH WITH REH FINAL FORM;Lo;0;AL;<final> 062A 0631;;;;N;;;;;
+FC71;ARABIC LIGATURE TEH WITH ZAIN FINAL FORM;Lo;0;AL;<final> 062A 0632;;;;N;;;;;
+FC72;ARABIC LIGATURE TEH WITH MEEM FINAL FORM;Lo;0;AL;<final> 062A 0645;;;;N;;;;;
+FC73;ARABIC LIGATURE TEH WITH NOON FINAL FORM;Lo;0;AL;<final> 062A 0646;;;;N;;;;;
+FC74;ARABIC LIGATURE TEH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 062A 0649;;;;N;;;;;
+FC75;ARABIC LIGATURE TEH WITH YEH FINAL FORM;Lo;0;AL;<final> 062A 064A;;;;N;;;;;
+FC76;ARABIC LIGATURE THEH WITH REH FINAL FORM;Lo;0;AL;<final> 062B 0631;;;;N;;;;;
+FC77;ARABIC LIGATURE THEH WITH ZAIN FINAL FORM;Lo;0;AL;<final> 062B 0632;;;;N;;;;;
+FC78;ARABIC LIGATURE THEH WITH MEEM FINAL FORM;Lo;0;AL;<final> 062B 0645;;;;N;;;;;
+FC79;ARABIC LIGATURE THEH WITH NOON FINAL FORM;Lo;0;AL;<final> 062B 0646;;;;N;;;;;
+FC7A;ARABIC LIGATURE THEH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 062B 0649;;;;N;;;;;
+FC7B;ARABIC LIGATURE THEH WITH YEH FINAL FORM;Lo;0;AL;<final> 062B 064A;;;;N;;;;;
+FC7C;ARABIC LIGATURE FEH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0641 0649;;;;N;;;;;
+FC7D;ARABIC LIGATURE FEH WITH YEH FINAL FORM;Lo;0;AL;<final> 0641 064A;;;;N;;;;;
+FC7E;ARABIC LIGATURE QAF WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0642 0649;;;;N;;;;;
+FC7F;ARABIC LIGATURE QAF WITH YEH FINAL FORM;Lo;0;AL;<final> 0642 064A;;;;N;;;;;
+FC80;ARABIC LIGATURE KAF WITH ALEF FINAL FORM;Lo;0;AL;<final> 0643 0627;;;;N;;;;;
+FC81;ARABIC LIGATURE KAF WITH LAM FINAL FORM;Lo;0;AL;<final> 0643 0644;;;;N;;;;;
+FC82;ARABIC LIGATURE KAF WITH MEEM FINAL FORM;Lo;0;AL;<final> 0643 0645;;;;N;;;;;
+FC83;ARABIC LIGATURE KAF WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0643 0649;;;;N;;;;;
+FC84;ARABIC LIGATURE KAF WITH YEH FINAL FORM;Lo;0;AL;<final> 0643 064A;;;;N;;;;;
+FC85;ARABIC LIGATURE LAM WITH MEEM FINAL FORM;Lo;0;AL;<final> 0644 0645;;;;N;;;;;
+FC86;ARABIC LIGATURE LAM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0644 0649;;;;N;;;;;
+FC87;ARABIC LIGATURE LAM WITH YEH FINAL FORM;Lo;0;AL;<final> 0644 064A;;;;N;;;;;
+FC88;ARABIC LIGATURE MEEM WITH ALEF FINAL FORM;Lo;0;AL;<final> 0645 0627;;;;N;;;;;
+FC89;ARABIC LIGATURE MEEM WITH MEEM FINAL FORM;Lo;0;AL;<final> 0645 0645;;;;N;;;;;
+FC8A;ARABIC LIGATURE NOON WITH REH FINAL FORM;Lo;0;AL;<final> 0646 0631;;;;N;;;;;
+FC8B;ARABIC LIGATURE NOON WITH ZAIN FINAL FORM;Lo;0;AL;<final> 0646 0632;;;;N;;;;;
+FC8C;ARABIC LIGATURE NOON WITH MEEM FINAL FORM;Lo;0;AL;<final> 0646 0645;;;;N;;;;;
+FC8D;ARABIC LIGATURE NOON WITH NOON FINAL FORM;Lo;0;AL;<final> 0646 0646;;;;N;;;;;
+FC8E;ARABIC LIGATURE NOON WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0646 0649;;;;N;;;;;
+FC8F;ARABIC LIGATURE NOON WITH YEH FINAL FORM;Lo;0;AL;<final> 0646 064A;;;;N;;;;;
+FC90;ARABIC LIGATURE ALEF MAKSURA WITH SUPERSCRIPT ALEF FINAL FORM;Lo;0;AL;<final> 0649 0670;;;;N;;;;;
+FC91;ARABIC LIGATURE YEH WITH REH FINAL FORM;Lo;0;AL;<final> 064A 0631;;;;N;;;;;
+FC92;ARABIC LIGATURE YEH WITH ZAIN FINAL FORM;Lo;0;AL;<final> 064A 0632;;;;N;;;;;
+FC93;ARABIC LIGATURE YEH WITH MEEM FINAL FORM;Lo;0;AL;<final> 064A 0645;;;;N;;;;;
+FC94;ARABIC LIGATURE YEH WITH NOON FINAL FORM;Lo;0;AL;<final> 064A 0646;;;;N;;;;;
+FC95;ARABIC LIGATURE YEH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 064A 0649;;;;N;;;;;
+FC96;ARABIC LIGATURE YEH WITH YEH FINAL FORM;Lo;0;AL;<final> 064A 064A;;;;N;;;;;
+FC97;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0626 062C;;;;N;;;;;
+FC98;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0626 062D;;;;N;;;;;
+FC99;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 0626 062E;;;;N;;;;;
+FC9A;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0626 0645;;;;N;;;;;
+FC9B;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH HEH INITIAL FORM;Lo;0;AL;<initial> 0626 0647;;;;N;;;;;
+FC9C;ARABIC LIGATURE BEH WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0628 062C;;;;N;;;;;
+FC9D;ARABIC LIGATURE BEH WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0628 062D;;;;N;;;;;
+FC9E;ARABIC LIGATURE BEH WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 0628 062E;;;;N;;;;;
+FC9F;ARABIC LIGATURE BEH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0628 0645;;;;N;;;;;
+FCA0;ARABIC LIGATURE BEH WITH HEH INITIAL FORM;Lo;0;AL;<initial> 0628 0647;;;;N;;;;;
+FCA1;ARABIC LIGATURE TEH WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 062A 062C;;;;N;;;;;
+FCA2;ARABIC LIGATURE TEH WITH HAH INITIAL FORM;Lo;0;AL;<initial> 062A 062D;;;;N;;;;;
+FCA3;ARABIC LIGATURE TEH WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 062A 062E;;;;N;;;;;
+FCA4;ARABIC LIGATURE TEH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 062A 0645;;;;N;;;;;
+FCA5;ARABIC LIGATURE TEH WITH HEH INITIAL FORM;Lo;0;AL;<initial> 062A 0647;;;;N;;;;;
+FCA6;ARABIC LIGATURE THEH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 062B 0645;;;;N;;;;;
+FCA7;ARABIC LIGATURE JEEM WITH HAH INITIAL FORM;Lo;0;AL;<initial> 062C 062D;;;;N;;;;;
+FCA8;ARABIC LIGATURE JEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 062C 0645;;;;N;;;;;
+FCA9;ARABIC LIGATURE HAH WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 062D 062C;;;;N;;;;;
+FCAA;ARABIC LIGATURE HAH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 062D 0645;;;;N;;;;;
+FCAB;ARABIC LIGATURE KHAH WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 062E 062C;;;;N;;;;;
+FCAC;ARABIC LIGATURE KHAH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 062E 0645;;;;N;;;;;
+FCAD;ARABIC LIGATURE SEEN WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0633 062C;;;;N;;;;;
+FCAE;ARABIC LIGATURE SEEN WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0633 062D;;;;N;;;;;
+FCAF;ARABIC LIGATURE SEEN WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 0633 062E;;;;N;;;;;
+FCB0;ARABIC LIGATURE SEEN WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0633 0645;;;;N;;;;;
+FCB1;ARABIC LIGATURE SAD WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0635 062D;;;;N;;;;;
+FCB2;ARABIC LIGATURE SAD WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 0635 062E;;;;N;;;;;
+FCB3;ARABIC LIGATURE SAD WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0635 0645;;;;N;;;;;
+FCB4;ARABIC LIGATURE DAD WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0636 062C;;;;N;;;;;
+FCB5;ARABIC LIGATURE DAD WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0636 062D;;;;N;;;;;
+FCB6;ARABIC LIGATURE DAD WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 0636 062E;;;;N;;;;;
+FCB7;ARABIC LIGATURE DAD WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0636 0645;;;;N;;;;;
+FCB8;ARABIC LIGATURE TAH WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0637 062D;;;;N;;;;;
+FCB9;ARABIC LIGATURE ZAH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0638 0645;;;;N;;;;;
+FCBA;ARABIC LIGATURE AIN WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0639 062C;;;;N;;;;;
+FCBB;ARABIC LIGATURE AIN WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0639 0645;;;;N;;;;;
+FCBC;ARABIC LIGATURE GHAIN WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 063A 062C;;;;N;;;;;
+FCBD;ARABIC LIGATURE GHAIN WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 063A 0645;;;;N;;;;;
+FCBE;ARABIC LIGATURE FEH WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0641 062C;;;;N;;;;;
+FCBF;ARABIC LIGATURE FEH WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0641 062D;;;;N;;;;;
+FCC0;ARABIC LIGATURE FEH WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 0641 062E;;;;N;;;;;
+FCC1;ARABIC LIGATURE FEH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0641 0645;;;;N;;;;;
+FCC2;ARABIC LIGATURE QAF WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0642 062D;;;;N;;;;;
+FCC3;ARABIC LIGATURE QAF WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0642 0645;;;;N;;;;;
+FCC4;ARABIC LIGATURE KAF WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0643 062C;;;;N;;;;;
+FCC5;ARABIC LIGATURE KAF WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0643 062D;;;;N;;;;;
+FCC6;ARABIC LIGATURE KAF WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 0643 062E;;;;N;;;;;
+FCC7;ARABIC LIGATURE KAF WITH LAM INITIAL FORM;Lo;0;AL;<initial> 0643 0644;;;;N;;;;;
+FCC8;ARABIC LIGATURE KAF WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0643 0645;;;;N;;;;;
+FCC9;ARABIC LIGATURE LAM WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0644 062C;;;;N;;;;;
+FCCA;ARABIC LIGATURE LAM WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0644 062D;;;;N;;;;;
+FCCB;ARABIC LIGATURE LAM WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 0644 062E;;;;N;;;;;
+FCCC;ARABIC LIGATURE LAM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0644 0645;;;;N;;;;;
+FCCD;ARABIC LIGATURE LAM WITH HEH INITIAL FORM;Lo;0;AL;<initial> 0644 0647;;;;N;;;;;
+FCCE;ARABIC LIGATURE MEEM WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0645 062C;;;;N;;;;;
+FCCF;ARABIC LIGATURE MEEM WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0645 062D;;;;N;;;;;
+FCD0;ARABIC LIGATURE MEEM WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 0645 062E;;;;N;;;;;
+FCD1;ARABIC LIGATURE MEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0645 0645;;;;N;;;;;
+FCD2;ARABIC LIGATURE NOON WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0646 062C;;;;N;;;;;
+FCD3;ARABIC LIGATURE NOON WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0646 062D;;;;N;;;;;
+FCD4;ARABIC LIGATURE NOON WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 0646 062E;;;;N;;;;;
+FCD5;ARABIC LIGATURE NOON WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0646 0645;;;;N;;;;;
+FCD6;ARABIC LIGATURE NOON WITH HEH INITIAL FORM;Lo;0;AL;<initial> 0646 0647;;;;N;;;;;
+FCD7;ARABIC LIGATURE HEH WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0647 062C;;;;N;;;;;
+FCD8;ARABIC LIGATURE HEH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0647 0645;;;;N;;;;;
+FCD9;ARABIC LIGATURE HEH WITH SUPERSCRIPT ALEF INITIAL FORM;Lo;0;AL;<initial> 0647 0670;;;;N;;;;;
+FCDA;ARABIC LIGATURE YEH WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 064A 062C;;;;N;;;;;
+FCDB;ARABIC LIGATURE YEH WITH HAH INITIAL FORM;Lo;0;AL;<initial> 064A 062D;;;;N;;;;;
+FCDC;ARABIC LIGATURE YEH WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 064A 062E;;;;N;;;;;
+FCDD;ARABIC LIGATURE YEH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 064A 0645;;;;N;;;;;
+FCDE;ARABIC LIGATURE YEH WITH HEH INITIAL FORM;Lo;0;AL;<initial> 064A 0647;;;;N;;;;;
+FCDF;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH MEEM MEDIAL FORM;Lo;0;AL;<medial> 0626 0645;;;;N;;;;;
+FCE0;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH HEH MEDIAL FORM;Lo;0;AL;<medial> 0626 0647;;;;N;;;;;
+FCE1;ARABIC LIGATURE BEH WITH MEEM MEDIAL FORM;Lo;0;AL;<medial> 0628 0645;;;;N;;;;;
+FCE2;ARABIC LIGATURE BEH WITH HEH MEDIAL FORM;Lo;0;AL;<medial> 0628 0647;;;;N;;;;;
+FCE3;ARABIC LIGATURE TEH WITH MEEM MEDIAL FORM;Lo;0;AL;<medial> 062A 0645;;;;N;;;;;
+FCE4;ARABIC LIGATURE TEH WITH HEH MEDIAL FORM;Lo;0;AL;<medial> 062A 0647;;;;N;;;;;
+FCE5;ARABIC LIGATURE THEH WITH MEEM MEDIAL FORM;Lo;0;AL;<medial> 062B 0645;;;;N;;;;;
+FCE6;ARABIC LIGATURE THEH WITH HEH MEDIAL FORM;Lo;0;AL;<medial> 062B 0647;;;;N;;;;;
+FCE7;ARABIC LIGATURE SEEN WITH MEEM MEDIAL FORM;Lo;0;AL;<medial> 0633 0645;;;;N;;;;;
+FCE8;ARABIC LIGATURE SEEN WITH HEH MEDIAL FORM;Lo;0;AL;<medial> 0633 0647;;;;N;;;;;
+FCE9;ARABIC LIGATURE SHEEN WITH MEEM MEDIAL FORM;Lo;0;AL;<medial> 0634 0645;;;;N;;;;;
+FCEA;ARABIC LIGATURE SHEEN WITH HEH MEDIAL FORM;Lo;0;AL;<medial> 0634 0647;;;;N;;;;;
+FCEB;ARABIC LIGATURE KAF WITH LAM MEDIAL FORM;Lo;0;AL;<medial> 0643 0644;;;;N;;;;;
+FCEC;ARABIC LIGATURE KAF WITH MEEM MEDIAL FORM;Lo;0;AL;<medial> 0643 0645;;;;N;;;;;
+FCED;ARABIC LIGATURE LAM WITH MEEM MEDIAL FORM;Lo;0;AL;<medial> 0644 0645;;;;N;;;;;
+FCEE;ARABIC LIGATURE NOON WITH MEEM MEDIAL FORM;Lo;0;AL;<medial> 0646 0645;;;;N;;;;;
+FCEF;ARABIC LIGATURE NOON WITH HEH MEDIAL FORM;Lo;0;AL;<medial> 0646 0647;;;;N;;;;;
+FCF0;ARABIC LIGATURE YEH WITH MEEM MEDIAL FORM;Lo;0;AL;<medial> 064A 0645;;;;N;;;;;
+FCF1;ARABIC LIGATURE YEH WITH HEH MEDIAL FORM;Lo;0;AL;<medial> 064A 0647;;;;N;;;;;
+FCF2;ARABIC LIGATURE SHADDA WITH FATHA MEDIAL FORM;Lo;0;AL;<medial> 0640 064E 0651;;;;N;;;;;
+FCF3;ARABIC LIGATURE SHADDA WITH DAMMA MEDIAL FORM;Lo;0;AL;<medial> 0640 064F 0651;;;;N;;;;;
+FCF4;ARABIC LIGATURE SHADDA WITH KASRA MEDIAL FORM;Lo;0;AL;<medial> 0640 0650 0651;;;;N;;;;;
+FCF5;ARABIC LIGATURE TAH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0637 0649;;;;N;;;;;
+FCF6;ARABIC LIGATURE TAH WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 0637 064A;;;;N;;;;;
+FCF7;ARABIC LIGATURE AIN WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0639 0649;;;;N;;;;;
+FCF8;ARABIC LIGATURE AIN WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 0639 064A;;;;N;;;;;
+FCF9;ARABIC LIGATURE GHAIN WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 063A 0649;;;;N;;;;;
+FCFA;ARABIC LIGATURE GHAIN WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 063A 064A;;;;N;;;;;
+FCFB;ARABIC LIGATURE SEEN WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0633 0649;;;;N;;;;;
+FCFC;ARABIC LIGATURE SEEN WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 0633 064A;;;;N;;;;;
+FCFD;ARABIC LIGATURE SHEEN WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0634 0649;;;;N;;;;;
+FCFE;ARABIC LIGATURE SHEEN WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 0634 064A;;;;N;;;;;
+FCFF;ARABIC LIGATURE HAH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 062D 0649;;;;N;;;;;
+FD00;ARABIC LIGATURE HAH WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 062D 064A;;;;N;;;;;
+FD01;ARABIC LIGATURE JEEM WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 062C 0649;;;;N;;;;;
+FD02;ARABIC LIGATURE JEEM WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 062C 064A;;;;N;;;;;
+FD03;ARABIC LIGATURE KHAH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 062E 0649;;;;N;;;;;
+FD04;ARABIC LIGATURE KHAH WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 062E 064A;;;;N;;;;;
+FD05;ARABIC LIGATURE SAD WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0635 0649;;;;N;;;;;
+FD06;ARABIC LIGATURE SAD WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 0635 064A;;;;N;;;;;
+FD07;ARABIC LIGATURE DAD WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0636 0649;;;;N;;;;;
+FD08;ARABIC LIGATURE DAD WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 0636 064A;;;;N;;;;;
+FD09;ARABIC LIGATURE SHEEN WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 0634 062C;;;;N;;;;;
+FD0A;ARABIC LIGATURE SHEEN WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 0634 062D;;;;N;;;;;
+FD0B;ARABIC LIGATURE SHEEN WITH KHAH ISOLATED FORM;Lo;0;AL;<isolated> 0634 062E;;;;N;;;;;
+FD0C;ARABIC LIGATURE SHEEN WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0634 0645;;;;N;;;;;
+FD0D;ARABIC LIGATURE SHEEN WITH REH ISOLATED FORM;Lo;0;AL;<isolated> 0634 0631;;;;N;;;;;
+FD0E;ARABIC LIGATURE SEEN WITH REH ISOLATED FORM;Lo;0;AL;<isolated> 0633 0631;;;;N;;;;;
+FD0F;ARABIC LIGATURE SAD WITH REH ISOLATED FORM;Lo;0;AL;<isolated> 0635 0631;;;;N;;;;;
+FD10;ARABIC LIGATURE DAD WITH REH ISOLATED FORM;Lo;0;AL;<isolated> 0636 0631;;;;N;;;;;
+FD11;ARABIC LIGATURE TAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0637 0649;;;;N;;;;;
+FD12;ARABIC LIGATURE TAH WITH YEH FINAL FORM;Lo;0;AL;<final> 0637 064A;;;;N;;;;;
+FD13;ARABIC LIGATURE AIN WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0639 0649;;;;N;;;;;
+FD14;ARABIC LIGATURE AIN WITH YEH FINAL FORM;Lo;0;AL;<final> 0639 064A;;;;N;;;;;
+FD15;ARABIC LIGATURE GHAIN WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 063A 0649;;;;N;;;;;
+FD16;ARABIC LIGATURE GHAIN WITH YEH FINAL FORM;Lo;0;AL;<final> 063A 064A;;;;N;;;;;
+FD17;ARABIC LIGATURE SEEN WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0633 0649;;;;N;;;;;
+FD18;ARABIC LIGATURE SEEN WITH YEH FINAL FORM;Lo;0;AL;<final> 0633 064A;;;;N;;;;;
+FD19;ARABIC LIGATURE SHEEN WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0634 0649;;;;N;;;;;
+FD1A;ARABIC LIGATURE SHEEN WITH YEH FINAL FORM;Lo;0;AL;<final> 0634 064A;;;;N;;;;;
+FD1B;ARABIC LIGATURE HAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 062D 0649;;;;N;;;;;
+FD1C;ARABIC LIGATURE HAH WITH YEH FINAL FORM;Lo;0;AL;<final> 062D 064A;;;;N;;;;;
+FD1D;ARABIC LIGATURE JEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 062C 0649;;;;N;;;;;
+FD1E;ARABIC LIGATURE JEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 062C 064A;;;;N;;;;;
+FD1F;ARABIC LIGATURE KHAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 062E 0649;;;;N;;;;;
+FD20;ARABIC LIGATURE KHAH WITH YEH FINAL FORM;Lo;0;AL;<final> 062E 064A;;;;N;;;;;
+FD21;ARABIC LIGATURE SAD WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0635 0649;;;;N;;;;;
+FD22;ARABIC LIGATURE SAD WITH YEH FINAL FORM;Lo;0;AL;<final> 0635 064A;;;;N;;;;;
+FD23;ARABIC LIGATURE DAD WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0636 0649;;;;N;;;;;
+FD24;ARABIC LIGATURE DAD WITH YEH FINAL FORM;Lo;0;AL;<final> 0636 064A;;;;N;;;;;
+FD25;ARABIC LIGATURE SHEEN WITH JEEM FINAL FORM;Lo;0;AL;<final> 0634 062C;;;;N;;;;;
+FD26;ARABIC LIGATURE SHEEN WITH HAH FINAL FORM;Lo;0;AL;<final> 0634 062D;;;;N;;;;;
+FD27;ARABIC LIGATURE SHEEN WITH KHAH FINAL FORM;Lo;0;AL;<final> 0634 062E;;;;N;;;;;
+FD28;ARABIC LIGATURE SHEEN WITH MEEM FINAL FORM;Lo;0;AL;<final> 0634 0645;;;;N;;;;;
+FD29;ARABIC LIGATURE SHEEN WITH REH FINAL FORM;Lo;0;AL;<final> 0634 0631;;;;N;;;;;
+FD2A;ARABIC LIGATURE SEEN WITH REH FINAL FORM;Lo;0;AL;<final> 0633 0631;;;;N;;;;;
+FD2B;ARABIC LIGATURE SAD WITH REH FINAL FORM;Lo;0;AL;<final> 0635 0631;;;;N;;;;;
+FD2C;ARABIC LIGATURE DAD WITH REH FINAL FORM;Lo;0;AL;<final> 0636 0631;;;;N;;;;;
+FD2D;ARABIC LIGATURE SHEEN WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0634 062C;;;;N;;;;;
+FD2E;ARABIC LIGATURE SHEEN WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0634 062D;;;;N;;;;;
+FD2F;ARABIC LIGATURE SHEEN WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 0634 062E;;;;N;;;;;
+FD30;ARABIC LIGATURE SHEEN WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0634 0645;;;;N;;;;;
+FD31;ARABIC LIGATURE SEEN WITH HEH INITIAL FORM;Lo;0;AL;<initial> 0633 0647;;;;N;;;;;
+FD32;ARABIC LIGATURE SHEEN WITH HEH INITIAL FORM;Lo;0;AL;<initial> 0634 0647;;;;N;;;;;
+FD33;ARABIC LIGATURE TAH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0637 0645;;;;N;;;;;
+FD34;ARABIC LIGATURE SEEN WITH JEEM MEDIAL FORM;Lo;0;AL;<medial> 0633 062C;;;;N;;;;;
+FD35;ARABIC LIGATURE SEEN WITH HAH MEDIAL FORM;Lo;0;AL;<medial> 0633 062D;;;;N;;;;;
+FD36;ARABIC LIGATURE SEEN WITH KHAH MEDIAL FORM;Lo;0;AL;<medial> 0633 062E;;;;N;;;;;
+FD37;ARABIC LIGATURE SHEEN WITH JEEM MEDIAL FORM;Lo;0;AL;<medial> 0634 062C;;;;N;;;;;
+FD38;ARABIC LIGATURE SHEEN WITH HAH MEDIAL FORM;Lo;0;AL;<medial> 0634 062D;;;;N;;;;;
+FD39;ARABIC LIGATURE SHEEN WITH KHAH MEDIAL FORM;Lo;0;AL;<medial> 0634 062E;;;;N;;;;;
+FD3A;ARABIC LIGATURE TAH WITH MEEM MEDIAL FORM;Lo;0;AL;<medial> 0637 0645;;;;N;;;;;
+FD3B;ARABIC LIGATURE ZAH WITH MEEM MEDIAL FORM;Lo;0;AL;<medial> 0638 0645;;;;N;;;;;
+FD3C;ARABIC LIGATURE ALEF WITH FATHATAN FINAL FORM;Lo;0;AL;<final> 0627 064B;;;;N;;;;;
+FD3D;ARABIC LIGATURE ALEF WITH FATHATAN ISOLATED FORM;Lo;0;AL;<isolated> 0627 064B;;;;N;;;;;
+FD3E;ORNATE LEFT PARENTHESIS;Ps;0;ON;;;;;N;;;;;
+FD3F;ORNATE RIGHT PARENTHESIS;Pe;0;ON;;;;;N;;;;;
+FD50;ARABIC LIGATURE TEH WITH JEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 062A 062C 0645;;;;N;;;;;
+FD51;ARABIC LIGATURE TEH WITH HAH WITH JEEM FINAL FORM;Lo;0;AL;<final> 062A 062D 062C;;;;N;;;;;
+FD52;ARABIC LIGATURE TEH WITH HAH WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 062A 062D 062C;;;;N;;;;;
+FD53;ARABIC LIGATURE TEH WITH HAH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 062A 062D 0645;;;;N;;;;;
+FD54;ARABIC LIGATURE TEH WITH KHAH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 062A 062E 0645;;;;N;;;;;
+FD55;ARABIC LIGATURE TEH WITH MEEM WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 062A 0645 062C;;;;N;;;;;
+FD56;ARABIC LIGATURE TEH WITH MEEM WITH HAH INITIAL FORM;Lo;0;AL;<initial> 062A 0645 062D;;;;N;;;;;
+FD57;ARABIC LIGATURE TEH WITH MEEM WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 062A 0645 062E;;;;N;;;;;
+FD58;ARABIC LIGATURE JEEM WITH MEEM WITH HAH FINAL FORM;Lo;0;AL;<final> 062C 0645 062D;;;;N;;;;;
+FD59;ARABIC LIGATURE JEEM WITH MEEM WITH HAH INITIAL FORM;Lo;0;AL;<initial> 062C 0645 062D;;;;N;;;;;
+FD5A;ARABIC LIGATURE HAH WITH MEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 062D 0645 064A;;;;N;;;;;
+FD5B;ARABIC LIGATURE HAH WITH MEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 062D 0645 0649;;;;N;;;;;
+FD5C;ARABIC LIGATURE SEEN WITH HAH WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0633 062D 062C;;;;N;;;;;
+FD5D;ARABIC LIGATURE SEEN WITH JEEM WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0633 062C 062D;;;;N;;;;;
+FD5E;ARABIC LIGATURE SEEN WITH JEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0633 062C 0649;;;;N;;;;;
+FD5F;ARABIC LIGATURE SEEN WITH MEEM WITH HAH FINAL FORM;Lo;0;AL;<final> 0633 0645 062D;;;;N;;;;;
+FD60;ARABIC LIGATURE SEEN WITH MEEM WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0633 0645 062D;;;;N;;;;;
+FD61;ARABIC LIGATURE SEEN WITH MEEM WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0633 0645 062C;;;;N;;;;;
+FD62;ARABIC LIGATURE SEEN WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL;<final> 0633 0645 0645;;;;N;;;;;
+FD63;ARABIC LIGATURE SEEN WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0633 0645 0645;;;;N;;;;;
+FD64;ARABIC LIGATURE SAD WITH HAH WITH HAH FINAL FORM;Lo;0;AL;<final> 0635 062D 062D;;;;N;;;;;
+FD65;ARABIC LIGATURE SAD WITH HAH WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0635 062D 062D;;;;N;;;;;
+FD66;ARABIC LIGATURE SAD WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL;<final> 0635 0645 0645;;;;N;;;;;
+FD67;ARABIC LIGATURE SHEEN WITH HAH WITH MEEM FINAL FORM;Lo;0;AL;<final> 0634 062D 0645;;;;N;;;;;
+FD68;ARABIC LIGATURE SHEEN WITH HAH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0634 062D 0645;;;;N;;;;;
+FD69;ARABIC LIGATURE SHEEN WITH JEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 0634 062C 064A;;;;N;;;;;
+FD6A;ARABIC LIGATURE SHEEN WITH MEEM WITH KHAH FINAL FORM;Lo;0;AL;<final> 0634 0645 062E;;;;N;;;;;
+FD6B;ARABIC LIGATURE SHEEN WITH MEEM WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 0634 0645 062E;;;;N;;;;;
+FD6C;ARABIC LIGATURE SHEEN WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL;<final> 0634 0645 0645;;;;N;;;;;
+FD6D;ARABIC LIGATURE SHEEN WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0634 0645 0645;;;;N;;;;;
+FD6E;ARABIC LIGATURE DAD WITH HAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0636 062D 0649;;;;N;;;;;
+FD6F;ARABIC LIGATURE DAD WITH KHAH WITH MEEM FINAL FORM;Lo;0;AL;<final> 0636 062E 0645;;;;N;;;;;
+FD70;ARABIC LIGATURE DAD WITH KHAH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0636 062E 0645;;;;N;;;;;
+FD71;ARABIC LIGATURE TAH WITH MEEM WITH HAH FINAL FORM;Lo;0;AL;<final> 0637 0645 062D;;;;N;;;;;
+FD72;ARABIC LIGATURE TAH WITH MEEM WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0637 0645 062D;;;;N;;;;;
+FD73;ARABIC LIGATURE TAH WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0637 0645 0645;;;;N;;;;;
+FD74;ARABIC LIGATURE TAH WITH MEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 0637 0645 064A;;;;N;;;;;
+FD75;ARABIC LIGATURE AIN WITH JEEM WITH MEEM FINAL FORM;Lo;0;AL;<final> 0639 062C 0645;;;;N;;;;;
+FD76;ARABIC LIGATURE AIN WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL;<final> 0639 0645 0645;;;;N;;;;;
+FD77;ARABIC LIGATURE AIN WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0639 0645 0645;;;;N;;;;;
+FD78;ARABIC LIGATURE AIN WITH MEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0639 0645 0649;;;;N;;;;;
+FD79;ARABIC LIGATURE GHAIN WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL;<final> 063A 0645 0645;;;;N;;;;;
+FD7A;ARABIC LIGATURE GHAIN WITH MEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 063A 0645 064A;;;;N;;;;;
+FD7B;ARABIC LIGATURE GHAIN WITH MEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 063A 0645 0649;;;;N;;;;;
+FD7C;ARABIC LIGATURE FEH WITH KHAH WITH MEEM FINAL FORM;Lo;0;AL;<final> 0641 062E 0645;;;;N;;;;;
+FD7D;ARABIC LIGATURE FEH WITH KHAH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0641 062E 0645;;;;N;;;;;
+FD7E;ARABIC LIGATURE QAF WITH MEEM WITH HAH FINAL FORM;Lo;0;AL;<final> 0642 0645 062D;;;;N;;;;;
+FD7F;ARABIC LIGATURE QAF WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL;<final> 0642 0645 0645;;;;N;;;;;
+FD80;ARABIC LIGATURE LAM WITH HAH WITH MEEM FINAL FORM;Lo;0;AL;<final> 0644 062D 0645;;;;N;;;;;
+FD81;ARABIC LIGATURE LAM WITH HAH WITH YEH FINAL FORM;Lo;0;AL;<final> 0644 062D 064A;;;;N;;;;;
+FD82;ARABIC LIGATURE LAM WITH HAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0644 062D 0649;;;;N;;;;;
+FD83;ARABIC LIGATURE LAM WITH JEEM WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0644 062C 062C;;;;N;;;;;
+FD84;ARABIC LIGATURE LAM WITH JEEM WITH JEEM FINAL FORM;Lo;0;AL;<final> 0644 062C 062C;;;;N;;;;;
+FD85;ARABIC LIGATURE LAM WITH KHAH WITH MEEM FINAL FORM;Lo;0;AL;<final> 0644 062E 0645;;;;N;;;;;
+FD86;ARABIC LIGATURE LAM WITH KHAH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0644 062E 0645;;;;N;;;;;
+FD87;ARABIC LIGATURE LAM WITH MEEM WITH HAH FINAL FORM;Lo;0;AL;<final> 0644 0645 062D;;;;N;;;;;
+FD88;ARABIC LIGATURE LAM WITH MEEM WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0644 0645 062D;;;;N;;;;;
+FD89;ARABIC LIGATURE MEEM WITH HAH WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0645 062D 062C;;;;N;;;;;
+FD8A;ARABIC LIGATURE MEEM WITH HAH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0645 062D 0645;;;;N;;;;;
+FD8B;ARABIC LIGATURE MEEM WITH HAH WITH YEH FINAL FORM;Lo;0;AL;<final> 0645 062D 064A;;;;N;;;;;
+FD8C;ARABIC LIGATURE MEEM WITH JEEM WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0645 062C 062D;;;;N;;;;;
+FD8D;ARABIC LIGATURE MEEM WITH JEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0645 062C 0645;;;;N;;;;;
+FD8E;ARABIC LIGATURE MEEM WITH KHAH WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0645 062E 062C;;;;N;;;;;
+FD8F;ARABIC LIGATURE MEEM WITH KHAH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0645 062E 0645;;;;N;;;;;
+FD92;ARABIC LIGATURE MEEM WITH JEEM WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 0645 062C 062E;;;;N;;;;;
+FD93;ARABIC LIGATURE HEH WITH MEEM WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0647 0645 062C;;;;N;;;;;
+FD94;ARABIC LIGATURE HEH WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0647 0645 0645;;;;N;;;;;
+FD95;ARABIC LIGATURE NOON WITH HAH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0646 062D 0645;;;;N;;;;;
+FD96;ARABIC LIGATURE NOON WITH HAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0646 062D 0649;;;;N;;;;;
+FD97;ARABIC LIGATURE NOON WITH JEEM WITH MEEM FINAL FORM;Lo;0;AL;<final> 0646 062C 0645;;;;N;;;;;
+FD98;ARABIC LIGATURE NOON WITH JEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0646 062C 0645;;;;N;;;;;
+FD99;ARABIC LIGATURE NOON WITH JEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0646 062C 0649;;;;N;;;;;
+FD9A;ARABIC LIGATURE NOON WITH MEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 0646 0645 064A;;;;N;;;;;
+FD9B;ARABIC LIGATURE NOON WITH MEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0646 0645 0649;;;;N;;;;;
+FD9C;ARABIC LIGATURE YEH WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL;<final> 064A 0645 0645;;;;N;;;;;
+FD9D;ARABIC LIGATURE YEH WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 064A 0645 0645;;;;N;;;;;
+FD9E;ARABIC LIGATURE BEH WITH KHAH WITH YEH FINAL FORM;Lo;0;AL;<final> 0628 062E 064A;;;;N;;;;;
+FD9F;ARABIC LIGATURE TEH WITH JEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 062A 062C 064A;;;;N;;;;;
+FDA0;ARABIC LIGATURE TEH WITH JEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 062A 062C 0649;;;;N;;;;;
+FDA1;ARABIC LIGATURE TEH WITH KHAH WITH YEH FINAL FORM;Lo;0;AL;<final> 062A 062E 064A;;;;N;;;;;
+FDA2;ARABIC LIGATURE TEH WITH KHAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 062A 062E 0649;;;;N;;;;;
+FDA3;ARABIC LIGATURE TEH WITH MEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 062A 0645 064A;;;;N;;;;;
+FDA4;ARABIC LIGATURE TEH WITH MEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 062A 0645 0649;;;;N;;;;;
+FDA5;ARABIC LIGATURE JEEM WITH MEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 062C 0645 064A;;;;N;;;;;
+FDA6;ARABIC LIGATURE JEEM WITH HAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 062C 062D 0649;;;;N;;;;;
+FDA7;ARABIC LIGATURE JEEM WITH MEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 062C 0645 0649;;;;N;;;;;
+FDA8;ARABIC LIGATURE SEEN WITH KHAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0633 062E 0649;;;;N;;;;;
+FDA9;ARABIC LIGATURE SAD WITH HAH WITH YEH FINAL FORM;Lo;0;AL;<final> 0635 062D 064A;;;;N;;;;;
+FDAA;ARABIC LIGATURE SHEEN WITH HAH WITH YEH FINAL FORM;Lo;0;AL;<final> 0634 062D 064A;;;;N;;;;;
+FDAB;ARABIC LIGATURE DAD WITH HAH WITH YEH FINAL FORM;Lo;0;AL;<final> 0636 062D 064A;;;;N;;;;;
+FDAC;ARABIC LIGATURE LAM WITH JEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 0644 062C 064A;;;;N;;;;;
+FDAD;ARABIC LIGATURE LAM WITH MEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 0644 0645 064A;;;;N;;;;;
+FDAE;ARABIC LIGATURE YEH WITH HAH WITH YEH FINAL FORM;Lo;0;AL;<final> 064A 062D 064A;;;;N;;;;;
+FDAF;ARABIC LIGATURE YEH WITH JEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 064A 062C 064A;;;;N;;;;;
+FDB0;ARABIC LIGATURE YEH WITH MEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 064A 0645 064A;;;;N;;;;;
+FDB1;ARABIC LIGATURE MEEM WITH MEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 0645 0645 064A;;;;N;;;;;
+FDB2;ARABIC LIGATURE QAF WITH MEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 0642 0645 064A;;;;N;;;;;
+FDB3;ARABIC LIGATURE NOON WITH HAH WITH YEH FINAL FORM;Lo;0;AL;<final> 0646 062D 064A;;;;N;;;;;
+FDB4;ARABIC LIGATURE QAF WITH MEEM WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0642 0645 062D;;;;N;;;;;
+FDB5;ARABIC LIGATURE LAM WITH HAH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0644 062D 0645;;;;N;;;;;
+FDB6;ARABIC LIGATURE AIN WITH MEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 0639 0645 064A;;;;N;;;;;
+FDB7;ARABIC LIGATURE KAF WITH MEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 0643 0645 064A;;;;N;;;;;
+FDB8;ARABIC LIGATURE NOON WITH JEEM WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0646 062C 062D;;;;N;;;;;
+FDB9;ARABIC LIGATURE MEEM WITH KHAH WITH YEH FINAL FORM;Lo;0;AL;<final> 0645 062E 064A;;;;N;;;;;
+FDBA;ARABIC LIGATURE LAM WITH JEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0644 062C 0645;;;;N;;;;;
+FDBB;ARABIC LIGATURE KAF WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL;<final> 0643 0645 0645;;;;N;;;;;
+FDBC;ARABIC LIGATURE LAM WITH JEEM WITH MEEM FINAL FORM;Lo;0;AL;<final> 0644 062C 0645;;;;N;;;;;
+FDBD;ARABIC LIGATURE NOON WITH JEEM WITH HAH FINAL FORM;Lo;0;AL;<final> 0646 062C 062D;;;;N;;;;;
+FDBE;ARABIC LIGATURE JEEM WITH HAH WITH YEH FINAL FORM;Lo;0;AL;<final> 062C 062D 064A;;;;N;;;;;
+FDBF;ARABIC LIGATURE HAH WITH JEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 062D 062C 064A;;;;N;;;;;
+FDC0;ARABIC LIGATURE MEEM WITH JEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 0645 062C 064A;;;;N;;;;;
+FDC1;ARABIC LIGATURE FEH WITH MEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 0641 0645 064A;;;;N;;;;;
+FDC2;ARABIC LIGATURE BEH WITH HAH WITH YEH FINAL FORM;Lo;0;AL;<final> 0628 062D 064A;;;;N;;;;;
+FDC3;ARABIC LIGATURE KAF WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0643 0645 0645;;;;N;;;;;
+FDC4;ARABIC LIGATURE AIN WITH JEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0639 062C 0645;;;;N;;;;;
+FDC5;ARABIC LIGATURE SAD WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0635 0645 0645;;;;N;;;;;
+FDC6;ARABIC LIGATURE SEEN WITH KHAH WITH YEH FINAL FORM;Lo;0;AL;<final> 0633 062E 064A;;;;N;;;;;
+FDC7;ARABIC LIGATURE NOON WITH JEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 0646 062C 064A;;;;N;;;;;
+FDF0;ARABIC LIGATURE SALLA USED AS KORANIC STOP SIGN ISOLATED FORM;Lo;0;AL;<isolated> 0635 0644 06D2;;;;N;;;;;
+FDF1;ARABIC LIGATURE QALA USED AS KORANIC STOP SIGN ISOLATED FORM;Lo;0;AL;<isolated> 0642 0644 06D2;;;;N;;;;;
+FDF2;ARABIC LIGATURE ALLAH ISOLATED FORM;Lo;0;AL;<isolated> 0627 0644 0644 0647;;;;N;;;;;
+FDF3;ARABIC LIGATURE AKBAR ISOLATED FORM;Lo;0;AL;<isolated> 0627 0643 0628 0631;;;;N;;;;;
+FDF4;ARABIC LIGATURE MOHAMMAD ISOLATED FORM;Lo;0;AL;<isolated> 0645 062D 0645 062F;;;;N;;;;;
+FDF5;ARABIC LIGATURE SALAM ISOLATED FORM;Lo;0;AL;<isolated> 0635 0644 0639 0645;;;;N;;;;;
+FDF6;ARABIC LIGATURE RASOUL ISOLATED FORM;Lo;0;AL;<isolated> 0631 0633 0648 0644;;;;N;;;;;
+FDF7;ARABIC LIGATURE ALAYHE ISOLATED FORM;Lo;0;AL;<isolated> 0639 0644 064A 0647;;;;N;;;;;
+FDF8;ARABIC LIGATURE WASALLAM ISOLATED FORM;Lo;0;AL;<isolated> 0648 0633 0644 0645;;;;N;;;;;
+FDF9;ARABIC LIGATURE SALLA ISOLATED FORM;Lo;0;AL;<isolated> 0635 0644 0649;;;;N;;;;;
+FDFA;ARABIC LIGATURE SALLALLAHOU ALAYHE WASALLAM;Lo;0;AL;<isolated> 0635 0644 0649 0020 0627 0644 0644 0647 0020 0639 0644 064A 0647 0020 0648 0633 0644 0645;;;;N;ARABIC LETTER SALLALLAHOU ALAYHE WASALLAM;;;;
+FDFB;ARABIC LIGATURE JALLAJALALOUHOU;Lo;0;AL;<isolated> 062C 0644 0020 062C 0644 0627 0644 0647;;;;N;ARABIC LETTER JALLAJALALOUHOU;;;;
+FDFC;RIAL SIGN;Sc;0;AL;<isolated> 0631 06CC 0627 0644;;;;N;;;;;
+FDFD;ARABIC LIGATURE BISMILLAH AR-RAHMAN AR-RAHEEM;So;0;ON;;;;;N;;;;;
+FE00;VARIATION SELECTOR-1;Mn;0;NSM;;;;;N;;;;;
+FE01;VARIATION SELECTOR-2;Mn;0;NSM;;;;;N;;;;;
+FE02;VARIATION SELECTOR-3;Mn;0;NSM;;;;;N;;;;;
+FE03;VARIATION SELECTOR-4;Mn;0;NSM;;;;;N;;;;;
+FE04;VARIATION SELECTOR-5;Mn;0;NSM;;;;;N;;;;;
+FE05;VARIATION SELECTOR-6;Mn;0;NSM;;;;;N;;;;;
+FE06;VARIATION SELECTOR-7;Mn;0;NSM;;;;;N;;;;;
+FE07;VARIATION SELECTOR-8;Mn;0;NSM;;;;;N;;;;;
+FE08;VARIATION SELECTOR-9;Mn;0;NSM;;;;;N;;;;;
+FE09;VARIATION SELECTOR-10;Mn;0;NSM;;;;;N;;;;;
+FE0A;VARIATION SELECTOR-11;Mn;0;NSM;;;;;N;;;;;
+FE0B;VARIATION SELECTOR-12;Mn;0;NSM;;;;;N;;;;;
+FE0C;VARIATION SELECTOR-13;Mn;0;NSM;;;;;N;;;;;
+FE0D;VARIATION SELECTOR-14;Mn;0;NSM;;;;;N;;;;;
+FE0E;VARIATION SELECTOR-15;Mn;0;NSM;;;;;N;;;;;
+FE0F;VARIATION SELECTOR-16;Mn;0;NSM;;;;;N;;;;;
+FE10;PRESENTATION FORM FOR VERTICAL COMMA;Po;0;ON;<vertical> 002C;;;;N;;;;;
+FE11;PRESENTATION FORM FOR VERTICAL IDEOGRAPHIC COMMA;Po;0;ON;<vertical> 3001;;;;N;;;;;
+FE12;PRESENTATION FORM FOR VERTICAL IDEOGRAPHIC FULL STOP;Po;0;ON;<vertical> 3002;;;;N;;;;;
+FE13;PRESENTATION FORM FOR VERTICAL COLON;Po;0;ON;<vertical> 003A;;;;N;;;;;
+FE14;PRESENTATION FORM FOR VERTICAL SEMICOLON;Po;0;ON;<vertical> 003B;;;;N;;;;;
+FE15;PRESENTATION FORM FOR VERTICAL EXCLAMATION MARK;Po;0;ON;<vertical> 0021;;;;N;;;;;
+FE16;PRESENTATION FORM FOR VERTICAL QUESTION MARK;Po;0;ON;<vertical> 003F;;;;N;;;;;
+FE17;PRESENTATION FORM FOR VERTICAL LEFT WHITE LENTICULAR BRACKET;Ps;0;ON;<vertical> 3016;;;;N;;;;;
+FE18;PRESENTATION FORM FOR VERTICAL RIGHT WHITE LENTICULAR BRAKCET;Pe;0;ON;<vertical> 3017;;;;N;;;;;
+FE19;PRESENTATION FORM FOR VERTICAL HORIZONTAL ELLIPSIS;Po;0;ON;<vertical> 2026;;;;N;;;;;
+FE20;COMBINING LIGATURE LEFT HALF;Mn;230;NSM;;;;;N;;;;;
+FE21;COMBINING LIGATURE RIGHT HALF;Mn;230;NSM;;;;;N;;;;;
+FE22;COMBINING DOUBLE TILDE LEFT HALF;Mn;230;NSM;;;;;N;;;;;
+FE23;COMBINING DOUBLE TILDE RIGHT HALF;Mn;230;NSM;;;;;N;;;;;
+FE24;COMBINING MACRON LEFT HALF;Mn;230;NSM;;;;;N;;;;;
+FE25;COMBINING MACRON RIGHT HALF;Mn;230;NSM;;;;;N;;;;;
+FE26;COMBINING CONJOINING MACRON;Mn;230;NSM;;;;;N;;;;;
+FE30;PRESENTATION FORM FOR VERTICAL TWO DOT LEADER;Po;0;ON;<vertical> 2025;;;;N;GLYPH FOR VERTICAL TWO DOT LEADER;;;;
+FE31;PRESENTATION FORM FOR VERTICAL EM DASH;Pd;0;ON;<vertical> 2014;;;;N;GLYPH FOR VERTICAL EM DASH;;;;
+FE32;PRESENTATION FORM FOR VERTICAL EN DASH;Pd;0;ON;<vertical> 2013;;;;N;GLYPH FOR VERTICAL EN DASH;;;;
+FE33;PRESENTATION FORM FOR VERTICAL LOW LINE;Pc;0;ON;<vertical> 005F;;;;N;GLYPH FOR VERTICAL SPACING UNDERSCORE;;;;
+FE34;PRESENTATION FORM FOR VERTICAL WAVY LOW LINE;Pc;0;ON;<vertical> 005F;;;;N;GLYPH FOR VERTICAL SPACING WAVY UNDERSCORE;;;;
+FE35;PRESENTATION FORM FOR VERTICAL LEFT PARENTHESIS;Ps;0;ON;<vertical> 0028;;;;N;GLYPH FOR VERTICAL OPENING PARENTHESIS;;;;
+FE36;PRESENTATION FORM FOR VERTICAL RIGHT PARENTHESIS;Pe;0;ON;<vertical> 0029;;;;N;GLYPH FOR VERTICAL CLOSING PARENTHESIS;;;;
+FE37;PRESENTATION FORM FOR VERTICAL LEFT CURLY BRACKET;Ps;0;ON;<vertical> 007B;;;;N;GLYPH FOR VERTICAL OPENING CURLY BRACKET;;;;
+FE38;PRESENTATION FORM FOR VERTICAL RIGHT CURLY BRACKET;Pe;0;ON;<vertical> 007D;;;;N;GLYPH FOR VERTICAL CLOSING CURLY BRACKET;;;;
+FE39;PRESENTATION FORM FOR VERTICAL LEFT TORTOISE SHELL BRACKET;Ps;0;ON;<vertical> 3014;;;;N;GLYPH FOR VERTICAL OPENING TORTOISE SHELL BRACKET;;;;
+FE3A;PRESENTATION FORM FOR VERTICAL RIGHT TORTOISE SHELL BRACKET;Pe;0;ON;<vertical> 3015;;;;N;GLYPH FOR VERTICAL CLOSING TORTOISE SHELL BRACKET;;;;
+FE3B;PRESENTATION FORM FOR VERTICAL LEFT BLACK LENTICULAR BRACKET;Ps;0;ON;<vertical> 3010;;;;N;GLYPH FOR VERTICAL OPENING BLACK LENTICULAR BRACKET;;;;
+FE3C;PRESENTATION FORM FOR VERTICAL RIGHT BLACK LENTICULAR BRACKET;Pe;0;ON;<vertical> 3011;;;;N;GLYPH FOR VERTICAL CLOSING BLACK LENTICULAR BRACKET;;;;
+FE3D;PRESENTATION FORM FOR VERTICAL LEFT DOUBLE ANGLE BRACKET;Ps;0;ON;<vertical> 300A;;;;N;GLYPH FOR VERTICAL OPENING DOUBLE ANGLE BRACKET;;;;
+FE3E;PRESENTATION FORM FOR VERTICAL RIGHT DOUBLE ANGLE BRACKET;Pe;0;ON;<vertical> 300B;;;;N;GLYPH FOR VERTICAL CLOSING DOUBLE ANGLE BRACKET;;;;
+FE3F;PRESENTATION FORM FOR VERTICAL LEFT ANGLE BRACKET;Ps;0;ON;<vertical> 3008;;;;N;GLYPH FOR VERTICAL OPENING ANGLE BRACKET;;;;
+FE40;PRESENTATION FORM FOR VERTICAL RIGHT ANGLE BRACKET;Pe;0;ON;<vertical> 3009;;;;N;GLYPH FOR VERTICAL CLOSING ANGLE BRACKET;;;;
+FE41;PRESENTATION FORM FOR VERTICAL LEFT CORNER BRACKET;Ps;0;ON;<vertical> 300C;;;;N;GLYPH FOR VERTICAL OPENING CORNER BRACKET;;;;
+FE42;PRESENTATION FORM FOR VERTICAL RIGHT CORNER BRACKET;Pe;0;ON;<vertical> 300D;;;;N;GLYPH FOR VERTICAL CLOSING CORNER BRACKET;;;;
+FE43;PRESENTATION FORM FOR VERTICAL LEFT WHITE CORNER BRACKET;Ps;0;ON;<vertical> 300E;;;;N;GLYPH FOR VERTICAL OPENING WHITE CORNER BRACKET;;;;
+FE44;PRESENTATION FORM FOR VERTICAL RIGHT WHITE CORNER BRACKET;Pe;0;ON;<vertical> 300F;;;;N;GLYPH FOR VERTICAL CLOSING WHITE CORNER BRACKET;;;;
+FE45;SESAME DOT;Po;0;ON;;;;;N;;;;;
+FE46;WHITE SESAME DOT;Po;0;ON;;;;;N;;;;;
+FE47;PRESENTATION FORM FOR VERTICAL LEFT SQUARE BRACKET;Ps;0;ON;<vertical> 005B;;;;N;;;;;
+FE48;PRESENTATION FORM FOR VERTICAL RIGHT SQUARE BRACKET;Pe;0;ON;<vertical> 005D;;;;N;;;;;
+FE49;DASHED OVERLINE;Po;0;ON;<compat> 203E;;;;N;SPACING DASHED OVERSCORE;;;;
+FE4A;CENTRELINE OVERLINE;Po;0;ON;<compat> 203E;;;;N;SPACING CENTERLINE OVERSCORE;;;;
+FE4B;WAVY OVERLINE;Po;0;ON;<compat> 203E;;;;N;SPACING WAVY OVERSCORE;;;;
+FE4C;DOUBLE WAVY OVERLINE;Po;0;ON;<compat> 203E;;;;N;SPACING DOUBLE WAVY OVERSCORE;;;;
+FE4D;DASHED LOW LINE;Pc;0;ON;<compat> 005F;;;;N;SPACING DASHED UNDERSCORE;;;;
+FE4E;CENTRELINE LOW LINE;Pc;0;ON;<compat> 005F;;;;N;SPACING CENTERLINE UNDERSCORE;;;;
+FE4F;WAVY LOW LINE;Pc;0;ON;<compat> 005F;;;;N;SPACING WAVY UNDERSCORE;;;;
+FE50;SMALL COMMA;Po;0;CS;<small> 002C;;;;N;;;;;
+FE51;SMALL IDEOGRAPHIC COMMA;Po;0;ON;<small> 3001;;;;N;;;;;
+FE52;SMALL FULL STOP;Po;0;CS;<small> 002E;;;;N;SMALL PERIOD;;;;
+FE54;SMALL SEMICOLON;Po;0;ON;<small> 003B;;;;N;;;;;
+FE55;SMALL COLON;Po;0;CS;<small> 003A;;;;N;;;;;
+FE56;SMALL QUESTION MARK;Po;0;ON;<small> 003F;;;;N;;;;;
+FE57;SMALL EXCLAMATION MARK;Po;0;ON;<small> 0021;;;;N;;;;;
+FE58;SMALL EM DASH;Pd;0;ON;<small> 2014;;;;N;;;;;
+FE59;SMALL LEFT PARENTHESIS;Ps;0;ON;<small> 0028;;;;Y;SMALL OPENING PARENTHESIS;;;;
+FE5A;SMALL RIGHT PARENTHESIS;Pe;0;ON;<small> 0029;;;;Y;SMALL CLOSING PARENTHESIS;;;;
+FE5B;SMALL LEFT CURLY BRACKET;Ps;0;ON;<small> 007B;;;;Y;SMALL OPENING CURLY BRACKET;;;;
+FE5C;SMALL RIGHT CURLY BRACKET;Pe;0;ON;<small> 007D;;;;Y;SMALL CLOSING CURLY BRACKET;;;;
+FE5D;SMALL LEFT TORTOISE SHELL BRACKET;Ps;0;ON;<small> 3014;;;;Y;SMALL OPENING TORTOISE SHELL BRACKET;;;;
+FE5E;SMALL RIGHT TORTOISE SHELL BRACKET;Pe;0;ON;<small> 3015;;;;Y;SMALL CLOSING TORTOISE SHELL BRACKET;;;;
+FE5F;SMALL NUMBER SIGN;Po;0;ET;<small> 0023;;;;N;;;;;
+FE60;SMALL AMPERSAND;Po;0;ON;<small> 0026;;;;N;;;;;
+FE61;SMALL ASTERISK;Po;0;ON;<small> 002A;;;;N;;;;;
+FE62;SMALL PLUS SIGN;Sm;0;ES;<small> 002B;;;;N;;;;;
+FE63;SMALL HYPHEN-MINUS;Pd;0;ES;<small> 002D;;;;N;;;;;
+FE64;SMALL LESS-THAN SIGN;Sm;0;ON;<small> 003C;;;;Y;;;;;
+FE65;SMALL GREATER-THAN SIGN;Sm;0;ON;<small> 003E;;;;Y;;;;;
+FE66;SMALL EQUALS SIGN;Sm;0;ON;<small> 003D;;;;N;;;;;
+FE68;SMALL REVERSE SOLIDUS;Po;0;ON;<small> 005C;;;;N;SMALL BACKSLASH;;;;
+FE69;SMALL DOLLAR SIGN;Sc;0;ET;<small> 0024;;;;N;;;;;
+FE6A;SMALL PERCENT SIGN;Po;0;ET;<small> 0025;;;;N;;;;;
+FE6B;SMALL COMMERCIAL AT;Po;0;ON;<small> 0040;;;;N;;;;;
+FE70;ARABIC FATHATAN ISOLATED FORM;Lo;0;AL;<isolated> 0020 064B;;;;N;ARABIC SPACING FATHATAN;;;;
+FE71;ARABIC TATWEEL WITH FATHATAN ABOVE;Lo;0;AL;<medial> 0640 064B;;;;N;ARABIC FATHATAN ON TATWEEL;;;;
+FE72;ARABIC DAMMATAN ISOLATED FORM;Lo;0;AL;<isolated> 0020 064C;;;;N;ARABIC SPACING DAMMATAN;;;;
+FE73;ARABIC TAIL FRAGMENT;Lo;0;AL;;;;;N;;;;;
+FE74;ARABIC KASRATAN ISOLATED FORM;Lo;0;AL;<isolated> 0020 064D;;;;N;ARABIC SPACING KASRATAN;;;;
+FE76;ARABIC FATHA ISOLATED FORM;Lo;0;AL;<isolated> 0020 064E;;;;N;ARABIC SPACING FATHAH;;;;
+FE77;ARABIC FATHA MEDIAL FORM;Lo;0;AL;<medial> 0640 064E;;;;N;ARABIC FATHAH ON TATWEEL;;;;
+FE78;ARABIC DAMMA ISOLATED FORM;Lo;0;AL;<isolated> 0020 064F;;;;N;ARABIC SPACING DAMMAH;;;;
+FE79;ARABIC DAMMA MEDIAL FORM;Lo;0;AL;<medial> 0640 064F;;;;N;ARABIC DAMMAH ON TATWEEL;;;;
+FE7A;ARABIC KASRA ISOLATED FORM;Lo;0;AL;<isolated> 0020 0650;;;;N;ARABIC SPACING KASRAH;;;;
+FE7B;ARABIC KASRA MEDIAL FORM;Lo;0;AL;<medial> 0640 0650;;;;N;ARABIC KASRAH ON TATWEEL;;;;
+FE7C;ARABIC SHADDA ISOLATED FORM;Lo;0;AL;<isolated> 0020 0651;;;;N;ARABIC SPACING SHADDAH;;;;
+FE7D;ARABIC SHADDA MEDIAL FORM;Lo;0;AL;<medial> 0640 0651;;;;N;ARABIC SHADDAH ON TATWEEL;;;;
+FE7E;ARABIC SUKUN ISOLATED FORM;Lo;0;AL;<isolated> 0020 0652;;;;N;ARABIC SPACING SUKUN;;;;
+FE7F;ARABIC SUKUN MEDIAL FORM;Lo;0;AL;<medial> 0640 0652;;;;N;ARABIC SUKUN ON TATWEEL;;;;
+FE80;ARABIC LETTER HAMZA ISOLATED FORM;Lo;0;AL;<isolated> 0621;;;;N;GLYPH FOR ISOLATE ARABIC HAMZAH;;;;
+FE81;ARABIC LETTER ALEF WITH MADDA ABOVE ISOLATED FORM;Lo;0;AL;<isolated> 0622;;;;N;GLYPH FOR ISOLATE ARABIC MADDAH ON ALEF;;;;
+FE82;ARABIC LETTER ALEF WITH MADDA ABOVE FINAL FORM;Lo;0;AL;<final> 0622;;;;N;GLYPH FOR FINAL ARABIC MADDAH ON ALEF;;;;
+FE83;ARABIC LETTER ALEF WITH HAMZA ABOVE ISOLATED FORM;Lo;0;AL;<isolated> 0623;;;;N;GLYPH FOR ISOLATE ARABIC HAMZAH ON ALEF;;;;
+FE84;ARABIC LETTER ALEF WITH HAMZA ABOVE FINAL FORM;Lo;0;AL;<final> 0623;;;;N;GLYPH FOR FINAL ARABIC HAMZAH ON ALEF;;;;
+FE85;ARABIC LETTER WAW WITH HAMZA ABOVE ISOLATED FORM;Lo;0;AL;<isolated> 0624;;;;N;GLYPH FOR ISOLATE ARABIC HAMZAH ON WAW;;;;
+FE86;ARABIC LETTER WAW WITH HAMZA ABOVE FINAL FORM;Lo;0;AL;<final> 0624;;;;N;GLYPH FOR FINAL ARABIC HAMZAH ON WAW;;;;
+FE87;ARABIC LETTER ALEF WITH HAMZA BELOW ISOLATED FORM;Lo;0;AL;<isolated> 0625;;;;N;GLYPH FOR ISOLATE ARABIC HAMZAH UNDER ALEF;;;;
+FE88;ARABIC LETTER ALEF WITH HAMZA BELOW FINAL FORM;Lo;0;AL;<final> 0625;;;;N;GLYPH FOR FINAL ARABIC HAMZAH UNDER ALEF;;;;
+FE89;ARABIC LETTER YEH WITH HAMZA ABOVE ISOLATED FORM;Lo;0;AL;<isolated> 0626;;;;N;GLYPH FOR ISOLATE ARABIC HAMZAH ON YA;;;;
+FE8A;ARABIC LETTER YEH WITH HAMZA ABOVE FINAL FORM;Lo;0;AL;<final> 0626;;;;N;GLYPH FOR FINAL ARABIC HAMZAH ON YA;;;;
+FE8B;ARABIC LETTER YEH WITH HAMZA ABOVE INITIAL FORM;Lo;0;AL;<initial> 0626;;;;N;GLYPH FOR INITIAL ARABIC HAMZAH ON YA;;;;
+FE8C;ARABIC LETTER YEH WITH HAMZA ABOVE MEDIAL FORM;Lo;0;AL;<medial> 0626;;;;N;GLYPH FOR MEDIAL ARABIC HAMZAH ON YA;;;;
+FE8D;ARABIC LETTER ALEF ISOLATED FORM;Lo;0;AL;<isolated> 0627;;;;N;GLYPH FOR ISOLATE ARABIC ALEF;;;;
+FE8E;ARABIC LETTER ALEF FINAL FORM;Lo;0;AL;<final> 0627;;;;N;GLYPH FOR FINAL ARABIC ALEF;;;;
+FE8F;ARABIC LETTER BEH ISOLATED FORM;Lo;0;AL;<isolated> 0628;;;;N;GLYPH FOR ISOLATE ARABIC BAA;;;;
+FE90;ARABIC LETTER BEH FINAL FORM;Lo;0;AL;<final> 0628;;;;N;GLYPH FOR FINAL ARABIC BAA;;;;
+FE91;ARABIC LETTER BEH INITIAL FORM;Lo;0;AL;<initial> 0628;;;;N;GLYPH FOR INITIAL ARABIC BAA;;;;
+FE92;ARABIC LETTER BEH MEDIAL FORM;Lo;0;AL;<medial> 0628;;;;N;GLYPH FOR MEDIAL ARABIC BAA;;;;
+FE93;ARABIC LETTER TEH MARBUTA ISOLATED FORM;Lo;0;AL;<isolated> 0629;;;;N;GLYPH FOR ISOLATE ARABIC TAA MARBUTAH;;;;
+FE94;ARABIC LETTER TEH MARBUTA FINAL FORM;Lo;0;AL;<final> 0629;;;;N;GLYPH FOR FINAL ARABIC TAA MARBUTAH;;;;
+FE95;ARABIC LETTER TEH ISOLATED FORM;Lo;0;AL;<isolated> 062A;;;;N;GLYPH FOR ISOLATE ARABIC TAA;;;;
+FE96;ARABIC LETTER TEH FINAL FORM;Lo;0;AL;<final> 062A;;;;N;GLYPH FOR FINAL ARABIC TAA;;;;
+FE97;ARABIC LETTER TEH INITIAL FORM;Lo;0;AL;<initial> 062A;;;;N;GLYPH FOR INITIAL ARABIC TAA;;;;
+FE98;ARABIC LETTER TEH MEDIAL FORM;Lo;0;AL;<medial> 062A;;;;N;GLYPH FOR MEDIAL ARABIC TAA;;;;
+FE99;ARABIC LETTER THEH ISOLATED FORM;Lo;0;AL;<isolated> 062B;;;;N;GLYPH FOR ISOLATE ARABIC THAA;;;;
+FE9A;ARABIC LETTER THEH FINAL FORM;Lo;0;AL;<final> 062B;;;;N;GLYPH FOR FINAL ARABIC THAA;;;;
+FE9B;ARABIC LETTER THEH INITIAL FORM;Lo;0;AL;<initial> 062B;;;;N;GLYPH FOR INITIAL ARABIC THAA;;;;
+FE9C;ARABIC LETTER THEH MEDIAL FORM;Lo;0;AL;<medial> 062B;;;;N;GLYPH FOR MEDIAL ARABIC THAA;;;;
+FE9D;ARABIC LETTER JEEM ISOLATED FORM;Lo;0;AL;<isolated> 062C;;;;N;GLYPH FOR ISOLATE ARABIC JEEM;;;;
+FE9E;ARABIC LETTER JEEM FINAL FORM;Lo;0;AL;<final> 062C;;;;N;GLYPH FOR FINAL ARABIC JEEM;;;;
+FE9F;ARABIC LETTER JEEM INITIAL FORM;Lo;0;AL;<initial> 062C;;;;N;GLYPH FOR INITIAL ARABIC JEEM;;;;
+FEA0;ARABIC LETTER JEEM MEDIAL FORM;Lo;0;AL;<medial> 062C;;;;N;GLYPH FOR MEDIAL ARABIC JEEM;;;;
+FEA1;ARABIC LETTER HAH ISOLATED FORM;Lo;0;AL;<isolated> 062D;;;;N;GLYPH FOR ISOLATE ARABIC HAA;;;;
+FEA2;ARABIC LETTER HAH FINAL FORM;Lo;0;AL;<final> 062D;;;;N;GLYPH FOR FINAL ARABIC HAA;;;;
+FEA3;ARABIC LETTER HAH INITIAL FORM;Lo;0;AL;<initial> 062D;;;;N;GLYPH FOR INITIAL ARABIC HAA;;;;
+FEA4;ARABIC LETTER HAH MEDIAL FORM;Lo;0;AL;<medial> 062D;;;;N;GLYPH FOR MEDIAL ARABIC HAA;;;;
+FEA5;ARABIC LETTER KHAH ISOLATED FORM;Lo;0;AL;<isolated> 062E;;;;N;GLYPH FOR ISOLATE ARABIC KHAA;;;;
+FEA6;ARABIC LETTER KHAH FINAL FORM;Lo;0;AL;<final> 062E;;;;N;GLYPH FOR FINAL ARABIC KHAA;;;;
+FEA7;ARABIC LETTER KHAH INITIAL FORM;Lo;0;AL;<initial> 062E;;;;N;GLYPH FOR INITIAL ARABIC KHAA;;;;
+FEA8;ARABIC LETTER KHAH MEDIAL FORM;Lo;0;AL;<medial> 062E;;;;N;GLYPH FOR MEDIAL ARABIC KHAA;;;;
+FEA9;ARABIC LETTER DAL ISOLATED FORM;Lo;0;AL;<isolated> 062F;;;;N;GLYPH FOR ISOLATE ARABIC DAL;;;;
+FEAA;ARABIC LETTER DAL FINAL FORM;Lo;0;AL;<final> 062F;;;;N;GLYPH FOR FINAL ARABIC DAL;;;;
+FEAB;ARABIC LETTER THAL ISOLATED FORM;Lo;0;AL;<isolated> 0630;;;;N;GLYPH FOR ISOLATE ARABIC THAL;;;;
+FEAC;ARABIC LETTER THAL FINAL FORM;Lo;0;AL;<final> 0630;;;;N;GLYPH FOR FINAL ARABIC THAL;;;;
+FEAD;ARABIC LETTER REH ISOLATED FORM;Lo;0;AL;<isolated> 0631;;;;N;GLYPH FOR ISOLATE ARABIC RA;;;;
+FEAE;ARABIC LETTER REH FINAL FORM;Lo;0;AL;<final> 0631;;;;N;GLYPH FOR FINAL ARABIC RA;;;;
+FEAF;ARABIC LETTER ZAIN ISOLATED FORM;Lo;0;AL;<isolated> 0632;;;;N;GLYPH FOR ISOLATE ARABIC ZAIN;;;;
+FEB0;ARABIC LETTER ZAIN FINAL FORM;Lo;0;AL;<final> 0632;;;;N;GLYPH FOR FINAL ARABIC ZAIN;;;;
+FEB1;ARABIC LETTER SEEN ISOLATED FORM;Lo;0;AL;<isolated> 0633;;;;N;GLYPH FOR ISOLATE ARABIC SEEN;;;;
+FEB2;ARABIC LETTER SEEN FINAL FORM;Lo;0;AL;<final> 0633;;;;N;GLYPH FOR FINAL ARABIC SEEN;;;;
+FEB3;ARABIC LETTER SEEN INITIAL FORM;Lo;0;AL;<initial> 0633;;;;N;GLYPH FOR INITIAL ARABIC SEEN;;;;
+FEB4;ARABIC LETTER SEEN MEDIAL FORM;Lo;0;AL;<medial> 0633;;;;N;GLYPH FOR MEDIAL ARABIC SEEN;;;;
+FEB5;ARABIC LETTER SHEEN ISOLATED FORM;Lo;0;AL;<isolated> 0634;;;;N;GLYPH FOR ISOLATE ARABIC SHEEN;;;;
+FEB6;ARABIC LETTER SHEEN FINAL FORM;Lo;0;AL;<final> 0634;;;;N;GLYPH FOR FINAL ARABIC SHEEN;;;;
+FEB7;ARABIC LETTER SHEEN INITIAL FORM;Lo;0;AL;<initial> 0634;;;;N;GLYPH FOR INITIAL ARABIC SHEEN;;;;
+FEB8;ARABIC LETTER SHEEN MEDIAL FORM;Lo;0;AL;<medial> 0634;;;;N;GLYPH FOR MEDIAL ARABIC SHEEN;;;;
+FEB9;ARABIC LETTER SAD ISOLATED FORM;Lo;0;AL;<isolated> 0635;;;;N;GLYPH FOR ISOLATE ARABIC SAD;;;;
+FEBA;ARABIC LETTER SAD FINAL FORM;Lo;0;AL;<final> 0635;;;;N;GLYPH FOR FINAL ARABIC SAD;;;;
+FEBB;ARABIC LETTER SAD INITIAL FORM;Lo;0;AL;<initial> 0635;;;;N;GLYPH FOR INITIAL ARABIC SAD;;;;
+FEBC;ARABIC LETTER SAD MEDIAL FORM;Lo;0;AL;<medial> 0635;;;;N;GLYPH FOR MEDIAL ARABIC SAD;;;;
+FEBD;ARABIC LETTER DAD ISOLATED FORM;Lo;0;AL;<isolated> 0636;;;;N;GLYPH FOR ISOLATE ARABIC DAD;;;;
+FEBE;ARABIC LETTER DAD FINAL FORM;Lo;0;AL;<final> 0636;;;;N;GLYPH FOR FINAL ARABIC DAD;;;;
+FEBF;ARABIC LETTER DAD INITIAL FORM;Lo;0;AL;<initial> 0636;;;;N;GLYPH FOR INITIAL ARABIC DAD;;;;
+FEC0;ARABIC LETTER DAD MEDIAL FORM;Lo;0;AL;<medial> 0636;;;;N;GLYPH FOR MEDIAL ARABIC DAD;;;;
+FEC1;ARABIC LETTER TAH ISOLATED FORM;Lo;0;AL;<isolated> 0637;;;;N;GLYPH FOR ISOLATE ARABIC TAH;;;;
+FEC2;ARABIC LETTER TAH FINAL FORM;Lo;0;AL;<final> 0637;;;;N;GLYPH FOR FINAL ARABIC TAH;;;;
+FEC3;ARABIC LETTER TAH INITIAL FORM;Lo;0;AL;<initial> 0637;;;;N;GLYPH FOR INITIAL ARABIC TAH;;;;
+FEC4;ARABIC LETTER TAH MEDIAL FORM;Lo;0;AL;<medial> 0637;;;;N;GLYPH FOR MEDIAL ARABIC TAH;;;;
+FEC5;ARABIC LETTER ZAH ISOLATED FORM;Lo;0;AL;<isolated> 0638;;;;N;GLYPH FOR ISOLATE ARABIC DHAH;;;;
+FEC6;ARABIC LETTER ZAH FINAL FORM;Lo;0;AL;<final> 0638;;;;N;GLYPH FOR FINAL ARABIC DHAH;;;;
+FEC7;ARABIC LETTER ZAH INITIAL FORM;Lo;0;AL;<initial> 0638;;;;N;GLYPH FOR INITIAL ARABIC DHAH;;;;
+FEC8;ARABIC LETTER ZAH MEDIAL FORM;Lo;0;AL;<medial> 0638;;;;N;GLYPH FOR MEDIAL ARABIC DHAH;;;;
+FEC9;ARABIC LETTER AIN ISOLATED FORM;Lo;0;AL;<isolated> 0639;;;;N;GLYPH FOR ISOLATE ARABIC AIN;;;;
+FECA;ARABIC LETTER AIN FINAL FORM;Lo;0;AL;<final> 0639;;;;N;GLYPH FOR FINAL ARABIC AIN;;;;
+FECB;ARABIC LETTER AIN INITIAL FORM;Lo;0;AL;<initial> 0639;;;;N;GLYPH FOR INITIAL ARABIC AIN;;;;
+FECC;ARABIC LETTER AIN MEDIAL FORM;Lo;0;AL;<medial> 0639;;;;N;GLYPH FOR MEDIAL ARABIC AIN;;;;
+FECD;ARABIC LETTER GHAIN ISOLATED FORM;Lo;0;AL;<isolated> 063A;;;;N;GLYPH FOR ISOLATE ARABIC GHAIN;;;;
+FECE;ARABIC LETTER GHAIN FINAL FORM;Lo;0;AL;<final> 063A;;;;N;GLYPH FOR FINAL ARABIC GHAIN;;;;
+FECF;ARABIC LETTER GHAIN INITIAL FORM;Lo;0;AL;<initial> 063A;;;;N;GLYPH FOR INITIAL ARABIC GHAIN;;;;
+FED0;ARABIC LETTER GHAIN MEDIAL FORM;Lo;0;AL;<medial> 063A;;;;N;GLYPH FOR MEDIAL ARABIC GHAIN;;;;
+FED1;ARABIC LETTER FEH ISOLATED FORM;Lo;0;AL;<isolated> 0641;;;;N;GLYPH FOR ISOLATE ARABIC FA;;;;
+FED2;ARABIC LETTER FEH FINAL FORM;Lo;0;AL;<final> 0641;;;;N;GLYPH FOR FINAL ARABIC FA;;;;
+FED3;ARABIC LETTER FEH INITIAL FORM;Lo;0;AL;<initial> 0641;;;;N;GLYPH FOR INITIAL ARABIC FA;;;;
+FED4;ARABIC LETTER FEH MEDIAL FORM;Lo;0;AL;<medial> 0641;;;;N;GLYPH FOR MEDIAL ARABIC FA;;;;
+FED5;ARABIC LETTER QAF ISOLATED FORM;Lo;0;AL;<isolated> 0642;;;;N;GLYPH FOR ISOLATE ARABIC QAF;;;;
+FED6;ARABIC LETTER QAF FINAL FORM;Lo;0;AL;<final> 0642;;;;N;GLYPH FOR FINAL ARABIC QAF;;;;
+FED7;ARABIC LETTER QAF INITIAL FORM;Lo;0;AL;<initial> 0642;;;;N;GLYPH FOR INITIAL ARABIC QAF;;;;
+FED8;ARABIC LETTER QAF MEDIAL FORM;Lo;0;AL;<medial> 0642;;;;N;GLYPH FOR MEDIAL ARABIC QAF;;;;
+FED9;ARABIC LETTER KAF ISOLATED FORM;Lo;0;AL;<isolated> 0643;;;;N;GLYPH FOR ISOLATE ARABIC CAF;;;;
+FEDA;ARABIC LETTER KAF FINAL FORM;Lo;0;AL;<final> 0643;;;;N;GLYPH FOR FINAL ARABIC CAF;;;;
+FEDB;ARABIC LETTER KAF INITIAL FORM;Lo;0;AL;<initial> 0643;;;;N;GLYPH FOR INITIAL ARABIC CAF;;;;
+FEDC;ARABIC LETTER KAF MEDIAL FORM;Lo;0;AL;<medial> 0643;;;;N;GLYPH FOR MEDIAL ARABIC CAF;;;;
+FEDD;ARABIC LETTER LAM ISOLATED FORM;Lo;0;AL;<isolated> 0644;;;;N;GLYPH FOR ISOLATE ARABIC LAM;;;;
+FEDE;ARABIC LETTER LAM FINAL FORM;Lo;0;AL;<final> 0644;;;;N;GLYPH FOR FINAL ARABIC LAM;;;;
+FEDF;ARABIC LETTER LAM INITIAL FORM;Lo;0;AL;<initial> 0644;;;;N;GLYPH FOR INITIAL ARABIC LAM;;;;
+FEE0;ARABIC LETTER LAM MEDIAL FORM;Lo;0;AL;<medial> 0644;;;;N;GLYPH FOR MEDIAL ARABIC LAM;;;;
+FEE1;ARABIC LETTER MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0645;;;;N;GLYPH FOR ISOLATE ARABIC MEEM;;;;
+FEE2;ARABIC LETTER MEEM FINAL FORM;Lo;0;AL;<final> 0645;;;;N;GLYPH FOR FINAL ARABIC MEEM;;;;
+FEE3;ARABIC LETTER MEEM INITIAL FORM;Lo;0;AL;<initial> 0645;;;;N;GLYPH FOR INITIAL ARABIC MEEM;;;;
+FEE4;ARABIC LETTER MEEM MEDIAL FORM;Lo;0;AL;<medial> 0645;;;;N;GLYPH FOR MEDIAL ARABIC MEEM;;;;
+FEE5;ARABIC LETTER NOON ISOLATED FORM;Lo;0;AL;<isolated> 0646;;;;N;GLYPH FOR ISOLATE ARABIC NOON;;;;
+FEE6;ARABIC LETTER NOON FINAL FORM;Lo;0;AL;<final> 0646;;;;N;GLYPH FOR FINAL ARABIC NOON;;;;
+FEE7;ARABIC LETTER NOON INITIAL FORM;Lo;0;AL;<initial> 0646;;;;N;GLYPH FOR INITIAL ARABIC NOON;;;;
+FEE8;ARABIC LETTER NOON MEDIAL FORM;Lo;0;AL;<medial> 0646;;;;N;GLYPH FOR MEDIAL ARABIC NOON;;;;
+FEE9;ARABIC LETTER HEH ISOLATED FORM;Lo;0;AL;<isolated> 0647;;;;N;GLYPH FOR ISOLATE ARABIC HA;;;;
+FEEA;ARABIC LETTER HEH FINAL FORM;Lo;0;AL;<final> 0647;;;;N;GLYPH FOR FINAL ARABIC HA;;;;
+FEEB;ARABIC LETTER HEH INITIAL FORM;Lo;0;AL;<initial> 0647;;;;N;GLYPH FOR INITIAL ARABIC HA;;;;
+FEEC;ARABIC LETTER HEH MEDIAL FORM;Lo;0;AL;<medial> 0647;;;;N;GLYPH FOR MEDIAL ARABIC HA;;;;
+FEED;ARABIC LETTER WAW ISOLATED FORM;Lo;0;AL;<isolated> 0648;;;;N;GLYPH FOR ISOLATE ARABIC WAW;;;;
+FEEE;ARABIC LETTER WAW FINAL FORM;Lo;0;AL;<final> 0648;;;;N;GLYPH FOR FINAL ARABIC WAW;;;;
+FEEF;ARABIC LETTER ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0649;;;;N;GLYPH FOR ISOLATE ARABIC ALEF MAQSURAH;;;;
+FEF0;ARABIC LETTER ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0649;;;;N;GLYPH FOR FINAL ARABIC ALEF MAQSURAH;;;;
+FEF1;ARABIC LETTER YEH ISOLATED FORM;Lo;0;AL;<isolated> 064A;;;;N;GLYPH FOR ISOLATE ARABIC YA;;;;
+FEF2;ARABIC LETTER YEH FINAL FORM;Lo;0;AL;<final> 064A;;;;N;GLYPH FOR FINAL ARABIC YA;;;;
+FEF3;ARABIC LETTER YEH INITIAL FORM;Lo;0;AL;<initial> 064A;;;;N;GLYPH FOR INITIAL ARABIC YA;;;;
+FEF4;ARABIC LETTER YEH MEDIAL FORM;Lo;0;AL;<medial> 064A;;;;N;GLYPH FOR MEDIAL ARABIC YA;;;;
+FEF5;ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE ISOLATED FORM;Lo;0;AL;<isolated> 0644 0622;;;;N;GLYPH FOR ISOLATE ARABIC MADDAH ON LIGATURE LAM ALEF;;;;
+FEF6;ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE FINAL FORM;Lo;0;AL;<final> 0644 0622;;;;N;GLYPH FOR FINAL ARABIC MADDAH ON LIGATURE LAM ALEF;;;;
+FEF7;ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE ISOLATED FORM;Lo;0;AL;<isolated> 0644 0623;;;;N;GLYPH FOR ISOLATE ARABIC HAMZAH ON LIGATURE LAM ALEF;;;;
+FEF8;ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE FINAL FORM;Lo;0;AL;<final> 0644 0623;;;;N;GLYPH FOR FINAL ARABIC HAMZAH ON LIGATURE LAM ALEF;;;;
+FEF9;ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW ISOLATED FORM;Lo;0;AL;<isolated> 0644 0625;;;;N;GLYPH FOR ISOLATE ARABIC HAMZAH UNDER LIGATURE LAM ALEF;;;;
+FEFA;ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW FINAL FORM;Lo;0;AL;<final> 0644 0625;;;;N;GLYPH FOR FINAL ARABIC HAMZAH UNDER LIGATURE LAM ALEF;;;;
+FEFB;ARABIC LIGATURE LAM WITH ALEF ISOLATED FORM;Lo;0;AL;<isolated> 0644 0627;;;;N;GLYPH FOR ISOLATE ARABIC LIGATURE LAM ALEF;;;;
+FEFC;ARABIC LIGATURE LAM WITH ALEF FINAL FORM;Lo;0;AL;<final> 0644 0627;;;;N;GLYPH FOR FINAL ARABIC LIGATURE LAM ALEF;;;;
+FEFF;ZERO WIDTH NO-BREAK SPACE;Cf;0;BN;;;;;N;BYTE ORDER MARK;;;;
+FF01;FULLWIDTH EXCLAMATION MARK;Po;0;ON;<wide> 0021;;;;N;;;;;
+FF02;FULLWIDTH QUOTATION MARK;Po;0;ON;<wide> 0022;;;;N;;;;;
+FF03;FULLWIDTH NUMBER SIGN;Po;0;ET;<wide> 0023;;;;N;;;;;
+FF04;FULLWIDTH DOLLAR SIGN;Sc;0;ET;<wide> 0024;;;;N;;;;;
+FF05;FULLWIDTH PERCENT SIGN;Po;0;ET;<wide> 0025;;;;N;;;;;
+FF06;FULLWIDTH AMPERSAND;Po;0;ON;<wide> 0026;;;;N;;;;;
+FF07;FULLWIDTH APOSTROPHE;Po;0;ON;<wide> 0027;;;;N;;;;;
+FF08;FULLWIDTH LEFT PARENTHESIS;Ps;0;ON;<wide> 0028;;;;Y;FULLWIDTH OPENING PARENTHESIS;;;;
+FF09;FULLWIDTH RIGHT PARENTHESIS;Pe;0;ON;<wide> 0029;;;;Y;FULLWIDTH CLOSING PARENTHESIS;;;;
+FF0A;FULLWIDTH ASTERISK;Po;0;ON;<wide> 002A;;;;N;;;;;
+FF0B;FULLWIDTH PLUS SIGN;Sm;0;ES;<wide> 002B;;;;N;;;;;
+FF0C;FULLWIDTH COMMA;Po;0;CS;<wide> 002C;;;;N;;;;;
+FF0D;FULLWIDTH HYPHEN-MINUS;Pd;0;ES;<wide> 002D;;;;N;;;;;
+FF0E;FULLWIDTH FULL STOP;Po;0;CS;<wide> 002E;;;;N;FULLWIDTH PERIOD;;;;
+FF0F;FULLWIDTH SOLIDUS;Po;0;CS;<wide> 002F;;;;N;FULLWIDTH SLASH;;;;
+FF10;FULLWIDTH DIGIT ZERO;Nd;0;EN;<wide> 0030;0;0;0;N;;;;;
+FF11;FULLWIDTH DIGIT ONE;Nd;0;EN;<wide> 0031;1;1;1;N;;;;;
+FF12;FULLWIDTH DIGIT TWO;Nd;0;EN;<wide> 0032;2;2;2;N;;;;;
+FF13;FULLWIDTH DIGIT THREE;Nd;0;EN;<wide> 0033;3;3;3;N;;;;;
+FF14;FULLWIDTH DIGIT FOUR;Nd;0;EN;<wide> 0034;4;4;4;N;;;;;
+FF15;FULLWIDTH DIGIT FIVE;Nd;0;EN;<wide> 0035;5;5;5;N;;;;;
+FF16;FULLWIDTH DIGIT SIX;Nd;0;EN;<wide> 0036;6;6;6;N;;;;;
+FF17;FULLWIDTH DIGIT SEVEN;Nd;0;EN;<wide> 0037;7;7;7;N;;;;;
+FF18;FULLWIDTH DIGIT EIGHT;Nd;0;EN;<wide> 0038;8;8;8;N;;;;;
+FF19;FULLWIDTH DIGIT NINE;Nd;0;EN;<wide> 0039;9;9;9;N;;;;;
+FF1A;FULLWIDTH COLON;Po;0;CS;<wide> 003A;;;;N;;;;;
+FF1B;FULLWIDTH SEMICOLON;Po;0;ON;<wide> 003B;;;;N;;;;;
+FF1C;FULLWIDTH LESS-THAN SIGN;Sm;0;ON;<wide> 003C;;;;Y;;;;;
+FF1D;FULLWIDTH EQUALS SIGN;Sm;0;ON;<wide> 003D;;;;N;;;;;
+FF1E;FULLWIDTH GREATER-THAN SIGN;Sm;0;ON;<wide> 003E;;;;Y;;;;;
+FF1F;FULLWIDTH QUESTION MARK;Po;0;ON;<wide> 003F;;;;N;;;;;
+FF20;FULLWIDTH COMMERCIAL AT;Po;0;ON;<wide> 0040;;;;N;;;;;
+FF21;FULLWIDTH LATIN CAPITAL LETTER A;Lu;0;L;<wide> 0041;;;;N;;;;FF41;
+FF22;FULLWIDTH LATIN CAPITAL LETTER B;Lu;0;L;<wide> 0042;;;;N;;;;FF42;
+FF23;FULLWIDTH LATIN CAPITAL LETTER C;Lu;0;L;<wide> 0043;;;;N;;;;FF43;
+FF24;FULLWIDTH LATIN CAPITAL LETTER D;Lu;0;L;<wide> 0044;;;;N;;;;FF44;
+FF25;FULLWIDTH LATIN CAPITAL LETTER E;Lu;0;L;<wide> 0045;;;;N;;;;FF45;
+FF26;FULLWIDTH LATIN CAPITAL LETTER F;Lu;0;L;<wide> 0046;;;;N;;;;FF46;
+FF27;FULLWIDTH LATIN CAPITAL LETTER G;Lu;0;L;<wide> 0047;;;;N;;;;FF47;
+FF28;FULLWIDTH LATIN CAPITAL LETTER H;Lu;0;L;<wide> 0048;;;;N;;;;FF48;
+FF29;FULLWIDTH LATIN CAPITAL LETTER I;Lu;0;L;<wide> 0049;;;;N;;;;FF49;
+FF2A;FULLWIDTH LATIN CAPITAL LETTER J;Lu;0;L;<wide> 004A;;;;N;;;;FF4A;
+FF2B;FULLWIDTH LATIN CAPITAL LETTER K;Lu;0;L;<wide> 004B;;;;N;;;;FF4B;
+FF2C;FULLWIDTH LATIN CAPITAL LETTER L;Lu;0;L;<wide> 004C;;;;N;;;;FF4C;
+FF2D;FULLWIDTH LATIN CAPITAL LETTER M;Lu;0;L;<wide> 004D;;;;N;;;;FF4D;
+FF2E;FULLWIDTH LATIN CAPITAL LETTER N;Lu;0;L;<wide> 004E;;;;N;;;;FF4E;
+FF2F;FULLWIDTH LATIN CAPITAL LETTER O;Lu;0;L;<wide> 004F;;;;N;;;;FF4F;
+FF30;FULLWIDTH LATIN CAPITAL LETTER P;Lu;0;L;<wide> 0050;;;;N;;;;FF50;
+FF31;FULLWIDTH LATIN CAPITAL LETTER Q;Lu;0;L;<wide> 0051;;;;N;;;;FF51;
+FF32;FULLWIDTH LATIN CAPITAL LETTER R;Lu;0;L;<wide> 0052;;;;N;;;;FF52;
+FF33;FULLWIDTH LATIN CAPITAL LETTER S;Lu;0;L;<wide> 0053;;;;N;;;;FF53;
+FF34;FULLWIDTH LATIN CAPITAL LETTER T;Lu;0;L;<wide> 0054;;;;N;;;;FF54;
+FF35;FULLWIDTH LATIN CAPITAL LETTER U;Lu;0;L;<wide> 0055;;;;N;;;;FF55;
+FF36;FULLWIDTH LATIN CAPITAL LETTER V;Lu;0;L;<wide> 0056;;;;N;;;;FF56;
+FF37;FULLWIDTH LATIN CAPITAL LETTER W;Lu;0;L;<wide> 0057;;;;N;;;;FF57;
+FF38;FULLWIDTH LATIN CAPITAL LETTER X;Lu;0;L;<wide> 0058;;;;N;;;;FF58;
+FF39;FULLWIDTH LATIN CAPITAL LETTER Y;Lu;0;L;<wide> 0059;;;;N;;;;FF59;
+FF3A;FULLWIDTH LATIN CAPITAL LETTER Z;Lu;0;L;<wide> 005A;;;;N;;;;FF5A;
+FF3B;FULLWIDTH LEFT SQUARE BRACKET;Ps;0;ON;<wide> 005B;;;;Y;FULLWIDTH OPENING SQUARE BRACKET;;;;
+FF3C;FULLWIDTH REVERSE SOLIDUS;Po;0;ON;<wide> 005C;;;;N;FULLWIDTH BACKSLASH;;;;
+FF3D;FULLWIDTH RIGHT SQUARE BRACKET;Pe;0;ON;<wide> 005D;;;;Y;FULLWIDTH CLOSING SQUARE BRACKET;;;;
+FF3E;FULLWIDTH CIRCUMFLEX ACCENT;Sk;0;ON;<wide> 005E;;;;N;FULLWIDTH SPACING CIRCUMFLEX;;;;
+FF3F;FULLWIDTH LOW LINE;Pc;0;ON;<wide> 005F;;;;N;FULLWIDTH SPACING UNDERSCORE;;;;
+FF40;FULLWIDTH GRAVE ACCENT;Sk;0;ON;<wide> 0060;;;;N;FULLWIDTH SPACING GRAVE;;;;
+FF41;FULLWIDTH LATIN SMALL LETTER A;Ll;0;L;<wide> 0061;;;;N;;;FF21;;FF21
+FF42;FULLWIDTH LATIN SMALL LETTER B;Ll;0;L;<wide> 0062;;;;N;;;FF22;;FF22
+FF43;FULLWIDTH LATIN SMALL LETTER C;Ll;0;L;<wide> 0063;;;;N;;;FF23;;FF23
+FF44;FULLWIDTH LATIN SMALL LETTER D;Ll;0;L;<wide> 0064;;;;N;;;FF24;;FF24
+FF45;FULLWIDTH LATIN SMALL LETTER E;Ll;0;L;<wide> 0065;;;;N;;;FF25;;FF25
+FF46;FULLWIDTH LATIN SMALL LETTER F;Ll;0;L;<wide> 0066;;;;N;;;FF26;;FF26
+FF47;FULLWIDTH LATIN SMALL LETTER G;Ll;0;L;<wide> 0067;;;;N;;;FF27;;FF27
+FF48;FULLWIDTH LATIN SMALL LETTER H;Ll;0;L;<wide> 0068;;;;N;;;FF28;;FF28
+FF49;FULLWIDTH LATIN SMALL LETTER I;Ll;0;L;<wide> 0069;;;;N;;;FF29;;FF29
+FF4A;FULLWIDTH LATIN SMALL LETTER J;Ll;0;L;<wide> 006A;;;;N;;;FF2A;;FF2A
+FF4B;FULLWIDTH LATIN SMALL LETTER K;Ll;0;L;<wide> 006B;;;;N;;;FF2B;;FF2B
+FF4C;FULLWIDTH LATIN SMALL LETTER L;Ll;0;L;<wide> 006C;;;;N;;;FF2C;;FF2C
+FF4D;FULLWIDTH LATIN SMALL LETTER M;Ll;0;L;<wide> 006D;;;;N;;;FF2D;;FF2D
+FF4E;FULLWIDTH LATIN SMALL LETTER N;Ll;0;L;<wide> 006E;;;;N;;;FF2E;;FF2E
+FF4F;FULLWIDTH LATIN SMALL LETTER O;Ll;0;L;<wide> 006F;;;;N;;;FF2F;;FF2F
+FF50;FULLWIDTH LATIN SMALL LETTER P;Ll;0;L;<wide> 0070;;;;N;;;FF30;;FF30
+FF51;FULLWIDTH LATIN SMALL LETTER Q;Ll;0;L;<wide> 0071;;;;N;;;FF31;;FF31
+FF52;FULLWIDTH LATIN SMALL LETTER R;Ll;0;L;<wide> 0072;;;;N;;;FF32;;FF32
+FF53;FULLWIDTH LATIN SMALL LETTER S;Ll;0;L;<wide> 0073;;;;N;;;FF33;;FF33
+FF54;FULLWIDTH LATIN SMALL LETTER T;Ll;0;L;<wide> 0074;;;;N;;;FF34;;FF34
+FF55;FULLWIDTH LATIN SMALL LETTER U;Ll;0;L;<wide> 0075;;;;N;;;FF35;;FF35
+FF56;FULLWIDTH LATIN SMALL LETTER V;Ll;0;L;<wide> 0076;;;;N;;;FF36;;FF36
+FF57;FULLWIDTH LATIN SMALL LETTER W;Ll;0;L;<wide> 0077;;;;N;;;FF37;;FF37
+FF58;FULLWIDTH LATIN SMALL LETTER X;Ll;0;L;<wide> 0078;;;;N;;;FF38;;FF38
+FF59;FULLWIDTH LATIN SMALL LETTER Y;Ll;0;L;<wide> 0079;;;;N;;;FF39;;FF39
+FF5A;FULLWIDTH LATIN SMALL LETTER Z;Ll;0;L;<wide> 007A;;;;N;;;FF3A;;FF3A
+FF5B;FULLWIDTH LEFT CURLY BRACKET;Ps;0;ON;<wide> 007B;;;;Y;FULLWIDTH OPENING CURLY BRACKET;;;;
+FF5C;FULLWIDTH VERTICAL LINE;Sm;0;ON;<wide> 007C;;;;N;FULLWIDTH VERTICAL BAR;;;;
+FF5D;FULLWIDTH RIGHT CURLY BRACKET;Pe;0;ON;<wide> 007D;;;;Y;FULLWIDTH CLOSING CURLY BRACKET;;;;
+FF5E;FULLWIDTH TILDE;Sm;0;ON;<wide> 007E;;;;N;FULLWIDTH SPACING TILDE;;;;
+FF5F;FULLWIDTH LEFT WHITE PARENTHESIS;Ps;0;ON;<wide> 2985;;;;Y;;;;;
+FF60;FULLWIDTH RIGHT WHITE PARENTHESIS;Pe;0;ON;<wide> 2986;;;;Y;;;;;
+FF61;HALFWIDTH IDEOGRAPHIC FULL STOP;Po;0;ON;<narrow> 3002;;;;N;HALFWIDTH IDEOGRAPHIC PERIOD;;;;
+FF62;HALFWIDTH LEFT CORNER BRACKET;Ps;0;ON;<narrow> 300C;;;;Y;HALFWIDTH OPENING CORNER BRACKET;;;;
+FF63;HALFWIDTH RIGHT CORNER BRACKET;Pe;0;ON;<narrow> 300D;;;;Y;HALFWIDTH CLOSING CORNER BRACKET;;;;
+FF64;HALFWIDTH IDEOGRAPHIC COMMA;Po;0;ON;<narrow> 3001;;;;N;;;;;
+FF65;HALFWIDTH KATAKANA MIDDLE DOT;Po;0;ON;<narrow> 30FB;;;;N;;;;;
+FF66;HALFWIDTH KATAKANA LETTER WO;Lo;0;L;<narrow> 30F2;;;;N;;;;;
+FF67;HALFWIDTH KATAKANA LETTER SMALL A;Lo;0;L;<narrow> 30A1;;;;N;;;;;
+FF68;HALFWIDTH KATAKANA LETTER SMALL I;Lo;0;L;<narrow> 30A3;;;;N;;;;;
+FF69;HALFWIDTH KATAKANA LETTER SMALL U;Lo;0;L;<narrow> 30A5;;;;N;;;;;
+FF6A;HALFWIDTH KATAKANA LETTER SMALL E;Lo;0;L;<narrow> 30A7;;;;N;;;;;
+FF6B;HALFWIDTH KATAKANA LETTER SMALL O;Lo;0;L;<narrow> 30A9;;;;N;;;;;
+FF6C;HALFWIDTH KATAKANA LETTER SMALL YA;Lo;0;L;<narrow> 30E3;;;;N;;;;;
+FF6D;HALFWIDTH KATAKANA LETTER SMALL YU;Lo;0;L;<narrow> 30E5;;;;N;;;;;
+FF6E;HALFWIDTH KATAKANA LETTER SMALL YO;Lo;0;L;<narrow> 30E7;;;;N;;;;;
+FF6F;HALFWIDTH KATAKANA LETTER SMALL TU;Lo;0;L;<narrow> 30C3;;;;N;;;;;
+FF70;HALFWIDTH KATAKANA-HIRAGANA PROLONGED SOUND MARK;Lm;0;L;<narrow> 30FC;;;;N;;;;;
+FF71;HALFWIDTH KATAKANA LETTER A;Lo;0;L;<narrow> 30A2;;;;N;;;;;
+FF72;HALFWIDTH KATAKANA LETTER I;Lo;0;L;<narrow> 30A4;;;;N;;;;;
+FF73;HALFWIDTH KATAKANA LETTER U;Lo;0;L;<narrow> 30A6;;;;N;;;;;
+FF74;HALFWIDTH KATAKANA LETTER E;Lo;0;L;<narrow> 30A8;;;;N;;;;;
+FF75;HALFWIDTH KATAKANA LETTER O;Lo;0;L;<narrow> 30AA;;;;N;;;;;
+FF76;HALFWIDTH KATAKANA LETTER KA;Lo;0;L;<narrow> 30AB;;;;N;;;;;
+FF77;HALFWIDTH KATAKANA LETTER KI;Lo;0;L;<narrow> 30AD;;;;N;;;;;
+FF78;HALFWIDTH KATAKANA LETTER KU;Lo;0;L;<narrow> 30AF;;;;N;;;;;
+FF79;HALFWIDTH KATAKANA LETTER KE;Lo;0;L;<narrow> 30B1;;;;N;;;;;
+FF7A;HALFWIDTH KATAKANA LETTER KO;Lo;0;L;<narrow> 30B3;;;;N;;;;;
+FF7B;HALFWIDTH KATAKANA LETTER SA;Lo;0;L;<narrow> 30B5;;;;N;;;;;
+FF7C;HALFWIDTH KATAKANA LETTER SI;Lo;0;L;<narrow> 30B7;;;;N;;;;;
+FF7D;HALFWIDTH KATAKANA LETTER SU;Lo;0;L;<narrow> 30B9;;;;N;;;;;
+FF7E;HALFWIDTH KATAKANA LETTER SE;Lo;0;L;<narrow> 30BB;;;;N;;;;;
+FF7F;HALFWIDTH KATAKANA LETTER SO;Lo;0;L;<narrow> 30BD;;;;N;;;;;
+FF80;HALFWIDTH KATAKANA LETTER TA;Lo;0;L;<narrow> 30BF;;;;N;;;;;
+FF81;HALFWIDTH KATAKANA LETTER TI;Lo;0;L;<narrow> 30C1;;;;N;;;;;
+FF82;HALFWIDTH KATAKANA LETTER TU;Lo;0;L;<narrow> 30C4;;;;N;;;;;
+FF83;HALFWIDTH KATAKANA LETTER TE;Lo;0;L;<narrow> 30C6;;;;N;;;;;
+FF84;HALFWIDTH KATAKANA LETTER TO;Lo;0;L;<narrow> 30C8;;;;N;;;;;
+FF85;HALFWIDTH KATAKANA LETTER NA;Lo;0;L;<narrow> 30CA;;;;N;;;;;
+FF86;HALFWIDTH KATAKANA LETTER NI;Lo;0;L;<narrow> 30CB;;;;N;;;;;
+FF87;HALFWIDTH KATAKANA LETTER NU;Lo;0;L;<narrow> 30CC;;;;N;;;;;
+FF88;HALFWIDTH KATAKANA LETTER NE;Lo;0;L;<narrow> 30CD;;;;N;;;;;
+FF89;HALFWIDTH KATAKANA LETTER NO;Lo;0;L;<narrow> 30CE;;;;N;;;;;
+FF8A;HALFWIDTH KATAKANA LETTER HA;Lo;0;L;<narrow> 30CF;;;;N;;;;;
+FF8B;HALFWIDTH KATAKANA LETTER HI;Lo;0;L;<narrow> 30D2;;;;N;;;;;
+FF8C;HALFWIDTH KATAKANA LETTER HU;Lo;0;L;<narrow> 30D5;;;;N;;;;;
+FF8D;HALFWIDTH KATAKANA LETTER HE;Lo;0;L;<narrow> 30D8;;;;N;;;;;
+FF8E;HALFWIDTH KATAKANA LETTER HO;Lo;0;L;<narrow> 30DB;;;;N;;;;;
+FF8F;HALFWIDTH KATAKANA LETTER MA;Lo;0;L;<narrow> 30DE;;;;N;;;;;
+FF90;HALFWIDTH KATAKANA LETTER MI;Lo;0;L;<narrow> 30DF;;;;N;;;;;
+FF91;HALFWIDTH KATAKANA LETTER MU;Lo;0;L;<narrow> 30E0;;;;N;;;;;
+FF92;HALFWIDTH KATAKANA LETTER ME;Lo;0;L;<narrow> 30E1;;;;N;;;;;
+FF93;HALFWIDTH KATAKANA LETTER MO;Lo;0;L;<narrow> 30E2;;;;N;;;;;
+FF94;HALFWIDTH KATAKANA LETTER YA;Lo;0;L;<narrow> 30E4;;;;N;;;;;
+FF95;HALFWIDTH KATAKANA LETTER YU;Lo;0;L;<narrow> 30E6;;;;N;;;;;
+FF96;HALFWIDTH KATAKANA LETTER YO;Lo;0;L;<narrow> 30E8;;;;N;;;;;
+FF97;HALFWIDTH KATAKANA LETTER RA;Lo;0;L;<narrow> 30E9;;;;N;;;;;
+FF98;HALFWIDTH KATAKANA LETTER RI;Lo;0;L;<narrow> 30EA;;;;N;;;;;
+FF99;HALFWIDTH KATAKANA LETTER RU;Lo;0;L;<narrow> 30EB;;;;N;;;;;
+FF9A;HALFWIDTH KATAKANA LETTER RE;Lo;0;L;<narrow> 30EC;;;;N;;;;;
+FF9B;HALFWIDTH KATAKANA LETTER RO;Lo;0;L;<narrow> 30ED;;;;N;;;;;
+FF9C;HALFWIDTH KATAKANA LETTER WA;Lo;0;L;<narrow> 30EF;;;;N;;;;;
+FF9D;HALFWIDTH KATAKANA LETTER N;Lo;0;L;<narrow> 30F3;;;;N;;;;;
+FF9E;HALFWIDTH KATAKANA VOICED SOUND MARK;Lm;0;L;<narrow> 3099;;;;N;;;;;
+FF9F;HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK;Lm;0;L;<narrow> 309A;;;;N;;;;;
+FFA0;HALFWIDTH HANGUL FILLER;Lo;0;L;<narrow> 3164;;;;N;HALFWIDTH HANGUL CAE OM;;;;
+FFA1;HALFWIDTH HANGUL LETTER KIYEOK;Lo;0;L;<narrow> 3131;;;;N;HALFWIDTH HANGUL LETTER GIYEOG;;;;
+FFA2;HALFWIDTH HANGUL LETTER SSANGKIYEOK;Lo;0;L;<narrow> 3132;;;;N;HALFWIDTH HANGUL LETTER SSANG GIYEOG;;;;
+FFA3;HALFWIDTH HANGUL LETTER KIYEOK-SIOS;Lo;0;L;<narrow> 3133;;;;N;HALFWIDTH HANGUL LETTER GIYEOG SIOS;;;;
+FFA4;HALFWIDTH HANGUL LETTER NIEUN;Lo;0;L;<narrow> 3134;;;;N;;;;;
+FFA5;HALFWIDTH HANGUL LETTER NIEUN-CIEUC;Lo;0;L;<narrow> 3135;;;;N;HALFWIDTH HANGUL LETTER NIEUN JIEUJ;;;;
+FFA6;HALFWIDTH HANGUL LETTER NIEUN-HIEUH;Lo;0;L;<narrow> 3136;;;;N;HALFWIDTH HANGUL LETTER NIEUN HIEUH;;;;
+FFA7;HALFWIDTH HANGUL LETTER TIKEUT;Lo;0;L;<narrow> 3137;;;;N;HALFWIDTH HANGUL LETTER DIGEUD;;;;
+FFA8;HALFWIDTH HANGUL LETTER SSANGTIKEUT;Lo;0;L;<narrow> 3138;;;;N;HALFWIDTH HANGUL LETTER SSANG DIGEUD;;;;
+FFA9;HALFWIDTH HANGUL LETTER RIEUL;Lo;0;L;<narrow> 3139;;;;N;HALFWIDTH HANGUL LETTER LIEUL;;;;
+FFAA;HALFWIDTH HANGUL LETTER RIEUL-KIYEOK;Lo;0;L;<narrow> 313A;;;;N;HALFWIDTH HANGUL LETTER LIEUL GIYEOG;;;;
+FFAB;HALFWIDTH HANGUL LETTER RIEUL-MIEUM;Lo;0;L;<narrow> 313B;;;;N;HALFWIDTH HANGUL LETTER LIEUL MIEUM;;;;
+FFAC;HALFWIDTH HANGUL LETTER RIEUL-PIEUP;Lo;0;L;<narrow> 313C;;;;N;HALFWIDTH HANGUL LETTER LIEUL BIEUB;;;;
+FFAD;HALFWIDTH HANGUL LETTER RIEUL-SIOS;Lo;0;L;<narrow> 313D;;;;N;HALFWIDTH HANGUL LETTER LIEUL SIOS;;;;
+FFAE;HALFWIDTH HANGUL LETTER RIEUL-THIEUTH;Lo;0;L;<narrow> 313E;;;;N;HALFWIDTH HANGUL LETTER LIEUL TIEUT;;;;
+FFAF;HALFWIDTH HANGUL LETTER RIEUL-PHIEUPH;Lo;0;L;<narrow> 313F;;;;N;HALFWIDTH HANGUL LETTER LIEUL PIEUP;;;;
+FFB0;HALFWIDTH HANGUL LETTER RIEUL-HIEUH;Lo;0;L;<narrow> 3140;;;;N;HALFWIDTH HANGUL LETTER LIEUL HIEUH;;;;
+FFB1;HALFWIDTH HANGUL LETTER MIEUM;Lo;0;L;<narrow> 3141;;;;N;;;;;
+FFB2;HALFWIDTH HANGUL LETTER PIEUP;Lo;0;L;<narrow> 3142;;;;N;HALFWIDTH HANGUL LETTER BIEUB;;;;
+FFB3;HALFWIDTH HANGUL LETTER SSANGPIEUP;Lo;0;L;<narrow> 3143;;;;N;HALFWIDTH HANGUL LETTER SSANG BIEUB;;;;
+FFB4;HALFWIDTH HANGUL LETTER PIEUP-SIOS;Lo;0;L;<narrow> 3144;;;;N;HALFWIDTH HANGUL LETTER BIEUB SIOS;;;;
+FFB5;HALFWIDTH HANGUL LETTER SIOS;Lo;0;L;<narrow> 3145;;;;N;;;;;
+FFB6;HALFWIDTH HANGUL LETTER SSANGSIOS;Lo;0;L;<narrow> 3146;;;;N;HALFWIDTH HANGUL LETTER SSANG SIOS;;;;
+FFB7;HALFWIDTH HANGUL LETTER IEUNG;Lo;0;L;<narrow> 3147;;;;N;;;;;
+FFB8;HALFWIDTH HANGUL LETTER CIEUC;Lo;0;L;<narrow> 3148;;;;N;HALFWIDTH HANGUL LETTER JIEUJ;;;;
+FFB9;HALFWIDTH HANGUL LETTER SSANGCIEUC;Lo;0;L;<narrow> 3149;;;;N;HALFWIDTH HANGUL LETTER SSANG JIEUJ;;;;
+FFBA;HALFWIDTH HANGUL LETTER CHIEUCH;Lo;0;L;<narrow> 314A;;;;N;HALFWIDTH HANGUL LETTER CIEUC;;;;
+FFBB;HALFWIDTH HANGUL LETTER KHIEUKH;Lo;0;L;<narrow> 314B;;;;N;HALFWIDTH HANGUL LETTER KIYEOK;;;;
+FFBC;HALFWIDTH HANGUL LETTER THIEUTH;Lo;0;L;<narrow> 314C;;;;N;HALFWIDTH HANGUL LETTER TIEUT;;;;
+FFBD;HALFWIDTH HANGUL LETTER PHIEUPH;Lo;0;L;<narrow> 314D;;;;N;HALFWIDTH HANGUL LETTER PIEUP;;;;
+FFBE;HALFWIDTH HANGUL LETTER HIEUH;Lo;0;L;<narrow> 314E;;;;N;;;;;
+FFC2;HALFWIDTH HANGUL LETTER A;Lo;0;L;<narrow> 314F;;;;N;;;;;
+FFC3;HALFWIDTH HANGUL LETTER AE;Lo;0;L;<narrow> 3150;;;;N;;;;;
+FFC4;HALFWIDTH HANGUL LETTER YA;Lo;0;L;<narrow> 3151;;;;N;;;;;
+FFC5;HALFWIDTH HANGUL LETTER YAE;Lo;0;L;<narrow> 3152;;;;N;;;;;
+FFC6;HALFWIDTH HANGUL LETTER EO;Lo;0;L;<narrow> 3153;;;;N;;;;;
+FFC7;HALFWIDTH HANGUL LETTER E;Lo;0;L;<narrow> 3154;;;;N;;;;;
+FFCA;HALFWIDTH HANGUL LETTER YEO;Lo;0;L;<narrow> 3155;;;;N;;;;;
+FFCB;HALFWIDTH HANGUL LETTER YE;Lo;0;L;<narrow> 3156;;;;N;;;;;
+FFCC;HALFWIDTH HANGUL LETTER O;Lo;0;L;<narrow> 3157;;;;N;;;;;
+FFCD;HALFWIDTH HANGUL LETTER WA;Lo;0;L;<narrow> 3158;;;;N;;;;;
+FFCE;HALFWIDTH HANGUL LETTER WAE;Lo;0;L;<narrow> 3159;;;;N;;;;;
+FFCF;HALFWIDTH HANGUL LETTER OE;Lo;0;L;<narrow> 315A;;;;N;;;;;
+FFD2;HALFWIDTH HANGUL LETTER YO;Lo;0;L;<narrow> 315B;;;;N;;;;;
+FFD3;HALFWIDTH HANGUL LETTER U;Lo;0;L;<narrow> 315C;;;;N;;;;;
+FFD4;HALFWIDTH HANGUL LETTER WEO;Lo;0;L;<narrow> 315D;;;;N;;;;;
+FFD5;HALFWIDTH HANGUL LETTER WE;Lo;0;L;<narrow> 315E;;;;N;;;;;
+FFD6;HALFWIDTH HANGUL LETTER WI;Lo;0;L;<narrow> 315F;;;;N;;;;;
+FFD7;HALFWIDTH HANGUL LETTER YU;Lo;0;L;<narrow> 3160;;;;N;;;;;
+FFDA;HALFWIDTH HANGUL LETTER EU;Lo;0;L;<narrow> 3161;;;;N;;;;;
+FFDB;HALFWIDTH HANGUL LETTER YI;Lo;0;L;<narrow> 3162;;;;N;;;;;
+FFDC;HALFWIDTH HANGUL LETTER I;Lo;0;L;<narrow> 3163;;;;N;;;;;
+FFE0;FULLWIDTH CENT SIGN;Sc;0;ET;<wide> 00A2;;;;N;;;;;
+FFE1;FULLWIDTH POUND SIGN;Sc;0;ET;<wide> 00A3;;;;N;;;;;
+FFE2;FULLWIDTH NOT SIGN;Sm;0;ON;<wide> 00AC;;;;N;;;;;
+FFE3;FULLWIDTH MACRON;Sk;0;ON;<wide> 00AF;;;;N;FULLWIDTH SPACING MACRON;;;;
+FFE4;FULLWIDTH BROKEN BAR;So;0;ON;<wide> 00A6;;;;N;FULLWIDTH BROKEN VERTICAL BAR;;;;
+FFE5;FULLWIDTH YEN SIGN;Sc;0;ET;<wide> 00A5;;;;N;;;;;
+FFE6;FULLWIDTH WON SIGN;Sc;0;ET;<wide> 20A9;;;;N;;;;;
+FFE8;HALFWIDTH FORMS LIGHT VERTICAL;So;0;ON;<narrow> 2502;;;;N;;;;;
+FFE9;HALFWIDTH LEFTWARDS ARROW;Sm;0;ON;<narrow> 2190;;;;N;;;;;
+FFEA;HALFWIDTH UPWARDS ARROW;Sm;0;ON;<narrow> 2191;;;;N;;;;;
+FFEB;HALFWIDTH RIGHTWARDS ARROW;Sm;0;ON;<narrow> 2192;;;;N;;;;;
+FFEC;HALFWIDTH DOWNWARDS ARROW;Sm;0;ON;<narrow> 2193;;;;N;;;;;
+FFED;HALFWIDTH BLACK SQUARE;So;0;ON;<narrow> 25A0;;;;N;;;;;
+FFEE;HALFWIDTH WHITE CIRCLE;So;0;ON;<narrow> 25CB;;;;N;;;;;
+FFF9;INTERLINEAR ANNOTATION ANCHOR;Cf;0;ON;;;;;N;;;;;
+FFFA;INTERLINEAR ANNOTATION SEPARATOR;Cf;0;ON;;;;;N;;;;;
+FFFB;INTERLINEAR ANNOTATION TERMINATOR;Cf;0;ON;;;;;N;;;;;
+FFFC;OBJECT REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
+FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
+10000;LINEAR B SYLLABLE B008 A;Lo;0;L;;;;;N;;;;;
+10001;LINEAR B SYLLABLE B038 E;Lo;0;L;;;;;N;;;;;
+10002;LINEAR B SYLLABLE B028 I;Lo;0;L;;;;;N;;;;;
+10003;LINEAR B SYLLABLE B061 O;Lo;0;L;;;;;N;;;;;
+10004;LINEAR B SYLLABLE B010 U;Lo;0;L;;;;;N;;;;;
+10005;LINEAR B SYLLABLE B001 DA;Lo;0;L;;;;;N;;;;;
+10006;LINEAR B SYLLABLE B045 DE;Lo;0;L;;;;;N;;;;;
+10007;LINEAR B SYLLABLE B007 DI;Lo;0;L;;;;;N;;;;;
+10008;LINEAR B SYLLABLE B014 DO;Lo;0;L;;;;;N;;;;;
+10009;LINEAR B SYLLABLE B051 DU;Lo;0;L;;;;;N;;;;;
+1000A;LINEAR B SYLLABLE B057 JA;Lo;0;L;;;;;N;;;;;
+1000B;LINEAR B SYLLABLE B046 JE;Lo;0;L;;;;;N;;;;;
+1000D;LINEAR B SYLLABLE B036 JO;Lo;0;L;;;;;N;;;;;
+1000E;LINEAR B SYLLABLE B065 JU;Lo;0;L;;;;;N;;;;;
+1000F;LINEAR B SYLLABLE B077 KA;Lo;0;L;;;;;N;;;;;
+10010;LINEAR B SYLLABLE B044 KE;Lo;0;L;;;;;N;;;;;
+10011;LINEAR B SYLLABLE B067 KI;Lo;0;L;;;;;N;;;;;
+10012;LINEAR B SYLLABLE B070 KO;Lo;0;L;;;;;N;;;;;
+10013;LINEAR B SYLLABLE B081 KU;Lo;0;L;;;;;N;;;;;
+10014;LINEAR B SYLLABLE B080 MA;Lo;0;L;;;;;N;;;;;
+10015;LINEAR B SYLLABLE B013 ME;Lo;0;L;;;;;N;;;;;
+10016;LINEAR B SYLLABLE B073 MI;Lo;0;L;;;;;N;;;;;
+10017;LINEAR B SYLLABLE B015 MO;Lo;0;L;;;;;N;;;;;
+10018;LINEAR B SYLLABLE B023 MU;Lo;0;L;;;;;N;;;;;
+10019;LINEAR B SYLLABLE B006 NA;Lo;0;L;;;;;N;;;;;
+1001A;LINEAR B SYLLABLE B024 NE;Lo;0;L;;;;;N;;;;;
+1001B;LINEAR B SYLLABLE B030 NI;Lo;0;L;;;;;N;;;;;
+1001C;LINEAR B SYLLABLE B052 NO;Lo;0;L;;;;;N;;;;;
+1001D;LINEAR B SYLLABLE B055 NU;Lo;0;L;;;;;N;;;;;
+1001E;LINEAR B SYLLABLE B003 PA;Lo;0;L;;;;;N;;;;;
+1001F;LINEAR B SYLLABLE B072 PE;Lo;0;L;;;;;N;;;;;
+10020;LINEAR B SYLLABLE B039 PI;Lo;0;L;;;;;N;;;;;
+10021;LINEAR B SYLLABLE B011 PO;Lo;0;L;;;;;N;;;;;
+10022;LINEAR B SYLLABLE B050 PU;Lo;0;L;;;;;N;;;;;
+10023;LINEAR B SYLLABLE B016 QA;Lo;0;L;;;;;N;;;;;
+10024;LINEAR B SYLLABLE B078 QE;Lo;0;L;;;;;N;;;;;
+10025;LINEAR B SYLLABLE B021 QI;Lo;0;L;;;;;N;;;;;
+10026;LINEAR B SYLLABLE B032 QO;Lo;0;L;;;;;N;;;;;
+10028;LINEAR B SYLLABLE B060 RA;Lo;0;L;;;;;N;;;;;
+10029;LINEAR B SYLLABLE B027 RE;Lo;0;L;;;;;N;;;;;
+1002A;LINEAR B SYLLABLE B053 RI;Lo;0;L;;;;;N;;;;;
+1002B;LINEAR B SYLLABLE B002 RO;Lo;0;L;;;;;N;;;;;
+1002C;LINEAR B SYLLABLE B026 RU;Lo;0;L;;;;;N;;;;;
+1002D;LINEAR B SYLLABLE B031 SA;Lo;0;L;;;;;N;;;;;
+1002E;LINEAR B SYLLABLE B009 SE;Lo;0;L;;;;;N;;;;;
+1002F;LINEAR B SYLLABLE B041 SI;Lo;0;L;;;;;N;;;;;
+10030;LINEAR B SYLLABLE B012 SO;Lo;0;L;;;;;N;;;;;
+10031;LINEAR B SYLLABLE B058 SU;Lo;0;L;;;;;N;;;;;
+10032;LINEAR B SYLLABLE B059 TA;Lo;0;L;;;;;N;;;;;
+10033;LINEAR B SYLLABLE B004 TE;Lo;0;L;;;;;N;;;;;
+10034;LINEAR B SYLLABLE B037 TI;Lo;0;L;;;;;N;;;;;
+10035;LINEAR B SYLLABLE B005 TO;Lo;0;L;;;;;N;;;;;
+10036;LINEAR B SYLLABLE B069 TU;Lo;0;L;;;;;N;;;;;
+10037;LINEAR B SYLLABLE B054 WA;Lo;0;L;;;;;N;;;;;
+10038;LINEAR B SYLLABLE B075 WE;Lo;0;L;;;;;N;;;;;
+10039;LINEAR B SYLLABLE B040 WI;Lo;0;L;;;;;N;;;;;
+1003A;LINEAR B SYLLABLE B042 WO;Lo;0;L;;;;;N;;;;;
+1003C;LINEAR B SYLLABLE B017 ZA;Lo;0;L;;;;;N;;;;;
+1003D;LINEAR B SYLLABLE B074 ZE;Lo;0;L;;;;;N;;;;;
+1003F;LINEAR B SYLLABLE B020 ZO;Lo;0;L;;;;;N;;;;;
+10040;LINEAR B SYLLABLE B025 A2;Lo;0;L;;;;;N;;;;;
+10041;LINEAR B SYLLABLE B043 A3;Lo;0;L;;;;;N;;;;;
+10042;LINEAR B SYLLABLE B085 AU;Lo;0;L;;;;;N;;;;;
+10043;LINEAR B SYLLABLE B071 DWE;Lo;0;L;;;;;N;;;;;
+10044;LINEAR B SYLLABLE B090 DWO;Lo;0;L;;;;;N;;;;;
+10045;LINEAR B SYLLABLE B048 NWA;Lo;0;L;;;;;N;;;;;
+10046;LINEAR B SYLLABLE B029 PU2;Lo;0;L;;;;;N;;;;;
+10047;LINEAR B SYLLABLE B062 PTE;Lo;0;L;;;;;N;;;;;
+10048;LINEAR B SYLLABLE B076 RA2;Lo;0;L;;;;;N;;;;;
+10049;LINEAR B SYLLABLE B033 RA3;Lo;0;L;;;;;N;;;;;
+1004A;LINEAR B SYLLABLE B068 RO2;Lo;0;L;;;;;N;;;;;
+1004B;LINEAR B SYLLABLE B066 TA2;Lo;0;L;;;;;N;;;;;
+1004C;LINEAR B SYLLABLE B087 TWE;Lo;0;L;;;;;N;;;;;
+1004D;LINEAR B SYLLABLE B091 TWO;Lo;0;L;;;;;N;;;;;
+10050;LINEAR B SYMBOL B018;Lo;0;L;;;;;N;;;;;
+10051;LINEAR B SYMBOL B019;Lo;0;L;;;;;N;;;;;
+10052;LINEAR B SYMBOL B022;Lo;0;L;;;;;N;;;;;
+10053;LINEAR B SYMBOL B034;Lo;0;L;;;;;N;;;;;
+10054;LINEAR B SYMBOL B047;Lo;0;L;;;;;N;;;;;
+10055;LINEAR B SYMBOL B049;Lo;0;L;;;;;N;;;;;
+10056;LINEAR B SYMBOL B056;Lo;0;L;;;;;N;;;;;
+10057;LINEAR B SYMBOL B063;Lo;0;L;;;;;N;;;;;
+10058;LINEAR B SYMBOL B064;Lo;0;L;;;;;N;;;;;
+10059;LINEAR B SYMBOL B079;Lo;0;L;;;;;N;;;;;
+1005A;LINEAR B SYMBOL B082;Lo;0;L;;;;;N;;;;;
+1005B;LINEAR B SYMBOL B083;Lo;0;L;;;;;N;;;;;
+1005C;LINEAR B SYMBOL B086;Lo;0;L;;;;;N;;;;;
+1005D;LINEAR B SYMBOL B089;Lo;0;L;;;;;N;;;;;
+10080;LINEAR B IDEOGRAM B100 MAN;Lo;0;L;;;;;N;;;;;
+10081;LINEAR B IDEOGRAM B102 WOMAN;Lo;0;L;;;;;N;;;;;
+10082;LINEAR B IDEOGRAM B104 DEER;Lo;0;L;;;;;N;;;;;
+10083;LINEAR B IDEOGRAM B105 EQUID;Lo;0;L;;;;;N;;;;;
+10084;LINEAR B IDEOGRAM B105F MARE;Lo;0;L;;;;;N;;;;;
+10085;LINEAR B IDEOGRAM B105M STALLION;Lo;0;L;;;;;N;;;;;
+10086;LINEAR B IDEOGRAM B106F EWE;Lo;0;L;;;;;N;;;;;
+10087;LINEAR B IDEOGRAM B106M RAM;Lo;0;L;;;;;N;;;;;
+10088;LINEAR B IDEOGRAM B107F SHE-GOAT;Lo;0;L;;;;;N;;;;;
+10089;LINEAR B IDEOGRAM B107M HE-GOAT;Lo;0;L;;;;;N;;;;;
+1008A;LINEAR B IDEOGRAM B108F SOW;Lo;0;L;;;;;N;;;;;
+1008B;LINEAR B IDEOGRAM B108M BOAR;Lo;0;L;;;;;N;;;;;
+1008C;LINEAR B IDEOGRAM B109F COW;Lo;0;L;;;;;N;;;;;
+1008D;LINEAR B IDEOGRAM B109M BULL;Lo;0;L;;;;;N;;;;;
+1008E;LINEAR B IDEOGRAM B120 WHEAT;Lo;0;L;;;;;N;;;;;
+1008F;LINEAR B IDEOGRAM B121 BARLEY;Lo;0;L;;;;;N;;;;;
+10090;LINEAR B IDEOGRAM B122 OLIVE;Lo;0;L;;;;;N;;;;;
+10091;LINEAR B IDEOGRAM B123 SPICE;Lo;0;L;;;;;N;;;;;
+10092;LINEAR B IDEOGRAM B125 CYPERUS;Lo;0;L;;;;;N;;;;;
+10093;LINEAR B MONOGRAM B127 KAPO;Lo;0;L;;;;;N;;;;;
+10094;LINEAR B MONOGRAM B128 KANAKO;Lo;0;L;;;;;N;;;;;
+10095;LINEAR B IDEOGRAM B130 OIL;Lo;0;L;;;;;N;;;;;
+10096;LINEAR B IDEOGRAM B131 WINE;Lo;0;L;;;;;N;;;;;
+10097;LINEAR B IDEOGRAM B132;Lo;0;L;;;;;N;;;;;
+10098;LINEAR B MONOGRAM B133 AREPA;Lo;0;L;;;;;N;;;;;
+10099;LINEAR B MONOGRAM B135 MERI;Lo;0;L;;;;;N;;;;;
+1009A;LINEAR B IDEOGRAM B140 BRONZE;Lo;0;L;;;;;N;;;;;
+1009B;LINEAR B IDEOGRAM B141 GOLD;Lo;0;L;;;;;N;;;;;
+1009C;LINEAR B IDEOGRAM B142;Lo;0;L;;;;;N;;;;;
+1009D;LINEAR B IDEOGRAM B145 WOOL;Lo;0;L;;;;;N;;;;;
+1009E;LINEAR B IDEOGRAM B146;Lo;0;L;;;;;N;;;;;
+1009F;LINEAR B IDEOGRAM B150;Lo;0;L;;;;;N;;;;;
+100A0;LINEAR B IDEOGRAM B151 HORN;Lo;0;L;;;;;N;;;;;
+100A1;LINEAR B IDEOGRAM B152;Lo;0;L;;;;;N;;;;;
+100A2;LINEAR B IDEOGRAM B153;Lo;0;L;;;;;N;;;;;
+100A3;LINEAR B IDEOGRAM B154;Lo;0;L;;;;;N;;;;;
+100A4;LINEAR B MONOGRAM B156 TURO2;Lo;0;L;;;;;N;;;;;
+100A5;LINEAR B IDEOGRAM B157;Lo;0;L;;;;;N;;;;;
+100A6;LINEAR B IDEOGRAM B158;Lo;0;L;;;;;N;;;;;
+100A7;LINEAR B IDEOGRAM B159 CLOTH;Lo;0;L;;;;;N;;;;;
+100A8;LINEAR B IDEOGRAM B160;Lo;0;L;;;;;N;;;;;
+100A9;LINEAR B IDEOGRAM B161;Lo;0;L;;;;;N;;;;;
+100AA;LINEAR B IDEOGRAM B162 GARMENT;Lo;0;L;;;;;N;;;;;
+100AB;LINEAR B IDEOGRAM B163 ARMOUR;Lo;0;L;;;;;N;;;;;
+100AC;LINEAR B IDEOGRAM B164;Lo;0;L;;;;;N;;;;;
+100AD;LINEAR B IDEOGRAM B165;Lo;0;L;;;;;N;;;;;
+100AE;LINEAR B IDEOGRAM B166;Lo;0;L;;;;;N;;;;;
+100AF;LINEAR B IDEOGRAM B167;Lo;0;L;;;;;N;;;;;
+100B0;LINEAR B IDEOGRAM B168;Lo;0;L;;;;;N;;;;;
+100B1;LINEAR B IDEOGRAM B169;Lo;0;L;;;;;N;;;;;
+100B2;LINEAR B IDEOGRAM B170;Lo;0;L;;;;;N;;;;;
+100B3;LINEAR B IDEOGRAM B171;Lo;0;L;;;;;N;;;;;
+100B4;LINEAR B IDEOGRAM B172;Lo;0;L;;;;;N;;;;;
+100B5;LINEAR B IDEOGRAM B173 MONTH;Lo;0;L;;;;;N;;;;;
+100B6;LINEAR B IDEOGRAM B174;Lo;0;L;;;;;N;;;;;
+100B7;LINEAR B IDEOGRAM B176 TREE;Lo;0;L;;;;;N;;;;;
+100B8;LINEAR B IDEOGRAM B177;Lo;0;L;;;;;N;;;;;
+100B9;LINEAR B IDEOGRAM B178;Lo;0;L;;;;;N;;;;;
+100BA;LINEAR B IDEOGRAM B179;Lo;0;L;;;;;N;;;;;
+100BB;LINEAR B IDEOGRAM B180;Lo;0;L;;;;;N;;;;;
+100BC;LINEAR B IDEOGRAM B181;Lo;0;L;;;;;N;;;;;
+100BD;LINEAR B IDEOGRAM B182;Lo;0;L;;;;;N;;;;;
+100BE;LINEAR B IDEOGRAM B183;Lo;0;L;;;;;N;;;;;
+100BF;LINEAR B IDEOGRAM B184;Lo;0;L;;;;;N;;;;;
+100C0;LINEAR B IDEOGRAM B185;Lo;0;L;;;;;N;;;;;
+100C1;LINEAR B IDEOGRAM B189;Lo;0;L;;;;;N;;;;;
+100C2;LINEAR B IDEOGRAM B190;Lo;0;L;;;;;N;;;;;
+100C3;LINEAR B IDEOGRAM B191 HELMET;Lo;0;L;;;;;N;;;;;
+100C4;LINEAR B IDEOGRAM B220 FOOTSTOOL;Lo;0;L;;;;;N;;;;;
+100C5;LINEAR B IDEOGRAM B225 BATHTUB;Lo;0;L;;;;;N;;;;;
+100C6;LINEAR B IDEOGRAM B230 SPEAR;Lo;0;L;;;;;N;;;;;
+100C7;LINEAR B IDEOGRAM B231 ARROW;Lo;0;L;;;;;N;;;;;
+100C8;LINEAR B IDEOGRAM B232;Lo;0;L;;;;;N;;;;;
+100C9;LINEAR B IDEOGRAM B233 SWORD;Lo;0;L;;;;;N;;;;;
+100CA;LINEAR B IDEOGRAM B234;Lo;0;L;;;;;N;;;;;
+100CB;LINEAR B IDEOGRAM B236;Lo;0;L;;;;;N;;;;;
+100CC;LINEAR B IDEOGRAM B240 WHEELED CHARIOT;Lo;0;L;;;;;N;;;;;
+100CD;LINEAR B IDEOGRAM B241 CHARIOT;Lo;0;L;;;;;N;;;;;
+100CE;LINEAR B IDEOGRAM B242 CHARIOT FRAME;Lo;0;L;;;;;N;;;;;
+100CF;LINEAR B IDEOGRAM B243 WHEEL;Lo;0;L;;;;;N;;;;;
+100D0;LINEAR B IDEOGRAM B245;Lo;0;L;;;;;N;;;;;
+100D1;LINEAR B IDEOGRAM B246;Lo;0;L;;;;;N;;;;;
+100D2;LINEAR B MONOGRAM B247 DIPTE;Lo;0;L;;;;;N;;;;;
+100D3;LINEAR B IDEOGRAM B248;Lo;0;L;;;;;N;;;;;
+100D4;LINEAR B IDEOGRAM B249;Lo;0;L;;;;;N;;;;;
+100D5;LINEAR B IDEOGRAM B251;Lo;0;L;;;;;N;;;;;
+100D6;LINEAR B IDEOGRAM B252;Lo;0;L;;;;;N;;;;;
+100D7;LINEAR B IDEOGRAM B253;Lo;0;L;;;;;N;;;;;
+100D8;LINEAR B IDEOGRAM B254 DART;Lo;0;L;;;;;N;;;;;
+100D9;LINEAR B IDEOGRAM B255;Lo;0;L;;;;;N;;;;;
+100DA;LINEAR B IDEOGRAM B256;Lo;0;L;;;;;N;;;;;
+100DB;LINEAR B IDEOGRAM B257;Lo;0;L;;;;;N;;;;;
+100DC;LINEAR B IDEOGRAM B258;Lo;0;L;;;;;N;;;;;
+100DD;LINEAR B IDEOGRAM B259;Lo;0;L;;;;;N;;;;;
+100DE;LINEAR B IDEOGRAM VESSEL B155;Lo;0;L;;;;;N;;;;;
+100DF;LINEAR B IDEOGRAM VESSEL B200;Lo;0;L;;;;;N;;;;;
+100E0;LINEAR B IDEOGRAM VESSEL B201;Lo;0;L;;;;;N;;;;;
+100E1;LINEAR B IDEOGRAM VESSEL B202;Lo;0;L;;;;;N;;;;;
+100E2;LINEAR B IDEOGRAM VESSEL B203;Lo;0;L;;;;;N;;;;;
+100E3;LINEAR B IDEOGRAM VESSEL B204;Lo;0;L;;;;;N;;;;;
+100E4;LINEAR B IDEOGRAM VESSEL B205;Lo;0;L;;;;;N;;;;;
+100E5;LINEAR B IDEOGRAM VESSEL B206;Lo;0;L;;;;;N;;;;;
+100E6;LINEAR B IDEOGRAM VESSEL B207;Lo;0;L;;;;;N;;;;;
+100E7;LINEAR B IDEOGRAM VESSEL B208;Lo;0;L;;;;;N;;;;;
+100E8;LINEAR B IDEOGRAM VESSEL B209;Lo;0;L;;;;;N;;;;;
+100E9;LINEAR B IDEOGRAM VESSEL B210;Lo;0;L;;;;;N;;;;;
+100EA;LINEAR B IDEOGRAM VESSEL B211;Lo;0;L;;;;;N;;;;;
+100EB;LINEAR B IDEOGRAM VESSEL B212;Lo;0;L;;;;;N;;;;;
+100EC;LINEAR B IDEOGRAM VESSEL B213;Lo;0;L;;;;;N;;;;;
+100ED;LINEAR B IDEOGRAM VESSEL B214;Lo;0;L;;;;;N;;;;;
+100EE;LINEAR B IDEOGRAM VESSEL B215;Lo;0;L;;;;;N;;;;;
+100EF;LINEAR B IDEOGRAM VESSEL B216;Lo;0;L;;;;;N;;;;;
+100F0;LINEAR B IDEOGRAM VESSEL B217;Lo;0;L;;;;;N;;;;;
+100F1;LINEAR B IDEOGRAM VESSEL B218;Lo;0;L;;;;;N;;;;;
+100F2;LINEAR B IDEOGRAM VESSEL B219;Lo;0;L;;;;;N;;;;;
+100F3;LINEAR B IDEOGRAM VESSEL B221;Lo;0;L;;;;;N;;;;;
+100F4;LINEAR B IDEOGRAM VESSEL B222;Lo;0;L;;;;;N;;;;;
+100F5;LINEAR B IDEOGRAM VESSEL B226;Lo;0;L;;;;;N;;;;;
+100F6;LINEAR B IDEOGRAM VESSEL B227;Lo;0;L;;;;;N;;;;;
+100F7;LINEAR B IDEOGRAM VESSEL B228;Lo;0;L;;;;;N;;;;;
+100F8;LINEAR B IDEOGRAM VESSEL B229;Lo;0;L;;;;;N;;;;;
+100F9;LINEAR B IDEOGRAM VESSEL B250;Lo;0;L;;;;;N;;;;;
+100FA;LINEAR B IDEOGRAM VESSEL B305;Lo;0;L;;;;;N;;;;;
+10100;AEGEAN WORD SEPARATOR LINE;Po;0;L;;;;;N;;;;;
+10101;AEGEAN WORD SEPARATOR DOT;Po;0;ON;;;;;N;;;;;
+10102;AEGEAN CHECK MARK;So;0;L;;;;;N;;;;;
+10107;AEGEAN NUMBER ONE;No;0;L;;;;1;N;;;;;
+10108;AEGEAN NUMBER TWO;No;0;L;;;;2;N;;;;;
+10109;AEGEAN NUMBER THREE;No;0;L;;;;3;N;;;;;
+1010A;AEGEAN NUMBER FOUR;No;0;L;;;;4;N;;;;;
+1010B;AEGEAN NUMBER FIVE;No;0;L;;;;5;N;;;;;
+1010C;AEGEAN NUMBER SIX;No;0;L;;;;6;N;;;;;
+1010D;AEGEAN NUMBER SEVEN;No;0;L;;;;7;N;;;;;
+1010E;AEGEAN NUMBER EIGHT;No;0;L;;;;8;N;;;;;
+1010F;AEGEAN NUMBER NINE;No;0;L;;;;9;N;;;;;
+10110;AEGEAN NUMBER TEN;No;0;L;;;;10;N;;;;;
+10111;AEGEAN NUMBER TWENTY;No;0;L;;;;20;N;;;;;
+10112;AEGEAN NUMBER THIRTY;No;0;L;;;;30;N;;;;;
+10113;AEGEAN NUMBER FORTY;No;0;L;;;;40;N;;;;;
+10114;AEGEAN NUMBER FIFTY;No;0;L;;;;50;N;;;;;
+10115;AEGEAN NUMBER SIXTY;No;0;L;;;;60;N;;;;;
+10116;AEGEAN NUMBER SEVENTY;No;0;L;;;;70;N;;;;;
+10117;AEGEAN NUMBER EIGHTY;No;0;L;;;;80;N;;;;;
+10118;AEGEAN NUMBER NINETY;No;0;L;;;;90;N;;;;;
+10119;AEGEAN NUMBER ONE HUNDRED;No;0;L;;;;100;N;;;;;
+1011A;AEGEAN NUMBER TWO HUNDRED;No;0;L;;;;200;N;;;;;
+1011B;AEGEAN NUMBER THREE HUNDRED;No;0;L;;;;300;N;;;;;
+1011C;AEGEAN NUMBER FOUR HUNDRED;No;0;L;;;;400;N;;;;;
+1011D;AEGEAN NUMBER FIVE HUNDRED;No;0;L;;;;500;N;;;;;
+1011E;AEGEAN NUMBER SIX HUNDRED;No;0;L;;;;600;N;;;;;
+1011F;AEGEAN NUMBER SEVEN HUNDRED;No;0;L;;;;700;N;;;;;
+10120;AEGEAN NUMBER EIGHT HUNDRED;No;0;L;;;;800;N;;;;;
+10121;AEGEAN NUMBER NINE HUNDRED;No;0;L;;;;900;N;;;;;
+10122;AEGEAN NUMBER ONE THOUSAND;No;0;L;;;;1000;N;;;;;
+10123;AEGEAN NUMBER TWO THOUSAND;No;0;L;;;;2000;N;;;;;
+10124;AEGEAN NUMBER THREE THOUSAND;No;0;L;;;;3000;N;;;;;
+10125;AEGEAN NUMBER FOUR THOUSAND;No;0;L;;;;4000;N;;;;;
+10126;AEGEAN NUMBER FIVE THOUSAND;No;0;L;;;;5000;N;;;;;
+10127;AEGEAN NUMBER SIX THOUSAND;No;0;L;;;;6000;N;;;;;
+10128;AEGEAN NUMBER SEVEN THOUSAND;No;0;L;;;;7000;N;;;;;
+10129;AEGEAN NUMBER EIGHT THOUSAND;No;0;L;;;;8000;N;;;;;
+1012A;AEGEAN NUMBER NINE THOUSAND;No;0;L;;;;9000;N;;;;;
+1012B;AEGEAN NUMBER TEN THOUSAND;No;0;L;;;;10000;N;;;;;
+1012C;AEGEAN NUMBER TWENTY THOUSAND;No;0;L;;;;20000;N;;;;;
+1012D;AEGEAN NUMBER THIRTY THOUSAND;No;0;L;;;;30000;N;;;;;
+1012E;AEGEAN NUMBER FORTY THOUSAND;No;0;L;;;;40000;N;;;;;
+1012F;AEGEAN NUMBER FIFTY THOUSAND;No;0;L;;;;50000;N;;;;;
+10130;AEGEAN NUMBER SIXTY THOUSAND;No;0;L;;;;60000;N;;;;;
+10131;AEGEAN NUMBER SEVENTY THOUSAND;No;0;L;;;;70000;N;;;;;
+10132;AEGEAN NUMBER EIGHTY THOUSAND;No;0;L;;;;80000;N;;;;;
+10133;AEGEAN NUMBER NINETY THOUSAND;No;0;L;;;;90000;N;;;;;
+10137;AEGEAN WEIGHT BASE UNIT;So;0;L;;;;;N;;;;;
+10138;AEGEAN WEIGHT FIRST SUBUNIT;So;0;L;;;;;N;;;;;
+10139;AEGEAN WEIGHT SECOND SUBUNIT;So;0;L;;;;;N;;;;;
+1013A;AEGEAN WEIGHT THIRD SUBUNIT;So;0;L;;;;;N;;;;;
+1013B;AEGEAN WEIGHT FOURTH SUBUNIT;So;0;L;;;;;N;;;;;
+1013C;AEGEAN DRY MEASURE FIRST SUBUNIT;So;0;L;;;;;N;;;;;
+1013D;AEGEAN LIQUID MEASURE FIRST SUBUNIT;So;0;L;;;;;N;;;;;
+1013E;AEGEAN MEASURE SECOND SUBUNIT;So;0;L;;;;;N;;;;;
+1013F;AEGEAN MEASURE THIRD SUBUNIT;So;0;L;;;;;N;;;;;
+10140;GREEK ACROPHONIC ATTIC ONE QUARTER;Nl;0;ON;;;;1/4;N;;;;;
+10141;GREEK ACROPHONIC ATTIC ONE HALF;Nl;0;ON;;;;1/2;N;;;;;
+10142;GREEK ACROPHONIC ATTIC ONE DRACHMA;Nl;0;ON;;;;1;N;;;;;
+10143;GREEK ACROPHONIC ATTIC FIVE;Nl;0;ON;;;;5;N;;;;;
+10144;GREEK ACROPHONIC ATTIC FIFTY;Nl;0;ON;;;;50;N;;;;;
+10145;GREEK ACROPHONIC ATTIC FIVE HUNDRED;Nl;0;ON;;;;500;N;;;;;
+10146;GREEK ACROPHONIC ATTIC FIVE THOUSAND;Nl;0;ON;;;;5000;N;;;;;
+10147;GREEK ACROPHONIC ATTIC FIFTY THOUSAND;Nl;0;ON;;;;50000;N;;;;;
+10148;GREEK ACROPHONIC ATTIC FIVE TALENTS;Nl;0;ON;;;;5;N;;;;;
+10149;GREEK ACROPHONIC ATTIC TEN TALENTS;Nl;0;ON;;;;10;N;;;;;
+1014A;GREEK ACROPHONIC ATTIC FIFTY TALENTS;Nl;0;ON;;;;50;N;;;;;
+1014B;GREEK ACROPHONIC ATTIC ONE HUNDRED TALENTS;Nl;0;ON;;;;100;N;;;;;
+1014C;GREEK ACROPHONIC ATTIC FIVE HUNDRED TALENTS;Nl;0;ON;;;;500;N;;;;;
+1014D;GREEK ACROPHONIC ATTIC ONE THOUSAND TALENTS;Nl;0;ON;;;;1000;N;;;;;
+1014E;GREEK ACROPHONIC ATTIC FIVE THOUSAND TALENTS;Nl;0;ON;;;;5000;N;;;;;
+1014F;GREEK ACROPHONIC ATTIC FIVE STATERS;Nl;0;ON;;;;5;N;;;;;
+10150;GREEK ACROPHONIC ATTIC TEN STATERS;Nl;0;ON;;;;10;N;;;;;
+10151;GREEK ACROPHONIC ATTIC FIFTY STATERS;Nl;0;ON;;;;50;N;;;;;
+10152;GREEK ACROPHONIC ATTIC ONE HUNDRED STATERS;Nl;0;ON;;;;100;N;;;;;
+10153;GREEK ACROPHONIC ATTIC FIVE HUNDRED STATERS;Nl;0;ON;;;;500;N;;;;;
+10154;GREEK ACROPHONIC ATTIC ONE THOUSAND STATERS;Nl;0;ON;;;;1000;N;;;;;
+10155;GREEK ACROPHONIC ATTIC TEN THOUSAND STATERS;Nl;0;ON;;;;10000;N;;;;;
+10156;GREEK ACROPHONIC ATTIC FIFTY THOUSAND STATERS;Nl;0;ON;;;;50000;N;;;;;
+10157;GREEK ACROPHONIC ATTIC TEN MNAS;Nl;0;ON;;;;10;N;;;;;
+10158;GREEK ACROPHONIC HERAEUM ONE PLETHRON;Nl;0;ON;;;;1;N;;;;;
+10159;GREEK ACROPHONIC THESPIAN ONE;Nl;0;ON;;;;1;N;;;;;
+1015A;GREEK ACROPHONIC HERMIONIAN ONE;Nl;0;ON;;;;1;N;;;;;
+1015B;GREEK ACROPHONIC EPIDAUREAN TWO;Nl;0;ON;;;;2;N;;;;;
+1015C;GREEK ACROPHONIC THESPIAN TWO;Nl;0;ON;;;;2;N;;;;;
+1015D;GREEK ACROPHONIC CYRENAIC TWO DRACHMAS;Nl;0;ON;;;;2;N;;;;;
+1015E;GREEK ACROPHONIC EPIDAUREAN TWO DRACHMAS;Nl;0;ON;;;;2;N;;;;;
+1015F;GREEK ACROPHONIC TROEZENIAN FIVE;Nl;0;ON;;;;5;N;;;;;
+10160;GREEK ACROPHONIC TROEZENIAN TEN;Nl;0;ON;;;;10;N;;;;;
+10161;GREEK ACROPHONIC TROEZENIAN TEN ALTERNATE FORM;Nl;0;ON;;;;10;N;;;;;
+10162;GREEK ACROPHONIC HERMIONIAN TEN;Nl;0;ON;;;;10;N;;;;;
+10163;GREEK ACROPHONIC MESSENIAN TEN;Nl;0;ON;;;;10;N;;;;;
+10164;GREEK ACROPHONIC THESPIAN TEN;Nl;0;ON;;;;10;N;;;;;
+10165;GREEK ACROPHONIC THESPIAN THIRTY;Nl;0;ON;;;;30;N;;;;;
+10166;GREEK ACROPHONIC TROEZENIAN FIFTY;Nl;0;ON;;;;50;N;;;;;
+10167;GREEK ACROPHONIC TROEZENIAN FIFTY ALTERNATE FORM;Nl;0;ON;;;;50;N;;;;;
+10168;GREEK ACROPHONIC HERMIONIAN FIFTY;Nl;0;ON;;;;50;N;;;;;
+10169;GREEK ACROPHONIC THESPIAN FIFTY;Nl;0;ON;;;;50;N;;;;;
+1016A;GREEK ACROPHONIC THESPIAN ONE HUNDRED;Nl;0;ON;;;;100;N;;;;;
+1016B;GREEK ACROPHONIC THESPIAN THREE HUNDRED;Nl;0;ON;;;;300;N;;;;;
+1016C;GREEK ACROPHONIC EPIDAUREAN FIVE HUNDRED;Nl;0;ON;;;;500;N;;;;;
+1016D;GREEK ACROPHONIC TROEZENIAN FIVE HUNDRED;Nl;0;ON;;;;500;N;;;;;
+1016E;GREEK ACROPHONIC THESPIAN FIVE HUNDRED;Nl;0;ON;;;;500;N;;;;;
+1016F;GREEK ACROPHONIC CARYSTIAN FIVE HUNDRED;Nl;0;ON;;;;500;N;;;;;
+10170;GREEK ACROPHONIC NAXIAN FIVE HUNDRED;Nl;0;ON;;;;500;N;;;;;
+10171;GREEK ACROPHONIC THESPIAN ONE THOUSAND;Nl;0;ON;;;;1000;N;;;;;
+10172;GREEK ACROPHONIC THESPIAN FIVE THOUSAND;Nl;0;ON;;;;5000;N;;;;;
+10173;GREEK ACROPHONIC DELPHIC FIVE MNAS;Nl;0;ON;;;;5;N;;;;;
+10174;GREEK ACROPHONIC STRATIAN FIFTY MNAS;Nl;0;ON;;;;50;N;;;;;
+10175;GREEK ONE HALF SIGN;No;0;ON;;;;1/2;N;;;;;
+10176;GREEK ONE HALF SIGN ALTERNATE FORM;No;0;ON;;;;1/2;N;;;;;
+10177;GREEK TWO THIRDS SIGN;No;0;ON;;;;2/3;N;;;;;
+10178;GREEK THREE QUARTERS SIGN;No;0;ON;;;;3/4;N;;;;;
+10179;GREEK YEAR SIGN;So;0;ON;;;;;N;;;;;
+1017A;GREEK TALENT SIGN;So;0;ON;;;;;N;;;;;
+1017B;GREEK DRACHMA SIGN;So;0;ON;;;;;N;;;;;
+1017C;GREEK OBOL SIGN;So;0;ON;;;;;N;;;;;
+1017D;GREEK TWO OBOLS SIGN;So;0;ON;;;;;N;;;;;
+1017E;GREEK THREE OBOLS SIGN;So;0;ON;;;;;N;;;;;
+1017F;GREEK FOUR OBOLS SIGN;So;0;ON;;;;;N;;;;;
+10180;GREEK FIVE OBOLS SIGN;So;0;ON;;;;;N;;;;;
+10181;GREEK METRETES SIGN;So;0;ON;;;;;N;;;;;
+10182;GREEK KYATHOS BASE SIGN;So;0;ON;;;;;N;;;;;
+10183;GREEK LITRA SIGN;So;0;ON;;;;;N;;;;;
+10184;GREEK OUNKIA SIGN;So;0;ON;;;;;N;;;;;
+10185;GREEK XESTES SIGN;So;0;ON;;;;;N;;;;;
+10186;GREEK ARTABE SIGN;So;0;ON;;;;;N;;;;;
+10187;GREEK AROURA SIGN;So;0;ON;;;;;N;;;;;
+10188;GREEK GRAMMA SIGN;So;0;ON;;;;;N;;;;;
+10189;GREEK TRYBLION BASE SIGN;So;0;ON;;;;;N;;;;;
+1018A;GREEK ZERO SIGN;No;0;ON;;;;0;N;;;;;
+10190;ROMAN SEXTANS SIGN;So;0;ON;;;;;N;;;;;
+10191;ROMAN UNCIA SIGN;So;0;ON;;;;;N;;;;;
+10192;ROMAN SEMUNCIA SIGN;So;0;ON;;;;;N;;;;;
+10193;ROMAN SEXTULA SIGN;So;0;ON;;;;;N;;;;;
+10194;ROMAN DIMIDIA SEXTULA SIGN;So;0;ON;;;;;N;;;;;
+10195;ROMAN SILIQUA SIGN;So;0;ON;;;;;N;;;;;
+10196;ROMAN DENARIUS SIGN;So;0;ON;;;;;N;;;;;
+10197;ROMAN QUINARIUS SIGN;So;0;ON;;;;;N;;;;;
+10198;ROMAN SESTERTIUS SIGN;So;0;ON;;;;;N;;;;;
+10199;ROMAN DUPONDIUS SIGN;So;0;ON;;;;;N;;;;;
+1019A;ROMAN AS SIGN;So;0;ON;;;;;N;;;;;
+1019B;ROMAN CENTURIAL SIGN;So;0;ON;;;;;N;;;;;
+101D0;PHAISTOS DISC SIGN PEDESTRIAN;So;0;L;;;;;N;;;;;
+101D1;PHAISTOS DISC SIGN PLUMED HEAD;So;0;L;;;;;N;;;;;
+101D2;PHAISTOS DISC SIGN TATTOOED HEAD;So;0;L;;;;;N;;;;;
+101D3;PHAISTOS DISC SIGN CAPTIVE;So;0;L;;;;;N;;;;;
+101D4;PHAISTOS DISC SIGN CHILD;So;0;L;;;;;N;;;;;
+101D5;PHAISTOS DISC SIGN WOMAN;So;0;L;;;;;N;;;;;
+101D6;PHAISTOS DISC SIGN HELMET;So;0;L;;;;;N;;;;;
+101D7;PHAISTOS DISC SIGN GAUNTLET;So;0;L;;;;;N;;;;;
+101D8;PHAISTOS DISC SIGN TIARA;So;0;L;;;;;N;;;;;
+101D9;PHAISTOS DISC SIGN ARROW;So;0;L;;;;;N;;;;;
+101DA;PHAISTOS DISC SIGN BOW;So;0;L;;;;;N;;;;;
+101DB;PHAISTOS DISC SIGN SHIELD;So;0;L;;;;;N;;;;;
+101DC;PHAISTOS DISC SIGN CLUB;So;0;L;;;;;N;;;;;
+101DD;PHAISTOS DISC SIGN MANACLES;So;0;L;;;;;N;;;;;
+101DE;PHAISTOS DISC SIGN MATTOCK;So;0;L;;;;;N;;;;;
+101DF;PHAISTOS DISC SIGN SAW;So;0;L;;;;;N;;;;;
+101E0;PHAISTOS DISC SIGN LID;So;0;L;;;;;N;;;;;
+101E1;PHAISTOS DISC SIGN BOOMERANG;So;0;L;;;;;N;;;;;
+101E2;PHAISTOS DISC SIGN CARPENTRY PLANE;So;0;L;;;;;N;;;;;
+101E3;PHAISTOS DISC SIGN DOLIUM;So;0;L;;;;;N;;;;;
+101E4;PHAISTOS DISC SIGN COMB;So;0;L;;;;;N;;;;;
+101E5;PHAISTOS DISC SIGN SLING;So;0;L;;;;;N;;;;;
+101E6;PHAISTOS DISC SIGN COLUMN;So;0;L;;;;;N;;;;;
+101E7;PHAISTOS DISC SIGN BEEHIVE;So;0;L;;;;;N;;;;;
+101E8;PHAISTOS DISC SIGN SHIP;So;0;L;;;;;N;;;;;
+101E9;PHAISTOS DISC SIGN HORN;So;0;L;;;;;N;;;;;
+101EA;PHAISTOS DISC SIGN HIDE;So;0;L;;;;;N;;;;;
+101EB;PHAISTOS DISC SIGN BULLS LEG;So;0;L;;;;;N;;;;;
+101EC;PHAISTOS DISC SIGN CAT;So;0;L;;;;;N;;;;;
+101ED;PHAISTOS DISC SIGN RAM;So;0;L;;;;;N;;;;;
+101EE;PHAISTOS DISC SIGN EAGLE;So;0;L;;;;;N;;;;;
+101EF;PHAISTOS DISC SIGN DOVE;So;0;L;;;;;N;;;;;
+101F0;PHAISTOS DISC SIGN TUNNY;So;0;L;;;;;N;;;;;
+101F1;PHAISTOS DISC SIGN BEE;So;0;L;;;;;N;;;;;
+101F2;PHAISTOS DISC SIGN PLANE TREE;So;0;L;;;;;N;;;;;
+101F3;PHAISTOS DISC SIGN VINE;So;0;L;;;;;N;;;;;
+101F4;PHAISTOS DISC SIGN PAPYRUS;So;0;L;;;;;N;;;;;
+101F5;PHAISTOS DISC SIGN ROSETTE;So;0;L;;;;;N;;;;;
+101F6;PHAISTOS DISC SIGN LILY;So;0;L;;;;;N;;;;;
+101F7;PHAISTOS DISC SIGN OX BACK;So;0;L;;;;;N;;;;;
+101F8;PHAISTOS DISC SIGN FLUTE;So;0;L;;;;;N;;;;;
+101F9;PHAISTOS DISC SIGN GRATER;So;0;L;;;;;N;;;;;
+101FA;PHAISTOS DISC SIGN STRAINER;So;0;L;;;;;N;;;;;
+101FB;PHAISTOS DISC SIGN SMALL AXE;So;0;L;;;;;N;;;;;
+101FC;PHAISTOS DISC SIGN WAVY BAND;So;0;L;;;;;N;;;;;
+101FD;PHAISTOS DISC SIGN COMBINING OBLIQUE STROKE;Mn;220;NSM;;;;;N;;;;;
+10280;LYCIAN LETTER A;Lo;0;L;;;;;N;;;;;
+10281;LYCIAN LETTER E;Lo;0;L;;;;;N;;;;;
+10282;LYCIAN LETTER B;Lo;0;L;;;;;N;;;;;
+10283;LYCIAN LETTER BH;Lo;0;L;;;;;N;;;;;
+10284;LYCIAN LETTER G;Lo;0;L;;;;;N;;;;;
+10285;LYCIAN LETTER D;Lo;0;L;;;;;N;;;;;
+10286;LYCIAN LETTER I;Lo;0;L;;;;;N;;;;;
+10287;LYCIAN LETTER W;Lo;0;L;;;;;N;;;;;
+10288;LYCIAN LETTER Z;Lo;0;L;;;;;N;;;;;
+10289;LYCIAN LETTER TH;Lo;0;L;;;;;N;;;;;
+1028A;LYCIAN LETTER J;Lo;0;L;;;;;N;;;;;
+1028B;LYCIAN LETTER K;Lo;0;L;;;;;N;;;;;
+1028C;LYCIAN LETTER Q;Lo;0;L;;;;;N;;;;;
+1028D;LYCIAN LETTER L;Lo;0;L;;;;;N;;;;;
+1028E;LYCIAN LETTER M;Lo;0;L;;;;;N;;;;;
+1028F;LYCIAN LETTER N;Lo;0;L;;;;;N;;;;;
+10290;LYCIAN LETTER MM;Lo;0;L;;;;;N;;;;;
+10291;LYCIAN LETTER NN;Lo;0;L;;;;;N;;;;;
+10292;LYCIAN LETTER U;Lo;0;L;;;;;N;;;;;
+10293;LYCIAN LETTER P;Lo;0;L;;;;;N;;;;;
+10294;LYCIAN LETTER KK;Lo;0;L;;;;;N;;;;;
+10295;LYCIAN LETTER R;Lo;0;L;;;;;N;;;;;
+10296;LYCIAN LETTER S;Lo;0;L;;;;;N;;;;;
+10297;LYCIAN LETTER T;Lo;0;L;;;;;N;;;;;
+10298;LYCIAN LETTER TT;Lo;0;L;;;;;N;;;;;
+10299;LYCIAN LETTER AN;Lo;0;L;;;;;N;;;;;
+1029A;LYCIAN LETTER EN;Lo;0;L;;;;;N;;;;;
+1029B;LYCIAN LETTER H;Lo;0;L;;;;;N;;;;;
+1029C;LYCIAN LETTER X;Lo;0;L;;;;;N;;;;;
+102A0;CARIAN LETTER A;Lo;0;L;;;;;N;;;;;
+102A1;CARIAN LETTER P2;Lo;0;L;;;;;N;;;;;
+102A2;CARIAN LETTER D;Lo;0;L;;;;;N;;;;;
+102A3;CARIAN LETTER L;Lo;0;L;;;;;N;;;;;
+102A4;CARIAN LETTER UUU;Lo;0;L;;;;;N;;;;;
+102A5;CARIAN LETTER R;Lo;0;L;;;;;N;;;;;
+102A6;CARIAN LETTER LD;Lo;0;L;;;;;N;;;;;
+102A7;CARIAN LETTER A2;Lo;0;L;;;;;N;;;;;
+102A8;CARIAN LETTER Q;Lo;0;L;;;;;N;;;;;
+102A9;CARIAN LETTER B;Lo;0;L;;;;;N;;;;;
+102AA;CARIAN LETTER M;Lo;0;L;;;;;N;;;;;
+102AB;CARIAN LETTER O;Lo;0;L;;;;;N;;;;;
+102AC;CARIAN LETTER D2;Lo;0;L;;;;;N;;;;;
+102AD;CARIAN LETTER T;Lo;0;L;;;;;N;;;;;
+102AE;CARIAN LETTER SH;Lo;0;L;;;;;N;;;;;
+102AF;CARIAN LETTER SH2;Lo;0;L;;;;;N;;;;;
+102B0;CARIAN LETTER S;Lo;0;L;;;;;N;;;;;
+102B1;CARIAN LETTER C-18;Lo;0;L;;;;;N;;;;;
+102B2;CARIAN LETTER U;Lo;0;L;;;;;N;;;;;
+102B3;CARIAN LETTER NN;Lo;0;L;;;;;N;;;;;
+102B4;CARIAN LETTER X;Lo;0;L;;;;;N;;;;;
+102B5;CARIAN LETTER N;Lo;0;L;;;;;N;;;;;
+102B6;CARIAN LETTER TT2;Lo;0;L;;;;;N;;;;;
+102B7;CARIAN LETTER P;Lo;0;L;;;;;N;;;;;
+102B8;CARIAN LETTER SS;Lo;0;L;;;;;N;;;;;
+102B9;CARIAN LETTER I;Lo;0;L;;;;;N;;;;;
+102BA;CARIAN LETTER E;Lo;0;L;;;;;N;;;;;
+102BB;CARIAN LETTER UUUU;Lo;0;L;;;;;N;;;;;
+102BC;CARIAN LETTER K;Lo;0;L;;;;;N;;;;;
+102BD;CARIAN LETTER K2;Lo;0;L;;;;;N;;;;;
+102BE;CARIAN LETTER ND;Lo;0;L;;;;;N;;;;;
+102BF;CARIAN LETTER UU;Lo;0;L;;;;;N;;;;;
+102C0;CARIAN LETTER G;Lo;0;L;;;;;N;;;;;
+102C1;CARIAN LETTER G2;Lo;0;L;;;;;N;;;;;
+102C2;CARIAN LETTER ST;Lo;0;L;;;;;N;;;;;
+102C3;CARIAN LETTER ST2;Lo;0;L;;;;;N;;;;;
+102C4;CARIAN LETTER NG;Lo;0;L;;;;;N;;;;;
+102C5;CARIAN LETTER II;Lo;0;L;;;;;N;;;;;
+102C6;CARIAN LETTER C-39;Lo;0;L;;;;;N;;;;;
+102C7;CARIAN LETTER TT;Lo;0;L;;;;;N;;;;;
+102C8;CARIAN LETTER UUU2;Lo;0;L;;;;;N;;;;;
+102C9;CARIAN LETTER RR;Lo;0;L;;;;;N;;;;;
+102CA;CARIAN LETTER MB;Lo;0;L;;;;;N;;;;;
+102CB;CARIAN LETTER MB2;Lo;0;L;;;;;N;;;;;
+102CC;CARIAN LETTER MB3;Lo;0;L;;;;;N;;;;;
+102CD;CARIAN LETTER MB4;Lo;0;L;;;;;N;;;;;
+102CE;CARIAN LETTER LD2;Lo;0;L;;;;;N;;;;;
+102CF;CARIAN LETTER E2;Lo;0;L;;;;;N;;;;;
+102D0;CARIAN LETTER UUU3;Lo;0;L;;;;;N;;;;;
+10300;OLD ITALIC LETTER A;Lo;0;L;;;;;N;;;;;
+10301;OLD ITALIC LETTER BE;Lo;0;L;;;;;N;;;;;
+10302;OLD ITALIC LETTER KE;Lo;0;L;;;;;N;;;;;
+10303;OLD ITALIC LETTER DE;Lo;0;L;;;;;N;;;;;
+10304;OLD ITALIC LETTER E;Lo;0;L;;;;;N;;;;;
+10305;OLD ITALIC LETTER VE;Lo;0;L;;;;;N;;;;;
+10306;OLD ITALIC LETTER ZE;Lo;0;L;;;;;N;;;;;
+10307;OLD ITALIC LETTER HE;Lo;0;L;;;;;N;;;;;
+10308;OLD ITALIC LETTER THE;Lo;0;L;;;;;N;;;;;
+10309;OLD ITALIC LETTER I;Lo;0;L;;;;;N;;;;;
+1030A;OLD ITALIC LETTER KA;Lo;0;L;;;;;N;;;;;
+1030B;OLD ITALIC LETTER EL;Lo;0;L;;;;;N;;;;;
+1030C;OLD ITALIC LETTER EM;Lo;0;L;;;;;N;;;;;
+1030D;OLD ITALIC LETTER EN;Lo;0;L;;;;;N;;;;;
+1030E;OLD ITALIC LETTER ESH;Lo;0;L;;;;;N;;;;;
+1030F;OLD ITALIC LETTER O;Lo;0;L;;;;;N;;;;;
+10310;OLD ITALIC LETTER PE;Lo;0;L;;;;;N;;;;;
+10311;OLD ITALIC LETTER SHE;Lo;0;L;;;;;N;;;;;
+10312;OLD ITALIC LETTER KU;Lo;0;L;;;;;N;;;;;
+10313;OLD ITALIC LETTER ER;Lo;0;L;;;;;N;;;;;
+10314;OLD ITALIC LETTER ES;Lo;0;L;;;;;N;;;;;
+10315;OLD ITALIC LETTER TE;Lo;0;L;;;;;N;;;;;
+10316;OLD ITALIC LETTER U;Lo;0;L;;;;;N;;;;;
+10317;OLD ITALIC LETTER EKS;Lo;0;L;;;;;N;;;;;
+10318;OLD ITALIC LETTER PHE;Lo;0;L;;;;;N;;;;;
+10319;OLD ITALIC LETTER KHE;Lo;0;L;;;;;N;;;;;
+1031A;OLD ITALIC LETTER EF;Lo;0;L;;;;;N;;;;;
+1031B;OLD ITALIC LETTER ERS;Lo;0;L;;;;;N;;;;;
+1031C;OLD ITALIC LETTER CHE;Lo;0;L;;;;;N;;;;;
+1031D;OLD ITALIC LETTER II;Lo;0;L;;;;;N;;;;;
+1031E;OLD ITALIC LETTER UU;Lo;0;L;;;;;N;;;;;
+10320;OLD ITALIC NUMERAL ONE;No;0;L;;;;1;N;;;;;
+10321;OLD ITALIC NUMERAL FIVE;No;0;L;;;;5;N;;;;;
+10322;OLD ITALIC NUMERAL TEN;No;0;L;;;;10;N;;;;;
+10323;OLD ITALIC NUMERAL FIFTY;No;0;L;;;;50;N;;;;;
+10330;GOTHIC LETTER AHSA;Lo;0;L;;;;;N;;;;;
+10331;GOTHIC LETTER BAIRKAN;Lo;0;L;;;;;N;;;;;
+10332;GOTHIC LETTER GIBA;Lo;0;L;;;;;N;;;;;
+10333;GOTHIC LETTER DAGS;Lo;0;L;;;;;N;;;;;
+10334;GOTHIC LETTER AIHVUS;Lo;0;L;;;;;N;;;;;
+10335;GOTHIC LETTER QAIRTHRA;Lo;0;L;;;;;N;;;;;
+10336;GOTHIC LETTER IUJA;Lo;0;L;;;;;N;;;;;
+10337;GOTHIC LETTER HAGL;Lo;0;L;;;;;N;;;;;
+10338;GOTHIC LETTER THIUTH;Lo;0;L;;;;;N;;;;;
+10339;GOTHIC LETTER EIS;Lo;0;L;;;;;N;;;;;
+1033A;GOTHIC LETTER KUSMA;Lo;0;L;;;;;N;;;;;
+1033B;GOTHIC LETTER LAGUS;Lo;0;L;;;;;N;;;;;
+1033C;GOTHIC LETTER MANNA;Lo;0;L;;;;;N;;;;;
+1033D;GOTHIC LETTER NAUTHS;Lo;0;L;;;;;N;;;;;
+1033E;GOTHIC LETTER JER;Lo;0;L;;;;;N;;;;;
+1033F;GOTHIC LETTER URUS;Lo;0;L;;;;;N;;;;;
+10340;GOTHIC LETTER PAIRTHRA;Lo;0;L;;;;;N;;;;;
+10341;GOTHIC LETTER NINETY;Nl;0;L;;;;90;N;;;;;
+10342;GOTHIC LETTER RAIDA;Lo;0;L;;;;;N;;;;;
+10343;GOTHIC LETTER SAUIL;Lo;0;L;;;;;N;;;;;
+10344;GOTHIC LETTER TEIWS;Lo;0;L;;;;;N;;;;;
+10345;GOTHIC LETTER WINJA;Lo;0;L;;;;;N;;;;;
+10346;GOTHIC LETTER FAIHU;Lo;0;L;;;;;N;;;;;
+10347;GOTHIC LETTER IGGWS;Lo;0;L;;;;;N;;;;;
+10348;GOTHIC LETTER HWAIR;Lo;0;L;;;;;N;;;;;
+10349;GOTHIC LETTER OTHAL;Lo;0;L;;;;;N;;;;;
+1034A;GOTHIC LETTER NINE HUNDRED;Nl;0;L;;;;900;N;;;;;
+10380;UGARITIC LETTER ALPA;Lo;0;L;;;;;N;;;;;
+10381;UGARITIC LETTER BETA;Lo;0;L;;;;;N;;;;;
+10382;UGARITIC LETTER GAMLA;Lo;0;L;;;;;N;;;;;
+10383;UGARITIC LETTER KHA;Lo;0;L;;;;;N;;;;;
+10384;UGARITIC LETTER DELTA;Lo;0;L;;;;;N;;;;;
+10385;UGARITIC LETTER HO;Lo;0;L;;;;;N;;;;;
+10386;UGARITIC LETTER WO;Lo;0;L;;;;;N;;;;;
+10387;UGARITIC LETTER ZETA;Lo;0;L;;;;;N;;;;;
+10388;UGARITIC LETTER HOTA;Lo;0;L;;;;;N;;;;;
+10389;UGARITIC LETTER TET;Lo;0;L;;;;;N;;;;;
+1038A;UGARITIC LETTER YOD;Lo;0;L;;;;;N;;;;;
+1038B;UGARITIC LETTER KAF;Lo;0;L;;;;;N;;;;;
+1038C;UGARITIC LETTER SHIN;Lo;0;L;;;;;N;;;;;
+1038D;UGARITIC LETTER LAMDA;Lo;0;L;;;;;N;;;;;
+1038E;UGARITIC LETTER MEM;Lo;0;L;;;;;N;;;;;
+1038F;UGARITIC LETTER DHAL;Lo;0;L;;;;;N;;;;;
+10390;UGARITIC LETTER NUN;Lo;0;L;;;;;N;;;;;
+10391;UGARITIC LETTER ZU;Lo;0;L;;;;;N;;;;;
+10392;UGARITIC LETTER SAMKA;Lo;0;L;;;;;N;;;;;
+10393;UGARITIC LETTER AIN;Lo;0;L;;;;;N;;;;;
+10394;UGARITIC LETTER PU;Lo;0;L;;;;;N;;;;;
+10395;UGARITIC LETTER SADE;Lo;0;L;;;;;N;;;;;
+10396;UGARITIC LETTER QOPA;Lo;0;L;;;;;N;;;;;
+10397;UGARITIC LETTER RASHA;Lo;0;L;;;;;N;;;;;
+10398;UGARITIC LETTER THANNA;Lo;0;L;;;;;N;;;;;
+10399;UGARITIC LETTER GHAIN;Lo;0;L;;;;;N;;;;;
+1039A;UGARITIC LETTER TO;Lo;0;L;;;;;N;;;;;
+1039B;UGARITIC LETTER I;Lo;0;L;;;;;N;;;;;
+1039C;UGARITIC LETTER U;Lo;0;L;;;;;N;;;;;
+1039D;UGARITIC LETTER SSU;Lo;0;L;;;;;N;;;;;
+1039F;UGARITIC WORD DIVIDER;Po;0;L;;;;;N;;;;;
+103A0;OLD PERSIAN SIGN A;Lo;0;L;;;;;N;;;;;
+103A1;OLD PERSIAN SIGN I;Lo;0;L;;;;;N;;;;;
+103A2;OLD PERSIAN SIGN U;Lo;0;L;;;;;N;;;;;
+103A3;OLD PERSIAN SIGN KA;Lo;0;L;;;;;N;;;;;
+103A4;OLD PERSIAN SIGN KU;Lo;0;L;;;;;N;;;;;
+103A5;OLD PERSIAN SIGN GA;Lo;0;L;;;;;N;;;;;
+103A6;OLD PERSIAN SIGN GU;Lo;0;L;;;;;N;;;;;
+103A7;OLD PERSIAN SIGN XA;Lo;0;L;;;;;N;;;;;
+103A8;OLD PERSIAN SIGN CA;Lo;0;L;;;;;N;;;;;
+103A9;OLD PERSIAN SIGN JA;Lo;0;L;;;;;N;;;;;
+103AA;OLD PERSIAN SIGN JI;Lo;0;L;;;;;N;;;;;
+103AB;OLD PERSIAN SIGN TA;Lo;0;L;;;;;N;;;;;
+103AC;OLD PERSIAN SIGN TU;Lo;0;L;;;;;N;;;;;
+103AD;OLD PERSIAN SIGN DA;Lo;0;L;;;;;N;;;;;
+103AE;OLD PERSIAN SIGN DI;Lo;0;L;;;;;N;;;;;
+103AF;OLD PERSIAN SIGN DU;Lo;0;L;;;;;N;;;;;
+103B0;OLD PERSIAN SIGN THA;Lo;0;L;;;;;N;;;;;
+103B1;OLD PERSIAN SIGN PA;Lo;0;L;;;;;N;;;;;
+103B2;OLD PERSIAN SIGN BA;Lo;0;L;;;;;N;;;;;
+103B3;OLD PERSIAN SIGN FA;Lo;0;L;;;;;N;;;;;
+103B4;OLD PERSIAN SIGN NA;Lo;0;L;;;;;N;;;;;
+103B5;OLD PERSIAN SIGN NU;Lo;0;L;;;;;N;;;;;
+103B6;OLD PERSIAN SIGN MA;Lo;0;L;;;;;N;;;;;
+103B7;OLD PERSIAN SIGN MI;Lo;0;L;;;;;N;;;;;
+103B8;OLD PERSIAN SIGN MU;Lo;0;L;;;;;N;;;;;
+103B9;OLD PERSIAN SIGN YA;Lo;0;L;;;;;N;;;;;
+103BA;OLD PERSIAN SIGN VA;Lo;0;L;;;;;N;;;;;
+103BB;OLD PERSIAN SIGN VI;Lo;0;L;;;;;N;;;;;
+103BC;OLD PERSIAN SIGN RA;Lo;0;L;;;;;N;;;;;
+103BD;OLD PERSIAN SIGN RU;Lo;0;L;;;;;N;;;;;
+103BE;OLD PERSIAN SIGN LA;Lo;0;L;;;;;N;;;;;
+103BF;OLD PERSIAN SIGN SA;Lo;0;L;;;;;N;;;;;
+103C0;OLD PERSIAN SIGN ZA;Lo;0;L;;;;;N;;;;;
+103C1;OLD PERSIAN SIGN SHA;Lo;0;L;;;;;N;;;;;
+103C2;OLD PERSIAN SIGN SSA;Lo;0;L;;;;;N;;;;;
+103C3;OLD PERSIAN SIGN HA;Lo;0;L;;;;;N;;;;;
+103C8;OLD PERSIAN SIGN AURAMAZDAA;Lo;0;L;;;;;N;;;;;
+103C9;OLD PERSIAN SIGN AURAMAZDAA-2;Lo;0;L;;;;;N;;;;;
+103CA;OLD PERSIAN SIGN AURAMAZDAAHA;Lo;0;L;;;;;N;;;;;
+103CB;OLD PERSIAN SIGN XSHAAYATHIYA;Lo;0;L;;;;;N;;;;;
+103CC;OLD PERSIAN SIGN DAHYAAUSH;Lo;0;L;;;;;N;;;;;
+103CD;OLD PERSIAN SIGN DAHYAAUSH-2;Lo;0;L;;;;;N;;;;;
+103CE;OLD PERSIAN SIGN BAGA;Lo;0;L;;;;;N;;;;;
+103CF;OLD PERSIAN SIGN BUUMISH;Lo;0;L;;;;;N;;;;;
+103D0;OLD PERSIAN WORD DIVIDER;Po;0;L;;;;;N;;;;;
+103D1;OLD PERSIAN NUMBER ONE;Nl;0;L;;;;1;N;;;;;
+103D2;OLD PERSIAN NUMBER TWO;Nl;0;L;;;;2;N;;;;;
+103D3;OLD PERSIAN NUMBER TEN;Nl;0;L;;;;10;N;;;;;
+103D4;OLD PERSIAN NUMBER TWENTY;Nl;0;L;;;;20;N;;;;;
+103D5;OLD PERSIAN NUMBER HUNDRED;Nl;0;L;;;;100;N;;;;;
+10400;DESERET CAPITAL LETTER LONG I;Lu;0;L;;;;;N;;;;10428;
+10401;DESERET CAPITAL LETTER LONG E;Lu;0;L;;;;;N;;;;10429;
+10402;DESERET CAPITAL LETTER LONG A;Lu;0;L;;;;;N;;;;1042A;
+10403;DESERET CAPITAL LETTER LONG AH;Lu;0;L;;;;;N;;;;1042B;
+10404;DESERET CAPITAL LETTER LONG O;Lu;0;L;;;;;N;;;;1042C;
+10405;DESERET CAPITAL LETTER LONG OO;Lu;0;L;;;;;N;;;;1042D;
+10406;DESERET CAPITAL LETTER SHORT I;Lu;0;L;;;;;N;;;;1042E;
+10407;DESERET CAPITAL LETTER SHORT E;Lu;0;L;;;;;N;;;;1042F;
+10408;DESERET CAPITAL LETTER SHORT A;Lu;0;L;;;;;N;;;;10430;
+10409;DESERET CAPITAL LETTER SHORT AH;Lu;0;L;;;;;N;;;;10431;
+1040A;DESERET CAPITAL LETTER SHORT O;Lu;0;L;;;;;N;;;;10432;
+1040B;DESERET CAPITAL LETTER SHORT OO;Lu;0;L;;;;;N;;;;10433;
+1040C;DESERET CAPITAL LETTER AY;Lu;0;L;;;;;N;;;;10434;
+1040D;DESERET CAPITAL LETTER OW;Lu;0;L;;;;;N;;;;10435;
+1040E;DESERET CAPITAL LETTER WU;Lu;0;L;;;;;N;;;;10436;
+1040F;DESERET CAPITAL LETTER YEE;Lu;0;L;;;;;N;;;;10437;
+10410;DESERET CAPITAL LETTER H;Lu;0;L;;;;;N;;;;10438;
+10411;DESERET CAPITAL LETTER PEE;Lu;0;L;;;;;N;;;;10439;
+10412;DESERET CAPITAL LETTER BEE;Lu;0;L;;;;;N;;;;1043A;
+10413;DESERET CAPITAL LETTER TEE;Lu;0;L;;;;;N;;;;1043B;
+10414;DESERET CAPITAL LETTER DEE;Lu;0;L;;;;;N;;;;1043C;
+10415;DESERET CAPITAL LETTER CHEE;Lu;0;L;;;;;N;;;;1043D;
+10416;DESERET CAPITAL LETTER JEE;Lu;0;L;;;;;N;;;;1043E;
+10417;DESERET CAPITAL LETTER KAY;Lu;0;L;;;;;N;;;;1043F;
+10418;DESERET CAPITAL LETTER GAY;Lu;0;L;;;;;N;;;;10440;
+10419;DESERET CAPITAL LETTER EF;Lu;0;L;;;;;N;;;;10441;
+1041A;DESERET CAPITAL LETTER VEE;Lu;0;L;;;;;N;;;;10442;
+1041B;DESERET CAPITAL LETTER ETH;Lu;0;L;;;;;N;;;;10443;
+1041C;DESERET CAPITAL LETTER THEE;Lu;0;L;;;;;N;;;;10444;
+1041D;DESERET CAPITAL LETTER ES;Lu;0;L;;;;;N;;;;10445;
+1041E;DESERET CAPITAL LETTER ZEE;Lu;0;L;;;;;N;;;;10446;
+1041F;DESERET CAPITAL LETTER ESH;Lu;0;L;;;;;N;;;;10447;
+10420;DESERET CAPITAL LETTER ZHEE;Lu;0;L;;;;;N;;;;10448;
+10421;DESERET CAPITAL LETTER ER;Lu;0;L;;;;;N;;;;10449;
+10422;DESERET CAPITAL LETTER EL;Lu;0;L;;;;;N;;;;1044A;
+10423;DESERET CAPITAL LETTER EM;Lu;0;L;;;;;N;;;;1044B;
+10424;DESERET CAPITAL LETTER EN;Lu;0;L;;;;;N;;;;1044C;
+10425;DESERET CAPITAL LETTER ENG;Lu;0;L;;;;;N;;;;1044D;
+10426;DESERET CAPITAL LETTER OI;Lu;0;L;;;;;N;;;;1044E;
+10427;DESERET CAPITAL LETTER EW;Lu;0;L;;;;;N;;;;1044F;
+10428;DESERET SMALL LETTER LONG I;Ll;0;L;;;;;N;;;10400;;10400
+10429;DESERET SMALL LETTER LONG E;Ll;0;L;;;;;N;;;10401;;10401
+1042A;DESERET SMALL LETTER LONG A;Ll;0;L;;;;;N;;;10402;;10402
+1042B;DESERET SMALL LETTER LONG AH;Ll;0;L;;;;;N;;;10403;;10403
+1042C;DESERET SMALL LETTER LONG O;Ll;0;L;;;;;N;;;10404;;10404
+1042D;DESERET SMALL LETTER LONG OO;Ll;0;L;;;;;N;;;10405;;10405
+1042E;DESERET SMALL LETTER SHORT I;Ll;0;L;;;;;N;;;10406;;10406
+1042F;DESERET SMALL LETTER SHORT E;Ll;0;L;;;;;N;;;10407;;10407
+10430;DESERET SMALL LETTER SHORT A;Ll;0;L;;;;;N;;;10408;;10408
+10431;DESERET SMALL LETTER SHORT AH;Ll;0;L;;;;;N;;;10409;;10409
+10432;DESERET SMALL LETTER SHORT O;Ll;0;L;;;;;N;;;1040A;;1040A
+10433;DESERET SMALL LETTER SHORT OO;Ll;0;L;;;;;N;;;1040B;;1040B
+10434;DESERET SMALL LETTER AY;Ll;0;L;;;;;N;;;1040C;;1040C
+10435;DESERET SMALL LETTER OW;Ll;0;L;;;;;N;;;1040D;;1040D
+10436;DESERET SMALL LETTER WU;Ll;0;L;;;;;N;;;1040E;;1040E
+10437;DESERET SMALL LETTER YEE;Ll;0;L;;;;;N;;;1040F;;1040F
+10438;DESERET SMALL LETTER H;Ll;0;L;;;;;N;;;10410;;10410
+10439;DESERET SMALL LETTER PEE;Ll;0;L;;;;;N;;;10411;;10411
+1043A;DESERET SMALL LETTER BEE;Ll;0;L;;;;;N;;;10412;;10412
+1043B;DESERET SMALL LETTER TEE;Ll;0;L;;;;;N;;;10413;;10413
+1043C;DESERET SMALL LETTER DEE;Ll;0;L;;;;;N;;;10414;;10414
+1043D;DESERET SMALL LETTER CHEE;Ll;0;L;;;;;N;;;10415;;10415
+1043E;DESERET SMALL LETTER JEE;Ll;0;L;;;;;N;;;10416;;10416
+1043F;DESERET SMALL LETTER KAY;Ll;0;L;;;;;N;;;10417;;10417
+10440;DESERET SMALL LETTER GAY;Ll;0;L;;;;;N;;;10418;;10418
+10441;DESERET SMALL LETTER EF;Ll;0;L;;;;;N;;;10419;;10419
+10442;DESERET SMALL LETTER VEE;Ll;0;L;;;;;N;;;1041A;;1041A
+10443;DESERET SMALL LETTER ETH;Ll;0;L;;;;;N;;;1041B;;1041B
+10444;DESERET SMALL LETTER THEE;Ll;0;L;;;;;N;;;1041C;;1041C
+10445;DESERET SMALL LETTER ES;Ll;0;L;;;;;N;;;1041D;;1041D
+10446;DESERET SMALL LETTER ZEE;Ll;0;L;;;;;N;;;1041E;;1041E
+10447;DESERET SMALL LETTER ESH;Ll;0;L;;;;;N;;;1041F;;1041F
+10448;DESERET SMALL LETTER ZHEE;Ll;0;L;;;;;N;;;10420;;10420
+10449;DESERET SMALL LETTER ER;Ll;0;L;;;;;N;;;10421;;10421
+1044A;DESERET SMALL LETTER EL;Ll;0;L;;;;;N;;;10422;;10422
+1044B;DESERET SMALL LETTER EM;Ll;0;L;;;;;N;;;10423;;10423
+1044C;DESERET SMALL LETTER EN;Ll;0;L;;;;;N;;;10424;;10424
+1044D;DESERET SMALL LETTER ENG;Ll;0;L;;;;;N;;;10425;;10425
+1044E;DESERET SMALL LETTER OI;Ll;0;L;;;;;N;;;10426;;10426
+1044F;DESERET SMALL LETTER EW;Ll;0;L;;;;;N;;;10427;;10427
+10450;SHAVIAN LETTER PEEP;Lo;0;L;;;;;N;;;;;
+10451;SHAVIAN LETTER TOT;Lo;0;L;;;;;N;;;;;
+10452;SHAVIAN LETTER KICK;Lo;0;L;;;;;N;;;;;
+10453;SHAVIAN LETTER FEE;Lo;0;L;;;;;N;;;;;
+10454;SHAVIAN LETTER THIGH;Lo;0;L;;;;;N;;;;;
+10455;SHAVIAN LETTER SO;Lo;0;L;;;;;N;;;;;
+10456;SHAVIAN LETTER SURE;Lo;0;L;;;;;N;;;;;
+10457;SHAVIAN LETTER CHURCH;Lo;0;L;;;;;N;;;;;
+10458;SHAVIAN LETTER YEA;Lo;0;L;;;;;N;;;;;
+10459;SHAVIAN LETTER HUNG;Lo;0;L;;;;;N;;;;;
+1045A;SHAVIAN LETTER BIB;Lo;0;L;;;;;N;;;;;
+1045B;SHAVIAN LETTER DEAD;Lo;0;L;;;;;N;;;;;
+1045C;SHAVIAN LETTER GAG;Lo;0;L;;;;;N;;;;;
+1045D;SHAVIAN LETTER VOW;Lo;0;L;;;;;N;;;;;
+1045E;SHAVIAN LETTER THEY;Lo;0;L;;;;;N;;;;;
+1045F;SHAVIAN LETTER ZOO;Lo;0;L;;;;;N;;;;;
+10460;SHAVIAN LETTER MEASURE;Lo;0;L;;;;;N;;;;;
+10461;SHAVIAN LETTER JUDGE;Lo;0;L;;;;;N;;;;;
+10462;SHAVIAN LETTER WOE;Lo;0;L;;;;;N;;;;;
+10463;SHAVIAN LETTER HA-HA;Lo;0;L;;;;;N;;;;;
+10464;SHAVIAN LETTER LOLL;Lo;0;L;;;;;N;;;;;
+10465;SHAVIAN LETTER MIME;Lo;0;L;;;;;N;;;;;
+10466;SHAVIAN LETTER IF;Lo;0;L;;;;;N;;;;;
+10467;SHAVIAN LETTER EGG;Lo;0;L;;;;;N;;;;;
+10468;SHAVIAN LETTER ASH;Lo;0;L;;;;;N;;;;;
+10469;SHAVIAN LETTER ADO;Lo;0;L;;;;;N;;;;;
+1046A;SHAVIAN LETTER ON;Lo;0;L;;;;;N;;;;;
+1046B;SHAVIAN LETTER WOOL;Lo;0;L;;;;;N;;;;;
+1046C;SHAVIAN LETTER OUT;Lo;0;L;;;;;N;;;;;
+1046D;SHAVIAN LETTER AH;Lo;0;L;;;;;N;;;;;
+1046E;SHAVIAN LETTER ROAR;Lo;0;L;;;;;N;;;;;
+1046F;SHAVIAN LETTER NUN;Lo;0;L;;;;;N;;;;;
+10470;SHAVIAN LETTER EAT;Lo;0;L;;;;;N;;;;;
+10471;SHAVIAN LETTER AGE;Lo;0;L;;;;;N;;;;;
+10472;SHAVIAN LETTER ICE;Lo;0;L;;;;;N;;;;;
+10473;SHAVIAN LETTER UP;Lo;0;L;;;;;N;;;;;
+10474;SHAVIAN LETTER OAK;Lo;0;L;;;;;N;;;;;
+10475;SHAVIAN LETTER OOZE;Lo;0;L;;;;;N;;;;;
+10476;SHAVIAN LETTER OIL;Lo;0;L;;;;;N;;;;;
+10477;SHAVIAN LETTER AWE;Lo;0;L;;;;;N;;;;;
+10478;SHAVIAN LETTER ARE;Lo;0;L;;;;;N;;;;;
+10479;SHAVIAN LETTER OR;Lo;0;L;;;;;N;;;;;
+1047A;SHAVIAN LETTER AIR;Lo;0;L;;;;;N;;;;;
+1047B;SHAVIAN LETTER ERR;Lo;0;L;;;;;N;;;;;
+1047C;SHAVIAN LETTER ARRAY;Lo;0;L;;;;;N;;;;;
+1047D;SHAVIAN LETTER EAR;Lo;0;L;;;;;N;;;;;
+1047E;SHAVIAN LETTER IAN;Lo;0;L;;;;;N;;;;;
+1047F;SHAVIAN LETTER YEW;Lo;0;L;;;;;N;;;;;
+10480;OSMANYA LETTER ALEF;Lo;0;L;;;;;N;;;;;
+10481;OSMANYA LETTER BA;Lo;0;L;;;;;N;;;;;
+10482;OSMANYA LETTER TA;Lo;0;L;;;;;N;;;;;
+10483;OSMANYA LETTER JA;Lo;0;L;;;;;N;;;;;
+10484;OSMANYA LETTER XA;Lo;0;L;;;;;N;;;;;
+10485;OSMANYA LETTER KHA;Lo;0;L;;;;;N;;;;;
+10486;OSMANYA LETTER DEEL;Lo;0;L;;;;;N;;;;;
+10487;OSMANYA LETTER RA;Lo;0;L;;;;;N;;;;;
+10488;OSMANYA LETTER SA;Lo;0;L;;;;;N;;;;;
+10489;OSMANYA LETTER SHIIN;Lo;0;L;;;;;N;;;;;
+1048A;OSMANYA LETTER DHA;Lo;0;L;;;;;N;;;;;
+1048B;OSMANYA LETTER CAYN;Lo;0;L;;;;;N;;;;;
+1048C;OSMANYA LETTER GA;Lo;0;L;;;;;N;;;;;
+1048D;OSMANYA LETTER FA;Lo;0;L;;;;;N;;;;;
+1048E;OSMANYA LETTER QAAF;Lo;0;L;;;;;N;;;;;
+1048F;OSMANYA LETTER KAAF;Lo;0;L;;;;;N;;;;;
+10490;OSMANYA LETTER LAAN;Lo;0;L;;;;;N;;;;;
+10491;OSMANYA LETTER MIIN;Lo;0;L;;;;;N;;;;;
+10492;OSMANYA LETTER NUUN;Lo;0;L;;;;;N;;;;;
+10493;OSMANYA LETTER WAW;Lo;0;L;;;;;N;;;;;
+10494;OSMANYA LETTER HA;Lo;0;L;;;;;N;;;;;
+10495;OSMANYA LETTER YA;Lo;0;L;;;;;N;;;;;
+10496;OSMANYA LETTER A;Lo;0;L;;;;;N;;;;;
+10497;OSMANYA LETTER E;Lo;0;L;;;;;N;;;;;
+10498;OSMANYA LETTER I;Lo;0;L;;;;;N;;;;;
+10499;OSMANYA LETTER O;Lo;0;L;;;;;N;;;;;
+1049A;OSMANYA LETTER U;Lo;0;L;;;;;N;;;;;
+1049B;OSMANYA LETTER AA;Lo;0;L;;;;;N;;;;;
+1049C;OSMANYA LETTER EE;Lo;0;L;;;;;N;;;;;
+1049D;OSMANYA LETTER OO;Lo;0;L;;;;;N;;;;;
+104A0;OSMANYA DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+104A1;OSMANYA DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+104A2;OSMANYA DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+104A3;OSMANYA DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+104A4;OSMANYA DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+104A5;OSMANYA DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+104A6;OSMANYA DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+104A7;OSMANYA DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+104A8;OSMANYA DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+104A9;OSMANYA DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+10800;CYPRIOT SYLLABLE A;Lo;0;R;;;;;N;;;;;
+10801;CYPRIOT SYLLABLE E;Lo;0;R;;;;;N;;;;;
+10802;CYPRIOT SYLLABLE I;Lo;0;R;;;;;N;;;;;
+10803;CYPRIOT SYLLABLE O;Lo;0;R;;;;;N;;;;;
+10804;CYPRIOT SYLLABLE U;Lo;0;R;;;;;N;;;;;
+10805;CYPRIOT SYLLABLE JA;Lo;0;R;;;;;N;;;;;
+10808;CYPRIOT SYLLABLE JO;Lo;0;R;;;;;N;;;;;
+1080A;CYPRIOT SYLLABLE KA;Lo;0;R;;;;;N;;;;;
+1080B;CYPRIOT SYLLABLE KE;Lo;0;R;;;;;N;;;;;
+1080C;CYPRIOT SYLLABLE KI;Lo;0;R;;;;;N;;;;;
+1080D;CYPRIOT SYLLABLE KO;Lo;0;R;;;;;N;;;;;
+1080E;CYPRIOT SYLLABLE KU;Lo;0;R;;;;;N;;;;;
+1080F;CYPRIOT SYLLABLE LA;Lo;0;R;;;;;N;;;;;
+10810;CYPRIOT SYLLABLE LE;Lo;0;R;;;;;N;;;;;
+10811;CYPRIOT SYLLABLE LI;Lo;0;R;;;;;N;;;;;
+10812;CYPRIOT SYLLABLE LO;Lo;0;R;;;;;N;;;;;
+10813;CYPRIOT SYLLABLE LU;Lo;0;R;;;;;N;;;;;
+10814;CYPRIOT SYLLABLE MA;Lo;0;R;;;;;N;;;;;
+10815;CYPRIOT SYLLABLE ME;Lo;0;R;;;;;N;;;;;
+10816;CYPRIOT SYLLABLE MI;Lo;0;R;;;;;N;;;;;
+10817;CYPRIOT SYLLABLE MO;Lo;0;R;;;;;N;;;;;
+10818;CYPRIOT SYLLABLE MU;Lo;0;R;;;;;N;;;;;
+10819;CYPRIOT SYLLABLE NA;Lo;0;R;;;;;N;;;;;
+1081A;CYPRIOT SYLLABLE NE;Lo;0;R;;;;;N;;;;;
+1081B;CYPRIOT SYLLABLE NI;Lo;0;R;;;;;N;;;;;
+1081C;CYPRIOT SYLLABLE NO;Lo;0;R;;;;;N;;;;;
+1081D;CYPRIOT SYLLABLE NU;Lo;0;R;;;;;N;;;;;
+1081E;CYPRIOT SYLLABLE PA;Lo;0;R;;;;;N;;;;;
+1081F;CYPRIOT SYLLABLE PE;Lo;0;R;;;;;N;;;;;
+10820;CYPRIOT SYLLABLE PI;Lo;0;R;;;;;N;;;;;
+10821;CYPRIOT SYLLABLE PO;Lo;0;R;;;;;N;;;;;
+10822;CYPRIOT SYLLABLE PU;Lo;0;R;;;;;N;;;;;
+10823;CYPRIOT SYLLABLE RA;Lo;0;R;;;;;N;;;;;
+10824;CYPRIOT SYLLABLE RE;Lo;0;R;;;;;N;;;;;
+10825;CYPRIOT SYLLABLE RI;Lo;0;R;;;;;N;;;;;
+10826;CYPRIOT SYLLABLE RO;Lo;0;R;;;;;N;;;;;
+10827;CYPRIOT SYLLABLE RU;Lo;0;R;;;;;N;;;;;
+10828;CYPRIOT SYLLABLE SA;Lo;0;R;;;;;N;;;;;
+10829;CYPRIOT SYLLABLE SE;Lo;0;R;;;;;N;;;;;
+1082A;CYPRIOT SYLLABLE SI;Lo;0;R;;;;;N;;;;;
+1082B;CYPRIOT SYLLABLE SO;Lo;0;R;;;;;N;;;;;
+1082C;CYPRIOT SYLLABLE SU;Lo;0;R;;;;;N;;;;;
+1082D;CYPRIOT SYLLABLE TA;Lo;0;R;;;;;N;;;;;
+1082E;CYPRIOT SYLLABLE TE;Lo;0;R;;;;;N;;;;;
+1082F;CYPRIOT SYLLABLE TI;Lo;0;R;;;;;N;;;;;
+10830;CYPRIOT SYLLABLE TO;Lo;0;R;;;;;N;;;;;
+10831;CYPRIOT SYLLABLE TU;Lo;0;R;;;;;N;;;;;
+10832;CYPRIOT SYLLABLE WA;Lo;0;R;;;;;N;;;;;
+10833;CYPRIOT SYLLABLE WE;Lo;0;R;;;;;N;;;;;
+10834;CYPRIOT SYLLABLE WI;Lo;0;R;;;;;N;;;;;
+10835;CYPRIOT SYLLABLE WO;Lo;0;R;;;;;N;;;;;
+10837;CYPRIOT SYLLABLE XA;Lo;0;R;;;;;N;;;;;
+10838;CYPRIOT SYLLABLE XE;Lo;0;R;;;;;N;;;;;
+1083C;CYPRIOT SYLLABLE ZA;Lo;0;R;;;;;N;;;;;
+1083F;CYPRIOT SYLLABLE ZO;Lo;0;R;;;;;N;;;;;
+10840;IMPERIAL ARAMAIC LETTER ALEPH;Lo;0;R;;;;;N;;;;;
+10841;IMPERIAL ARAMAIC LETTER BETH;Lo;0;R;;;;;N;;;;;
+10842;IMPERIAL ARAMAIC LETTER GIMEL;Lo;0;R;;;;;N;;;;;
+10843;IMPERIAL ARAMAIC LETTER DALETH;Lo;0;R;;;;;N;;;;;
+10844;IMPERIAL ARAMAIC LETTER HE;Lo;0;R;;;;;N;;;;;
+10845;IMPERIAL ARAMAIC LETTER WAW;Lo;0;R;;;;;N;;;;;
+10846;IMPERIAL ARAMAIC LETTER ZAYIN;Lo;0;R;;;;;N;;;;;
+10847;IMPERIAL ARAMAIC LETTER HETH;Lo;0;R;;;;;N;;;;;
+10848;IMPERIAL ARAMAIC LETTER TETH;Lo;0;R;;;;;N;;;;;
+10849;IMPERIAL ARAMAIC LETTER YODH;Lo;0;R;;;;;N;;;;;
+1084A;IMPERIAL ARAMAIC LETTER KAPH;Lo;0;R;;;;;N;;;;;
+1084B;IMPERIAL ARAMAIC LETTER LAMEDH;Lo;0;R;;;;;N;;;;;
+1084C;IMPERIAL ARAMAIC LETTER MEM;Lo;0;R;;;;;N;;;;;
+1084D;IMPERIAL ARAMAIC LETTER NUN;Lo;0;R;;;;;N;;;;;
+1084E;IMPERIAL ARAMAIC LETTER SAMEKH;Lo;0;R;;;;;N;;;;;
+1084F;IMPERIAL ARAMAIC LETTER AYIN;Lo;0;R;;;;;N;;;;;
+10850;IMPERIAL ARAMAIC LETTER PE;Lo;0;R;;;;;N;;;;;
+10851;IMPERIAL ARAMAIC LETTER SADHE;Lo;0;R;;;;;N;;;;;
+10852;IMPERIAL ARAMAIC LETTER QOPH;Lo;0;R;;;;;N;;;;;
+10853;IMPERIAL ARAMAIC LETTER RESH;Lo;0;R;;;;;N;;;;;
+10854;IMPERIAL ARAMAIC LETTER SHIN;Lo;0;R;;;;;N;;;;;
+10855;IMPERIAL ARAMAIC LETTER TAW;Lo;0;R;;;;;N;;;;;
+10857;IMPERIAL ARAMAIC SECTION SIGN;Po;0;R;;;;;N;;;;;
+10858;IMPERIAL ARAMAIC NUMBER ONE;No;0;R;;;;1;N;;;;;
+10859;IMPERIAL ARAMAIC NUMBER TWO;No;0;R;;;;2;N;;;;;
+1085A;IMPERIAL ARAMAIC NUMBER THREE;No;0;R;;;;3;N;;;;;
+1085B;IMPERIAL ARAMAIC NUMBER TEN;No;0;R;;;;10;N;;;;;
+1085C;IMPERIAL ARAMAIC NUMBER TWENTY;No;0;R;;;;20;N;;;;;
+1085D;IMPERIAL ARAMAIC NUMBER ONE HUNDRED;No;0;R;;;;100;N;;;;;
+1085E;IMPERIAL ARAMAIC NUMBER ONE THOUSAND;No;0;R;;;;1000;N;;;;;
+1085F;IMPERIAL ARAMAIC NUMBER TEN THOUSAND;No;0;R;;;;10000;N;;;;;
+10900;PHOENICIAN LETTER ALF;Lo;0;R;;;;;N;;;;;
+10901;PHOENICIAN LETTER BET;Lo;0;R;;;;;N;;;;;
+10902;PHOENICIAN LETTER GAML;Lo;0;R;;;;;N;;;;;
+10903;PHOENICIAN LETTER DELT;Lo;0;R;;;;;N;;;;;
+10904;PHOENICIAN LETTER HE;Lo;0;R;;;;;N;;;;;
+10905;PHOENICIAN LETTER WAU;Lo;0;R;;;;;N;;;;;
+10906;PHOENICIAN LETTER ZAI;Lo;0;R;;;;;N;;;;;
+10907;PHOENICIAN LETTER HET;Lo;0;R;;;;;N;;;;;
+10908;PHOENICIAN LETTER TET;Lo;0;R;;;;;N;;;;;
+10909;PHOENICIAN LETTER YOD;Lo;0;R;;;;;N;;;;;
+1090A;PHOENICIAN LETTER KAF;Lo;0;R;;;;;N;;;;;
+1090B;PHOENICIAN LETTER LAMD;Lo;0;R;;;;;N;;;;;
+1090C;PHOENICIAN LETTER MEM;Lo;0;R;;;;;N;;;;;
+1090D;PHOENICIAN LETTER NUN;Lo;0;R;;;;;N;;;;;
+1090E;PHOENICIAN LETTER SEMK;Lo;0;R;;;;;N;;;;;
+1090F;PHOENICIAN LETTER AIN;Lo;0;R;;;;;N;;;;;
+10910;PHOENICIAN LETTER PE;Lo;0;R;;;;;N;;;;;
+10911;PHOENICIAN LETTER SADE;Lo;0;R;;;;;N;;;;;
+10912;PHOENICIAN LETTER QOF;Lo;0;R;;;;;N;;;;;
+10913;PHOENICIAN LETTER ROSH;Lo;0;R;;;;;N;;;;;
+10914;PHOENICIAN LETTER SHIN;Lo;0;R;;;;;N;;;;;
+10915;PHOENICIAN LETTER TAU;Lo;0;R;;;;;N;;;;;
+10916;PHOENICIAN NUMBER ONE;No;0;R;;;;1;N;;;;;
+10917;PHOENICIAN NUMBER TEN;No;0;R;;;;10;N;;;;;
+10918;PHOENICIAN NUMBER TWENTY;No;0;R;;;;20;N;;;;;
+10919;PHOENICIAN NUMBER ONE HUNDRED;No;0;R;;;;100;N;;;;;
+1091A;PHOENICIAN NUMBER TWO;No;0;R;;;;2;N;;;;;
+1091B;PHOENICIAN NUMBER THREE;No;0;R;;;;3;N;;;;;
+1091F;PHOENICIAN WORD SEPARATOR;Po;0;ON;;;;;N;;;;;
+10920;LYDIAN LETTER A;Lo;0;R;;;;;N;;;;;
+10921;LYDIAN LETTER B;Lo;0;R;;;;;N;;;;;
+10922;LYDIAN LETTER G;Lo;0;R;;;;;N;;;;;
+10923;LYDIAN LETTER D;Lo;0;R;;;;;N;;;;;
+10924;LYDIAN LETTER E;Lo;0;R;;;;;N;;;;;
+10925;LYDIAN LETTER V;Lo;0;R;;;;;N;;;;;
+10926;LYDIAN LETTER I;Lo;0;R;;;;;N;;;;;
+10927;LYDIAN LETTER Y;Lo;0;R;;;;;N;;;;;
+10928;LYDIAN LETTER K;Lo;0;R;;;;;N;;;;;
+10929;LYDIAN LETTER L;Lo;0;R;;;;;N;;;;;
+1092A;LYDIAN LETTER M;Lo;0;R;;;;;N;;;;;
+1092B;LYDIAN LETTER N;Lo;0;R;;;;;N;;;;;
+1092C;LYDIAN LETTER O;Lo;0;R;;;;;N;;;;;
+1092D;LYDIAN LETTER R;Lo;0;R;;;;;N;;;;;
+1092E;LYDIAN LETTER SS;Lo;0;R;;;;;N;;;;;
+1092F;LYDIAN LETTER T;Lo;0;R;;;;;N;;;;;
+10930;LYDIAN LETTER U;Lo;0;R;;;;;N;;;;;
+10931;LYDIAN LETTER F;Lo;0;R;;;;;N;;;;;
+10932;LYDIAN LETTER Q;Lo;0;R;;;;;N;;;;;
+10933;LYDIAN LETTER S;Lo;0;R;;;;;N;;;;;
+10934;LYDIAN LETTER TT;Lo;0;R;;;;;N;;;;;
+10935;LYDIAN LETTER AN;Lo;0;R;;;;;N;;;;;
+10936;LYDIAN LETTER EN;Lo;0;R;;;;;N;;;;;
+10937;LYDIAN LETTER LY;Lo;0;R;;;;;N;;;;;
+10938;LYDIAN LETTER NN;Lo;0;R;;;;;N;;;;;
+10939;LYDIAN LETTER C;Lo;0;R;;;;;N;;;;;
+1093F;LYDIAN TRIANGULAR MARK;Po;0;R;;;;;N;;;;;
+10A00;KHAROSHTHI LETTER A;Lo;0;R;;;;;N;;;;;
+10A01;KHAROSHTHI VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;
+10A02;KHAROSHTHI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+10A03;KHAROSHTHI VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;;
+10A05;KHAROSHTHI VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;;
+10A06;KHAROSHTHI VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;;
+10A0C;KHAROSHTHI VOWEL LENGTH MARK;Mn;0;NSM;;;;;N;;;;;
+10A0D;KHAROSHTHI SIGN DOUBLE RING BELOW;Mn;220;NSM;;;;;N;;;;;
+10A0E;KHAROSHTHI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;
+10A0F;KHAROSHTHI SIGN VISARGA;Mn;230;NSM;;;;;N;;;;;
+10A10;KHAROSHTHI LETTER KA;Lo;0;R;;;;;N;;;;;
+10A11;KHAROSHTHI LETTER KHA;Lo;0;R;;;;;N;;;;;
+10A12;KHAROSHTHI LETTER GA;Lo;0;R;;;;;N;;;;;
+10A13;KHAROSHTHI LETTER GHA;Lo;0;R;;;;;N;;;;;
+10A15;KHAROSHTHI LETTER CA;Lo;0;R;;;;;N;;;;;
+10A16;KHAROSHTHI LETTER CHA;Lo;0;R;;;;;N;;;;;
+10A17;KHAROSHTHI LETTER JA;Lo;0;R;;;;;N;;;;;
+10A19;KHAROSHTHI LETTER NYA;Lo;0;R;;;;;N;;;;;
+10A1A;KHAROSHTHI LETTER TTA;Lo;0;R;;;;;N;;;;;
+10A1B;KHAROSHTHI LETTER TTHA;Lo;0;R;;;;;N;;;;;
+10A1C;KHAROSHTHI LETTER DDA;Lo;0;R;;;;;N;;;;;
+10A1D;KHAROSHTHI LETTER DDHA;Lo;0;R;;;;;N;;;;;
+10A1E;KHAROSHTHI LETTER NNA;Lo;0;R;;;;;N;;;;;
+10A1F;KHAROSHTHI LETTER TA;Lo;0;R;;;;;N;;;;;
+10A20;KHAROSHTHI LETTER THA;Lo;0;R;;;;;N;;;;;
+10A21;KHAROSHTHI LETTER DA;Lo;0;R;;;;;N;;;;;
+10A22;KHAROSHTHI LETTER DHA;Lo;0;R;;;;;N;;;;;
+10A23;KHAROSHTHI LETTER NA;Lo;0;R;;;;;N;;;;;
+10A24;KHAROSHTHI LETTER PA;Lo;0;R;;;;;N;;;;;
+10A25;KHAROSHTHI LETTER PHA;Lo;0;R;;;;;N;;;;;
+10A26;KHAROSHTHI LETTER BA;Lo;0;R;;;;;N;;;;;
+10A27;KHAROSHTHI LETTER BHA;Lo;0;R;;;;;N;;;;;
+10A28;KHAROSHTHI LETTER MA;Lo;0;R;;;;;N;;;;;
+10A29;KHAROSHTHI LETTER YA;Lo;0;R;;;;;N;;;;;
+10A2A;KHAROSHTHI LETTER RA;Lo;0;R;;;;;N;;;;;
+10A2B;KHAROSHTHI LETTER LA;Lo;0;R;;;;;N;;;;;
+10A2C;KHAROSHTHI LETTER VA;Lo;0;R;;;;;N;;;;;
+10A2D;KHAROSHTHI LETTER SHA;Lo;0;R;;;;;N;;;;;
+10A2E;KHAROSHTHI LETTER SSA;Lo;0;R;;;;;N;;;;;
+10A2F;KHAROSHTHI LETTER SA;Lo;0;R;;;;;N;;;;;
+10A30;KHAROSHTHI LETTER ZA;Lo;0;R;;;;;N;;;;;
+10A31;KHAROSHTHI LETTER HA;Lo;0;R;;;;;N;;;;;
+10A32;KHAROSHTHI LETTER KKA;Lo;0;R;;;;;N;;;;;
+10A33;KHAROSHTHI LETTER TTTHA;Lo;0;R;;;;;N;;;;;
+10A38;KHAROSHTHI SIGN BAR ABOVE;Mn;230;NSM;;;;;N;;;;;
+10A39;KHAROSHTHI SIGN CAUDA;Mn;1;NSM;;;;;N;;;;;
+10A3A;KHAROSHTHI SIGN DOT BELOW;Mn;220;NSM;;;;;N;;;;;
+10A3F;KHAROSHTHI VIRAMA;Mn;9;NSM;;;;;N;;;;;
+10A40;KHAROSHTHI DIGIT ONE;No;0;R;;;1;1;N;;;;;
+10A41;KHAROSHTHI DIGIT TWO;No;0;R;;;2;2;N;;;;;
+10A42;KHAROSHTHI DIGIT THREE;No;0;R;;;3;3;N;;;;;
+10A43;KHAROSHTHI DIGIT FOUR;No;0;R;;;4;4;N;;;;;
+10A44;KHAROSHTHI NUMBER TEN;No;0;R;;;;10;N;;;;;
+10A45;KHAROSHTHI NUMBER TWENTY;No;0;R;;;;20;N;;;;;
+10A46;KHAROSHTHI NUMBER ONE HUNDRED;No;0;R;;;;100;N;;;;;
+10A47;KHAROSHTHI NUMBER ONE THOUSAND;No;0;R;;;;1000;N;;;;;
+10A50;KHAROSHTHI PUNCTUATION DOT;Po;0;R;;;;;N;;;;;
+10A51;KHAROSHTHI PUNCTUATION SMALL CIRCLE;Po;0;R;;;;;N;;;;;
+10A52;KHAROSHTHI PUNCTUATION CIRCLE;Po;0;R;;;;;N;;;;;
+10A53;KHAROSHTHI PUNCTUATION CRESCENT BAR;Po;0;R;;;;;N;;;;;
+10A54;KHAROSHTHI PUNCTUATION MANGALAM;Po;0;R;;;;;N;;;;;
+10A55;KHAROSHTHI PUNCTUATION LOTUS;Po;0;R;;;;;N;;;;;
+10A56;KHAROSHTHI PUNCTUATION DANDA;Po;0;R;;;;;N;;;;;
+10A57;KHAROSHTHI PUNCTUATION DOUBLE DANDA;Po;0;R;;;;;N;;;;;
+10A58;KHAROSHTHI PUNCTUATION LINES;Po;0;R;;;;;N;;;;;
+10A60;OLD SOUTH ARABIAN LETTER HE;Lo;0;R;;;;;N;;;;;
+10A61;OLD SOUTH ARABIAN LETTER LAMEDH;Lo;0;R;;;;;N;;;;;
+10A62;OLD SOUTH ARABIAN LETTER HETH;Lo;0;R;;;;;N;;;;;
+10A63;OLD SOUTH ARABIAN LETTER MEM;Lo;0;R;;;;;N;;;;;
+10A64;OLD SOUTH ARABIAN LETTER QOPH;Lo;0;R;;;;;N;;;;;
+10A65;OLD SOUTH ARABIAN LETTER WAW;Lo;0;R;;;;;N;;;;;
+10A66;OLD SOUTH ARABIAN LETTER SHIN;Lo;0;R;;;;;N;;;;;
+10A67;OLD SOUTH ARABIAN LETTER RESH;Lo;0;R;;;;;N;;;;;
+10A68;OLD SOUTH ARABIAN LETTER BETH;Lo;0;R;;;;;N;;;;;
+10A69;OLD SOUTH ARABIAN LETTER TAW;Lo;0;R;;;;;N;;;;;
+10A6A;OLD SOUTH ARABIAN LETTER SAT;Lo;0;R;;;;;N;;;;;
+10A6B;OLD SOUTH ARABIAN LETTER KAPH;Lo;0;R;;;;;N;;;;;
+10A6C;OLD SOUTH ARABIAN LETTER NUN;Lo;0;R;;;;;N;;;;;
+10A6D;OLD SOUTH ARABIAN LETTER KHETH;Lo;0;R;;;;;N;;;;;
+10A6E;OLD SOUTH ARABIAN LETTER SADHE;Lo;0;R;;;;;N;;;;;
+10A6F;OLD SOUTH ARABIAN LETTER SAMEKH;Lo;0;R;;;;;N;;;;;
+10A70;OLD SOUTH ARABIAN LETTER FE;Lo;0;R;;;;;N;;;;;
+10A71;OLD SOUTH ARABIAN LETTER ALEF;Lo;0;R;;;;;N;;;;;
+10A72;OLD SOUTH ARABIAN LETTER AYN;Lo;0;R;;;;;N;;;;;
+10A73;OLD SOUTH ARABIAN LETTER DHADHE;Lo;0;R;;;;;N;;;;;
+10A74;OLD SOUTH ARABIAN LETTER GIMEL;Lo;0;R;;;;;N;;;;;
+10A75;OLD SOUTH ARABIAN LETTER DALETH;Lo;0;R;;;;;N;;;;;
+10A76;OLD SOUTH ARABIAN LETTER GHAYN;Lo;0;R;;;;;N;;;;;
+10A77;OLD SOUTH ARABIAN LETTER TETH;Lo;0;R;;;;;N;;;;;
+10A78;OLD SOUTH ARABIAN LETTER ZAYN;Lo;0;R;;;;;N;;;;;
+10A79;OLD SOUTH ARABIAN LETTER DHALETH;Lo;0;R;;;;;N;;;;;
+10A7A;OLD SOUTH ARABIAN LETTER YODH;Lo;0;R;;;;;N;;;;;
+10A7B;OLD SOUTH ARABIAN LETTER THAW;Lo;0;R;;;;;N;;;;;
+10A7C;OLD SOUTH ARABIAN LETTER THETH;Lo;0;R;;;;;N;;;;;
+10A7D;OLD SOUTH ARABIAN NUMBER ONE;No;0;R;;;;1;N;;;;;
+10A7E;OLD SOUTH ARABIAN NUMBER FIFTY;No;0;R;;;;50;N;;;;;
+10A7F;OLD SOUTH ARABIAN NUMERIC INDICATOR;Po;0;R;;;;;N;;;;;
+10B00;AVESTAN LETTER A;Lo;0;R;;;;;N;;;;;
+10B01;AVESTAN LETTER AA;Lo;0;R;;;;;N;;;;;
+10B02;AVESTAN LETTER AO;Lo;0;R;;;;;N;;;;;
+10B03;AVESTAN LETTER AAO;Lo;0;R;;;;;N;;;;;
+10B04;AVESTAN LETTER AN;Lo;0;R;;;;;N;;;;;
+10B05;AVESTAN LETTER AAN;Lo;0;R;;;;;N;;;;;
+10B06;AVESTAN LETTER AE;Lo;0;R;;;;;N;;;;;
+10B07;AVESTAN LETTER AEE;Lo;0;R;;;;;N;;;;;
+10B08;AVESTAN LETTER E;Lo;0;R;;;;;N;;;;;
+10B09;AVESTAN LETTER EE;Lo;0;R;;;;;N;;;;;
+10B0A;AVESTAN LETTER O;Lo;0;R;;;;;N;;;;;
+10B0B;AVESTAN LETTER OO;Lo;0;R;;;;;N;;;;;
+10B0C;AVESTAN LETTER I;Lo;0;R;;;;;N;;;;;
+10B0D;AVESTAN LETTER II;Lo;0;R;;;;;N;;;;;
+10B0E;AVESTAN LETTER U;Lo;0;R;;;;;N;;;;;
+10B0F;AVESTAN LETTER UU;Lo;0;R;;;;;N;;;;;
+10B10;AVESTAN LETTER KE;Lo;0;R;;;;;N;;;;;
+10B11;AVESTAN LETTER XE;Lo;0;R;;;;;N;;;;;
+10B12;AVESTAN LETTER XYE;Lo;0;R;;;;;N;;;;;
+10B13;AVESTAN LETTER XVE;Lo;0;R;;;;;N;;;;;
+10B14;AVESTAN LETTER GE;Lo;0;R;;;;;N;;;;;
+10B15;AVESTAN LETTER GGE;Lo;0;R;;;;;N;;;;;
+10B16;AVESTAN LETTER GHE;Lo;0;R;;;;;N;;;;;
+10B17;AVESTAN LETTER CE;Lo;0;R;;;;;N;;;;;
+10B18;AVESTAN LETTER JE;Lo;0;R;;;;;N;;;;;
+10B19;AVESTAN LETTER TE;Lo;0;R;;;;;N;;;;;
+10B1A;AVESTAN LETTER THE;Lo;0;R;;;;;N;;;;;
+10B1B;AVESTAN LETTER DE;Lo;0;R;;;;;N;;;;;
+10B1C;AVESTAN LETTER DHE;Lo;0;R;;;;;N;;;;;
+10B1D;AVESTAN LETTER TTE;Lo;0;R;;;;;N;;;;;
+10B1E;AVESTAN LETTER PE;Lo;0;R;;;;;N;;;;;
+10B1F;AVESTAN LETTER FE;Lo;0;R;;;;;N;;;;;
+10B20;AVESTAN LETTER BE;Lo;0;R;;;;;N;;;;;
+10B21;AVESTAN LETTER BHE;Lo;0;R;;;;;N;;;;;
+10B22;AVESTAN LETTER NGE;Lo;0;R;;;;;N;;;;;
+10B23;AVESTAN LETTER NGYE;Lo;0;R;;;;;N;;;;;
+10B24;AVESTAN LETTER NGVE;Lo;0;R;;;;;N;;;;;
+10B25;AVESTAN LETTER NE;Lo;0;R;;;;;N;;;;;
+10B26;AVESTAN LETTER NYE;Lo;0;R;;;;;N;;;;;
+10B27;AVESTAN LETTER NNE;Lo;0;R;;;;;N;;;;;
+10B28;AVESTAN LETTER ME;Lo;0;R;;;;;N;;;;;
+10B29;AVESTAN LETTER HME;Lo;0;R;;;;;N;;;;;
+10B2A;AVESTAN LETTER YYE;Lo;0;R;;;;;N;;;;;
+10B2B;AVESTAN LETTER YE;Lo;0;R;;;;;N;;;;;
+10B2C;AVESTAN LETTER VE;Lo;0;R;;;;;N;;;;;
+10B2D;AVESTAN LETTER RE;Lo;0;R;;;;;N;;;;;
+10B2E;AVESTAN LETTER LE;Lo;0;R;;;;;N;;;;;
+10B2F;AVESTAN LETTER SE;Lo;0;R;;;;;N;;;;;
+10B30;AVESTAN LETTER ZE;Lo;0;R;;;;;N;;;;;
+10B31;AVESTAN LETTER SHE;Lo;0;R;;;;;N;;;;;
+10B32;AVESTAN LETTER ZHE;Lo;0;R;;;;;N;;;;;
+10B33;AVESTAN LETTER SHYE;Lo;0;R;;;;;N;;;;;
+10B34;AVESTAN LETTER SSHE;Lo;0;R;;;;;N;;;;;
+10B35;AVESTAN LETTER HE;Lo;0;R;;;;;N;;;;;
+10B39;AVESTAN ABBREVIATION MARK;Po;0;ON;;;;;N;;;;;
+10B3A;TINY TWO DOTS OVER ONE DOT PUNCTUATION;Po;0;ON;;;;;N;;;;;
+10B3B;SMALL TWO DOTS OVER ONE DOT PUNCTUATION;Po;0;ON;;;;;N;;;;;
+10B3C;LARGE TWO DOTS OVER ONE DOT PUNCTUATION;Po;0;ON;;;;;N;;;;;
+10B3D;LARGE ONE DOT OVER TWO DOTS PUNCTUATION;Po;0;ON;;;;;N;;;;;
+10B3E;LARGE TWO RINGS OVER ONE RING PUNCTUATION;Po;0;ON;;;;;N;;;;;
+10B3F;LARGE ONE RING OVER TWO RINGS PUNCTUATION;Po;0;ON;;;;;N;;;;;
+10B40;INSCRIPTIONAL PARTHIAN LETTER ALEPH;Lo;0;R;;;;;N;;;;;
+10B41;INSCRIPTIONAL PARTHIAN LETTER BETH;Lo;0;R;;;;;N;;;;;
+10B42;INSCRIPTIONAL PARTHIAN LETTER GIMEL;Lo;0;R;;;;;N;;;;;
+10B43;INSCRIPTIONAL PARTHIAN LETTER DALETH;Lo;0;R;;;;;N;;;;;
+10B44;INSCRIPTIONAL PARTHIAN LETTER HE;Lo;0;R;;;;;N;;;;;
+10B45;INSCRIPTIONAL PARTHIAN LETTER WAW;Lo;0;R;;;;;N;;;;;
+10B46;INSCRIPTIONAL PARTHIAN LETTER ZAYIN;Lo;0;R;;;;;N;;;;;
+10B47;INSCRIPTIONAL PARTHIAN LETTER HETH;Lo;0;R;;;;;N;;;;;
+10B48;INSCRIPTIONAL PARTHIAN LETTER TETH;Lo;0;R;;;;;N;;;;;
+10B49;INSCRIPTIONAL PARTHIAN LETTER YODH;Lo;0;R;;;;;N;;;;;
+10B4A;INSCRIPTIONAL PARTHIAN LETTER KAPH;Lo;0;R;;;;;N;;;;;
+10B4B;INSCRIPTIONAL PARTHIAN LETTER LAMEDH;Lo;0;R;;;;;N;;;;;
+10B4C;INSCRIPTIONAL PARTHIAN LETTER MEM;Lo;0;R;;;;;N;;;;;
+10B4D;INSCRIPTIONAL PARTHIAN LETTER NUN;Lo;0;R;;;;;N;;;;;
+10B4E;INSCRIPTIONAL PARTHIAN LETTER SAMEKH;Lo;0;R;;;;;N;;;;;
+10B4F;INSCRIPTIONAL PARTHIAN LETTER AYIN;Lo;0;R;;;;;N;;;;;
+10B50;INSCRIPTIONAL PARTHIAN LETTER PE;Lo;0;R;;;;;N;;;;;
+10B51;INSCRIPTIONAL PARTHIAN LETTER SADHE;Lo;0;R;;;;;N;;;;;
+10B52;INSCRIPTIONAL PARTHIAN LETTER QOPH;Lo;0;R;;;;;N;;;;;
+10B53;INSCRIPTIONAL PARTHIAN LETTER RESH;Lo;0;R;;;;;N;;;;;
+10B54;INSCRIPTIONAL PARTHIAN LETTER SHIN;Lo;0;R;;;;;N;;;;;
+10B55;INSCRIPTIONAL PARTHIAN LETTER TAW;Lo;0;R;;;;;N;;;;;
+10B58;INSCRIPTIONAL PARTHIAN NUMBER ONE;No;0;R;;;;1;N;;;;;
+10B59;INSCRIPTIONAL PARTHIAN NUMBER TWO;No;0;R;;;;2;N;;;;;
+10B5A;INSCRIPTIONAL PARTHIAN NUMBER THREE;No;0;R;;;;3;N;;;;;
+10B5B;INSCRIPTIONAL PARTHIAN NUMBER FOUR;No;0;R;;;;4;N;;;;;
+10B5C;INSCRIPTIONAL PARTHIAN NUMBER TEN;No;0;R;;;;10;N;;;;;
+10B5D;INSCRIPTIONAL PARTHIAN NUMBER TWENTY;No;0;R;;;;20;N;;;;;
+10B5E;INSCRIPTIONAL PARTHIAN NUMBER ONE HUNDRED;No;0;R;;;;100;N;;;;;
+10B5F;INSCRIPTIONAL PARTHIAN NUMBER ONE THOUSAND;No;0;R;;;;1000;N;;;;;
+10B60;INSCRIPTIONAL PAHLAVI LETTER ALEPH;Lo;0;R;;;;;N;;;;;
+10B61;INSCRIPTIONAL PAHLAVI LETTER BETH;Lo;0;R;;;;;N;;;;;
+10B62;INSCRIPTIONAL PAHLAVI LETTER GIMEL;Lo;0;R;;;;;N;;;;;
+10B63;INSCRIPTIONAL PAHLAVI LETTER DALETH;Lo;0;R;;;;;N;;;;;
+10B64;INSCRIPTIONAL PAHLAVI LETTER HE;Lo;0;R;;;;;N;;;;;
+10B65;INSCRIPTIONAL PAHLAVI LETTER WAW-AYIN-RESH;Lo;0;R;;;;;N;;;;;
+10B66;INSCRIPTIONAL PAHLAVI LETTER ZAYIN;Lo;0;R;;;;;N;;;;;
+10B67;INSCRIPTIONAL PAHLAVI LETTER HETH;Lo;0;R;;;;;N;;;;;
+10B68;INSCRIPTIONAL PAHLAVI LETTER TETH;Lo;0;R;;;;;N;;;;;
+10B69;INSCRIPTIONAL PAHLAVI LETTER YODH;Lo;0;R;;;;;N;;;;;
+10B6A;INSCRIPTIONAL PAHLAVI LETTER KAPH;Lo;0;R;;;;;N;;;;;
+10B6B;INSCRIPTIONAL PAHLAVI LETTER LAMEDH;Lo;0;R;;;;;N;;;;;
+10B6C;INSCRIPTIONAL PAHLAVI LETTER MEM-QOPH;Lo;0;R;;;;;N;;;;;
+10B6D;INSCRIPTIONAL PAHLAVI LETTER NUN;Lo;0;R;;;;;N;;;;;
+10B6E;INSCRIPTIONAL PAHLAVI LETTER SAMEKH;Lo;0;R;;;;;N;;;;;
+10B6F;INSCRIPTIONAL PAHLAVI LETTER PE;Lo;0;R;;;;;N;;;;;
+10B70;INSCRIPTIONAL PAHLAVI LETTER SADHE;Lo;0;R;;;;;N;;;;;
+10B71;INSCRIPTIONAL PAHLAVI LETTER SHIN;Lo;0;R;;;;;N;;;;;
+10B72;INSCRIPTIONAL PAHLAVI LETTER TAW;Lo;0;R;;;;;N;;;;;
+10B78;INSCRIPTIONAL PAHLAVI NUMBER ONE;No;0;R;;;;1;N;;;;;
+10B79;INSCRIPTIONAL PAHLAVI NUMBER TWO;No;0;R;;;;2;N;;;;;
+10B7A;INSCRIPTIONAL PAHLAVI NUMBER THREE;No;0;R;;;;3;N;;;;;
+10B7B;INSCRIPTIONAL PAHLAVI NUMBER FOUR;No;0;R;;;;4;N;;;;;
+10B7C;INSCRIPTIONAL PAHLAVI NUMBER TEN;No;0;R;;;;10;N;;;;;
+10B7D;INSCRIPTIONAL PAHLAVI NUMBER TWENTY;No;0;R;;;;20;N;;;;;
+10B7E;INSCRIPTIONAL PAHLAVI NUMBER ONE HUNDRED;No;0;R;;;;100;N;;;;;
+10B7F;INSCRIPTIONAL PAHLAVI NUMBER ONE THOUSAND;No;0;R;;;;1000;N;;;;;
+10C00;OLD TURKIC LETTER ORKHON A;Lo;0;R;;;;;N;;;;;
+10C01;OLD TURKIC LETTER YENISEI A;Lo;0;R;;;;;N;;;;;
+10C02;OLD TURKIC LETTER YENISEI AE;Lo;0;R;;;;;N;;;;;
+10C03;OLD TURKIC LETTER ORKHON I;Lo;0;R;;;;;N;;;;;
+10C04;OLD TURKIC LETTER YENISEI I;Lo;0;R;;;;;N;;;;;
+10C05;OLD TURKIC LETTER YENISEI E;Lo;0;R;;;;;N;;;;;
+10C06;OLD TURKIC LETTER ORKHON O;Lo;0;R;;;;;N;;;;;
+10C07;OLD TURKIC LETTER ORKHON OE;Lo;0;R;;;;;N;;;;;
+10C08;OLD TURKIC LETTER YENISEI OE;Lo;0;R;;;;;N;;;;;
+10C09;OLD TURKIC LETTER ORKHON AB;Lo;0;R;;;;;N;;;;;
+10C0A;OLD TURKIC LETTER YENISEI AB;Lo;0;R;;;;;N;;;;;
+10C0B;OLD TURKIC LETTER ORKHON AEB;Lo;0;R;;;;;N;;;;;
+10C0C;OLD TURKIC LETTER YENISEI AEB;Lo;0;R;;;;;N;;;;;
+10C0D;OLD TURKIC LETTER ORKHON AG;Lo;0;R;;;;;N;;;;;
+10C0E;OLD TURKIC LETTER YENISEI AG;Lo;0;R;;;;;N;;;;;
+10C0F;OLD TURKIC LETTER ORKHON AEG;Lo;0;R;;;;;N;;;;;
+10C10;OLD TURKIC LETTER YENISEI AEG;Lo;0;R;;;;;N;;;;;
+10C11;OLD TURKIC LETTER ORKHON AD;Lo;0;R;;;;;N;;;;;
+10C12;OLD TURKIC LETTER YENISEI AD;Lo;0;R;;;;;N;;;;;
+10C13;OLD TURKIC LETTER ORKHON AED;Lo;0;R;;;;;N;;;;;
+10C14;OLD TURKIC LETTER ORKHON EZ;Lo;0;R;;;;;N;;;;;
+10C15;OLD TURKIC LETTER YENISEI EZ;Lo;0;R;;;;;N;;;;;
+10C16;OLD TURKIC LETTER ORKHON AY;Lo;0;R;;;;;N;;;;;
+10C17;OLD TURKIC LETTER YENISEI AY;Lo;0;R;;;;;N;;;;;
+10C18;OLD TURKIC LETTER ORKHON AEY;Lo;0;R;;;;;N;;;;;
+10C19;OLD TURKIC LETTER YENISEI AEY;Lo;0;R;;;;;N;;;;;
+10C1A;OLD TURKIC LETTER ORKHON AEK;Lo;0;R;;;;;N;;;;;
+10C1B;OLD TURKIC LETTER YENISEI AEK;Lo;0;R;;;;;N;;;;;
+10C1C;OLD TURKIC LETTER ORKHON OEK;Lo;0;R;;;;;N;;;;;
+10C1D;OLD TURKIC LETTER YENISEI OEK;Lo;0;R;;;;;N;;;;;
+10C1E;OLD TURKIC LETTER ORKHON AL;Lo;0;R;;;;;N;;;;;
+10C1F;OLD TURKIC LETTER YENISEI AL;Lo;0;R;;;;;N;;;;;
+10C20;OLD TURKIC LETTER ORKHON AEL;Lo;0;R;;;;;N;;;;;
+10C21;OLD TURKIC LETTER ORKHON ELT;Lo;0;R;;;;;N;;;;;
+10C22;OLD TURKIC LETTER ORKHON EM;Lo;0;R;;;;;N;;;;;
+10C23;OLD TURKIC LETTER ORKHON AN;Lo;0;R;;;;;N;;;;;
+10C24;OLD TURKIC LETTER ORKHON AEN;Lo;0;R;;;;;N;;;;;
+10C25;OLD TURKIC LETTER YENISEI AEN;Lo;0;R;;;;;N;;;;;
+10C26;OLD TURKIC LETTER ORKHON ENT;Lo;0;R;;;;;N;;;;;
+10C27;OLD TURKIC LETTER YENISEI ENT;Lo;0;R;;;;;N;;;;;
+10C28;OLD TURKIC LETTER ORKHON ENC;Lo;0;R;;;;;N;;;;;
+10C29;OLD TURKIC LETTER YENISEI ENC;Lo;0;R;;;;;N;;;;;
+10C2A;OLD TURKIC LETTER ORKHON ENY;Lo;0;R;;;;;N;;;;;
+10C2B;OLD TURKIC LETTER YENISEI ENY;Lo;0;R;;;;;N;;;;;
+10C2C;OLD TURKIC LETTER YENISEI ANG;Lo;0;R;;;;;N;;;;;
+10C2D;OLD TURKIC LETTER ORKHON ENG;Lo;0;R;;;;;N;;;;;
+10C2E;OLD TURKIC LETTER YENISEI AENG;Lo;0;R;;;;;N;;;;;
+10C2F;OLD TURKIC LETTER ORKHON EP;Lo;0;R;;;;;N;;;;;
+10C30;OLD TURKIC LETTER ORKHON OP;Lo;0;R;;;;;N;;;;;
+10C31;OLD TURKIC LETTER ORKHON IC;Lo;0;R;;;;;N;;;;;
+10C32;OLD TURKIC LETTER ORKHON EC;Lo;0;R;;;;;N;;;;;
+10C33;OLD TURKIC LETTER YENISEI EC;Lo;0;R;;;;;N;;;;;
+10C34;OLD TURKIC LETTER ORKHON AQ;Lo;0;R;;;;;N;;;;;
+10C35;OLD TURKIC LETTER YENISEI AQ;Lo;0;R;;;;;N;;;;;
+10C36;OLD TURKIC LETTER ORKHON IQ;Lo;0;R;;;;;N;;;;;
+10C37;OLD TURKIC LETTER YENISEI IQ;Lo;0;R;;;;;N;;;;;
+10C38;OLD TURKIC LETTER ORKHON OQ;Lo;0;R;;;;;N;;;;;
+10C39;OLD TURKIC LETTER YENISEI OQ;Lo;0;R;;;;;N;;;;;
+10C3A;OLD TURKIC LETTER ORKHON AR;Lo;0;R;;;;;N;;;;;
+10C3B;OLD TURKIC LETTER YENISEI AR;Lo;0;R;;;;;N;;;;;
+10C3C;OLD TURKIC LETTER ORKHON AER;Lo;0;R;;;;;N;;;;;
+10C3D;OLD TURKIC LETTER ORKHON AS;Lo;0;R;;;;;N;;;;;
+10C3E;OLD TURKIC LETTER ORKHON AES;Lo;0;R;;;;;N;;;;;
+10C3F;OLD TURKIC LETTER ORKHON ASH;Lo;0;R;;;;;N;;;;;
+10C40;OLD TURKIC LETTER YENISEI ASH;Lo;0;R;;;;;N;;;;;
+10C41;OLD TURKIC LETTER ORKHON ESH;Lo;0;R;;;;;N;;;;;
+10C42;OLD TURKIC LETTER YENISEI ESH;Lo;0;R;;;;;N;;;;;
+10C43;OLD TURKIC LETTER ORKHON AT;Lo;0;R;;;;;N;;;;;
+10C44;OLD TURKIC LETTER YENISEI AT;Lo;0;R;;;;;N;;;;;
+10C45;OLD TURKIC LETTER ORKHON AET;Lo;0;R;;;;;N;;;;;
+10C46;OLD TURKIC LETTER YENISEI AET;Lo;0;R;;;;;N;;;;;
+10C47;OLD TURKIC LETTER ORKHON OT;Lo;0;R;;;;;N;;;;;
+10C48;OLD TURKIC LETTER ORKHON BASH;Lo;0;R;;;;;N;;;;;
+10E60;RUMI DIGIT ONE;No;0;AN;;;1;1;N;;;;;
+10E61;RUMI DIGIT TWO;No;0;AN;;;2;2;N;;;;;
+10E62;RUMI DIGIT THREE;No;0;AN;;;3;3;N;;;;;
+10E63;RUMI DIGIT FOUR;No;0;AN;;;4;4;N;;;;;
+10E64;RUMI DIGIT FIVE;No;0;AN;;;5;5;N;;;;;
+10E65;RUMI DIGIT SIX;No;0;AN;;;6;6;N;;;;;
+10E66;RUMI DIGIT SEVEN;No;0;AN;;;7;7;N;;;;;
+10E67;RUMI DIGIT EIGHT;No;0;AN;;;8;8;N;;;;;
+10E68;RUMI DIGIT NINE;No;0;AN;;;9;9;N;;;;;
+10E69;RUMI NUMBER TEN;No;0;AN;;;;10;N;;;;;
+10E6A;RUMI NUMBER TWENTY;No;0;AN;;;;20;N;;;;;
+10E6B;RUMI NUMBER THIRTY;No;0;AN;;;;30;N;;;;;
+10E6C;RUMI NUMBER FORTY;No;0;AN;;;;40;N;;;;;
+10E6D;RUMI NUMBER FIFTY;No;0;AN;;;;50;N;;;;;
+10E6E;RUMI NUMBER SIXTY;No;0;AN;;;;60;N;;;;;
+10E6F;RUMI NUMBER SEVENTY;No;0;AN;;;;70;N;;;;;
+10E70;RUMI NUMBER EIGHTY;No;0;AN;;;;80;N;;;;;
+10E71;RUMI NUMBER NINETY;No;0;AN;;;;90;N;;;;;
+10E72;RUMI NUMBER ONE HUNDRED;No;0;AN;;;;100;N;;;;;
+10E73;RUMI NUMBER TWO HUNDRED;No;0;AN;;;;200;N;;;;;
+10E74;RUMI NUMBER THREE HUNDRED;No;0;AN;;;;300;N;;;;;
+10E75;RUMI NUMBER FOUR HUNDRED;No;0;AN;;;;400;N;;;;;
+10E76;RUMI NUMBER FIVE HUNDRED;No;0;AN;;;;500;N;;;;;
+10E77;RUMI NUMBER SIX HUNDRED;No;0;AN;;;;600;N;;;;;
+10E78;RUMI NUMBER SEVEN HUNDRED;No;0;AN;;;;700;N;;;;;
+10E79;RUMI NUMBER EIGHT HUNDRED;No;0;AN;;;;800;N;;;;;
+10E7A;RUMI NUMBER NINE HUNDRED;No;0;AN;;;;900;N;;;;;
+10E7B;RUMI FRACTION ONE HALF;No;0;AN;;;;1/2;N;;;;;
+10E7C;RUMI FRACTION ONE QUARTER;No;0;AN;;;;1/4;N;;;;;
+10E7D;RUMI FRACTION ONE THIRD;No;0;AN;;;;1/3;N;;;;;
+10E7E;RUMI FRACTION TWO THIRDS;No;0;AN;;;;2/3;N;;;;;
+11000;BRAHMI SIGN CANDRABINDU;Mc;0;L;;;;;N;;;;;
+11001;BRAHMI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;
+11002;BRAHMI SIGN VISARGA;Mc;0;L;;;;;N;;;;;
+11003;BRAHMI SIGN JIHVAMULIYA;Lo;0;L;;;;;N;;;;;
+11004;BRAHMI SIGN UPADHMANIYA;Lo;0;L;;;;;N;;;;;
+11005;BRAHMI LETTER A;Lo;0;L;;;;;N;;;;;
+11006;BRAHMI LETTER AA;Lo;0;L;;;;;N;;;;;
+11007;BRAHMI LETTER I;Lo;0;L;;;;;N;;;;;
+11008;BRAHMI LETTER II;Lo;0;L;;;;;N;;;;;
+11009;BRAHMI LETTER U;Lo;0;L;;;;;N;;;;;
+1100A;BRAHMI LETTER UU;Lo;0;L;;;;;N;;;;;
+1100B;BRAHMI LETTER VOCALIC R;Lo;0;L;;;;;N;;;;;
+1100C;BRAHMI LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;;
+1100D;BRAHMI LETTER VOCALIC L;Lo;0;L;;;;;N;;;;;
+1100E;BRAHMI LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;;
+1100F;BRAHMI LETTER E;Lo;0;L;;;;;N;;;;;
+11010;BRAHMI LETTER AI;Lo;0;L;;;;;N;;;;;
+11011;BRAHMI LETTER O;Lo;0;L;;;;;N;;;;;
+11012;BRAHMI LETTER AU;Lo;0;L;;;;;N;;;;;
+11013;BRAHMI LETTER KA;Lo;0;L;;;;;N;;;;;
+11014;BRAHMI LETTER KHA;Lo;0;L;;;;;N;;;;;
+11015;BRAHMI LETTER GA;Lo;0;L;;;;;N;;;;;
+11016;BRAHMI LETTER GHA;Lo;0;L;;;;;N;;;;;
+11017;BRAHMI LETTER NGA;Lo;0;L;;;;;N;;;;;
+11018;BRAHMI LETTER CA;Lo;0;L;;;;;N;;;;;
+11019;BRAHMI LETTER CHA;Lo;0;L;;;;;N;;;;;
+1101A;BRAHMI LETTER JA;Lo;0;L;;;;;N;;;;;
+1101B;BRAHMI LETTER JHA;Lo;0;L;;;;;N;;;;;
+1101C;BRAHMI LETTER NYA;Lo;0;L;;;;;N;;;;;
+1101D;BRAHMI LETTER TTA;Lo;0;L;;;;;N;;;;;
+1101E;BRAHMI LETTER TTHA;Lo;0;L;;;;;N;;;;;
+1101F;BRAHMI LETTER DDA;Lo;0;L;;;;;N;;;;;
+11020;BRAHMI LETTER DDHA;Lo;0;L;;;;;N;;;;;
+11021;BRAHMI LETTER NNA;Lo;0;L;;;;;N;;;;;
+11022;BRAHMI LETTER TA;Lo;0;L;;;;;N;;;;;
+11023;BRAHMI LETTER THA;Lo;0;L;;;;;N;;;;;
+11024;BRAHMI LETTER DA;Lo;0;L;;;;;N;;;;;
+11025;BRAHMI LETTER DHA;Lo;0;L;;;;;N;;;;;
+11026;BRAHMI LETTER NA;Lo;0;L;;;;;N;;;;;
+11027;BRAHMI LETTER PA;Lo;0;L;;;;;N;;;;;
+11028;BRAHMI LETTER PHA;Lo;0;L;;;;;N;;;;;
+11029;BRAHMI LETTER BA;Lo;0;L;;;;;N;;;;;
+1102A;BRAHMI LETTER BHA;Lo;0;L;;;;;N;;;;;
+1102B;BRAHMI LETTER MA;Lo;0;L;;;;;N;;;;;
+1102C;BRAHMI LETTER YA;Lo;0;L;;;;;N;;;;;
+1102D;BRAHMI LETTER RA;Lo;0;L;;;;;N;;;;;
+1102E;BRAHMI LETTER LA;Lo;0;L;;;;;N;;;;;
+1102F;BRAHMI LETTER VA;Lo;0;L;;;;;N;;;;;
+11030;BRAHMI LETTER SHA;Lo;0;L;;;;;N;;;;;
+11031;BRAHMI LETTER SSA;Lo;0;L;;;;;N;;;;;
+11032;BRAHMI LETTER SA;Lo;0;L;;;;;N;;;;;
+11033;BRAHMI LETTER HA;Lo;0;L;;;;;N;;;;;
+11034;BRAHMI LETTER LLA;Lo;0;L;;;;;N;;;;;
+11035;BRAHMI LETTER OLD TAMIL LLLA;Lo;0;L;;;;;N;;;;;
+11036;BRAHMI LETTER OLD TAMIL RRA;Lo;0;L;;;;;N;;;;;
+11037;BRAHMI LETTER OLD TAMIL NNNA;Lo;0;L;;;;;N;;;;;
+11038;BRAHMI VOWEL SIGN AA;Mn;0;NSM;;;;;N;;;;;
+11039;BRAHMI VOWEL SIGN BHATTIPROLU AA;Mn;0;NSM;;;;;N;;;;;
+1103A;BRAHMI VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;
+1103B;BRAHMI VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;;
+1103C;BRAHMI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+1103D;BRAHMI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;
+1103E;BRAHMI VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;;
+1103F;BRAHMI VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;;
+11040;BRAHMI VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;;
+11041;BRAHMI VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;;
+11042;BRAHMI VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;;
+11043;BRAHMI VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;;
+11044;BRAHMI VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;;
+11045;BRAHMI VOWEL SIGN AU;Mn;0;NSM;;;;;N;;;;;
+11046;BRAHMI VIRAMA;Mn;9;NSM;;;;;N;;;;;
+11047;BRAHMI DANDA;Po;0;L;;;;;N;;;;;
+11048;BRAHMI DOUBLE DANDA;Po;0;L;;;;;N;;;;;
+11049;BRAHMI PUNCTUATION DOT;Po;0;L;;;;;N;;;;;
+1104A;BRAHMI PUNCTUATION DOUBLE DOT;Po;0;L;;;;;N;;;;;
+1104B;BRAHMI PUNCTUATION LINE;Po;0;L;;;;;N;;;;;
+1104C;BRAHMI PUNCTUATION CRESCENT BAR;Po;0;L;;;;;N;;;;;
+1104D;BRAHMI PUNCTUATION LOTUS;Po;0;L;;;;;N;;;;;
+11052;BRAHMI NUMBER ONE;No;0;ON;;;1;1;N;;;;;
+11053;BRAHMI NUMBER TWO;No;0;ON;;;2;2;N;;;;;
+11054;BRAHMI NUMBER THREE;No;0;ON;;;3;3;N;;;;;
+11055;BRAHMI NUMBER FOUR;No;0;ON;;;4;4;N;;;;;
+11056;BRAHMI NUMBER FIVE;No;0;ON;;;5;5;N;;;;;
+11057;BRAHMI NUMBER SIX;No;0;ON;;;6;6;N;;;;;
+11058;BRAHMI NUMBER SEVEN;No;0;ON;;;7;7;N;;;;;
+11059;BRAHMI NUMBER EIGHT;No;0;ON;;;8;8;N;;;;;
+1105A;BRAHMI NUMBER NINE;No;0;ON;;;9;9;N;;;;;
+1105B;BRAHMI NUMBER TEN;No;0;ON;;;;10;N;;;;;
+1105C;BRAHMI NUMBER TWENTY;No;0;ON;;;;20;N;;;;;
+1105D;BRAHMI NUMBER THIRTY;No;0;ON;;;;30;N;;;;;
+1105E;BRAHMI NUMBER FORTY;No;0;ON;;;;40;N;;;;;
+1105F;BRAHMI NUMBER FIFTY;No;0;ON;;;;50;N;;;;;
+11060;BRAHMI NUMBER SIXTY;No;0;ON;;;;60;N;;;;;
+11061;BRAHMI NUMBER SEVENTY;No;0;ON;;;;70;N;;;;;
+11062;BRAHMI NUMBER EIGHTY;No;0;ON;;;;80;N;;;;;
+11063;BRAHMI NUMBER NINETY;No;0;ON;;;;90;N;;;;;
+11064;BRAHMI NUMBER ONE HUNDRED;No;0;ON;;;;100;N;;;;;
+11065;BRAHMI NUMBER ONE THOUSAND;No;0;ON;;;;1000;N;;;;;
+11066;BRAHMI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+11067;BRAHMI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+11068;BRAHMI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+11069;BRAHMI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+1106A;BRAHMI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+1106B;BRAHMI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+1106C;BRAHMI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+1106D;BRAHMI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+1106E;BRAHMI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+1106F;BRAHMI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+11080;KAITHI SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;;
+11081;KAITHI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;
+11082;KAITHI SIGN VISARGA;Mc;0;L;;;;;N;;;;;
+11083;KAITHI LETTER A;Lo;0;L;;;;;N;;;;;
+11084;KAITHI LETTER AA;Lo;0;L;;;;;N;;;;;
+11085;KAITHI LETTER I;Lo;0;L;;;;;N;;;;;
+11086;KAITHI LETTER II;Lo;0;L;;;;;N;;;;;
+11087;KAITHI LETTER U;Lo;0;L;;;;;N;;;;;
+11088;KAITHI LETTER UU;Lo;0;L;;;;;N;;;;;
+11089;KAITHI LETTER E;Lo;0;L;;;;;N;;;;;
+1108A;KAITHI LETTER AI;Lo;0;L;;;;;N;;;;;
+1108B;KAITHI LETTER O;Lo;0;L;;;;;N;;;;;
+1108C;KAITHI LETTER AU;Lo;0;L;;;;;N;;;;;
+1108D;KAITHI LETTER KA;Lo;0;L;;;;;N;;;;;
+1108E;KAITHI LETTER KHA;Lo;0;L;;;;;N;;;;;
+1108F;KAITHI LETTER GA;Lo;0;L;;;;;N;;;;;
+11090;KAITHI LETTER GHA;Lo;0;L;;;;;N;;;;;
+11091;KAITHI LETTER NGA;Lo;0;L;;;;;N;;;;;
+11092;KAITHI LETTER CA;Lo;0;L;;;;;N;;;;;
+11093;KAITHI LETTER CHA;Lo;0;L;;;;;N;;;;;
+11094;KAITHI LETTER JA;Lo;0;L;;;;;N;;;;;
+11095;KAITHI LETTER JHA;Lo;0;L;;;;;N;;;;;
+11096;KAITHI LETTER NYA;Lo;0;L;;;;;N;;;;;
+11097;KAITHI LETTER TTA;Lo;0;L;;;;;N;;;;;
+11098;KAITHI LETTER TTHA;Lo;0;L;;;;;N;;;;;
+11099;KAITHI LETTER DDA;Lo;0;L;;;;;N;;;;;
+1109A;KAITHI LETTER DDDHA;Lo;0;L;11099 110BA;;;;N;;;;;
+1109B;KAITHI LETTER DDHA;Lo;0;L;;;;;N;;;;;
+1109C;KAITHI LETTER RHA;Lo;0;L;1109B 110BA;;;;N;;;;;
+1109D;KAITHI LETTER NNA;Lo;0;L;;;;;N;;;;;
+1109E;KAITHI LETTER TA;Lo;0;L;;;;;N;;;;;
+1109F;KAITHI LETTER THA;Lo;0;L;;;;;N;;;;;
+110A0;KAITHI LETTER DA;Lo;0;L;;;;;N;;;;;
+110A1;KAITHI LETTER DHA;Lo;0;L;;;;;N;;;;;
+110A2;KAITHI LETTER NA;Lo;0;L;;;;;N;;;;;
+110A3;KAITHI LETTER PA;Lo;0;L;;;;;N;;;;;
+110A4;KAITHI LETTER PHA;Lo;0;L;;;;;N;;;;;
+110A5;KAITHI LETTER BA;Lo;0;L;;;;;N;;;;;
+110A6;KAITHI LETTER BHA;Lo;0;L;;;;;N;;;;;
+110A7;KAITHI LETTER MA;Lo;0;L;;;;;N;;;;;
+110A8;KAITHI LETTER YA;Lo;0;L;;;;;N;;;;;
+110A9;KAITHI LETTER RA;Lo;0;L;;;;;N;;;;;
+110AA;KAITHI LETTER LA;Lo;0;L;;;;;N;;;;;
+110AB;KAITHI LETTER VA;Lo;0;L;110A5 110BA;;;;N;;;;;
+110AC;KAITHI LETTER SHA;Lo;0;L;;;;;N;;;;;
+110AD;KAITHI LETTER SSA;Lo;0;L;;;;;N;;;;;
+110AE;KAITHI LETTER SA;Lo;0;L;;;;;N;;;;;
+110AF;KAITHI LETTER HA;Lo;0;L;;;;;N;;;;;
+110B0;KAITHI VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
+110B1;KAITHI VOWEL SIGN I;Mc;0;L;;;;;N;;;;;
+110B2;KAITHI VOWEL SIGN II;Mc;0;L;;;;;N;;;;;
+110B3;KAITHI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+110B4;KAITHI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;
+110B5;KAITHI VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;;
+110B6;KAITHI VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;;
+110B7;KAITHI VOWEL SIGN O;Mc;0;L;;;;;N;;;;;
+110B8;KAITHI VOWEL SIGN AU;Mc;0;L;;;;;N;;;;;
+110B9;KAITHI SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;
+110BA;KAITHI SIGN NUKTA;Mn;7;NSM;;;;;N;;;;;
+110BB;KAITHI ABBREVIATION SIGN;Po;0;L;;;;;N;;;;;
+110BC;KAITHI ENUMERATION SIGN;Po;0;L;;;;;N;;;;;
+110BD;KAITHI NUMBER SIGN;Cf;0;L;;;;;N;;;;;
+110BE;KAITHI SECTION MARK;Po;0;L;;;;;N;;;;;
+110BF;KAITHI DOUBLE SECTION MARK;Po;0;L;;;;;N;;;;;
+110C0;KAITHI DANDA;Po;0;L;;;;;N;;;;;
+110C1;KAITHI DOUBLE DANDA;Po;0;L;;;;;N;;;;;
+12000;CUNEIFORM SIGN A;Lo;0;L;;;;;N;;;;;
+12001;CUNEIFORM SIGN A TIMES A;Lo;0;L;;;;;N;;;;;
+12002;CUNEIFORM SIGN A TIMES BAD;Lo;0;L;;;;;N;;;;;
+12003;CUNEIFORM SIGN A TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;;
+12004;CUNEIFORM SIGN A TIMES HA;Lo;0;L;;;;;N;;;;;
+12005;CUNEIFORM SIGN A TIMES IGI;Lo;0;L;;;;;N;;;;;
+12006;CUNEIFORM SIGN A TIMES LAGAR GUNU;Lo;0;L;;;;;N;;;;;
+12007;CUNEIFORM SIGN A TIMES MUSH;Lo;0;L;;;;;N;;;;;
+12008;CUNEIFORM SIGN A TIMES SAG;Lo;0;L;;;;;N;;;;;
+12009;CUNEIFORM SIGN A2;Lo;0;L;;;;;N;;;;;
+1200A;CUNEIFORM SIGN AB;Lo;0;L;;;;;N;;;;;
+1200B;CUNEIFORM SIGN AB TIMES ASH2;Lo;0;L;;;;;N;;;;;
+1200C;CUNEIFORM SIGN AB TIMES DUN3 GUNU;Lo;0;L;;;;;N;;;;;
+1200D;CUNEIFORM SIGN AB TIMES GAL;Lo;0;L;;;;;N;;;;;
+1200E;CUNEIFORM SIGN AB TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;;
+1200F;CUNEIFORM SIGN AB TIMES HA;Lo;0;L;;;;;N;;;;;
+12010;CUNEIFORM SIGN AB TIMES IGI GUNU;Lo;0;L;;;;;N;;;;;
+12011;CUNEIFORM SIGN AB TIMES IMIN;Lo;0;L;;;;;N;;;;;
+12012;CUNEIFORM SIGN AB TIMES LAGAB;Lo;0;L;;;;;N;;;;;
+12013;CUNEIFORM SIGN AB TIMES SHESH;Lo;0;L;;;;;N;;;;;
+12014;CUNEIFORM SIGN AB TIMES U PLUS U PLUS U;Lo;0;L;;;;;N;;;;;
+12015;CUNEIFORM SIGN AB GUNU;Lo;0;L;;;;;N;;;;;
+12016;CUNEIFORM SIGN AB2;Lo;0;L;;;;;N;;;;;
+12017;CUNEIFORM SIGN AB2 TIMES BALAG;Lo;0;L;;;;;N;;;;;
+12018;CUNEIFORM SIGN AB2 TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;;
+12019;CUNEIFORM SIGN AB2 TIMES ME PLUS EN;Lo;0;L;;;;;N;;;;;
+1201A;CUNEIFORM SIGN AB2 TIMES SHA3;Lo;0;L;;;;;N;;;;;
+1201B;CUNEIFORM SIGN AB2 TIMES TAK4;Lo;0;L;;;;;N;;;;;
+1201C;CUNEIFORM SIGN AD;Lo;0;L;;;;;N;;;;;
+1201D;CUNEIFORM SIGN AK;Lo;0;L;;;;;N;;;;;
+1201E;CUNEIFORM SIGN AK TIMES ERIN2;Lo;0;L;;;;;N;;;;;
+1201F;CUNEIFORM SIGN AK TIMES SHITA PLUS GISH;Lo;0;L;;;;;N;;;;;
+12020;CUNEIFORM SIGN AL;Lo;0;L;;;;;N;;;;;
+12021;CUNEIFORM SIGN AL TIMES AL;Lo;0;L;;;;;N;;;;;
+12022;CUNEIFORM SIGN AL TIMES DIM2;Lo;0;L;;;;;N;;;;;
+12023;CUNEIFORM SIGN AL TIMES GISH;Lo;0;L;;;;;N;;;;;
+12024;CUNEIFORM SIGN AL TIMES HA;Lo;0;L;;;;;N;;;;;
+12025;CUNEIFORM SIGN AL TIMES KAD3;Lo;0;L;;;;;N;;;;;
+12026;CUNEIFORM SIGN AL TIMES KI;Lo;0;L;;;;;N;;;;;
+12027;CUNEIFORM SIGN AL TIMES SHE;Lo;0;L;;;;;N;;;;;
+12028;CUNEIFORM SIGN AL TIMES USH;Lo;0;L;;;;;N;;;;;
+12029;CUNEIFORM SIGN ALAN;Lo;0;L;;;;;N;;;;;
+1202A;CUNEIFORM SIGN ALEPH;Lo;0;L;;;;;N;;;;;
+1202B;CUNEIFORM SIGN AMAR;Lo;0;L;;;;;N;;;;;
+1202C;CUNEIFORM SIGN AMAR TIMES SHE;Lo;0;L;;;;;N;;;;;
+1202D;CUNEIFORM SIGN AN;Lo;0;L;;;;;N;;;;;
+1202E;CUNEIFORM SIGN AN OVER AN;Lo;0;L;;;;;N;;;;;
+1202F;CUNEIFORM SIGN AN THREE TIMES;Lo;0;L;;;;;N;;;;;
+12030;CUNEIFORM SIGN AN PLUS NAGA OPPOSING AN PLUS NAGA;Lo;0;L;;;;;N;;;;;
+12031;CUNEIFORM SIGN AN PLUS NAGA SQUARED;Lo;0;L;;;;;N;;;;;
+12032;CUNEIFORM SIGN ANSHE;Lo;0;L;;;;;N;;;;;
+12033;CUNEIFORM SIGN APIN;Lo;0;L;;;;;N;;;;;
+12034;CUNEIFORM SIGN ARAD;Lo;0;L;;;;;N;;;;;
+12035;CUNEIFORM SIGN ARAD TIMES KUR;Lo;0;L;;;;;N;;;;;
+12036;CUNEIFORM SIGN ARKAB;Lo;0;L;;;;;N;;;;;
+12037;CUNEIFORM SIGN ASAL2;Lo;0;L;;;;;N;;;;;
+12038;CUNEIFORM SIGN ASH;Lo;0;L;;;;;N;;;;;
+12039;CUNEIFORM SIGN ASH ZIDA TENU;Lo;0;L;;;;;N;;;;;
+1203A;CUNEIFORM SIGN ASH KABA TENU;Lo;0;L;;;;;N;;;;;
+1203B;CUNEIFORM SIGN ASH OVER ASH TUG2 OVER TUG2 TUG2 OVER TUG2 PAP;Lo;0;L;;;;;N;;;;;
+1203C;CUNEIFORM SIGN ASH OVER ASH OVER ASH;Lo;0;L;;;;;N;;;;;
+1203D;CUNEIFORM SIGN ASH OVER ASH OVER ASH CROSSING ASH OVER ASH OVER ASH;Lo;0;L;;;;;N;;;;;
+1203E;CUNEIFORM SIGN ASH2;Lo;0;L;;;;;N;;;;;
+1203F;CUNEIFORM SIGN ASHGAB;Lo;0;L;;;;;N;;;;;
+12040;CUNEIFORM SIGN BA;Lo;0;L;;;;;N;;;;;
+12041;CUNEIFORM SIGN BAD;Lo;0;L;;;;;N;;;;;
+12042;CUNEIFORM SIGN BAG3;Lo;0;L;;;;;N;;;;;
+12043;CUNEIFORM SIGN BAHAR2;Lo;0;L;;;;;N;;;;;
+12044;CUNEIFORM SIGN BAL;Lo;0;L;;;;;N;;;;;
+12045;CUNEIFORM SIGN BAL OVER BAL;Lo;0;L;;;;;N;;;;;
+12046;CUNEIFORM SIGN BALAG;Lo;0;L;;;;;N;;;;;
+12047;CUNEIFORM SIGN BAR;Lo;0;L;;;;;N;;;;;
+12048;CUNEIFORM SIGN BARA2;Lo;0;L;;;;;N;;;;;
+12049;CUNEIFORM SIGN BI;Lo;0;L;;;;;N;;;;;
+1204A;CUNEIFORM SIGN BI TIMES A;Lo;0;L;;;;;N;;;;;
+1204B;CUNEIFORM SIGN BI TIMES GAR;Lo;0;L;;;;;N;;;;;
+1204C;CUNEIFORM SIGN BI TIMES IGI GUNU;Lo;0;L;;;;;N;;;;;
+1204D;CUNEIFORM SIGN BU;Lo;0;L;;;;;N;;;;;
+1204E;CUNEIFORM SIGN BU OVER BU AB;Lo;0;L;;;;;N;;;;;
+1204F;CUNEIFORM SIGN BU OVER BU UN;Lo;0;L;;;;;N;;;;;
+12050;CUNEIFORM SIGN BU CROSSING BU;Lo;0;L;;;;;N;;;;;
+12051;CUNEIFORM SIGN BULUG;Lo;0;L;;;;;N;;;;;
+12052;CUNEIFORM SIGN BULUG OVER BULUG;Lo;0;L;;;;;N;;;;;
+12053;CUNEIFORM SIGN BUR;Lo;0;L;;;;;N;;;;;
+12054;CUNEIFORM SIGN BUR2;Lo;0;L;;;;;N;;;;;
+12055;CUNEIFORM SIGN DA;Lo;0;L;;;;;N;;;;;
+12056;CUNEIFORM SIGN DAG;Lo;0;L;;;;;N;;;;;
+12057;CUNEIFORM SIGN DAG KISIM5 TIMES A PLUS MASH;Lo;0;L;;;;;N;;;;;
+12058;CUNEIFORM SIGN DAG KISIM5 TIMES AMAR;Lo;0;L;;;;;N;;;;;
+12059;CUNEIFORM SIGN DAG KISIM5 TIMES BALAG;Lo;0;L;;;;;N;;;;;
+1205A;CUNEIFORM SIGN DAG KISIM5 TIMES BI;Lo;0;L;;;;;N;;;;;
+1205B;CUNEIFORM SIGN DAG KISIM5 TIMES GA;Lo;0;L;;;;;N;;;;;
+1205C;CUNEIFORM SIGN DAG KISIM5 TIMES GA PLUS MASH;Lo;0;L;;;;;N;;;;;
+1205D;CUNEIFORM SIGN DAG KISIM5 TIMES GI;Lo;0;L;;;;;N;;;;;
+1205E;CUNEIFORM SIGN DAG KISIM5 TIMES GIR2;Lo;0;L;;;;;N;;;;;
+1205F;CUNEIFORM SIGN DAG KISIM5 TIMES GUD;Lo;0;L;;;;;N;;;;;
+12060;CUNEIFORM SIGN DAG KISIM5 TIMES HA;Lo;0;L;;;;;N;;;;;
+12061;CUNEIFORM SIGN DAG KISIM5 TIMES IR;Lo;0;L;;;;;N;;;;;
+12062;CUNEIFORM SIGN DAG KISIM5 TIMES IR PLUS LU;Lo;0;L;;;;;N;;;;;
+12063;CUNEIFORM SIGN DAG KISIM5 TIMES KAK;Lo;0;L;;;;;N;;;;;
+12064;CUNEIFORM SIGN DAG KISIM5 TIMES LA;Lo;0;L;;;;;N;;;;;
+12065;CUNEIFORM SIGN DAG KISIM5 TIMES LU;Lo;0;L;;;;;N;;;;;
+12066;CUNEIFORM SIGN DAG KISIM5 TIMES LU PLUS MASH2;Lo;0;L;;;;;N;;;;;
+12067;CUNEIFORM SIGN DAG KISIM5 TIMES LUM;Lo;0;L;;;;;N;;;;;
+12068;CUNEIFORM SIGN DAG KISIM5 TIMES NE;Lo;0;L;;;;;N;;;;;
+12069;CUNEIFORM SIGN DAG KISIM5 TIMES PAP PLUS PAP;Lo;0;L;;;;;N;;;;;
+1206A;CUNEIFORM SIGN DAG KISIM5 TIMES SI;Lo;0;L;;;;;N;;;;;
+1206B;CUNEIFORM SIGN DAG KISIM5 TIMES TAK4;Lo;0;L;;;;;N;;;;;
+1206C;CUNEIFORM SIGN DAG KISIM5 TIMES U2 PLUS GIR2;Lo;0;L;;;;;N;;;;;
+1206D;CUNEIFORM SIGN DAG KISIM5 TIMES USH;Lo;0;L;;;;;N;;;;;
+1206E;CUNEIFORM SIGN DAM;Lo;0;L;;;;;N;;;;;
+1206F;CUNEIFORM SIGN DAR;Lo;0;L;;;;;N;;;;;
+12070;CUNEIFORM SIGN DARA3;Lo;0;L;;;;;N;;;;;
+12071;CUNEIFORM SIGN DARA4;Lo;0;L;;;;;N;;;;;
+12072;CUNEIFORM SIGN DI;Lo;0;L;;;;;N;;;;;
+12073;CUNEIFORM SIGN DIB;Lo;0;L;;;;;N;;;;;
+12074;CUNEIFORM SIGN DIM;Lo;0;L;;;;;N;;;;;
+12075;CUNEIFORM SIGN DIM TIMES SHE;Lo;0;L;;;;;N;;;;;
+12076;CUNEIFORM SIGN DIM2;Lo;0;L;;;;;N;;;;;
+12077;CUNEIFORM SIGN DIN;Lo;0;L;;;;;N;;;;;
+12078;CUNEIFORM SIGN DIN KASKAL U GUNU DISH;Lo;0;L;;;;;N;;;;;
+12079;CUNEIFORM SIGN DISH;Lo;0;L;;;;;N;;;;;
+1207A;CUNEIFORM SIGN DU;Lo;0;L;;;;;N;;;;;
+1207B;CUNEIFORM SIGN DU OVER DU;Lo;0;L;;;;;N;;;;;
+1207C;CUNEIFORM SIGN DU GUNU;Lo;0;L;;;;;N;;;;;
+1207D;CUNEIFORM SIGN DU SHESHIG;Lo;0;L;;;;;N;;;;;
+1207E;CUNEIFORM SIGN DUB;Lo;0;L;;;;;N;;;;;
+1207F;CUNEIFORM SIGN DUB TIMES ESH2;Lo;0;L;;;;;N;;;;;
+12080;CUNEIFORM SIGN DUB2;Lo;0;L;;;;;N;;;;;
+12081;CUNEIFORM SIGN DUG;Lo;0;L;;;;;N;;;;;
+12082;CUNEIFORM SIGN DUGUD;Lo;0;L;;;;;N;;;;;
+12083;CUNEIFORM SIGN DUH;Lo;0;L;;;;;N;;;;;
+12084;CUNEIFORM SIGN DUN;Lo;0;L;;;;;N;;;;;
+12085;CUNEIFORM SIGN DUN3;Lo;0;L;;;;;N;;;;;
+12086;CUNEIFORM SIGN DUN3 GUNU;Lo;0;L;;;;;N;;;;;
+12087;CUNEIFORM SIGN DUN3 GUNU GUNU;Lo;0;L;;;;;N;;;;;
+12088;CUNEIFORM SIGN DUN4;Lo;0;L;;;;;N;;;;;
+12089;CUNEIFORM SIGN DUR2;Lo;0;L;;;;;N;;;;;
+1208A;CUNEIFORM SIGN E;Lo;0;L;;;;;N;;;;;
+1208B;CUNEIFORM SIGN E TIMES PAP;Lo;0;L;;;;;N;;;;;
+1208C;CUNEIFORM SIGN E OVER E NUN OVER NUN;Lo;0;L;;;;;N;;;;;
+1208D;CUNEIFORM SIGN E2;Lo;0;L;;;;;N;;;;;
+1208E;CUNEIFORM SIGN E2 TIMES A PLUS HA PLUS DA;Lo;0;L;;;;;N;;;;;
+1208F;CUNEIFORM SIGN E2 TIMES GAR;Lo;0;L;;;;;N;;;;;
+12090;CUNEIFORM SIGN E2 TIMES MI;Lo;0;L;;;;;N;;;;;
+12091;CUNEIFORM SIGN E2 TIMES SAL;Lo;0;L;;;;;N;;;;;
+12092;CUNEIFORM SIGN E2 TIMES SHE;Lo;0;L;;;;;N;;;;;
+12093;CUNEIFORM SIGN E2 TIMES U;Lo;0;L;;;;;N;;;;;
+12094;CUNEIFORM SIGN EDIN;Lo;0;L;;;;;N;;;;;
+12095;CUNEIFORM SIGN EGIR;Lo;0;L;;;;;N;;;;;
+12096;CUNEIFORM SIGN EL;Lo;0;L;;;;;N;;;;;
+12097;CUNEIFORM SIGN EN;Lo;0;L;;;;;N;;;;;
+12098;CUNEIFORM SIGN EN TIMES GAN2;Lo;0;L;;;;;N;;;;;
+12099;CUNEIFORM SIGN EN TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;;
+1209A;CUNEIFORM SIGN EN TIMES ME;Lo;0;L;;;;;N;;;;;
+1209B;CUNEIFORM SIGN EN CROSSING EN;Lo;0;L;;;;;N;;;;;
+1209C;CUNEIFORM SIGN EN OPPOSING EN;Lo;0;L;;;;;N;;;;;
+1209D;CUNEIFORM SIGN EN SQUARED;Lo;0;L;;;;;N;;;;;
+1209E;CUNEIFORM SIGN EREN;Lo;0;L;;;;;N;;;;;
+1209F;CUNEIFORM SIGN ERIN2;Lo;0;L;;;;;N;;;;;
+120A0;CUNEIFORM SIGN ESH2;Lo;0;L;;;;;N;;;;;
+120A1;CUNEIFORM SIGN EZEN;Lo;0;L;;;;;N;;;;;
+120A2;CUNEIFORM SIGN EZEN TIMES A;Lo;0;L;;;;;N;;;;;
+120A3;CUNEIFORM SIGN EZEN TIMES A PLUS LAL;Lo;0;L;;;;;N;;;;;
+120A4;CUNEIFORM SIGN EZEN TIMES A PLUS LAL TIMES LAL;Lo;0;L;;;;;N;;;;;
+120A5;CUNEIFORM SIGN EZEN TIMES AN;Lo;0;L;;;;;N;;;;;
+120A6;CUNEIFORM SIGN EZEN TIMES BAD;Lo;0;L;;;;;N;;;;;
+120A7;CUNEIFORM SIGN EZEN TIMES DUN3 GUNU;Lo;0;L;;;;;N;;;;;
+120A8;CUNEIFORM SIGN EZEN TIMES DUN3 GUNU GUNU;Lo;0;L;;;;;N;;;;;
+120A9;CUNEIFORM SIGN EZEN TIMES HA;Lo;0;L;;;;;N;;;;;
+120AA;CUNEIFORM SIGN EZEN TIMES HA GUNU;Lo;0;L;;;;;N;;;;;
+120AB;CUNEIFORM SIGN EZEN TIMES IGI GUNU;Lo;0;L;;;;;N;;;;;
+120AC;CUNEIFORM SIGN EZEN TIMES KASKAL;Lo;0;L;;;;;N;;;;;
+120AD;CUNEIFORM SIGN EZEN TIMES KASKAL SQUARED;Lo;0;L;;;;;N;;;;;
+120AE;CUNEIFORM SIGN EZEN TIMES KU3;Lo;0;L;;;;;N;;;;;
+120AF;CUNEIFORM SIGN EZEN TIMES LA;Lo;0;L;;;;;N;;;;;
+120B0;CUNEIFORM SIGN EZEN TIMES LAL TIMES LAL;Lo;0;L;;;;;N;;;;;
+120B1;CUNEIFORM SIGN EZEN TIMES LI;Lo;0;L;;;;;N;;;;;
+120B2;CUNEIFORM SIGN EZEN TIMES LU;Lo;0;L;;;;;N;;;;;
+120B3;CUNEIFORM SIGN EZEN TIMES U2;Lo;0;L;;;;;N;;;;;
+120B4;CUNEIFORM SIGN EZEN TIMES UD;Lo;0;L;;;;;N;;;;;
+120B5;CUNEIFORM SIGN GA;Lo;0;L;;;;;N;;;;;
+120B6;CUNEIFORM SIGN GA GUNU;Lo;0;L;;;;;N;;;;;
+120B7;CUNEIFORM SIGN GA2;Lo;0;L;;;;;N;;;;;
+120B8;CUNEIFORM SIGN GA2 TIMES A PLUS DA PLUS HA;Lo;0;L;;;;;N;;;;;
+120B9;CUNEIFORM SIGN GA2 TIMES A PLUS HA;Lo;0;L;;;;;N;;;;;
+120BA;CUNEIFORM SIGN GA2 TIMES A PLUS IGI;Lo;0;L;;;;;N;;;;;
+120BB;CUNEIFORM SIGN GA2 TIMES AB2 TENU PLUS TAB;Lo;0;L;;;;;N;;;;;
+120BC;CUNEIFORM SIGN GA2 TIMES AN;Lo;0;L;;;;;N;;;;;
+120BD;CUNEIFORM SIGN GA2 TIMES ASH;Lo;0;L;;;;;N;;;;;
+120BE;CUNEIFORM SIGN GA2 TIMES ASH2 PLUS GAL;Lo;0;L;;;;;N;;;;;
+120BF;CUNEIFORM SIGN GA2 TIMES BAD;Lo;0;L;;;;;N;;;;;
+120C0;CUNEIFORM SIGN GA2 TIMES BAR PLUS RA;Lo;0;L;;;;;N;;;;;
+120C1;CUNEIFORM SIGN GA2 TIMES BUR;Lo;0;L;;;;;N;;;;;
+120C2;CUNEIFORM SIGN GA2 TIMES BUR PLUS RA;Lo;0;L;;;;;N;;;;;
+120C3;CUNEIFORM SIGN GA2 TIMES DA;Lo;0;L;;;;;N;;;;;
+120C4;CUNEIFORM SIGN GA2 TIMES DI;Lo;0;L;;;;;N;;;;;
+120C5;CUNEIFORM SIGN GA2 TIMES DIM TIMES SHE;Lo;0;L;;;;;N;;;;;
+120C6;CUNEIFORM SIGN GA2 TIMES DUB;Lo;0;L;;;;;N;;;;;
+120C7;CUNEIFORM SIGN GA2 TIMES EL;Lo;0;L;;;;;N;;;;;
+120C8;CUNEIFORM SIGN GA2 TIMES EL PLUS LA;Lo;0;L;;;;;N;;;;;
+120C9;CUNEIFORM SIGN GA2 TIMES EN;Lo;0;L;;;;;N;;;;;
+120CA;CUNEIFORM SIGN GA2 TIMES EN TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;;
+120CB;CUNEIFORM SIGN GA2 TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;;
+120CC;CUNEIFORM SIGN GA2 TIMES GAR;Lo;0;L;;;;;N;;;;;
+120CD;CUNEIFORM SIGN GA2 TIMES GI;Lo;0;L;;;;;N;;;;;
+120CE;CUNEIFORM SIGN GA2 TIMES GI4;Lo;0;L;;;;;N;;;;;
+120CF;CUNEIFORM SIGN GA2 TIMES GI4 PLUS A;Lo;0;L;;;;;N;;;;;
+120D0;CUNEIFORM SIGN GA2 TIMES GIR2 PLUS SU;Lo;0;L;;;;;N;;;;;
+120D1;CUNEIFORM SIGN GA2 TIMES HA PLUS LU PLUS ESH2;Lo;0;L;;;;;N;;;;;
+120D2;CUNEIFORM SIGN GA2 TIMES HAL;Lo;0;L;;;;;N;;;;;
+120D3;CUNEIFORM SIGN GA2 TIMES HAL PLUS LA;Lo;0;L;;;;;N;;;;;
+120D4;CUNEIFORM SIGN GA2 TIMES HI PLUS LI;Lo;0;L;;;;;N;;;;;
+120D5;CUNEIFORM SIGN GA2 TIMES HUB2;Lo;0;L;;;;;N;;;;;
+120D6;CUNEIFORM SIGN GA2 TIMES IGI GUNU;Lo;0;L;;;;;N;;;;;
+120D7;CUNEIFORM SIGN GA2 TIMES ISH PLUS HU PLUS ASH;Lo;0;L;;;;;N;;;;;
+120D8;CUNEIFORM SIGN GA2 TIMES KAK;Lo;0;L;;;;;N;;;;;
+120D9;CUNEIFORM SIGN GA2 TIMES KASKAL;Lo;0;L;;;;;N;;;;;
+120DA;CUNEIFORM SIGN GA2 TIMES KID;Lo;0;L;;;;;N;;;;;
+120DB;CUNEIFORM SIGN GA2 TIMES KID PLUS LAL;Lo;0;L;;;;;N;;;;;
+120DC;CUNEIFORM SIGN GA2 TIMES KU3 PLUS AN;Lo;0;L;;;;;N;;;;;
+120DD;CUNEIFORM SIGN GA2 TIMES LA;Lo;0;L;;;;;N;;;;;
+120DE;CUNEIFORM SIGN GA2 TIMES ME PLUS EN;Lo;0;L;;;;;N;;;;;
+120DF;CUNEIFORM SIGN GA2 TIMES MI;Lo;0;L;;;;;N;;;;;
+120E0;CUNEIFORM SIGN GA2 TIMES NUN;Lo;0;L;;;;;N;;;;;
+120E1;CUNEIFORM SIGN GA2 TIMES NUN OVER NUN;Lo;0;L;;;;;N;;;;;
+120E2;CUNEIFORM SIGN GA2 TIMES PA;Lo;0;L;;;;;N;;;;;
+120E3;CUNEIFORM SIGN GA2 TIMES SAL;Lo;0;L;;;;;N;;;;;
+120E4;CUNEIFORM SIGN GA2 TIMES SAR;Lo;0;L;;;;;N;;;;;
+120E5;CUNEIFORM SIGN GA2 TIMES SHE;Lo;0;L;;;;;N;;;;;
+120E6;CUNEIFORM SIGN GA2 TIMES SHE PLUS TUR;Lo;0;L;;;;;N;;;;;
+120E7;CUNEIFORM SIGN GA2 TIMES SHID;Lo;0;L;;;;;N;;;;;
+120E8;CUNEIFORM SIGN GA2 TIMES SUM;Lo;0;L;;;;;N;;;;;
+120E9;CUNEIFORM SIGN GA2 TIMES TAK4;Lo;0;L;;;;;N;;;;;
+120EA;CUNEIFORM SIGN GA2 TIMES U;Lo;0;L;;;;;N;;;;;
+120EB;CUNEIFORM SIGN GA2 TIMES UD;Lo;0;L;;;;;N;;;;;
+120EC;CUNEIFORM SIGN GA2 TIMES UD PLUS DU;Lo;0;L;;;;;N;;;;;
+120ED;CUNEIFORM SIGN GA2 OVER GA2;Lo;0;L;;;;;N;;;;;
+120EE;CUNEIFORM SIGN GABA;Lo;0;L;;;;;N;;;;;
+120EF;CUNEIFORM SIGN GABA CROSSING GABA;Lo;0;L;;;;;N;;;;;
+120F0;CUNEIFORM SIGN GAD;Lo;0;L;;;;;N;;;;;
+120F1;CUNEIFORM SIGN GAD OVER GAD GAR OVER GAR;Lo;0;L;;;;;N;;;;;
+120F2;CUNEIFORM SIGN GAL;Lo;0;L;;;;;N;;;;;
+120F3;CUNEIFORM SIGN GAL GAD OVER GAD GAR OVER GAR;Lo;0;L;;;;;N;;;;;
+120F4;CUNEIFORM SIGN GALAM;Lo;0;L;;;;;N;;;;;
+120F5;CUNEIFORM SIGN GAM;Lo;0;L;;;;;N;;;;;
+120F6;CUNEIFORM SIGN GAN;Lo;0;L;;;;;N;;;;;
+120F7;CUNEIFORM SIGN GAN2;Lo;0;L;;;;;N;;;;;
+120F8;CUNEIFORM SIGN GAN2 TENU;Lo;0;L;;;;;N;;;;;
+120F9;CUNEIFORM SIGN GAN2 OVER GAN2;Lo;0;L;;;;;N;;;;;
+120FA;CUNEIFORM SIGN GAN2 CROSSING GAN2;Lo;0;L;;;;;N;;;;;
+120FB;CUNEIFORM SIGN GAR;Lo;0;L;;;;;N;;;;;
+120FC;CUNEIFORM SIGN GAR3;Lo;0;L;;;;;N;;;;;
+120FD;CUNEIFORM SIGN GASHAN;Lo;0;L;;;;;N;;;;;
+120FE;CUNEIFORM SIGN GESHTIN;Lo;0;L;;;;;N;;;;;
+120FF;CUNEIFORM SIGN GESHTIN TIMES KUR;Lo;0;L;;;;;N;;;;;
+12100;CUNEIFORM SIGN GI;Lo;0;L;;;;;N;;;;;
+12101;CUNEIFORM SIGN GI TIMES E;Lo;0;L;;;;;N;;;;;
+12102;CUNEIFORM SIGN GI TIMES U;Lo;0;L;;;;;N;;;;;
+12103;CUNEIFORM SIGN GI CROSSING GI;Lo;0;L;;;;;N;;;;;
+12104;CUNEIFORM SIGN GI4;Lo;0;L;;;;;N;;;;;
+12105;CUNEIFORM SIGN GI4 OVER GI4;Lo;0;L;;;;;N;;;;;
+12106;CUNEIFORM SIGN GI4 CROSSING GI4;Lo;0;L;;;;;N;;;;;
+12107;CUNEIFORM SIGN GIDIM;Lo;0;L;;;;;N;;;;;
+12108;CUNEIFORM SIGN GIR2;Lo;0;L;;;;;N;;;;;
+12109;CUNEIFORM SIGN GIR2 GUNU;Lo;0;L;;;;;N;;;;;
+1210A;CUNEIFORM SIGN GIR3;Lo;0;L;;;;;N;;;;;
+1210B;CUNEIFORM SIGN GIR3 TIMES A PLUS IGI;Lo;0;L;;;;;N;;;;;
+1210C;CUNEIFORM SIGN GIR3 TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;;
+1210D;CUNEIFORM SIGN GIR3 TIMES IGI;Lo;0;L;;;;;N;;;;;
+1210E;CUNEIFORM SIGN GIR3 TIMES LU PLUS IGI;Lo;0;L;;;;;N;;;;;
+1210F;CUNEIFORM SIGN GIR3 TIMES PA;Lo;0;L;;;;;N;;;;;
+12110;CUNEIFORM SIGN GISAL;Lo;0;L;;;;;N;;;;;
+12111;CUNEIFORM SIGN GISH;Lo;0;L;;;;;N;;;;;
+12112;CUNEIFORM SIGN GISH CROSSING GISH;Lo;0;L;;;;;N;;;;;
+12113;CUNEIFORM SIGN GISH TIMES BAD;Lo;0;L;;;;;N;;;;;
+12114;CUNEIFORM SIGN GISH TIMES TAK4;Lo;0;L;;;;;N;;;;;
+12115;CUNEIFORM SIGN GISH TENU;Lo;0;L;;;;;N;;;;;
+12116;CUNEIFORM SIGN GU;Lo;0;L;;;;;N;;;;;
+12117;CUNEIFORM SIGN GU CROSSING GU;Lo;0;L;;;;;N;;;;;
+12118;CUNEIFORM SIGN GU2;Lo;0;L;;;;;N;;;;;
+12119;CUNEIFORM SIGN GU2 TIMES KAK;Lo;0;L;;;;;N;;;;;
+1211A;CUNEIFORM SIGN GU2 TIMES KAK TIMES IGI GUNU;Lo;0;L;;;;;N;;;;;
+1211B;CUNEIFORM SIGN GU2 TIMES NUN;Lo;0;L;;;;;N;;;;;
+1211C;CUNEIFORM SIGN GU2 TIMES SAL PLUS TUG2;Lo;0;L;;;;;N;;;;;
+1211D;CUNEIFORM SIGN GU2 GUNU;Lo;0;L;;;;;N;;;;;
+1211E;CUNEIFORM SIGN GUD;Lo;0;L;;;;;N;;;;;
+1211F;CUNEIFORM SIGN GUD TIMES A PLUS KUR;Lo;0;L;;;;;N;;;;;
+12120;CUNEIFORM SIGN GUD TIMES KUR;Lo;0;L;;;;;N;;;;;
+12121;CUNEIFORM SIGN GUD OVER GUD LUGAL;Lo;0;L;;;;;N;;;;;
+12122;CUNEIFORM SIGN GUL;Lo;0;L;;;;;N;;;;;
+12123;CUNEIFORM SIGN GUM;Lo;0;L;;;;;N;;;;;
+12124;CUNEIFORM SIGN GUM TIMES SHE;Lo;0;L;;;;;N;;;;;
+12125;CUNEIFORM SIGN GUR;Lo;0;L;;;;;N;;;;;
+12126;CUNEIFORM SIGN GUR7;Lo;0;L;;;;;N;;;;;
+12127;CUNEIFORM SIGN GURUN;Lo;0;L;;;;;N;;;;;
+12128;CUNEIFORM SIGN GURUSH;Lo;0;L;;;;;N;;;;;
+12129;CUNEIFORM SIGN HA;Lo;0;L;;;;;N;;;;;
+1212A;CUNEIFORM SIGN HA TENU;Lo;0;L;;;;;N;;;;;
+1212B;CUNEIFORM SIGN HA GUNU;Lo;0;L;;;;;N;;;;;
+1212C;CUNEIFORM SIGN HAL;Lo;0;L;;;;;N;;;;;
+1212D;CUNEIFORM SIGN HI;Lo;0;L;;;;;N;;;;;
+1212E;CUNEIFORM SIGN HI TIMES ASH;Lo;0;L;;;;;N;;;;;
+1212F;CUNEIFORM SIGN HI TIMES ASH2;Lo;0;L;;;;;N;;;;;
+12130;CUNEIFORM SIGN HI TIMES BAD;Lo;0;L;;;;;N;;;;;
+12131;CUNEIFORM SIGN HI TIMES DISH;Lo;0;L;;;;;N;;;;;
+12132;CUNEIFORM SIGN HI TIMES GAD;Lo;0;L;;;;;N;;;;;
+12133;CUNEIFORM SIGN HI TIMES KIN;Lo;0;L;;;;;N;;;;;
+12134;CUNEIFORM SIGN HI TIMES NUN;Lo;0;L;;;;;N;;;;;
+12135;CUNEIFORM SIGN HI TIMES SHE;Lo;0;L;;;;;N;;;;;
+12136;CUNEIFORM SIGN HI TIMES U;Lo;0;L;;;;;N;;;;;
+12137;CUNEIFORM SIGN HU;Lo;0;L;;;;;N;;;;;
+12138;CUNEIFORM SIGN HUB2;Lo;0;L;;;;;N;;;;;
+12139;CUNEIFORM SIGN HUB2 TIMES AN;Lo;0;L;;;;;N;;;;;
+1213A;CUNEIFORM SIGN HUB2 TIMES HAL;Lo;0;L;;;;;N;;;;;
+1213B;CUNEIFORM SIGN HUB2 TIMES KASKAL;Lo;0;L;;;;;N;;;;;
+1213C;CUNEIFORM SIGN HUB2 TIMES LISH;Lo;0;L;;;;;N;;;;;
+1213D;CUNEIFORM SIGN HUB2 TIMES UD;Lo;0;L;;;;;N;;;;;
+1213E;CUNEIFORM SIGN HUL2;Lo;0;L;;;;;N;;;;;
+1213F;CUNEIFORM SIGN I;Lo;0;L;;;;;N;;;;;
+12140;CUNEIFORM SIGN I A;Lo;0;L;;;;;N;;;;;
+12141;CUNEIFORM SIGN IB;Lo;0;L;;;;;N;;;;;
+12142;CUNEIFORM SIGN IDIM;Lo;0;L;;;;;N;;;;;
+12143;CUNEIFORM SIGN IDIM OVER IDIM BUR;Lo;0;L;;;;;N;;;;;
+12144;CUNEIFORM SIGN IDIM OVER IDIM SQUARED;Lo;0;L;;;;;N;;;;;
+12145;CUNEIFORM SIGN IG;Lo;0;L;;;;;N;;;;;
+12146;CUNEIFORM SIGN IGI;Lo;0;L;;;;;N;;;;;
+12147;CUNEIFORM SIGN IGI DIB;Lo;0;L;;;;;N;;;;;
+12148;CUNEIFORM SIGN IGI RI;Lo;0;L;;;;;N;;;;;
+12149;CUNEIFORM SIGN IGI OVER IGI SHIR OVER SHIR UD OVER UD;Lo;0;L;;;;;N;;;;;
+1214A;CUNEIFORM SIGN IGI GUNU;Lo;0;L;;;;;N;;;;;
+1214B;CUNEIFORM SIGN IL;Lo;0;L;;;;;N;;;;;
+1214C;CUNEIFORM SIGN IL TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;;
+1214D;CUNEIFORM SIGN IL2;Lo;0;L;;;;;N;;;;;
+1214E;CUNEIFORM SIGN IM;Lo;0;L;;;;;N;;;;;
+1214F;CUNEIFORM SIGN IM TIMES TAK4;Lo;0;L;;;;;N;;;;;
+12150;CUNEIFORM SIGN IM CROSSING IM;Lo;0;L;;;;;N;;;;;
+12151;CUNEIFORM SIGN IM OPPOSING IM;Lo;0;L;;;;;N;;;;;
+12152;CUNEIFORM SIGN IM SQUARED;Lo;0;L;;;;;N;;;;;
+12153;CUNEIFORM SIGN IMIN;Lo;0;L;;;;;N;;;;;
+12154;CUNEIFORM SIGN IN;Lo;0;L;;;;;N;;;;;
+12155;CUNEIFORM SIGN IR;Lo;0;L;;;;;N;;;;;
+12156;CUNEIFORM SIGN ISH;Lo;0;L;;;;;N;;;;;
+12157;CUNEIFORM SIGN KA;Lo;0;L;;;;;N;;;;;
+12158;CUNEIFORM SIGN KA TIMES A;Lo;0;L;;;;;N;;;;;
+12159;CUNEIFORM SIGN KA TIMES AD;Lo;0;L;;;;;N;;;;;
+1215A;CUNEIFORM SIGN KA TIMES AD PLUS KU3;Lo;0;L;;;;;N;;;;;
+1215B;CUNEIFORM SIGN KA TIMES ASH2;Lo;0;L;;;;;N;;;;;
+1215C;CUNEIFORM SIGN KA TIMES BAD;Lo;0;L;;;;;N;;;;;
+1215D;CUNEIFORM SIGN KA TIMES BALAG;Lo;0;L;;;;;N;;;;;
+1215E;CUNEIFORM SIGN KA TIMES BAR;Lo;0;L;;;;;N;;;;;
+1215F;CUNEIFORM SIGN KA TIMES BI;Lo;0;L;;;;;N;;;;;
+12160;CUNEIFORM SIGN KA TIMES ERIN2;Lo;0;L;;;;;N;;;;;
+12161;CUNEIFORM SIGN KA TIMES ESH2;Lo;0;L;;;;;N;;;;;
+12162;CUNEIFORM SIGN KA TIMES GA;Lo;0;L;;;;;N;;;;;
+12163;CUNEIFORM SIGN KA TIMES GAL;Lo;0;L;;;;;N;;;;;
+12164;CUNEIFORM SIGN KA TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;;
+12165;CUNEIFORM SIGN KA TIMES GAR;Lo;0;L;;;;;N;;;;;
+12166;CUNEIFORM SIGN KA TIMES GAR PLUS SHA3 PLUS A;Lo;0;L;;;;;N;;;;;
+12167;CUNEIFORM SIGN KA TIMES GI;Lo;0;L;;;;;N;;;;;
+12168;CUNEIFORM SIGN KA TIMES GIR2;Lo;0;L;;;;;N;;;;;
+12169;CUNEIFORM SIGN KA TIMES GISH PLUS SAR;Lo;0;L;;;;;N;;;;;
+1216A;CUNEIFORM SIGN KA TIMES GISH CROSSING GISH;Lo;0;L;;;;;N;;;;;
+1216B;CUNEIFORM SIGN KA TIMES GU;Lo;0;L;;;;;N;;;;;
+1216C;CUNEIFORM SIGN KA TIMES GUR7;Lo;0;L;;;;;N;;;;;
+1216D;CUNEIFORM SIGN KA TIMES IGI;Lo;0;L;;;;;N;;;;;
+1216E;CUNEIFORM SIGN KA TIMES IM;Lo;0;L;;;;;N;;;;;
+1216F;CUNEIFORM SIGN KA TIMES KAK;Lo;0;L;;;;;N;;;;;
+12170;CUNEIFORM SIGN KA TIMES KI;Lo;0;L;;;;;N;;;;;
+12171;CUNEIFORM SIGN KA TIMES KID;Lo;0;L;;;;;N;;;;;
+12172;CUNEIFORM SIGN KA TIMES LI;Lo;0;L;;;;;N;;;;;
+12173;CUNEIFORM SIGN KA TIMES LU;Lo;0;L;;;;;N;;;;;
+12174;CUNEIFORM SIGN KA TIMES ME;Lo;0;L;;;;;N;;;;;
+12175;CUNEIFORM SIGN KA TIMES ME PLUS DU;Lo;0;L;;;;;N;;;;;
+12176;CUNEIFORM SIGN KA TIMES ME PLUS GI;Lo;0;L;;;;;N;;;;;
+12177;CUNEIFORM SIGN KA TIMES ME PLUS TE;Lo;0;L;;;;;N;;;;;
+12178;CUNEIFORM SIGN KA TIMES MI;Lo;0;L;;;;;N;;;;;
+12179;CUNEIFORM SIGN KA TIMES MI PLUS NUNUZ;Lo;0;L;;;;;N;;;;;
+1217A;CUNEIFORM SIGN KA TIMES NE;Lo;0;L;;;;;N;;;;;
+1217B;CUNEIFORM SIGN KA TIMES NUN;Lo;0;L;;;;;N;;;;;
+1217C;CUNEIFORM SIGN KA TIMES PI;Lo;0;L;;;;;N;;;;;
+1217D;CUNEIFORM SIGN KA TIMES RU;Lo;0;L;;;;;N;;;;;
+1217E;CUNEIFORM SIGN KA TIMES SA;Lo;0;L;;;;;N;;;;;
+1217F;CUNEIFORM SIGN KA TIMES SAR;Lo;0;L;;;;;N;;;;;
+12180;CUNEIFORM SIGN KA TIMES SHA;Lo;0;L;;;;;N;;;;;
+12181;CUNEIFORM SIGN KA TIMES SHE;Lo;0;L;;;;;N;;;;;
+12182;CUNEIFORM SIGN KA TIMES SHID;Lo;0;L;;;;;N;;;;;
+12183;CUNEIFORM SIGN KA TIMES SHU;Lo;0;L;;;;;N;;;;;
+12184;CUNEIFORM SIGN KA TIMES SIG;Lo;0;L;;;;;N;;;;;
+12185;CUNEIFORM SIGN KA TIMES SUHUR;Lo;0;L;;;;;N;;;;;
+12186;CUNEIFORM SIGN KA TIMES TAR;Lo;0;L;;;;;N;;;;;
+12187;CUNEIFORM SIGN KA TIMES U;Lo;0;L;;;;;N;;;;;
+12188;CUNEIFORM SIGN KA TIMES U2;Lo;0;L;;;;;N;;;;;
+12189;CUNEIFORM SIGN KA TIMES UD;Lo;0;L;;;;;N;;;;;
+1218A;CUNEIFORM SIGN KA TIMES UMUM TIMES PA;Lo;0;L;;;;;N;;;;;
+1218B;CUNEIFORM SIGN KA TIMES USH;Lo;0;L;;;;;N;;;;;
+1218C;CUNEIFORM SIGN KA TIMES ZI;Lo;0;L;;;;;N;;;;;
+1218D;CUNEIFORM SIGN KA2;Lo;0;L;;;;;N;;;;;
+1218E;CUNEIFORM SIGN KA2 CROSSING KA2;Lo;0;L;;;;;N;;;;;
+1218F;CUNEIFORM SIGN KAB;Lo;0;L;;;;;N;;;;;
+12190;CUNEIFORM SIGN KAD2;Lo;0;L;;;;;N;;;;;
+12191;CUNEIFORM SIGN KAD3;Lo;0;L;;;;;N;;;;;
+12192;CUNEIFORM SIGN KAD4;Lo;0;L;;;;;N;;;;;
+12193;CUNEIFORM SIGN KAD5;Lo;0;L;;;;;N;;;;;
+12194;CUNEIFORM SIGN KAD5 OVER KAD5;Lo;0;L;;;;;N;;;;;
+12195;CUNEIFORM SIGN KAK;Lo;0;L;;;;;N;;;;;
+12196;CUNEIFORM SIGN KAK TIMES IGI GUNU;Lo;0;L;;;;;N;;;;;
+12197;CUNEIFORM SIGN KAL;Lo;0;L;;;;;N;;;;;
+12198;CUNEIFORM SIGN KAL TIMES BAD;Lo;0;L;;;;;N;;;;;
+12199;CUNEIFORM SIGN KAL CROSSING KAL;Lo;0;L;;;;;N;;;;;
+1219A;CUNEIFORM SIGN KAM2;Lo;0;L;;;;;N;;;;;
+1219B;CUNEIFORM SIGN KAM4;Lo;0;L;;;;;N;;;;;
+1219C;CUNEIFORM SIGN KASKAL;Lo;0;L;;;;;N;;;;;
+1219D;CUNEIFORM SIGN KASKAL LAGAB TIMES U OVER LAGAB TIMES U;Lo;0;L;;;;;N;;;;;
+1219E;CUNEIFORM SIGN KASKAL OVER KASKAL LAGAB TIMES U OVER LAGAB TIMES U;Lo;0;L;;;;;N;;;;;
+1219F;CUNEIFORM SIGN KESH2;Lo;0;L;;;;;N;;;;;
+121A0;CUNEIFORM SIGN KI;Lo;0;L;;;;;N;;;;;
+121A1;CUNEIFORM SIGN KI TIMES BAD;Lo;0;L;;;;;N;;;;;
+121A2;CUNEIFORM SIGN KI TIMES U;Lo;0;L;;;;;N;;;;;
+121A3;CUNEIFORM SIGN KI TIMES UD;Lo;0;L;;;;;N;;;;;
+121A4;CUNEIFORM SIGN KID;Lo;0;L;;;;;N;;;;;
+121A5;CUNEIFORM SIGN KIN;Lo;0;L;;;;;N;;;;;
+121A6;CUNEIFORM SIGN KISAL;Lo;0;L;;;;;N;;;;;
+121A7;CUNEIFORM SIGN KISH;Lo;0;L;;;;;N;;;;;
+121A8;CUNEIFORM SIGN KISIM5;Lo;0;L;;;;;N;;;;;
+121A9;CUNEIFORM SIGN KISIM5 OVER KISIM5;Lo;0;L;;;;;N;;;;;
+121AA;CUNEIFORM SIGN KU;Lo;0;L;;;;;N;;;;;
+121AB;CUNEIFORM SIGN KU OVER HI TIMES ASH2 KU OVER HI TIMES ASH2;Lo;0;L;;;;;N;;;;;
+121AC;CUNEIFORM SIGN KU3;Lo;0;L;;;;;N;;;;;
+121AD;CUNEIFORM SIGN KU4;Lo;0;L;;;;;N;;;;;
+121AE;CUNEIFORM SIGN KU4 VARIANT FORM;Lo;0;L;;;;;N;;;;;
+121AF;CUNEIFORM SIGN KU7;Lo;0;L;;;;;N;;;;;
+121B0;CUNEIFORM SIGN KUL;Lo;0;L;;;;;N;;;;;
+121B1;CUNEIFORM SIGN KUL GUNU;Lo;0;L;;;;;N;;;;;
+121B2;CUNEIFORM SIGN KUN;Lo;0;L;;;;;N;;;;;
+121B3;CUNEIFORM SIGN KUR;Lo;0;L;;;;;N;;;;;
+121B4;CUNEIFORM SIGN KUR OPPOSING KUR;Lo;0;L;;;;;N;;;;;
+121B5;CUNEIFORM SIGN KUSHU2;Lo;0;L;;;;;N;;;;;
+121B6;CUNEIFORM SIGN KWU318;Lo;0;L;;;;;N;;;;;
+121B7;CUNEIFORM SIGN LA;Lo;0;L;;;;;N;;;;;
+121B8;CUNEIFORM SIGN LAGAB;Lo;0;L;;;;;N;;;;;
+121B9;CUNEIFORM SIGN LAGAB TIMES A;Lo;0;L;;;;;N;;;;;
+121BA;CUNEIFORM SIGN LAGAB TIMES A PLUS DA PLUS HA;Lo;0;L;;;;;N;;;;;
+121BB;CUNEIFORM SIGN LAGAB TIMES A PLUS GAR;Lo;0;L;;;;;N;;;;;
+121BC;CUNEIFORM SIGN LAGAB TIMES A PLUS LAL;Lo;0;L;;;;;N;;;;;
+121BD;CUNEIFORM SIGN LAGAB TIMES AL;Lo;0;L;;;;;N;;;;;
+121BE;CUNEIFORM SIGN LAGAB TIMES AN;Lo;0;L;;;;;N;;;;;
+121BF;CUNEIFORM SIGN LAGAB TIMES ASH ZIDA TENU;Lo;0;L;;;;;N;;;;;
+121C0;CUNEIFORM SIGN LAGAB TIMES BAD;Lo;0;L;;;;;N;;;;;
+121C1;CUNEIFORM SIGN LAGAB TIMES BI;Lo;0;L;;;;;N;;;;;
+121C2;CUNEIFORM SIGN LAGAB TIMES DAR;Lo;0;L;;;;;N;;;;;
+121C3;CUNEIFORM SIGN LAGAB TIMES EN;Lo;0;L;;;;;N;;;;;
+121C4;CUNEIFORM SIGN LAGAB TIMES GA;Lo;0;L;;;;;N;;;;;
+121C5;CUNEIFORM SIGN LAGAB TIMES GAR;Lo;0;L;;;;;N;;;;;
+121C6;CUNEIFORM SIGN LAGAB TIMES GUD;Lo;0;L;;;;;N;;;;;
+121C7;CUNEIFORM SIGN LAGAB TIMES GUD PLUS GUD;Lo;0;L;;;;;N;;;;;
+121C8;CUNEIFORM SIGN LAGAB TIMES HA;Lo;0;L;;;;;N;;;;;
+121C9;CUNEIFORM SIGN LAGAB TIMES HAL;Lo;0;L;;;;;N;;;;;
+121CA;CUNEIFORM SIGN LAGAB TIMES HI TIMES NUN;Lo;0;L;;;;;N;;;;;
+121CB;CUNEIFORM SIGN LAGAB TIMES IGI GUNU;Lo;0;L;;;;;N;;;;;
+121CC;CUNEIFORM SIGN LAGAB TIMES IM;Lo;0;L;;;;;N;;;;;
+121CD;CUNEIFORM SIGN LAGAB TIMES IM PLUS HA;Lo;0;L;;;;;N;;;;;
+121CE;CUNEIFORM SIGN LAGAB TIMES IM PLUS LU;Lo;0;L;;;;;N;;;;;
+121CF;CUNEIFORM SIGN LAGAB TIMES KI;Lo;0;L;;;;;N;;;;;
+121D0;CUNEIFORM SIGN LAGAB TIMES KIN;Lo;0;L;;;;;N;;;;;
+121D1;CUNEIFORM SIGN LAGAB TIMES KU3;Lo;0;L;;;;;N;;;;;
+121D2;CUNEIFORM SIGN LAGAB TIMES KUL;Lo;0;L;;;;;N;;;;;
+121D3;CUNEIFORM SIGN LAGAB TIMES KUL PLUS HI PLUS A;Lo;0;L;;;;;N;;;;;
+121D4;CUNEIFORM SIGN LAGAB TIMES LAGAB;Lo;0;L;;;;;N;;;;;
+121D5;CUNEIFORM SIGN LAGAB TIMES LISH;Lo;0;L;;;;;N;;;;;
+121D6;CUNEIFORM SIGN LAGAB TIMES LU;Lo;0;L;;;;;N;;;;;
+121D7;CUNEIFORM SIGN LAGAB TIMES LUL;Lo;0;L;;;;;N;;;;;
+121D8;CUNEIFORM SIGN LAGAB TIMES ME;Lo;0;L;;;;;N;;;;;
+121D9;CUNEIFORM SIGN LAGAB TIMES ME PLUS EN;Lo;0;L;;;;;N;;;;;
+121DA;CUNEIFORM SIGN LAGAB TIMES MUSH;Lo;0;L;;;;;N;;;;;
+121DB;CUNEIFORM SIGN LAGAB TIMES NE;Lo;0;L;;;;;N;;;;;
+121DC;CUNEIFORM SIGN LAGAB TIMES SHE PLUS SUM;Lo;0;L;;;;;N;;;;;
+121DD;CUNEIFORM SIGN LAGAB TIMES SHITA PLUS GISH PLUS ERIN2;Lo;0;L;;;;;N;;;;;
+121DE;CUNEIFORM SIGN LAGAB TIMES SHITA PLUS GISH TENU;Lo;0;L;;;;;N;;;;;
+121DF;CUNEIFORM SIGN LAGAB TIMES SHU2;Lo;0;L;;;;;N;;;;;
+121E0;CUNEIFORM SIGN LAGAB TIMES SHU2 PLUS SHU2;Lo;0;L;;;;;N;;;;;
+121E1;CUNEIFORM SIGN LAGAB TIMES SUM;Lo;0;L;;;;;N;;;;;
+121E2;CUNEIFORM SIGN LAGAB TIMES TAG;Lo;0;L;;;;;N;;;;;
+121E3;CUNEIFORM SIGN LAGAB TIMES TAK4;Lo;0;L;;;;;N;;;;;
+121E4;CUNEIFORM SIGN LAGAB TIMES TE PLUS A PLUS SU PLUS NA;Lo;0;L;;;;;N;;;;;
+121E5;CUNEIFORM SIGN LAGAB TIMES U;Lo;0;L;;;;;N;;;;;
+121E6;CUNEIFORM SIGN LAGAB TIMES U PLUS A;Lo;0;L;;;;;N;;;;;
+121E7;CUNEIFORM SIGN LAGAB TIMES U PLUS U PLUS U;Lo;0;L;;;;;N;;;;;
+121E8;CUNEIFORM SIGN LAGAB TIMES U2 PLUS ASH;Lo;0;L;;;;;N;;;;;
+121E9;CUNEIFORM SIGN LAGAB TIMES UD;Lo;0;L;;;;;N;;;;;
+121EA;CUNEIFORM SIGN LAGAB TIMES USH;Lo;0;L;;;;;N;;;;;
+121EB;CUNEIFORM SIGN LAGAB SQUARED;Lo;0;L;;;;;N;;;;;
+121EC;CUNEIFORM SIGN LAGAR;Lo;0;L;;;;;N;;;;;
+121ED;CUNEIFORM SIGN LAGAR TIMES SHE;Lo;0;L;;;;;N;;;;;
+121EE;CUNEIFORM SIGN LAGAR TIMES SHE PLUS SUM;Lo;0;L;;;;;N;;;;;
+121EF;CUNEIFORM SIGN LAGAR GUNU;Lo;0;L;;;;;N;;;;;
+121F0;CUNEIFORM SIGN LAGAR GUNU OVER LAGAR GUNU SHE;Lo;0;L;;;;;N;;;;;
+121F1;CUNEIFORM SIGN LAHSHU;Lo;0;L;;;;;N;;;;;
+121F2;CUNEIFORM SIGN LAL;Lo;0;L;;;;;N;;;;;
+121F3;CUNEIFORM SIGN LAL TIMES LAL;Lo;0;L;;;;;N;;;;;
+121F4;CUNEIFORM SIGN LAM;Lo;0;L;;;;;N;;;;;
+121F5;CUNEIFORM SIGN LAM TIMES KUR;Lo;0;L;;;;;N;;;;;
+121F6;CUNEIFORM SIGN LAM TIMES KUR PLUS RU;Lo;0;L;;;;;N;;;;;
+121F7;CUNEIFORM SIGN LI;Lo;0;L;;;;;N;;;;;
+121F8;CUNEIFORM SIGN LIL;Lo;0;L;;;;;N;;;;;
+121F9;CUNEIFORM SIGN LIMMU2;Lo;0;L;;;;;N;;;;;
+121FA;CUNEIFORM SIGN LISH;Lo;0;L;;;;;N;;;;;
+121FB;CUNEIFORM SIGN LU;Lo;0;L;;;;;N;;;;;
+121FC;CUNEIFORM SIGN LU TIMES BAD;Lo;0;L;;;;;N;;;;;
+121FD;CUNEIFORM SIGN LU2;Lo;0;L;;;;;N;;;;;
+121FE;CUNEIFORM SIGN LU2 TIMES AL;Lo;0;L;;;;;N;;;;;
+121FF;CUNEIFORM SIGN LU2 TIMES BAD;Lo;0;L;;;;;N;;;;;
+12200;CUNEIFORM SIGN LU2 TIMES ESH2;Lo;0;L;;;;;N;;;;;
+12201;CUNEIFORM SIGN LU2 TIMES ESH2 TENU;Lo;0;L;;;;;N;;;;;
+12202;CUNEIFORM SIGN LU2 TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;;
+12203;CUNEIFORM SIGN LU2 TIMES HI TIMES BAD;Lo;0;L;;;;;N;;;;;
+12204;CUNEIFORM SIGN LU2 TIMES IM;Lo;0;L;;;;;N;;;;;
+12205;CUNEIFORM SIGN LU2 TIMES KAD2;Lo;0;L;;;;;N;;;;;
+12206;CUNEIFORM SIGN LU2 TIMES KAD3;Lo;0;L;;;;;N;;;;;
+12207;CUNEIFORM SIGN LU2 TIMES KAD3 PLUS ASH;Lo;0;L;;;;;N;;;;;
+12208;CUNEIFORM SIGN LU2 TIMES KI;Lo;0;L;;;;;N;;;;;
+12209;CUNEIFORM SIGN LU2 TIMES LA PLUS ASH;Lo;0;L;;;;;N;;;;;
+1220A;CUNEIFORM SIGN LU2 TIMES LAGAB;Lo;0;L;;;;;N;;;;;
+1220B;CUNEIFORM SIGN LU2 TIMES ME PLUS EN;Lo;0;L;;;;;N;;;;;
+1220C;CUNEIFORM SIGN LU2 TIMES NE;Lo;0;L;;;;;N;;;;;
+1220D;CUNEIFORM SIGN LU2 TIMES NU;Lo;0;L;;;;;N;;;;;
+1220E;CUNEIFORM SIGN LU2 TIMES SI PLUS ASH;Lo;0;L;;;;;N;;;;;
+1220F;CUNEIFORM SIGN LU2 TIMES SIK2 PLUS BU;Lo;0;L;;;;;N;;;;;
+12210;CUNEIFORM SIGN LU2 TIMES TUG2;Lo;0;L;;;;;N;;;;;
+12211;CUNEIFORM SIGN LU2 TENU;Lo;0;L;;;;;N;;;;;
+12212;CUNEIFORM SIGN LU2 CROSSING LU2;Lo;0;L;;;;;N;;;;;
+12213;CUNEIFORM SIGN LU2 OPPOSING LU2;Lo;0;L;;;;;N;;;;;
+12214;CUNEIFORM SIGN LU2 SQUARED;Lo;0;L;;;;;N;;;;;
+12215;CUNEIFORM SIGN LU2 SHESHIG;Lo;0;L;;;;;N;;;;;
+12216;CUNEIFORM SIGN LU3;Lo;0;L;;;;;N;;;;;
+12217;CUNEIFORM SIGN LUGAL;Lo;0;L;;;;;N;;;;;
+12218;CUNEIFORM SIGN LUGAL OVER LUGAL;Lo;0;L;;;;;N;;;;;
+12219;CUNEIFORM SIGN LUGAL OPPOSING LUGAL;Lo;0;L;;;;;N;;;;;
+1221A;CUNEIFORM SIGN LUGAL SHESHIG;Lo;0;L;;;;;N;;;;;
+1221B;CUNEIFORM SIGN LUH;Lo;0;L;;;;;N;;;;;
+1221C;CUNEIFORM SIGN LUL;Lo;0;L;;;;;N;;;;;
+1221D;CUNEIFORM SIGN LUM;Lo;0;L;;;;;N;;;;;
+1221E;CUNEIFORM SIGN LUM OVER LUM;Lo;0;L;;;;;N;;;;;
+1221F;CUNEIFORM SIGN LUM OVER LUM GAR OVER GAR;Lo;0;L;;;;;N;;;;;
+12220;CUNEIFORM SIGN MA;Lo;0;L;;;;;N;;;;;
+12221;CUNEIFORM SIGN MA TIMES TAK4;Lo;0;L;;;;;N;;;;;
+12222;CUNEIFORM SIGN MA GUNU;Lo;0;L;;;;;N;;;;;
+12223;CUNEIFORM SIGN MA2;Lo;0;L;;;;;N;;;;;
+12224;CUNEIFORM SIGN MAH;Lo;0;L;;;;;N;;;;;
+12225;CUNEIFORM SIGN MAR;Lo;0;L;;;;;N;;;;;
+12226;CUNEIFORM SIGN MASH;Lo;0;L;;;;;N;;;;;
+12227;CUNEIFORM SIGN MASH2;Lo;0;L;;;;;N;;;;;
+12228;CUNEIFORM SIGN ME;Lo;0;L;;;;;N;;;;;
+12229;CUNEIFORM SIGN MES;Lo;0;L;;;;;N;;;;;
+1222A;CUNEIFORM SIGN MI;Lo;0;L;;;;;N;;;;;
+1222B;CUNEIFORM SIGN MIN;Lo;0;L;;;;;N;;;;;
+1222C;CUNEIFORM SIGN MU;Lo;0;L;;;;;N;;;;;
+1222D;CUNEIFORM SIGN MU OVER MU;Lo;0;L;;;;;N;;;;;
+1222E;CUNEIFORM SIGN MUG;Lo;0;L;;;;;N;;;;;
+1222F;CUNEIFORM SIGN MUG GUNU;Lo;0;L;;;;;N;;;;;
+12230;CUNEIFORM SIGN MUNSUB;Lo;0;L;;;;;N;;;;;
+12231;CUNEIFORM SIGN MURGU2;Lo;0;L;;;;;N;;;;;
+12232;CUNEIFORM SIGN MUSH;Lo;0;L;;;;;N;;;;;
+12233;CUNEIFORM SIGN MUSH TIMES A;Lo;0;L;;;;;N;;;;;
+12234;CUNEIFORM SIGN MUSH TIMES KUR;Lo;0;L;;;;;N;;;;;
+12235;CUNEIFORM SIGN MUSH TIMES ZA;Lo;0;L;;;;;N;;;;;
+12236;CUNEIFORM SIGN MUSH OVER MUSH;Lo;0;L;;;;;N;;;;;
+12237;CUNEIFORM SIGN MUSH OVER MUSH TIMES A PLUS NA;Lo;0;L;;;;;N;;;;;
+12238;CUNEIFORM SIGN MUSH CROSSING MUSH;Lo;0;L;;;;;N;;;;;
+12239;CUNEIFORM SIGN MUSH3;Lo;0;L;;;;;N;;;;;
+1223A;CUNEIFORM SIGN MUSH3 TIMES A;Lo;0;L;;;;;N;;;;;
+1223B;CUNEIFORM SIGN MUSH3 TIMES A PLUS DI;Lo;0;L;;;;;N;;;;;
+1223C;CUNEIFORM SIGN MUSH3 TIMES DI;Lo;0;L;;;;;N;;;;;
+1223D;CUNEIFORM SIGN MUSH3 GUNU;Lo;0;L;;;;;N;;;;;
+1223E;CUNEIFORM SIGN NA;Lo;0;L;;;;;N;;;;;
+1223F;CUNEIFORM SIGN NA2;Lo;0;L;;;;;N;;;;;
+12240;CUNEIFORM SIGN NAGA;Lo;0;L;;;;;N;;;;;
+12241;CUNEIFORM SIGN NAGA INVERTED;Lo;0;L;;;;;N;;;;;
+12242;CUNEIFORM SIGN NAGA TIMES SHU TENU;Lo;0;L;;;;;N;;;;;
+12243;CUNEIFORM SIGN NAGA OPPOSING NAGA;Lo;0;L;;;;;N;;;;;
+12244;CUNEIFORM SIGN NAGAR;Lo;0;L;;;;;N;;;;;
+12245;CUNEIFORM SIGN NAM NUTILLU;Lo;0;L;;;;;N;;;;;
+12246;CUNEIFORM SIGN NAM;Lo;0;L;;;;;N;;;;;
+12247;CUNEIFORM SIGN NAM2;Lo;0;L;;;;;N;;;;;
+12248;CUNEIFORM SIGN NE;Lo;0;L;;;;;N;;;;;
+12249;CUNEIFORM SIGN NE TIMES A;Lo;0;L;;;;;N;;;;;
+1224A;CUNEIFORM SIGN NE TIMES UD;Lo;0;L;;;;;N;;;;;
+1224B;CUNEIFORM SIGN NE SHESHIG;Lo;0;L;;;;;N;;;;;
+1224C;CUNEIFORM SIGN NI;Lo;0;L;;;;;N;;;;;
+1224D;CUNEIFORM SIGN NI TIMES E;Lo;0;L;;;;;N;;;;;
+1224E;CUNEIFORM SIGN NI2;Lo;0;L;;;;;N;;;;;
+1224F;CUNEIFORM SIGN NIM;Lo;0;L;;;;;N;;;;;
+12250;CUNEIFORM SIGN NIM TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;;
+12251;CUNEIFORM SIGN NIM TIMES GAR PLUS GAN2 TENU;Lo;0;L;;;;;N;;;;;
+12252;CUNEIFORM SIGN NINDA2;Lo;0;L;;;;;N;;;;;
+12253;CUNEIFORM SIGN NINDA2 TIMES AN;Lo;0;L;;;;;N;;;;;
+12254;CUNEIFORM SIGN NINDA2 TIMES ASH;Lo;0;L;;;;;N;;;;;
+12255;CUNEIFORM SIGN NINDA2 TIMES ASH PLUS ASH;Lo;0;L;;;;;N;;;;;
+12256;CUNEIFORM SIGN NINDA2 TIMES GUD;Lo;0;L;;;;;N;;;;;
+12257;CUNEIFORM SIGN NINDA2 TIMES ME PLUS GAN2 TENU;Lo;0;L;;;;;N;;;;;
+12258;CUNEIFORM SIGN NINDA2 TIMES NE;Lo;0;L;;;;;N;;;;;
+12259;CUNEIFORM SIGN NINDA2 TIMES NUN;Lo;0;L;;;;;N;;;;;
+1225A;CUNEIFORM SIGN NINDA2 TIMES SHE;Lo;0;L;;;;;N;;;;;
+1225B;CUNEIFORM SIGN NINDA2 TIMES SHE PLUS A AN;Lo;0;L;;;;;N;;;;;
+1225C;CUNEIFORM SIGN NINDA2 TIMES SHE PLUS ASH;Lo;0;L;;;;;N;;;;;
+1225D;CUNEIFORM SIGN NINDA2 TIMES SHE PLUS ASH PLUS ASH;Lo;0;L;;;;;N;;;;;
+1225E;CUNEIFORM SIGN NINDA2 TIMES U2 PLUS ASH;Lo;0;L;;;;;N;;;;;
+1225F;CUNEIFORM SIGN NINDA2 TIMES USH;Lo;0;L;;;;;N;;;;;
+12260;CUNEIFORM SIGN NISAG;Lo;0;L;;;;;N;;;;;
+12261;CUNEIFORM SIGN NU;Lo;0;L;;;;;N;;;;;
+12262;CUNEIFORM SIGN NU11;Lo;0;L;;;;;N;;;;;
+12263;CUNEIFORM SIGN NUN;Lo;0;L;;;;;N;;;;;
+12264;CUNEIFORM SIGN NUN LAGAR TIMES GAR;Lo;0;L;;;;;N;;;;;
+12265;CUNEIFORM SIGN NUN LAGAR TIMES MASH;Lo;0;L;;;;;N;;;;;
+12266;CUNEIFORM SIGN NUN LAGAR TIMES SAL;Lo;0;L;;;;;N;;;;;
+12267;CUNEIFORM SIGN NUN LAGAR TIMES SAL OVER NUN LAGAR TIMES SAL;Lo;0;L;;;;;N;;;;;
+12268;CUNEIFORM SIGN NUN LAGAR TIMES USH;Lo;0;L;;;;;N;;;;;
+12269;CUNEIFORM SIGN NUN TENU;Lo;0;L;;;;;N;;;;;
+1226A;CUNEIFORM SIGN NUN OVER NUN;Lo;0;L;;;;;N;;;;;
+1226B;CUNEIFORM SIGN NUN CROSSING NUN;Lo;0;L;;;;;N;;;;;
+1226C;CUNEIFORM SIGN NUN CROSSING NUN LAGAR OVER LAGAR;Lo;0;L;;;;;N;;;;;
+1226D;CUNEIFORM SIGN NUNUZ;Lo;0;L;;;;;N;;;;;
+1226E;CUNEIFORM SIGN NUNUZ AB2 TIMES ASHGAB;Lo;0;L;;;;;N;;;;;
+1226F;CUNEIFORM SIGN NUNUZ AB2 TIMES BI;Lo;0;L;;;;;N;;;;;
+12270;CUNEIFORM SIGN NUNUZ AB2 TIMES DUG;Lo;0;L;;;;;N;;;;;
+12271;CUNEIFORM SIGN NUNUZ AB2 TIMES GUD;Lo;0;L;;;;;N;;;;;
+12272;CUNEIFORM SIGN NUNUZ AB2 TIMES IGI GUNU;Lo;0;L;;;;;N;;;;;
+12273;CUNEIFORM SIGN NUNUZ AB2 TIMES KAD3;Lo;0;L;;;;;N;;;;;
+12274;CUNEIFORM SIGN NUNUZ AB2 TIMES LA;Lo;0;L;;;;;N;;;;;
+12275;CUNEIFORM SIGN NUNUZ AB2 TIMES NE;Lo;0;L;;;;;N;;;;;
+12276;CUNEIFORM SIGN NUNUZ AB2 TIMES SILA3;Lo;0;L;;;;;N;;;;;
+12277;CUNEIFORM SIGN NUNUZ AB2 TIMES U2;Lo;0;L;;;;;N;;;;;
+12278;CUNEIFORM SIGN NUNUZ KISIM5 TIMES BI;Lo;0;L;;;;;N;;;;;
+12279;CUNEIFORM SIGN NUNUZ KISIM5 TIMES BI U;Lo;0;L;;;;;N;;;;;
+1227A;CUNEIFORM SIGN PA;Lo;0;L;;;;;N;;;;;
+1227B;CUNEIFORM SIGN PAD;Lo;0;L;;;;;N;;;;;
+1227C;CUNEIFORM SIGN PAN;Lo;0;L;;;;;N;;;;;
+1227D;CUNEIFORM SIGN PAP;Lo;0;L;;;;;N;;;;;
+1227E;CUNEIFORM SIGN PESH2;Lo;0;L;;;;;N;;;;;
+1227F;CUNEIFORM SIGN PI;Lo;0;L;;;;;N;;;;;
+12280;CUNEIFORM SIGN PI TIMES A;Lo;0;L;;;;;N;;;;;
+12281;CUNEIFORM SIGN PI TIMES AB;Lo;0;L;;;;;N;;;;;
+12282;CUNEIFORM SIGN PI TIMES BI;Lo;0;L;;;;;N;;;;;
+12283;CUNEIFORM SIGN PI TIMES BU;Lo;0;L;;;;;N;;;;;
+12284;CUNEIFORM SIGN PI TIMES E;Lo;0;L;;;;;N;;;;;
+12285;CUNEIFORM SIGN PI TIMES I;Lo;0;L;;;;;N;;;;;
+12286;CUNEIFORM SIGN PI TIMES IB;Lo;0;L;;;;;N;;;;;
+12287;CUNEIFORM SIGN PI TIMES U;Lo;0;L;;;;;N;;;;;
+12288;CUNEIFORM SIGN PI TIMES U2;Lo;0;L;;;;;N;;;;;
+12289;CUNEIFORM SIGN PI CROSSING PI;Lo;0;L;;;;;N;;;;;
+1228A;CUNEIFORM SIGN PIRIG;Lo;0;L;;;;;N;;;;;
+1228B;CUNEIFORM SIGN PIRIG TIMES KAL;Lo;0;L;;;;;N;;;;;
+1228C;CUNEIFORM SIGN PIRIG TIMES UD;Lo;0;L;;;;;N;;;;;
+1228D;CUNEIFORM SIGN PIRIG TIMES ZA;Lo;0;L;;;;;N;;;;;
+1228E;CUNEIFORM SIGN PIRIG OPPOSING PIRIG;Lo;0;L;;;;;N;;;;;
+1228F;CUNEIFORM SIGN RA;Lo;0;L;;;;;N;;;;;
+12290;CUNEIFORM SIGN RAB;Lo;0;L;;;;;N;;;;;
+12291;CUNEIFORM SIGN RI;Lo;0;L;;;;;N;;;;;
+12292;CUNEIFORM SIGN RU;Lo;0;L;;;;;N;;;;;
+12293;CUNEIFORM SIGN SA;Lo;0;L;;;;;N;;;;;
+12294;CUNEIFORM SIGN SAG NUTILLU;Lo;0;L;;;;;N;;;;;
+12295;CUNEIFORM SIGN SAG;Lo;0;L;;;;;N;;;;;
+12296;CUNEIFORM SIGN SAG TIMES A;Lo;0;L;;;;;N;;;;;
+12297;CUNEIFORM SIGN SAG TIMES DU;Lo;0;L;;;;;N;;;;;
+12298;CUNEIFORM SIGN SAG TIMES DUB;Lo;0;L;;;;;N;;;;;
+12299;CUNEIFORM SIGN SAG TIMES HA;Lo;0;L;;;;;N;;;;;
+1229A;CUNEIFORM SIGN SAG TIMES KAK;Lo;0;L;;;;;N;;;;;
+1229B;CUNEIFORM SIGN SAG TIMES KUR;Lo;0;L;;;;;N;;;;;
+1229C;CUNEIFORM SIGN SAG TIMES LUM;Lo;0;L;;;;;N;;;;;
+1229D;CUNEIFORM SIGN SAG TIMES MI;Lo;0;L;;;;;N;;;;;
+1229E;CUNEIFORM SIGN SAG TIMES NUN;Lo;0;L;;;;;N;;;;;
+1229F;CUNEIFORM SIGN SAG TIMES SAL;Lo;0;L;;;;;N;;;;;
+122A0;CUNEIFORM SIGN SAG TIMES SHID;Lo;0;L;;;;;N;;;;;
+122A1;CUNEIFORM SIGN SAG TIMES TAB;Lo;0;L;;;;;N;;;;;
+122A2;CUNEIFORM SIGN SAG TIMES U2;Lo;0;L;;;;;N;;;;;
+122A3;CUNEIFORM SIGN SAG TIMES UB;Lo;0;L;;;;;N;;;;;
+122A4;CUNEIFORM SIGN SAG TIMES UM;Lo;0;L;;;;;N;;;;;
+122A5;CUNEIFORM SIGN SAG TIMES UR;Lo;0;L;;;;;N;;;;;
+122A6;CUNEIFORM SIGN SAG TIMES USH;Lo;0;L;;;;;N;;;;;
+122A7;CUNEIFORM SIGN SAG OVER SAG;Lo;0;L;;;;;N;;;;;
+122A8;CUNEIFORM SIGN SAG GUNU;Lo;0;L;;;;;N;;;;;
+122A9;CUNEIFORM SIGN SAL;Lo;0;L;;;;;N;;;;;
+122AA;CUNEIFORM SIGN SAL LAGAB TIMES ASH2;Lo;0;L;;;;;N;;;;;
+122AB;CUNEIFORM SIGN SANGA2;Lo;0;L;;;;;N;;;;;
+122AC;CUNEIFORM SIGN SAR;Lo;0;L;;;;;N;;;;;
+122AD;CUNEIFORM SIGN SHA;Lo;0;L;;;;;N;;;;;
+122AE;CUNEIFORM SIGN SHA3;Lo;0;L;;;;;N;;;;;
+122AF;CUNEIFORM SIGN SHA3 TIMES A;Lo;0;L;;;;;N;;;;;
+122B0;CUNEIFORM SIGN SHA3 TIMES BAD;Lo;0;L;;;;;N;;;;;
+122B1;CUNEIFORM SIGN SHA3 TIMES GISH;Lo;0;L;;;;;N;;;;;
+122B2;CUNEIFORM SIGN SHA3 TIMES NE;Lo;0;L;;;;;N;;;;;
+122B3;CUNEIFORM SIGN SHA3 TIMES SHU2;Lo;0;L;;;;;N;;;;;
+122B4;CUNEIFORM SIGN SHA3 TIMES TUR;Lo;0;L;;;;;N;;;;;
+122B5;CUNEIFORM SIGN SHA3 TIMES U;Lo;0;L;;;;;N;;;;;
+122B6;CUNEIFORM SIGN SHA3 TIMES U PLUS A;Lo;0;L;;;;;N;;;;;
+122B7;CUNEIFORM SIGN SHA6;Lo;0;L;;;;;N;;;;;
+122B8;CUNEIFORM SIGN SHAB6;Lo;0;L;;;;;N;;;;;
+122B9;CUNEIFORM SIGN SHAR2;Lo;0;L;;;;;N;;;;;
+122BA;CUNEIFORM SIGN SHE;Lo;0;L;;;;;N;;;;;
+122BB;CUNEIFORM SIGN SHE HU;Lo;0;L;;;;;N;;;;;
+122BC;CUNEIFORM SIGN SHE OVER SHE GAD OVER GAD GAR OVER GAR;Lo;0;L;;;;;N;;;;;
+122BD;CUNEIFORM SIGN SHE OVER SHE TAB OVER TAB GAR OVER GAR;Lo;0;L;;;;;N;;;;;
+122BE;CUNEIFORM SIGN SHEG9;Lo;0;L;;;;;N;;;;;
+122BF;CUNEIFORM SIGN SHEN;Lo;0;L;;;;;N;;;;;
+122C0;CUNEIFORM SIGN SHESH;Lo;0;L;;;;;N;;;;;
+122C1;CUNEIFORM SIGN SHESH2;Lo;0;L;;;;;N;;;;;
+122C2;CUNEIFORM SIGN SHESHLAM;Lo;0;L;;;;;N;;;;;
+122C3;CUNEIFORM SIGN SHID;Lo;0;L;;;;;N;;;;;
+122C4;CUNEIFORM SIGN SHID TIMES A;Lo;0;L;;;;;N;;;;;
+122C5;CUNEIFORM SIGN SHID TIMES IM;Lo;0;L;;;;;N;;;;;
+122C6;CUNEIFORM SIGN SHIM;Lo;0;L;;;;;N;;;;;
+122C7;CUNEIFORM SIGN SHIM TIMES A;Lo;0;L;;;;;N;;;;;
+122C8;CUNEIFORM SIGN SHIM TIMES BAL;Lo;0;L;;;;;N;;;;;
+122C9;CUNEIFORM SIGN SHIM TIMES BULUG;Lo;0;L;;;;;N;;;;;
+122CA;CUNEIFORM SIGN SHIM TIMES DIN;Lo;0;L;;;;;N;;;;;
+122CB;CUNEIFORM SIGN SHIM TIMES GAR;Lo;0;L;;;;;N;;;;;
+122CC;CUNEIFORM SIGN SHIM TIMES IGI;Lo;0;L;;;;;N;;;;;
+122CD;CUNEIFORM SIGN SHIM TIMES IGI GUNU;Lo;0;L;;;;;N;;;;;
+122CE;CUNEIFORM SIGN SHIM TIMES KUSHU2;Lo;0;L;;;;;N;;;;;
+122CF;CUNEIFORM SIGN SHIM TIMES LUL;Lo;0;L;;;;;N;;;;;
+122D0;CUNEIFORM SIGN SHIM TIMES MUG;Lo;0;L;;;;;N;;;;;
+122D1;CUNEIFORM SIGN SHIM TIMES SAL;Lo;0;L;;;;;N;;;;;
+122D2;CUNEIFORM SIGN SHINIG;Lo;0;L;;;;;N;;;;;
+122D3;CUNEIFORM SIGN SHIR;Lo;0;L;;;;;N;;;;;
+122D4;CUNEIFORM SIGN SHIR TENU;Lo;0;L;;;;;N;;;;;
+122D5;CUNEIFORM SIGN SHIR OVER SHIR BUR OVER BUR;Lo;0;L;;;;;N;;;;;
+122D6;CUNEIFORM SIGN SHITA;Lo;0;L;;;;;N;;;;;
+122D7;CUNEIFORM SIGN SHU;Lo;0;L;;;;;N;;;;;
+122D8;CUNEIFORM SIGN SHU OVER INVERTED SHU;Lo;0;L;;;;;N;;;;;
+122D9;CUNEIFORM SIGN SHU2;Lo;0;L;;;;;N;;;;;
+122DA;CUNEIFORM SIGN SHUBUR;Lo;0;L;;;;;N;;;;;
+122DB;CUNEIFORM SIGN SI;Lo;0;L;;;;;N;;;;;
+122DC;CUNEIFORM SIGN SI GUNU;Lo;0;L;;;;;N;;;;;
+122DD;CUNEIFORM SIGN SIG;Lo;0;L;;;;;N;;;;;
+122DE;CUNEIFORM SIGN SIG4;Lo;0;L;;;;;N;;;;;
+122DF;CUNEIFORM SIGN SIG4 OVER SIG4 SHU2;Lo;0;L;;;;;N;;;;;
+122E0;CUNEIFORM SIGN SIK2;Lo;0;L;;;;;N;;;;;
+122E1;CUNEIFORM SIGN SILA3;Lo;0;L;;;;;N;;;;;
+122E2;CUNEIFORM SIGN SU;Lo;0;L;;;;;N;;;;;
+122E3;CUNEIFORM SIGN SU OVER SU;Lo;0;L;;;;;N;;;;;
+122E4;CUNEIFORM SIGN SUD;Lo;0;L;;;;;N;;;;;
+122E5;CUNEIFORM SIGN SUD2;Lo;0;L;;;;;N;;;;;
+122E6;CUNEIFORM SIGN SUHUR;Lo;0;L;;;;;N;;;;;
+122E7;CUNEIFORM SIGN SUM;Lo;0;L;;;;;N;;;;;
+122E8;CUNEIFORM SIGN SUMASH;Lo;0;L;;;;;N;;;;;
+122E9;CUNEIFORM SIGN SUR;Lo;0;L;;;;;N;;;;;
+122EA;CUNEIFORM SIGN SUR9;Lo;0;L;;;;;N;;;;;
+122EB;CUNEIFORM SIGN TA;Lo;0;L;;;;;N;;;;;
+122EC;CUNEIFORM SIGN TA ASTERISK;Lo;0;L;;;;;N;;;;;
+122ED;CUNEIFORM SIGN TA TIMES HI;Lo;0;L;;;;;N;;;;;
+122EE;CUNEIFORM SIGN TA TIMES MI;Lo;0;L;;;;;N;;;;;
+122EF;CUNEIFORM SIGN TA GUNU;Lo;0;L;;;;;N;;;;;
+122F0;CUNEIFORM SIGN TAB;Lo;0;L;;;;;N;;;;;
+122F1;CUNEIFORM SIGN TAB OVER TAB NI OVER NI DISH OVER DISH;Lo;0;L;;;;;N;;;;;
+122F2;CUNEIFORM SIGN TAB SQUARED;Lo;0;L;;;;;N;;;;;
+122F3;CUNEIFORM SIGN TAG;Lo;0;L;;;;;N;;;;;
+122F4;CUNEIFORM SIGN TAG TIMES BI;Lo;0;L;;;;;N;;;;;
+122F5;CUNEIFORM SIGN TAG TIMES GUD;Lo;0;L;;;;;N;;;;;
+122F6;CUNEIFORM SIGN TAG TIMES SHE;Lo;0;L;;;;;N;;;;;
+122F7;CUNEIFORM SIGN TAG TIMES SHU;Lo;0;L;;;;;N;;;;;
+122F8;CUNEIFORM SIGN TAG TIMES TUG2;Lo;0;L;;;;;N;;;;;
+122F9;CUNEIFORM SIGN TAG TIMES UD;Lo;0;L;;;;;N;;;;;
+122FA;CUNEIFORM SIGN TAK4;Lo;0;L;;;;;N;;;;;
+122FB;CUNEIFORM SIGN TAR;Lo;0;L;;;;;N;;;;;
+122FC;CUNEIFORM SIGN TE;Lo;0;L;;;;;N;;;;;
+122FD;CUNEIFORM SIGN TE GUNU;Lo;0;L;;;;;N;;;;;
+122FE;CUNEIFORM SIGN TI;Lo;0;L;;;;;N;;;;;
+122FF;CUNEIFORM SIGN TI TENU;Lo;0;L;;;;;N;;;;;
+12300;CUNEIFORM SIGN TIL;Lo;0;L;;;;;N;;;;;
+12301;CUNEIFORM SIGN TIR;Lo;0;L;;;;;N;;;;;
+12302;CUNEIFORM SIGN TIR TIMES TAK4;Lo;0;L;;;;;N;;;;;
+12303;CUNEIFORM SIGN TIR OVER TIR;Lo;0;L;;;;;N;;;;;
+12304;CUNEIFORM SIGN TIR OVER TIR GAD OVER GAD GAR OVER GAR;Lo;0;L;;;;;N;;;;;
+12305;CUNEIFORM SIGN TU;Lo;0;L;;;;;N;;;;;
+12306;CUNEIFORM SIGN TUG2;Lo;0;L;;;;;N;;;;;
+12307;CUNEIFORM SIGN TUK;Lo;0;L;;;;;N;;;;;
+12308;CUNEIFORM SIGN TUM;Lo;0;L;;;;;N;;;;;
+12309;CUNEIFORM SIGN TUR;Lo;0;L;;;;;N;;;;;
+1230A;CUNEIFORM SIGN TUR OVER TUR ZA OVER ZA;Lo;0;L;;;;;N;;;;;
+1230B;CUNEIFORM SIGN U;Lo;0;L;;;;;N;;;;;
+1230C;CUNEIFORM SIGN U GUD;Lo;0;L;;;;;N;;;;;
+1230D;CUNEIFORM SIGN U U U;Lo;0;L;;;;;N;;;;;
+1230E;CUNEIFORM SIGN U OVER U PA OVER PA GAR OVER GAR;Lo;0;L;;;;;N;;;;;
+1230F;CUNEIFORM SIGN U OVER U SUR OVER SUR;Lo;0;L;;;;;N;;;;;
+12310;CUNEIFORM SIGN U OVER U U REVERSED OVER U REVERSED;Lo;0;L;;;;;N;;;;;
+12311;CUNEIFORM SIGN U2;Lo;0;L;;;;;N;;;;;
+12312;CUNEIFORM SIGN UB;Lo;0;L;;;;;N;;;;;
+12313;CUNEIFORM SIGN UD;Lo;0;L;;;;;N;;;;;
+12314;CUNEIFORM SIGN UD KUSHU2;Lo;0;L;;;;;N;;;;;
+12315;CUNEIFORM SIGN UD TIMES BAD;Lo;0;L;;;;;N;;;;;
+12316;CUNEIFORM SIGN UD TIMES MI;Lo;0;L;;;;;N;;;;;
+12317;CUNEIFORM SIGN UD TIMES U PLUS U PLUS U;Lo;0;L;;;;;N;;;;;
+12318;CUNEIFORM SIGN UD TIMES U PLUS U PLUS U GUNU;Lo;0;L;;;;;N;;;;;
+12319;CUNEIFORM SIGN UD GUNU;Lo;0;L;;;;;N;;;;;
+1231A;CUNEIFORM SIGN UD SHESHIG;Lo;0;L;;;;;N;;;;;
+1231B;CUNEIFORM SIGN UD SHESHIG TIMES BAD;Lo;0;L;;;;;N;;;;;
+1231C;CUNEIFORM SIGN UDUG;Lo;0;L;;;;;N;;;;;
+1231D;CUNEIFORM SIGN UM;Lo;0;L;;;;;N;;;;;
+1231E;CUNEIFORM SIGN UM TIMES LAGAB;Lo;0;L;;;;;N;;;;;
+1231F;CUNEIFORM SIGN UM TIMES ME PLUS DA;Lo;0;L;;;;;N;;;;;
+12320;CUNEIFORM SIGN UM TIMES SHA3;Lo;0;L;;;;;N;;;;;
+12321;CUNEIFORM SIGN UM TIMES U;Lo;0;L;;;;;N;;;;;
+12322;CUNEIFORM SIGN UMBIN;Lo;0;L;;;;;N;;;;;
+12323;CUNEIFORM SIGN UMUM;Lo;0;L;;;;;N;;;;;
+12324;CUNEIFORM SIGN UMUM TIMES KASKAL;Lo;0;L;;;;;N;;;;;
+12325;CUNEIFORM SIGN UMUM TIMES PA;Lo;0;L;;;;;N;;;;;
+12326;CUNEIFORM SIGN UN;Lo;0;L;;;;;N;;;;;
+12327;CUNEIFORM SIGN UN GUNU;Lo;0;L;;;;;N;;;;;
+12328;CUNEIFORM SIGN UR;Lo;0;L;;;;;N;;;;;
+12329;CUNEIFORM SIGN UR CROSSING UR;Lo;0;L;;;;;N;;;;;
+1232A;CUNEIFORM SIGN UR SHESHIG;Lo;0;L;;;;;N;;;;;
+1232B;CUNEIFORM SIGN UR2;Lo;0;L;;;;;N;;;;;
+1232C;CUNEIFORM SIGN UR2 TIMES A PLUS HA;Lo;0;L;;;;;N;;;;;
+1232D;CUNEIFORM SIGN UR2 TIMES A PLUS NA;Lo;0;L;;;;;N;;;;;
+1232E;CUNEIFORM SIGN UR2 TIMES AL;Lo;0;L;;;;;N;;;;;
+1232F;CUNEIFORM SIGN UR2 TIMES HA;Lo;0;L;;;;;N;;;;;
+12330;CUNEIFORM SIGN UR2 TIMES NUN;Lo;0;L;;;;;N;;;;;
+12331;CUNEIFORM SIGN UR2 TIMES U2;Lo;0;L;;;;;N;;;;;
+12332;CUNEIFORM SIGN UR2 TIMES U2 PLUS ASH;Lo;0;L;;;;;N;;;;;
+12333;CUNEIFORM SIGN UR2 TIMES U2 PLUS BI;Lo;0;L;;;;;N;;;;;
+12334;CUNEIFORM SIGN UR4;Lo;0;L;;;;;N;;;;;
+12335;CUNEIFORM SIGN URI;Lo;0;L;;;;;N;;;;;
+12336;CUNEIFORM SIGN URI3;Lo;0;L;;;;;N;;;;;
+12337;CUNEIFORM SIGN URU;Lo;0;L;;;;;N;;;;;
+12338;CUNEIFORM SIGN URU TIMES A;Lo;0;L;;;;;N;;;;;
+12339;CUNEIFORM SIGN URU TIMES ASHGAB;Lo;0;L;;;;;N;;;;;
+1233A;CUNEIFORM SIGN URU TIMES BAR;Lo;0;L;;;;;N;;;;;
+1233B;CUNEIFORM SIGN URU TIMES DUN;Lo;0;L;;;;;N;;;;;
+1233C;CUNEIFORM SIGN URU TIMES GA;Lo;0;L;;;;;N;;;;;
+1233D;CUNEIFORM SIGN URU TIMES GAL;Lo;0;L;;;;;N;;;;;
+1233E;CUNEIFORM SIGN URU TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;;
+1233F;CUNEIFORM SIGN URU TIMES GAR;Lo;0;L;;;;;N;;;;;
+12340;CUNEIFORM SIGN URU TIMES GU;Lo;0;L;;;;;N;;;;;
+12341;CUNEIFORM SIGN URU TIMES HA;Lo;0;L;;;;;N;;;;;
+12342;CUNEIFORM SIGN URU TIMES IGI;Lo;0;L;;;;;N;;;;;
+12343;CUNEIFORM SIGN URU TIMES IM;Lo;0;L;;;;;N;;;;;
+12344;CUNEIFORM SIGN URU TIMES ISH;Lo;0;L;;;;;N;;;;;
+12345;CUNEIFORM SIGN URU TIMES KI;Lo;0;L;;;;;N;;;;;
+12346;CUNEIFORM SIGN URU TIMES LUM;Lo;0;L;;;;;N;;;;;
+12347;CUNEIFORM SIGN URU TIMES MIN;Lo;0;L;;;;;N;;;;;
+12348;CUNEIFORM SIGN URU TIMES PA;Lo;0;L;;;;;N;;;;;
+12349;CUNEIFORM SIGN URU TIMES SHE;Lo;0;L;;;;;N;;;;;
+1234A;CUNEIFORM SIGN URU TIMES SIG4;Lo;0;L;;;;;N;;;;;
+1234B;CUNEIFORM SIGN URU TIMES TU;Lo;0;L;;;;;N;;;;;
+1234C;CUNEIFORM SIGN URU TIMES U PLUS GUD;Lo;0;L;;;;;N;;;;;
+1234D;CUNEIFORM SIGN URU TIMES UD;Lo;0;L;;;;;N;;;;;
+1234E;CUNEIFORM SIGN URU TIMES URUDA;Lo;0;L;;;;;N;;;;;
+1234F;CUNEIFORM SIGN URUDA;Lo;0;L;;;;;N;;;;;
+12350;CUNEIFORM SIGN URUDA TIMES U;Lo;0;L;;;;;N;;;;;
+12351;CUNEIFORM SIGN USH;Lo;0;L;;;;;N;;;;;
+12352;CUNEIFORM SIGN USH TIMES A;Lo;0;L;;;;;N;;;;;
+12353;CUNEIFORM SIGN USH TIMES KU;Lo;0;L;;;;;N;;;;;
+12354;CUNEIFORM SIGN USH TIMES KUR;Lo;0;L;;;;;N;;;;;
+12355;CUNEIFORM SIGN USH TIMES TAK4;Lo;0;L;;;;;N;;;;;
+12356;CUNEIFORM SIGN USHX;Lo;0;L;;;;;N;;;;;
+12357;CUNEIFORM SIGN USH2;Lo;0;L;;;;;N;;;;;
+12358;CUNEIFORM SIGN USHUMX;Lo;0;L;;;;;N;;;;;
+12359;CUNEIFORM SIGN UTUKI;Lo;0;L;;;;;N;;;;;
+1235A;CUNEIFORM SIGN UZ3;Lo;0;L;;;;;N;;;;;
+1235B;CUNEIFORM SIGN UZ3 TIMES KASKAL;Lo;0;L;;;;;N;;;;;
+1235C;CUNEIFORM SIGN UZU;Lo;0;L;;;;;N;;;;;
+1235D;CUNEIFORM SIGN ZA;Lo;0;L;;;;;N;;;;;
+1235E;CUNEIFORM SIGN ZA TENU;Lo;0;L;;;;;N;;;;;
+1235F;CUNEIFORM SIGN ZA SQUARED TIMES KUR;Lo;0;L;;;;;N;;;;;
+12360;CUNEIFORM SIGN ZAG;Lo;0;L;;;;;N;;;;;
+12361;CUNEIFORM SIGN ZAMX;Lo;0;L;;;;;N;;;;;
+12362;CUNEIFORM SIGN ZE2;Lo;0;L;;;;;N;;;;;
+12363;CUNEIFORM SIGN ZI;Lo;0;L;;;;;N;;;;;
+12364;CUNEIFORM SIGN ZI OVER ZI;Lo;0;L;;;;;N;;;;;
+12365;CUNEIFORM SIGN ZI3;Lo;0;L;;;;;N;;;;;
+12366;CUNEIFORM SIGN ZIB;Lo;0;L;;;;;N;;;;;
+12367;CUNEIFORM SIGN ZIB KABA TENU;Lo;0;L;;;;;N;;;;;
+12368;CUNEIFORM SIGN ZIG;Lo;0;L;;;;;N;;;;;
+12369;CUNEIFORM SIGN ZIZ2;Lo;0;L;;;;;N;;;;;
+1236A;CUNEIFORM SIGN ZU;Lo;0;L;;;;;N;;;;;
+1236B;CUNEIFORM SIGN ZU5;Lo;0;L;;;;;N;;;;;
+1236C;CUNEIFORM SIGN ZU5 TIMES A;Lo;0;L;;;;;N;;;;;
+1236D;CUNEIFORM SIGN ZUBUR;Lo;0;L;;;;;N;;;;;
+1236E;CUNEIFORM SIGN ZUM;Lo;0;L;;;;;N;;;;;
+12400;CUNEIFORM NUMERIC SIGN TWO ASH;Nl;0;L;;;;2;N;;;;;
+12401;CUNEIFORM NUMERIC SIGN THREE ASH;Nl;0;L;;;;3;N;;;;;
+12402;CUNEIFORM NUMERIC SIGN FOUR ASH;Nl;0;L;;;;4;N;;;;;
+12403;CUNEIFORM NUMERIC SIGN FIVE ASH;Nl;0;L;;;;5;N;;;;;
+12404;CUNEIFORM NUMERIC SIGN SIX ASH;Nl;0;L;;;;6;N;;;;;
+12405;CUNEIFORM NUMERIC SIGN SEVEN ASH;Nl;0;L;;;;7;N;;;;;
+12406;CUNEIFORM NUMERIC SIGN EIGHT ASH;Nl;0;L;;;;8;N;;;;;
+12407;CUNEIFORM NUMERIC SIGN NINE ASH;Nl;0;L;;;;9;N;;;;;
+12408;CUNEIFORM NUMERIC SIGN THREE DISH;Nl;0;L;;;;3;N;;;;;
+12409;CUNEIFORM NUMERIC SIGN FOUR DISH;Nl;0;L;;;;4;N;;;;;
+1240A;CUNEIFORM NUMERIC SIGN FIVE DISH;Nl;0;L;;;;5;N;;;;;
+1240B;CUNEIFORM NUMERIC SIGN SIX DISH;Nl;0;L;;;;6;N;;;;;
+1240C;CUNEIFORM NUMERIC SIGN SEVEN DISH;Nl;0;L;;;;7;N;;;;;
+1240D;CUNEIFORM NUMERIC SIGN EIGHT DISH;Nl;0;L;;;;8;N;;;;;
+1240E;CUNEIFORM NUMERIC SIGN NINE DISH;Nl;0;L;;;;9;N;;;;;
+1240F;CUNEIFORM NUMERIC SIGN FOUR U;Nl;0;L;;;;4;N;;;;;
+12410;CUNEIFORM NUMERIC SIGN FIVE U;Nl;0;L;;;;5;N;;;;;
+12411;CUNEIFORM NUMERIC SIGN SIX U;Nl;0;L;;;;6;N;;;;;
+12412;CUNEIFORM NUMERIC SIGN SEVEN U;Nl;0;L;;;;7;N;;;;;
+12413;CUNEIFORM NUMERIC SIGN EIGHT U;Nl;0;L;;;;8;N;;;;;
+12414;CUNEIFORM NUMERIC SIGN NINE U;Nl;0;L;;;;9;N;;;;;
+12415;CUNEIFORM NUMERIC SIGN ONE GESH2;Nl;0;L;;;;1;N;;;;;
+12416;CUNEIFORM NUMERIC SIGN TWO GESH2;Nl;0;L;;;;2;N;;;;;
+12417;CUNEIFORM NUMERIC SIGN THREE GESH2;Nl;0;L;;;;3;N;;;;;
+12418;CUNEIFORM NUMERIC SIGN FOUR GESH2;Nl;0;L;;;;4;N;;;;;
+12419;CUNEIFORM NUMERIC SIGN FIVE GESH2;Nl;0;L;;;;5;N;;;;;
+1241A;CUNEIFORM NUMERIC SIGN SIX GESH2;Nl;0;L;;;;6;N;;;;;
+1241B;CUNEIFORM NUMERIC SIGN SEVEN GESH2;Nl;0;L;;;;7;N;;;;;
+1241C;CUNEIFORM NUMERIC SIGN EIGHT GESH2;Nl;0;L;;;;8;N;;;;;
+1241D;CUNEIFORM NUMERIC SIGN NINE GESH2;Nl;0;L;;;;9;N;;;;;
+1241E;CUNEIFORM NUMERIC SIGN ONE GESHU;Nl;0;L;;;;1;N;;;;;
+1241F;CUNEIFORM NUMERIC SIGN TWO GESHU;Nl;0;L;;;;2;N;;;;;
+12420;CUNEIFORM NUMERIC SIGN THREE GESHU;Nl;0;L;;;;3;N;;;;;
+12421;CUNEIFORM NUMERIC SIGN FOUR GESHU;Nl;0;L;;;;4;N;;;;;
+12422;CUNEIFORM NUMERIC SIGN FIVE GESHU;Nl;0;L;;;;5;N;;;;;
+12423;CUNEIFORM NUMERIC SIGN TWO SHAR2;Nl;0;L;;;;2;N;;;;;
+12424;CUNEIFORM NUMERIC SIGN THREE SHAR2;Nl;0;L;;;;3;N;;;;;
+12425;CUNEIFORM NUMERIC SIGN THREE SHAR2 VARIANT FORM;Nl;0;L;;;;3;N;;;;;
+12426;CUNEIFORM NUMERIC SIGN FOUR SHAR2;Nl;0;L;;;;4;N;;;;;
+12427;CUNEIFORM NUMERIC SIGN FIVE SHAR2;Nl;0;L;;;;5;N;;;;;
+12428;CUNEIFORM NUMERIC SIGN SIX SHAR2;Nl;0;L;;;;6;N;;;;;
+12429;CUNEIFORM NUMERIC SIGN SEVEN SHAR2;Nl;0;L;;;;7;N;;;;;
+1242A;CUNEIFORM NUMERIC SIGN EIGHT SHAR2;Nl;0;L;;;;8;N;;;;;
+1242B;CUNEIFORM NUMERIC SIGN NINE SHAR2;Nl;0;L;;;;9;N;;;;;
+1242C;CUNEIFORM NUMERIC SIGN ONE SHARU;Nl;0;L;;;;1;N;;;;;
+1242D;CUNEIFORM NUMERIC SIGN TWO SHARU;Nl;0;L;;;;2;N;;;;;
+1242E;CUNEIFORM NUMERIC SIGN THREE SHARU;Nl;0;L;;;;3;N;;;;;
+1242F;CUNEIFORM NUMERIC SIGN THREE SHARU VARIANT FORM;Nl;0;L;;;;3;N;;;;;
+12430;CUNEIFORM NUMERIC SIGN FOUR SHARU;Nl;0;L;;;;4;N;;;;;
+12431;CUNEIFORM NUMERIC SIGN FIVE SHARU;Nl;0;L;;;;5;N;;;;;
+12432;CUNEIFORM NUMERIC SIGN SHAR2 TIMES GAL PLUS DISH;Nl;0;L;;;;;N;;;;;
+12433;CUNEIFORM NUMERIC SIGN SHAR2 TIMES GAL PLUS MIN;Nl;0;L;;;;;N;;;;;
+12434;CUNEIFORM NUMERIC SIGN ONE BURU;Nl;0;L;;;;1;N;;;;;
+12435;CUNEIFORM NUMERIC SIGN TWO BURU;Nl;0;L;;;;2;N;;;;;
+12436;CUNEIFORM NUMERIC SIGN THREE BURU;Nl;0;L;;;;3;N;;;;;
+12437;CUNEIFORM NUMERIC SIGN THREE BURU VARIANT FORM;Nl;0;L;;;;3;N;;;;;
+12438;CUNEIFORM NUMERIC SIGN FOUR BURU;Nl;0;L;;;;4;N;;;;;
+12439;CUNEIFORM NUMERIC SIGN FIVE BURU;Nl;0;L;;;;5;N;;;;;
+1243A;CUNEIFORM NUMERIC SIGN THREE VARIANT FORM ESH16;Nl;0;L;;;;3;N;;;;;
+1243B;CUNEIFORM NUMERIC SIGN THREE VARIANT FORM ESH21;Nl;0;L;;;;3;N;;;;;
+1243C;CUNEIFORM NUMERIC SIGN FOUR VARIANT FORM LIMMU;Nl;0;L;;;;4;N;;;;;
+1243D;CUNEIFORM NUMERIC SIGN FOUR VARIANT FORM LIMMU4;Nl;0;L;;;;4;N;;;;;
+1243E;CUNEIFORM NUMERIC SIGN FOUR VARIANT FORM LIMMU A;Nl;0;L;;;;4;N;;;;;
+1243F;CUNEIFORM NUMERIC SIGN FOUR VARIANT FORM LIMMU B;Nl;0;L;;;;4;N;;;;;
+12440;CUNEIFORM NUMERIC SIGN SIX VARIANT FORM ASH9;Nl;0;L;;;;6;N;;;;;
+12441;CUNEIFORM NUMERIC SIGN SEVEN VARIANT FORM IMIN3;Nl;0;L;;;;7;N;;;;;
+12442;CUNEIFORM NUMERIC SIGN SEVEN VARIANT FORM IMIN A;Nl;0;L;;;;7;N;;;;;
+12443;CUNEIFORM NUMERIC SIGN SEVEN VARIANT FORM IMIN B;Nl;0;L;;;;7;N;;;;;
+12444;CUNEIFORM NUMERIC SIGN EIGHT VARIANT FORM USSU;Nl;0;L;;;;8;N;;;;;
+12445;CUNEIFORM NUMERIC SIGN EIGHT VARIANT FORM USSU3;Nl;0;L;;;;8;N;;;;;
+12446;CUNEIFORM NUMERIC SIGN NINE VARIANT FORM ILIMMU;Nl;0;L;;;;9;N;;;;;
+12447;CUNEIFORM NUMERIC SIGN NINE VARIANT FORM ILIMMU3;Nl;0;L;;;;9;N;;;;;
+12448;CUNEIFORM NUMERIC SIGN NINE VARIANT FORM ILIMMU4;Nl;0;L;;;;9;N;;;;;
+12449;CUNEIFORM NUMERIC SIGN NINE VARIANT FORM ILIMMU A;Nl;0;L;;;;9;N;;;;;
+1244A;CUNEIFORM NUMERIC SIGN TWO ASH TENU;Nl;0;L;;;;2;N;;;;;
+1244B;CUNEIFORM NUMERIC SIGN THREE ASH TENU;Nl;0;L;;;;3;N;;;;;
+1244C;CUNEIFORM NUMERIC SIGN FOUR ASH TENU;Nl;0;L;;;;4;N;;;;;
+1244D;CUNEIFORM NUMERIC SIGN FIVE ASH TENU;Nl;0;L;;;;5;N;;;;;
+1244E;CUNEIFORM NUMERIC SIGN SIX ASH TENU;Nl;0;L;;;;6;N;;;;;
+1244F;CUNEIFORM NUMERIC SIGN ONE BAN2;Nl;0;L;;;;1;N;;;;;
+12450;CUNEIFORM NUMERIC SIGN TWO BAN2;Nl;0;L;;;;2;N;;;;;
+12451;CUNEIFORM NUMERIC SIGN THREE BAN2;Nl;0;L;;;;3;N;;;;;
+12452;CUNEIFORM NUMERIC SIGN FOUR BAN2;Nl;0;L;;;;4;N;;;;;
+12453;CUNEIFORM NUMERIC SIGN FOUR BAN2 VARIANT FORM;Nl;0;L;;;;4;N;;;;;
+12454;CUNEIFORM NUMERIC SIGN FIVE BAN2;Nl;0;L;;;;5;N;;;;;
+12455;CUNEIFORM NUMERIC SIGN FIVE BAN2 VARIANT FORM;Nl;0;L;;;;5;N;;;;;
+12456;CUNEIFORM NUMERIC SIGN NIGIDAMIN;Nl;0;L;;;;;N;;;;;
+12457;CUNEIFORM NUMERIC SIGN NIGIDAESH;Nl;0;L;;;;;N;;;;;
+12458;CUNEIFORM NUMERIC SIGN ONE ESHE3;Nl;0;L;;;;1;N;;;;;
+12459;CUNEIFORM NUMERIC SIGN TWO ESHE3;Nl;0;L;;;;2;N;;;;;
+1245A;CUNEIFORM NUMERIC SIGN ONE THIRD DISH;Nl;0;L;;;;1/3;N;;;;;
+1245B;CUNEIFORM NUMERIC SIGN TWO THIRDS DISH;Nl;0;L;;;;2/3;N;;;;;
+1245C;CUNEIFORM NUMERIC SIGN FIVE SIXTHS DISH;Nl;0;L;;;;5/6;N;;;;;
+1245D;CUNEIFORM NUMERIC SIGN ONE THIRD VARIANT FORM A;Nl;0;L;;;;1/3;N;;;;;
+1245E;CUNEIFORM NUMERIC SIGN TWO THIRDS VARIANT FORM A;Nl;0;L;;;;2/3;N;;;;;
+1245F;CUNEIFORM NUMERIC SIGN ONE EIGHTH ASH;Nl;0;L;;;;1/8;N;;;;;
+12460;CUNEIFORM NUMERIC SIGN ONE QUARTER ASH;Nl;0;L;;;;1/4;N;;;;;
+12461;CUNEIFORM NUMERIC SIGN OLD ASSYRIAN ONE SIXTH;Nl;0;L;;;;1/6;N;;;;;
+12462;CUNEIFORM NUMERIC SIGN OLD ASSYRIAN ONE QUARTER;Nl;0;L;;;;1/4;N;;;;;
+12470;CUNEIFORM PUNCTUATION SIGN OLD ASSYRIAN WORD DIVIDER;Po;0;L;;;;;N;;;;;
+12471;CUNEIFORM PUNCTUATION SIGN VERTICAL COLON;Po;0;L;;;;;N;;;;;
+12472;CUNEIFORM PUNCTUATION SIGN DIAGONAL COLON;Po;0;L;;;;;N;;;;;
+12473;CUNEIFORM PUNCTUATION SIGN DIAGONAL TRICOLON;Po;0;L;;;;;N;;;;;
+13000;EGYPTIAN HIEROGLYPH A001;Lo;0;L;;;;;N;;;;;
+13001;EGYPTIAN HIEROGLYPH A002;Lo;0;L;;;;;N;;;;;
+13002;EGYPTIAN HIEROGLYPH A003;Lo;0;L;;;;;N;;;;;
+13003;EGYPTIAN HIEROGLYPH A004;Lo;0;L;;;;;N;;;;;
+13004;EGYPTIAN HIEROGLYPH A005;Lo;0;L;;;;;N;;;;;
+13005;EGYPTIAN HIEROGLYPH A005A;Lo;0;L;;;;;N;;;;;
+13006;EGYPTIAN HIEROGLYPH A006;Lo;0;L;;;;;N;;;;;
+13007;EGYPTIAN HIEROGLYPH A006A;Lo;0;L;;;;;N;;;;;
+13008;EGYPTIAN HIEROGLYPH A006B;Lo;0;L;;;;;N;;;;;
+13009;EGYPTIAN HIEROGLYPH A007;Lo;0;L;;;;;N;;;;;
+1300A;EGYPTIAN HIEROGLYPH A008;Lo;0;L;;;;;N;;;;;
+1300B;EGYPTIAN HIEROGLYPH A009;Lo;0;L;;;;;N;;;;;
+1300C;EGYPTIAN HIEROGLYPH A010;Lo;0;L;;;;;N;;;;;
+1300D;EGYPTIAN HIEROGLYPH A011;Lo;0;L;;;;;N;;;;;
+1300E;EGYPTIAN HIEROGLYPH A012;Lo;0;L;;;;;N;;;;;
+1300F;EGYPTIAN HIEROGLYPH A013;Lo;0;L;;;;;N;;;;;
+13010;EGYPTIAN HIEROGLYPH A014;Lo;0;L;;;;;N;;;;;
+13011;EGYPTIAN HIEROGLYPH A014A;Lo;0;L;;;;;N;;;;;
+13012;EGYPTIAN HIEROGLYPH A015;Lo;0;L;;;;;N;;;;;
+13013;EGYPTIAN HIEROGLYPH A016;Lo;0;L;;;;;N;;;;;
+13014;EGYPTIAN HIEROGLYPH A017;Lo;0;L;;;;;N;;;;;
+13015;EGYPTIAN HIEROGLYPH A017A;Lo;0;L;;;;;N;;;;;
+13016;EGYPTIAN HIEROGLYPH A018;Lo;0;L;;;;;N;;;;;
+13017;EGYPTIAN HIEROGLYPH A019;Lo;0;L;;;;;N;;;;;
+13018;EGYPTIAN HIEROGLYPH A020;Lo;0;L;;;;;N;;;;;
+13019;EGYPTIAN HIEROGLYPH A021;Lo;0;L;;;;;N;;;;;
+1301A;EGYPTIAN HIEROGLYPH A022;Lo;0;L;;;;;N;;;;;
+1301B;EGYPTIAN HIEROGLYPH A023;Lo;0;L;;;;;N;;;;;
+1301C;EGYPTIAN HIEROGLYPH A024;Lo;0;L;;;;;N;;;;;
+1301D;EGYPTIAN HIEROGLYPH A025;Lo;0;L;;;;;N;;;;;
+1301E;EGYPTIAN HIEROGLYPH A026;Lo;0;L;;;;;N;;;;;
+1301F;EGYPTIAN HIEROGLYPH A027;Lo;0;L;;;;;N;;;;;
+13020;EGYPTIAN HIEROGLYPH A028;Lo;0;L;;;;;N;;;;;
+13021;EGYPTIAN HIEROGLYPH A029;Lo;0;L;;;;;N;;;;;
+13022;EGYPTIAN HIEROGLYPH A030;Lo;0;L;;;;;N;;;;;
+13023;EGYPTIAN HIEROGLYPH A031;Lo;0;L;;;;;N;;;;;
+13024;EGYPTIAN HIEROGLYPH A032;Lo;0;L;;;;;N;;;;;
+13025;EGYPTIAN HIEROGLYPH A032A;Lo;0;L;;;;;N;;;;;
+13026;EGYPTIAN HIEROGLYPH A033;Lo;0;L;;;;;N;;;;;
+13027;EGYPTIAN HIEROGLYPH A034;Lo;0;L;;;;;N;;;;;
+13028;EGYPTIAN HIEROGLYPH A035;Lo;0;L;;;;;N;;;;;
+13029;EGYPTIAN HIEROGLYPH A036;Lo;0;L;;;;;N;;;;;
+1302A;EGYPTIAN HIEROGLYPH A037;Lo;0;L;;;;;N;;;;;
+1302B;EGYPTIAN HIEROGLYPH A038;Lo;0;L;;;;;N;;;;;
+1302C;EGYPTIAN HIEROGLYPH A039;Lo;0;L;;;;;N;;;;;
+1302D;EGYPTIAN HIEROGLYPH A040;Lo;0;L;;;;;N;;;;;
+1302E;EGYPTIAN HIEROGLYPH A040A;Lo;0;L;;;;;N;;;;;
+1302F;EGYPTIAN HIEROGLYPH A041;Lo;0;L;;;;;N;;;;;
+13030;EGYPTIAN HIEROGLYPH A042;Lo;0;L;;;;;N;;;;;
+13031;EGYPTIAN HIEROGLYPH A042A;Lo;0;L;;;;;N;;;;;
+13032;EGYPTIAN HIEROGLYPH A043;Lo;0;L;;;;;N;;;;;
+13033;EGYPTIAN HIEROGLYPH A043A;Lo;0;L;;;;;N;;;;;
+13034;EGYPTIAN HIEROGLYPH A044;Lo;0;L;;;;;N;;;;;
+13035;EGYPTIAN HIEROGLYPH A045;Lo;0;L;;;;;N;;;;;
+13036;EGYPTIAN HIEROGLYPH A045A;Lo;0;L;;;;;N;;;;;
+13037;EGYPTIAN HIEROGLYPH A046;Lo;0;L;;;;;N;;;;;
+13038;EGYPTIAN HIEROGLYPH A047;Lo;0;L;;;;;N;;;;;
+13039;EGYPTIAN HIEROGLYPH A048;Lo;0;L;;;;;N;;;;;
+1303A;EGYPTIAN HIEROGLYPH A049;Lo;0;L;;;;;N;;;;;
+1303B;EGYPTIAN HIEROGLYPH A050;Lo;0;L;;;;;N;;;;;
+1303C;EGYPTIAN HIEROGLYPH A051;Lo;0;L;;;;;N;;;;;
+1303D;EGYPTIAN HIEROGLYPH A052;Lo;0;L;;;;;N;;;;;
+1303E;EGYPTIAN HIEROGLYPH A053;Lo;0;L;;;;;N;;;;;
+1303F;EGYPTIAN HIEROGLYPH A054;Lo;0;L;;;;;N;;;;;
+13040;EGYPTIAN HIEROGLYPH A055;Lo;0;L;;;;;N;;;;;
+13041;EGYPTIAN HIEROGLYPH A056;Lo;0;L;;;;;N;;;;;
+13042;EGYPTIAN HIEROGLYPH A057;Lo;0;L;;;;;N;;;;;
+13043;EGYPTIAN HIEROGLYPH A058;Lo;0;L;;;;;N;;;;;
+13044;EGYPTIAN HIEROGLYPH A059;Lo;0;L;;;;;N;;;;;
+13045;EGYPTIAN HIEROGLYPH A060;Lo;0;L;;;;;N;;;;;
+13046;EGYPTIAN HIEROGLYPH A061;Lo;0;L;;;;;N;;;;;
+13047;EGYPTIAN HIEROGLYPH A062;Lo;0;L;;;;;N;;;;;
+13048;EGYPTIAN HIEROGLYPH A063;Lo;0;L;;;;;N;;;;;
+13049;EGYPTIAN HIEROGLYPH A064;Lo;0;L;;;;;N;;;;;
+1304A;EGYPTIAN HIEROGLYPH A065;Lo;0;L;;;;;N;;;;;
+1304B;EGYPTIAN HIEROGLYPH A066;Lo;0;L;;;;;N;;;;;
+1304C;EGYPTIAN HIEROGLYPH A067;Lo;0;L;;;;;N;;;;;
+1304D;EGYPTIAN HIEROGLYPH A068;Lo;0;L;;;;;N;;;;;
+1304E;EGYPTIAN HIEROGLYPH A069;Lo;0;L;;;;;N;;;;;
+1304F;EGYPTIAN HIEROGLYPH A070;Lo;0;L;;;;;N;;;;;
+13050;EGYPTIAN HIEROGLYPH B001;Lo;0;L;;;;;N;;;;;
+13051;EGYPTIAN HIEROGLYPH B002;Lo;0;L;;;;;N;;;;;
+13052;EGYPTIAN HIEROGLYPH B003;Lo;0;L;;;;;N;;;;;
+13053;EGYPTIAN HIEROGLYPH B004;Lo;0;L;;;;;N;;;;;
+13054;EGYPTIAN HIEROGLYPH B005;Lo;0;L;;;;;N;;;;;
+13055;EGYPTIAN HIEROGLYPH B005A;Lo;0;L;;;;;N;;;;;
+13056;EGYPTIAN HIEROGLYPH B006;Lo;0;L;;;;;N;;;;;
+13057;EGYPTIAN HIEROGLYPH B007;Lo;0;L;;;;;N;;;;;
+13058;EGYPTIAN HIEROGLYPH B008;Lo;0;L;;;;;N;;;;;
+13059;EGYPTIAN HIEROGLYPH B009;Lo;0;L;;;;;N;;;;;
+1305A;EGYPTIAN HIEROGLYPH C001;Lo;0;L;;;;;N;;;;;
+1305B;EGYPTIAN HIEROGLYPH C002;Lo;0;L;;;;;N;;;;;
+1305C;EGYPTIAN HIEROGLYPH C002A;Lo;0;L;;;;;N;;;;;
+1305D;EGYPTIAN HIEROGLYPH C002B;Lo;0;L;;;;;N;;;;;
+1305E;EGYPTIAN HIEROGLYPH C002C;Lo;0;L;;;;;N;;;;;
+1305F;EGYPTIAN HIEROGLYPH C003;Lo;0;L;;;;;N;;;;;
+13060;EGYPTIAN HIEROGLYPH C004;Lo;0;L;;;;;N;;;;;
+13061;EGYPTIAN HIEROGLYPH C005;Lo;0;L;;;;;N;;;;;
+13062;EGYPTIAN HIEROGLYPH C006;Lo;0;L;;;;;N;;;;;
+13063;EGYPTIAN HIEROGLYPH C007;Lo;0;L;;;;;N;;;;;
+13064;EGYPTIAN HIEROGLYPH C008;Lo;0;L;;;;;N;;;;;
+13065;EGYPTIAN HIEROGLYPH C009;Lo;0;L;;;;;N;;;;;
+13066;EGYPTIAN HIEROGLYPH C010;Lo;0;L;;;;;N;;;;;
+13067;EGYPTIAN HIEROGLYPH C010A;Lo;0;L;;;;;N;;;;;
+13068;EGYPTIAN HIEROGLYPH C011;Lo;0;L;;;;;N;;;;;
+13069;EGYPTIAN HIEROGLYPH C012;Lo;0;L;;;;;N;;;;;
+1306A;EGYPTIAN HIEROGLYPH C013;Lo;0;L;;;;;N;;;;;
+1306B;EGYPTIAN HIEROGLYPH C014;Lo;0;L;;;;;N;;;;;
+1306C;EGYPTIAN HIEROGLYPH C015;Lo;0;L;;;;;N;;;;;
+1306D;EGYPTIAN HIEROGLYPH C016;Lo;0;L;;;;;N;;;;;
+1306E;EGYPTIAN HIEROGLYPH C017;Lo;0;L;;;;;N;;;;;
+1306F;EGYPTIAN HIEROGLYPH C018;Lo;0;L;;;;;N;;;;;
+13070;EGYPTIAN HIEROGLYPH C019;Lo;0;L;;;;;N;;;;;
+13071;EGYPTIAN HIEROGLYPH C020;Lo;0;L;;;;;N;;;;;
+13072;EGYPTIAN HIEROGLYPH C021;Lo;0;L;;;;;N;;;;;
+13073;EGYPTIAN HIEROGLYPH C022;Lo;0;L;;;;;N;;;;;
+13074;EGYPTIAN HIEROGLYPH C023;Lo;0;L;;;;;N;;;;;
+13075;EGYPTIAN HIEROGLYPH C024;Lo;0;L;;;;;N;;;;;
+13076;EGYPTIAN HIEROGLYPH D001;Lo;0;L;;;;;N;;;;;
+13077;EGYPTIAN HIEROGLYPH D002;Lo;0;L;;;;;N;;;;;
+13078;EGYPTIAN HIEROGLYPH D003;Lo;0;L;;;;;N;;;;;
+13079;EGYPTIAN HIEROGLYPH D004;Lo;0;L;;;;;N;;;;;
+1307A;EGYPTIAN HIEROGLYPH D005;Lo;0;L;;;;;N;;;;;
+1307B;EGYPTIAN HIEROGLYPH D006;Lo;0;L;;;;;N;;;;;
+1307C;EGYPTIAN HIEROGLYPH D007;Lo;0;L;;;;;N;;;;;
+1307D;EGYPTIAN HIEROGLYPH D008;Lo;0;L;;;;;N;;;;;
+1307E;EGYPTIAN HIEROGLYPH D008A;Lo;0;L;;;;;N;;;;;
+1307F;EGYPTIAN HIEROGLYPH D009;Lo;0;L;;;;;N;;;;;
+13080;EGYPTIAN HIEROGLYPH D010;Lo;0;L;;;;;N;;;;;
+13081;EGYPTIAN HIEROGLYPH D011;Lo;0;L;;;;;N;;;;;
+13082;EGYPTIAN HIEROGLYPH D012;Lo;0;L;;;;;N;;;;;
+13083;EGYPTIAN HIEROGLYPH D013;Lo;0;L;;;;;N;;;;;
+13084;EGYPTIAN HIEROGLYPH D014;Lo;0;L;;;;;N;;;;;
+13085;EGYPTIAN HIEROGLYPH D015;Lo;0;L;;;;;N;;;;;
+13086;EGYPTIAN HIEROGLYPH D016;Lo;0;L;;;;;N;;;;;
+13087;EGYPTIAN HIEROGLYPH D017;Lo;0;L;;;;;N;;;;;
+13088;EGYPTIAN HIEROGLYPH D018;Lo;0;L;;;;;N;;;;;
+13089;EGYPTIAN HIEROGLYPH D019;Lo;0;L;;;;;N;;;;;
+1308A;EGYPTIAN HIEROGLYPH D020;Lo;0;L;;;;;N;;;;;
+1308B;EGYPTIAN HIEROGLYPH D021;Lo;0;L;;;;;N;;;;;
+1308C;EGYPTIAN HIEROGLYPH D022;Lo;0;L;;;;;N;;;;;
+1308D;EGYPTIAN HIEROGLYPH D023;Lo;0;L;;;;;N;;;;;
+1308E;EGYPTIAN HIEROGLYPH D024;Lo;0;L;;;;;N;;;;;
+1308F;EGYPTIAN HIEROGLYPH D025;Lo;0;L;;;;;N;;;;;
+13090;EGYPTIAN HIEROGLYPH D026;Lo;0;L;;;;;N;;;;;
+13091;EGYPTIAN HIEROGLYPH D027;Lo;0;L;;;;;N;;;;;
+13092;EGYPTIAN HIEROGLYPH D027A;Lo;0;L;;;;;N;;;;;
+13093;EGYPTIAN HIEROGLYPH D028;Lo;0;L;;;;;N;;;;;
+13094;EGYPTIAN HIEROGLYPH D029;Lo;0;L;;;;;N;;;;;
+13095;EGYPTIAN HIEROGLYPH D030;Lo;0;L;;;;;N;;;;;
+13096;EGYPTIAN HIEROGLYPH D031;Lo;0;L;;;;;N;;;;;
+13097;EGYPTIAN HIEROGLYPH D031A;Lo;0;L;;;;;N;;;;;
+13098;EGYPTIAN HIEROGLYPH D032;Lo;0;L;;;;;N;;;;;
+13099;EGYPTIAN HIEROGLYPH D033;Lo;0;L;;;;;N;;;;;
+1309A;EGYPTIAN HIEROGLYPH D034;Lo;0;L;;;;;N;;;;;
+1309B;EGYPTIAN HIEROGLYPH D034A;Lo;0;L;;;;;N;;;;;
+1309C;EGYPTIAN HIEROGLYPH D035;Lo;0;L;;;;;N;;;;;
+1309D;EGYPTIAN HIEROGLYPH D036;Lo;0;L;;;;;N;;;;;
+1309E;EGYPTIAN HIEROGLYPH D037;Lo;0;L;;;;;N;;;;;
+1309F;EGYPTIAN HIEROGLYPH D038;Lo;0;L;;;;;N;;;;;
+130A0;EGYPTIAN HIEROGLYPH D039;Lo;0;L;;;;;N;;;;;
+130A1;EGYPTIAN HIEROGLYPH D040;Lo;0;L;;;;;N;;;;;
+130A2;EGYPTIAN HIEROGLYPH D041;Lo;0;L;;;;;N;;;;;
+130A3;EGYPTIAN HIEROGLYPH D042;Lo;0;L;;;;;N;;;;;
+130A4;EGYPTIAN HIEROGLYPH D043;Lo;0;L;;;;;N;;;;;
+130A5;EGYPTIAN HIEROGLYPH D044;Lo;0;L;;;;;N;;;;;
+130A6;EGYPTIAN HIEROGLYPH D045;Lo;0;L;;;;;N;;;;;
+130A7;EGYPTIAN HIEROGLYPH D046;Lo;0;L;;;;;N;;;;;
+130A8;EGYPTIAN HIEROGLYPH D046A;Lo;0;L;;;;;N;;;;;
+130A9;EGYPTIAN HIEROGLYPH D047;Lo;0;L;;;;;N;;;;;
+130AA;EGYPTIAN HIEROGLYPH D048;Lo;0;L;;;;;N;;;;;
+130AB;EGYPTIAN HIEROGLYPH D048A;Lo;0;L;;;;;N;;;;;
+130AC;EGYPTIAN HIEROGLYPH D049;Lo;0;L;;;;;N;;;;;
+130AD;EGYPTIAN HIEROGLYPH D050;Lo;0;L;;;;;N;;;;;
+130AE;EGYPTIAN HIEROGLYPH D050A;Lo;0;L;;;;;N;;;;;
+130AF;EGYPTIAN HIEROGLYPH D050B;Lo;0;L;;;;;N;;;;;
+130B0;EGYPTIAN HIEROGLYPH D050C;Lo;0;L;;;;;N;;;;;
+130B1;EGYPTIAN HIEROGLYPH D050D;Lo;0;L;;;;;N;;;;;
+130B2;EGYPTIAN HIEROGLYPH D050E;Lo;0;L;;;;;N;;;;;
+130B3;EGYPTIAN HIEROGLYPH D050F;Lo;0;L;;;;;N;;;;;
+130B4;EGYPTIAN HIEROGLYPH D050G;Lo;0;L;;;;;N;;;;;
+130B5;EGYPTIAN HIEROGLYPH D050H;Lo;0;L;;;;;N;;;;;
+130B6;EGYPTIAN HIEROGLYPH D050I;Lo;0;L;;;;;N;;;;;
+130B7;EGYPTIAN HIEROGLYPH D051;Lo;0;L;;;;;N;;;;;
+130B8;EGYPTIAN HIEROGLYPH D052;Lo;0;L;;;;;N;;;;;
+130B9;EGYPTIAN HIEROGLYPH D052A;Lo;0;L;;;;;N;;;;;
+130BA;EGYPTIAN HIEROGLYPH D053;Lo;0;L;;;;;N;;;;;
+130BB;EGYPTIAN HIEROGLYPH D054;Lo;0;L;;;;;N;;;;;
+130BC;EGYPTIAN HIEROGLYPH D054A;Lo;0;L;;;;;N;;;;;
+130BD;EGYPTIAN HIEROGLYPH D055;Lo;0;L;;;;;N;;;;;
+130BE;EGYPTIAN HIEROGLYPH D056;Lo;0;L;;;;;N;;;;;
+130BF;EGYPTIAN HIEROGLYPH D057;Lo;0;L;;;;;N;;;;;
+130C0;EGYPTIAN HIEROGLYPH D058;Lo;0;L;;;;;N;;;;;
+130C1;EGYPTIAN HIEROGLYPH D059;Lo;0;L;;;;;N;;;;;
+130C2;EGYPTIAN HIEROGLYPH D060;Lo;0;L;;;;;N;;;;;
+130C3;EGYPTIAN HIEROGLYPH D061;Lo;0;L;;;;;N;;;;;
+130C4;EGYPTIAN HIEROGLYPH D062;Lo;0;L;;;;;N;;;;;
+130C5;EGYPTIAN HIEROGLYPH D063;Lo;0;L;;;;;N;;;;;
+130C6;EGYPTIAN HIEROGLYPH D064;Lo;0;L;;;;;N;;;;;
+130C7;EGYPTIAN HIEROGLYPH D065;Lo;0;L;;;;;N;;;;;
+130C8;EGYPTIAN HIEROGLYPH D066;Lo;0;L;;;;;N;;;;;
+130C9;EGYPTIAN HIEROGLYPH D067;Lo;0;L;;;;;N;;;;;
+130CA;EGYPTIAN HIEROGLYPH D067A;Lo;0;L;;;;;N;;;;;
+130CB;EGYPTIAN HIEROGLYPH D067B;Lo;0;L;;;;;N;;;;;
+130CC;EGYPTIAN HIEROGLYPH D067C;Lo;0;L;;;;;N;;;;;
+130CD;EGYPTIAN HIEROGLYPH D067D;Lo;0;L;;;;;N;;;;;
+130CE;EGYPTIAN HIEROGLYPH D067E;Lo;0;L;;;;;N;;;;;
+130CF;EGYPTIAN HIEROGLYPH D067F;Lo;0;L;;;;;N;;;;;
+130D0;EGYPTIAN HIEROGLYPH D067G;Lo;0;L;;;;;N;;;;;
+130D1;EGYPTIAN HIEROGLYPH D067H;Lo;0;L;;;;;N;;;;;
+130D2;EGYPTIAN HIEROGLYPH E001;Lo;0;L;;;;;N;;;;;
+130D3;EGYPTIAN HIEROGLYPH E002;Lo;0;L;;;;;N;;;;;
+130D4;EGYPTIAN HIEROGLYPH E003;Lo;0;L;;;;;N;;;;;
+130D5;EGYPTIAN HIEROGLYPH E004;Lo;0;L;;;;;N;;;;;
+130D6;EGYPTIAN HIEROGLYPH E005;Lo;0;L;;;;;N;;;;;
+130D7;EGYPTIAN HIEROGLYPH E006;Lo;0;L;;;;;N;;;;;
+130D8;EGYPTIAN HIEROGLYPH E007;Lo;0;L;;;;;N;;;;;
+130D9;EGYPTIAN HIEROGLYPH E008;Lo;0;L;;;;;N;;;;;
+130DA;EGYPTIAN HIEROGLYPH E008A;Lo;0;L;;;;;N;;;;;
+130DB;EGYPTIAN HIEROGLYPH E009;Lo;0;L;;;;;N;;;;;
+130DC;EGYPTIAN HIEROGLYPH E009A;Lo;0;L;;;;;N;;;;;
+130DD;EGYPTIAN HIEROGLYPH E010;Lo;0;L;;;;;N;;;;;
+130DE;EGYPTIAN HIEROGLYPH E011;Lo;0;L;;;;;N;;;;;
+130DF;EGYPTIAN HIEROGLYPH E012;Lo;0;L;;;;;N;;;;;
+130E0;EGYPTIAN HIEROGLYPH E013;Lo;0;L;;;;;N;;;;;
+130E1;EGYPTIAN HIEROGLYPH E014;Lo;0;L;;;;;N;;;;;
+130E2;EGYPTIAN HIEROGLYPH E015;Lo;0;L;;;;;N;;;;;
+130E3;EGYPTIAN HIEROGLYPH E016;Lo;0;L;;;;;N;;;;;
+130E4;EGYPTIAN HIEROGLYPH E016A;Lo;0;L;;;;;N;;;;;
+130E5;EGYPTIAN HIEROGLYPH E017;Lo;0;L;;;;;N;;;;;
+130E6;EGYPTIAN HIEROGLYPH E017A;Lo;0;L;;;;;N;;;;;
+130E7;EGYPTIAN HIEROGLYPH E018;Lo;0;L;;;;;N;;;;;
+130E8;EGYPTIAN HIEROGLYPH E019;Lo;0;L;;;;;N;;;;;
+130E9;EGYPTIAN HIEROGLYPH E020;Lo;0;L;;;;;N;;;;;
+130EA;EGYPTIAN HIEROGLYPH E020A;Lo;0;L;;;;;N;;;;;
+130EB;EGYPTIAN HIEROGLYPH E021;Lo;0;L;;;;;N;;;;;
+130EC;EGYPTIAN HIEROGLYPH E022;Lo;0;L;;;;;N;;;;;
+130ED;EGYPTIAN HIEROGLYPH E023;Lo;0;L;;;;;N;;;;;
+130EE;EGYPTIAN HIEROGLYPH E024;Lo;0;L;;;;;N;;;;;
+130EF;EGYPTIAN HIEROGLYPH E025;Lo;0;L;;;;;N;;;;;
+130F0;EGYPTIAN HIEROGLYPH E026;Lo;0;L;;;;;N;;;;;
+130F1;EGYPTIAN HIEROGLYPH E027;Lo;0;L;;;;;N;;;;;
+130F2;EGYPTIAN HIEROGLYPH E028;Lo;0;L;;;;;N;;;;;
+130F3;EGYPTIAN HIEROGLYPH E028A;Lo;0;L;;;;;N;;;;;
+130F4;EGYPTIAN HIEROGLYPH E029;Lo;0;L;;;;;N;;;;;
+130F5;EGYPTIAN HIEROGLYPH E030;Lo;0;L;;;;;N;;;;;
+130F6;EGYPTIAN HIEROGLYPH E031;Lo;0;L;;;;;N;;;;;
+130F7;EGYPTIAN HIEROGLYPH E032;Lo;0;L;;;;;N;;;;;
+130F8;EGYPTIAN HIEROGLYPH E033;Lo;0;L;;;;;N;;;;;
+130F9;EGYPTIAN HIEROGLYPH E034;Lo;0;L;;;;;N;;;;;
+130FA;EGYPTIAN HIEROGLYPH E034A;Lo;0;L;;;;;N;;;;;
+130FB;EGYPTIAN HIEROGLYPH E036;Lo;0;L;;;;;N;;;;;
+130FC;EGYPTIAN HIEROGLYPH E037;Lo;0;L;;;;;N;;;;;
+130FD;EGYPTIAN HIEROGLYPH E038;Lo;0;L;;;;;N;;;;;
+130FE;EGYPTIAN HIEROGLYPH F001;Lo;0;L;;;;;N;;;;;
+130FF;EGYPTIAN HIEROGLYPH F001A;Lo;0;L;;;;;N;;;;;
+13100;EGYPTIAN HIEROGLYPH F002;Lo;0;L;;;;;N;;;;;
+13101;EGYPTIAN HIEROGLYPH F003;Lo;0;L;;;;;N;;;;;
+13102;EGYPTIAN HIEROGLYPH F004;Lo;0;L;;;;;N;;;;;
+13103;EGYPTIAN HIEROGLYPH F005;Lo;0;L;;;;;N;;;;;
+13104;EGYPTIAN HIEROGLYPH F006;Lo;0;L;;;;;N;;;;;
+13105;EGYPTIAN HIEROGLYPH F007;Lo;0;L;;;;;N;;;;;
+13106;EGYPTIAN HIEROGLYPH F008;Lo;0;L;;;;;N;;;;;
+13107;EGYPTIAN HIEROGLYPH F009;Lo;0;L;;;;;N;;;;;
+13108;EGYPTIAN HIEROGLYPH F010;Lo;0;L;;;;;N;;;;;
+13109;EGYPTIAN HIEROGLYPH F011;Lo;0;L;;;;;N;;;;;
+1310A;EGYPTIAN HIEROGLYPH F012;Lo;0;L;;;;;N;;;;;
+1310B;EGYPTIAN HIEROGLYPH F013;Lo;0;L;;;;;N;;;;;
+1310C;EGYPTIAN HIEROGLYPH F013A;Lo;0;L;;;;;N;;;;;
+1310D;EGYPTIAN HIEROGLYPH F014;Lo;0;L;;;;;N;;;;;
+1310E;EGYPTIAN HIEROGLYPH F015;Lo;0;L;;;;;N;;;;;
+1310F;EGYPTIAN HIEROGLYPH F016;Lo;0;L;;;;;N;;;;;
+13110;EGYPTIAN HIEROGLYPH F017;Lo;0;L;;;;;N;;;;;
+13111;EGYPTIAN HIEROGLYPH F018;Lo;0;L;;;;;N;;;;;
+13112;EGYPTIAN HIEROGLYPH F019;Lo;0;L;;;;;N;;;;;
+13113;EGYPTIAN HIEROGLYPH F020;Lo;0;L;;;;;N;;;;;
+13114;EGYPTIAN HIEROGLYPH F021;Lo;0;L;;;;;N;;;;;
+13115;EGYPTIAN HIEROGLYPH F021A;Lo;0;L;;;;;N;;;;;
+13116;EGYPTIAN HIEROGLYPH F022;Lo;0;L;;;;;N;;;;;
+13117;EGYPTIAN HIEROGLYPH F023;Lo;0;L;;;;;N;;;;;
+13118;EGYPTIAN HIEROGLYPH F024;Lo;0;L;;;;;N;;;;;
+13119;EGYPTIAN HIEROGLYPH F025;Lo;0;L;;;;;N;;;;;
+1311A;EGYPTIAN HIEROGLYPH F026;Lo;0;L;;;;;N;;;;;
+1311B;EGYPTIAN HIEROGLYPH F027;Lo;0;L;;;;;N;;;;;
+1311C;EGYPTIAN HIEROGLYPH F028;Lo;0;L;;;;;N;;;;;
+1311D;EGYPTIAN HIEROGLYPH F029;Lo;0;L;;;;;N;;;;;
+1311E;EGYPTIAN HIEROGLYPH F030;Lo;0;L;;;;;N;;;;;
+1311F;EGYPTIAN HIEROGLYPH F031;Lo;0;L;;;;;N;;;;;
+13120;EGYPTIAN HIEROGLYPH F031A;Lo;0;L;;;;;N;;;;;
+13121;EGYPTIAN HIEROGLYPH F032;Lo;0;L;;;;;N;;;;;
+13122;EGYPTIAN HIEROGLYPH F033;Lo;0;L;;;;;N;;;;;
+13123;EGYPTIAN HIEROGLYPH F034;Lo;0;L;;;;;N;;;;;
+13124;EGYPTIAN HIEROGLYPH F035;Lo;0;L;;;;;N;;;;;
+13125;EGYPTIAN HIEROGLYPH F036;Lo;0;L;;;;;N;;;;;
+13126;EGYPTIAN HIEROGLYPH F037;Lo;0;L;;;;;N;;;;;
+13127;EGYPTIAN HIEROGLYPH F037A;Lo;0;L;;;;;N;;;;;
+13128;EGYPTIAN HIEROGLYPH F038;Lo;0;L;;;;;N;;;;;
+13129;EGYPTIAN HIEROGLYPH F038A;Lo;0;L;;;;;N;;;;;
+1312A;EGYPTIAN HIEROGLYPH F039;Lo;0;L;;;;;N;;;;;
+1312B;EGYPTIAN HIEROGLYPH F040;Lo;0;L;;;;;N;;;;;
+1312C;EGYPTIAN HIEROGLYPH F041;Lo;0;L;;;;;N;;;;;
+1312D;EGYPTIAN HIEROGLYPH F042;Lo;0;L;;;;;N;;;;;
+1312E;EGYPTIAN HIEROGLYPH F043;Lo;0;L;;;;;N;;;;;
+1312F;EGYPTIAN HIEROGLYPH F044;Lo;0;L;;;;;N;;;;;
+13130;EGYPTIAN HIEROGLYPH F045;Lo;0;L;;;;;N;;;;;
+13131;EGYPTIAN HIEROGLYPH F045A;Lo;0;L;;;;;N;;;;;
+13132;EGYPTIAN HIEROGLYPH F046;Lo;0;L;;;;;N;;;;;
+13133;EGYPTIAN HIEROGLYPH F046A;Lo;0;L;;;;;N;;;;;
+13134;EGYPTIAN HIEROGLYPH F047;Lo;0;L;;;;;N;;;;;
+13135;EGYPTIAN HIEROGLYPH F047A;Lo;0;L;;;;;N;;;;;
+13136;EGYPTIAN HIEROGLYPH F048;Lo;0;L;;;;;N;;;;;
+13137;EGYPTIAN HIEROGLYPH F049;Lo;0;L;;;;;N;;;;;
+13138;EGYPTIAN HIEROGLYPH F050;Lo;0;L;;;;;N;;;;;
+13139;EGYPTIAN HIEROGLYPH F051;Lo;0;L;;;;;N;;;;;
+1313A;EGYPTIAN HIEROGLYPH F051A;Lo;0;L;;;;;N;;;;;
+1313B;EGYPTIAN HIEROGLYPH F051B;Lo;0;L;;;;;N;;;;;
+1313C;EGYPTIAN HIEROGLYPH F051C;Lo;0;L;;;;;N;;;;;
+1313D;EGYPTIAN HIEROGLYPH F052;Lo;0;L;;;;;N;;;;;
+1313E;EGYPTIAN HIEROGLYPH F053;Lo;0;L;;;;;N;;;;;
+1313F;EGYPTIAN HIEROGLYPH G001;Lo;0;L;;;;;N;;;;;
+13140;EGYPTIAN HIEROGLYPH G002;Lo;0;L;;;;;N;;;;;
+13141;EGYPTIAN HIEROGLYPH G003;Lo;0;L;;;;;N;;;;;
+13142;EGYPTIAN HIEROGLYPH G004;Lo;0;L;;;;;N;;;;;
+13143;EGYPTIAN HIEROGLYPH G005;Lo;0;L;;;;;N;;;;;
+13144;EGYPTIAN HIEROGLYPH G006;Lo;0;L;;;;;N;;;;;
+13145;EGYPTIAN HIEROGLYPH G006A;Lo;0;L;;;;;N;;;;;
+13146;EGYPTIAN HIEROGLYPH G007;Lo;0;L;;;;;N;;;;;
+13147;EGYPTIAN HIEROGLYPH G007A;Lo;0;L;;;;;N;;;;;
+13148;EGYPTIAN HIEROGLYPH G007B;Lo;0;L;;;;;N;;;;;
+13149;EGYPTIAN HIEROGLYPH G008;Lo;0;L;;;;;N;;;;;
+1314A;EGYPTIAN HIEROGLYPH G009;Lo;0;L;;;;;N;;;;;
+1314B;EGYPTIAN HIEROGLYPH G010;Lo;0;L;;;;;N;;;;;
+1314C;EGYPTIAN HIEROGLYPH G011;Lo;0;L;;;;;N;;;;;
+1314D;EGYPTIAN HIEROGLYPH G011A;Lo;0;L;;;;;N;;;;;
+1314E;EGYPTIAN HIEROGLYPH G012;Lo;0;L;;;;;N;;;;;
+1314F;EGYPTIAN HIEROGLYPH G013;Lo;0;L;;;;;N;;;;;
+13150;EGYPTIAN HIEROGLYPH G014;Lo;0;L;;;;;N;;;;;
+13151;EGYPTIAN HIEROGLYPH G015;Lo;0;L;;;;;N;;;;;
+13152;EGYPTIAN HIEROGLYPH G016;Lo;0;L;;;;;N;;;;;
+13153;EGYPTIAN HIEROGLYPH G017;Lo;0;L;;;;;N;;;;;
+13154;EGYPTIAN HIEROGLYPH G018;Lo;0;L;;;;;N;;;;;
+13155;EGYPTIAN HIEROGLYPH G019;Lo;0;L;;;;;N;;;;;
+13156;EGYPTIAN HIEROGLYPH G020;Lo;0;L;;;;;N;;;;;
+13157;EGYPTIAN HIEROGLYPH G020A;Lo;0;L;;;;;N;;;;;
+13158;EGYPTIAN HIEROGLYPH G021;Lo;0;L;;;;;N;;;;;
+13159;EGYPTIAN HIEROGLYPH G022;Lo;0;L;;;;;N;;;;;
+1315A;EGYPTIAN HIEROGLYPH G023;Lo;0;L;;;;;N;;;;;
+1315B;EGYPTIAN HIEROGLYPH G024;Lo;0;L;;;;;N;;;;;
+1315C;EGYPTIAN HIEROGLYPH G025;Lo;0;L;;;;;N;;;;;
+1315D;EGYPTIAN HIEROGLYPH G026;Lo;0;L;;;;;N;;;;;
+1315E;EGYPTIAN HIEROGLYPH G026A;Lo;0;L;;;;;N;;;;;
+1315F;EGYPTIAN HIEROGLYPH G027;Lo;0;L;;;;;N;;;;;
+13160;EGYPTIAN HIEROGLYPH G028;Lo;0;L;;;;;N;;;;;
+13161;EGYPTIAN HIEROGLYPH G029;Lo;0;L;;;;;N;;;;;
+13162;EGYPTIAN HIEROGLYPH G030;Lo;0;L;;;;;N;;;;;
+13163;EGYPTIAN HIEROGLYPH G031;Lo;0;L;;;;;N;;;;;
+13164;EGYPTIAN HIEROGLYPH G032;Lo;0;L;;;;;N;;;;;
+13165;EGYPTIAN HIEROGLYPH G033;Lo;0;L;;;;;N;;;;;
+13166;EGYPTIAN HIEROGLYPH G034;Lo;0;L;;;;;N;;;;;
+13167;EGYPTIAN HIEROGLYPH G035;Lo;0;L;;;;;N;;;;;
+13168;EGYPTIAN HIEROGLYPH G036;Lo;0;L;;;;;N;;;;;
+13169;EGYPTIAN HIEROGLYPH G036A;Lo;0;L;;;;;N;;;;;
+1316A;EGYPTIAN HIEROGLYPH G037;Lo;0;L;;;;;N;;;;;
+1316B;EGYPTIAN HIEROGLYPH G037A;Lo;0;L;;;;;N;;;;;
+1316C;EGYPTIAN HIEROGLYPH G038;Lo;0;L;;;;;N;;;;;
+1316D;EGYPTIAN HIEROGLYPH G039;Lo;0;L;;;;;N;;;;;
+1316E;EGYPTIAN HIEROGLYPH G040;Lo;0;L;;;;;N;;;;;
+1316F;EGYPTIAN HIEROGLYPH G041;Lo;0;L;;;;;N;;;;;
+13170;EGYPTIAN HIEROGLYPH G042;Lo;0;L;;;;;N;;;;;
+13171;EGYPTIAN HIEROGLYPH G043;Lo;0;L;;;;;N;;;;;
+13172;EGYPTIAN HIEROGLYPH G043A;Lo;0;L;;;;;N;;;;;
+13173;EGYPTIAN HIEROGLYPH G044;Lo;0;L;;;;;N;;;;;
+13174;EGYPTIAN HIEROGLYPH G045;Lo;0;L;;;;;N;;;;;
+13175;EGYPTIAN HIEROGLYPH G045A;Lo;0;L;;;;;N;;;;;
+13176;EGYPTIAN HIEROGLYPH G046;Lo;0;L;;;;;N;;;;;
+13177;EGYPTIAN HIEROGLYPH G047;Lo;0;L;;;;;N;;;;;
+13178;EGYPTIAN HIEROGLYPH G048;Lo;0;L;;;;;N;;;;;
+13179;EGYPTIAN HIEROGLYPH G049;Lo;0;L;;;;;N;;;;;
+1317A;EGYPTIAN HIEROGLYPH G050;Lo;0;L;;;;;N;;;;;
+1317B;EGYPTIAN HIEROGLYPH G051;Lo;0;L;;;;;N;;;;;
+1317C;EGYPTIAN HIEROGLYPH G052;Lo;0;L;;;;;N;;;;;
+1317D;EGYPTIAN HIEROGLYPH G053;Lo;0;L;;;;;N;;;;;
+1317E;EGYPTIAN HIEROGLYPH G054;Lo;0;L;;;;;N;;;;;
+1317F;EGYPTIAN HIEROGLYPH H001;Lo;0;L;;;;;N;;;;;
+13180;EGYPTIAN HIEROGLYPH H002;Lo;0;L;;;;;N;;;;;
+13181;EGYPTIAN HIEROGLYPH H003;Lo;0;L;;;;;N;;;;;
+13182;EGYPTIAN HIEROGLYPH H004;Lo;0;L;;;;;N;;;;;
+13183;EGYPTIAN HIEROGLYPH H005;Lo;0;L;;;;;N;;;;;
+13184;EGYPTIAN HIEROGLYPH H006;Lo;0;L;;;;;N;;;;;
+13185;EGYPTIAN HIEROGLYPH H006A;Lo;0;L;;;;;N;;;;;
+13186;EGYPTIAN HIEROGLYPH H007;Lo;0;L;;;;;N;;;;;
+13187;EGYPTIAN HIEROGLYPH H008;Lo;0;L;;;;;N;;;;;
+13188;EGYPTIAN HIEROGLYPH I001;Lo;0;L;;;;;N;;;;;
+13189;EGYPTIAN HIEROGLYPH I002;Lo;0;L;;;;;N;;;;;
+1318A;EGYPTIAN HIEROGLYPH I003;Lo;0;L;;;;;N;;;;;
+1318B;EGYPTIAN HIEROGLYPH I004;Lo;0;L;;;;;N;;;;;
+1318C;EGYPTIAN HIEROGLYPH I005;Lo;0;L;;;;;N;;;;;
+1318D;EGYPTIAN HIEROGLYPH I005A;Lo;0;L;;;;;N;;;;;
+1318E;EGYPTIAN HIEROGLYPH I006;Lo;0;L;;;;;N;;;;;
+1318F;EGYPTIAN HIEROGLYPH I007;Lo;0;L;;;;;N;;;;;
+13190;EGYPTIAN HIEROGLYPH I008;Lo;0;L;;;;;N;;;;;
+13191;EGYPTIAN HIEROGLYPH I009;Lo;0;L;;;;;N;;;;;
+13192;EGYPTIAN HIEROGLYPH I009A;Lo;0;L;;;;;N;;;;;
+13193;EGYPTIAN HIEROGLYPH I010;Lo;0;L;;;;;N;;;;;
+13194;EGYPTIAN HIEROGLYPH I010A;Lo;0;L;;;;;N;;;;;
+13195;EGYPTIAN HIEROGLYPH I011;Lo;0;L;;;;;N;;;;;
+13196;EGYPTIAN HIEROGLYPH I011A;Lo;0;L;;;;;N;;;;;
+13197;EGYPTIAN HIEROGLYPH I012;Lo;0;L;;;;;N;;;;;
+13198;EGYPTIAN HIEROGLYPH I013;Lo;0;L;;;;;N;;;;;
+13199;EGYPTIAN HIEROGLYPH I014;Lo;0;L;;;;;N;;;;;
+1319A;EGYPTIAN HIEROGLYPH I015;Lo;0;L;;;;;N;;;;;
+1319B;EGYPTIAN HIEROGLYPH K001;Lo;0;L;;;;;N;;;;;
+1319C;EGYPTIAN HIEROGLYPH K002;Lo;0;L;;;;;N;;;;;
+1319D;EGYPTIAN HIEROGLYPH K003;Lo;0;L;;;;;N;;;;;
+1319E;EGYPTIAN HIEROGLYPH K004;Lo;0;L;;;;;N;;;;;
+1319F;EGYPTIAN HIEROGLYPH K005;Lo;0;L;;;;;N;;;;;
+131A0;EGYPTIAN HIEROGLYPH K006;Lo;0;L;;;;;N;;;;;
+131A1;EGYPTIAN HIEROGLYPH K007;Lo;0;L;;;;;N;;;;;
+131A2;EGYPTIAN HIEROGLYPH K008;Lo;0;L;;;;;N;;;;;
+131A3;EGYPTIAN HIEROGLYPH L001;Lo;0;L;;;;;N;;;;;
+131A4;EGYPTIAN HIEROGLYPH L002;Lo;0;L;;;;;N;;;;;
+131A5;EGYPTIAN HIEROGLYPH L002A;Lo;0;L;;;;;N;;;;;
+131A6;EGYPTIAN HIEROGLYPH L003;Lo;0;L;;;;;N;;;;;
+131A7;EGYPTIAN HIEROGLYPH L004;Lo;0;L;;;;;N;;;;;
+131A8;EGYPTIAN HIEROGLYPH L005;Lo;0;L;;;;;N;;;;;
+131A9;EGYPTIAN HIEROGLYPH L006;Lo;0;L;;;;;N;;;;;
+131AA;EGYPTIAN HIEROGLYPH L006A;Lo;0;L;;;;;N;;;;;
+131AB;EGYPTIAN HIEROGLYPH L007;Lo;0;L;;;;;N;;;;;
+131AC;EGYPTIAN HIEROGLYPH L008;Lo;0;L;;;;;N;;;;;
+131AD;EGYPTIAN HIEROGLYPH M001;Lo;0;L;;;;;N;;;;;
+131AE;EGYPTIAN HIEROGLYPH M001A;Lo;0;L;;;;;N;;;;;
+131AF;EGYPTIAN HIEROGLYPH M001B;Lo;0;L;;;;;N;;;;;
+131B0;EGYPTIAN HIEROGLYPH M002;Lo;0;L;;;;;N;;;;;
+131B1;EGYPTIAN HIEROGLYPH M003;Lo;0;L;;;;;N;;;;;
+131B2;EGYPTIAN HIEROGLYPH M003A;Lo;0;L;;;;;N;;;;;
+131B3;EGYPTIAN HIEROGLYPH M004;Lo;0;L;;;;;N;;;;;
+131B4;EGYPTIAN HIEROGLYPH M005;Lo;0;L;;;;;N;;;;;
+131B5;EGYPTIAN HIEROGLYPH M006;Lo;0;L;;;;;N;;;;;
+131B6;EGYPTIAN HIEROGLYPH M007;Lo;0;L;;;;;N;;;;;
+131B7;EGYPTIAN HIEROGLYPH M008;Lo;0;L;;;;;N;;;;;
+131B8;EGYPTIAN HIEROGLYPH M009;Lo;0;L;;;;;N;;;;;
+131B9;EGYPTIAN HIEROGLYPH M010;Lo;0;L;;;;;N;;;;;
+131BA;EGYPTIAN HIEROGLYPH M010A;Lo;0;L;;;;;N;;;;;
+131BB;EGYPTIAN HIEROGLYPH M011;Lo;0;L;;;;;N;;;;;
+131BC;EGYPTIAN HIEROGLYPH M012;Lo;0;L;;;;;N;;;;;
+131BD;EGYPTIAN HIEROGLYPH M012A;Lo;0;L;;;;;N;;;;;
+131BE;EGYPTIAN HIEROGLYPH M012B;Lo;0;L;;;;;N;;;;;
+131BF;EGYPTIAN HIEROGLYPH M012C;Lo;0;L;;;;;N;;;;;
+131C0;EGYPTIAN HIEROGLYPH M012D;Lo;0;L;;;;;N;;;;;
+131C1;EGYPTIAN HIEROGLYPH M012E;Lo;0;L;;;;;N;;;;;
+131C2;EGYPTIAN HIEROGLYPH M012F;Lo;0;L;;;;;N;;;;;
+131C3;EGYPTIAN HIEROGLYPH M012G;Lo;0;L;;;;;N;;;;;
+131C4;EGYPTIAN HIEROGLYPH M012H;Lo;0;L;;;;;N;;;;;
+131C5;EGYPTIAN HIEROGLYPH M013;Lo;0;L;;;;;N;;;;;
+131C6;EGYPTIAN HIEROGLYPH M014;Lo;0;L;;;;;N;;;;;
+131C7;EGYPTIAN HIEROGLYPH M015;Lo;0;L;;;;;N;;;;;
+131C8;EGYPTIAN HIEROGLYPH M015A;Lo;0;L;;;;;N;;;;;
+131C9;EGYPTIAN HIEROGLYPH M016;Lo;0;L;;;;;N;;;;;
+131CA;EGYPTIAN HIEROGLYPH M016A;Lo;0;L;;;;;N;;;;;
+131CB;EGYPTIAN HIEROGLYPH M017;Lo;0;L;;;;;N;;;;;
+131CC;EGYPTIAN HIEROGLYPH M017A;Lo;0;L;;;;;N;;;;;
+131CD;EGYPTIAN HIEROGLYPH M018;Lo;0;L;;;;;N;;;;;
+131CE;EGYPTIAN HIEROGLYPH M019;Lo;0;L;;;;;N;;;;;
+131CF;EGYPTIAN HIEROGLYPH M020;Lo;0;L;;;;;N;;;;;
+131D0;EGYPTIAN HIEROGLYPH M021;Lo;0;L;;;;;N;;;;;
+131D1;EGYPTIAN HIEROGLYPH M022;Lo;0;L;;;;;N;;;;;
+131D2;EGYPTIAN HIEROGLYPH M022A;Lo;0;L;;;;;N;;;;;
+131D3;EGYPTIAN HIEROGLYPH M023;Lo;0;L;;;;;N;;;;;
+131D4;EGYPTIAN HIEROGLYPH M024;Lo;0;L;;;;;N;;;;;
+131D5;EGYPTIAN HIEROGLYPH M024A;Lo;0;L;;;;;N;;;;;
+131D6;EGYPTIAN HIEROGLYPH M025;Lo;0;L;;;;;N;;;;;
+131D7;EGYPTIAN HIEROGLYPH M026;Lo;0;L;;;;;N;;;;;
+131D8;EGYPTIAN HIEROGLYPH M027;Lo;0;L;;;;;N;;;;;
+131D9;EGYPTIAN HIEROGLYPH M028;Lo;0;L;;;;;N;;;;;
+131DA;EGYPTIAN HIEROGLYPH M028A;Lo;0;L;;;;;N;;;;;
+131DB;EGYPTIAN HIEROGLYPH M029;Lo;0;L;;;;;N;;;;;
+131DC;EGYPTIAN HIEROGLYPH M030;Lo;0;L;;;;;N;;;;;
+131DD;EGYPTIAN HIEROGLYPH M031;Lo;0;L;;;;;N;;;;;
+131DE;EGYPTIAN HIEROGLYPH M031A;Lo;0;L;;;;;N;;;;;
+131DF;EGYPTIAN HIEROGLYPH M032;Lo;0;L;;;;;N;;;;;
+131E0;EGYPTIAN HIEROGLYPH M033;Lo;0;L;;;;;N;;;;;
+131E1;EGYPTIAN HIEROGLYPH M033A;Lo;0;L;;;;;N;;;;;
+131E2;EGYPTIAN HIEROGLYPH M033B;Lo;0;L;;;;;N;;;;;
+131E3;EGYPTIAN HIEROGLYPH M034;Lo;0;L;;;;;N;;;;;
+131E4;EGYPTIAN HIEROGLYPH M035;Lo;0;L;;;;;N;;;;;
+131E5;EGYPTIAN HIEROGLYPH M036;Lo;0;L;;;;;N;;;;;
+131E6;EGYPTIAN HIEROGLYPH M037;Lo;0;L;;;;;N;;;;;
+131E7;EGYPTIAN HIEROGLYPH M038;Lo;0;L;;;;;N;;;;;
+131E8;EGYPTIAN HIEROGLYPH M039;Lo;0;L;;;;;N;;;;;
+131E9;EGYPTIAN HIEROGLYPH M040;Lo;0;L;;;;;N;;;;;
+131EA;EGYPTIAN HIEROGLYPH M040A;Lo;0;L;;;;;N;;;;;
+131EB;EGYPTIAN HIEROGLYPH M041;Lo;0;L;;;;;N;;;;;
+131EC;EGYPTIAN HIEROGLYPH M042;Lo;0;L;;;;;N;;;;;
+131ED;EGYPTIAN HIEROGLYPH M043;Lo;0;L;;;;;N;;;;;
+131EE;EGYPTIAN HIEROGLYPH M044;Lo;0;L;;;;;N;;;;;
+131EF;EGYPTIAN HIEROGLYPH N001;Lo;0;L;;;;;N;;;;;
+131F0;EGYPTIAN HIEROGLYPH N002;Lo;0;L;;;;;N;;;;;
+131F1;EGYPTIAN HIEROGLYPH N003;Lo;0;L;;;;;N;;;;;
+131F2;EGYPTIAN HIEROGLYPH N004;Lo;0;L;;;;;N;;;;;
+131F3;EGYPTIAN HIEROGLYPH N005;Lo;0;L;;;;;N;;;;;
+131F4;EGYPTIAN HIEROGLYPH N006;Lo;0;L;;;;;N;;;;;
+131F5;EGYPTIAN HIEROGLYPH N007;Lo;0;L;;;;;N;;;;;
+131F6;EGYPTIAN HIEROGLYPH N008;Lo;0;L;;;;;N;;;;;
+131F7;EGYPTIAN HIEROGLYPH N009;Lo;0;L;;;;;N;;;;;
+131F8;EGYPTIAN HIEROGLYPH N010;Lo;0;L;;;;;N;;;;;
+131F9;EGYPTIAN HIEROGLYPH N011;Lo;0;L;;;;;N;;;;;
+131FA;EGYPTIAN HIEROGLYPH N012;Lo;0;L;;;;;N;;;;;
+131FB;EGYPTIAN HIEROGLYPH N013;Lo;0;L;;;;;N;;;;;
+131FC;EGYPTIAN HIEROGLYPH N014;Lo;0;L;;;;;N;;;;;
+131FD;EGYPTIAN HIEROGLYPH N015;Lo;0;L;;;;;N;;;;;
+131FE;EGYPTIAN HIEROGLYPH N016;Lo;0;L;;;;;N;;;;;
+131FF;EGYPTIAN HIEROGLYPH N017;Lo;0;L;;;;;N;;;;;
+13200;EGYPTIAN HIEROGLYPH N018;Lo;0;L;;;;;N;;;;;
+13201;EGYPTIAN HIEROGLYPH N018A;Lo;0;L;;;;;N;;;;;
+13202;EGYPTIAN HIEROGLYPH N018B;Lo;0;L;;;;;N;;;;;
+13203;EGYPTIAN HIEROGLYPH N019;Lo;0;L;;;;;N;;;;;
+13204;EGYPTIAN HIEROGLYPH N020;Lo;0;L;;;;;N;;;;;
+13205;EGYPTIAN HIEROGLYPH N021;Lo;0;L;;;;;N;;;;;
+13206;EGYPTIAN HIEROGLYPH N022;Lo;0;L;;;;;N;;;;;
+13207;EGYPTIAN HIEROGLYPH N023;Lo;0;L;;;;;N;;;;;
+13208;EGYPTIAN HIEROGLYPH N024;Lo;0;L;;;;;N;;;;;
+13209;EGYPTIAN HIEROGLYPH N025;Lo;0;L;;;;;N;;;;;
+1320A;EGYPTIAN HIEROGLYPH N025A;Lo;0;L;;;;;N;;;;;
+1320B;EGYPTIAN HIEROGLYPH N026;Lo;0;L;;;;;N;;;;;
+1320C;EGYPTIAN HIEROGLYPH N027;Lo;0;L;;;;;N;;;;;
+1320D;EGYPTIAN HIEROGLYPH N028;Lo;0;L;;;;;N;;;;;
+1320E;EGYPTIAN HIEROGLYPH N029;Lo;0;L;;;;;N;;;;;
+1320F;EGYPTIAN HIEROGLYPH N030;Lo;0;L;;;;;N;;;;;
+13210;EGYPTIAN HIEROGLYPH N031;Lo;0;L;;;;;N;;;;;
+13211;EGYPTIAN HIEROGLYPH N032;Lo;0;L;;;;;N;;;;;
+13212;EGYPTIAN HIEROGLYPH N033;Lo;0;L;;;;;N;;;;;
+13213;EGYPTIAN HIEROGLYPH N033A;Lo;0;L;;;;;N;;;;;
+13214;EGYPTIAN HIEROGLYPH N034;Lo;0;L;;;;;N;;;;;
+13215;EGYPTIAN HIEROGLYPH N034A;Lo;0;L;;;;;N;;;;;
+13216;EGYPTIAN HIEROGLYPH N035;Lo;0;L;;;;;N;;;;;
+13217;EGYPTIAN HIEROGLYPH N035A;Lo;0;L;;;;;N;;;;;
+13218;EGYPTIAN HIEROGLYPH N036;Lo;0;L;;;;;N;;;;;
+13219;EGYPTIAN HIEROGLYPH N037;Lo;0;L;;;;;N;;;;;
+1321A;EGYPTIAN HIEROGLYPH N037A;Lo;0;L;;;;;N;;;;;
+1321B;EGYPTIAN HIEROGLYPH N038;Lo;0;L;;;;;N;;;;;
+1321C;EGYPTIAN HIEROGLYPH N039;Lo;0;L;;;;;N;;;;;
+1321D;EGYPTIAN HIEROGLYPH N040;Lo;0;L;;;;;N;;;;;
+1321E;EGYPTIAN HIEROGLYPH N041;Lo;0;L;;;;;N;;;;;
+1321F;EGYPTIAN HIEROGLYPH N042;Lo;0;L;;;;;N;;;;;
+13220;EGYPTIAN HIEROGLYPH NL001;Lo;0;L;;;;;N;;;;;
+13221;EGYPTIAN HIEROGLYPH NL002;Lo;0;L;;;;;N;;;;;
+13222;EGYPTIAN HIEROGLYPH NL003;Lo;0;L;;;;;N;;;;;
+13223;EGYPTIAN HIEROGLYPH NL004;Lo;0;L;;;;;N;;;;;
+13224;EGYPTIAN HIEROGLYPH NL005;Lo;0;L;;;;;N;;;;;
+13225;EGYPTIAN HIEROGLYPH NL005A;Lo;0;L;;;;;N;;;;;
+13226;EGYPTIAN HIEROGLYPH NL006;Lo;0;L;;;;;N;;;;;
+13227;EGYPTIAN HIEROGLYPH NL007;Lo;0;L;;;;;N;;;;;
+13228;EGYPTIAN HIEROGLYPH NL008;Lo;0;L;;;;;N;;;;;
+13229;EGYPTIAN HIEROGLYPH NL009;Lo;0;L;;;;;N;;;;;
+1322A;EGYPTIAN HIEROGLYPH NL010;Lo;0;L;;;;;N;;;;;
+1322B;EGYPTIAN HIEROGLYPH NL011;Lo;0;L;;;;;N;;;;;
+1322C;EGYPTIAN HIEROGLYPH NL012;Lo;0;L;;;;;N;;;;;
+1322D;EGYPTIAN HIEROGLYPH NL013;Lo;0;L;;;;;N;;;;;
+1322E;EGYPTIAN HIEROGLYPH NL014;Lo;0;L;;;;;N;;;;;
+1322F;EGYPTIAN HIEROGLYPH NL015;Lo;0;L;;;;;N;;;;;
+13230;EGYPTIAN HIEROGLYPH NL016;Lo;0;L;;;;;N;;;;;
+13231;EGYPTIAN HIEROGLYPH NL017;Lo;0;L;;;;;N;;;;;
+13232;EGYPTIAN HIEROGLYPH NL017A;Lo;0;L;;;;;N;;;;;
+13233;EGYPTIAN HIEROGLYPH NL018;Lo;0;L;;;;;N;;;;;
+13234;EGYPTIAN HIEROGLYPH NL019;Lo;0;L;;;;;N;;;;;
+13235;EGYPTIAN HIEROGLYPH NL020;Lo;0;L;;;;;N;;;;;
+13236;EGYPTIAN HIEROGLYPH NU001;Lo;0;L;;;;;N;;;;;
+13237;EGYPTIAN HIEROGLYPH NU002;Lo;0;L;;;;;N;;;;;
+13238;EGYPTIAN HIEROGLYPH NU003;Lo;0;L;;;;;N;;;;;
+13239;EGYPTIAN HIEROGLYPH NU004;Lo;0;L;;;;;N;;;;;
+1323A;EGYPTIAN HIEROGLYPH NU005;Lo;0;L;;;;;N;;;;;
+1323B;EGYPTIAN HIEROGLYPH NU006;Lo;0;L;;;;;N;;;;;
+1323C;EGYPTIAN HIEROGLYPH NU007;Lo;0;L;;;;;N;;;;;
+1323D;EGYPTIAN HIEROGLYPH NU008;Lo;0;L;;;;;N;;;;;
+1323E;EGYPTIAN HIEROGLYPH NU009;Lo;0;L;;;;;N;;;;;
+1323F;EGYPTIAN HIEROGLYPH NU010;Lo;0;L;;;;;N;;;;;
+13240;EGYPTIAN HIEROGLYPH NU010A;Lo;0;L;;;;;N;;;;;
+13241;EGYPTIAN HIEROGLYPH NU011;Lo;0;L;;;;;N;;;;;
+13242;EGYPTIAN HIEROGLYPH NU011A;Lo;0;L;;;;;N;;;;;
+13243;EGYPTIAN HIEROGLYPH NU012;Lo;0;L;;;;;N;;;;;
+13244;EGYPTIAN HIEROGLYPH NU013;Lo;0;L;;;;;N;;;;;
+13245;EGYPTIAN HIEROGLYPH NU014;Lo;0;L;;;;;N;;;;;
+13246;EGYPTIAN HIEROGLYPH NU015;Lo;0;L;;;;;N;;;;;
+13247;EGYPTIAN HIEROGLYPH NU016;Lo;0;L;;;;;N;;;;;
+13248;EGYPTIAN HIEROGLYPH NU017;Lo;0;L;;;;;N;;;;;
+13249;EGYPTIAN HIEROGLYPH NU018;Lo;0;L;;;;;N;;;;;
+1324A;EGYPTIAN HIEROGLYPH NU018A;Lo;0;L;;;;;N;;;;;
+1324B;EGYPTIAN HIEROGLYPH NU019;Lo;0;L;;;;;N;;;;;
+1324C;EGYPTIAN HIEROGLYPH NU020;Lo;0;L;;;;;N;;;;;
+1324D;EGYPTIAN HIEROGLYPH NU021;Lo;0;L;;;;;N;;;;;
+1324E;EGYPTIAN HIEROGLYPH NU022;Lo;0;L;;;;;N;;;;;
+1324F;EGYPTIAN HIEROGLYPH NU022A;Lo;0;L;;;;;N;;;;;
+13250;EGYPTIAN HIEROGLYPH O001;Lo;0;L;;;;;N;;;;;
+13251;EGYPTIAN HIEROGLYPH O001A;Lo;0;L;;;;;N;;;;;
+13252;EGYPTIAN HIEROGLYPH O002;Lo;0;L;;;;;N;;;;;
+13253;EGYPTIAN HIEROGLYPH O003;Lo;0;L;;;;;N;;;;;
+13254;EGYPTIAN HIEROGLYPH O004;Lo;0;L;;;;;N;;;;;
+13255;EGYPTIAN HIEROGLYPH O005;Lo;0;L;;;;;N;;;;;
+13256;EGYPTIAN HIEROGLYPH O005A;Lo;0;L;;;;;N;;;;;
+13257;EGYPTIAN HIEROGLYPH O006;Lo;0;L;;;;;N;;;;;
+13258;EGYPTIAN HIEROGLYPH O006A;Lo;0;L;;;;;N;;;;;
+13259;EGYPTIAN HIEROGLYPH O006B;Lo;0;L;;;;;N;;;;;
+1325A;EGYPTIAN HIEROGLYPH O006C;Lo;0;L;;;;;N;;;;;
+1325B;EGYPTIAN HIEROGLYPH O006D;Lo;0;L;;;;;N;;;;;
+1325C;EGYPTIAN HIEROGLYPH O006E;Lo;0;L;;;;;N;;;;;
+1325D;EGYPTIAN HIEROGLYPH O006F;Lo;0;L;;;;;N;;;;;
+1325E;EGYPTIAN HIEROGLYPH O007;Lo;0;L;;;;;N;;;;;
+1325F;EGYPTIAN HIEROGLYPH O008;Lo;0;L;;;;;N;;;;;
+13260;EGYPTIAN HIEROGLYPH O009;Lo;0;L;;;;;N;;;;;
+13261;EGYPTIAN HIEROGLYPH O010;Lo;0;L;;;;;N;;;;;
+13262;EGYPTIAN HIEROGLYPH O010A;Lo;0;L;;;;;N;;;;;
+13263;EGYPTIAN HIEROGLYPH O010B;Lo;0;L;;;;;N;;;;;
+13264;EGYPTIAN HIEROGLYPH O010C;Lo;0;L;;;;;N;;;;;
+13265;EGYPTIAN HIEROGLYPH O011;Lo;0;L;;;;;N;;;;;
+13266;EGYPTIAN HIEROGLYPH O012;Lo;0;L;;;;;N;;;;;
+13267;EGYPTIAN HIEROGLYPH O013;Lo;0;L;;;;;N;;;;;
+13268;EGYPTIAN HIEROGLYPH O014;Lo;0;L;;;;;N;;;;;
+13269;EGYPTIAN HIEROGLYPH O015;Lo;0;L;;;;;N;;;;;
+1326A;EGYPTIAN HIEROGLYPH O016;Lo;0;L;;;;;N;;;;;
+1326B;EGYPTIAN HIEROGLYPH O017;Lo;0;L;;;;;N;;;;;
+1326C;EGYPTIAN HIEROGLYPH O018;Lo;0;L;;;;;N;;;;;
+1326D;EGYPTIAN HIEROGLYPH O019;Lo;0;L;;;;;N;;;;;
+1326E;EGYPTIAN HIEROGLYPH O019A;Lo;0;L;;;;;N;;;;;
+1326F;EGYPTIAN HIEROGLYPH O020;Lo;0;L;;;;;N;;;;;
+13270;EGYPTIAN HIEROGLYPH O020A;Lo;0;L;;;;;N;;;;;
+13271;EGYPTIAN HIEROGLYPH O021;Lo;0;L;;;;;N;;;;;
+13272;EGYPTIAN HIEROGLYPH O022;Lo;0;L;;;;;N;;;;;
+13273;EGYPTIAN HIEROGLYPH O023;Lo;0;L;;;;;N;;;;;
+13274;EGYPTIAN HIEROGLYPH O024;Lo;0;L;;;;;N;;;;;
+13275;EGYPTIAN HIEROGLYPH O024A;Lo;0;L;;;;;N;;;;;
+13276;EGYPTIAN HIEROGLYPH O025;Lo;0;L;;;;;N;;;;;
+13277;EGYPTIAN HIEROGLYPH O025A;Lo;0;L;;;;;N;;;;;
+13278;EGYPTIAN HIEROGLYPH O026;Lo;0;L;;;;;N;;;;;
+13279;EGYPTIAN HIEROGLYPH O027;Lo;0;L;;;;;N;;;;;
+1327A;EGYPTIAN HIEROGLYPH O028;Lo;0;L;;;;;N;;;;;
+1327B;EGYPTIAN HIEROGLYPH O029;Lo;0;L;;;;;N;;;;;
+1327C;EGYPTIAN HIEROGLYPH O029A;Lo;0;L;;;;;N;;;;;
+1327D;EGYPTIAN HIEROGLYPH O030;Lo;0;L;;;;;N;;;;;
+1327E;EGYPTIAN HIEROGLYPH O030A;Lo;0;L;;;;;N;;;;;
+1327F;EGYPTIAN HIEROGLYPH O031;Lo;0;L;;;;;N;;;;;
+13280;EGYPTIAN HIEROGLYPH O032;Lo;0;L;;;;;N;;;;;
+13281;EGYPTIAN HIEROGLYPH O033;Lo;0;L;;;;;N;;;;;
+13282;EGYPTIAN HIEROGLYPH O033A;Lo;0;L;;;;;N;;;;;
+13283;EGYPTIAN HIEROGLYPH O034;Lo;0;L;;;;;N;;;;;
+13284;EGYPTIAN HIEROGLYPH O035;Lo;0;L;;;;;N;;;;;
+13285;EGYPTIAN HIEROGLYPH O036;Lo;0;L;;;;;N;;;;;
+13286;EGYPTIAN HIEROGLYPH O036A;Lo;0;L;;;;;N;;;;;
+13287;EGYPTIAN HIEROGLYPH O036B;Lo;0;L;;;;;N;;;;;
+13288;EGYPTIAN HIEROGLYPH O036C;Lo;0;L;;;;;N;;;;;
+13289;EGYPTIAN HIEROGLYPH O036D;Lo;0;L;;;;;N;;;;;
+1328A;EGYPTIAN HIEROGLYPH O037;Lo;0;L;;;;;N;;;;;
+1328B;EGYPTIAN HIEROGLYPH O038;Lo;0;L;;;;;N;;;;;
+1328C;EGYPTIAN HIEROGLYPH O039;Lo;0;L;;;;;N;;;;;
+1328D;EGYPTIAN HIEROGLYPH O040;Lo;0;L;;;;;N;;;;;
+1328E;EGYPTIAN HIEROGLYPH O041;Lo;0;L;;;;;N;;;;;
+1328F;EGYPTIAN HIEROGLYPH O042;Lo;0;L;;;;;N;;;;;
+13290;EGYPTIAN HIEROGLYPH O043;Lo;0;L;;;;;N;;;;;
+13291;EGYPTIAN HIEROGLYPH O044;Lo;0;L;;;;;N;;;;;
+13292;EGYPTIAN HIEROGLYPH O045;Lo;0;L;;;;;N;;;;;
+13293;EGYPTIAN HIEROGLYPH O046;Lo;0;L;;;;;N;;;;;
+13294;EGYPTIAN HIEROGLYPH O047;Lo;0;L;;;;;N;;;;;
+13295;EGYPTIAN HIEROGLYPH O048;Lo;0;L;;;;;N;;;;;
+13296;EGYPTIAN HIEROGLYPH O049;Lo;0;L;;;;;N;;;;;
+13297;EGYPTIAN HIEROGLYPH O050;Lo;0;L;;;;;N;;;;;
+13298;EGYPTIAN HIEROGLYPH O050A;Lo;0;L;;;;;N;;;;;
+13299;EGYPTIAN HIEROGLYPH O050B;Lo;0;L;;;;;N;;;;;
+1329A;EGYPTIAN HIEROGLYPH O051;Lo;0;L;;;;;N;;;;;
+1329B;EGYPTIAN HIEROGLYPH P001;Lo;0;L;;;;;N;;;;;
+1329C;EGYPTIAN HIEROGLYPH P001A;Lo;0;L;;;;;N;;;;;
+1329D;EGYPTIAN HIEROGLYPH P002;Lo;0;L;;;;;N;;;;;
+1329E;EGYPTIAN HIEROGLYPH P003;Lo;0;L;;;;;N;;;;;
+1329F;EGYPTIAN HIEROGLYPH P003A;Lo;0;L;;;;;N;;;;;
+132A0;EGYPTIAN HIEROGLYPH P004;Lo;0;L;;;;;N;;;;;
+132A1;EGYPTIAN HIEROGLYPH P005;Lo;0;L;;;;;N;;;;;
+132A2;EGYPTIAN HIEROGLYPH P006;Lo;0;L;;;;;N;;;;;
+132A3;EGYPTIAN HIEROGLYPH P007;Lo;0;L;;;;;N;;;;;
+132A4;EGYPTIAN HIEROGLYPH P008;Lo;0;L;;;;;N;;;;;
+132A5;EGYPTIAN HIEROGLYPH P009;Lo;0;L;;;;;N;;;;;
+132A6;EGYPTIAN HIEROGLYPH P010;Lo;0;L;;;;;N;;;;;
+132A7;EGYPTIAN HIEROGLYPH P011;Lo;0;L;;;;;N;;;;;
+132A8;EGYPTIAN HIEROGLYPH Q001;Lo;0;L;;;;;N;;;;;
+132A9;EGYPTIAN HIEROGLYPH Q002;Lo;0;L;;;;;N;;;;;
+132AA;EGYPTIAN HIEROGLYPH Q003;Lo;0;L;;;;;N;;;;;
+132AB;EGYPTIAN HIEROGLYPH Q004;Lo;0;L;;;;;N;;;;;
+132AC;EGYPTIAN HIEROGLYPH Q005;Lo;0;L;;;;;N;;;;;
+132AD;EGYPTIAN HIEROGLYPH Q006;Lo;0;L;;;;;N;;;;;
+132AE;EGYPTIAN HIEROGLYPH Q007;Lo;0;L;;;;;N;;;;;
+132AF;EGYPTIAN HIEROGLYPH R001;Lo;0;L;;;;;N;;;;;
+132B0;EGYPTIAN HIEROGLYPH R002;Lo;0;L;;;;;N;;;;;
+132B1;EGYPTIAN HIEROGLYPH R002A;Lo;0;L;;;;;N;;;;;
+132B2;EGYPTIAN HIEROGLYPH R003;Lo;0;L;;;;;N;;;;;
+132B3;EGYPTIAN HIEROGLYPH R003A;Lo;0;L;;;;;N;;;;;
+132B4;EGYPTIAN HIEROGLYPH R003B;Lo;0;L;;;;;N;;;;;
+132B5;EGYPTIAN HIEROGLYPH R004;Lo;0;L;;;;;N;;;;;
+132B6;EGYPTIAN HIEROGLYPH R005;Lo;0;L;;;;;N;;;;;
+132B7;EGYPTIAN HIEROGLYPH R006;Lo;0;L;;;;;N;;;;;
+132B8;EGYPTIAN HIEROGLYPH R007;Lo;0;L;;;;;N;;;;;
+132B9;EGYPTIAN HIEROGLYPH R008;Lo;0;L;;;;;N;;;;;
+132BA;EGYPTIAN HIEROGLYPH R009;Lo;0;L;;;;;N;;;;;
+132BB;EGYPTIAN HIEROGLYPH R010;Lo;0;L;;;;;N;;;;;
+132BC;EGYPTIAN HIEROGLYPH R010A;Lo;0;L;;;;;N;;;;;
+132BD;EGYPTIAN HIEROGLYPH R011;Lo;0;L;;;;;N;;;;;
+132BE;EGYPTIAN HIEROGLYPH R012;Lo;0;L;;;;;N;;;;;
+132BF;EGYPTIAN HIEROGLYPH R013;Lo;0;L;;;;;N;;;;;
+132C0;EGYPTIAN HIEROGLYPH R014;Lo;0;L;;;;;N;;;;;
+132C1;EGYPTIAN HIEROGLYPH R015;Lo;0;L;;;;;N;;;;;
+132C2;EGYPTIAN HIEROGLYPH R016;Lo;0;L;;;;;N;;;;;
+132C3;EGYPTIAN HIEROGLYPH R016A;Lo;0;L;;;;;N;;;;;
+132C4;EGYPTIAN HIEROGLYPH R017;Lo;0;L;;;;;N;;;;;
+132C5;EGYPTIAN HIEROGLYPH R018;Lo;0;L;;;;;N;;;;;
+132C6;EGYPTIAN HIEROGLYPH R019;Lo;0;L;;;;;N;;;;;
+132C7;EGYPTIAN HIEROGLYPH R020;Lo;0;L;;;;;N;;;;;
+132C8;EGYPTIAN HIEROGLYPH R021;Lo;0;L;;;;;N;;;;;
+132C9;EGYPTIAN HIEROGLYPH R022;Lo;0;L;;;;;N;;;;;
+132CA;EGYPTIAN HIEROGLYPH R023;Lo;0;L;;;;;N;;;;;
+132CB;EGYPTIAN HIEROGLYPH R024;Lo;0;L;;;;;N;;;;;
+132CC;EGYPTIAN HIEROGLYPH R025;Lo;0;L;;;;;N;;;;;
+132CD;EGYPTIAN HIEROGLYPH R026;Lo;0;L;;;;;N;;;;;
+132CE;EGYPTIAN HIEROGLYPH R027;Lo;0;L;;;;;N;;;;;
+132CF;EGYPTIAN HIEROGLYPH R028;Lo;0;L;;;;;N;;;;;
+132D0;EGYPTIAN HIEROGLYPH R029;Lo;0;L;;;;;N;;;;;
+132D1;EGYPTIAN HIEROGLYPH S001;Lo;0;L;;;;;N;;;;;
+132D2;EGYPTIAN HIEROGLYPH S002;Lo;0;L;;;;;N;;;;;
+132D3;EGYPTIAN HIEROGLYPH S002A;Lo;0;L;;;;;N;;;;;
+132D4;EGYPTIAN HIEROGLYPH S003;Lo;0;L;;;;;N;;;;;
+132D5;EGYPTIAN HIEROGLYPH S004;Lo;0;L;;;;;N;;;;;
+132D6;EGYPTIAN HIEROGLYPH S005;Lo;0;L;;;;;N;;;;;
+132D7;EGYPTIAN HIEROGLYPH S006;Lo;0;L;;;;;N;;;;;
+132D8;EGYPTIAN HIEROGLYPH S006A;Lo;0;L;;;;;N;;;;;
+132D9;EGYPTIAN HIEROGLYPH S007;Lo;0;L;;;;;N;;;;;
+132DA;EGYPTIAN HIEROGLYPH S008;Lo;0;L;;;;;N;;;;;
+132DB;EGYPTIAN HIEROGLYPH S009;Lo;0;L;;;;;N;;;;;
+132DC;EGYPTIAN HIEROGLYPH S010;Lo;0;L;;;;;N;;;;;
+132DD;EGYPTIAN HIEROGLYPH S011;Lo;0;L;;;;;N;;;;;
+132DE;EGYPTIAN HIEROGLYPH S012;Lo;0;L;;;;;N;;;;;
+132DF;EGYPTIAN HIEROGLYPH S013;Lo;0;L;;;;;N;;;;;
+132E0;EGYPTIAN HIEROGLYPH S014;Lo;0;L;;;;;N;;;;;
+132E1;EGYPTIAN HIEROGLYPH S014A;Lo;0;L;;;;;N;;;;;
+132E2;EGYPTIAN HIEROGLYPH S014B;Lo;0;L;;;;;N;;;;;
+132E3;EGYPTIAN HIEROGLYPH S015;Lo;0;L;;;;;N;;;;;
+132E4;EGYPTIAN HIEROGLYPH S016;Lo;0;L;;;;;N;;;;;
+132E5;EGYPTIAN HIEROGLYPH S017;Lo;0;L;;;;;N;;;;;
+132E6;EGYPTIAN HIEROGLYPH S017A;Lo;0;L;;;;;N;;;;;
+132E7;EGYPTIAN HIEROGLYPH S018;Lo;0;L;;;;;N;;;;;
+132E8;EGYPTIAN HIEROGLYPH S019;Lo;0;L;;;;;N;;;;;
+132E9;EGYPTIAN HIEROGLYPH S020;Lo;0;L;;;;;N;;;;;
+132EA;EGYPTIAN HIEROGLYPH S021;Lo;0;L;;;;;N;;;;;
+132EB;EGYPTIAN HIEROGLYPH S022;Lo;0;L;;;;;N;;;;;
+132EC;EGYPTIAN HIEROGLYPH S023;Lo;0;L;;;;;N;;;;;
+132ED;EGYPTIAN HIEROGLYPH S024;Lo;0;L;;;;;N;;;;;
+132EE;EGYPTIAN HIEROGLYPH S025;Lo;0;L;;;;;N;;;;;
+132EF;EGYPTIAN HIEROGLYPH S026;Lo;0;L;;;;;N;;;;;
+132F0;EGYPTIAN HIEROGLYPH S026A;Lo;0;L;;;;;N;;;;;
+132F1;EGYPTIAN HIEROGLYPH S026B;Lo;0;L;;;;;N;;;;;
+132F2;EGYPTIAN HIEROGLYPH S027;Lo;0;L;;;;;N;;;;;
+132F3;EGYPTIAN HIEROGLYPH S028;Lo;0;L;;;;;N;;;;;
+132F4;EGYPTIAN HIEROGLYPH S029;Lo;0;L;;;;;N;;;;;
+132F5;EGYPTIAN HIEROGLYPH S030;Lo;0;L;;;;;N;;;;;
+132F6;EGYPTIAN HIEROGLYPH S031;Lo;0;L;;;;;N;;;;;
+132F7;EGYPTIAN HIEROGLYPH S032;Lo;0;L;;;;;N;;;;;
+132F8;EGYPTIAN HIEROGLYPH S033;Lo;0;L;;;;;N;;;;;
+132F9;EGYPTIAN HIEROGLYPH S034;Lo;0;L;;;;;N;;;;;
+132FA;EGYPTIAN HIEROGLYPH S035;Lo;0;L;;;;;N;;;;;
+132FB;EGYPTIAN HIEROGLYPH S035A;Lo;0;L;;;;;N;;;;;
+132FC;EGYPTIAN HIEROGLYPH S036;Lo;0;L;;;;;N;;;;;
+132FD;EGYPTIAN HIEROGLYPH S037;Lo;0;L;;;;;N;;;;;
+132FE;EGYPTIAN HIEROGLYPH S038;Lo;0;L;;;;;N;;;;;
+132FF;EGYPTIAN HIEROGLYPH S039;Lo;0;L;;;;;N;;;;;
+13300;EGYPTIAN HIEROGLYPH S040;Lo;0;L;;;;;N;;;;;
+13301;EGYPTIAN HIEROGLYPH S041;Lo;0;L;;;;;N;;;;;
+13302;EGYPTIAN HIEROGLYPH S042;Lo;0;L;;;;;N;;;;;
+13303;EGYPTIAN HIEROGLYPH S043;Lo;0;L;;;;;N;;;;;
+13304;EGYPTIAN HIEROGLYPH S044;Lo;0;L;;;;;N;;;;;
+13305;EGYPTIAN HIEROGLYPH S045;Lo;0;L;;;;;N;;;;;
+13306;EGYPTIAN HIEROGLYPH S046;Lo;0;L;;;;;N;;;;;
+13307;EGYPTIAN HIEROGLYPH T001;Lo;0;L;;;;;N;;;;;
+13308;EGYPTIAN HIEROGLYPH T002;Lo;0;L;;;;;N;;;;;
+13309;EGYPTIAN HIEROGLYPH T003;Lo;0;L;;;;;N;;;;;
+1330A;EGYPTIAN HIEROGLYPH T003A;Lo;0;L;;;;;N;;;;;
+1330B;EGYPTIAN HIEROGLYPH T004;Lo;0;L;;;;;N;;;;;
+1330C;EGYPTIAN HIEROGLYPH T005;Lo;0;L;;;;;N;;;;;
+1330D;EGYPTIAN HIEROGLYPH T006;Lo;0;L;;;;;N;;;;;
+1330E;EGYPTIAN HIEROGLYPH T007;Lo;0;L;;;;;N;;;;;
+1330F;EGYPTIAN HIEROGLYPH T007A;Lo;0;L;;;;;N;;;;;
+13310;EGYPTIAN HIEROGLYPH T008;Lo;0;L;;;;;N;;;;;
+13311;EGYPTIAN HIEROGLYPH T008A;Lo;0;L;;;;;N;;;;;
+13312;EGYPTIAN HIEROGLYPH T009;Lo;0;L;;;;;N;;;;;
+13313;EGYPTIAN HIEROGLYPH T009A;Lo;0;L;;;;;N;;;;;
+13314;EGYPTIAN HIEROGLYPH T010;Lo;0;L;;;;;N;;;;;
+13315;EGYPTIAN HIEROGLYPH T011;Lo;0;L;;;;;N;;;;;
+13316;EGYPTIAN HIEROGLYPH T011A;Lo;0;L;;;;;N;;;;;
+13317;EGYPTIAN HIEROGLYPH T012;Lo;0;L;;;;;N;;;;;
+13318;EGYPTIAN HIEROGLYPH T013;Lo;0;L;;;;;N;;;;;
+13319;EGYPTIAN HIEROGLYPH T014;Lo;0;L;;;;;N;;;;;
+1331A;EGYPTIAN HIEROGLYPH T015;Lo;0;L;;;;;N;;;;;
+1331B;EGYPTIAN HIEROGLYPH T016;Lo;0;L;;;;;N;;;;;
+1331C;EGYPTIAN HIEROGLYPH T016A;Lo;0;L;;;;;N;;;;;
+1331D;EGYPTIAN HIEROGLYPH T017;Lo;0;L;;;;;N;;;;;
+1331E;EGYPTIAN HIEROGLYPH T018;Lo;0;L;;;;;N;;;;;
+1331F;EGYPTIAN HIEROGLYPH T019;Lo;0;L;;;;;N;;;;;
+13320;EGYPTIAN HIEROGLYPH T020;Lo;0;L;;;;;N;;;;;
+13321;EGYPTIAN HIEROGLYPH T021;Lo;0;L;;;;;N;;;;;
+13322;EGYPTIAN HIEROGLYPH T022;Lo;0;L;;;;;N;;;;;
+13323;EGYPTIAN HIEROGLYPH T023;Lo;0;L;;;;;N;;;;;
+13324;EGYPTIAN HIEROGLYPH T024;Lo;0;L;;;;;N;;;;;
+13325;EGYPTIAN HIEROGLYPH T025;Lo;0;L;;;;;N;;;;;
+13326;EGYPTIAN HIEROGLYPH T026;Lo;0;L;;;;;N;;;;;
+13327;EGYPTIAN HIEROGLYPH T027;Lo;0;L;;;;;N;;;;;
+13328;EGYPTIAN HIEROGLYPH T028;Lo;0;L;;;;;N;;;;;
+13329;EGYPTIAN HIEROGLYPH T029;Lo;0;L;;;;;N;;;;;
+1332A;EGYPTIAN HIEROGLYPH T030;Lo;0;L;;;;;N;;;;;
+1332B;EGYPTIAN HIEROGLYPH T031;Lo;0;L;;;;;N;;;;;
+1332C;EGYPTIAN HIEROGLYPH T032;Lo;0;L;;;;;N;;;;;
+1332D;EGYPTIAN HIEROGLYPH T032A;Lo;0;L;;;;;N;;;;;
+1332E;EGYPTIAN HIEROGLYPH T033;Lo;0;L;;;;;N;;;;;
+1332F;EGYPTIAN HIEROGLYPH T033A;Lo;0;L;;;;;N;;;;;
+13330;EGYPTIAN HIEROGLYPH T034;Lo;0;L;;;;;N;;;;;
+13331;EGYPTIAN HIEROGLYPH T035;Lo;0;L;;;;;N;;;;;
+13332;EGYPTIAN HIEROGLYPH T036;Lo;0;L;;;;;N;;;;;
+13333;EGYPTIAN HIEROGLYPH U001;Lo;0;L;;;;;N;;;;;
+13334;EGYPTIAN HIEROGLYPH U002;Lo;0;L;;;;;N;;;;;
+13335;EGYPTIAN HIEROGLYPH U003;Lo;0;L;;;;;N;;;;;
+13336;EGYPTIAN HIEROGLYPH U004;Lo;0;L;;;;;N;;;;;
+13337;EGYPTIAN HIEROGLYPH U005;Lo;0;L;;;;;N;;;;;
+13338;EGYPTIAN HIEROGLYPH U006;Lo;0;L;;;;;N;;;;;
+13339;EGYPTIAN HIEROGLYPH U006A;Lo;0;L;;;;;N;;;;;
+1333A;EGYPTIAN HIEROGLYPH U006B;Lo;0;L;;;;;N;;;;;
+1333B;EGYPTIAN HIEROGLYPH U007;Lo;0;L;;;;;N;;;;;
+1333C;EGYPTIAN HIEROGLYPH U008;Lo;0;L;;;;;N;;;;;
+1333D;EGYPTIAN HIEROGLYPH U009;Lo;0;L;;;;;N;;;;;
+1333E;EGYPTIAN HIEROGLYPH U010;Lo;0;L;;;;;N;;;;;
+1333F;EGYPTIAN HIEROGLYPH U011;Lo;0;L;;;;;N;;;;;
+13340;EGYPTIAN HIEROGLYPH U012;Lo;0;L;;;;;N;;;;;
+13341;EGYPTIAN HIEROGLYPH U013;Lo;0;L;;;;;N;;;;;
+13342;EGYPTIAN HIEROGLYPH U014;Lo;0;L;;;;;N;;;;;
+13343;EGYPTIAN HIEROGLYPH U015;Lo;0;L;;;;;N;;;;;
+13344;EGYPTIAN HIEROGLYPH U016;Lo;0;L;;;;;N;;;;;
+13345;EGYPTIAN HIEROGLYPH U017;Lo;0;L;;;;;N;;;;;
+13346;EGYPTIAN HIEROGLYPH U018;Lo;0;L;;;;;N;;;;;
+13347;EGYPTIAN HIEROGLYPH U019;Lo;0;L;;;;;N;;;;;
+13348;EGYPTIAN HIEROGLYPH U020;Lo;0;L;;;;;N;;;;;
+13349;EGYPTIAN HIEROGLYPH U021;Lo;0;L;;;;;N;;;;;
+1334A;EGYPTIAN HIEROGLYPH U022;Lo;0;L;;;;;N;;;;;
+1334B;EGYPTIAN HIEROGLYPH U023;Lo;0;L;;;;;N;;;;;
+1334C;EGYPTIAN HIEROGLYPH U023A;Lo;0;L;;;;;N;;;;;
+1334D;EGYPTIAN HIEROGLYPH U024;Lo;0;L;;;;;N;;;;;
+1334E;EGYPTIAN HIEROGLYPH U025;Lo;0;L;;;;;N;;;;;
+1334F;EGYPTIAN HIEROGLYPH U026;Lo;0;L;;;;;N;;;;;
+13350;EGYPTIAN HIEROGLYPH U027;Lo;0;L;;;;;N;;;;;
+13351;EGYPTIAN HIEROGLYPH U028;Lo;0;L;;;;;N;;;;;
+13352;EGYPTIAN HIEROGLYPH U029;Lo;0;L;;;;;N;;;;;
+13353;EGYPTIAN HIEROGLYPH U029A;Lo;0;L;;;;;N;;;;;
+13354;EGYPTIAN HIEROGLYPH U030;Lo;0;L;;;;;N;;;;;
+13355;EGYPTIAN HIEROGLYPH U031;Lo;0;L;;;;;N;;;;;
+13356;EGYPTIAN HIEROGLYPH U032;Lo;0;L;;;;;N;;;;;
+13357;EGYPTIAN HIEROGLYPH U032A;Lo;0;L;;;;;N;;;;;
+13358;EGYPTIAN HIEROGLYPH U033;Lo;0;L;;;;;N;;;;;
+13359;EGYPTIAN HIEROGLYPH U034;Lo;0;L;;;;;N;;;;;
+1335A;EGYPTIAN HIEROGLYPH U035;Lo;0;L;;;;;N;;;;;
+1335B;EGYPTIAN HIEROGLYPH U036;Lo;0;L;;;;;N;;;;;
+1335C;EGYPTIAN HIEROGLYPH U037;Lo;0;L;;;;;N;;;;;
+1335D;EGYPTIAN HIEROGLYPH U038;Lo;0;L;;;;;N;;;;;
+1335E;EGYPTIAN HIEROGLYPH U039;Lo;0;L;;;;;N;;;;;
+1335F;EGYPTIAN HIEROGLYPH U040;Lo;0;L;;;;;N;;;;;
+13360;EGYPTIAN HIEROGLYPH U041;Lo;0;L;;;;;N;;;;;
+13361;EGYPTIAN HIEROGLYPH U042;Lo;0;L;;;;;N;;;;;
+13362;EGYPTIAN HIEROGLYPH V001;Lo;0;L;;;;;N;;;;;
+13363;EGYPTIAN HIEROGLYPH V001A;Lo;0;L;;;;;N;;;;;
+13364;EGYPTIAN HIEROGLYPH V001B;Lo;0;L;;;;;N;;;;;
+13365;EGYPTIAN HIEROGLYPH V001C;Lo;0;L;;;;;N;;;;;
+13366;EGYPTIAN HIEROGLYPH V001D;Lo;0;L;;;;;N;;;;;
+13367;EGYPTIAN HIEROGLYPH V001E;Lo;0;L;;;;;N;;;;;
+13368;EGYPTIAN HIEROGLYPH V001F;Lo;0;L;;;;;N;;;;;
+13369;EGYPTIAN HIEROGLYPH V001G;Lo;0;L;;;;;N;;;;;
+1336A;EGYPTIAN HIEROGLYPH V001H;Lo;0;L;;;;;N;;;;;
+1336B;EGYPTIAN HIEROGLYPH V001I;Lo;0;L;;;;;N;;;;;
+1336C;EGYPTIAN HIEROGLYPH V002;Lo;0;L;;;;;N;;;;;
+1336D;EGYPTIAN HIEROGLYPH V002A;Lo;0;L;;;;;N;;;;;
+1336E;EGYPTIAN HIEROGLYPH V003;Lo;0;L;;;;;N;;;;;
+1336F;EGYPTIAN HIEROGLYPH V004;Lo;0;L;;;;;N;;;;;
+13370;EGYPTIAN HIEROGLYPH V005;Lo;0;L;;;;;N;;;;;
+13371;EGYPTIAN HIEROGLYPH V006;Lo;0;L;;;;;N;;;;;
+13372;EGYPTIAN HIEROGLYPH V007;Lo;0;L;;;;;N;;;;;
+13373;EGYPTIAN HIEROGLYPH V007A;Lo;0;L;;;;;N;;;;;
+13374;EGYPTIAN HIEROGLYPH V007B;Lo;0;L;;;;;N;;;;;
+13375;EGYPTIAN HIEROGLYPH V008;Lo;0;L;;;;;N;;;;;
+13376;EGYPTIAN HIEROGLYPH V009;Lo;0;L;;;;;N;;;;;
+13377;EGYPTIAN HIEROGLYPH V010;Lo;0;L;;;;;N;;;;;
+13378;EGYPTIAN HIEROGLYPH V011;Lo;0;L;;;;;N;;;;;
+13379;EGYPTIAN HIEROGLYPH V011A;Lo;0;L;;;;;N;;;;;
+1337A;EGYPTIAN HIEROGLYPH V011B;Lo;0;L;;;;;N;;;;;
+1337B;EGYPTIAN HIEROGLYPH V011C;Lo;0;L;;;;;N;;;;;
+1337C;EGYPTIAN HIEROGLYPH V012;Lo;0;L;;;;;N;;;;;
+1337D;EGYPTIAN HIEROGLYPH V012A;Lo;0;L;;;;;N;;;;;
+1337E;EGYPTIAN HIEROGLYPH V012B;Lo;0;L;;;;;N;;;;;
+1337F;EGYPTIAN HIEROGLYPH V013;Lo;0;L;;;;;N;;;;;
+13380;EGYPTIAN HIEROGLYPH V014;Lo;0;L;;;;;N;;;;;
+13381;EGYPTIAN HIEROGLYPH V015;Lo;0;L;;;;;N;;;;;
+13382;EGYPTIAN HIEROGLYPH V016;Lo;0;L;;;;;N;;;;;
+13383;EGYPTIAN HIEROGLYPH V017;Lo;0;L;;;;;N;;;;;
+13384;EGYPTIAN HIEROGLYPH V018;Lo;0;L;;;;;N;;;;;
+13385;EGYPTIAN HIEROGLYPH V019;Lo;0;L;;;;;N;;;;;
+13386;EGYPTIAN HIEROGLYPH V020;Lo;0;L;;;;;N;;;;;
+13387;EGYPTIAN HIEROGLYPH V020A;Lo;0;L;;;;;N;;;;;
+13388;EGYPTIAN HIEROGLYPH V020B;Lo;0;L;;;;;N;;;;;
+13389;EGYPTIAN HIEROGLYPH V020C;Lo;0;L;;;;;N;;;;;
+1338A;EGYPTIAN HIEROGLYPH V020D;Lo;0;L;;;;;N;;;;;
+1338B;EGYPTIAN HIEROGLYPH V020E;Lo;0;L;;;;;N;;;;;
+1338C;EGYPTIAN HIEROGLYPH V020F;Lo;0;L;;;;;N;;;;;
+1338D;EGYPTIAN HIEROGLYPH V020G;Lo;0;L;;;;;N;;;;;
+1338E;EGYPTIAN HIEROGLYPH V020H;Lo;0;L;;;;;N;;;;;
+1338F;EGYPTIAN HIEROGLYPH V020I;Lo;0;L;;;;;N;;;;;
+13390;EGYPTIAN HIEROGLYPH V020J;Lo;0;L;;;;;N;;;;;
+13391;EGYPTIAN HIEROGLYPH V020K;Lo;0;L;;;;;N;;;;;
+13392;EGYPTIAN HIEROGLYPH V020L;Lo;0;L;;;;;N;;;;;
+13393;EGYPTIAN HIEROGLYPH V021;Lo;0;L;;;;;N;;;;;
+13394;EGYPTIAN HIEROGLYPH V022;Lo;0;L;;;;;N;;;;;
+13395;EGYPTIAN HIEROGLYPH V023;Lo;0;L;;;;;N;;;;;
+13396;EGYPTIAN HIEROGLYPH V023A;Lo;0;L;;;;;N;;;;;
+13397;EGYPTIAN HIEROGLYPH V024;Lo;0;L;;;;;N;;;;;
+13398;EGYPTIAN HIEROGLYPH V025;Lo;0;L;;;;;N;;;;;
+13399;EGYPTIAN HIEROGLYPH V026;Lo;0;L;;;;;N;;;;;
+1339A;EGYPTIAN HIEROGLYPH V027;Lo;0;L;;;;;N;;;;;
+1339B;EGYPTIAN HIEROGLYPH V028;Lo;0;L;;;;;N;;;;;
+1339C;EGYPTIAN HIEROGLYPH V028A;Lo;0;L;;;;;N;;;;;
+1339D;EGYPTIAN HIEROGLYPH V029;Lo;0;L;;;;;N;;;;;
+1339E;EGYPTIAN HIEROGLYPH V029A;Lo;0;L;;;;;N;;;;;
+1339F;EGYPTIAN HIEROGLYPH V030;Lo;0;L;;;;;N;;;;;
+133A0;EGYPTIAN HIEROGLYPH V030A;Lo;0;L;;;;;N;;;;;
+133A1;EGYPTIAN HIEROGLYPH V031;Lo;0;L;;;;;N;;;;;
+133A2;EGYPTIAN HIEROGLYPH V031A;Lo;0;L;;;;;N;;;;;
+133A3;EGYPTIAN HIEROGLYPH V032;Lo;0;L;;;;;N;;;;;
+133A4;EGYPTIAN HIEROGLYPH V033;Lo;0;L;;;;;N;;;;;
+133A5;EGYPTIAN HIEROGLYPH V033A;Lo;0;L;;;;;N;;;;;
+133A6;EGYPTIAN HIEROGLYPH V034;Lo;0;L;;;;;N;;;;;
+133A7;EGYPTIAN HIEROGLYPH V035;Lo;0;L;;;;;N;;;;;
+133A8;EGYPTIAN HIEROGLYPH V036;Lo;0;L;;;;;N;;;;;
+133A9;EGYPTIAN HIEROGLYPH V037;Lo;0;L;;;;;N;;;;;
+133AA;EGYPTIAN HIEROGLYPH V037A;Lo;0;L;;;;;N;;;;;
+133AB;EGYPTIAN HIEROGLYPH V038;Lo;0;L;;;;;N;;;;;
+133AC;EGYPTIAN HIEROGLYPH V039;Lo;0;L;;;;;N;;;;;
+133AD;EGYPTIAN HIEROGLYPH V040;Lo;0;L;;;;;N;;;;;
+133AE;EGYPTIAN HIEROGLYPH V040A;Lo;0;L;;;;;N;;;;;
+133AF;EGYPTIAN HIEROGLYPH W001;Lo;0;L;;;;;N;;;;;
+133B0;EGYPTIAN HIEROGLYPH W002;Lo;0;L;;;;;N;;;;;
+133B1;EGYPTIAN HIEROGLYPH W003;Lo;0;L;;;;;N;;;;;
+133B2;EGYPTIAN HIEROGLYPH W003A;Lo;0;L;;;;;N;;;;;
+133B3;EGYPTIAN HIEROGLYPH W004;Lo;0;L;;;;;N;;;;;
+133B4;EGYPTIAN HIEROGLYPH W005;Lo;0;L;;;;;N;;;;;
+133B5;EGYPTIAN HIEROGLYPH W006;Lo;0;L;;;;;N;;;;;
+133B6;EGYPTIAN HIEROGLYPH W007;Lo;0;L;;;;;N;;;;;
+133B7;EGYPTIAN HIEROGLYPH W008;Lo;0;L;;;;;N;;;;;
+133B8;EGYPTIAN HIEROGLYPH W009;Lo;0;L;;;;;N;;;;;
+133B9;EGYPTIAN HIEROGLYPH W009A;Lo;0;L;;;;;N;;;;;
+133BA;EGYPTIAN HIEROGLYPH W010;Lo;0;L;;;;;N;;;;;
+133BB;EGYPTIAN HIEROGLYPH W010A;Lo;0;L;;;;;N;;;;;
+133BC;EGYPTIAN HIEROGLYPH W011;Lo;0;L;;;;;N;;;;;
+133BD;EGYPTIAN HIEROGLYPH W012;Lo;0;L;;;;;N;;;;;
+133BE;EGYPTIAN HIEROGLYPH W013;Lo;0;L;;;;;N;;;;;
+133BF;EGYPTIAN HIEROGLYPH W014;Lo;0;L;;;;;N;;;;;
+133C0;EGYPTIAN HIEROGLYPH W014A;Lo;0;L;;;;;N;;;;;
+133C1;EGYPTIAN HIEROGLYPH W015;Lo;0;L;;;;;N;;;;;
+133C2;EGYPTIAN HIEROGLYPH W016;Lo;0;L;;;;;N;;;;;
+133C3;EGYPTIAN HIEROGLYPH W017;Lo;0;L;;;;;N;;;;;
+133C4;EGYPTIAN HIEROGLYPH W017A;Lo;0;L;;;;;N;;;;;
+133C5;EGYPTIAN HIEROGLYPH W018;Lo;0;L;;;;;N;;;;;
+133C6;EGYPTIAN HIEROGLYPH W018A;Lo;0;L;;;;;N;;;;;
+133C7;EGYPTIAN HIEROGLYPH W019;Lo;0;L;;;;;N;;;;;
+133C8;EGYPTIAN HIEROGLYPH W020;Lo;0;L;;;;;N;;;;;
+133C9;EGYPTIAN HIEROGLYPH W021;Lo;0;L;;;;;N;;;;;
+133CA;EGYPTIAN HIEROGLYPH W022;Lo;0;L;;;;;N;;;;;
+133CB;EGYPTIAN HIEROGLYPH W023;Lo;0;L;;;;;N;;;;;
+133CC;EGYPTIAN HIEROGLYPH W024;Lo;0;L;;;;;N;;;;;
+133CD;EGYPTIAN HIEROGLYPH W024A;Lo;0;L;;;;;N;;;;;
+133CE;EGYPTIAN HIEROGLYPH W025;Lo;0;L;;;;;N;;;;;
+133CF;EGYPTIAN HIEROGLYPH X001;Lo;0;L;;;;;N;;;;;
+133D0;EGYPTIAN HIEROGLYPH X002;Lo;0;L;;;;;N;;;;;
+133D1;EGYPTIAN HIEROGLYPH X003;Lo;0;L;;;;;N;;;;;
+133D2;EGYPTIAN HIEROGLYPH X004;Lo;0;L;;;;;N;;;;;
+133D3;EGYPTIAN HIEROGLYPH X004A;Lo;0;L;;;;;N;;;;;
+133D4;EGYPTIAN HIEROGLYPH X004B;Lo;0;L;;;;;N;;;;;
+133D5;EGYPTIAN HIEROGLYPH X005;Lo;0;L;;;;;N;;;;;
+133D6;EGYPTIAN HIEROGLYPH X006;Lo;0;L;;;;;N;;;;;
+133D7;EGYPTIAN HIEROGLYPH X006A;Lo;0;L;;;;;N;;;;;
+133D8;EGYPTIAN HIEROGLYPH X007;Lo;0;L;;;;;N;;;;;
+133D9;EGYPTIAN HIEROGLYPH X008;Lo;0;L;;;;;N;;;;;
+133DA;EGYPTIAN HIEROGLYPH X008A;Lo;0;L;;;;;N;;;;;
+133DB;EGYPTIAN HIEROGLYPH Y001;Lo;0;L;;;;;N;;;;;
+133DC;EGYPTIAN HIEROGLYPH Y001A;Lo;0;L;;;;;N;;;;;
+133DD;EGYPTIAN HIEROGLYPH Y002;Lo;0;L;;;;;N;;;;;
+133DE;EGYPTIAN HIEROGLYPH Y003;Lo;0;L;;;;;N;;;;;
+133DF;EGYPTIAN HIEROGLYPH Y004;Lo;0;L;;;;;N;;;;;
+133E0;EGYPTIAN HIEROGLYPH Y005;Lo;0;L;;;;;N;;;;;
+133E1;EGYPTIAN HIEROGLYPH Y006;Lo;0;L;;;;;N;;;;;
+133E2;EGYPTIAN HIEROGLYPH Y007;Lo;0;L;;;;;N;;;;;
+133E3;EGYPTIAN HIEROGLYPH Y008;Lo;0;L;;;;;N;;;;;
+133E4;EGYPTIAN HIEROGLYPH Z001;Lo;0;L;;;;;N;;;;;
+133E5;EGYPTIAN HIEROGLYPH Z002;Lo;0;L;;;;;N;;;;;
+133E6;EGYPTIAN HIEROGLYPH Z002A;Lo;0;L;;;;;N;;;;;
+133E7;EGYPTIAN HIEROGLYPH Z002B;Lo;0;L;;;;;N;;;;;
+133E8;EGYPTIAN HIEROGLYPH Z002C;Lo;0;L;;;;;N;;;;;
+133E9;EGYPTIAN HIEROGLYPH Z002D;Lo;0;L;;;;;N;;;;;
+133EA;EGYPTIAN HIEROGLYPH Z003;Lo;0;L;;;;;N;;;;;
+133EB;EGYPTIAN HIEROGLYPH Z003A;Lo;0;L;;;;;N;;;;;
+133EC;EGYPTIAN HIEROGLYPH Z003B;Lo;0;L;;;;;N;;;;;
+133ED;EGYPTIAN HIEROGLYPH Z004;Lo;0;L;;;;;N;;;;;
+133EE;EGYPTIAN HIEROGLYPH Z004A;Lo;0;L;;;;;N;;;;;
+133EF;EGYPTIAN HIEROGLYPH Z005;Lo;0;L;;;;;N;;;;;
+133F0;EGYPTIAN HIEROGLYPH Z005A;Lo;0;L;;;;;N;;;;;
+133F1;EGYPTIAN HIEROGLYPH Z006;Lo;0;L;;;;;N;;;;;
+133F2;EGYPTIAN HIEROGLYPH Z007;Lo;0;L;;;;;N;;;;;
+133F3;EGYPTIAN HIEROGLYPH Z008;Lo;0;L;;;;;N;;;;;
+133F4;EGYPTIAN HIEROGLYPH Z009;Lo;0;L;;;;;N;;;;;
+133F5;EGYPTIAN HIEROGLYPH Z010;Lo;0;L;;;;;N;;;;;
+133F6;EGYPTIAN HIEROGLYPH Z011;Lo;0;L;;;;;N;;;;;
+133F7;EGYPTIAN HIEROGLYPH Z012;Lo;0;L;;;;;N;;;;;
+133F8;EGYPTIAN HIEROGLYPH Z013;Lo;0;L;;;;;N;;;;;
+133F9;EGYPTIAN HIEROGLYPH Z014;Lo;0;L;;;;;N;;;;;
+133FA;EGYPTIAN HIEROGLYPH Z015;Lo;0;L;;;;;N;;;;;
+133FB;EGYPTIAN HIEROGLYPH Z015A;Lo;0;L;;;;;N;;;;;
+133FC;EGYPTIAN HIEROGLYPH Z015B;Lo;0;L;;;;;N;;;;;
+133FD;EGYPTIAN HIEROGLYPH Z015C;Lo;0;L;;;;;N;;;;;
+133FE;EGYPTIAN HIEROGLYPH Z015D;Lo;0;L;;;;;N;;;;;
+133FF;EGYPTIAN HIEROGLYPH Z015E;Lo;0;L;;;;;N;;;;;
+13400;EGYPTIAN HIEROGLYPH Z015F;Lo;0;L;;;;;N;;;;;
+13401;EGYPTIAN HIEROGLYPH Z015G;Lo;0;L;;;;;N;;;;;
+13402;EGYPTIAN HIEROGLYPH Z015H;Lo;0;L;;;;;N;;;;;
+13403;EGYPTIAN HIEROGLYPH Z015I;Lo;0;L;;;;;N;;;;;
+13404;EGYPTIAN HIEROGLYPH Z016;Lo;0;L;;;;;N;;;;;
+13405;EGYPTIAN HIEROGLYPH Z016A;Lo;0;L;;;;;N;;;;;
+13406;EGYPTIAN HIEROGLYPH Z016B;Lo;0;L;;;;;N;;;;;
+13407;EGYPTIAN HIEROGLYPH Z016C;Lo;0;L;;;;;N;;;;;
+13408;EGYPTIAN HIEROGLYPH Z016D;Lo;0;L;;;;;N;;;;;
+13409;EGYPTIAN HIEROGLYPH Z016E;Lo;0;L;;;;;N;;;;;
+1340A;EGYPTIAN HIEROGLYPH Z016F;Lo;0;L;;;;;N;;;;;
+1340B;EGYPTIAN HIEROGLYPH Z016G;Lo;0;L;;;;;N;;;;;
+1340C;EGYPTIAN HIEROGLYPH Z016H;Lo;0;L;;;;;N;;;;;
+1340D;EGYPTIAN HIEROGLYPH AA001;Lo;0;L;;;;;N;;;;;
+1340E;EGYPTIAN HIEROGLYPH AA002;Lo;0;L;;;;;N;;;;;
+1340F;EGYPTIAN HIEROGLYPH AA003;Lo;0;L;;;;;N;;;;;
+13410;EGYPTIAN HIEROGLYPH AA004;Lo;0;L;;;;;N;;;;;
+13411;EGYPTIAN HIEROGLYPH AA005;Lo;0;L;;;;;N;;;;;
+13412;EGYPTIAN HIEROGLYPH AA006;Lo;0;L;;;;;N;;;;;
+13413;EGYPTIAN HIEROGLYPH AA007;Lo;0;L;;;;;N;;;;;
+13414;EGYPTIAN HIEROGLYPH AA007A;Lo;0;L;;;;;N;;;;;
+13415;EGYPTIAN HIEROGLYPH AA007B;Lo;0;L;;;;;N;;;;;
+13416;EGYPTIAN HIEROGLYPH AA008;Lo;0;L;;;;;N;;;;;
+13417;EGYPTIAN HIEROGLYPH AA009;Lo;0;L;;;;;N;;;;;
+13418;EGYPTIAN HIEROGLYPH AA010;Lo;0;L;;;;;N;;;;;
+13419;EGYPTIAN HIEROGLYPH AA011;Lo;0;L;;;;;N;;;;;
+1341A;EGYPTIAN HIEROGLYPH AA012;Lo;0;L;;;;;N;;;;;
+1341B;EGYPTIAN HIEROGLYPH AA013;Lo;0;L;;;;;N;;;;;
+1341C;EGYPTIAN HIEROGLYPH AA014;Lo;0;L;;;;;N;;;;;
+1341D;EGYPTIAN HIEROGLYPH AA015;Lo;0;L;;;;;N;;;;;
+1341E;EGYPTIAN HIEROGLYPH AA016;Lo;0;L;;;;;N;;;;;
+1341F;EGYPTIAN HIEROGLYPH AA017;Lo;0;L;;;;;N;;;;;
+13420;EGYPTIAN HIEROGLYPH AA018;Lo;0;L;;;;;N;;;;;
+13421;EGYPTIAN HIEROGLYPH AA019;Lo;0;L;;;;;N;;;;;
+13422;EGYPTIAN HIEROGLYPH AA020;Lo;0;L;;;;;N;;;;;
+13423;EGYPTIAN HIEROGLYPH AA021;Lo;0;L;;;;;N;;;;;
+13424;EGYPTIAN HIEROGLYPH AA022;Lo;0;L;;;;;N;;;;;
+13425;EGYPTIAN HIEROGLYPH AA023;Lo;0;L;;;;;N;;;;;
+13426;EGYPTIAN HIEROGLYPH AA024;Lo;0;L;;;;;N;;;;;
+13427;EGYPTIAN HIEROGLYPH AA025;Lo;0;L;;;;;N;;;;;
+13428;EGYPTIAN HIEROGLYPH AA026;Lo;0;L;;;;;N;;;;;
+13429;EGYPTIAN HIEROGLYPH AA027;Lo;0;L;;;;;N;;;;;
+1342A;EGYPTIAN HIEROGLYPH AA028;Lo;0;L;;;;;N;;;;;
+1342B;EGYPTIAN HIEROGLYPH AA029;Lo;0;L;;;;;N;;;;;
+1342C;EGYPTIAN HIEROGLYPH AA030;Lo;0;L;;;;;N;;;;;
+1342D;EGYPTIAN HIEROGLYPH AA031;Lo;0;L;;;;;N;;;;;
+1342E;EGYPTIAN HIEROGLYPH AA032;Lo;0;L;;;;;N;;;;;
+16800;BAMUM LETTER PHASE-A NGKUE MFON;Lo;0;L;;;;;N;;;;;
+16801;BAMUM LETTER PHASE-A GBIEE FON;Lo;0;L;;;;;N;;;;;
+16802;BAMUM LETTER PHASE-A PON MFON PIPAEMGBIEE;Lo;0;L;;;;;N;;;;;
+16803;BAMUM LETTER PHASE-A PON MFON PIPAEMBA;Lo;0;L;;;;;N;;;;;
+16804;BAMUM LETTER PHASE-A NAA MFON;Lo;0;L;;;;;N;;;;;
+16805;BAMUM LETTER PHASE-A SHUENSHUET;Lo;0;L;;;;;N;;;;;
+16806;BAMUM LETTER PHASE-A TITA MFON;Lo;0;L;;;;;N;;;;;
+16807;BAMUM LETTER PHASE-A NZA MFON;Lo;0;L;;;;;N;;;;;
+16808;BAMUM LETTER PHASE-A SHINDA PA NJI;Lo;0;L;;;;;N;;;;;
+16809;BAMUM LETTER PHASE-A PON PA NJI PIPAEMGBIEE;Lo;0;L;;;;;N;;;;;
+1680A;BAMUM LETTER PHASE-A PON PA NJI PIPAEMBA;Lo;0;L;;;;;N;;;;;
+1680B;BAMUM LETTER PHASE-A MAEMBGBIEE;Lo;0;L;;;;;N;;;;;
+1680C;BAMUM LETTER PHASE-A TU MAEMBA;Lo;0;L;;;;;N;;;;;
+1680D;BAMUM LETTER PHASE-A NGANGU;Lo;0;L;;;;;N;;;;;
+1680E;BAMUM LETTER PHASE-A MAEMVEUX;Lo;0;L;;;;;N;;;;;
+1680F;BAMUM LETTER PHASE-A MANSUAE;Lo;0;L;;;;;N;;;;;
+16810;BAMUM LETTER PHASE-A MVEUAENGAM;Lo;0;L;;;;;N;;;;;
+16811;BAMUM LETTER PHASE-A SEUNYAM;Lo;0;L;;;;;N;;;;;
+16812;BAMUM LETTER PHASE-A NTOQPEN;Lo;0;L;;;;;N;;;;;
+16813;BAMUM LETTER PHASE-A KEUKEUTNDA;Lo;0;L;;;;;N;;;;;
+16814;BAMUM LETTER PHASE-A NKINDI;Lo;0;L;;;;;N;;;;;
+16815;BAMUM LETTER PHASE-A SUU;Lo;0;L;;;;;N;;;;;
+16816;BAMUM LETTER PHASE-A NGKUENZEUM;Lo;0;L;;;;;N;;;;;
+16817;BAMUM LETTER PHASE-A LAPAQ;Lo;0;L;;;;;N;;;;;
+16818;BAMUM LETTER PHASE-A LET KUT;Lo;0;L;;;;;N;;;;;
+16819;BAMUM LETTER PHASE-A NTAP MFAA;Lo;0;L;;;;;N;;;;;
+1681A;BAMUM LETTER PHASE-A MAEKEUP;Lo;0;L;;;;;N;;;;;
+1681B;BAMUM LETTER PHASE-A PASHAE;Lo;0;L;;;;;N;;;;;
+1681C;BAMUM LETTER PHASE-A GHEUAERAE;Lo;0;L;;;;;N;;;;;
+1681D;BAMUM LETTER PHASE-A PAMSHAE;Lo;0;L;;;;;N;;;;;
+1681E;BAMUM LETTER PHASE-A MON NGGEUAET;Lo;0;L;;;;;N;;;;;
+1681F;BAMUM LETTER PHASE-A NZUN MEUT;Lo;0;L;;;;;N;;;;;
+16820;BAMUM LETTER PHASE-A U YUQ NAE;Lo;0;L;;;;;N;;;;;
+16821;BAMUM LETTER PHASE-A GHEUAEGHEUAE;Lo;0;L;;;;;N;;;;;
+16822;BAMUM LETTER PHASE-A NTAP NTAA;Lo;0;L;;;;;N;;;;;
+16823;BAMUM LETTER PHASE-A SISA;Lo;0;L;;;;;N;;;;;
+16824;BAMUM LETTER PHASE-A MGBASA;Lo;0;L;;;;;N;;;;;
+16825;BAMUM LETTER PHASE-A MEUNJOMNDEUQ;Lo;0;L;;;;;N;;;;;
+16826;BAMUM LETTER PHASE-A MOOMPUQ;Lo;0;L;;;;;N;;;;;
+16827;BAMUM LETTER PHASE-A KAFA;Lo;0;L;;;;;N;;;;;
+16828;BAMUM LETTER PHASE-A PA LEERAEWA;Lo;0;L;;;;;N;;;;;
+16829;BAMUM LETTER PHASE-A NDA LEERAEWA;Lo;0;L;;;;;N;;;;;
+1682A;BAMUM LETTER PHASE-A PET;Lo;0;L;;;;;N;;;;;
+1682B;BAMUM LETTER PHASE-A MAEMKPEN;Lo;0;L;;;;;N;;;;;
+1682C;BAMUM LETTER PHASE-A NIKA;Lo;0;L;;;;;N;;;;;
+1682D;BAMUM LETTER PHASE-A PUP;Lo;0;L;;;;;N;;;;;
+1682E;BAMUM LETTER PHASE-A TUAEP;Lo;0;L;;;;;N;;;;;
+1682F;BAMUM LETTER PHASE-A LUAEP;Lo;0;L;;;;;N;;;;;
+16830;BAMUM LETTER PHASE-A SONJAM;Lo;0;L;;;;;N;;;;;
+16831;BAMUM LETTER PHASE-A TEUTEUWEN;Lo;0;L;;;;;N;;;;;
+16832;BAMUM LETTER PHASE-A MAENYI;Lo;0;L;;;;;N;;;;;
+16833;BAMUM LETTER PHASE-A KET;Lo;0;L;;;;;N;;;;;
+16834;BAMUM LETTER PHASE-A NDAANGGEUAET;Lo;0;L;;;;;N;;;;;
+16835;BAMUM LETTER PHASE-A KUOQ;Lo;0;L;;;;;N;;;;;
+16836;BAMUM LETTER PHASE-A MOOMEUT;Lo;0;L;;;;;N;;;;;
+16837;BAMUM LETTER PHASE-A SHUM;Lo;0;L;;;;;N;;;;;
+16838;BAMUM LETTER PHASE-A LOMMAE;Lo;0;L;;;;;N;;;;;
+16839;BAMUM LETTER PHASE-A FIRI;Lo;0;L;;;;;N;;;;;
+1683A;BAMUM LETTER PHASE-A ROM;Lo;0;L;;;;;N;;;;;
+1683B;BAMUM LETTER PHASE-A KPOQ;Lo;0;L;;;;;N;;;;;
+1683C;BAMUM LETTER PHASE-A SOQ;Lo;0;L;;;;;N;;;;;
+1683D;BAMUM LETTER PHASE-A MAP PIEET;Lo;0;L;;;;;N;;;;;
+1683E;BAMUM LETTER PHASE-A SHIRAE;Lo;0;L;;;;;N;;;;;
+1683F;BAMUM LETTER PHASE-A NTAP;Lo;0;L;;;;;N;;;;;
+16840;BAMUM LETTER PHASE-A SHOQ NSHUT YUM;Lo;0;L;;;;;N;;;;;
+16841;BAMUM LETTER PHASE-A NYIT MONGKEUAEQ;Lo;0;L;;;;;N;;;;;
+16842;BAMUM LETTER PHASE-A PAARAE;Lo;0;L;;;;;N;;;;;
+16843;BAMUM LETTER PHASE-A NKAARAE;Lo;0;L;;;;;N;;;;;
+16844;BAMUM LETTER PHASE-A UNKNOWN;Lo;0;L;;;;;N;;;;;
+16845;BAMUM LETTER PHASE-A NGGEN;Lo;0;L;;;;;N;;;;;
+16846;BAMUM LETTER PHASE-A MAESI;Lo;0;L;;;;;N;;;;;
+16847;BAMUM LETTER PHASE-A NJAM;Lo;0;L;;;;;N;;;;;
+16848;BAMUM LETTER PHASE-A MBANYI;Lo;0;L;;;;;N;;;;;
+16849;BAMUM LETTER PHASE-A NYET;Lo;0;L;;;;;N;;;;;
+1684A;BAMUM LETTER PHASE-A TEUAEN;Lo;0;L;;;;;N;;;;;
+1684B;BAMUM LETTER PHASE-A SOT;Lo;0;L;;;;;N;;;;;
+1684C;BAMUM LETTER PHASE-A PAAM;Lo;0;L;;;;;N;;;;;
+1684D;BAMUM LETTER PHASE-A NSHIEE;Lo;0;L;;;;;N;;;;;
+1684E;BAMUM LETTER PHASE-A MAEM;Lo;0;L;;;;;N;;;;;
+1684F;BAMUM LETTER PHASE-A NYI;Lo;0;L;;;;;N;;;;;
+16850;BAMUM LETTER PHASE-A KAQ;Lo;0;L;;;;;N;;;;;
+16851;BAMUM LETTER PHASE-A NSHA;Lo;0;L;;;;;N;;;;;
+16852;BAMUM LETTER PHASE-A VEE;Lo;0;L;;;;;N;;;;;
+16853;BAMUM LETTER PHASE-A LU;Lo;0;L;;;;;N;;;;;
+16854;BAMUM LETTER PHASE-A NEN;Lo;0;L;;;;;N;;;;;
+16855;BAMUM LETTER PHASE-A NAQ;Lo;0;L;;;;;N;;;;;
+16856;BAMUM LETTER PHASE-A MBAQ;Lo;0;L;;;;;N;;;;;
+16857;BAMUM LETTER PHASE-B NSHUET;Lo;0;L;;;;;N;;;;;
+16858;BAMUM LETTER PHASE-B TU MAEMGBIEE;Lo;0;L;;;;;N;;;;;
+16859;BAMUM LETTER PHASE-B SIEE;Lo;0;L;;;;;N;;;;;
+1685A;BAMUM LETTER PHASE-B SET TU;Lo;0;L;;;;;N;;;;;
+1685B;BAMUM LETTER PHASE-B LOM NTEUM;Lo;0;L;;;;;N;;;;;
+1685C;BAMUM LETTER PHASE-B MBA MAELEE;Lo;0;L;;;;;N;;;;;
+1685D;BAMUM LETTER PHASE-B KIEEM;Lo;0;L;;;;;N;;;;;
+1685E;BAMUM LETTER PHASE-B YEURAE;Lo;0;L;;;;;N;;;;;
+1685F;BAMUM LETTER PHASE-B MBAARAE;Lo;0;L;;;;;N;;;;;
+16860;BAMUM LETTER PHASE-B KAM;Lo;0;L;;;;;N;;;;;
+16861;BAMUM LETTER PHASE-B PEESHI;Lo;0;L;;;;;N;;;;;
+16862;BAMUM LETTER PHASE-B YAFU LEERAEWA;Lo;0;L;;;;;N;;;;;
+16863;BAMUM LETTER PHASE-B LAM NSHUT NYAM;Lo;0;L;;;;;N;;;;;
+16864;BAMUM LETTER PHASE-B NTIEE SHEUOQ;Lo;0;L;;;;;N;;;;;
+16865;BAMUM LETTER PHASE-B NDU NJAA;Lo;0;L;;;;;N;;;;;
+16866;BAMUM LETTER PHASE-B GHEUGHEUAEM;Lo;0;L;;;;;N;;;;;
+16867;BAMUM LETTER PHASE-B PIT;Lo;0;L;;;;;N;;;;;
+16868;BAMUM LETTER PHASE-B TU NSIEE;Lo;0;L;;;;;N;;;;;
+16869;BAMUM LETTER PHASE-B SHET NJAQ;Lo;0;L;;;;;N;;;;;
+1686A;BAMUM LETTER PHASE-B SHEUAEQTU;Lo;0;L;;;;;N;;;;;
+1686B;BAMUM LETTER PHASE-B MFON TEUAEQ;Lo;0;L;;;;;N;;;;;
+1686C;BAMUM LETTER PHASE-B MBIT MBAAKET;Lo;0;L;;;;;N;;;;;
+1686D;BAMUM LETTER PHASE-B NYI NTEUM;Lo;0;L;;;;;N;;;;;
+1686E;BAMUM LETTER PHASE-B KEUPUQ;Lo;0;L;;;;;N;;;;;
+1686F;BAMUM LETTER PHASE-B GHEUGHEN;Lo;0;L;;;;;N;;;;;
+16870;BAMUM LETTER PHASE-B KEUYEUX;Lo;0;L;;;;;N;;;;;
+16871;BAMUM LETTER PHASE-B LAANAE;Lo;0;L;;;;;N;;;;;
+16872;BAMUM LETTER PHASE-B PARUM;Lo;0;L;;;;;N;;;;;
+16873;BAMUM LETTER PHASE-B VEUM;Lo;0;L;;;;;N;;;;;
+16874;BAMUM LETTER PHASE-B NGKINDI MVOP;Lo;0;L;;;;;N;;;;;
+16875;BAMUM LETTER PHASE-B NGGEU MBU;Lo;0;L;;;;;N;;;;;
+16876;BAMUM LETTER PHASE-B WUAET;Lo;0;L;;;;;N;;;;;
+16877;BAMUM LETTER PHASE-B SAKEUAE;Lo;0;L;;;;;N;;;;;
+16878;BAMUM LETTER PHASE-B TAAM;Lo;0;L;;;;;N;;;;;
+16879;BAMUM LETTER PHASE-B MEUQ;Lo;0;L;;;;;N;;;;;
+1687A;BAMUM LETTER PHASE-B NGGUOQ;Lo;0;L;;;;;N;;;;;
+1687B;BAMUM LETTER PHASE-B NGGUOQ LARGE;Lo;0;L;;;;;N;;;;;
+1687C;BAMUM LETTER PHASE-B MFIYAQ;Lo;0;L;;;;;N;;;;;
+1687D;BAMUM LETTER PHASE-B SUE;Lo;0;L;;;;;N;;;;;
+1687E;BAMUM LETTER PHASE-B MBEURI;Lo;0;L;;;;;N;;;;;
+1687F;BAMUM LETTER PHASE-B MONTIEEN;Lo;0;L;;;;;N;;;;;
+16880;BAMUM LETTER PHASE-B NYAEMAE;Lo;0;L;;;;;N;;;;;
+16881;BAMUM LETTER PHASE-B PUNGAAM;Lo;0;L;;;;;N;;;;;
+16882;BAMUM LETTER PHASE-B MEUT NGGEET;Lo;0;L;;;;;N;;;;;
+16883;BAMUM LETTER PHASE-B FEUX;Lo;0;L;;;;;N;;;;;
+16884;BAMUM LETTER PHASE-B MBUOQ;Lo;0;L;;;;;N;;;;;
+16885;BAMUM LETTER PHASE-B FEE;Lo;0;L;;;;;N;;;;;
+16886;BAMUM LETTER PHASE-B KEUAEM;Lo;0;L;;;;;N;;;;;
+16887;BAMUM LETTER PHASE-B MA NJEUAENA;Lo;0;L;;;;;N;;;;;
+16888;BAMUM LETTER PHASE-B MA NJUQA;Lo;0;L;;;;;N;;;;;
+16889;BAMUM LETTER PHASE-B LET;Lo;0;L;;;;;N;;;;;
+1688A;BAMUM LETTER PHASE-B NGGAAM;Lo;0;L;;;;;N;;;;;
+1688B;BAMUM LETTER PHASE-B NSEN;Lo;0;L;;;;;N;;;;;
+1688C;BAMUM LETTER PHASE-B MA;Lo;0;L;;;;;N;;;;;
+1688D;BAMUM LETTER PHASE-B KIQ;Lo;0;L;;;;;N;;;;;
+1688E;BAMUM LETTER PHASE-B NGOM;Lo;0;L;;;;;N;;;;;
+1688F;BAMUM LETTER PHASE-C NGKUE MAEMBA;Lo;0;L;;;;;N;;;;;
+16890;BAMUM LETTER PHASE-C NZA;Lo;0;L;;;;;N;;;;;
+16891;BAMUM LETTER PHASE-C YUM;Lo;0;L;;;;;N;;;;;
+16892;BAMUM LETTER PHASE-C WANGKUOQ;Lo;0;L;;;;;N;;;;;
+16893;BAMUM LETTER PHASE-C NGGEN;Lo;0;L;;;;;N;;;;;
+16894;BAMUM LETTER PHASE-C NDEUAEREE;Lo;0;L;;;;;N;;;;;
+16895;BAMUM LETTER PHASE-C NGKAQ;Lo;0;L;;;;;N;;;;;
+16896;BAMUM LETTER PHASE-C GHARAE;Lo;0;L;;;;;N;;;;;
+16897;BAMUM LETTER PHASE-C MBEEKEET;Lo;0;L;;;;;N;;;;;
+16898;BAMUM LETTER PHASE-C GBAYI;Lo;0;L;;;;;N;;;;;
+16899;BAMUM LETTER PHASE-C NYIR MKPARAQ MEUN;Lo;0;L;;;;;N;;;;;
+1689A;BAMUM LETTER PHASE-C NTU MBIT;Lo;0;L;;;;;N;;;;;
+1689B;BAMUM LETTER PHASE-C MBEUM;Lo;0;L;;;;;N;;;;;
+1689C;BAMUM LETTER PHASE-C PIRIEEN;Lo;0;L;;;;;N;;;;;
+1689D;BAMUM LETTER PHASE-C NDOMBU;Lo;0;L;;;;;N;;;;;
+1689E;BAMUM LETTER PHASE-C MBAA CABBAGE-TREE;Lo;0;L;;;;;N;;;;;
+1689F;BAMUM LETTER PHASE-C KEUSHEUAEP;Lo;0;L;;;;;N;;;;;
+168A0;BAMUM LETTER PHASE-C GHAP;Lo;0;L;;;;;N;;;;;
+168A1;BAMUM LETTER PHASE-C KEUKAQ;Lo;0;L;;;;;N;;;;;
+168A2;BAMUM LETTER PHASE-C YU MUOMAE;Lo;0;L;;;;;N;;;;;
+168A3;BAMUM LETTER PHASE-C NZEUM;Lo;0;L;;;;;N;;;;;
+168A4;BAMUM LETTER PHASE-C MBUE;Lo;0;L;;;;;N;;;;;
+168A5;BAMUM LETTER PHASE-C NSEUAEN;Lo;0;L;;;;;N;;;;;
+168A6;BAMUM LETTER PHASE-C MBIT;Lo;0;L;;;;;N;;;;;
+168A7;BAMUM LETTER PHASE-C YEUQ;Lo;0;L;;;;;N;;;;;
+168A8;BAMUM LETTER PHASE-C KPARAQ;Lo;0;L;;;;;N;;;;;
+168A9;BAMUM LETTER PHASE-C KAA;Lo;0;L;;;;;N;;;;;
+168AA;BAMUM LETTER PHASE-C SEUX;Lo;0;L;;;;;N;;;;;
+168AB;BAMUM LETTER PHASE-C NDIDA;Lo;0;L;;;;;N;;;;;
+168AC;BAMUM LETTER PHASE-C TAASHAE;Lo;0;L;;;;;N;;;;;
+168AD;BAMUM LETTER PHASE-C NJUEQ;Lo;0;L;;;;;N;;;;;
+168AE;BAMUM LETTER PHASE-C TITA YUE;Lo;0;L;;;;;N;;;;;
+168AF;BAMUM LETTER PHASE-C SUAET;Lo;0;L;;;;;N;;;;;
+168B0;BAMUM LETTER PHASE-C NGGUAEN NYAM;Lo;0;L;;;;;N;;;;;
+168B1;BAMUM LETTER PHASE-C VEUX;Lo;0;L;;;;;N;;;;;
+168B2;BAMUM LETTER PHASE-C NANSANAQ;Lo;0;L;;;;;N;;;;;
+168B3;BAMUM LETTER PHASE-C MA KEUAERI;Lo;0;L;;;;;N;;;;;
+168B4;BAMUM LETTER PHASE-C NTAA;Lo;0;L;;;;;N;;;;;
+168B5;BAMUM LETTER PHASE-C NGGUON;Lo;0;L;;;;;N;;;;;
+168B6;BAMUM LETTER PHASE-C LAP;Lo;0;L;;;;;N;;;;;
+168B7;BAMUM LETTER PHASE-C MBIRIEEN;Lo;0;L;;;;;N;;;;;
+168B8;BAMUM LETTER PHASE-C MGBASAQ;Lo;0;L;;;;;N;;;;;
+168B9;BAMUM LETTER PHASE-C NTEUNGBA;Lo;0;L;;;;;N;;;;;
+168BA;BAMUM LETTER PHASE-C TEUTEUX;Lo;0;L;;;;;N;;;;;
+168BB;BAMUM LETTER PHASE-C NGGUM;Lo;0;L;;;;;N;;;;;
+168BC;BAMUM LETTER PHASE-C FUE;Lo;0;L;;;;;N;;;;;
+168BD;BAMUM LETTER PHASE-C NDEUT;Lo;0;L;;;;;N;;;;;
+168BE;BAMUM LETTER PHASE-C NSA;Lo;0;L;;;;;N;;;;;
+168BF;BAMUM LETTER PHASE-C NSHAQ;Lo;0;L;;;;;N;;;;;
+168C0;BAMUM LETTER PHASE-C BUNG;Lo;0;L;;;;;N;;;;;
+168C1;BAMUM LETTER PHASE-C VEUAEPEN;Lo;0;L;;;;;N;;;;;
+168C2;BAMUM LETTER PHASE-C MBERAE;Lo;0;L;;;;;N;;;;;
+168C3;BAMUM LETTER PHASE-C RU;Lo;0;L;;;;;N;;;;;
+168C4;BAMUM LETTER PHASE-C NJAEM;Lo;0;L;;;;;N;;;;;
+168C5;BAMUM LETTER PHASE-C LAM;Lo;0;L;;;;;N;;;;;
+168C6;BAMUM LETTER PHASE-C TITUAEP;Lo;0;L;;;;;N;;;;;
+168C7;BAMUM LETTER PHASE-C NSUOT NGOM;Lo;0;L;;;;;N;;;;;
+168C8;BAMUM LETTER PHASE-C NJEEEE;Lo;0;L;;;;;N;;;;;
+168C9;BAMUM LETTER PHASE-C KET;Lo;0;L;;;;;N;;;;;
+168CA;BAMUM LETTER PHASE-C NGGU;Lo;0;L;;;;;N;;;;;
+168CB;BAMUM LETTER PHASE-C MAESI;Lo;0;L;;;;;N;;;;;
+168CC;BAMUM LETTER PHASE-C MBUAEM;Lo;0;L;;;;;N;;;;;
+168CD;BAMUM LETTER PHASE-C LU;Lo;0;L;;;;;N;;;;;
+168CE;BAMUM LETTER PHASE-C KUT;Lo;0;L;;;;;N;;;;;
+168CF;BAMUM LETTER PHASE-C NJAM;Lo;0;L;;;;;N;;;;;
+168D0;BAMUM LETTER PHASE-C NGOM;Lo;0;L;;;;;N;;;;;
+168D1;BAMUM LETTER PHASE-C WUP;Lo;0;L;;;;;N;;;;;
+168D2;BAMUM LETTER PHASE-C NGGUEET;Lo;0;L;;;;;N;;;;;
+168D3;BAMUM LETTER PHASE-C NSOM;Lo;0;L;;;;;N;;;;;
+168D4;BAMUM LETTER PHASE-C NTEN;Lo;0;L;;;;;N;;;;;
+168D5;BAMUM LETTER PHASE-C KUOP NKAARAE;Lo;0;L;;;;;N;;;;;
+168D6;BAMUM LETTER PHASE-C NSUN;Lo;0;L;;;;;N;;;;;
+168D7;BAMUM LETTER PHASE-C NDAM;Lo;0;L;;;;;N;;;;;
+168D8;BAMUM LETTER PHASE-C MA NSIEE;Lo;0;L;;;;;N;;;;;
+168D9;BAMUM LETTER PHASE-C YAA;Lo;0;L;;;;;N;;;;;
+168DA;BAMUM LETTER PHASE-C NDAP;Lo;0;L;;;;;N;;;;;
+168DB;BAMUM LETTER PHASE-C SHUEQ;Lo;0;L;;;;;N;;;;;
+168DC;BAMUM LETTER PHASE-C SETFON;Lo;0;L;;;;;N;;;;;
+168DD;BAMUM LETTER PHASE-C MBI;Lo;0;L;;;;;N;;;;;
+168DE;BAMUM LETTER PHASE-C MAEMBA;Lo;0;L;;;;;N;;;;;
+168DF;BAMUM LETTER PHASE-C MBANYI;Lo;0;L;;;;;N;;;;;
+168E0;BAMUM LETTER PHASE-C KEUSEUX;Lo;0;L;;;;;N;;;;;
+168E1;BAMUM LETTER PHASE-C MBEUX;Lo;0;L;;;;;N;;;;;
+168E2;BAMUM LETTER PHASE-C KEUM;Lo;0;L;;;;;N;;;;;
+168E3;BAMUM LETTER PHASE-C MBAA PICKET;Lo;0;L;;;;;N;;;;;
+168E4;BAMUM LETTER PHASE-C YUWOQ;Lo;0;L;;;;;N;;;;;
+168E5;BAMUM LETTER PHASE-C NJEUX;Lo;0;L;;;;;N;;;;;
+168E6;BAMUM LETTER PHASE-C MIEE;Lo;0;L;;;;;N;;;;;
+168E7;BAMUM LETTER PHASE-C MUAE;Lo;0;L;;;;;N;;;;;
+168E8;BAMUM LETTER PHASE-C SHIQ;Lo;0;L;;;;;N;;;;;
+168E9;BAMUM LETTER PHASE-C KEN LAW;Lo;0;L;;;;;N;;;;;
+168EA;BAMUM LETTER PHASE-C KEN FATIGUE;Lo;0;L;;;;;N;;;;;
+168EB;BAMUM LETTER PHASE-C NGAQ;Lo;0;L;;;;;N;;;;;
+168EC;BAMUM LETTER PHASE-C NAQ;Lo;0;L;;;;;N;;;;;
+168ED;BAMUM LETTER PHASE-C LIQ;Lo;0;L;;;;;N;;;;;
+168EE;BAMUM LETTER PHASE-C PIN;Lo;0;L;;;;;N;;;;;
+168EF;BAMUM LETTER PHASE-C PEN;Lo;0;L;;;;;N;;;;;
+168F0;BAMUM LETTER PHASE-C TET;Lo;0;L;;;;;N;;;;;
+168F1;BAMUM LETTER PHASE-D MBUO;Lo;0;L;;;;;N;;;;;
+168F2;BAMUM LETTER PHASE-D WAP;Lo;0;L;;;;;N;;;;;
+168F3;BAMUM LETTER PHASE-D NJI;Lo;0;L;;;;;N;;;;;
+168F4;BAMUM LETTER PHASE-D MFON;Lo;0;L;;;;;N;;;;;
+168F5;BAMUM LETTER PHASE-D NJIEE;Lo;0;L;;;;;N;;;;;
+168F6;BAMUM LETTER PHASE-D LIEE;Lo;0;L;;;;;N;;;;;
+168F7;BAMUM LETTER PHASE-D NJEUT;Lo;0;L;;;;;N;;;;;
+168F8;BAMUM LETTER PHASE-D NSHEE;Lo;0;L;;;;;N;;;;;
+168F9;BAMUM LETTER PHASE-D NGGAAMAE;Lo;0;L;;;;;N;;;;;
+168FA;BAMUM LETTER PHASE-D NYAM;Lo;0;L;;;;;N;;;;;
+168FB;BAMUM LETTER PHASE-D WUAEN;Lo;0;L;;;;;N;;;;;
+168FC;BAMUM LETTER PHASE-D NGKUN;Lo;0;L;;;;;N;;;;;
+168FD;BAMUM LETTER PHASE-D SHEE;Lo;0;L;;;;;N;;;;;
+168FE;BAMUM LETTER PHASE-D NGKAP;Lo;0;L;;;;;N;;;;;
+168FF;BAMUM LETTER PHASE-D KEUAETMEUN;Lo;0;L;;;;;N;;;;;
+16900;BAMUM LETTER PHASE-D TEUT;Lo;0;L;;;;;N;;;;;
+16901;BAMUM LETTER PHASE-D SHEUAE;Lo;0;L;;;;;N;;;;;
+16902;BAMUM LETTER PHASE-D NJAP;Lo;0;L;;;;;N;;;;;
+16903;BAMUM LETTER PHASE-D SUE;Lo;0;L;;;;;N;;;;;
+16904;BAMUM LETTER PHASE-D KET;Lo;0;L;;;;;N;;;;;
+16905;BAMUM LETTER PHASE-D YAEMMAE;Lo;0;L;;;;;N;;;;;
+16906;BAMUM LETTER PHASE-D KUOM;Lo;0;L;;;;;N;;;;;
+16907;BAMUM LETTER PHASE-D SAP;Lo;0;L;;;;;N;;;;;
+16908;BAMUM LETTER PHASE-D MFEUT;Lo;0;L;;;;;N;;;;;
+16909;BAMUM LETTER PHASE-D NDEUX;Lo;0;L;;;;;N;;;;;
+1690A;BAMUM LETTER PHASE-D MALEERI;Lo;0;L;;;;;N;;;;;
+1690B;BAMUM LETTER PHASE-D MEUT;Lo;0;L;;;;;N;;;;;
+1690C;BAMUM LETTER PHASE-D SEUAEQ;Lo;0;L;;;;;N;;;;;
+1690D;BAMUM LETTER PHASE-D YEN;Lo;0;L;;;;;N;;;;;
+1690E;BAMUM LETTER PHASE-D NJEUAEM;Lo;0;L;;;;;N;;;;;
+1690F;BAMUM LETTER PHASE-D KEUOT MBUAE;Lo;0;L;;;;;N;;;;;
+16910;BAMUM LETTER PHASE-D NGKEURI;Lo;0;L;;;;;N;;;;;
+16911;BAMUM LETTER PHASE-D TU;Lo;0;L;;;;;N;;;;;
+16912;BAMUM LETTER PHASE-D GHAA;Lo;0;L;;;;;N;;;;;
+16913;BAMUM LETTER PHASE-D NGKYEE;Lo;0;L;;;;;N;;;;;
+16914;BAMUM LETTER PHASE-D FEUFEUAET;Lo;0;L;;;;;N;;;;;
+16915;BAMUM LETTER PHASE-D NDEE;Lo;0;L;;;;;N;;;;;
+16916;BAMUM LETTER PHASE-D MGBOFUM;Lo;0;L;;;;;N;;;;;
+16917;BAMUM LETTER PHASE-D LEUAEP;Lo;0;L;;;;;N;;;;;
+16918;BAMUM LETTER PHASE-D NDON;Lo;0;L;;;;;N;;;;;
+16919;BAMUM LETTER PHASE-D MONI;Lo;0;L;;;;;N;;;;;
+1691A;BAMUM LETTER PHASE-D MGBEUN;Lo;0;L;;;;;N;;;;;
+1691B;BAMUM LETTER PHASE-D PUUT;Lo;0;L;;;;;N;;;;;
+1691C;BAMUM LETTER PHASE-D MGBIEE;Lo;0;L;;;;;N;;;;;
+1691D;BAMUM LETTER PHASE-D MFO;Lo;0;L;;;;;N;;;;;
+1691E;BAMUM LETTER PHASE-D LUM;Lo;0;L;;;;;N;;;;;
+1691F;BAMUM LETTER PHASE-D NSIEEP;Lo;0;L;;;;;N;;;;;
+16920;BAMUM LETTER PHASE-D MBAA;Lo;0;L;;;;;N;;;;;
+16921;BAMUM LETTER PHASE-D KWAET;Lo;0;L;;;;;N;;;;;
+16922;BAMUM LETTER PHASE-D NYET;Lo;0;L;;;;;N;;;;;
+16923;BAMUM LETTER PHASE-D TEUAEN;Lo;0;L;;;;;N;;;;;
+16924;BAMUM LETTER PHASE-D SOT;Lo;0;L;;;;;N;;;;;
+16925;BAMUM LETTER PHASE-D YUWOQ;Lo;0;L;;;;;N;;;;;
+16926;BAMUM LETTER PHASE-D KEUM;Lo;0;L;;;;;N;;;;;
+16927;BAMUM LETTER PHASE-D RAEM;Lo;0;L;;;;;N;;;;;
+16928;BAMUM LETTER PHASE-D TEEEE;Lo;0;L;;;;;N;;;;;
+16929;BAMUM LETTER PHASE-D NGKEUAEQ;Lo;0;L;;;;;N;;;;;
+1692A;BAMUM LETTER PHASE-D MFEUAE;Lo;0;L;;;;;N;;;;;
+1692B;BAMUM LETTER PHASE-D NSIEET;Lo;0;L;;;;;N;;;;;
+1692C;BAMUM LETTER PHASE-D KEUP;Lo;0;L;;;;;N;;;;;
+1692D;BAMUM LETTER PHASE-D PIP;Lo;0;L;;;;;N;;;;;
+1692E;BAMUM LETTER PHASE-D PEUTAE;Lo;0;L;;;;;N;;;;;
+1692F;BAMUM LETTER PHASE-D NYUE;Lo;0;L;;;;;N;;;;;
+16930;BAMUM LETTER PHASE-D LET;Lo;0;L;;;;;N;;;;;
+16931;BAMUM LETTER PHASE-D NGGAAM;Lo;0;L;;;;;N;;;;;
+16932;BAMUM LETTER PHASE-D MFIEE;Lo;0;L;;;;;N;;;;;
+16933;BAMUM LETTER PHASE-D NGGWAEN;Lo;0;L;;;;;N;;;;;
+16934;BAMUM LETTER PHASE-D YUOM;Lo;0;L;;;;;N;;;;;
+16935;BAMUM LETTER PHASE-D PAP;Lo;0;L;;;;;N;;;;;
+16936;BAMUM LETTER PHASE-D YUOP;Lo;0;L;;;;;N;;;;;
+16937;BAMUM LETTER PHASE-D NDAM;Lo;0;L;;;;;N;;;;;
+16938;BAMUM LETTER PHASE-D NTEUM;Lo;0;L;;;;;N;;;;;
+16939;BAMUM LETTER PHASE-D SUAE;Lo;0;L;;;;;N;;;;;
+1693A;BAMUM LETTER PHASE-D KUN;Lo;0;L;;;;;N;;;;;
+1693B;BAMUM LETTER PHASE-D NGGEUX;Lo;0;L;;;;;N;;;;;
+1693C;BAMUM LETTER PHASE-D NGKIEE;Lo;0;L;;;;;N;;;;;
+1693D;BAMUM LETTER PHASE-D TUOT;Lo;0;L;;;;;N;;;;;
+1693E;BAMUM LETTER PHASE-D MEUN;Lo;0;L;;;;;N;;;;;
+1693F;BAMUM LETTER PHASE-D KUQ;Lo;0;L;;;;;N;;;;;
+16940;BAMUM LETTER PHASE-D NSUM;Lo;0;L;;;;;N;;;;;
+16941;BAMUM LETTER PHASE-D TEUN;Lo;0;L;;;;;N;;;;;
+16942;BAMUM LETTER PHASE-D MAENJET;Lo;0;L;;;;;N;;;;;
+16943;BAMUM LETTER PHASE-D NGGAP;Lo;0;L;;;;;N;;;;;
+16944;BAMUM LETTER PHASE-D LEUM;Lo;0;L;;;;;N;;;;;
+16945;BAMUM LETTER PHASE-D NGGUOM;Lo;0;L;;;;;N;;;;;
+16946;BAMUM LETTER PHASE-D NSHUT;Lo;0;L;;;;;N;;;;;
+16947;BAMUM LETTER PHASE-D NJUEQ;Lo;0;L;;;;;N;;;;;
+16948;BAMUM LETTER PHASE-D GHEUAE;Lo;0;L;;;;;N;;;;;
+16949;BAMUM LETTER PHASE-D KU;Lo;0;L;;;;;N;;;;;
+1694A;BAMUM LETTER PHASE-D REN OLD;Lo;0;L;;;;;N;;;;;
+1694B;BAMUM LETTER PHASE-D TAE;Lo;0;L;;;;;N;;;;;
+1694C;BAMUM LETTER PHASE-D TOQ;Lo;0;L;;;;;N;;;;;
+1694D;BAMUM LETTER PHASE-D NYI;Lo;0;L;;;;;N;;;;;
+1694E;BAMUM LETTER PHASE-D RII;Lo;0;L;;;;;N;;;;;
+1694F;BAMUM LETTER PHASE-D LEEEE;Lo;0;L;;;;;N;;;;;
+16950;BAMUM LETTER PHASE-D MEEEE;Lo;0;L;;;;;N;;;;;
+16951;BAMUM LETTER PHASE-D M;Lo;0;L;;;;;N;;;;;
+16952;BAMUM LETTER PHASE-D SUU;Lo;0;L;;;;;N;;;;;
+16953;BAMUM LETTER PHASE-D MU;Lo;0;L;;;;;N;;;;;
+16954;BAMUM LETTER PHASE-D SHII;Lo;0;L;;;;;N;;;;;
+16955;BAMUM LETTER PHASE-D SHEUX;Lo;0;L;;;;;N;;;;;
+16956;BAMUM LETTER PHASE-D KYEE;Lo;0;L;;;;;N;;;;;
+16957;BAMUM LETTER PHASE-D NU;Lo;0;L;;;;;N;;;;;
+16958;BAMUM LETTER PHASE-D SHU;Lo;0;L;;;;;N;;;;;
+16959;BAMUM LETTER PHASE-D NTEE;Lo;0;L;;;;;N;;;;;
+1695A;BAMUM LETTER PHASE-D PEE;Lo;0;L;;;;;N;;;;;
+1695B;BAMUM LETTER PHASE-D NI;Lo;0;L;;;;;N;;;;;
+1695C;BAMUM LETTER PHASE-D SHOQ;Lo;0;L;;;;;N;;;;;
+1695D;BAMUM LETTER PHASE-D PUQ;Lo;0;L;;;;;N;;;;;
+1695E;BAMUM LETTER PHASE-D MVOP;Lo;0;L;;;;;N;;;;;
+1695F;BAMUM LETTER PHASE-D LOQ;Lo;0;L;;;;;N;;;;;
+16960;BAMUM LETTER PHASE-D REN MUCH;Lo;0;L;;;;;N;;;;;
+16961;BAMUM LETTER PHASE-D TI;Lo;0;L;;;;;N;;;;;
+16962;BAMUM LETTER PHASE-D NTUU;Lo;0;L;;;;;N;;;;;
+16963;BAMUM LETTER PHASE-D MBAA SEVEN;Lo;0;L;;;;;N;;;;;
+16964;BAMUM LETTER PHASE-D SAQ;Lo;0;L;;;;;N;;;;;
+16965;BAMUM LETTER PHASE-D FAA;Lo;0;L;;;;;N;;;;;
+16966;BAMUM LETTER PHASE-E NDAP;Lo;0;L;;;;;N;;;;;
+16967;BAMUM LETTER PHASE-E TOON;Lo;0;L;;;;;N;;;;;
+16968;BAMUM LETTER PHASE-E MBEUM;Lo;0;L;;;;;N;;;;;
+16969;BAMUM LETTER PHASE-E LAP;Lo;0;L;;;;;N;;;;;
+1696A;BAMUM LETTER PHASE-E VOM;Lo;0;L;;;;;N;;;;;
+1696B;BAMUM LETTER PHASE-E LOON;Lo;0;L;;;;;N;;;;;
+1696C;BAMUM LETTER PHASE-E PAA;Lo;0;L;;;;;N;;;;;
+1696D;BAMUM LETTER PHASE-E SOM;Lo;0;L;;;;;N;;;;;
+1696E;BAMUM LETTER PHASE-E RAQ;Lo;0;L;;;;;N;;;;;
+1696F;BAMUM LETTER PHASE-E NSHUOP;Lo;0;L;;;;;N;;;;;
+16970;BAMUM LETTER PHASE-E NDUN;Lo;0;L;;;;;N;;;;;
+16971;BAMUM LETTER PHASE-E PUAE;Lo;0;L;;;;;N;;;;;
+16972;BAMUM LETTER PHASE-E TAM;Lo;0;L;;;;;N;;;;;
+16973;BAMUM LETTER PHASE-E NGKA;Lo;0;L;;;;;N;;;;;
+16974;BAMUM LETTER PHASE-E KPEUX;Lo;0;L;;;;;N;;;;;
+16975;BAMUM LETTER PHASE-E WUO;Lo;0;L;;;;;N;;;;;
+16976;BAMUM LETTER PHASE-E SEE;Lo;0;L;;;;;N;;;;;
+16977;BAMUM LETTER PHASE-E NGGEUAET;Lo;0;L;;;;;N;;;;;
+16978;BAMUM LETTER PHASE-E PAAM;Lo;0;L;;;;;N;;;;;
+16979;BAMUM LETTER PHASE-E TOO;Lo;0;L;;;;;N;;;;;
+1697A;BAMUM LETTER PHASE-E KUOP;Lo;0;L;;;;;N;;;;;
+1697B;BAMUM LETTER PHASE-E LOM;Lo;0;L;;;;;N;;;;;
+1697C;BAMUM LETTER PHASE-E NSHIEE;Lo;0;L;;;;;N;;;;;
+1697D;BAMUM LETTER PHASE-E NGOP;Lo;0;L;;;;;N;;;;;
+1697E;BAMUM LETTER PHASE-E MAEM;Lo;0;L;;;;;N;;;;;
+1697F;BAMUM LETTER PHASE-E NGKEUX;Lo;0;L;;;;;N;;;;;
+16980;BAMUM LETTER PHASE-E NGOQ;Lo;0;L;;;;;N;;;;;
+16981;BAMUM LETTER PHASE-E NSHUE;Lo;0;L;;;;;N;;;;;
+16982;BAMUM LETTER PHASE-E RIMGBA;Lo;0;L;;;;;N;;;;;
+16983;BAMUM LETTER PHASE-E NJEUX;Lo;0;L;;;;;N;;;;;
+16984;BAMUM LETTER PHASE-E PEEM;Lo;0;L;;;;;N;;;;;
+16985;BAMUM LETTER PHASE-E SAA;Lo;0;L;;;;;N;;;;;
+16986;BAMUM LETTER PHASE-E NGGURAE;Lo;0;L;;;;;N;;;;;
+16987;BAMUM LETTER PHASE-E MGBA;Lo;0;L;;;;;N;;;;;
+16988;BAMUM LETTER PHASE-E GHEUX;Lo;0;L;;;;;N;;;;;
+16989;BAMUM LETTER PHASE-E NGKEUAEM;Lo;0;L;;;;;N;;;;;
+1698A;BAMUM LETTER PHASE-E NJAEMLI;Lo;0;L;;;;;N;;;;;
+1698B;BAMUM LETTER PHASE-E MAP;Lo;0;L;;;;;N;;;;;
+1698C;BAMUM LETTER PHASE-E LOOT;Lo;0;L;;;;;N;;;;;
+1698D;BAMUM LETTER PHASE-E NGGEEEE;Lo;0;L;;;;;N;;;;;
+1698E;BAMUM LETTER PHASE-E NDIQ;Lo;0;L;;;;;N;;;;;
+1698F;BAMUM LETTER PHASE-E TAEN NTEUM;Lo;0;L;;;;;N;;;;;
+16990;BAMUM LETTER PHASE-E SET;Lo;0;L;;;;;N;;;;;
+16991;BAMUM LETTER PHASE-E PUM;Lo;0;L;;;;;N;;;;;
+16992;BAMUM LETTER PHASE-E NDAA SOFTNESS;Lo;0;L;;;;;N;;;;;
+16993;BAMUM LETTER PHASE-E NGGUAESHAE NYAM;Lo;0;L;;;;;N;;;;;
+16994;BAMUM LETTER PHASE-E YIEE;Lo;0;L;;;;;N;;;;;
+16995;BAMUM LETTER PHASE-E GHEUN;Lo;0;L;;;;;N;;;;;
+16996;BAMUM LETTER PHASE-E TUAE;Lo;0;L;;;;;N;;;;;
+16997;BAMUM LETTER PHASE-E YEUAE;Lo;0;L;;;;;N;;;;;
+16998;BAMUM LETTER PHASE-E PO;Lo;0;L;;;;;N;;;;;
+16999;BAMUM LETTER PHASE-E TUMAE;Lo;0;L;;;;;N;;;;;
+1699A;BAMUM LETTER PHASE-E KEUAE;Lo;0;L;;;;;N;;;;;
+1699B;BAMUM LETTER PHASE-E SUAEN;Lo;0;L;;;;;N;;;;;
+1699C;BAMUM LETTER PHASE-E TEUAEQ;Lo;0;L;;;;;N;;;;;
+1699D;BAMUM LETTER PHASE-E VEUAE;Lo;0;L;;;;;N;;;;;
+1699E;BAMUM LETTER PHASE-E WEUX;Lo;0;L;;;;;N;;;;;
+1699F;BAMUM LETTER PHASE-E LAAM;Lo;0;L;;;;;N;;;;;
+169A0;BAMUM LETTER PHASE-E PU;Lo;0;L;;;;;N;;;;;
+169A1;BAMUM LETTER PHASE-E TAAQ;Lo;0;L;;;;;N;;;;;
+169A2;BAMUM LETTER PHASE-E GHAAMAE;Lo;0;L;;;;;N;;;;;
+169A3;BAMUM LETTER PHASE-E NGEUREUT;Lo;0;L;;;;;N;;;;;
+169A4;BAMUM LETTER PHASE-E SHEUAEQ;Lo;0;L;;;;;N;;;;;
+169A5;BAMUM LETTER PHASE-E MGBEN;Lo;0;L;;;;;N;;;;;
+169A6;BAMUM LETTER PHASE-E MBEE;Lo;0;L;;;;;N;;;;;
+169A7;BAMUM LETTER PHASE-E NZAQ;Lo;0;L;;;;;N;;;;;
+169A8;BAMUM LETTER PHASE-E NKOM;Lo;0;L;;;;;N;;;;;
+169A9;BAMUM LETTER PHASE-E GBET;Lo;0;L;;;;;N;;;;;
+169AA;BAMUM LETTER PHASE-E TUM;Lo;0;L;;;;;N;;;;;
+169AB;BAMUM LETTER PHASE-E KUET;Lo;0;L;;;;;N;;;;;
+169AC;BAMUM LETTER PHASE-E YAP;Lo;0;L;;;;;N;;;;;
+169AD;BAMUM LETTER PHASE-E NYI CLEAVER;Lo;0;L;;;;;N;;;;;
+169AE;BAMUM LETTER PHASE-E YIT;Lo;0;L;;;;;N;;;;;
+169AF;BAMUM LETTER PHASE-E MFEUQ;Lo;0;L;;;;;N;;;;;
+169B0;BAMUM LETTER PHASE-E NDIAQ;Lo;0;L;;;;;N;;;;;
+169B1;BAMUM LETTER PHASE-E PIEEQ;Lo;0;L;;;;;N;;;;;
+169B2;BAMUM LETTER PHASE-E YUEQ;Lo;0;L;;;;;N;;;;;
+169B3;BAMUM LETTER PHASE-E LEUAEM;Lo;0;L;;;;;N;;;;;
+169B4;BAMUM LETTER PHASE-E FUE;Lo;0;L;;;;;N;;;;;
+169B5;BAMUM LETTER PHASE-E GBEUX;Lo;0;L;;;;;N;;;;;
+169B6;BAMUM LETTER PHASE-E NGKUP;Lo;0;L;;;;;N;;;;;
+169B7;BAMUM LETTER PHASE-E KET;Lo;0;L;;;;;N;;;;;
+169B8;BAMUM LETTER PHASE-E MAE;Lo;0;L;;;;;N;;;;;
+169B9;BAMUM LETTER PHASE-E NGKAAMI;Lo;0;L;;;;;N;;;;;
+169BA;BAMUM LETTER PHASE-E GHET;Lo;0;L;;;;;N;;;;;
+169BB;BAMUM LETTER PHASE-E FA;Lo;0;L;;;;;N;;;;;
+169BC;BAMUM LETTER PHASE-E NTUM;Lo;0;L;;;;;N;;;;;
+169BD;BAMUM LETTER PHASE-E PEUT;Lo;0;L;;;;;N;;;;;
+169BE;BAMUM LETTER PHASE-E YEUM;Lo;0;L;;;;;N;;;;;
+169BF;BAMUM LETTER PHASE-E NGGEUAE;Lo;0;L;;;;;N;;;;;
+169C0;BAMUM LETTER PHASE-E NYI BETWEEN;Lo;0;L;;;;;N;;;;;
+169C1;BAMUM LETTER PHASE-E NZUQ;Lo;0;L;;;;;N;;;;;
+169C2;BAMUM LETTER PHASE-E POON;Lo;0;L;;;;;N;;;;;
+169C3;BAMUM LETTER PHASE-E MIEE;Lo;0;L;;;;;N;;;;;
+169C4;BAMUM LETTER PHASE-E FUET;Lo;0;L;;;;;N;;;;;
+169C5;BAMUM LETTER PHASE-E NAE;Lo;0;L;;;;;N;;;;;
+169C6;BAMUM LETTER PHASE-E MUAE;Lo;0;L;;;;;N;;;;;
+169C7;BAMUM LETTER PHASE-E GHEUAE;Lo;0;L;;;;;N;;;;;
+169C8;BAMUM LETTER PHASE-E FU I;Lo;0;L;;;;;N;;;;;
+169C9;BAMUM LETTER PHASE-E MVI;Lo;0;L;;;;;N;;;;;
+169CA;BAMUM LETTER PHASE-E PUAQ;Lo;0;L;;;;;N;;;;;
+169CB;BAMUM LETTER PHASE-E NGKUM;Lo;0;L;;;;;N;;;;;
+169CC;BAMUM LETTER PHASE-E KUT;Lo;0;L;;;;;N;;;;;
+169CD;BAMUM LETTER PHASE-E PIET;Lo;0;L;;;;;N;;;;;
+169CE;BAMUM LETTER PHASE-E NTAP;Lo;0;L;;;;;N;;;;;
+169CF;BAMUM LETTER PHASE-E YEUAET;Lo;0;L;;;;;N;;;;;
+169D0;BAMUM LETTER PHASE-E NGGUP;Lo;0;L;;;;;N;;;;;
+169D1;BAMUM LETTER PHASE-E PA PEOPLE;Lo;0;L;;;;;N;;;;;
+169D2;BAMUM LETTER PHASE-E FU CALL;Lo;0;L;;;;;N;;;;;
+169D3;BAMUM LETTER PHASE-E FOM;Lo;0;L;;;;;N;;;;;
+169D4;BAMUM LETTER PHASE-E NJEE;Lo;0;L;;;;;N;;;;;
+169D5;BAMUM LETTER PHASE-E A;Lo;0;L;;;;;N;;;;;
+169D6;BAMUM LETTER PHASE-E TOQ;Lo;0;L;;;;;N;;;;;
+169D7;BAMUM LETTER PHASE-E O;Lo;0;L;;;;;N;;;;;
+169D8;BAMUM LETTER PHASE-E I;Lo;0;L;;;;;N;;;;;
+169D9;BAMUM LETTER PHASE-E LAQ;Lo;0;L;;;;;N;;;;;
+169DA;BAMUM LETTER PHASE-E PA PLURAL;Lo;0;L;;;;;N;;;;;
+169DB;BAMUM LETTER PHASE-E TAA;Lo;0;L;;;;;N;;;;;
+169DC;BAMUM LETTER PHASE-E TAQ;Lo;0;L;;;;;N;;;;;
+169DD;BAMUM LETTER PHASE-E NDAA MY HOUSE;Lo;0;L;;;;;N;;;;;
+169DE;BAMUM LETTER PHASE-E SHIQ;Lo;0;L;;;;;N;;;;;
+169DF;BAMUM LETTER PHASE-E YEUX;Lo;0;L;;;;;N;;;;;
+169E0;BAMUM LETTER PHASE-E NGUAE;Lo;0;L;;;;;N;;;;;
+169E1;BAMUM LETTER PHASE-E YUAEN;Lo;0;L;;;;;N;;;;;
+169E2;BAMUM LETTER PHASE-E YOQ SWIMMING;Lo;0;L;;;;;N;;;;;
+169E3;BAMUM LETTER PHASE-E YOQ COVER;Lo;0;L;;;;;N;;;;;
+169E4;BAMUM LETTER PHASE-E YUQ;Lo;0;L;;;;;N;;;;;
+169E5;BAMUM LETTER PHASE-E YUN;Lo;0;L;;;;;N;;;;;
+169E6;BAMUM LETTER PHASE-E KEUX;Lo;0;L;;;;;N;;;;;
+169E7;BAMUM LETTER PHASE-E PEUX;Lo;0;L;;;;;N;;;;;
+169E8;BAMUM LETTER PHASE-E NJEE EPOCH;Lo;0;L;;;;;N;;;;;
+169E9;BAMUM LETTER PHASE-E PUE;Lo;0;L;;;;;N;;;;;
+169EA;BAMUM LETTER PHASE-E WUE;Lo;0;L;;;;;N;;;;;
+169EB;BAMUM LETTER PHASE-E FEE;Lo;0;L;;;;;N;;;;;
+169EC;BAMUM LETTER PHASE-E VEE;Lo;0;L;;;;;N;;;;;
+169ED;BAMUM LETTER PHASE-E LU;Lo;0;L;;;;;N;;;;;
+169EE;BAMUM LETTER PHASE-E MI;Lo;0;L;;;;;N;;;;;
+169EF;BAMUM LETTER PHASE-E REUX;Lo;0;L;;;;;N;;;;;
+169F0;BAMUM LETTER PHASE-E RAE;Lo;0;L;;;;;N;;;;;
+169F1;BAMUM LETTER PHASE-E NGUAET;Lo;0;L;;;;;N;;;;;
+169F2;BAMUM LETTER PHASE-E NGA;Lo;0;L;;;;;N;;;;;
+169F3;BAMUM LETTER PHASE-E SHO;Lo;0;L;;;;;N;;;;;
+169F4;BAMUM LETTER PHASE-E SHOQ;Lo;0;L;;;;;N;;;;;
+169F5;BAMUM LETTER PHASE-E FU REMEDY;Lo;0;L;;;;;N;;;;;
+169F6;BAMUM LETTER PHASE-E NA;Lo;0;L;;;;;N;;;;;
+169F7;BAMUM LETTER PHASE-E PI;Lo;0;L;;;;;N;;;;;
+169F8;BAMUM LETTER PHASE-E LOQ;Lo;0;L;;;;;N;;;;;
+169F9;BAMUM LETTER PHASE-E KO;Lo;0;L;;;;;N;;;;;
+169FA;BAMUM LETTER PHASE-E MEN;Lo;0;L;;;;;N;;;;;
+169FB;BAMUM LETTER PHASE-E MA;Lo;0;L;;;;;N;;;;;
+169FC;BAMUM LETTER PHASE-E MAQ;Lo;0;L;;;;;N;;;;;
+169FD;BAMUM LETTER PHASE-E TEU;Lo;0;L;;;;;N;;;;;
+169FE;BAMUM LETTER PHASE-E KI;Lo;0;L;;;;;N;;;;;
+169FF;BAMUM LETTER PHASE-E MON;Lo;0;L;;;;;N;;;;;
+16A00;BAMUM LETTER PHASE-E TEN;Lo;0;L;;;;;N;;;;;
+16A01;BAMUM LETTER PHASE-E FAQ;Lo;0;L;;;;;N;;;;;
+16A02;BAMUM LETTER PHASE-E GHOM;Lo;0;L;;;;;N;;;;;
+16A03;BAMUM LETTER PHASE-F KA;Lo;0;L;;;;;N;;;;;
+16A04;BAMUM LETTER PHASE-F U;Lo;0;L;;;;;N;;;;;
+16A05;BAMUM LETTER PHASE-F KU;Lo;0;L;;;;;N;;;;;
+16A06;BAMUM LETTER PHASE-F EE;Lo;0;L;;;;;N;;;;;
+16A07;BAMUM LETTER PHASE-F REE;Lo;0;L;;;;;N;;;;;
+16A08;BAMUM LETTER PHASE-F TAE;Lo;0;L;;;;;N;;;;;
+16A09;BAMUM LETTER PHASE-F NYI;Lo;0;L;;;;;N;;;;;
+16A0A;BAMUM LETTER PHASE-F LA;Lo;0;L;;;;;N;;;;;
+16A0B;BAMUM LETTER PHASE-F RII;Lo;0;L;;;;;N;;;;;
+16A0C;BAMUM LETTER PHASE-F RIEE;Lo;0;L;;;;;N;;;;;
+16A0D;BAMUM LETTER PHASE-F MEEEE;Lo;0;L;;;;;N;;;;;
+16A0E;BAMUM LETTER PHASE-F TAA;Lo;0;L;;;;;N;;;;;
+16A0F;BAMUM LETTER PHASE-F NDAA;Lo;0;L;;;;;N;;;;;
+16A10;BAMUM LETTER PHASE-F NJAEM;Lo;0;L;;;;;N;;;;;
+16A11;BAMUM LETTER PHASE-F M;Lo;0;L;;;;;N;;;;;
+16A12;BAMUM LETTER PHASE-F SUU;Lo;0;L;;;;;N;;;;;
+16A13;BAMUM LETTER PHASE-F SHII;Lo;0;L;;;;;N;;;;;
+16A14;BAMUM LETTER PHASE-F SI;Lo;0;L;;;;;N;;;;;
+16A15;BAMUM LETTER PHASE-F SEUX;Lo;0;L;;;;;N;;;;;
+16A16;BAMUM LETTER PHASE-F KYEE;Lo;0;L;;;;;N;;;;;
+16A17;BAMUM LETTER PHASE-F KET;Lo;0;L;;;;;N;;;;;
+16A18;BAMUM LETTER PHASE-F NUAE;Lo;0;L;;;;;N;;;;;
+16A19;BAMUM LETTER PHASE-F NU;Lo;0;L;;;;;N;;;;;
+16A1A;BAMUM LETTER PHASE-F NJUAE;Lo;0;L;;;;;N;;;;;
+16A1B;BAMUM LETTER PHASE-F YOQ;Lo;0;L;;;;;N;;;;;
+16A1C;BAMUM LETTER PHASE-F SHU;Lo;0;L;;;;;N;;;;;
+16A1D;BAMUM LETTER PHASE-F YA;Lo;0;L;;;;;N;;;;;
+16A1E;BAMUM LETTER PHASE-F NSHA;Lo;0;L;;;;;N;;;;;
+16A1F;BAMUM LETTER PHASE-F PEUX;Lo;0;L;;;;;N;;;;;
+16A20;BAMUM LETTER PHASE-F NTEE;Lo;0;L;;;;;N;;;;;
+16A21;BAMUM LETTER PHASE-F WUE;Lo;0;L;;;;;N;;;;;
+16A22;BAMUM LETTER PHASE-F PEE;Lo;0;L;;;;;N;;;;;
+16A23;BAMUM LETTER PHASE-F RU;Lo;0;L;;;;;N;;;;;
+16A24;BAMUM LETTER PHASE-F NI;Lo;0;L;;;;;N;;;;;
+16A25;BAMUM LETTER PHASE-F REUX;Lo;0;L;;;;;N;;;;;
+16A26;BAMUM LETTER PHASE-F KEN;Lo;0;L;;;;;N;;;;;
+16A27;BAMUM LETTER PHASE-F NGKWAEN;Lo;0;L;;;;;N;;;;;
+16A28;BAMUM LETTER PHASE-F NGGA;Lo;0;L;;;;;N;;;;;
+16A29;BAMUM LETTER PHASE-F SHO;Lo;0;L;;;;;N;;;;;
+16A2A;BAMUM LETTER PHASE-F PUAE;Lo;0;L;;;;;N;;;;;
+16A2B;BAMUM LETTER PHASE-F FOM;Lo;0;L;;;;;N;;;;;
+16A2C;BAMUM LETTER PHASE-F WA;Lo;0;L;;;;;N;;;;;
+16A2D;BAMUM LETTER PHASE-F LI;Lo;0;L;;;;;N;;;;;
+16A2E;BAMUM LETTER PHASE-F LOQ;Lo;0;L;;;;;N;;;;;
+16A2F;BAMUM LETTER PHASE-F KO;Lo;0;L;;;;;N;;;;;
+16A30;BAMUM LETTER PHASE-F MBEN;Lo;0;L;;;;;N;;;;;
+16A31;BAMUM LETTER PHASE-F REN;Lo;0;L;;;;;N;;;;;
+16A32;BAMUM LETTER PHASE-F MA;Lo;0;L;;;;;N;;;;;
+16A33;BAMUM LETTER PHASE-F MO;Lo;0;L;;;;;N;;;;;
+16A34;BAMUM LETTER PHASE-F MBAA;Lo;0;L;;;;;N;;;;;
+16A35;BAMUM LETTER PHASE-F TET;Lo;0;L;;;;;N;;;;;
+16A36;BAMUM LETTER PHASE-F KPA;Lo;0;L;;;;;N;;;;;
+16A37;BAMUM LETTER PHASE-F SAMBA;Lo;0;L;;;;;N;;;;;
+16A38;BAMUM LETTER PHASE-F VUEQ;Lo;0;L;;;;;N;;;;;
+1B000;KATAKANA LETTER ARCHAIC E;Lo;0;L;;;;;N;;;;;
+1B001;HIRAGANA LETTER ARCHAIC YE;Lo;0;L;;;;;N;;;;;
+1D000;BYZANTINE MUSICAL SYMBOL PSILI;So;0;L;;;;;N;;;;;
+1D001;BYZANTINE MUSICAL SYMBOL DASEIA;So;0;L;;;;;N;;;;;
+1D002;BYZANTINE MUSICAL SYMBOL PERISPOMENI;So;0;L;;;;;N;;;;;
+1D003;BYZANTINE MUSICAL SYMBOL OXEIA EKFONITIKON;So;0;L;;;;;N;;;;;
+1D004;BYZANTINE MUSICAL SYMBOL OXEIA DIPLI;So;0;L;;;;;N;;;;;
+1D005;BYZANTINE MUSICAL SYMBOL VAREIA EKFONITIKON;So;0;L;;;;;N;;;;;
+1D006;BYZANTINE MUSICAL SYMBOL VAREIA DIPLI;So;0;L;;;;;N;;;;;
+1D007;BYZANTINE MUSICAL SYMBOL KATHISTI;So;0;L;;;;;N;;;;;
+1D008;BYZANTINE MUSICAL SYMBOL SYRMATIKI;So;0;L;;;;;N;;;;;
+1D009;BYZANTINE MUSICAL SYMBOL PARAKLITIKI;So;0;L;;;;;N;;;;;
+1D00A;BYZANTINE MUSICAL SYMBOL YPOKRISIS;So;0;L;;;;;N;;;;;
+1D00B;BYZANTINE MUSICAL SYMBOL YPOKRISIS DIPLI;So;0;L;;;;;N;;;;;
+1D00C;BYZANTINE MUSICAL SYMBOL KREMASTI;So;0;L;;;;;N;;;;;
+1D00D;BYZANTINE MUSICAL SYMBOL APESO EKFONITIKON;So;0;L;;;;;N;;;;;
+1D00E;BYZANTINE MUSICAL SYMBOL EXO EKFONITIKON;So;0;L;;;;;N;;;;;
+1D00F;BYZANTINE MUSICAL SYMBOL TELEIA;So;0;L;;;;;N;;;;;
+1D010;BYZANTINE MUSICAL SYMBOL KENTIMATA;So;0;L;;;;;N;;;;;
+1D011;BYZANTINE MUSICAL SYMBOL APOSTROFOS;So;0;L;;;;;N;;;;;
+1D012;BYZANTINE MUSICAL SYMBOL APOSTROFOS DIPLI;So;0;L;;;;;N;;;;;
+1D013;BYZANTINE MUSICAL SYMBOL SYNEVMA;So;0;L;;;;;N;;;;;
+1D014;BYZANTINE MUSICAL SYMBOL THITA;So;0;L;;;;;N;;;;;
+1D015;BYZANTINE MUSICAL SYMBOL OLIGON ARCHAION;So;0;L;;;;;N;;;;;
+1D016;BYZANTINE MUSICAL SYMBOL GORGON ARCHAION;So;0;L;;;;;N;;;;;
+1D017;BYZANTINE MUSICAL SYMBOL PSILON;So;0;L;;;;;N;;;;;
+1D018;BYZANTINE MUSICAL SYMBOL CHAMILON;So;0;L;;;;;N;;;;;
+1D019;BYZANTINE MUSICAL SYMBOL VATHY;So;0;L;;;;;N;;;;;
+1D01A;BYZANTINE MUSICAL SYMBOL ISON ARCHAION;So;0;L;;;;;N;;;;;
+1D01B;BYZANTINE MUSICAL SYMBOL KENTIMA ARCHAION;So;0;L;;;;;N;;;;;
+1D01C;BYZANTINE MUSICAL SYMBOL KENTIMATA ARCHAION;So;0;L;;;;;N;;;;;
+1D01D;BYZANTINE MUSICAL SYMBOL SAXIMATA;So;0;L;;;;;N;;;;;
+1D01E;BYZANTINE MUSICAL SYMBOL PARICHON;So;0;L;;;;;N;;;;;
+1D01F;BYZANTINE MUSICAL SYMBOL STAVROS APODEXIA;So;0;L;;;;;N;;;;;
+1D020;BYZANTINE MUSICAL SYMBOL OXEIAI ARCHAION;So;0;L;;;;;N;;;;;
+1D021;BYZANTINE MUSICAL SYMBOL VAREIAI ARCHAION;So;0;L;;;;;N;;;;;
+1D022;BYZANTINE MUSICAL SYMBOL APODERMA ARCHAION;So;0;L;;;;;N;;;;;
+1D023;BYZANTINE MUSICAL SYMBOL APOTHEMA;So;0;L;;;;;N;;;;;
+1D024;BYZANTINE MUSICAL SYMBOL KLASMA;So;0;L;;;;;N;;;;;
+1D025;BYZANTINE MUSICAL SYMBOL REVMA;So;0;L;;;;;N;;;;;
+1D026;BYZANTINE MUSICAL SYMBOL PIASMA ARCHAION;So;0;L;;;;;N;;;;;
+1D027;BYZANTINE MUSICAL SYMBOL TINAGMA;So;0;L;;;;;N;;;;;
+1D028;BYZANTINE MUSICAL SYMBOL ANATRICHISMA;So;0;L;;;;;N;;;;;
+1D029;BYZANTINE MUSICAL SYMBOL SEISMA;So;0;L;;;;;N;;;;;
+1D02A;BYZANTINE MUSICAL SYMBOL SYNAGMA ARCHAION;So;0;L;;;;;N;;;;;
+1D02B;BYZANTINE MUSICAL SYMBOL SYNAGMA META STAVROU;So;0;L;;;;;N;;;;;
+1D02C;BYZANTINE MUSICAL SYMBOL OYRANISMA ARCHAION;So;0;L;;;;;N;;;;;
+1D02D;BYZANTINE MUSICAL SYMBOL THEMA;So;0;L;;;;;N;;;;;
+1D02E;BYZANTINE MUSICAL SYMBOL LEMOI;So;0;L;;;;;N;;;;;
+1D02F;BYZANTINE MUSICAL SYMBOL DYO;So;0;L;;;;;N;;;;;
+1D030;BYZANTINE MUSICAL SYMBOL TRIA;So;0;L;;;;;N;;;;;
+1D031;BYZANTINE MUSICAL SYMBOL TESSERA;So;0;L;;;;;N;;;;;
+1D032;BYZANTINE MUSICAL SYMBOL KRATIMATA;So;0;L;;;;;N;;;;;
+1D033;BYZANTINE MUSICAL SYMBOL APESO EXO NEO;So;0;L;;;;;N;;;;;
+1D034;BYZANTINE MUSICAL SYMBOL FTHORA ARCHAION;So;0;L;;;;;N;;;;;
+1D035;BYZANTINE MUSICAL SYMBOL IMIFTHORA;So;0;L;;;;;N;;;;;
+1D036;BYZANTINE MUSICAL SYMBOL TROMIKON ARCHAION;So;0;L;;;;;N;;;;;
+1D037;BYZANTINE MUSICAL SYMBOL KATAVA TROMIKON;So;0;L;;;;;N;;;;;
+1D038;BYZANTINE MUSICAL SYMBOL PELASTON;So;0;L;;;;;N;;;;;
+1D039;BYZANTINE MUSICAL SYMBOL PSIFISTON;So;0;L;;;;;N;;;;;
+1D03A;BYZANTINE MUSICAL SYMBOL KONTEVMA;So;0;L;;;;;N;;;;;
+1D03B;BYZANTINE MUSICAL SYMBOL CHOREVMA ARCHAION;So;0;L;;;;;N;;;;;
+1D03C;BYZANTINE MUSICAL SYMBOL RAPISMA;So;0;L;;;;;N;;;;;
+1D03D;BYZANTINE MUSICAL SYMBOL PARAKALESMA ARCHAION;So;0;L;;;;;N;;;;;
+1D03E;BYZANTINE MUSICAL SYMBOL PARAKLITIKI ARCHAION;So;0;L;;;;;N;;;;;
+1D03F;BYZANTINE MUSICAL SYMBOL ICHADIN;So;0;L;;;;;N;;;;;
+1D040;BYZANTINE MUSICAL SYMBOL NANA;So;0;L;;;;;N;;;;;
+1D041;BYZANTINE MUSICAL SYMBOL PETASMA;So;0;L;;;;;N;;;;;
+1D042;BYZANTINE MUSICAL SYMBOL KONTEVMA ALLO;So;0;L;;;;;N;;;;;
+1D043;BYZANTINE MUSICAL SYMBOL TROMIKON ALLO;So;0;L;;;;;N;;;;;
+1D044;BYZANTINE MUSICAL SYMBOL STRAGGISMATA;So;0;L;;;;;N;;;;;
+1D045;BYZANTINE MUSICAL SYMBOL GRONTHISMATA;So;0;L;;;;;N;;;;;
+1D046;BYZANTINE MUSICAL SYMBOL ISON NEO;So;0;L;;;;;N;;;;;
+1D047;BYZANTINE MUSICAL SYMBOL OLIGON NEO;So;0;L;;;;;N;;;;;
+1D048;BYZANTINE MUSICAL SYMBOL OXEIA NEO;So;0;L;;;;;N;;;;;
+1D049;BYZANTINE MUSICAL SYMBOL PETASTI;So;0;L;;;;;N;;;;;
+1D04A;BYZANTINE MUSICAL SYMBOL KOUFISMA;So;0;L;;;;;N;;;;;
+1D04B;BYZANTINE MUSICAL SYMBOL PETASTOKOUFISMA;So;0;L;;;;;N;;;;;
+1D04C;BYZANTINE MUSICAL SYMBOL KRATIMOKOUFISMA;So;0;L;;;;;N;;;;;
+1D04D;BYZANTINE MUSICAL SYMBOL PELASTON NEO;So;0;L;;;;;N;;;;;
+1D04E;BYZANTINE MUSICAL SYMBOL KENTIMATA NEO ANO;So;0;L;;;;;N;;;;;
+1D04F;BYZANTINE MUSICAL SYMBOL KENTIMA NEO ANO;So;0;L;;;;;N;;;;;
+1D050;BYZANTINE MUSICAL SYMBOL YPSILI;So;0;L;;;;;N;;;;;
+1D051;BYZANTINE MUSICAL SYMBOL APOSTROFOS NEO;So;0;L;;;;;N;;;;;
+1D052;BYZANTINE MUSICAL SYMBOL APOSTROFOI SYNDESMOS NEO;So;0;L;;;;;N;;;;;
+1D053;BYZANTINE MUSICAL SYMBOL YPORROI;So;0;L;;;;;N;;;;;
+1D054;BYZANTINE MUSICAL SYMBOL KRATIMOYPORROON;So;0;L;;;;;N;;;;;
+1D055;BYZANTINE MUSICAL SYMBOL ELAFRON;So;0;L;;;;;N;;;;;
+1D056;BYZANTINE MUSICAL SYMBOL CHAMILI;So;0;L;;;;;N;;;;;
+1D057;BYZANTINE MUSICAL SYMBOL MIKRON ISON;So;0;L;;;;;N;;;;;
+1D058;BYZANTINE MUSICAL SYMBOL VAREIA NEO;So;0;L;;;;;N;;;;;
+1D059;BYZANTINE MUSICAL SYMBOL PIASMA NEO;So;0;L;;;;;N;;;;;
+1D05A;BYZANTINE MUSICAL SYMBOL PSIFISTON NEO;So;0;L;;;;;N;;;;;
+1D05B;BYZANTINE MUSICAL SYMBOL OMALON;So;0;L;;;;;N;;;;;
+1D05C;BYZANTINE MUSICAL SYMBOL ANTIKENOMA;So;0;L;;;;;N;;;;;
+1D05D;BYZANTINE MUSICAL SYMBOL LYGISMA;So;0;L;;;;;N;;;;;
+1D05E;BYZANTINE MUSICAL SYMBOL PARAKLITIKI NEO;So;0;L;;;;;N;;;;;
+1D05F;BYZANTINE MUSICAL SYMBOL PARAKALESMA NEO;So;0;L;;;;;N;;;;;
+1D060;BYZANTINE MUSICAL SYMBOL ETERON PARAKALESMA;So;0;L;;;;;N;;;;;
+1D061;BYZANTINE MUSICAL SYMBOL KYLISMA;So;0;L;;;;;N;;;;;
+1D062;BYZANTINE MUSICAL SYMBOL ANTIKENOKYLISMA;So;0;L;;;;;N;;;;;
+1D063;BYZANTINE MUSICAL SYMBOL TROMIKON NEO;So;0;L;;;;;N;;;;;
+1D064;BYZANTINE MUSICAL SYMBOL EKSTREPTON;So;0;L;;;;;N;;;;;
+1D065;BYZANTINE MUSICAL SYMBOL SYNAGMA NEO;So;0;L;;;;;N;;;;;
+1D066;BYZANTINE MUSICAL SYMBOL SYRMA;So;0;L;;;;;N;;;;;
+1D067;BYZANTINE MUSICAL SYMBOL CHOREVMA NEO;So;0;L;;;;;N;;;;;
+1D068;BYZANTINE MUSICAL SYMBOL EPEGERMA;So;0;L;;;;;N;;;;;
+1D069;BYZANTINE MUSICAL SYMBOL SEISMA NEO;So;0;L;;;;;N;;;;;
+1D06A;BYZANTINE MUSICAL SYMBOL XIRON KLASMA;So;0;L;;;;;N;;;;;
+1D06B;BYZANTINE MUSICAL SYMBOL TROMIKOPSIFISTON;So;0;L;;;;;N;;;;;
+1D06C;BYZANTINE MUSICAL SYMBOL PSIFISTOLYGISMA;So;0;L;;;;;N;;;;;
+1D06D;BYZANTINE MUSICAL SYMBOL TROMIKOLYGISMA;So;0;L;;;;;N;;;;;
+1D06E;BYZANTINE MUSICAL SYMBOL TROMIKOPARAKALESMA;So;0;L;;;;;N;;;;;
+1D06F;BYZANTINE MUSICAL SYMBOL PSIFISTOPARAKALESMA;So;0;L;;;;;N;;;;;
+1D070;BYZANTINE MUSICAL SYMBOL TROMIKOSYNAGMA;So;0;L;;;;;N;;;;;
+1D071;BYZANTINE MUSICAL SYMBOL PSIFISTOSYNAGMA;So;0;L;;;;;N;;;;;
+1D072;BYZANTINE MUSICAL SYMBOL GORGOSYNTHETON;So;0;L;;;;;N;;;;;
+1D073;BYZANTINE MUSICAL SYMBOL ARGOSYNTHETON;So;0;L;;;;;N;;;;;
+1D074;BYZANTINE MUSICAL SYMBOL ETERON ARGOSYNTHETON;So;0;L;;;;;N;;;;;
+1D075;BYZANTINE MUSICAL SYMBOL OYRANISMA NEO;So;0;L;;;;;N;;;;;
+1D076;BYZANTINE MUSICAL SYMBOL THEMATISMOS ESO;So;0;L;;;;;N;;;;;
+1D077;BYZANTINE MUSICAL SYMBOL THEMATISMOS EXO;So;0;L;;;;;N;;;;;
+1D078;BYZANTINE MUSICAL SYMBOL THEMA APLOUN;So;0;L;;;;;N;;;;;
+1D079;BYZANTINE MUSICAL SYMBOL THES KAI APOTHES;So;0;L;;;;;N;;;;;
+1D07A;BYZANTINE MUSICAL SYMBOL KATAVASMA;So;0;L;;;;;N;;;;;
+1D07B;BYZANTINE MUSICAL SYMBOL ENDOFONON;So;0;L;;;;;N;;;;;
+1D07C;BYZANTINE MUSICAL SYMBOL YFEN KATO;So;0;L;;;;;N;;;;;
+1D07D;BYZANTINE MUSICAL SYMBOL YFEN ANO;So;0;L;;;;;N;;;;;
+1D07E;BYZANTINE MUSICAL SYMBOL STAVROS;So;0;L;;;;;N;;;;;
+1D07F;BYZANTINE MUSICAL SYMBOL KLASMA ANO;So;0;L;;;;;N;;;;;
+1D080;BYZANTINE MUSICAL SYMBOL DIPLI ARCHAION;So;0;L;;;;;N;;;;;
+1D081;BYZANTINE MUSICAL SYMBOL KRATIMA ARCHAION;So;0;L;;;;;N;;;;;
+1D082;BYZANTINE MUSICAL SYMBOL KRATIMA ALLO;So;0;L;;;;;N;;;;;
+1D083;BYZANTINE MUSICAL SYMBOL KRATIMA NEO;So;0;L;;;;;N;;;;;
+1D084;BYZANTINE MUSICAL SYMBOL APODERMA NEO;So;0;L;;;;;N;;;;;
+1D085;BYZANTINE MUSICAL SYMBOL APLI;So;0;L;;;;;N;;;;;
+1D086;BYZANTINE MUSICAL SYMBOL DIPLI;So;0;L;;;;;N;;;;;
+1D087;BYZANTINE MUSICAL SYMBOL TRIPLI;So;0;L;;;;;N;;;;;
+1D088;BYZANTINE MUSICAL SYMBOL TETRAPLI;So;0;L;;;;;N;;;;;
+1D089;BYZANTINE MUSICAL SYMBOL KORONIS;So;0;L;;;;;N;;;;;
+1D08A;BYZANTINE MUSICAL SYMBOL LEIMMA ENOS CHRONOU;So;0;L;;;;;N;;;;;
+1D08B;BYZANTINE MUSICAL SYMBOL LEIMMA DYO CHRONON;So;0;L;;;;;N;;;;;
+1D08C;BYZANTINE MUSICAL SYMBOL LEIMMA TRION CHRONON;So;0;L;;;;;N;;;;;
+1D08D;BYZANTINE MUSICAL SYMBOL LEIMMA TESSARON CHRONON;So;0;L;;;;;N;;;;;
+1D08E;BYZANTINE MUSICAL SYMBOL LEIMMA IMISEOS CHRONOU;So;0;L;;;;;N;;;;;
+1D08F;BYZANTINE MUSICAL SYMBOL GORGON NEO ANO;So;0;L;;;;;N;;;;;
+1D090;BYZANTINE MUSICAL SYMBOL GORGON PARESTIGMENON ARISTERA;So;0;L;;;;;N;;;;;
+1D091;BYZANTINE MUSICAL SYMBOL GORGON PARESTIGMENON DEXIA;So;0;L;;;;;N;;;;;
+1D092;BYZANTINE MUSICAL SYMBOL DIGORGON;So;0;L;;;;;N;;;;;
+1D093;BYZANTINE MUSICAL SYMBOL DIGORGON PARESTIGMENON ARISTERA KATO;So;0;L;;;;;N;;;;;
+1D094;BYZANTINE MUSICAL SYMBOL DIGORGON PARESTIGMENON ARISTERA ANO;So;0;L;;;;;N;;;;;
+1D095;BYZANTINE MUSICAL SYMBOL DIGORGON PARESTIGMENON DEXIA;So;0;L;;;;;N;;;;;
+1D096;BYZANTINE MUSICAL SYMBOL TRIGORGON;So;0;L;;;;;N;;;;;
+1D097;BYZANTINE MUSICAL SYMBOL ARGON;So;0;L;;;;;N;;;;;
+1D098;BYZANTINE MUSICAL SYMBOL IMIDIARGON;So;0;L;;;;;N;;;;;
+1D099;BYZANTINE MUSICAL SYMBOL DIARGON;So;0;L;;;;;N;;;;;
+1D09A;BYZANTINE MUSICAL SYMBOL AGOGI POLI ARGI;So;0;L;;;;;N;;;;;
+1D09B;BYZANTINE MUSICAL SYMBOL AGOGI ARGOTERI;So;0;L;;;;;N;;;;;
+1D09C;BYZANTINE MUSICAL SYMBOL AGOGI ARGI;So;0;L;;;;;N;;;;;
+1D09D;BYZANTINE MUSICAL SYMBOL AGOGI METRIA;So;0;L;;;;;N;;;;;
+1D09E;BYZANTINE MUSICAL SYMBOL AGOGI MESI;So;0;L;;;;;N;;;;;
+1D09F;BYZANTINE MUSICAL SYMBOL AGOGI GORGI;So;0;L;;;;;N;;;;;
+1D0A0;BYZANTINE MUSICAL SYMBOL AGOGI GORGOTERI;So;0;L;;;;;N;;;;;
+1D0A1;BYZANTINE MUSICAL SYMBOL AGOGI POLI GORGI;So;0;L;;;;;N;;;;;
+1D0A2;BYZANTINE MUSICAL SYMBOL MARTYRIA PROTOS ICHOS;So;0;L;;;;;N;;;;;
+1D0A3;BYZANTINE MUSICAL SYMBOL MARTYRIA ALLI PROTOS ICHOS;So;0;L;;;;;N;;;;;
+1D0A4;BYZANTINE MUSICAL SYMBOL MARTYRIA DEYTEROS ICHOS;So;0;L;;;;;N;;;;;
+1D0A5;BYZANTINE MUSICAL SYMBOL MARTYRIA ALLI DEYTEROS ICHOS;So;0;L;;;;;N;;;;;
+1D0A6;BYZANTINE MUSICAL SYMBOL MARTYRIA TRITOS ICHOS;So;0;L;;;;;N;;;;;
+1D0A7;BYZANTINE MUSICAL SYMBOL MARTYRIA TRIFONIAS;So;0;L;;;;;N;;;;;
+1D0A8;BYZANTINE MUSICAL SYMBOL MARTYRIA TETARTOS ICHOS;So;0;L;;;;;N;;;;;
+1D0A9;BYZANTINE MUSICAL SYMBOL MARTYRIA TETARTOS LEGETOS ICHOS;So;0;L;;;;;N;;;;;
+1D0AA;BYZANTINE MUSICAL SYMBOL MARTYRIA LEGETOS ICHOS;So;0;L;;;;;N;;;;;
+1D0AB;BYZANTINE MUSICAL SYMBOL MARTYRIA PLAGIOS ICHOS;So;0;L;;;;;N;;;;;
+1D0AC;BYZANTINE MUSICAL SYMBOL ISAKIA TELOUS ICHIMATOS;So;0;L;;;;;N;;;;;
+1D0AD;BYZANTINE MUSICAL SYMBOL APOSTROFOI TELOUS ICHIMATOS;So;0;L;;;;;N;;;;;
+1D0AE;BYZANTINE MUSICAL SYMBOL FANEROSIS TETRAFONIAS;So;0;L;;;;;N;;;;;
+1D0AF;BYZANTINE MUSICAL SYMBOL FANEROSIS MONOFONIAS;So;0;L;;;;;N;;;;;
+1D0B0;BYZANTINE MUSICAL SYMBOL FANEROSIS DIFONIAS;So;0;L;;;;;N;;;;;
+1D0B1;BYZANTINE MUSICAL SYMBOL MARTYRIA VARYS ICHOS;So;0;L;;;;;N;;;;;
+1D0B2;BYZANTINE MUSICAL SYMBOL MARTYRIA PROTOVARYS ICHOS;So;0;L;;;;;N;;;;;
+1D0B3;BYZANTINE MUSICAL SYMBOL MARTYRIA PLAGIOS TETARTOS ICHOS;So;0;L;;;;;N;;;;;
+1D0B4;BYZANTINE MUSICAL SYMBOL GORTHMIKON N APLOUN;So;0;L;;;;;N;;;;;
+1D0B5;BYZANTINE MUSICAL SYMBOL GORTHMIKON N DIPLOUN;So;0;L;;;;;N;;;;;
+1D0B6;BYZANTINE MUSICAL SYMBOL ENARXIS KAI FTHORA VOU;So;0;L;;;;;N;;;;;
+1D0B7;BYZANTINE MUSICAL SYMBOL IMIFONON;So;0;L;;;;;N;;;;;
+1D0B8;BYZANTINE MUSICAL SYMBOL IMIFTHORON;So;0;L;;;;;N;;;;;
+1D0B9;BYZANTINE MUSICAL SYMBOL FTHORA ARCHAION DEYTEROU ICHOU;So;0;L;;;;;N;;;;;
+1D0BA;BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI PA;So;0;L;;;;;N;;;;;
+1D0BB;BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI NANA;So;0;L;;;;;N;;;;;
+1D0BC;BYZANTINE MUSICAL SYMBOL FTHORA NAOS ICHOS;So;0;L;;;;;N;;;;;
+1D0BD;BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI DI;So;0;L;;;;;N;;;;;
+1D0BE;BYZANTINE MUSICAL SYMBOL FTHORA SKLIRON DIATONON DI;So;0;L;;;;;N;;;;;
+1D0BF;BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI KE;So;0;L;;;;;N;;;;;
+1D0C0;BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI ZO;So;0;L;;;;;N;;;;;
+1D0C1;BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI NI KATO;So;0;L;;;;;N;;;;;
+1D0C2;BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI NI ANO;So;0;L;;;;;N;;;;;
+1D0C3;BYZANTINE MUSICAL SYMBOL FTHORA MALAKON CHROMA DIFONIAS;So;0;L;;;;;N;;;;;
+1D0C4;BYZANTINE MUSICAL SYMBOL FTHORA MALAKON CHROMA MONOFONIAS;So;0;L;;;;;N;;;;;
+1D0C5;BYZANTINE MUSICAL SYMBOL FHTORA SKLIRON CHROMA VASIS;So;0;L;;;;;N;;;;;
+1D0C6;BYZANTINE MUSICAL SYMBOL FTHORA SKLIRON CHROMA SYNAFI;So;0;L;;;;;N;;;;;
+1D0C7;BYZANTINE MUSICAL SYMBOL FTHORA NENANO;So;0;L;;;;;N;;;;;
+1D0C8;BYZANTINE MUSICAL SYMBOL CHROA ZYGOS;So;0;L;;;;;N;;;;;
+1D0C9;BYZANTINE MUSICAL SYMBOL CHROA KLITON;So;0;L;;;;;N;;;;;
+1D0CA;BYZANTINE MUSICAL SYMBOL CHROA SPATHI;So;0;L;;;;;N;;;;;
+1D0CB;BYZANTINE MUSICAL SYMBOL FTHORA I YFESIS TETARTIMORION;So;0;L;;;;;N;;;;;
+1D0CC;BYZANTINE MUSICAL SYMBOL FTHORA ENARMONIOS ANTIFONIA;So;0;L;;;;;N;;;;;
+1D0CD;BYZANTINE MUSICAL SYMBOL YFESIS TRITIMORION;So;0;L;;;;;N;;;;;
+1D0CE;BYZANTINE MUSICAL SYMBOL DIESIS TRITIMORION;So;0;L;;;;;N;;;;;
+1D0CF;BYZANTINE MUSICAL SYMBOL DIESIS TETARTIMORION;So;0;L;;;;;N;;;;;
+1D0D0;BYZANTINE MUSICAL SYMBOL DIESIS APLI DYO DODEKATA;So;0;L;;;;;N;;;;;
+1D0D1;BYZANTINE MUSICAL SYMBOL DIESIS MONOGRAMMOS TESSERA DODEKATA;So;0;L;;;;;N;;;;;
+1D0D2;BYZANTINE MUSICAL SYMBOL DIESIS DIGRAMMOS EX DODEKATA;So;0;L;;;;;N;;;;;
+1D0D3;BYZANTINE MUSICAL SYMBOL DIESIS TRIGRAMMOS OKTO DODEKATA;So;0;L;;;;;N;;;;;
+1D0D4;BYZANTINE MUSICAL SYMBOL YFESIS APLI DYO DODEKATA;So;0;L;;;;;N;;;;;
+1D0D5;BYZANTINE MUSICAL SYMBOL YFESIS MONOGRAMMOS TESSERA DODEKATA;So;0;L;;;;;N;;;;;
+1D0D6;BYZANTINE MUSICAL SYMBOL YFESIS DIGRAMMOS EX DODEKATA;So;0;L;;;;;N;;;;;
+1D0D7;BYZANTINE MUSICAL SYMBOL YFESIS TRIGRAMMOS OKTO DODEKATA;So;0;L;;;;;N;;;;;
+1D0D8;BYZANTINE MUSICAL SYMBOL GENIKI DIESIS;So;0;L;;;;;N;;;;;
+1D0D9;BYZANTINE MUSICAL SYMBOL GENIKI YFESIS;So;0;L;;;;;N;;;;;
+1D0DA;BYZANTINE MUSICAL SYMBOL DIASTOLI APLI MIKRI;So;0;L;;;;;N;;;;;
+1D0DB;BYZANTINE MUSICAL SYMBOL DIASTOLI APLI MEGALI;So;0;L;;;;;N;;;;;
+1D0DC;BYZANTINE MUSICAL SYMBOL DIASTOLI DIPLI;So;0;L;;;;;N;;;;;
+1D0DD;BYZANTINE MUSICAL SYMBOL DIASTOLI THESEOS;So;0;L;;;;;N;;;;;
+1D0DE;BYZANTINE MUSICAL SYMBOL SIMANSIS THESEOS;So;0;L;;;;;N;;;;;
+1D0DF;BYZANTINE MUSICAL SYMBOL SIMANSIS THESEOS DISIMOU;So;0;L;;;;;N;;;;;
+1D0E0;BYZANTINE MUSICAL SYMBOL SIMANSIS THESEOS TRISIMOU;So;0;L;;;;;N;;;;;
+1D0E1;BYZANTINE MUSICAL SYMBOL SIMANSIS THESEOS TETRASIMOU;So;0;L;;;;;N;;;;;
+1D0E2;BYZANTINE MUSICAL SYMBOL SIMANSIS ARSEOS;So;0;L;;;;;N;;;;;
+1D0E3;BYZANTINE MUSICAL SYMBOL SIMANSIS ARSEOS DISIMOU;So;0;L;;;;;N;;;;;
+1D0E4;BYZANTINE MUSICAL SYMBOL SIMANSIS ARSEOS TRISIMOU;So;0;L;;;;;N;;;;;
+1D0E5;BYZANTINE MUSICAL SYMBOL SIMANSIS ARSEOS TETRASIMOU;So;0;L;;;;;N;;;;;
+1D0E6;BYZANTINE MUSICAL SYMBOL DIGRAMMA GG;So;0;L;;;;;N;;;;;
+1D0E7;BYZANTINE MUSICAL SYMBOL DIFTOGGOS OU;So;0;L;;;;;N;;;;;
+1D0E8;BYZANTINE MUSICAL SYMBOL STIGMA;So;0;L;;;;;N;;;;;
+1D0E9;BYZANTINE MUSICAL SYMBOL ARKTIKO PA;So;0;L;;;;;N;;;;;
+1D0EA;BYZANTINE MUSICAL SYMBOL ARKTIKO VOU;So;0;L;;;;;N;;;;;
+1D0EB;BYZANTINE MUSICAL SYMBOL ARKTIKO GA;So;0;L;;;;;N;;;;;
+1D0EC;BYZANTINE MUSICAL SYMBOL ARKTIKO DI;So;0;L;;;;;N;;;;;
+1D0ED;BYZANTINE MUSICAL SYMBOL ARKTIKO KE;So;0;L;;;;;N;;;;;
+1D0EE;BYZANTINE MUSICAL SYMBOL ARKTIKO ZO;So;0;L;;;;;N;;;;;
+1D0EF;BYZANTINE MUSICAL SYMBOL ARKTIKO NI;So;0;L;;;;;N;;;;;
+1D0F0;BYZANTINE MUSICAL SYMBOL KENTIMATA NEO MESO;So;0;L;;;;;N;;;;;
+1D0F1;BYZANTINE MUSICAL SYMBOL KENTIMA NEO MESO;So;0;L;;;;;N;;;;;
+1D0F2;BYZANTINE MUSICAL SYMBOL KENTIMATA NEO KATO;So;0;L;;;;;N;;;;;
+1D0F3;BYZANTINE MUSICAL SYMBOL KENTIMA NEO KATO;So;0;L;;;;;N;;;;;
+1D0F4;BYZANTINE MUSICAL SYMBOL KLASMA KATO;So;0;L;;;;;N;;;;;
+1D0F5;BYZANTINE MUSICAL SYMBOL GORGON NEO KATO;So;0;L;;;;;N;;;;;
+1D100;MUSICAL SYMBOL SINGLE BARLINE;So;0;L;;;;;N;;;;;
+1D101;MUSICAL SYMBOL DOUBLE BARLINE;So;0;L;;;;;N;;;;;
+1D102;MUSICAL SYMBOL FINAL BARLINE;So;0;L;;;;;N;;;;;
+1D103;MUSICAL SYMBOL REVERSE FINAL BARLINE;So;0;L;;;;;N;;;;;
+1D104;MUSICAL SYMBOL DASHED BARLINE;So;0;L;;;;;N;;;;;
+1D105;MUSICAL SYMBOL SHORT BARLINE;So;0;L;;;;;N;;;;;
+1D106;MUSICAL SYMBOL LEFT REPEAT SIGN;So;0;L;;;;;N;;;;;
+1D107;MUSICAL SYMBOL RIGHT REPEAT SIGN;So;0;L;;;;;N;;;;;
+1D108;MUSICAL SYMBOL REPEAT DOTS;So;0;L;;;;;N;;;;;
+1D109;MUSICAL SYMBOL DAL SEGNO;So;0;L;;;;;N;;;;;
+1D10A;MUSICAL SYMBOL DA CAPO;So;0;L;;;;;N;;;;;
+1D10B;MUSICAL SYMBOL SEGNO;So;0;L;;;;;N;;;;;
+1D10C;MUSICAL SYMBOL CODA;So;0;L;;;;;N;;;;;
+1D10D;MUSICAL SYMBOL REPEATED FIGURE-1;So;0;L;;;;;N;;;;;
+1D10E;MUSICAL SYMBOL REPEATED FIGURE-2;So;0;L;;;;;N;;;;;
+1D10F;MUSICAL SYMBOL REPEATED FIGURE-3;So;0;L;;;;;N;;;;;
+1D110;MUSICAL SYMBOL FERMATA;So;0;L;;;;;N;;;;;
+1D111;MUSICAL SYMBOL FERMATA BELOW;So;0;L;;;;;N;;;;;
+1D112;MUSICAL SYMBOL BREATH MARK;So;0;L;;;;;N;;;;;
+1D113;MUSICAL SYMBOL CAESURA;So;0;L;;;;;N;;;;;
+1D114;MUSICAL SYMBOL BRACE;So;0;L;;;;;N;;;;;
+1D115;MUSICAL SYMBOL BRACKET;So;0;L;;;;;N;;;;;
+1D116;MUSICAL SYMBOL ONE-LINE STAFF;So;0;L;;;;;N;;;;;
+1D117;MUSICAL SYMBOL TWO-LINE STAFF;So;0;L;;;;;N;;;;;
+1D118;MUSICAL SYMBOL THREE-LINE STAFF;So;0;L;;;;;N;;;;;
+1D119;MUSICAL SYMBOL FOUR-LINE STAFF;So;0;L;;;;;N;;;;;
+1D11A;MUSICAL SYMBOL FIVE-LINE STAFF;So;0;L;;;;;N;;;;;
+1D11B;MUSICAL SYMBOL SIX-LINE STAFF;So;0;L;;;;;N;;;;;
+1D11C;MUSICAL SYMBOL SIX-STRING FRETBOARD;So;0;L;;;;;N;;;;;
+1D11D;MUSICAL SYMBOL FOUR-STRING FRETBOARD;So;0;L;;;;;N;;;;;
+1D11E;MUSICAL SYMBOL G CLEF;So;0;L;;;;;N;;;;;
+1D11F;MUSICAL SYMBOL G CLEF OTTAVA ALTA;So;0;L;;;;;N;;;;;
+1D120;MUSICAL SYMBOL G CLEF OTTAVA BASSA;So;0;L;;;;;N;;;;;
+1D121;MUSICAL SYMBOL C CLEF;So;0;L;;;;;N;;;;;
+1D122;MUSICAL SYMBOL F CLEF;So;0;L;;;;;N;;;;;
+1D123;MUSICAL SYMBOL F CLEF OTTAVA ALTA;So;0;L;;;;;N;;;;;
+1D124;MUSICAL SYMBOL F CLEF OTTAVA BASSA;So;0;L;;;;;N;;;;;
+1D125;MUSICAL SYMBOL DRUM CLEF-1;So;0;L;;;;;N;;;;;
+1D126;MUSICAL SYMBOL DRUM CLEF-2;So;0;L;;;;;N;;;;;
+1D129;MUSICAL SYMBOL MULTIPLE MEASURE REST;So;0;L;;;;;N;;;;;
+1D12A;MUSICAL SYMBOL DOUBLE SHARP;So;0;L;;;;;N;;;;;
+1D12B;MUSICAL SYMBOL DOUBLE FLAT;So;0;L;;;;;N;;;;;
+1D12C;MUSICAL SYMBOL FLAT UP;So;0;L;;;;;N;;;;;
+1D12D;MUSICAL SYMBOL FLAT DOWN;So;0;L;;;;;N;;;;;
+1D12E;MUSICAL SYMBOL NATURAL UP;So;0;L;;;;;N;;;;;
+1D12F;MUSICAL SYMBOL NATURAL DOWN;So;0;L;;;;;N;;;;;
+1D130;MUSICAL SYMBOL SHARP UP;So;0;L;;;;;N;;;;;
+1D131;MUSICAL SYMBOL SHARP DOWN;So;0;L;;;;;N;;;;;
+1D132;MUSICAL SYMBOL QUARTER TONE SHARP;So;0;L;;;;;N;;;;;
+1D133;MUSICAL SYMBOL QUARTER TONE FLAT;So;0;L;;;;;N;;;;;
+1D134;MUSICAL SYMBOL COMMON TIME;So;0;L;;;;;N;;;;;
+1D135;MUSICAL SYMBOL CUT TIME;So;0;L;;;;;N;;;;;
+1D136;MUSICAL SYMBOL OTTAVA ALTA;So;0;L;;;;;N;;;;;
+1D137;MUSICAL SYMBOL OTTAVA BASSA;So;0;L;;;;;N;;;;;
+1D138;MUSICAL SYMBOL QUINDICESIMA ALTA;So;0;L;;;;;N;;;;;
+1D139;MUSICAL SYMBOL QUINDICESIMA BASSA;So;0;L;;;;;N;;;;;
+1D13A;MUSICAL SYMBOL MULTI REST;So;0;L;;;;;N;;;;;
+1D13B;MUSICAL SYMBOL WHOLE REST;So;0;L;;;;;N;;;;;
+1D13C;MUSICAL SYMBOL HALF REST;So;0;L;;;;;N;;;;;
+1D13D;MUSICAL SYMBOL QUARTER REST;So;0;L;;;;;N;;;;;
+1D13E;MUSICAL SYMBOL EIGHTH REST;So;0;L;;;;;N;;;;;
+1D13F;MUSICAL SYMBOL SIXTEENTH REST;So;0;L;;;;;N;;;;;
+1D140;MUSICAL SYMBOL THIRTY-SECOND REST;So;0;L;;;;;N;;;;;
+1D141;MUSICAL SYMBOL SIXTY-FOURTH REST;So;0;L;;;;;N;;;;;
+1D142;MUSICAL SYMBOL ONE HUNDRED TWENTY-EIGHTH REST;So;0;L;;;;;N;;;;;
+1D143;MUSICAL SYMBOL X NOTEHEAD;So;0;L;;;;;N;;;;;
+1D144;MUSICAL SYMBOL PLUS NOTEHEAD;So;0;L;;;;;N;;;;;
+1D145;MUSICAL SYMBOL CIRCLE X NOTEHEAD;So;0;L;;;;;N;;;;;
+1D146;MUSICAL SYMBOL SQUARE NOTEHEAD WHITE;So;0;L;;;;;N;;;;;
+1D147;MUSICAL SYMBOL SQUARE NOTEHEAD BLACK;So;0;L;;;;;N;;;;;
+1D148;MUSICAL SYMBOL TRIANGLE NOTEHEAD UP WHITE;So;0;L;;;;;N;;;;;
+1D149;MUSICAL SYMBOL TRIANGLE NOTEHEAD UP BLACK;So;0;L;;;;;N;;;;;
+1D14A;MUSICAL SYMBOL TRIANGLE NOTEHEAD LEFT WHITE;So;0;L;;;;;N;;;;;
+1D14B;MUSICAL SYMBOL TRIANGLE NOTEHEAD LEFT BLACK;So;0;L;;;;;N;;;;;
+1D14C;MUSICAL SYMBOL TRIANGLE NOTEHEAD RIGHT WHITE;So;0;L;;;;;N;;;;;
+1D14D;MUSICAL SYMBOL TRIANGLE NOTEHEAD RIGHT BLACK;So;0;L;;;;;N;;;;;
+1D14E;MUSICAL SYMBOL TRIANGLE NOTEHEAD DOWN WHITE;So;0;L;;;;;N;;;;;
+1D14F;MUSICAL SYMBOL TRIANGLE NOTEHEAD DOWN BLACK;So;0;L;;;;;N;;;;;
+1D150;MUSICAL SYMBOL TRIANGLE NOTEHEAD UP RIGHT WHITE;So;0;L;;;;;N;;;;;
+1D151;MUSICAL SYMBOL TRIANGLE NOTEHEAD UP RIGHT BLACK;So;0;L;;;;;N;;;;;
+1D152;MUSICAL SYMBOL MOON NOTEHEAD WHITE;So;0;L;;;;;N;;;;;
+1D153;MUSICAL SYMBOL MOON NOTEHEAD BLACK;So;0;L;;;;;N;;;;;
+1D154;MUSICAL SYMBOL TRIANGLE-ROUND NOTEHEAD DOWN WHITE;So;0;L;;;;;N;;;;;
+1D155;MUSICAL SYMBOL TRIANGLE-ROUND NOTEHEAD DOWN BLACK;So;0;L;;;;;N;;;;;
+1D156;MUSICAL SYMBOL PARENTHESIS NOTEHEAD;So;0;L;;;;;N;;;;;
+1D157;MUSICAL SYMBOL VOID NOTEHEAD;So;0;L;;;;;N;;;;;
+1D158;MUSICAL SYMBOL NOTEHEAD BLACK;So;0;L;;;;;N;;;;;
+1D159;MUSICAL SYMBOL NULL NOTEHEAD;So;0;L;;;;;N;;;;;
+1D15A;MUSICAL SYMBOL CLUSTER NOTEHEAD WHITE;So;0;L;;;;;N;;;;;
+1D15B;MUSICAL SYMBOL CLUSTER NOTEHEAD BLACK;So;0;L;;;;;N;;;;;
+1D15C;MUSICAL SYMBOL BREVE;So;0;L;;;;;N;;;;;
+1D15D;MUSICAL SYMBOL WHOLE NOTE;So;0;L;;;;;N;;;;;
+1D15E;MUSICAL SYMBOL HALF NOTE;So;0;L;1D157 1D165;;;;N;;;;;
+1D15F;MUSICAL SYMBOL QUARTER NOTE;So;0;L;1D158 1D165;;;;N;;;;;
+1D160;MUSICAL SYMBOL EIGHTH NOTE;So;0;L;1D15F 1D16E;;;;N;;;;;
+1D161;MUSICAL SYMBOL SIXTEENTH NOTE;So;0;L;1D15F 1D16F;;;;N;;;;;
+1D162;MUSICAL SYMBOL THIRTY-SECOND NOTE;So;0;L;1D15F 1D170;;;;N;;;;;
+1D163;MUSICAL SYMBOL SIXTY-FOURTH NOTE;So;0;L;1D15F 1D171;;;;N;;;;;
+1D164;MUSICAL SYMBOL ONE HUNDRED TWENTY-EIGHTH NOTE;So;0;L;1D15F 1D172;;;;N;;;;;
+1D165;MUSICAL SYMBOL COMBINING STEM;Mc;216;L;;;;;N;;;;;
+1D166;MUSICAL SYMBOL COMBINING SPRECHGESANG STEM;Mc;216;L;;;;;N;;;;;
+1D167;MUSICAL SYMBOL COMBINING TREMOLO-1;Mn;1;NSM;;;;;N;;;;;
+1D168;MUSICAL SYMBOL COMBINING TREMOLO-2;Mn;1;NSM;;;;;N;;;;;
+1D169;MUSICAL SYMBOL COMBINING TREMOLO-3;Mn;1;NSM;;;;;N;;;;;
+1D16A;MUSICAL SYMBOL FINGERED TREMOLO-1;So;0;L;;;;;N;;;;;
+1D16B;MUSICAL SYMBOL FINGERED TREMOLO-2;So;0;L;;;;;N;;;;;
+1D16C;MUSICAL SYMBOL FINGERED TREMOLO-3;So;0;L;;;;;N;;;;;
+1D16D;MUSICAL SYMBOL COMBINING AUGMENTATION DOT;Mc;226;L;;;;;N;;;;;
+1D16E;MUSICAL SYMBOL COMBINING FLAG-1;Mc;216;L;;;;;N;;;;;
+1D16F;MUSICAL SYMBOL COMBINING FLAG-2;Mc;216;L;;;;;N;;;;;
+1D170;MUSICAL SYMBOL COMBINING FLAG-3;Mc;216;L;;;;;N;;;;;
+1D171;MUSICAL SYMBOL COMBINING FLAG-4;Mc;216;L;;;;;N;;;;;
+1D172;MUSICAL SYMBOL COMBINING FLAG-5;Mc;216;L;;;;;N;;;;;
+1D173;MUSICAL SYMBOL BEGIN BEAM;Cf;0;BN;;;;;N;;;;;
+1D174;MUSICAL SYMBOL END BEAM;Cf;0;BN;;;;;N;;;;;
+1D175;MUSICAL SYMBOL BEGIN TIE;Cf;0;BN;;;;;N;;;;;
+1D176;MUSICAL SYMBOL END TIE;Cf;0;BN;;;;;N;;;;;
+1D177;MUSICAL SYMBOL BEGIN SLUR;Cf;0;BN;;;;;N;;;;;
+1D178;MUSICAL SYMBOL END SLUR;Cf;0;BN;;;;;N;;;;;
+1D179;MUSICAL SYMBOL BEGIN PHRASE;Cf;0;BN;;;;;N;;;;;
+1D17A;MUSICAL SYMBOL END PHRASE;Cf;0;BN;;;;;N;;;;;
+1D17B;MUSICAL SYMBOL COMBINING ACCENT;Mn;220;NSM;;;;;N;;;;;
+1D17C;MUSICAL SYMBOL COMBINING STACCATO;Mn;220;NSM;;;;;N;;;;;
+1D17D;MUSICAL SYMBOL COMBINING TENUTO;Mn;220;NSM;;;;;N;;;;;
+1D17E;MUSICAL SYMBOL COMBINING STACCATISSIMO;Mn;220;NSM;;;;;N;;;;;
+1D17F;MUSICAL SYMBOL COMBINING MARCATO;Mn;220;NSM;;;;;N;;;;;
+1D180;MUSICAL SYMBOL COMBINING MARCATO-STACCATO;Mn;220;NSM;;;;;N;;;;;
+1D181;MUSICAL SYMBOL COMBINING ACCENT-STACCATO;Mn;220;NSM;;;;;N;;;;;
+1D182;MUSICAL SYMBOL COMBINING LOURE;Mn;220;NSM;;;;;N;;;;;
+1D183;MUSICAL SYMBOL ARPEGGIATO UP;So;0;L;;;;;N;;;;;
+1D184;MUSICAL SYMBOL ARPEGGIATO DOWN;So;0;L;;;;;N;;;;;
+1D185;MUSICAL SYMBOL COMBINING DOIT;Mn;230;NSM;;;;;N;;;;;
+1D186;MUSICAL SYMBOL COMBINING RIP;Mn;230;NSM;;;;;N;;;;;
+1D187;MUSICAL SYMBOL COMBINING FLIP;Mn;230;NSM;;;;;N;;;;;
+1D188;MUSICAL SYMBOL COMBINING SMEAR;Mn;230;NSM;;;;;N;;;;;
+1D189;MUSICAL SYMBOL COMBINING BEND;Mn;230;NSM;;;;;N;;;;;
+1D18A;MUSICAL SYMBOL COMBINING DOUBLE TONGUE;Mn;220;NSM;;;;;N;;;;;
+1D18B;MUSICAL SYMBOL COMBINING TRIPLE TONGUE;Mn;220;NSM;;;;;N;;;;;
+1D18C;MUSICAL SYMBOL RINFORZANDO;So;0;L;;;;;N;;;;;
+1D18D;MUSICAL SYMBOL SUBITO;So;0;L;;;;;N;;;;;
+1D18E;MUSICAL SYMBOL Z;So;0;L;;;;;N;;;;;
+1D18F;MUSICAL SYMBOL PIANO;So;0;L;;;;;N;;;;;
+1D190;MUSICAL SYMBOL MEZZO;So;0;L;;;;;N;;;;;
+1D191;MUSICAL SYMBOL FORTE;So;0;L;;;;;N;;;;;
+1D192;MUSICAL SYMBOL CRESCENDO;So;0;L;;;;;N;;;;;
+1D193;MUSICAL SYMBOL DECRESCENDO;So;0;L;;;;;N;;;;;
+1D194;MUSICAL SYMBOL GRACE NOTE SLASH;So;0;L;;;;;N;;;;;
+1D195;MUSICAL SYMBOL GRACE NOTE NO SLASH;So;0;L;;;;;N;;;;;
+1D196;MUSICAL SYMBOL TR;So;0;L;;;;;N;;;;;
+1D197;MUSICAL SYMBOL TURN;So;0;L;;;;;N;;;;;
+1D198;MUSICAL SYMBOL INVERTED TURN;So;0;L;;;;;N;;;;;
+1D199;MUSICAL SYMBOL TURN SLASH;So;0;L;;;;;N;;;;;
+1D19A;MUSICAL SYMBOL TURN UP;So;0;L;;;;;N;;;;;
+1D19B;MUSICAL SYMBOL ORNAMENT STROKE-1;So;0;L;;;;;N;;;;;
+1D19C;MUSICAL SYMBOL ORNAMENT STROKE-2;So;0;L;;;;;N;;;;;
+1D19D;MUSICAL SYMBOL ORNAMENT STROKE-3;So;0;L;;;;;N;;;;;
+1D19E;MUSICAL SYMBOL ORNAMENT STROKE-4;So;0;L;;;;;N;;;;;
+1D19F;MUSICAL SYMBOL ORNAMENT STROKE-5;So;0;L;;;;;N;;;;;
+1D1A0;MUSICAL SYMBOL ORNAMENT STROKE-6;So;0;L;;;;;N;;;;;
+1D1A1;MUSICAL SYMBOL ORNAMENT STROKE-7;So;0;L;;;;;N;;;;;
+1D1A2;MUSICAL SYMBOL ORNAMENT STROKE-8;So;0;L;;;;;N;;;;;
+1D1A3;MUSICAL SYMBOL ORNAMENT STROKE-9;So;0;L;;;;;N;;;;;
+1D1A4;MUSICAL SYMBOL ORNAMENT STROKE-10;So;0;L;;;;;N;;;;;
+1D1A5;MUSICAL SYMBOL ORNAMENT STROKE-11;So;0;L;;;;;N;;;;;
+1D1A6;MUSICAL SYMBOL HAUPTSTIMME;So;0;L;;;;;N;;;;;
+1D1A7;MUSICAL SYMBOL NEBENSTIMME;So;0;L;;;;;N;;;;;
+1D1A8;MUSICAL SYMBOL END OF STIMME;So;0;L;;;;;N;;;;;
+1D1A9;MUSICAL SYMBOL DEGREE SLASH;So;0;L;;;;;N;;;;;
+1D1AA;MUSICAL SYMBOL COMBINING DOWN BOW;Mn;230;NSM;;;;;N;;;;;
+1D1AB;MUSICAL SYMBOL COMBINING UP BOW;Mn;230;NSM;;;;;N;;;;;
+1D1AC;MUSICAL SYMBOL COMBINING HARMONIC;Mn;230;NSM;;;;;N;;;;;
+1D1AD;MUSICAL SYMBOL COMBINING SNAP PIZZICATO;Mn;230;NSM;;;;;N;;;;;
+1D1AE;MUSICAL SYMBOL PEDAL MARK;So;0;L;;;;;N;;;;;
+1D1AF;MUSICAL SYMBOL PEDAL UP MARK;So;0;L;;;;;N;;;;;
+1D1B0;MUSICAL SYMBOL HALF PEDAL MARK;So;0;L;;;;;N;;;;;
+1D1B1;MUSICAL SYMBOL GLISSANDO UP;So;0;L;;;;;N;;;;;
+1D1B2;MUSICAL SYMBOL GLISSANDO DOWN;So;0;L;;;;;N;;;;;
+1D1B3;MUSICAL SYMBOL WITH FINGERNAILS;So;0;L;;;;;N;;;;;
+1D1B4;MUSICAL SYMBOL DAMP;So;0;L;;;;;N;;;;;
+1D1B5;MUSICAL SYMBOL DAMP ALL;So;0;L;;;;;N;;;;;
+1D1B6;MUSICAL SYMBOL MAXIMA;So;0;L;;;;;N;;;;;
+1D1B7;MUSICAL SYMBOL LONGA;So;0;L;;;;;N;;;;;
+1D1B8;MUSICAL SYMBOL BREVIS;So;0;L;;;;;N;;;;;
+1D1B9;MUSICAL SYMBOL SEMIBREVIS WHITE;So;0;L;;;;;N;;;;;
+1D1BA;MUSICAL SYMBOL SEMIBREVIS BLACK;So;0;L;;;;;N;;;;;
+1D1BB;MUSICAL SYMBOL MINIMA;So;0;L;1D1B9 1D165;;;;N;;;;;
+1D1BC;MUSICAL SYMBOL MINIMA BLACK;So;0;L;1D1BA 1D165;;;;N;;;;;
+1D1BD;MUSICAL SYMBOL SEMIMINIMA WHITE;So;0;L;1D1BB 1D16E;;;;N;;;;;
+1D1BE;MUSICAL SYMBOL SEMIMINIMA BLACK;So;0;L;1D1BC 1D16E;;;;N;;;;;
+1D1BF;MUSICAL SYMBOL FUSA WHITE;So;0;L;1D1BB 1D16F;;;;N;;;;;
+1D1C0;MUSICAL SYMBOL FUSA BLACK;So;0;L;1D1BC 1D16F;;;;N;;;;;
+1D1C1;MUSICAL SYMBOL LONGA PERFECTA REST;So;0;L;;;;;N;;;;;
+1D1C2;MUSICAL SYMBOL LONGA IMPERFECTA REST;So;0;L;;;;;N;;;;;
+1D1C3;MUSICAL SYMBOL BREVIS REST;So;0;L;;;;;N;;;;;
+1D1C4;MUSICAL SYMBOL SEMIBREVIS REST;So;0;L;;;;;N;;;;;
+1D1C5;MUSICAL SYMBOL MINIMA REST;So;0;L;;;;;N;;;;;
+1D1C6;MUSICAL SYMBOL SEMIMINIMA REST;So;0;L;;;;;N;;;;;
+1D1C7;MUSICAL SYMBOL TEMPUS PERFECTUM CUM PROLATIONE PERFECTA;So;0;L;;;;;N;;;;;
+1D1C8;MUSICAL SYMBOL TEMPUS PERFECTUM CUM PROLATIONE IMPERFECTA;So;0;L;;;;;N;;;;;
+1D1C9;MUSICAL SYMBOL TEMPUS PERFECTUM CUM PROLATIONE PERFECTA DIMINUTION-1;So;0;L;;;;;N;;;;;
+1D1CA;MUSICAL SYMBOL TEMPUS IMPERFECTUM CUM PROLATIONE PERFECTA;So;0;L;;;;;N;;;;;
+1D1CB;MUSICAL SYMBOL TEMPUS IMPERFECTUM CUM PROLATIONE IMPERFECTA;So;0;L;;;;;N;;;;;
+1D1CC;MUSICAL SYMBOL TEMPUS IMPERFECTUM CUM PROLATIONE IMPERFECTA DIMINUTION-1;So;0;L;;;;;N;;;;;
+1D1CD;MUSICAL SYMBOL TEMPUS IMPERFECTUM CUM PROLATIONE IMPERFECTA DIMINUTION-2;So;0;L;;;;;N;;;;;
+1D1CE;MUSICAL SYMBOL TEMPUS IMPERFECTUM CUM PROLATIONE IMPERFECTA DIMINUTION-3;So;0;L;;;;;N;;;;;
+1D1CF;MUSICAL SYMBOL CROIX;So;0;L;;;;;N;;;;;
+1D1D0;MUSICAL SYMBOL GREGORIAN C CLEF;So;0;L;;;;;N;;;;;
+1D1D1;MUSICAL SYMBOL GREGORIAN F CLEF;So;0;L;;;;;N;;;;;
+1D1D2;MUSICAL SYMBOL SQUARE B;So;0;L;;;;;N;;;;;
+1D1D3;MUSICAL SYMBOL VIRGA;So;0;L;;;;;N;;;;;
+1D1D4;MUSICAL SYMBOL PODATUS;So;0;L;;;;;N;;;;;
+1D1D5;MUSICAL SYMBOL CLIVIS;So;0;L;;;;;N;;;;;
+1D1D6;MUSICAL SYMBOL SCANDICUS;So;0;L;;;;;N;;;;;
+1D1D7;MUSICAL SYMBOL CLIMACUS;So;0;L;;;;;N;;;;;
+1D1D8;MUSICAL SYMBOL TORCULUS;So;0;L;;;;;N;;;;;
+1D1D9;MUSICAL SYMBOL PORRECTUS;So;0;L;;;;;N;;;;;
+1D1DA;MUSICAL SYMBOL PORRECTUS FLEXUS;So;0;L;;;;;N;;;;;
+1D1DB;MUSICAL SYMBOL SCANDICUS FLEXUS;So;0;L;;;;;N;;;;;
+1D1DC;MUSICAL SYMBOL TORCULUS RESUPINUS;So;0;L;;;;;N;;;;;
+1D1DD;MUSICAL SYMBOL PES SUBPUNCTIS;So;0;L;;;;;N;;;;;
+1D200;GREEK VOCAL NOTATION SYMBOL-1;So;0;ON;;;;;N;;;;;
+1D201;GREEK VOCAL NOTATION SYMBOL-2;So;0;ON;;;;;N;;;;;
+1D202;GREEK VOCAL NOTATION SYMBOL-3;So;0;ON;;;;;N;;;;;
+1D203;GREEK VOCAL NOTATION SYMBOL-4;So;0;ON;;;;;N;;;;;
+1D204;GREEK VOCAL NOTATION SYMBOL-5;So;0;ON;;;;;N;;;;;
+1D205;GREEK VOCAL NOTATION SYMBOL-6;So;0;ON;;;;;N;;;;;
+1D206;GREEK VOCAL NOTATION SYMBOL-7;So;0;ON;;;;;N;;;;;
+1D207;GREEK VOCAL NOTATION SYMBOL-8;So;0;ON;;;;;N;;;;;
+1D208;GREEK VOCAL NOTATION SYMBOL-9;So;0;ON;;;;;N;;;;;
+1D209;GREEK VOCAL NOTATION SYMBOL-10;So;0;ON;;;;;N;;;;;
+1D20A;GREEK VOCAL NOTATION SYMBOL-11;So;0;ON;;;;;N;;;;;
+1D20B;GREEK VOCAL NOTATION SYMBOL-12;So;0;ON;;;;;N;;;;;
+1D20C;GREEK VOCAL NOTATION SYMBOL-13;So;0;ON;;;;;N;;;;;
+1D20D;GREEK VOCAL NOTATION SYMBOL-14;So;0;ON;;;;;N;;;;;
+1D20E;GREEK VOCAL NOTATION SYMBOL-15;So;0;ON;;;;;N;;;;;
+1D20F;GREEK VOCAL NOTATION SYMBOL-16;So;0;ON;;;;;N;;;;;
+1D210;GREEK VOCAL NOTATION SYMBOL-17;So;0;ON;;;;;N;;;;;
+1D211;GREEK VOCAL NOTATION SYMBOL-18;So;0;ON;;;;;N;;;;;
+1D212;GREEK VOCAL NOTATION SYMBOL-19;So;0;ON;;;;;N;;;;;
+1D213;GREEK VOCAL NOTATION SYMBOL-20;So;0;ON;;;;;N;;;;;
+1D214;GREEK VOCAL NOTATION SYMBOL-21;So;0;ON;;;;;N;;;;;
+1D215;GREEK VOCAL NOTATION SYMBOL-22;So;0;ON;;;;;N;;;;;
+1D216;GREEK VOCAL NOTATION SYMBOL-23;So;0;ON;;;;;N;;;;;
+1D217;GREEK VOCAL NOTATION SYMBOL-24;So;0;ON;;;;;N;;;;;
+1D218;GREEK VOCAL NOTATION SYMBOL-50;So;0;ON;;;;;N;;;;;
+1D219;GREEK VOCAL NOTATION SYMBOL-51;So;0;ON;;;;;N;;;;;
+1D21A;GREEK VOCAL NOTATION SYMBOL-52;So;0;ON;;;;;N;;;;;
+1D21B;GREEK VOCAL NOTATION SYMBOL-53;So;0;ON;;;;;N;;;;;
+1D21C;GREEK VOCAL NOTATION SYMBOL-54;So;0;ON;;;;;N;;;;;
+1D21D;GREEK INSTRUMENTAL NOTATION SYMBOL-1;So;0;ON;;;;;N;;;;;
+1D21E;GREEK INSTRUMENTAL NOTATION SYMBOL-2;So;0;ON;;;;;N;;;;;
+1D21F;GREEK INSTRUMENTAL NOTATION SYMBOL-4;So;0;ON;;;;;N;;;;;
+1D220;GREEK INSTRUMENTAL NOTATION SYMBOL-5;So;0;ON;;;;;N;;;;;
+1D221;GREEK INSTRUMENTAL NOTATION SYMBOL-7;So;0;ON;;;;;N;;;;;
+1D222;GREEK INSTRUMENTAL NOTATION SYMBOL-8;So;0;ON;;;;;N;;;;;
+1D223;GREEK INSTRUMENTAL NOTATION SYMBOL-11;So;0;ON;;;;;N;;;;;
+1D224;GREEK INSTRUMENTAL NOTATION SYMBOL-12;So;0;ON;;;;;N;;;;;
+1D225;GREEK INSTRUMENTAL NOTATION SYMBOL-13;So;0;ON;;;;;N;;;;;
+1D226;GREEK INSTRUMENTAL NOTATION SYMBOL-14;So;0;ON;;;;;N;;;;;
+1D227;GREEK INSTRUMENTAL NOTATION SYMBOL-17;So;0;ON;;;;;N;;;;;
+1D228;GREEK INSTRUMENTAL NOTATION SYMBOL-18;So;0;ON;;;;;N;;;;;
+1D229;GREEK INSTRUMENTAL NOTATION SYMBOL-19;So;0;ON;;;;;N;;;;;
+1D22A;GREEK INSTRUMENTAL NOTATION SYMBOL-23;So;0;ON;;;;;N;;;;;
+1D22B;GREEK INSTRUMENTAL NOTATION SYMBOL-24;So;0;ON;;;;;N;;;;;
+1D22C;GREEK INSTRUMENTAL NOTATION SYMBOL-25;So;0;ON;;;;;N;;;;;
+1D22D;GREEK INSTRUMENTAL NOTATION SYMBOL-26;So;0;ON;;;;;N;;;;;
+1D22E;GREEK INSTRUMENTAL NOTATION SYMBOL-27;So;0;ON;;;;;N;;;;;
+1D22F;GREEK INSTRUMENTAL NOTATION SYMBOL-29;So;0;ON;;;;;N;;;;;
+1D230;GREEK INSTRUMENTAL NOTATION SYMBOL-30;So;0;ON;;;;;N;;;;;
+1D231;GREEK INSTRUMENTAL NOTATION SYMBOL-32;So;0;ON;;;;;N;;;;;
+1D232;GREEK INSTRUMENTAL NOTATION SYMBOL-36;So;0;ON;;;;;N;;;;;
+1D233;GREEK INSTRUMENTAL NOTATION SYMBOL-37;So;0;ON;;;;;N;;;;;
+1D234;GREEK INSTRUMENTAL NOTATION SYMBOL-38;So;0;ON;;;;;N;;;;;
+1D235;GREEK INSTRUMENTAL NOTATION SYMBOL-39;So;0;ON;;;;;N;;;;;
+1D236;GREEK INSTRUMENTAL NOTATION SYMBOL-40;So;0;ON;;;;;N;;;;;
+1D237;GREEK INSTRUMENTAL NOTATION SYMBOL-42;So;0;ON;;;;;N;;;;;
+1D238;GREEK INSTRUMENTAL NOTATION SYMBOL-43;So;0;ON;;;;;N;;;;;
+1D239;GREEK INSTRUMENTAL NOTATION SYMBOL-45;So;0;ON;;;;;N;;;;;
+1D23A;GREEK INSTRUMENTAL NOTATION SYMBOL-47;So;0;ON;;;;;N;;;;;
+1D23B;GREEK INSTRUMENTAL NOTATION SYMBOL-48;So;0;ON;;;;;N;;;;;
+1D23C;GREEK INSTRUMENTAL NOTATION SYMBOL-49;So;0;ON;;;;;N;;;;;
+1D23D;GREEK INSTRUMENTAL NOTATION SYMBOL-50;So;0;ON;;;;;N;;;;;
+1D23E;GREEK INSTRUMENTAL NOTATION SYMBOL-51;So;0;ON;;;;;N;;;;;
+1D23F;GREEK INSTRUMENTAL NOTATION SYMBOL-52;So;0;ON;;;;;N;;;;;
+1D240;GREEK INSTRUMENTAL NOTATION SYMBOL-53;So;0;ON;;;;;N;;;;;
+1D241;GREEK INSTRUMENTAL NOTATION SYMBOL-54;So;0;ON;;;;;N;;;;;
+1D242;COMBINING GREEK MUSICAL TRISEME;Mn;230;NSM;;;;;N;;;;;
+1D243;COMBINING GREEK MUSICAL TETRASEME;Mn;230;NSM;;;;;N;;;;;
+1D244;COMBINING GREEK MUSICAL PENTASEME;Mn;230;NSM;;;;;N;;;;;
+1D245;GREEK MUSICAL LEIMMA;So;0;ON;;;;;N;;;;;
+1D300;MONOGRAM FOR EARTH;So;0;ON;;;;;N;;;;;
+1D301;DIGRAM FOR HEAVENLY EARTH;So;0;ON;;;;;N;;;;;
+1D302;DIGRAM FOR HUMAN EARTH;So;0;ON;;;;;N;;;;;
+1D303;DIGRAM FOR EARTHLY HEAVEN;So;0;ON;;;;;N;;;;;
+1D304;DIGRAM FOR EARTHLY HUMAN;So;0;ON;;;;;N;;;;;
+1D305;DIGRAM FOR EARTH;So;0;ON;;;;;N;;;;;
+1D306;TETRAGRAM FOR CENTRE;So;0;ON;;;;;N;;;;;
+1D307;TETRAGRAM FOR FULL CIRCLE;So;0;ON;;;;;N;;;;;
+1D308;TETRAGRAM FOR MIRED;So;0;ON;;;;;N;;;;;
+1D309;TETRAGRAM FOR BARRIER;So;0;ON;;;;;N;;;;;
+1D30A;TETRAGRAM FOR KEEPING SMALL;So;0;ON;;;;;N;;;;;
+1D30B;TETRAGRAM FOR CONTRARIETY;So;0;ON;;;;;N;;;;;
+1D30C;TETRAGRAM FOR ASCENT;So;0;ON;;;;;N;;;;;
+1D30D;TETRAGRAM FOR OPPOSITION;So;0;ON;;;;;N;;;;;
+1D30E;TETRAGRAM FOR BRANCHING OUT;So;0;ON;;;;;N;;;;;
+1D30F;TETRAGRAM FOR DEFECTIVENESS OR DISTORTION;So;0;ON;;;;;N;;;;;
+1D310;TETRAGRAM FOR DIVERGENCE;So;0;ON;;;;;N;;;;;
+1D311;TETRAGRAM FOR YOUTHFULNESS;So;0;ON;;;;;N;;;;;
+1D312;TETRAGRAM FOR INCREASE;So;0;ON;;;;;N;;;;;
+1D313;TETRAGRAM FOR PENETRATION;So;0;ON;;;;;N;;;;;
+1D314;TETRAGRAM FOR REACH;So;0;ON;;;;;N;;;;;
+1D315;TETRAGRAM FOR CONTACT;So;0;ON;;;;;N;;;;;
+1D316;TETRAGRAM FOR HOLDING BACK;So;0;ON;;;;;N;;;;;
+1D317;TETRAGRAM FOR WAITING;So;0;ON;;;;;N;;;;;
+1D318;TETRAGRAM FOR FOLLOWING;So;0;ON;;;;;N;;;;;
+1D319;TETRAGRAM FOR ADVANCE;So;0;ON;;;;;N;;;;;
+1D31A;TETRAGRAM FOR RELEASE;So;0;ON;;;;;N;;;;;
+1D31B;TETRAGRAM FOR RESISTANCE;So;0;ON;;;;;N;;;;;
+1D31C;TETRAGRAM FOR EASE;So;0;ON;;;;;N;;;;;
+1D31D;TETRAGRAM FOR JOY;So;0;ON;;;;;N;;;;;
+1D31E;TETRAGRAM FOR CONTENTION;So;0;ON;;;;;N;;;;;
+1D31F;TETRAGRAM FOR ENDEAVOUR;So;0;ON;;;;;N;;;;;
+1D320;TETRAGRAM FOR DUTIES;So;0;ON;;;;;N;;;;;
+1D321;TETRAGRAM FOR CHANGE;So;0;ON;;;;;N;;;;;
+1D322;TETRAGRAM FOR DECISIVENESS;So;0;ON;;;;;N;;;;;
+1D323;TETRAGRAM FOR BOLD RESOLUTION;So;0;ON;;;;;N;;;;;
+1D324;TETRAGRAM FOR PACKING;So;0;ON;;;;;N;;;;;
+1D325;TETRAGRAM FOR LEGION;So;0;ON;;;;;N;;;;;
+1D326;TETRAGRAM FOR CLOSENESS;So;0;ON;;;;;N;;;;;
+1D327;TETRAGRAM FOR KINSHIP;So;0;ON;;;;;N;;;;;
+1D328;TETRAGRAM FOR GATHERING;So;0;ON;;;;;N;;;;;
+1D329;TETRAGRAM FOR STRENGTH;So;0;ON;;;;;N;;;;;
+1D32A;TETRAGRAM FOR PURITY;So;0;ON;;;;;N;;;;;
+1D32B;TETRAGRAM FOR FULLNESS;So;0;ON;;;;;N;;;;;
+1D32C;TETRAGRAM FOR RESIDENCE;So;0;ON;;;;;N;;;;;
+1D32D;TETRAGRAM FOR LAW OR MODEL;So;0;ON;;;;;N;;;;;
+1D32E;TETRAGRAM FOR RESPONSE;So;0;ON;;;;;N;;;;;
+1D32F;TETRAGRAM FOR GOING TO MEET;So;0;ON;;;;;N;;;;;
+1D330;TETRAGRAM FOR ENCOUNTERS;So;0;ON;;;;;N;;;;;
+1D331;TETRAGRAM FOR STOVE;So;0;ON;;;;;N;;;;;
+1D332;TETRAGRAM FOR GREATNESS;So;0;ON;;;;;N;;;;;
+1D333;TETRAGRAM FOR ENLARGEMENT;So;0;ON;;;;;N;;;;;
+1D334;TETRAGRAM FOR PATTERN;So;0;ON;;;;;N;;;;;
+1D335;TETRAGRAM FOR RITUAL;So;0;ON;;;;;N;;;;;
+1D336;TETRAGRAM FOR FLIGHT;So;0;ON;;;;;N;;;;;
+1D337;TETRAGRAM FOR VASTNESS OR WASTING;So;0;ON;;;;;N;;;;;
+1D338;TETRAGRAM FOR CONSTANCY;So;0;ON;;;;;N;;;;;
+1D339;TETRAGRAM FOR MEASURE;So;0;ON;;;;;N;;;;;
+1D33A;TETRAGRAM FOR ETERNITY;So;0;ON;;;;;N;;;;;
+1D33B;TETRAGRAM FOR UNITY;So;0;ON;;;;;N;;;;;
+1D33C;TETRAGRAM FOR DIMINISHMENT;So;0;ON;;;;;N;;;;;
+1D33D;TETRAGRAM FOR CLOSED MOUTH;So;0;ON;;;;;N;;;;;
+1D33E;TETRAGRAM FOR GUARDEDNESS;So;0;ON;;;;;N;;;;;
+1D33F;TETRAGRAM FOR GATHERING IN;So;0;ON;;;;;N;;;;;
+1D340;TETRAGRAM FOR MASSING;So;0;ON;;;;;N;;;;;
+1D341;TETRAGRAM FOR ACCUMULATION;So;0;ON;;;;;N;;;;;
+1D342;TETRAGRAM FOR EMBELLISHMENT;So;0;ON;;;;;N;;;;;
+1D343;TETRAGRAM FOR DOUBT;So;0;ON;;;;;N;;;;;
+1D344;TETRAGRAM FOR WATCH;So;0;ON;;;;;N;;;;;
+1D345;TETRAGRAM FOR SINKING;So;0;ON;;;;;N;;;;;
+1D346;TETRAGRAM FOR INNER;So;0;ON;;;;;N;;;;;
+1D347;TETRAGRAM FOR DEPARTURE;So;0;ON;;;;;N;;;;;
+1D348;TETRAGRAM FOR DARKENING;So;0;ON;;;;;N;;;;;
+1D349;TETRAGRAM FOR DIMMING;So;0;ON;;;;;N;;;;;
+1D34A;TETRAGRAM FOR EXHAUSTION;So;0;ON;;;;;N;;;;;
+1D34B;TETRAGRAM FOR SEVERANCE;So;0;ON;;;;;N;;;;;
+1D34C;TETRAGRAM FOR STOPPAGE;So;0;ON;;;;;N;;;;;
+1D34D;TETRAGRAM FOR HARDNESS;So;0;ON;;;;;N;;;;;
+1D34E;TETRAGRAM FOR COMPLETION;So;0;ON;;;;;N;;;;;
+1D34F;TETRAGRAM FOR CLOSURE;So;0;ON;;;;;N;;;;;
+1D350;TETRAGRAM FOR FAILURE;So;0;ON;;;;;N;;;;;
+1D351;TETRAGRAM FOR AGGRAVATION;So;0;ON;;;;;N;;;;;
+1D352;TETRAGRAM FOR COMPLIANCE;So;0;ON;;;;;N;;;;;
+1D353;TETRAGRAM FOR ON THE VERGE;So;0;ON;;;;;N;;;;;
+1D354;TETRAGRAM FOR DIFFICULTIES;So;0;ON;;;;;N;;;;;
+1D355;TETRAGRAM FOR LABOURING;So;0;ON;;;;;N;;;;;
+1D356;TETRAGRAM FOR FOSTERING;So;0;ON;;;;;N;;;;;
+1D360;COUNTING ROD UNIT DIGIT ONE;No;0;L;;;;1;N;;;;;
+1D361;COUNTING ROD UNIT DIGIT TWO;No;0;L;;;;2;N;;;;;
+1D362;COUNTING ROD UNIT DIGIT THREE;No;0;L;;;;3;N;;;;;
+1D363;COUNTING ROD UNIT DIGIT FOUR;No;0;L;;;;4;N;;;;;
+1D364;COUNTING ROD UNIT DIGIT FIVE;No;0;L;;;;5;N;;;;;
+1D365;COUNTING ROD UNIT DIGIT SIX;No;0;L;;;;6;N;;;;;
+1D366;COUNTING ROD UNIT DIGIT SEVEN;No;0;L;;;;7;N;;;;;
+1D367;COUNTING ROD UNIT DIGIT EIGHT;No;0;L;;;;8;N;;;;;
+1D368;COUNTING ROD UNIT DIGIT NINE;No;0;L;;;;9;N;;;;;
+1D369;COUNTING ROD TENS DIGIT ONE;No;0;L;;;;10;N;;;;;
+1D36A;COUNTING ROD TENS DIGIT TWO;No;0;L;;;;20;N;;;;;
+1D36B;COUNTING ROD TENS DIGIT THREE;No;0;L;;;;30;N;;;;;
+1D36C;COUNTING ROD TENS DIGIT FOUR;No;0;L;;;;40;N;;;;;
+1D36D;COUNTING ROD TENS DIGIT FIVE;No;0;L;;;;50;N;;;;;
+1D36E;COUNTING ROD TENS DIGIT SIX;No;0;L;;;;60;N;;;;;
+1D36F;COUNTING ROD TENS DIGIT SEVEN;No;0;L;;;;70;N;;;;;
+1D370;COUNTING ROD TENS DIGIT EIGHT;No;0;L;;;;80;N;;;;;
+1D371;COUNTING ROD TENS DIGIT NINE;No;0;L;;;;90;N;;;;;
+1D400;MATHEMATICAL BOLD CAPITAL A;Lu;0;L;<font> 0041;;;;N;;;;;
+1D401;MATHEMATICAL BOLD CAPITAL B;Lu;0;L;<font> 0042;;;;N;;;;;
+1D402;MATHEMATICAL BOLD CAPITAL C;Lu;0;L;<font> 0043;;;;N;;;;;
+1D403;MATHEMATICAL BOLD CAPITAL D;Lu;0;L;<font> 0044;;;;N;;;;;
+1D404;MATHEMATICAL BOLD CAPITAL E;Lu;0;L;<font> 0045;;;;N;;;;;
+1D405;MATHEMATICAL BOLD CAPITAL F;Lu;0;L;<font> 0046;;;;N;;;;;
+1D406;MATHEMATICAL BOLD CAPITAL G;Lu;0;L;<font> 0047;;;;N;;;;;
+1D407;MATHEMATICAL BOLD CAPITAL H;Lu;0;L;<font> 0048;;;;N;;;;;
+1D408;MATHEMATICAL BOLD CAPITAL I;Lu;0;L;<font> 0049;;;;N;;;;;
+1D409;MATHEMATICAL BOLD CAPITAL J;Lu;0;L;<font> 004A;;;;N;;;;;
+1D40A;MATHEMATICAL BOLD CAPITAL K;Lu;0;L;<font> 004B;;;;N;;;;;
+1D40B;MATHEMATICAL BOLD CAPITAL L;Lu;0;L;<font> 004C;;;;N;;;;;
+1D40C;MATHEMATICAL BOLD CAPITAL M;Lu;0;L;<font> 004D;;;;N;;;;;
+1D40D;MATHEMATICAL BOLD CAPITAL N;Lu;0;L;<font> 004E;;;;N;;;;;
+1D40E;MATHEMATICAL BOLD CAPITAL O;Lu;0;L;<font> 004F;;;;N;;;;;
+1D40F;MATHEMATICAL BOLD CAPITAL P;Lu;0;L;<font> 0050;;;;N;;;;;
+1D410;MATHEMATICAL BOLD CAPITAL Q;Lu;0;L;<font> 0051;;;;N;;;;;
+1D411;MATHEMATICAL BOLD CAPITAL R;Lu;0;L;<font> 0052;;;;N;;;;;
+1D412;MATHEMATICAL BOLD CAPITAL S;Lu;0;L;<font> 0053;;;;N;;;;;
+1D413;MATHEMATICAL BOLD CAPITAL T;Lu;0;L;<font> 0054;;;;N;;;;;
+1D414;MATHEMATICAL BOLD CAPITAL U;Lu;0;L;<font> 0055;;;;N;;;;;
+1D415;MATHEMATICAL BOLD CAPITAL V;Lu;0;L;<font> 0056;;;;N;;;;;
+1D416;MATHEMATICAL BOLD CAPITAL W;Lu;0;L;<font> 0057;;;;N;;;;;
+1D417;MATHEMATICAL BOLD CAPITAL X;Lu;0;L;<font> 0058;;;;N;;;;;
+1D418;MATHEMATICAL BOLD CAPITAL Y;Lu;0;L;<font> 0059;;;;N;;;;;
+1D419;MATHEMATICAL BOLD CAPITAL Z;Lu;0;L;<font> 005A;;;;N;;;;;
+1D41A;MATHEMATICAL BOLD SMALL A;Ll;0;L;<font> 0061;;;;N;;;;;
+1D41B;MATHEMATICAL BOLD SMALL B;Ll;0;L;<font> 0062;;;;N;;;;;
+1D41C;MATHEMATICAL BOLD SMALL C;Ll;0;L;<font> 0063;;;;N;;;;;
+1D41D;MATHEMATICAL BOLD SMALL D;Ll;0;L;<font> 0064;;;;N;;;;;
+1D41E;MATHEMATICAL BOLD SMALL E;Ll;0;L;<font> 0065;;;;N;;;;;
+1D41F;MATHEMATICAL BOLD SMALL F;Ll;0;L;<font> 0066;;;;N;;;;;
+1D420;MATHEMATICAL BOLD SMALL G;Ll;0;L;<font> 0067;;;;N;;;;;
+1D421;MATHEMATICAL BOLD SMALL H;Ll;0;L;<font> 0068;;;;N;;;;;
+1D422;MATHEMATICAL BOLD SMALL I;Ll;0;L;<font> 0069;;;;N;;;;;
+1D423;MATHEMATICAL BOLD SMALL J;Ll;0;L;<font> 006A;;;;N;;;;;
+1D424;MATHEMATICAL BOLD SMALL K;Ll;0;L;<font> 006B;;;;N;;;;;
+1D425;MATHEMATICAL BOLD SMALL L;Ll;0;L;<font> 006C;;;;N;;;;;
+1D426;MATHEMATICAL BOLD SMALL M;Ll;0;L;<font> 006D;;;;N;;;;;
+1D427;MATHEMATICAL BOLD SMALL N;Ll;0;L;<font> 006E;;;;N;;;;;
+1D428;MATHEMATICAL BOLD SMALL O;Ll;0;L;<font> 006F;;;;N;;;;;
+1D429;MATHEMATICAL BOLD SMALL P;Ll;0;L;<font> 0070;;;;N;;;;;
+1D42A;MATHEMATICAL BOLD SMALL Q;Ll;0;L;<font> 0071;;;;N;;;;;
+1D42B;MATHEMATICAL BOLD SMALL R;Ll;0;L;<font> 0072;;;;N;;;;;
+1D42C;MATHEMATICAL BOLD SMALL S;Ll;0;L;<font> 0073;;;;N;;;;;
+1D42D;MATHEMATICAL BOLD SMALL T;Ll;0;L;<font> 0074;;;;N;;;;;
+1D42E;MATHEMATICAL BOLD SMALL U;Ll;0;L;<font> 0075;;;;N;;;;;
+1D42F;MATHEMATICAL BOLD SMALL V;Ll;0;L;<font> 0076;;;;N;;;;;
+1D430;MATHEMATICAL BOLD SMALL W;Ll;0;L;<font> 0077;;;;N;;;;;
+1D431;MATHEMATICAL BOLD SMALL X;Ll;0;L;<font> 0078;;;;N;;;;;
+1D432;MATHEMATICAL BOLD SMALL Y;Ll;0;L;<font> 0079;;;;N;;;;;
+1D433;MATHEMATICAL BOLD SMALL Z;Ll;0;L;<font> 007A;;;;N;;;;;
+1D434;MATHEMATICAL ITALIC CAPITAL A;Lu;0;L;<font> 0041;;;;N;;;;;
+1D435;MATHEMATICAL ITALIC CAPITAL B;Lu;0;L;<font> 0042;;;;N;;;;;
+1D436;MATHEMATICAL ITALIC CAPITAL C;Lu;0;L;<font> 0043;;;;N;;;;;
+1D437;MATHEMATICAL ITALIC CAPITAL D;Lu;0;L;<font> 0044;;;;N;;;;;
+1D438;MATHEMATICAL ITALIC CAPITAL E;Lu;0;L;<font> 0045;;;;N;;;;;
+1D439;MATHEMATICAL ITALIC CAPITAL F;Lu;0;L;<font> 0046;;;;N;;;;;
+1D43A;MATHEMATICAL ITALIC CAPITAL G;Lu;0;L;<font> 0047;;;;N;;;;;
+1D43B;MATHEMATICAL ITALIC CAPITAL H;Lu;0;L;<font> 0048;;;;N;;;;;
+1D43C;MATHEMATICAL ITALIC CAPITAL I;Lu;0;L;<font> 0049;;;;N;;;;;
+1D43D;MATHEMATICAL ITALIC CAPITAL J;Lu;0;L;<font> 004A;;;;N;;;;;
+1D43E;MATHEMATICAL ITALIC CAPITAL K;Lu;0;L;<font> 004B;;;;N;;;;;
+1D43F;MATHEMATICAL ITALIC CAPITAL L;Lu;0;L;<font> 004C;;;;N;;;;;
+1D440;MATHEMATICAL ITALIC CAPITAL M;Lu;0;L;<font> 004D;;;;N;;;;;
+1D441;MATHEMATICAL ITALIC CAPITAL N;Lu;0;L;<font> 004E;;;;N;;;;;
+1D442;MATHEMATICAL ITALIC CAPITAL O;Lu;0;L;<font> 004F;;;;N;;;;;
+1D443;MATHEMATICAL ITALIC CAPITAL P;Lu;0;L;<font> 0050;;;;N;;;;;
+1D444;MATHEMATICAL ITALIC CAPITAL Q;Lu;0;L;<font> 0051;;;;N;;;;;
+1D445;MATHEMATICAL ITALIC CAPITAL R;Lu;0;L;<font> 0052;;;;N;;;;;
+1D446;MATHEMATICAL ITALIC CAPITAL S;Lu;0;L;<font> 0053;;;;N;;;;;
+1D447;MATHEMATICAL ITALIC CAPITAL T;Lu;0;L;<font> 0054;;;;N;;;;;
+1D448;MATHEMATICAL ITALIC CAPITAL U;Lu;0;L;<font> 0055;;;;N;;;;;
+1D449;MATHEMATICAL ITALIC CAPITAL V;Lu;0;L;<font> 0056;;;;N;;;;;
+1D44A;MATHEMATICAL ITALIC CAPITAL W;Lu;0;L;<font> 0057;;;;N;;;;;
+1D44B;MATHEMATICAL ITALIC CAPITAL X;Lu;0;L;<font> 0058;;;;N;;;;;
+1D44C;MATHEMATICAL ITALIC CAPITAL Y;Lu;0;L;<font> 0059;;;;N;;;;;
+1D44D;MATHEMATICAL ITALIC CAPITAL Z;Lu;0;L;<font> 005A;;;;N;;;;;
+1D44E;MATHEMATICAL ITALIC SMALL A;Ll;0;L;<font> 0061;;;;N;;;;;
+1D44F;MATHEMATICAL ITALIC SMALL B;Ll;0;L;<font> 0062;;;;N;;;;;
+1D450;MATHEMATICAL ITALIC SMALL C;Ll;0;L;<font> 0063;;;;N;;;;;
+1D451;MATHEMATICAL ITALIC SMALL D;Ll;0;L;<font> 0064;;;;N;;;;;
+1D452;MATHEMATICAL ITALIC SMALL E;Ll;0;L;<font> 0065;;;;N;;;;;
+1D453;MATHEMATICAL ITALIC SMALL F;Ll;0;L;<font> 0066;;;;N;;;;;
+1D454;MATHEMATICAL ITALIC SMALL G;Ll;0;L;<font> 0067;;;;N;;;;;
+1D456;MATHEMATICAL ITALIC SMALL I;Ll;0;L;<font> 0069;;;;N;;;;;
+1D457;MATHEMATICAL ITALIC SMALL J;Ll;0;L;<font> 006A;;;;N;;;;;
+1D458;MATHEMATICAL ITALIC SMALL K;Ll;0;L;<font> 006B;;;;N;;;;;
+1D459;MATHEMATICAL ITALIC SMALL L;Ll;0;L;<font> 006C;;;;N;;;;;
+1D45A;MATHEMATICAL ITALIC SMALL M;Ll;0;L;<font> 006D;;;;N;;;;;
+1D45B;MATHEMATICAL ITALIC SMALL N;Ll;0;L;<font> 006E;;;;N;;;;;
+1D45C;MATHEMATICAL ITALIC SMALL O;Ll;0;L;<font> 006F;;;;N;;;;;
+1D45D;MATHEMATICAL ITALIC SMALL P;Ll;0;L;<font> 0070;;;;N;;;;;
+1D45E;MATHEMATICAL ITALIC SMALL Q;Ll;0;L;<font> 0071;;;;N;;;;;
+1D45F;MATHEMATICAL ITALIC SMALL R;Ll;0;L;<font> 0072;;;;N;;;;;
+1D460;MATHEMATICAL ITALIC SMALL S;Ll;0;L;<font> 0073;;;;N;;;;;
+1D461;MATHEMATICAL ITALIC SMALL T;Ll;0;L;<font> 0074;;;;N;;;;;
+1D462;MATHEMATICAL ITALIC SMALL U;Ll;0;L;<font> 0075;;;;N;;;;;
+1D463;MATHEMATICAL ITALIC SMALL V;Ll;0;L;<font> 0076;;;;N;;;;;
+1D464;MATHEMATICAL ITALIC SMALL W;Ll;0;L;<font> 0077;;;;N;;;;;
+1D465;MATHEMATICAL ITALIC SMALL X;Ll;0;L;<font> 0078;;;;N;;;;;
+1D466;MATHEMATICAL ITALIC SMALL Y;Ll;0;L;<font> 0079;;;;N;;;;;
+1D467;MATHEMATICAL ITALIC SMALL Z;Ll;0;L;<font> 007A;;;;N;;;;;
+1D468;MATHEMATICAL BOLD ITALIC CAPITAL A;Lu;0;L;<font> 0041;;;;N;;;;;
+1D469;MATHEMATICAL BOLD ITALIC CAPITAL B;Lu;0;L;<font> 0042;;;;N;;;;;
+1D46A;MATHEMATICAL BOLD ITALIC CAPITAL C;Lu;0;L;<font> 0043;;;;N;;;;;
+1D46B;MATHEMATICAL BOLD ITALIC CAPITAL D;Lu;0;L;<font> 0044;;;;N;;;;;
+1D46C;MATHEMATICAL BOLD ITALIC CAPITAL E;Lu;0;L;<font> 0045;;;;N;;;;;
+1D46D;MATHEMATICAL BOLD ITALIC CAPITAL F;Lu;0;L;<font> 0046;;;;N;;;;;
+1D46E;MATHEMATICAL BOLD ITALIC CAPITAL G;Lu;0;L;<font> 0047;;;;N;;;;;
+1D46F;MATHEMATICAL BOLD ITALIC CAPITAL H;Lu;0;L;<font> 0048;;;;N;;;;;
+1D470;MATHEMATICAL BOLD ITALIC CAPITAL I;Lu;0;L;<font> 0049;;;;N;;;;;
+1D471;MATHEMATICAL BOLD ITALIC CAPITAL J;Lu;0;L;<font> 004A;;;;N;;;;;
+1D472;MATHEMATICAL BOLD ITALIC CAPITAL K;Lu;0;L;<font> 004B;;;;N;;;;;
+1D473;MATHEMATICAL BOLD ITALIC CAPITAL L;Lu;0;L;<font> 004C;;;;N;;;;;
+1D474;MATHEMATICAL BOLD ITALIC CAPITAL M;Lu;0;L;<font> 004D;;;;N;;;;;
+1D475;MATHEMATICAL BOLD ITALIC CAPITAL N;Lu;0;L;<font> 004E;;;;N;;;;;
+1D476;MATHEMATICAL BOLD ITALIC CAPITAL O;Lu;0;L;<font> 004F;;;;N;;;;;
+1D477;MATHEMATICAL BOLD ITALIC CAPITAL P;Lu;0;L;<font> 0050;;;;N;;;;;
+1D478;MATHEMATICAL BOLD ITALIC CAPITAL Q;Lu;0;L;<font> 0051;;;;N;;;;;
+1D479;MATHEMATICAL BOLD ITALIC CAPITAL R;Lu;0;L;<font> 0052;;;;N;;;;;
+1D47A;MATHEMATICAL BOLD ITALIC CAPITAL S;Lu;0;L;<font> 0053;;;;N;;;;;
+1D47B;MATHEMATICAL BOLD ITALIC CAPITAL T;Lu;0;L;<font> 0054;;;;N;;;;;
+1D47C;MATHEMATICAL BOLD ITALIC CAPITAL U;Lu;0;L;<font> 0055;;;;N;;;;;
+1D47D;MATHEMATICAL BOLD ITALIC CAPITAL V;Lu;0;L;<font> 0056;;;;N;;;;;
+1D47E;MATHEMATICAL BOLD ITALIC CAPITAL W;Lu;0;L;<font> 0057;;;;N;;;;;
+1D47F;MATHEMATICAL BOLD ITALIC CAPITAL X;Lu;0;L;<font> 0058;;;;N;;;;;
+1D480;MATHEMATICAL BOLD ITALIC CAPITAL Y;Lu;0;L;<font> 0059;;;;N;;;;;
+1D481;MATHEMATICAL BOLD ITALIC CAPITAL Z;Lu;0;L;<font> 005A;;;;N;;;;;
+1D482;MATHEMATICAL BOLD ITALIC SMALL A;Ll;0;L;<font> 0061;;;;N;;;;;
+1D483;MATHEMATICAL BOLD ITALIC SMALL B;Ll;0;L;<font> 0062;;;;N;;;;;
+1D484;MATHEMATICAL BOLD ITALIC SMALL C;Ll;0;L;<font> 0063;;;;N;;;;;
+1D485;MATHEMATICAL BOLD ITALIC SMALL D;Ll;0;L;<font> 0064;;;;N;;;;;
+1D486;MATHEMATICAL BOLD ITALIC SMALL E;Ll;0;L;<font> 0065;;;;N;;;;;
+1D487;MATHEMATICAL BOLD ITALIC SMALL F;Ll;0;L;<font> 0066;;;;N;;;;;
+1D488;MATHEMATICAL BOLD ITALIC SMALL G;Ll;0;L;<font> 0067;;;;N;;;;;
+1D489;MATHEMATICAL BOLD ITALIC SMALL H;Ll;0;L;<font> 0068;;;;N;;;;;
+1D48A;MATHEMATICAL BOLD ITALIC SMALL I;Ll;0;L;<font> 0069;;;;N;;;;;
+1D48B;MATHEMATICAL BOLD ITALIC SMALL J;Ll;0;L;<font> 006A;;;;N;;;;;
+1D48C;MATHEMATICAL BOLD ITALIC SMALL K;Ll;0;L;<font> 006B;;;;N;;;;;
+1D48D;MATHEMATICAL BOLD ITALIC SMALL L;Ll;0;L;<font> 006C;;;;N;;;;;
+1D48E;MATHEMATICAL BOLD ITALIC SMALL M;Ll;0;L;<font> 006D;;;;N;;;;;
+1D48F;MATHEMATICAL BOLD ITALIC SMALL N;Ll;0;L;<font> 006E;;;;N;;;;;
+1D490;MATHEMATICAL BOLD ITALIC SMALL O;Ll;0;L;<font> 006F;;;;N;;;;;
+1D491;MATHEMATICAL BOLD ITALIC SMALL P;Ll;0;L;<font> 0070;;;;N;;;;;
+1D492;MATHEMATICAL BOLD ITALIC SMALL Q;Ll;0;L;<font> 0071;;;;N;;;;;
+1D493;MATHEMATICAL BOLD ITALIC SMALL R;Ll;0;L;<font> 0072;;;;N;;;;;
+1D494;MATHEMATICAL BOLD ITALIC SMALL S;Ll;0;L;<font> 0073;;;;N;;;;;
+1D495;MATHEMATICAL BOLD ITALIC SMALL T;Ll;0;L;<font> 0074;;;;N;;;;;
+1D496;MATHEMATICAL BOLD ITALIC SMALL U;Ll;0;L;<font> 0075;;;;N;;;;;
+1D497;MATHEMATICAL BOLD ITALIC SMALL V;Ll;0;L;<font> 0076;;;;N;;;;;
+1D498;MATHEMATICAL BOLD ITALIC SMALL W;Ll;0;L;<font> 0077;;;;N;;;;;
+1D499;MATHEMATICAL BOLD ITALIC SMALL X;Ll;0;L;<font> 0078;;;;N;;;;;
+1D49A;MATHEMATICAL BOLD ITALIC SMALL Y;Ll;0;L;<font> 0079;;;;N;;;;;
+1D49B;MATHEMATICAL BOLD ITALIC SMALL Z;Ll;0;L;<font> 007A;;;;N;;;;;
+1D49C;MATHEMATICAL SCRIPT CAPITAL A;Lu;0;L;<font> 0041;;;;N;;;;;
+1D49E;MATHEMATICAL SCRIPT CAPITAL C;Lu;0;L;<font> 0043;;;;N;;;;;
+1D49F;MATHEMATICAL SCRIPT CAPITAL D;Lu;0;L;<font> 0044;;;;N;;;;;
+1D4A2;MATHEMATICAL SCRIPT CAPITAL G;Lu;0;L;<font> 0047;;;;N;;;;;
+1D4A5;MATHEMATICAL SCRIPT CAPITAL J;Lu;0;L;<font> 004A;;;;N;;;;;
+1D4A6;MATHEMATICAL SCRIPT CAPITAL K;Lu;0;L;<font> 004B;;;;N;;;;;
+1D4A9;MATHEMATICAL SCRIPT CAPITAL N;Lu;0;L;<font> 004E;;;;N;;;;;
+1D4AA;MATHEMATICAL SCRIPT CAPITAL O;Lu;0;L;<font> 004F;;;;N;;;;;
+1D4AB;MATHEMATICAL SCRIPT CAPITAL P;Lu;0;L;<font> 0050;;;;N;;;;;
+1D4AC;MATHEMATICAL SCRIPT CAPITAL Q;Lu;0;L;<font> 0051;;;;N;;;;;
+1D4AE;MATHEMATICAL SCRIPT CAPITAL S;Lu;0;L;<font> 0053;;;;N;;;;;
+1D4AF;MATHEMATICAL SCRIPT CAPITAL T;Lu;0;L;<font> 0054;;;;N;;;;;
+1D4B0;MATHEMATICAL SCRIPT CAPITAL U;Lu;0;L;<font> 0055;;;;N;;;;;
+1D4B1;MATHEMATICAL SCRIPT CAPITAL V;Lu;0;L;<font> 0056;;;;N;;;;;
+1D4B2;MATHEMATICAL SCRIPT CAPITAL W;Lu;0;L;<font> 0057;;;;N;;;;;
+1D4B3;MATHEMATICAL SCRIPT CAPITAL X;Lu;0;L;<font> 0058;;;;N;;;;;
+1D4B4;MATHEMATICAL SCRIPT CAPITAL Y;Lu;0;L;<font> 0059;;;;N;;;;;
+1D4B5;MATHEMATICAL SCRIPT CAPITAL Z;Lu;0;L;<font> 005A;;;;N;;;;;
+1D4B6;MATHEMATICAL SCRIPT SMALL A;Ll;0;L;<font> 0061;;;;N;;;;;
+1D4B7;MATHEMATICAL SCRIPT SMALL B;Ll;0;L;<font> 0062;;;;N;;;;;
+1D4B8;MATHEMATICAL SCRIPT SMALL C;Ll;0;L;<font> 0063;;;;N;;;;;
+1D4B9;MATHEMATICAL SCRIPT SMALL D;Ll;0;L;<font> 0064;;;;N;;;;;
+1D4BB;MATHEMATICAL SCRIPT SMALL F;Ll;0;L;<font> 0066;;;;N;;;;;
+1D4BD;MATHEMATICAL SCRIPT SMALL H;Ll;0;L;<font> 0068;;;;N;;;;;
+1D4BE;MATHEMATICAL SCRIPT SMALL I;Ll;0;L;<font> 0069;;;;N;;;;;
+1D4BF;MATHEMATICAL SCRIPT SMALL J;Ll;0;L;<font> 006A;;;;N;;;;;
+1D4C0;MATHEMATICAL SCRIPT SMALL K;Ll;0;L;<font> 006B;;;;N;;;;;
+1D4C1;MATHEMATICAL SCRIPT SMALL L;Ll;0;L;<font> 006C;;;;N;;;;;
+1D4C2;MATHEMATICAL SCRIPT SMALL M;Ll;0;L;<font> 006D;;;;N;;;;;
+1D4C3;MATHEMATICAL SCRIPT SMALL N;Ll;0;L;<font> 006E;;;;N;;;;;
+1D4C5;MATHEMATICAL SCRIPT SMALL P;Ll;0;L;<font> 0070;;;;N;;;;;
+1D4C6;MATHEMATICAL SCRIPT SMALL Q;Ll;0;L;<font> 0071;;;;N;;;;;
+1D4C7;MATHEMATICAL SCRIPT SMALL R;Ll;0;L;<font> 0072;;;;N;;;;;
+1D4C8;MATHEMATICAL SCRIPT SMALL S;Ll;0;L;<font> 0073;;;;N;;;;;
+1D4C9;MATHEMATICAL SCRIPT SMALL T;Ll;0;L;<font> 0074;;;;N;;;;;
+1D4CA;MATHEMATICAL SCRIPT SMALL U;Ll;0;L;<font> 0075;;;;N;;;;;
+1D4CB;MATHEMATICAL SCRIPT SMALL V;Ll;0;L;<font> 0076;;;;N;;;;;
+1D4CC;MATHEMATICAL SCRIPT SMALL W;Ll;0;L;<font> 0077;;;;N;;;;;
+1D4CD;MATHEMATICAL SCRIPT SMALL X;Ll;0;L;<font> 0078;;;;N;;;;;
+1D4CE;MATHEMATICAL SCRIPT SMALL Y;Ll;0;L;<font> 0079;;;;N;;;;;
+1D4CF;MATHEMATICAL SCRIPT SMALL Z;Ll;0;L;<font> 007A;;;;N;;;;;
+1D4D0;MATHEMATICAL BOLD SCRIPT CAPITAL A;Lu;0;L;<font> 0041;;;;N;;;;;
+1D4D1;MATHEMATICAL BOLD SCRIPT CAPITAL B;Lu;0;L;<font> 0042;;;;N;;;;;
+1D4D2;MATHEMATICAL BOLD SCRIPT CAPITAL C;Lu;0;L;<font> 0043;;;;N;;;;;
+1D4D3;MATHEMATICAL BOLD SCRIPT CAPITAL D;Lu;0;L;<font> 0044;;;;N;;;;;
+1D4D4;MATHEMATICAL BOLD SCRIPT CAPITAL E;Lu;0;L;<font> 0045;;;;N;;;;;
+1D4D5;MATHEMATICAL BOLD SCRIPT CAPITAL F;Lu;0;L;<font> 0046;;;;N;;;;;
+1D4D6;MATHEMATICAL BOLD SCRIPT CAPITAL G;Lu;0;L;<font> 0047;;;;N;;;;;
+1D4D7;MATHEMATICAL BOLD SCRIPT CAPITAL H;Lu;0;L;<font> 0048;;;;N;;;;;
+1D4D8;MATHEMATICAL BOLD SCRIPT CAPITAL I;Lu;0;L;<font> 0049;;;;N;;;;;
+1D4D9;MATHEMATICAL BOLD SCRIPT CAPITAL J;Lu;0;L;<font> 004A;;;;N;;;;;
+1D4DA;MATHEMATICAL BOLD SCRIPT CAPITAL K;Lu;0;L;<font> 004B;;;;N;;;;;
+1D4DB;MATHEMATICAL BOLD SCRIPT CAPITAL L;Lu;0;L;<font> 004C;;;;N;;;;;
+1D4DC;MATHEMATICAL BOLD SCRIPT CAPITAL M;Lu;0;L;<font> 004D;;;;N;;;;;
+1D4DD;MATHEMATICAL BOLD SCRIPT CAPITAL N;Lu;0;L;<font> 004E;;;;N;;;;;
+1D4DE;MATHEMATICAL BOLD SCRIPT CAPITAL O;Lu;0;L;<font> 004F;;;;N;;;;;
+1D4DF;MATHEMATICAL BOLD SCRIPT CAPITAL P;Lu;0;L;<font> 0050;;;;N;;;;;
+1D4E0;MATHEMATICAL BOLD SCRIPT CAPITAL Q;Lu;0;L;<font> 0051;;;;N;;;;;
+1D4E1;MATHEMATICAL BOLD SCRIPT CAPITAL R;Lu;0;L;<font> 0052;;;;N;;;;;
+1D4E2;MATHEMATICAL BOLD SCRIPT CAPITAL S;Lu;0;L;<font> 0053;;;;N;;;;;
+1D4E3;MATHEMATICAL BOLD SCRIPT CAPITAL T;Lu;0;L;<font> 0054;;;;N;;;;;
+1D4E4;MATHEMATICAL BOLD SCRIPT CAPITAL U;Lu;0;L;<font> 0055;;;;N;;;;;
+1D4E5;MATHEMATICAL BOLD SCRIPT CAPITAL V;Lu;0;L;<font> 0056;;;;N;;;;;
+1D4E6;MATHEMATICAL BOLD SCRIPT CAPITAL W;Lu;0;L;<font> 0057;;;;N;;;;;
+1D4E7;MATHEMATICAL BOLD SCRIPT CAPITAL X;Lu;0;L;<font> 0058;;;;N;;;;;
+1D4E8;MATHEMATICAL BOLD SCRIPT CAPITAL Y;Lu;0;L;<font> 0059;;;;N;;;;;
+1D4E9;MATHEMATICAL BOLD SCRIPT CAPITAL Z;Lu;0;L;<font> 005A;;;;N;;;;;
+1D4EA;MATHEMATICAL BOLD SCRIPT SMALL A;Ll;0;L;<font> 0061;;;;N;;;;;
+1D4EB;MATHEMATICAL BOLD SCRIPT SMALL B;Ll;0;L;<font> 0062;;;;N;;;;;
+1D4EC;MATHEMATICAL BOLD SCRIPT SMALL C;Ll;0;L;<font> 0063;;;;N;;;;;
+1D4ED;MATHEMATICAL BOLD SCRIPT SMALL D;Ll;0;L;<font> 0064;;;;N;;;;;
+1D4EE;MATHEMATICAL BOLD SCRIPT SMALL E;Ll;0;L;<font> 0065;;;;N;;;;;
+1D4EF;MATHEMATICAL BOLD SCRIPT SMALL F;Ll;0;L;<font> 0066;;;;N;;;;;
+1D4F0;MATHEMATICAL BOLD SCRIPT SMALL G;Ll;0;L;<font> 0067;;;;N;;;;;
+1D4F1;MATHEMATICAL BOLD SCRIPT SMALL H;Ll;0;L;<font> 0068;;;;N;;;;;
+1D4F2;MATHEMATICAL BOLD SCRIPT SMALL I;Ll;0;L;<font> 0069;;;;N;;;;;
+1D4F3;MATHEMATICAL BOLD SCRIPT SMALL J;Ll;0;L;<font> 006A;;;;N;;;;;
+1D4F4;MATHEMATICAL BOLD SCRIPT SMALL K;Ll;0;L;<font> 006B;;;;N;;;;;
+1D4F5;MATHEMATICAL BOLD SCRIPT SMALL L;Ll;0;L;<font> 006C;;;;N;;;;;
+1D4F6;MATHEMATICAL BOLD SCRIPT SMALL M;Ll;0;L;<font> 006D;;;;N;;;;;
+1D4F7;MATHEMATICAL BOLD SCRIPT SMALL N;Ll;0;L;<font> 006E;;;;N;;;;;
+1D4F8;MATHEMATICAL BOLD SCRIPT SMALL O;Ll;0;L;<font> 006F;;;;N;;;;;
+1D4F9;MATHEMATICAL BOLD SCRIPT SMALL P;Ll;0;L;<font> 0070;;;;N;;;;;
+1D4FA;MATHEMATICAL BOLD SCRIPT SMALL Q;Ll;0;L;<font> 0071;;;;N;;;;;
+1D4FB;MATHEMATICAL BOLD SCRIPT SMALL R;Ll;0;L;<font> 0072;;;;N;;;;;
+1D4FC;MATHEMATICAL BOLD SCRIPT SMALL S;Ll;0;L;<font> 0073;;;;N;;;;;
+1D4FD;MATHEMATICAL BOLD SCRIPT SMALL T;Ll;0;L;<font> 0074;;;;N;;;;;
+1D4FE;MATHEMATICAL BOLD SCRIPT SMALL U;Ll;0;L;<font> 0075;;;;N;;;;;
+1D4FF;MATHEMATICAL BOLD SCRIPT SMALL V;Ll;0;L;<font> 0076;;;;N;;;;;
+1D500;MATHEMATICAL BOLD SCRIPT SMALL W;Ll;0;L;<font> 0077;;;;N;;;;;
+1D501;MATHEMATICAL BOLD SCRIPT SMALL X;Ll;0;L;<font> 0078;;;;N;;;;;
+1D502;MATHEMATICAL BOLD SCRIPT SMALL Y;Ll;0;L;<font> 0079;;;;N;;;;;
+1D503;MATHEMATICAL BOLD SCRIPT SMALL Z;Ll;0;L;<font> 007A;;;;N;;;;;
+1D504;MATHEMATICAL FRAKTUR CAPITAL A;Lu;0;L;<font> 0041;;;;N;;;;;
+1D505;MATHEMATICAL FRAKTUR CAPITAL B;Lu;0;L;<font> 0042;;;;N;;;;;
+1D507;MATHEMATICAL FRAKTUR CAPITAL D;Lu;0;L;<font> 0044;;;;N;;;;;
+1D508;MATHEMATICAL FRAKTUR CAPITAL E;Lu;0;L;<font> 0045;;;;N;;;;;
+1D509;MATHEMATICAL FRAKTUR CAPITAL F;Lu;0;L;<font> 0046;;;;N;;;;;
+1D50A;MATHEMATICAL FRAKTUR CAPITAL G;Lu;0;L;<font> 0047;;;;N;;;;;
+1D50D;MATHEMATICAL FRAKTUR CAPITAL J;Lu;0;L;<font> 004A;;;;N;;;;;
+1D50E;MATHEMATICAL FRAKTUR CAPITAL K;Lu;0;L;<font> 004B;;;;N;;;;;
+1D50F;MATHEMATICAL FRAKTUR CAPITAL L;Lu;0;L;<font> 004C;;;;N;;;;;
+1D510;MATHEMATICAL FRAKTUR CAPITAL M;Lu;0;L;<font> 004D;;;;N;;;;;
+1D511;MATHEMATICAL FRAKTUR CAPITAL N;Lu;0;L;<font> 004E;;;;N;;;;;
+1D512;MATHEMATICAL FRAKTUR CAPITAL O;Lu;0;L;<font> 004F;;;;N;;;;;
+1D513;MATHEMATICAL FRAKTUR CAPITAL P;Lu;0;L;<font> 0050;;;;N;;;;;
+1D514;MATHEMATICAL FRAKTUR CAPITAL Q;Lu;0;L;<font> 0051;;;;N;;;;;
+1D516;MATHEMATICAL FRAKTUR CAPITAL S;Lu;0;L;<font> 0053;;;;N;;;;;
+1D517;MATHEMATICAL FRAKTUR CAPITAL T;Lu;0;L;<font> 0054;;;;N;;;;;
+1D518;MATHEMATICAL FRAKTUR CAPITAL U;Lu;0;L;<font> 0055;;;;N;;;;;
+1D519;MATHEMATICAL FRAKTUR CAPITAL V;Lu;0;L;<font> 0056;;;;N;;;;;
+1D51A;MATHEMATICAL FRAKTUR CAPITAL W;Lu;0;L;<font> 0057;;;;N;;;;;
+1D51B;MATHEMATICAL FRAKTUR CAPITAL X;Lu;0;L;<font> 0058;;;;N;;;;;
+1D51C;MATHEMATICAL FRAKTUR CAPITAL Y;Lu;0;L;<font> 0059;;;;N;;;;;
+1D51E;MATHEMATICAL FRAKTUR SMALL A;Ll;0;L;<font> 0061;;;;N;;;;;
+1D51F;MATHEMATICAL FRAKTUR SMALL B;Ll;0;L;<font> 0062;;;;N;;;;;
+1D520;MATHEMATICAL FRAKTUR SMALL C;Ll;0;L;<font> 0063;;;;N;;;;;
+1D521;MATHEMATICAL FRAKTUR SMALL D;Ll;0;L;<font> 0064;;;;N;;;;;
+1D522;MATHEMATICAL FRAKTUR SMALL E;Ll;0;L;<font> 0065;;;;N;;;;;
+1D523;MATHEMATICAL FRAKTUR SMALL F;Ll;0;L;<font> 0066;;;;N;;;;;
+1D524;MATHEMATICAL FRAKTUR SMALL G;Ll;0;L;<font> 0067;;;;N;;;;;
+1D525;MATHEMATICAL FRAKTUR SMALL H;Ll;0;L;<font> 0068;;;;N;;;;;
+1D526;MATHEMATICAL FRAKTUR SMALL I;Ll;0;L;<font> 0069;;;;N;;;;;
+1D527;MATHEMATICAL FRAKTUR SMALL J;Ll;0;L;<font> 006A;;;;N;;;;;
+1D528;MATHEMATICAL FRAKTUR SMALL K;Ll;0;L;<font> 006B;;;;N;;;;;
+1D529;MATHEMATICAL FRAKTUR SMALL L;Ll;0;L;<font> 006C;;;;N;;;;;
+1D52A;MATHEMATICAL FRAKTUR SMALL M;Ll;0;L;<font> 006D;;;;N;;;;;
+1D52B;MATHEMATICAL FRAKTUR SMALL N;Ll;0;L;<font> 006E;;;;N;;;;;
+1D52C;MATHEMATICAL FRAKTUR SMALL O;Ll;0;L;<font> 006F;;;;N;;;;;
+1D52D;MATHEMATICAL FRAKTUR SMALL P;Ll;0;L;<font> 0070;;;;N;;;;;
+1D52E;MATHEMATICAL FRAKTUR SMALL Q;Ll;0;L;<font> 0071;;;;N;;;;;
+1D52F;MATHEMATICAL FRAKTUR SMALL R;Ll;0;L;<font> 0072;;;;N;;;;;
+1D530;MATHEMATICAL FRAKTUR SMALL S;Ll;0;L;<font> 0073;;;;N;;;;;
+1D531;MATHEMATICAL FRAKTUR SMALL T;Ll;0;L;<font> 0074;;;;N;;;;;
+1D532;MATHEMATICAL FRAKTUR SMALL U;Ll;0;L;<font> 0075;;;;N;;;;;
+1D533;MATHEMATICAL FRAKTUR SMALL V;Ll;0;L;<font> 0076;;;;N;;;;;
+1D534;MATHEMATICAL FRAKTUR SMALL W;Ll;0;L;<font> 0077;;;;N;;;;;
+1D535;MATHEMATICAL FRAKTUR SMALL X;Ll;0;L;<font> 0078;;;;N;;;;;
+1D536;MATHEMATICAL FRAKTUR SMALL Y;Ll;0;L;<font> 0079;;;;N;;;;;
+1D537;MATHEMATICAL FRAKTUR SMALL Z;Ll;0;L;<font> 007A;;;;N;;;;;
+1D538;MATHEMATICAL DOUBLE-STRUCK CAPITAL A;Lu;0;L;<font> 0041;;;;N;;;;;
+1D539;MATHEMATICAL DOUBLE-STRUCK CAPITAL B;Lu;0;L;<font> 0042;;;;N;;;;;
+1D53B;MATHEMATICAL DOUBLE-STRUCK CAPITAL D;Lu;0;L;<font> 0044;;;;N;;;;;
+1D53C;MATHEMATICAL DOUBLE-STRUCK CAPITAL E;Lu;0;L;<font> 0045;;;;N;;;;;
+1D53D;MATHEMATICAL DOUBLE-STRUCK CAPITAL F;Lu;0;L;<font> 0046;;;;N;;;;;
+1D53E;MATHEMATICAL DOUBLE-STRUCK CAPITAL G;Lu;0;L;<font> 0047;;;;N;;;;;
+1D540;MATHEMATICAL DOUBLE-STRUCK CAPITAL I;Lu;0;L;<font> 0049;;;;N;;;;;
+1D541;MATHEMATICAL DOUBLE-STRUCK CAPITAL J;Lu;0;L;<font> 004A;;;;N;;;;;
+1D542;MATHEMATICAL DOUBLE-STRUCK CAPITAL K;Lu;0;L;<font> 004B;;;;N;;;;;
+1D543;MATHEMATICAL DOUBLE-STRUCK CAPITAL L;Lu;0;L;<font> 004C;;;;N;;;;;
+1D544;MATHEMATICAL DOUBLE-STRUCK CAPITAL M;Lu;0;L;<font> 004D;;;;N;;;;;
+1D546;MATHEMATICAL DOUBLE-STRUCK CAPITAL O;Lu;0;L;<font> 004F;;;;N;;;;;
+1D54A;MATHEMATICAL DOUBLE-STRUCK CAPITAL S;Lu;0;L;<font> 0053;;;;N;;;;;
+1D54B;MATHEMATICAL DOUBLE-STRUCK CAPITAL T;Lu;0;L;<font> 0054;;;;N;;;;;
+1D54C;MATHEMATICAL DOUBLE-STRUCK CAPITAL U;Lu;0;L;<font> 0055;;;;N;;;;;
+1D54D;MATHEMATICAL DOUBLE-STRUCK CAPITAL V;Lu;0;L;<font> 0056;;;;N;;;;;
+1D54E;MATHEMATICAL DOUBLE-STRUCK CAPITAL W;Lu;0;L;<font> 0057;;;;N;;;;;
+1D54F;MATHEMATICAL DOUBLE-STRUCK CAPITAL X;Lu;0;L;<font> 0058;;;;N;;;;;
+1D550;MATHEMATICAL DOUBLE-STRUCK CAPITAL Y;Lu;0;L;<font> 0059;;;;N;;;;;
+1D552;MATHEMATICAL DOUBLE-STRUCK SMALL A;Ll;0;L;<font> 0061;;;;N;;;;;
+1D553;MATHEMATICAL DOUBLE-STRUCK SMALL B;Ll;0;L;<font> 0062;;;;N;;;;;
+1D554;MATHEMATICAL DOUBLE-STRUCK SMALL C;Ll;0;L;<font> 0063;;;;N;;;;;
+1D555;MATHEMATICAL DOUBLE-STRUCK SMALL D;Ll;0;L;<font> 0064;;;;N;;;;;
+1D556;MATHEMATICAL DOUBLE-STRUCK SMALL E;Ll;0;L;<font> 0065;;;;N;;;;;
+1D557;MATHEMATICAL DOUBLE-STRUCK SMALL F;Ll;0;L;<font> 0066;;;;N;;;;;
+1D558;MATHEMATICAL DOUBLE-STRUCK SMALL G;Ll;0;L;<font> 0067;;;;N;;;;;
+1D559;MATHEMATICAL DOUBLE-STRUCK SMALL H;Ll;0;L;<font> 0068;;;;N;;;;;
+1D55A;MATHEMATICAL DOUBLE-STRUCK SMALL I;Ll;0;L;<font> 0069;;;;N;;;;;
+1D55B;MATHEMATICAL DOUBLE-STRUCK SMALL J;Ll;0;L;<font> 006A;;;;N;;;;;
+1D55C;MATHEMATICAL DOUBLE-STRUCK SMALL K;Ll;0;L;<font> 006B;;;;N;;;;;
+1D55D;MATHEMATICAL DOUBLE-STRUCK SMALL L;Ll;0;L;<font> 006C;;;;N;;;;;
+1D55E;MATHEMATICAL DOUBLE-STRUCK SMALL M;Ll;0;L;<font> 006D;;;;N;;;;;
+1D55F;MATHEMATICAL DOUBLE-STRUCK SMALL N;Ll;0;L;<font> 006E;;;;N;;;;;
+1D560;MATHEMATICAL DOUBLE-STRUCK SMALL O;Ll;0;L;<font> 006F;;;;N;;;;;
+1D561;MATHEMATICAL DOUBLE-STRUCK SMALL P;Ll;0;L;<font> 0070;;;;N;;;;;
+1D562;MATHEMATICAL DOUBLE-STRUCK SMALL Q;Ll;0;L;<font> 0071;;;;N;;;;;
+1D563;MATHEMATICAL DOUBLE-STRUCK SMALL R;Ll;0;L;<font> 0072;;;;N;;;;;
+1D564;MATHEMATICAL DOUBLE-STRUCK SMALL S;Ll;0;L;<font> 0073;;;;N;;;;;
+1D565;MATHEMATICAL DOUBLE-STRUCK SMALL T;Ll;0;L;<font> 0074;;;;N;;;;;
+1D566;MATHEMATICAL DOUBLE-STRUCK SMALL U;Ll;0;L;<font> 0075;;;;N;;;;;
+1D567;MATHEMATICAL DOUBLE-STRUCK SMALL V;Ll;0;L;<font> 0076;;;;N;;;;;
+1D568;MATHEMATICAL DOUBLE-STRUCK SMALL W;Ll;0;L;<font> 0077;;;;N;;;;;
+1D569;MATHEMATICAL DOUBLE-STRUCK SMALL X;Ll;0;L;<font> 0078;;;;N;;;;;
+1D56A;MATHEMATICAL DOUBLE-STRUCK SMALL Y;Ll;0;L;<font> 0079;;;;N;;;;;
+1D56B;MATHEMATICAL DOUBLE-STRUCK SMALL Z;Ll;0;L;<font> 007A;;;;N;;;;;
+1D56C;MATHEMATICAL BOLD FRAKTUR CAPITAL A;Lu;0;L;<font> 0041;;;;N;;;;;
+1D56D;MATHEMATICAL BOLD FRAKTUR CAPITAL B;Lu;0;L;<font> 0042;;;;N;;;;;
+1D56E;MATHEMATICAL BOLD FRAKTUR CAPITAL C;Lu;0;L;<font> 0043;;;;N;;;;;
+1D56F;MATHEMATICAL BOLD FRAKTUR CAPITAL D;Lu;0;L;<font> 0044;;;;N;;;;;
+1D570;MATHEMATICAL BOLD FRAKTUR CAPITAL E;Lu;0;L;<font> 0045;;;;N;;;;;
+1D571;MATHEMATICAL BOLD FRAKTUR CAPITAL F;Lu;0;L;<font> 0046;;;;N;;;;;
+1D572;MATHEMATICAL BOLD FRAKTUR CAPITAL G;Lu;0;L;<font> 0047;;;;N;;;;;
+1D573;MATHEMATICAL BOLD FRAKTUR CAPITAL H;Lu;0;L;<font> 0048;;;;N;;;;;
+1D574;MATHEMATICAL BOLD FRAKTUR CAPITAL I;Lu;0;L;<font> 0049;;;;N;;;;;
+1D575;MATHEMATICAL BOLD FRAKTUR CAPITAL J;Lu;0;L;<font> 004A;;;;N;;;;;
+1D576;MATHEMATICAL BOLD FRAKTUR CAPITAL K;Lu;0;L;<font> 004B;;;;N;;;;;
+1D577;MATHEMATICAL BOLD FRAKTUR CAPITAL L;Lu;0;L;<font> 004C;;;;N;;;;;
+1D578;MATHEMATICAL BOLD FRAKTUR CAPITAL M;Lu;0;L;<font> 004D;;;;N;;;;;
+1D579;MATHEMATICAL BOLD FRAKTUR CAPITAL N;Lu;0;L;<font> 004E;;;;N;;;;;
+1D57A;MATHEMATICAL BOLD FRAKTUR CAPITAL O;Lu;0;L;<font> 004F;;;;N;;;;;
+1D57B;MATHEMATICAL BOLD FRAKTUR CAPITAL P;Lu;0;L;<font> 0050;;;;N;;;;;
+1D57C;MATHEMATICAL BOLD FRAKTUR CAPITAL Q;Lu;0;L;<font> 0051;;;;N;;;;;
+1D57D;MATHEMATICAL BOLD FRAKTUR CAPITAL R;Lu;0;L;<font> 0052;;;;N;;;;;
+1D57E;MATHEMATICAL BOLD FRAKTUR CAPITAL S;Lu;0;L;<font> 0053;;;;N;;;;;
+1D57F;MATHEMATICAL BOLD FRAKTUR CAPITAL T;Lu;0;L;<font> 0054;;;;N;;;;;
+1D580;MATHEMATICAL BOLD FRAKTUR CAPITAL U;Lu;0;L;<font> 0055;;;;N;;;;;
+1D581;MATHEMATICAL BOLD FRAKTUR CAPITAL V;Lu;0;L;<font> 0056;;;;N;;;;;
+1D582;MATHEMATICAL BOLD FRAKTUR CAPITAL W;Lu;0;L;<font> 0057;;;;N;;;;;
+1D583;MATHEMATICAL BOLD FRAKTUR CAPITAL X;Lu;0;L;<font> 0058;;;;N;;;;;
+1D584;MATHEMATICAL BOLD FRAKTUR CAPITAL Y;Lu;0;L;<font> 0059;;;;N;;;;;
+1D585;MATHEMATICAL BOLD FRAKTUR CAPITAL Z;Lu;0;L;<font> 005A;;;;N;;;;;
+1D586;MATHEMATICAL BOLD FRAKTUR SMALL A;Ll;0;L;<font> 0061;;;;N;;;;;
+1D587;MATHEMATICAL BOLD FRAKTUR SMALL B;Ll;0;L;<font> 0062;;;;N;;;;;
+1D588;MATHEMATICAL BOLD FRAKTUR SMALL C;Ll;0;L;<font> 0063;;;;N;;;;;
+1D589;MATHEMATICAL BOLD FRAKTUR SMALL D;Ll;0;L;<font> 0064;;;;N;;;;;
+1D58A;MATHEMATICAL BOLD FRAKTUR SMALL E;Ll;0;L;<font> 0065;;;;N;;;;;
+1D58B;MATHEMATICAL BOLD FRAKTUR SMALL F;Ll;0;L;<font> 0066;;;;N;;;;;
+1D58C;MATHEMATICAL BOLD FRAKTUR SMALL G;Ll;0;L;<font> 0067;;;;N;;;;;
+1D58D;MATHEMATICAL BOLD FRAKTUR SMALL H;Ll;0;L;<font> 0068;;;;N;;;;;
+1D58E;MATHEMATICAL BOLD FRAKTUR SMALL I;Ll;0;L;<font> 0069;;;;N;;;;;
+1D58F;MATHEMATICAL BOLD FRAKTUR SMALL J;Ll;0;L;<font> 006A;;;;N;;;;;
+1D590;MATHEMATICAL BOLD FRAKTUR SMALL K;Ll;0;L;<font> 006B;;;;N;;;;;
+1D591;MATHEMATICAL BOLD FRAKTUR SMALL L;Ll;0;L;<font> 006C;;;;N;;;;;
+1D592;MATHEMATICAL BOLD FRAKTUR SMALL M;Ll;0;L;<font> 006D;;;;N;;;;;
+1D593;MATHEMATICAL BOLD FRAKTUR SMALL N;Ll;0;L;<font> 006E;;;;N;;;;;
+1D594;MATHEMATICAL BOLD FRAKTUR SMALL O;Ll;0;L;<font> 006F;;;;N;;;;;
+1D595;MATHEMATICAL BOLD FRAKTUR SMALL P;Ll;0;L;<font> 0070;;;;N;;;;;
+1D596;MATHEMATICAL BOLD FRAKTUR SMALL Q;Ll;0;L;<font> 0071;;;;N;;;;;
+1D597;MATHEMATICAL BOLD FRAKTUR SMALL R;Ll;0;L;<font> 0072;;;;N;;;;;
+1D598;MATHEMATICAL BOLD FRAKTUR SMALL S;Ll;0;L;<font> 0073;;;;N;;;;;
+1D599;MATHEMATICAL BOLD FRAKTUR SMALL T;Ll;0;L;<font> 0074;;;;N;;;;;
+1D59A;MATHEMATICAL BOLD FRAKTUR SMALL U;Ll;0;L;<font> 0075;;;;N;;;;;
+1D59B;MATHEMATICAL BOLD FRAKTUR SMALL V;Ll;0;L;<font> 0076;;;;N;;;;;
+1D59C;MATHEMATICAL BOLD FRAKTUR SMALL W;Ll;0;L;<font> 0077;;;;N;;;;;
+1D59D;MATHEMATICAL BOLD FRAKTUR SMALL X;Ll;0;L;<font> 0078;;;;N;;;;;
+1D59E;MATHEMATICAL BOLD FRAKTUR SMALL Y;Ll;0;L;<font> 0079;;;;N;;;;;
+1D59F;MATHEMATICAL BOLD FRAKTUR SMALL Z;Ll;0;L;<font> 007A;;;;N;;;;;
+1D5A0;MATHEMATICAL SANS-SERIF CAPITAL A;Lu;0;L;<font> 0041;;;;N;;;;;
+1D5A1;MATHEMATICAL SANS-SERIF CAPITAL B;Lu;0;L;<font> 0042;;;;N;;;;;
+1D5A2;MATHEMATICAL SANS-SERIF CAPITAL C;Lu;0;L;<font> 0043;;;;N;;;;;
+1D5A3;MATHEMATICAL SANS-SERIF CAPITAL D;Lu;0;L;<font> 0044;;;;N;;;;;
+1D5A4;MATHEMATICAL SANS-SERIF CAPITAL E;Lu;0;L;<font> 0045;;;;N;;;;;
+1D5A5;MATHEMATICAL SANS-SERIF CAPITAL F;Lu;0;L;<font> 0046;;;;N;;;;;
+1D5A6;MATHEMATICAL SANS-SERIF CAPITAL G;Lu;0;L;<font> 0047;;;;N;;;;;
+1D5A7;MATHEMATICAL SANS-SERIF CAPITAL H;Lu;0;L;<font> 0048;;;;N;;;;;
+1D5A8;MATHEMATICAL SANS-SERIF CAPITAL I;Lu;0;L;<font> 0049;;;;N;;;;;
+1D5A9;MATHEMATICAL SANS-SERIF CAPITAL J;Lu;0;L;<font> 004A;;;;N;;;;;
+1D5AA;MATHEMATICAL SANS-SERIF CAPITAL K;Lu;0;L;<font> 004B;;;;N;;;;;
+1D5AB;MATHEMATICAL SANS-SERIF CAPITAL L;Lu;0;L;<font> 004C;;;;N;;;;;
+1D5AC;MATHEMATICAL SANS-SERIF CAPITAL M;Lu;0;L;<font> 004D;;;;N;;;;;
+1D5AD;MATHEMATICAL SANS-SERIF CAPITAL N;Lu;0;L;<font> 004E;;;;N;;;;;
+1D5AE;MATHEMATICAL SANS-SERIF CAPITAL O;Lu;0;L;<font> 004F;;;;N;;;;;
+1D5AF;MATHEMATICAL SANS-SERIF CAPITAL P;Lu;0;L;<font> 0050;;;;N;;;;;
+1D5B0;MATHEMATICAL SANS-SERIF CAPITAL Q;Lu;0;L;<font> 0051;;;;N;;;;;
+1D5B1;MATHEMATICAL SANS-SERIF CAPITAL R;Lu;0;L;<font> 0052;;;;N;;;;;
+1D5B2;MATHEMATICAL SANS-SERIF CAPITAL S;Lu;0;L;<font> 0053;;;;N;;;;;
+1D5B3;MATHEMATICAL SANS-SERIF CAPITAL T;Lu;0;L;<font> 0054;;;;N;;;;;
+1D5B4;MATHEMATICAL SANS-SERIF CAPITAL U;Lu;0;L;<font> 0055;;;;N;;;;;
+1D5B5;MATHEMATICAL SANS-SERIF CAPITAL V;Lu;0;L;<font> 0056;;;;N;;;;;
+1D5B6;MATHEMATICAL SANS-SERIF CAPITAL W;Lu;0;L;<font> 0057;;;;N;;;;;
+1D5B7;MATHEMATICAL SANS-SERIF CAPITAL X;Lu;0;L;<font> 0058;;;;N;;;;;
+1D5B8;MATHEMATICAL SANS-SERIF CAPITAL Y;Lu;0;L;<font> 0059;;;;N;;;;;
+1D5B9;MATHEMATICAL SANS-SERIF CAPITAL Z;Lu;0;L;<font> 005A;;;;N;;;;;
+1D5BA;MATHEMATICAL SANS-SERIF SMALL A;Ll;0;L;<font> 0061;;;;N;;;;;
+1D5BB;MATHEMATICAL SANS-SERIF SMALL B;Ll;0;L;<font> 0062;;;;N;;;;;
+1D5BC;MATHEMATICAL SANS-SERIF SMALL C;Ll;0;L;<font> 0063;;;;N;;;;;
+1D5BD;MATHEMATICAL SANS-SERIF SMALL D;Ll;0;L;<font> 0064;;;;N;;;;;
+1D5BE;MATHEMATICAL SANS-SERIF SMALL E;Ll;0;L;<font> 0065;;;;N;;;;;
+1D5BF;MATHEMATICAL SANS-SERIF SMALL F;Ll;0;L;<font> 0066;;;;N;;;;;
+1D5C0;MATHEMATICAL SANS-SERIF SMALL G;Ll;0;L;<font> 0067;;;;N;;;;;
+1D5C1;MATHEMATICAL SANS-SERIF SMALL H;Ll;0;L;<font> 0068;;;;N;;;;;
+1D5C2;MATHEMATICAL SANS-SERIF SMALL I;Ll;0;L;<font> 0069;;;;N;;;;;
+1D5C3;MATHEMATICAL SANS-SERIF SMALL J;Ll;0;L;<font> 006A;;;;N;;;;;
+1D5C4;MATHEMATICAL SANS-SERIF SMALL K;Ll;0;L;<font> 006B;;;;N;;;;;
+1D5C5;MATHEMATICAL SANS-SERIF SMALL L;Ll;0;L;<font> 006C;;;;N;;;;;
+1D5C6;MATHEMATICAL SANS-SERIF SMALL M;Ll;0;L;<font> 006D;;;;N;;;;;
+1D5C7;MATHEMATICAL SANS-SERIF SMALL N;Ll;0;L;<font> 006E;;;;N;;;;;
+1D5C8;MATHEMATICAL SANS-SERIF SMALL O;Ll;0;L;<font> 006F;;;;N;;;;;
+1D5C9;MATHEMATICAL SANS-SERIF SMALL P;Ll;0;L;<font> 0070;;;;N;;;;;
+1D5CA;MATHEMATICAL SANS-SERIF SMALL Q;Ll;0;L;<font> 0071;;;;N;;;;;
+1D5CB;MATHEMATICAL SANS-SERIF SMALL R;Ll;0;L;<font> 0072;;;;N;;;;;
+1D5CC;MATHEMATICAL SANS-SERIF SMALL S;Ll;0;L;<font> 0073;;;;N;;;;;
+1D5CD;MATHEMATICAL SANS-SERIF SMALL T;Ll;0;L;<font> 0074;;;;N;;;;;
+1D5CE;MATHEMATICAL SANS-SERIF SMALL U;Ll;0;L;<font> 0075;;;;N;;;;;
+1D5CF;MATHEMATICAL SANS-SERIF SMALL V;Ll;0;L;<font> 0076;;;;N;;;;;
+1D5D0;MATHEMATICAL SANS-SERIF SMALL W;Ll;0;L;<font> 0077;;;;N;;;;;
+1D5D1;MATHEMATICAL SANS-SERIF SMALL X;Ll;0;L;<font> 0078;;;;N;;;;;
+1D5D2;MATHEMATICAL SANS-SERIF SMALL Y;Ll;0;L;<font> 0079;;;;N;;;;;
+1D5D3;MATHEMATICAL SANS-SERIF SMALL Z;Ll;0;L;<font> 007A;;;;N;;;;;
+1D5D4;MATHEMATICAL SANS-SERIF BOLD CAPITAL A;Lu;0;L;<font> 0041;;;;N;;;;;
+1D5D5;MATHEMATICAL SANS-SERIF BOLD CAPITAL B;Lu;0;L;<font> 0042;;;;N;;;;;
+1D5D6;MATHEMATICAL SANS-SERIF BOLD CAPITAL C;Lu;0;L;<font> 0043;;;;N;;;;;
+1D5D7;MATHEMATICAL SANS-SERIF BOLD CAPITAL D;Lu;0;L;<font> 0044;;;;N;;;;;
+1D5D8;MATHEMATICAL SANS-SERIF BOLD CAPITAL E;Lu;0;L;<font> 0045;;;;N;;;;;
+1D5D9;MATHEMATICAL SANS-SERIF BOLD CAPITAL F;Lu;0;L;<font> 0046;;;;N;;;;;
+1D5DA;MATHEMATICAL SANS-SERIF BOLD CAPITAL G;Lu;0;L;<font> 0047;;;;N;;;;;
+1D5DB;MATHEMATICAL SANS-SERIF BOLD CAPITAL H;Lu;0;L;<font> 0048;;;;N;;;;;
+1D5DC;MATHEMATICAL SANS-SERIF BOLD CAPITAL I;Lu;0;L;<font> 0049;;;;N;;;;;
+1D5DD;MATHEMATICAL SANS-SERIF BOLD CAPITAL J;Lu;0;L;<font> 004A;;;;N;;;;;
+1D5DE;MATHEMATICAL SANS-SERIF BOLD CAPITAL K;Lu;0;L;<font> 004B;;;;N;;;;;
+1D5DF;MATHEMATICAL SANS-SERIF BOLD CAPITAL L;Lu;0;L;<font> 004C;;;;N;;;;;
+1D5E0;MATHEMATICAL SANS-SERIF BOLD CAPITAL M;Lu;0;L;<font> 004D;;;;N;;;;;
+1D5E1;MATHEMATICAL SANS-SERIF BOLD CAPITAL N;Lu;0;L;<font> 004E;;;;N;;;;;
+1D5E2;MATHEMATICAL SANS-SERIF BOLD CAPITAL O;Lu;0;L;<font> 004F;;;;N;;;;;
+1D5E3;MATHEMATICAL SANS-SERIF BOLD CAPITAL P;Lu;0;L;<font> 0050;;;;N;;;;;
+1D5E4;MATHEMATICAL SANS-SERIF BOLD CAPITAL Q;Lu;0;L;<font> 0051;;;;N;;;;;
+1D5E5;MATHEMATICAL SANS-SERIF BOLD CAPITAL R;Lu;0;L;<font> 0052;;;;N;;;;;
+1D5E6;MATHEMATICAL SANS-SERIF BOLD CAPITAL S;Lu;0;L;<font> 0053;;;;N;;;;;
+1D5E7;MATHEMATICAL SANS-SERIF BOLD CAPITAL T;Lu;0;L;<font> 0054;;;;N;;;;;
+1D5E8;MATHEMATICAL SANS-SERIF BOLD CAPITAL U;Lu;0;L;<font> 0055;;;;N;;;;;
+1D5E9;MATHEMATICAL SANS-SERIF BOLD CAPITAL V;Lu;0;L;<font> 0056;;;;N;;;;;
+1D5EA;MATHEMATICAL SANS-SERIF BOLD CAPITAL W;Lu;0;L;<font> 0057;;;;N;;;;;
+1D5EB;MATHEMATICAL SANS-SERIF BOLD CAPITAL X;Lu;0;L;<font> 0058;;;;N;;;;;
+1D5EC;MATHEMATICAL SANS-SERIF BOLD CAPITAL Y;Lu;0;L;<font> 0059;;;;N;;;;;
+1D5ED;MATHEMATICAL SANS-SERIF BOLD CAPITAL Z;Lu;0;L;<font> 005A;;;;N;;;;;
+1D5EE;MATHEMATICAL SANS-SERIF BOLD SMALL A;Ll;0;L;<font> 0061;;;;N;;;;;
+1D5EF;MATHEMATICAL SANS-SERIF BOLD SMALL B;Ll;0;L;<font> 0062;;;;N;;;;;
+1D5F0;MATHEMATICAL SANS-SERIF BOLD SMALL C;Ll;0;L;<font> 0063;;;;N;;;;;
+1D5F1;MATHEMATICAL SANS-SERIF BOLD SMALL D;Ll;0;L;<font> 0064;;;;N;;;;;
+1D5F2;MATHEMATICAL SANS-SERIF BOLD SMALL E;Ll;0;L;<font> 0065;;;;N;;;;;
+1D5F3;MATHEMATICAL SANS-SERIF BOLD SMALL F;Ll;0;L;<font> 0066;;;;N;;;;;
+1D5F4;MATHEMATICAL SANS-SERIF BOLD SMALL G;Ll;0;L;<font> 0067;;;;N;;;;;
+1D5F5;MATHEMATICAL SANS-SERIF BOLD SMALL H;Ll;0;L;<font> 0068;;;;N;;;;;
+1D5F6;MATHEMATICAL SANS-SERIF BOLD SMALL I;Ll;0;L;<font> 0069;;;;N;;;;;
+1D5F7;MATHEMATICAL SANS-SERIF BOLD SMALL J;Ll;0;L;<font> 006A;;;;N;;;;;
+1D5F8;MATHEMATICAL SANS-SERIF BOLD SMALL K;Ll;0;L;<font> 006B;;;;N;;;;;
+1D5F9;MATHEMATICAL SANS-SERIF BOLD SMALL L;Ll;0;L;<font> 006C;;;;N;;;;;
+1D5FA;MATHEMATICAL SANS-SERIF BOLD SMALL M;Ll;0;L;<font> 006D;;;;N;;;;;
+1D5FB;MATHEMATICAL SANS-SERIF BOLD SMALL N;Ll;0;L;<font> 006E;;;;N;;;;;
+1D5FC;MATHEMATICAL SANS-SERIF BOLD SMALL O;Ll;0;L;<font> 006F;;;;N;;;;;
+1D5FD;MATHEMATICAL SANS-SERIF BOLD SMALL P;Ll;0;L;<font> 0070;;;;N;;;;;
+1D5FE;MATHEMATICAL SANS-SERIF BOLD SMALL Q;Ll;0;L;<font> 0071;;;;N;;;;;
+1D5FF;MATHEMATICAL SANS-SERIF BOLD SMALL R;Ll;0;L;<font> 0072;;;;N;;;;;
+1D600;MATHEMATICAL SANS-SERIF BOLD SMALL S;Ll;0;L;<font> 0073;;;;N;;;;;
+1D601;MATHEMATICAL SANS-SERIF BOLD SMALL T;Ll;0;L;<font> 0074;;;;N;;;;;
+1D602;MATHEMATICAL SANS-SERIF BOLD SMALL U;Ll;0;L;<font> 0075;;;;N;;;;;
+1D603;MATHEMATICAL SANS-SERIF BOLD SMALL V;Ll;0;L;<font> 0076;;;;N;;;;;
+1D604;MATHEMATICAL SANS-SERIF BOLD SMALL W;Ll;0;L;<font> 0077;;;;N;;;;;
+1D605;MATHEMATICAL SANS-SERIF BOLD SMALL X;Ll;0;L;<font> 0078;;;;N;;;;;
+1D606;MATHEMATICAL SANS-SERIF BOLD SMALL Y;Ll;0;L;<font> 0079;;;;N;;;;;
+1D607;MATHEMATICAL SANS-SERIF BOLD SMALL Z;Ll;0;L;<font> 007A;;;;N;;;;;
+1D608;MATHEMATICAL SANS-SERIF ITALIC CAPITAL A;Lu;0;L;<font> 0041;;;;N;;;;;
+1D609;MATHEMATICAL SANS-SERIF ITALIC CAPITAL B;Lu;0;L;<font> 0042;;;;N;;;;;
+1D60A;MATHEMATICAL SANS-SERIF ITALIC CAPITAL C;Lu;0;L;<font> 0043;;;;N;;;;;
+1D60B;MATHEMATICAL SANS-SERIF ITALIC CAPITAL D;Lu;0;L;<font> 0044;;;;N;;;;;
+1D60C;MATHEMATICAL SANS-SERIF ITALIC CAPITAL E;Lu;0;L;<font> 0045;;;;N;;;;;
+1D60D;MATHEMATICAL SANS-SERIF ITALIC CAPITAL F;Lu;0;L;<font> 0046;;;;N;;;;;
+1D60E;MATHEMATICAL SANS-SERIF ITALIC CAPITAL G;Lu;0;L;<font> 0047;;;;N;;;;;
+1D60F;MATHEMATICAL SANS-SERIF ITALIC CAPITAL H;Lu;0;L;<font> 0048;;;;N;;;;;
+1D610;MATHEMATICAL SANS-SERIF ITALIC CAPITAL I;Lu;0;L;<font> 0049;;;;N;;;;;
+1D611;MATHEMATICAL SANS-SERIF ITALIC CAPITAL J;Lu;0;L;<font> 004A;;;;N;;;;;
+1D612;MATHEMATICAL SANS-SERIF ITALIC CAPITAL K;Lu;0;L;<font> 004B;;;;N;;;;;
+1D613;MATHEMATICAL SANS-SERIF ITALIC CAPITAL L;Lu;0;L;<font> 004C;;;;N;;;;;
+1D614;MATHEMATICAL SANS-SERIF ITALIC CAPITAL M;Lu;0;L;<font> 004D;;;;N;;;;;
+1D615;MATHEMATICAL SANS-SERIF ITALIC CAPITAL N;Lu;0;L;<font> 004E;;;;N;;;;;
+1D616;MATHEMATICAL SANS-SERIF ITALIC CAPITAL O;Lu;0;L;<font> 004F;;;;N;;;;;
+1D617;MATHEMATICAL SANS-SERIF ITALIC CAPITAL P;Lu;0;L;<font> 0050;;;;N;;;;;
+1D618;MATHEMATICAL SANS-SERIF ITALIC CAPITAL Q;Lu;0;L;<font> 0051;;;;N;;;;;
+1D619;MATHEMATICAL SANS-SERIF ITALIC CAPITAL R;Lu;0;L;<font> 0052;;;;N;;;;;
+1D61A;MATHEMATICAL SANS-SERIF ITALIC CAPITAL S;Lu;0;L;<font> 0053;;;;N;;;;;
+1D61B;MATHEMATICAL SANS-SERIF ITALIC CAPITAL T;Lu;0;L;<font> 0054;;;;N;;;;;
+1D61C;MATHEMATICAL SANS-SERIF ITALIC CAPITAL U;Lu;0;L;<font> 0055;;;;N;;;;;
+1D61D;MATHEMATICAL SANS-SERIF ITALIC CAPITAL V;Lu;0;L;<font> 0056;;;;N;;;;;
+1D61E;MATHEMATICAL SANS-SERIF ITALIC CAPITAL W;Lu;0;L;<font> 0057;;;;N;;;;;
+1D61F;MATHEMATICAL SANS-SERIF ITALIC CAPITAL X;Lu;0;L;<font> 0058;;;;N;;;;;
+1D620;MATHEMATICAL SANS-SERIF ITALIC CAPITAL Y;Lu;0;L;<font> 0059;;;;N;;;;;
+1D621;MATHEMATICAL SANS-SERIF ITALIC CAPITAL Z;Lu;0;L;<font> 005A;;;;N;;;;;
+1D622;MATHEMATICAL SANS-SERIF ITALIC SMALL A;Ll;0;L;<font> 0061;;;;N;;;;;
+1D623;MATHEMATICAL SANS-SERIF ITALIC SMALL B;Ll;0;L;<font> 0062;;;;N;;;;;
+1D624;MATHEMATICAL SANS-SERIF ITALIC SMALL C;Ll;0;L;<font> 0063;;;;N;;;;;
+1D625;MATHEMATICAL SANS-SERIF ITALIC SMALL D;Ll;0;L;<font> 0064;;;;N;;;;;
+1D626;MATHEMATICAL SANS-SERIF ITALIC SMALL E;Ll;0;L;<font> 0065;;;;N;;;;;
+1D627;MATHEMATICAL SANS-SERIF ITALIC SMALL F;Ll;0;L;<font> 0066;;;;N;;;;;
+1D628;MATHEMATICAL SANS-SERIF ITALIC SMALL G;Ll;0;L;<font> 0067;;;;N;;;;;
+1D629;MATHEMATICAL SANS-SERIF ITALIC SMALL H;Ll;0;L;<font> 0068;;;;N;;;;;
+1D62A;MATHEMATICAL SANS-SERIF ITALIC SMALL I;Ll;0;L;<font> 0069;;;;N;;;;;
+1D62B;MATHEMATICAL SANS-SERIF ITALIC SMALL J;Ll;0;L;<font> 006A;;;;N;;;;;
+1D62C;MATHEMATICAL SANS-SERIF ITALIC SMALL K;Ll;0;L;<font> 006B;;;;N;;;;;
+1D62D;MATHEMATICAL SANS-SERIF ITALIC SMALL L;Ll;0;L;<font> 006C;;;;N;;;;;
+1D62E;MATHEMATICAL SANS-SERIF ITALIC SMALL M;Ll;0;L;<font> 006D;;;;N;;;;;
+1D62F;MATHEMATICAL SANS-SERIF ITALIC SMALL N;Ll;0;L;<font> 006E;;;;N;;;;;
+1D630;MATHEMATICAL SANS-SERIF ITALIC SMALL O;Ll;0;L;<font> 006F;;;;N;;;;;
+1D631;MATHEMATICAL SANS-SERIF ITALIC SMALL P;Ll;0;L;<font> 0070;;;;N;;;;;
+1D632;MATHEMATICAL SANS-SERIF ITALIC SMALL Q;Ll;0;L;<font> 0071;;;;N;;;;;
+1D633;MATHEMATICAL SANS-SERIF ITALIC SMALL R;Ll;0;L;<font> 0072;;;;N;;;;;
+1D634;MATHEMATICAL SANS-SERIF ITALIC SMALL S;Ll;0;L;<font> 0073;;;;N;;;;;
+1D635;MATHEMATICAL SANS-SERIF ITALIC SMALL T;Ll;0;L;<font> 0074;;;;N;;;;;
+1D636;MATHEMATICAL SANS-SERIF ITALIC SMALL U;Ll;0;L;<font> 0075;;;;N;;;;;
+1D637;MATHEMATICAL SANS-SERIF ITALIC SMALL V;Ll;0;L;<font> 0076;;;;N;;;;;
+1D638;MATHEMATICAL SANS-SERIF ITALIC SMALL W;Ll;0;L;<font> 0077;;;;N;;;;;
+1D639;MATHEMATICAL SANS-SERIF ITALIC SMALL X;Ll;0;L;<font> 0078;;;;N;;;;;
+1D63A;MATHEMATICAL SANS-SERIF ITALIC SMALL Y;Ll;0;L;<font> 0079;;;;N;;;;;
+1D63B;MATHEMATICAL SANS-SERIF ITALIC SMALL Z;Ll;0;L;<font> 007A;;;;N;;;;;
+1D63C;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL A;Lu;0;L;<font> 0041;;;;N;;;;;
+1D63D;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL B;Lu;0;L;<font> 0042;;;;N;;;;;
+1D63E;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL C;Lu;0;L;<font> 0043;;;;N;;;;;
+1D63F;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL D;Lu;0;L;<font> 0044;;;;N;;;;;
+1D640;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL E;Lu;0;L;<font> 0045;;;;N;;;;;
+1D641;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL F;Lu;0;L;<font> 0046;;;;N;;;;;
+1D642;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL G;Lu;0;L;<font> 0047;;;;N;;;;;
+1D643;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL H;Lu;0;L;<font> 0048;;;;N;;;;;
+1D644;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL I;Lu;0;L;<font> 0049;;;;N;;;;;
+1D645;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL J;Lu;0;L;<font> 004A;;;;N;;;;;
+1D646;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL K;Lu;0;L;<font> 004B;;;;N;;;;;
+1D647;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL L;Lu;0;L;<font> 004C;;;;N;;;;;
+1D648;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL M;Lu;0;L;<font> 004D;;;;N;;;;;
+1D649;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL N;Lu;0;L;<font> 004E;;;;N;;;;;
+1D64A;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL O;Lu;0;L;<font> 004F;;;;N;;;;;
+1D64B;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL P;Lu;0;L;<font> 0050;;;;N;;;;;
+1D64C;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL Q;Lu;0;L;<font> 0051;;;;N;;;;;
+1D64D;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL R;Lu;0;L;<font> 0052;;;;N;;;;;
+1D64E;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL S;Lu;0;L;<font> 0053;;;;N;;;;;
+1D64F;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL T;Lu;0;L;<font> 0054;;;;N;;;;;
+1D650;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL U;Lu;0;L;<font> 0055;;;;N;;;;;
+1D651;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL V;Lu;0;L;<font> 0056;;;;N;;;;;
+1D652;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL W;Lu;0;L;<font> 0057;;;;N;;;;;
+1D653;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL X;Lu;0;L;<font> 0058;;;;N;;;;;
+1D654;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL Y;Lu;0;L;<font> 0059;;;;N;;;;;
+1D655;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL Z;Lu;0;L;<font> 005A;;;;N;;;;;
+1D656;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL A;Ll;0;L;<font> 0061;;;;N;;;;;
+1D657;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL B;Ll;0;L;<font> 0062;;;;N;;;;;
+1D658;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL C;Ll;0;L;<font> 0063;;;;N;;;;;
+1D659;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL D;Ll;0;L;<font> 0064;;;;N;;;;;
+1D65A;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL E;Ll;0;L;<font> 0065;;;;N;;;;;
+1D65B;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL F;Ll;0;L;<font> 0066;;;;N;;;;;
+1D65C;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL G;Ll;0;L;<font> 0067;;;;N;;;;;
+1D65D;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL H;Ll;0;L;<font> 0068;;;;N;;;;;
+1D65E;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL I;Ll;0;L;<font> 0069;;;;N;;;;;
+1D65F;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL J;Ll;0;L;<font> 006A;;;;N;;;;;
+1D660;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL K;Ll;0;L;<font> 006B;;;;N;;;;;
+1D661;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL L;Ll;0;L;<font> 006C;;;;N;;;;;
+1D662;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL M;Ll;0;L;<font> 006D;;;;N;;;;;
+1D663;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL N;Ll;0;L;<font> 006E;;;;N;;;;;
+1D664;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL O;Ll;0;L;<font> 006F;;;;N;;;;;
+1D665;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL P;Ll;0;L;<font> 0070;;;;N;;;;;
+1D666;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL Q;Ll;0;L;<font> 0071;;;;N;;;;;
+1D667;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL R;Ll;0;L;<font> 0072;;;;N;;;;;
+1D668;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL S;Ll;0;L;<font> 0073;;;;N;;;;;
+1D669;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL T;Ll;0;L;<font> 0074;;;;N;;;;;
+1D66A;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL U;Ll;0;L;<font> 0075;;;;N;;;;;
+1D66B;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL V;Ll;0;L;<font> 0076;;;;N;;;;;
+1D66C;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL W;Ll;0;L;<font> 0077;;;;N;;;;;
+1D66D;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL X;Ll;0;L;<font> 0078;;;;N;;;;;
+1D66E;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL Y;Ll;0;L;<font> 0079;;;;N;;;;;
+1D66F;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL Z;Ll;0;L;<font> 007A;;;;N;;;;;
+1D670;MATHEMATICAL MONOSPACE CAPITAL A;Lu;0;L;<font> 0041;;;;N;;;;;
+1D671;MATHEMATICAL MONOSPACE CAPITAL B;Lu;0;L;<font> 0042;;;;N;;;;;
+1D672;MATHEMATICAL MONOSPACE CAPITAL C;Lu;0;L;<font> 0043;;;;N;;;;;
+1D673;MATHEMATICAL MONOSPACE CAPITAL D;Lu;0;L;<font> 0044;;;;N;;;;;
+1D674;MATHEMATICAL MONOSPACE CAPITAL E;Lu;0;L;<font> 0045;;;;N;;;;;
+1D675;MATHEMATICAL MONOSPACE CAPITAL F;Lu;0;L;<font> 0046;;;;N;;;;;
+1D676;MATHEMATICAL MONOSPACE CAPITAL G;Lu;0;L;<font> 0047;;;;N;;;;;
+1D677;MATHEMATICAL MONOSPACE CAPITAL H;Lu;0;L;<font> 0048;;;;N;;;;;
+1D678;MATHEMATICAL MONOSPACE CAPITAL I;Lu;0;L;<font> 0049;;;;N;;;;;
+1D679;MATHEMATICAL MONOSPACE CAPITAL J;Lu;0;L;<font> 004A;;;;N;;;;;
+1D67A;MATHEMATICAL MONOSPACE CAPITAL K;Lu;0;L;<font> 004B;;;;N;;;;;
+1D67B;MATHEMATICAL MONOSPACE CAPITAL L;Lu;0;L;<font> 004C;;;;N;;;;;
+1D67C;MATHEMATICAL MONOSPACE CAPITAL M;Lu;0;L;<font> 004D;;;;N;;;;;
+1D67D;MATHEMATICAL MONOSPACE CAPITAL N;Lu;0;L;<font> 004E;;;;N;;;;;
+1D67E;MATHEMATICAL MONOSPACE CAPITAL O;Lu;0;L;<font> 004F;;;;N;;;;;
+1D67F;MATHEMATICAL MONOSPACE CAPITAL P;Lu;0;L;<font> 0050;;;;N;;;;;
+1D680;MATHEMATICAL MONOSPACE CAPITAL Q;Lu;0;L;<font> 0051;;;;N;;;;;
+1D681;MATHEMATICAL MONOSPACE CAPITAL R;Lu;0;L;<font> 0052;;;;N;;;;;
+1D682;MATHEMATICAL MONOSPACE CAPITAL S;Lu;0;L;<font> 0053;;;;N;;;;;
+1D683;MATHEMATICAL MONOSPACE CAPITAL T;Lu;0;L;<font> 0054;;;;N;;;;;
+1D684;MATHEMATICAL MONOSPACE CAPITAL U;Lu;0;L;<font> 0055;;;;N;;;;;
+1D685;MATHEMATICAL MONOSPACE CAPITAL V;Lu;0;L;<font> 0056;;;;N;;;;;
+1D686;MATHEMATICAL MONOSPACE CAPITAL W;Lu;0;L;<font> 0057;;;;N;;;;;
+1D687;MATHEMATICAL MONOSPACE CAPITAL X;Lu;0;L;<font> 0058;;;;N;;;;;
+1D688;MATHEMATICAL MONOSPACE CAPITAL Y;Lu;0;L;<font> 0059;;;;N;;;;;
+1D689;MATHEMATICAL MONOSPACE CAPITAL Z;Lu;0;L;<font> 005A;;;;N;;;;;
+1D68A;MATHEMATICAL MONOSPACE SMALL A;Ll;0;L;<font> 0061;;;;N;;;;;
+1D68B;MATHEMATICAL MONOSPACE SMALL B;Ll;0;L;<font> 0062;;;;N;;;;;
+1D68C;MATHEMATICAL MONOSPACE SMALL C;Ll;0;L;<font> 0063;;;;N;;;;;
+1D68D;MATHEMATICAL MONOSPACE SMALL D;Ll;0;L;<font> 0064;;;;N;;;;;
+1D68E;MATHEMATICAL MONOSPACE SMALL E;Ll;0;L;<font> 0065;;;;N;;;;;
+1D68F;MATHEMATICAL MONOSPACE SMALL F;Ll;0;L;<font> 0066;;;;N;;;;;
+1D690;MATHEMATICAL MONOSPACE SMALL G;Ll;0;L;<font> 0067;;;;N;;;;;
+1D691;MATHEMATICAL MONOSPACE SMALL H;Ll;0;L;<font> 0068;;;;N;;;;;
+1D692;MATHEMATICAL MONOSPACE SMALL I;Ll;0;L;<font> 0069;;;;N;;;;;
+1D693;MATHEMATICAL MONOSPACE SMALL J;Ll;0;L;<font> 006A;;;;N;;;;;
+1D694;MATHEMATICAL MONOSPACE SMALL K;Ll;0;L;<font> 006B;;;;N;;;;;
+1D695;MATHEMATICAL MONOSPACE SMALL L;Ll;0;L;<font> 006C;;;;N;;;;;
+1D696;MATHEMATICAL MONOSPACE SMALL M;Ll;0;L;<font> 006D;;;;N;;;;;
+1D697;MATHEMATICAL MONOSPACE SMALL N;Ll;0;L;<font> 006E;;;;N;;;;;
+1D698;MATHEMATICAL MONOSPACE SMALL O;Ll;0;L;<font> 006F;;;;N;;;;;
+1D699;MATHEMATICAL MONOSPACE SMALL P;Ll;0;L;<font> 0070;;;;N;;;;;
+1D69A;MATHEMATICAL MONOSPACE SMALL Q;Ll;0;L;<font> 0071;;;;N;;;;;
+1D69B;MATHEMATICAL MONOSPACE SMALL R;Ll;0;L;<font> 0072;;;;N;;;;;
+1D69C;MATHEMATICAL MONOSPACE SMALL S;Ll;0;L;<font> 0073;;;;N;;;;;
+1D69D;MATHEMATICAL MONOSPACE SMALL T;Ll;0;L;<font> 0074;;;;N;;;;;
+1D69E;MATHEMATICAL MONOSPACE SMALL U;Ll;0;L;<font> 0075;;;;N;;;;;
+1D69F;MATHEMATICAL MONOSPACE SMALL V;Ll;0;L;<font> 0076;;;;N;;;;;
+1D6A0;MATHEMATICAL MONOSPACE SMALL W;Ll;0;L;<font> 0077;;;;N;;;;;
+1D6A1;MATHEMATICAL MONOSPACE SMALL X;Ll;0;L;<font> 0078;;;;N;;;;;
+1D6A2;MATHEMATICAL MONOSPACE SMALL Y;Ll;0;L;<font> 0079;;;;N;;;;;
+1D6A3;MATHEMATICAL MONOSPACE SMALL Z;Ll;0;L;<font> 007A;;;;N;;;;;
+1D6A4;MATHEMATICAL ITALIC SMALL DOTLESS I;Ll;0;L;<font> 0131;;;;N;;;;;
+1D6A5;MATHEMATICAL ITALIC SMALL DOTLESS J;Ll;0;L;<font> 0237;;;;N;;;;;
+1D6A8;MATHEMATICAL BOLD CAPITAL ALPHA;Lu;0;L;<font> 0391;;;;N;;;;;
+1D6A9;MATHEMATICAL BOLD CAPITAL BETA;Lu;0;L;<font> 0392;;;;N;;;;;
+1D6AA;MATHEMATICAL BOLD CAPITAL GAMMA;Lu;0;L;<font> 0393;;;;N;;;;;
+1D6AB;MATHEMATICAL BOLD CAPITAL DELTA;Lu;0;L;<font> 0394;;;;N;;;;;
+1D6AC;MATHEMATICAL BOLD CAPITAL EPSILON;Lu;0;L;<font> 0395;;;;N;;;;;
+1D6AD;MATHEMATICAL BOLD CAPITAL ZETA;Lu;0;L;<font> 0396;;;;N;;;;;
+1D6AE;MATHEMATICAL BOLD CAPITAL ETA;Lu;0;L;<font> 0397;;;;N;;;;;
+1D6AF;MATHEMATICAL BOLD CAPITAL THETA;Lu;0;L;<font> 0398;;;;N;;;;;
+1D6B0;MATHEMATICAL BOLD CAPITAL IOTA;Lu;0;L;<font> 0399;;;;N;;;;;
+1D6B1;MATHEMATICAL BOLD CAPITAL KAPPA;Lu;0;L;<font> 039A;;;;N;;;;;
+1D6B2;MATHEMATICAL BOLD CAPITAL LAMDA;Lu;0;L;<font> 039B;;;;N;;;;;
+1D6B3;MATHEMATICAL BOLD CAPITAL MU;Lu;0;L;<font> 039C;;;;N;;;;;
+1D6B4;MATHEMATICAL BOLD CAPITAL NU;Lu;0;L;<font> 039D;;;;N;;;;;
+1D6B5;MATHEMATICAL BOLD CAPITAL XI;Lu;0;L;<font> 039E;;;;N;;;;;
+1D6B6;MATHEMATICAL BOLD CAPITAL OMICRON;Lu;0;L;<font> 039F;;;;N;;;;;
+1D6B7;MATHEMATICAL BOLD CAPITAL PI;Lu;0;L;<font> 03A0;;;;N;;;;;
+1D6B8;MATHEMATICAL BOLD CAPITAL RHO;Lu;0;L;<font> 03A1;;;;N;;;;;
+1D6B9;MATHEMATICAL BOLD CAPITAL THETA SYMBOL;Lu;0;L;<font> 03F4;;;;N;;;;;
+1D6BA;MATHEMATICAL BOLD CAPITAL SIGMA;Lu;0;L;<font> 03A3;;;;N;;;;;
+1D6BB;MATHEMATICAL BOLD CAPITAL TAU;Lu;0;L;<font> 03A4;;;;N;;;;;
+1D6BC;MATHEMATICAL BOLD CAPITAL UPSILON;Lu;0;L;<font> 03A5;;;;N;;;;;
+1D6BD;MATHEMATICAL BOLD CAPITAL PHI;Lu;0;L;<font> 03A6;;;;N;;;;;
+1D6BE;MATHEMATICAL BOLD CAPITAL CHI;Lu;0;L;<font> 03A7;;;;N;;;;;
+1D6BF;MATHEMATICAL BOLD CAPITAL PSI;Lu;0;L;<font> 03A8;;;;N;;;;;
+1D6C0;MATHEMATICAL BOLD CAPITAL OMEGA;Lu;0;L;<font> 03A9;;;;N;;;;;
+1D6C1;MATHEMATICAL BOLD NABLA;Sm;0;L;<font> 2207;;;;N;;;;;
+1D6C2;MATHEMATICAL BOLD SMALL ALPHA;Ll;0;L;<font> 03B1;;;;N;;;;;
+1D6C3;MATHEMATICAL BOLD SMALL BETA;Ll;0;L;<font> 03B2;;;;N;;;;;
+1D6C4;MATHEMATICAL BOLD SMALL GAMMA;Ll;0;L;<font> 03B3;;;;N;;;;;
+1D6C5;MATHEMATICAL BOLD SMALL DELTA;Ll;0;L;<font> 03B4;;;;N;;;;;
+1D6C6;MATHEMATICAL BOLD SMALL EPSILON;Ll;0;L;<font> 03B5;;;;N;;;;;
+1D6C7;MATHEMATICAL BOLD SMALL ZETA;Ll;0;L;<font> 03B6;;;;N;;;;;
+1D6C8;MATHEMATICAL BOLD SMALL ETA;Ll;0;L;<font> 03B7;;;;N;;;;;
+1D6C9;MATHEMATICAL BOLD SMALL THETA;Ll;0;L;<font> 03B8;;;;N;;;;;
+1D6CA;MATHEMATICAL BOLD SMALL IOTA;Ll;0;L;<font> 03B9;;;;N;;;;;
+1D6CB;MATHEMATICAL BOLD SMALL KAPPA;Ll;0;L;<font> 03BA;;;;N;;;;;
+1D6CC;MATHEMATICAL BOLD SMALL LAMDA;Ll;0;L;<font> 03BB;;;;N;;;;;
+1D6CD;MATHEMATICAL BOLD SMALL MU;Ll;0;L;<font> 03BC;;;;N;;;;;
+1D6CE;MATHEMATICAL BOLD SMALL NU;Ll;0;L;<font> 03BD;;;;N;;;;;
+1D6CF;MATHEMATICAL BOLD SMALL XI;Ll;0;L;<font> 03BE;;;;N;;;;;
+1D6D0;MATHEMATICAL BOLD SMALL OMICRON;Ll;0;L;<font> 03BF;;;;N;;;;;
+1D6D1;MATHEMATICAL BOLD SMALL PI;Ll;0;L;<font> 03C0;;;;N;;;;;
+1D6D2;MATHEMATICAL BOLD SMALL RHO;Ll;0;L;<font> 03C1;;;;N;;;;;
+1D6D3;MATHEMATICAL BOLD SMALL FINAL SIGMA;Ll;0;L;<font> 03C2;;;;N;;;;;
+1D6D4;MATHEMATICAL BOLD SMALL SIGMA;Ll;0;L;<font> 03C3;;;;N;;;;;
+1D6D5;MATHEMATICAL BOLD SMALL TAU;Ll;0;L;<font> 03C4;;;;N;;;;;
+1D6D6;MATHEMATICAL BOLD SMALL UPSILON;Ll;0;L;<font> 03C5;;;;N;;;;;
+1D6D7;MATHEMATICAL BOLD SMALL PHI;Ll;0;L;<font> 03C6;;;;N;;;;;
+1D6D8;MATHEMATICAL BOLD SMALL CHI;Ll;0;L;<font> 03C7;;;;N;;;;;
+1D6D9;MATHEMATICAL BOLD SMALL PSI;Ll;0;L;<font> 03C8;;;;N;;;;;
+1D6DA;MATHEMATICAL BOLD SMALL OMEGA;Ll;0;L;<font> 03C9;;;;N;;;;;
+1D6DB;MATHEMATICAL BOLD PARTIAL DIFFERENTIAL;Sm;0;ON;<font> 2202;;;;Y;;;;;
+1D6DC;MATHEMATICAL BOLD EPSILON SYMBOL;Ll;0;L;<font> 03F5;;;;N;;;;;
+1D6DD;MATHEMATICAL BOLD THETA SYMBOL;Ll;0;L;<font> 03D1;;;;N;;;;;
+1D6DE;MATHEMATICAL BOLD KAPPA SYMBOL;Ll;0;L;<font> 03F0;;;;N;;;;;
+1D6DF;MATHEMATICAL BOLD PHI SYMBOL;Ll;0;L;<font> 03D5;;;;N;;;;;
+1D6E0;MATHEMATICAL BOLD RHO SYMBOL;Ll;0;L;<font> 03F1;;;;N;;;;;
+1D6E1;MATHEMATICAL BOLD PI SYMBOL;Ll;0;L;<font> 03D6;;;;N;;;;;
+1D6E2;MATHEMATICAL ITALIC CAPITAL ALPHA;Lu;0;L;<font> 0391;;;;N;;;;;
+1D6E3;MATHEMATICAL ITALIC CAPITAL BETA;Lu;0;L;<font> 0392;;;;N;;;;;
+1D6E4;MATHEMATICAL ITALIC CAPITAL GAMMA;Lu;0;L;<font> 0393;;;;N;;;;;
+1D6E5;MATHEMATICAL ITALIC CAPITAL DELTA;Lu;0;L;<font> 0394;;;;N;;;;;
+1D6E6;MATHEMATICAL ITALIC CAPITAL EPSILON;Lu;0;L;<font> 0395;;;;N;;;;;
+1D6E7;MATHEMATICAL ITALIC CAPITAL ZETA;Lu;0;L;<font> 0396;;;;N;;;;;
+1D6E8;MATHEMATICAL ITALIC CAPITAL ETA;Lu;0;L;<font> 0397;;;;N;;;;;
+1D6E9;MATHEMATICAL ITALIC CAPITAL THETA;Lu;0;L;<font> 0398;;;;N;;;;;
+1D6EA;MATHEMATICAL ITALIC CAPITAL IOTA;Lu;0;L;<font> 0399;;;;N;;;;;
+1D6EB;MATHEMATICAL ITALIC CAPITAL KAPPA;Lu;0;L;<font> 039A;;;;N;;;;;
+1D6EC;MATHEMATICAL ITALIC CAPITAL LAMDA;Lu;0;L;<font> 039B;;;;N;;;;;
+1D6ED;MATHEMATICAL ITALIC CAPITAL MU;Lu;0;L;<font> 039C;;;;N;;;;;
+1D6EE;MATHEMATICAL ITALIC CAPITAL NU;Lu;0;L;<font> 039D;;;;N;;;;;
+1D6EF;MATHEMATICAL ITALIC CAPITAL XI;Lu;0;L;<font> 039E;;;;N;;;;;
+1D6F0;MATHEMATICAL ITALIC CAPITAL OMICRON;Lu;0;L;<font> 039F;;;;N;;;;;
+1D6F1;MATHEMATICAL ITALIC CAPITAL PI;Lu;0;L;<font> 03A0;;;;N;;;;;
+1D6F2;MATHEMATICAL ITALIC CAPITAL RHO;Lu;0;L;<font> 03A1;;;;N;;;;;
+1D6F3;MATHEMATICAL ITALIC CAPITAL THETA SYMBOL;Lu;0;L;<font> 03F4;;;;N;;;;;
+1D6F4;MATHEMATICAL ITALIC CAPITAL SIGMA;Lu;0;L;<font> 03A3;;;;N;;;;;
+1D6F5;MATHEMATICAL ITALIC CAPITAL TAU;Lu;0;L;<font> 03A4;;;;N;;;;;
+1D6F6;MATHEMATICAL ITALIC CAPITAL UPSILON;Lu;0;L;<font> 03A5;;;;N;;;;;
+1D6F7;MATHEMATICAL ITALIC CAPITAL PHI;Lu;0;L;<font> 03A6;;;;N;;;;;
+1D6F8;MATHEMATICAL ITALIC CAPITAL CHI;Lu;0;L;<font> 03A7;;;;N;;;;;
+1D6F9;MATHEMATICAL ITALIC CAPITAL PSI;Lu;0;L;<font> 03A8;;;;N;;;;;
+1D6FA;MATHEMATICAL ITALIC CAPITAL OMEGA;Lu;0;L;<font> 03A9;;;;N;;;;;
+1D6FB;MATHEMATICAL ITALIC NABLA;Sm;0;L;<font> 2207;;;;N;;;;;
+1D6FC;MATHEMATICAL ITALIC SMALL ALPHA;Ll;0;L;<font> 03B1;;;;N;;;;;
+1D6FD;MATHEMATICAL ITALIC SMALL BETA;Ll;0;L;<font> 03B2;;;;N;;;;;
+1D6FE;MATHEMATICAL ITALIC SMALL GAMMA;Ll;0;L;<font> 03B3;;;;N;;;;;
+1D6FF;MATHEMATICAL ITALIC SMALL DELTA;Ll;0;L;<font> 03B4;;;;N;;;;;
+1D700;MATHEMATICAL ITALIC SMALL EPSILON;Ll;0;L;<font> 03B5;;;;N;;;;;
+1D701;MATHEMATICAL ITALIC SMALL ZETA;Ll;0;L;<font> 03B6;;;;N;;;;;
+1D702;MATHEMATICAL ITALIC SMALL ETA;Ll;0;L;<font> 03B7;;;;N;;;;;
+1D703;MATHEMATICAL ITALIC SMALL THETA;Ll;0;L;<font> 03B8;;;;N;;;;;
+1D704;MATHEMATICAL ITALIC SMALL IOTA;Ll;0;L;<font> 03B9;;;;N;;;;;
+1D705;MATHEMATICAL ITALIC SMALL KAPPA;Ll;0;L;<font> 03BA;;;;N;;;;;
+1D706;MATHEMATICAL ITALIC SMALL LAMDA;Ll;0;L;<font> 03BB;;;;N;;;;;
+1D707;MATHEMATICAL ITALIC SMALL MU;Ll;0;L;<font> 03BC;;;;N;;;;;
+1D708;MATHEMATICAL ITALIC SMALL NU;Ll;0;L;<font> 03BD;;;;N;;;;;
+1D709;MATHEMATICAL ITALIC SMALL XI;Ll;0;L;<font> 03BE;;;;N;;;;;
+1D70A;MATHEMATICAL ITALIC SMALL OMICRON;Ll;0;L;<font> 03BF;;;;N;;;;;
+1D70B;MATHEMATICAL ITALIC SMALL PI;Ll;0;L;<font> 03C0;;;;N;;;;;
+1D70C;MATHEMATICAL ITALIC SMALL RHO;Ll;0;L;<font> 03C1;;;;N;;;;;
+1D70D;MATHEMATICAL ITALIC SMALL FINAL SIGMA;Ll;0;L;<font> 03C2;;;;N;;;;;
+1D70E;MATHEMATICAL ITALIC SMALL SIGMA;Ll;0;L;<font> 03C3;;;;N;;;;;
+1D70F;MATHEMATICAL ITALIC SMALL TAU;Ll;0;L;<font> 03C4;;;;N;;;;;
+1D710;MATHEMATICAL ITALIC SMALL UPSILON;Ll;0;L;<font> 03C5;;;;N;;;;;
+1D711;MATHEMATICAL ITALIC SMALL PHI;Ll;0;L;<font> 03C6;;;;N;;;;;
+1D712;MATHEMATICAL ITALIC SMALL CHI;Ll;0;L;<font> 03C7;;;;N;;;;;
+1D713;MATHEMATICAL ITALIC SMALL PSI;Ll;0;L;<font> 03C8;;;;N;;;;;
+1D714;MATHEMATICAL ITALIC SMALL OMEGA;Ll;0;L;<font> 03C9;;;;N;;;;;
+1D715;MATHEMATICAL ITALIC PARTIAL DIFFERENTIAL;Sm;0;ON;<font> 2202;;;;Y;;;;;
+1D716;MATHEMATICAL ITALIC EPSILON SYMBOL;Ll;0;L;<font> 03F5;;;;N;;;;;
+1D717;MATHEMATICAL ITALIC THETA SYMBOL;Ll;0;L;<font> 03D1;;;;N;;;;;
+1D718;MATHEMATICAL ITALIC KAPPA SYMBOL;Ll;0;L;<font> 03F0;;;;N;;;;;
+1D719;MATHEMATICAL ITALIC PHI SYMBOL;Ll;0;L;<font> 03D5;;;;N;;;;;
+1D71A;MATHEMATICAL ITALIC RHO SYMBOL;Ll;0;L;<font> 03F1;;;;N;;;;;
+1D71B;MATHEMATICAL ITALIC PI SYMBOL;Ll;0;L;<font> 03D6;;;;N;;;;;
+1D71C;MATHEMATICAL BOLD ITALIC CAPITAL ALPHA;Lu;0;L;<font> 0391;;;;N;;;;;
+1D71D;MATHEMATICAL BOLD ITALIC CAPITAL BETA;Lu;0;L;<font> 0392;;;;N;;;;;
+1D71E;MATHEMATICAL BOLD ITALIC CAPITAL GAMMA;Lu;0;L;<font> 0393;;;;N;;;;;
+1D71F;MATHEMATICAL BOLD ITALIC CAPITAL DELTA;Lu;0;L;<font> 0394;;;;N;;;;;
+1D720;MATHEMATICAL BOLD ITALIC CAPITAL EPSILON;Lu;0;L;<font> 0395;;;;N;;;;;
+1D721;MATHEMATICAL BOLD ITALIC CAPITAL ZETA;Lu;0;L;<font> 0396;;;;N;;;;;
+1D722;MATHEMATICAL BOLD ITALIC CAPITAL ETA;Lu;0;L;<font> 0397;;;;N;;;;;
+1D723;MATHEMATICAL BOLD ITALIC CAPITAL THETA;Lu;0;L;<font> 0398;;;;N;;;;;
+1D724;MATHEMATICAL BOLD ITALIC CAPITAL IOTA;Lu;0;L;<font> 0399;;;;N;;;;;
+1D725;MATHEMATICAL BOLD ITALIC CAPITAL KAPPA;Lu;0;L;<font> 039A;;;;N;;;;;
+1D726;MATHEMATICAL BOLD ITALIC CAPITAL LAMDA;Lu;0;L;<font> 039B;;;;N;;;;;
+1D727;MATHEMATICAL BOLD ITALIC CAPITAL MU;Lu;0;L;<font> 039C;;;;N;;;;;
+1D728;MATHEMATICAL BOLD ITALIC CAPITAL NU;Lu;0;L;<font> 039D;;;;N;;;;;
+1D729;MATHEMATICAL BOLD ITALIC CAPITAL XI;Lu;0;L;<font> 039E;;;;N;;;;;
+1D72A;MATHEMATICAL BOLD ITALIC CAPITAL OMICRON;Lu;0;L;<font> 039F;;;;N;;;;;
+1D72B;MATHEMATICAL BOLD ITALIC CAPITAL PI;Lu;0;L;<font> 03A0;;;;N;;;;;
+1D72C;MATHEMATICAL BOLD ITALIC CAPITAL RHO;Lu;0;L;<font> 03A1;;;;N;;;;;
+1D72D;MATHEMATICAL BOLD ITALIC CAPITAL THETA SYMBOL;Lu;0;L;<font> 03F4;;;;N;;;;;
+1D72E;MATHEMATICAL BOLD ITALIC CAPITAL SIGMA;Lu;0;L;<font> 03A3;;;;N;;;;;
+1D72F;MATHEMATICAL BOLD ITALIC CAPITAL TAU;Lu;0;L;<font> 03A4;;;;N;;;;;
+1D730;MATHEMATICAL BOLD ITALIC CAPITAL UPSILON;Lu;0;L;<font> 03A5;;;;N;;;;;
+1D731;MATHEMATICAL BOLD ITALIC CAPITAL PHI;Lu;0;L;<font> 03A6;;;;N;;;;;
+1D732;MATHEMATICAL BOLD ITALIC CAPITAL CHI;Lu;0;L;<font> 03A7;;;;N;;;;;
+1D733;MATHEMATICAL BOLD ITALIC CAPITAL PSI;Lu;0;L;<font> 03A8;;;;N;;;;;
+1D734;MATHEMATICAL BOLD ITALIC CAPITAL OMEGA;Lu;0;L;<font> 03A9;;;;N;;;;;
+1D735;MATHEMATICAL BOLD ITALIC NABLA;Sm;0;L;<font> 2207;;;;N;;;;;
+1D736;MATHEMATICAL BOLD ITALIC SMALL ALPHA;Ll;0;L;<font> 03B1;;;;N;;;;;
+1D737;MATHEMATICAL BOLD ITALIC SMALL BETA;Ll;0;L;<font> 03B2;;;;N;;;;;
+1D738;MATHEMATICAL BOLD ITALIC SMALL GAMMA;Ll;0;L;<font> 03B3;;;;N;;;;;
+1D739;MATHEMATICAL BOLD ITALIC SMALL DELTA;Ll;0;L;<font> 03B4;;;;N;;;;;
+1D73A;MATHEMATICAL BOLD ITALIC SMALL EPSILON;Ll;0;L;<font> 03B5;;;;N;;;;;
+1D73B;MATHEMATICAL BOLD ITALIC SMALL ZETA;Ll;0;L;<font> 03B6;;;;N;;;;;
+1D73C;MATHEMATICAL BOLD ITALIC SMALL ETA;Ll;0;L;<font> 03B7;;;;N;;;;;
+1D73D;MATHEMATICAL BOLD ITALIC SMALL THETA;Ll;0;L;<font> 03B8;;;;N;;;;;
+1D73E;MATHEMATICAL BOLD ITALIC SMALL IOTA;Ll;0;L;<font> 03B9;;;;N;;;;;
+1D73F;MATHEMATICAL BOLD ITALIC SMALL KAPPA;Ll;0;L;<font> 03BA;;;;N;;;;;
+1D740;MATHEMATICAL BOLD ITALIC SMALL LAMDA;Ll;0;L;<font> 03BB;;;;N;;;;;
+1D741;MATHEMATICAL BOLD ITALIC SMALL MU;Ll;0;L;<font> 03BC;;;;N;;;;;
+1D742;MATHEMATICAL BOLD ITALIC SMALL NU;Ll;0;L;<font> 03BD;;;;N;;;;;
+1D743;MATHEMATICAL BOLD ITALIC SMALL XI;Ll;0;L;<font> 03BE;;;;N;;;;;
+1D744;MATHEMATICAL BOLD ITALIC SMALL OMICRON;Ll;0;L;<font> 03BF;;;;N;;;;;
+1D745;MATHEMATICAL BOLD ITALIC SMALL PI;Ll;0;L;<font> 03C0;;;;N;;;;;
+1D746;MATHEMATICAL BOLD ITALIC SMALL RHO;Ll;0;L;<font> 03C1;;;;N;;;;;
+1D747;MATHEMATICAL BOLD ITALIC SMALL FINAL SIGMA;Ll;0;L;<font> 03C2;;;;N;;;;;
+1D748;MATHEMATICAL BOLD ITALIC SMALL SIGMA;Ll;0;L;<font> 03C3;;;;N;;;;;
+1D749;MATHEMATICAL BOLD ITALIC SMALL TAU;Ll;0;L;<font> 03C4;;;;N;;;;;
+1D74A;MATHEMATICAL BOLD ITALIC SMALL UPSILON;Ll;0;L;<font> 03C5;;;;N;;;;;
+1D74B;MATHEMATICAL BOLD ITALIC SMALL PHI;Ll;0;L;<font> 03C6;;;;N;;;;;
+1D74C;MATHEMATICAL BOLD ITALIC SMALL CHI;Ll;0;L;<font> 03C7;;;;N;;;;;
+1D74D;MATHEMATICAL BOLD ITALIC SMALL PSI;Ll;0;L;<font> 03C8;;;;N;;;;;
+1D74E;MATHEMATICAL BOLD ITALIC SMALL OMEGA;Ll;0;L;<font> 03C9;;;;N;;;;;
+1D74F;MATHEMATICAL BOLD ITALIC PARTIAL DIFFERENTIAL;Sm;0;ON;<font> 2202;;;;Y;;;;;
+1D750;MATHEMATICAL BOLD ITALIC EPSILON SYMBOL;Ll;0;L;<font> 03F5;;;;N;;;;;
+1D751;MATHEMATICAL BOLD ITALIC THETA SYMBOL;Ll;0;L;<font> 03D1;;;;N;;;;;
+1D752;MATHEMATICAL BOLD ITALIC KAPPA SYMBOL;Ll;0;L;<font> 03F0;;;;N;;;;;
+1D753;MATHEMATICAL BOLD ITALIC PHI SYMBOL;Ll;0;L;<font> 03D5;;;;N;;;;;
+1D754;MATHEMATICAL BOLD ITALIC RHO SYMBOL;Ll;0;L;<font> 03F1;;;;N;;;;;
+1D755;MATHEMATICAL BOLD ITALIC PI SYMBOL;Ll;0;L;<font> 03D6;;;;N;;;;;
+1D756;MATHEMATICAL SANS-SERIF BOLD CAPITAL ALPHA;Lu;0;L;<font> 0391;;;;N;;;;;
+1D757;MATHEMATICAL SANS-SERIF BOLD CAPITAL BETA;Lu;0;L;<font> 0392;;;;N;;;;;
+1D758;MATHEMATICAL SANS-SERIF BOLD CAPITAL GAMMA;Lu;0;L;<font> 0393;;;;N;;;;;
+1D759;MATHEMATICAL SANS-SERIF BOLD CAPITAL DELTA;Lu;0;L;<font> 0394;;;;N;;;;;
+1D75A;MATHEMATICAL SANS-SERIF BOLD CAPITAL EPSILON;Lu;0;L;<font> 0395;;;;N;;;;;
+1D75B;MATHEMATICAL SANS-SERIF BOLD CAPITAL ZETA;Lu;0;L;<font> 0396;;;;N;;;;;
+1D75C;MATHEMATICAL SANS-SERIF BOLD CAPITAL ETA;Lu;0;L;<font> 0397;;;;N;;;;;
+1D75D;MATHEMATICAL SANS-SERIF BOLD CAPITAL THETA;Lu;0;L;<font> 0398;;;;N;;;;;
+1D75E;MATHEMATICAL SANS-SERIF BOLD CAPITAL IOTA;Lu;0;L;<font> 0399;;;;N;;;;;
+1D75F;MATHEMATICAL SANS-SERIF BOLD CAPITAL KAPPA;Lu;0;L;<font> 039A;;;;N;;;;;
+1D760;MATHEMATICAL SANS-SERIF BOLD CAPITAL LAMDA;Lu;0;L;<font> 039B;;;;N;;;;;
+1D761;MATHEMATICAL SANS-SERIF BOLD CAPITAL MU;Lu;0;L;<font> 039C;;;;N;;;;;
+1D762;MATHEMATICAL SANS-SERIF BOLD CAPITAL NU;Lu;0;L;<font> 039D;;;;N;;;;;
+1D763;MATHEMATICAL SANS-SERIF BOLD CAPITAL XI;Lu;0;L;<font> 039E;;;;N;;;;;
+1D764;MATHEMATICAL SANS-SERIF BOLD CAPITAL OMICRON;Lu;0;L;<font> 039F;;;;N;;;;;
+1D765;MATHEMATICAL SANS-SERIF BOLD CAPITAL PI;Lu;0;L;<font> 03A0;;;;N;;;;;
+1D766;MATHEMATICAL SANS-SERIF BOLD CAPITAL RHO;Lu;0;L;<font> 03A1;;;;N;;;;;
+1D767;MATHEMATICAL SANS-SERIF BOLD CAPITAL THETA SYMBOL;Lu;0;L;<font> 03F4;;;;N;;;;;
+1D768;MATHEMATICAL SANS-SERIF BOLD CAPITAL SIGMA;Lu;0;L;<font> 03A3;;;;N;;;;;
+1D769;MATHEMATICAL SANS-SERIF BOLD CAPITAL TAU;Lu;0;L;<font> 03A4;;;;N;;;;;
+1D76A;MATHEMATICAL SANS-SERIF BOLD CAPITAL UPSILON;Lu;0;L;<font> 03A5;;;;N;;;;;
+1D76B;MATHEMATICAL SANS-SERIF BOLD CAPITAL PHI;Lu;0;L;<font> 03A6;;;;N;;;;;
+1D76C;MATHEMATICAL SANS-SERIF BOLD CAPITAL CHI;Lu;0;L;<font> 03A7;;;;N;;;;;
+1D76D;MATHEMATICAL SANS-SERIF BOLD CAPITAL PSI;Lu;0;L;<font> 03A8;;;;N;;;;;
+1D76E;MATHEMATICAL SANS-SERIF BOLD CAPITAL OMEGA;Lu;0;L;<font> 03A9;;;;N;;;;;
+1D76F;MATHEMATICAL SANS-SERIF BOLD NABLA;Sm;0;L;<font> 2207;;;;N;;;;;
+1D770;MATHEMATICAL SANS-SERIF BOLD SMALL ALPHA;Ll;0;L;<font> 03B1;;;;N;;;;;
+1D771;MATHEMATICAL SANS-SERIF BOLD SMALL BETA;Ll;0;L;<font> 03B2;;;;N;;;;;
+1D772;MATHEMATICAL SANS-SERIF BOLD SMALL GAMMA;Ll;0;L;<font> 03B3;;;;N;;;;;
+1D773;MATHEMATICAL SANS-SERIF BOLD SMALL DELTA;Ll;0;L;<font> 03B4;;;;N;;;;;
+1D774;MATHEMATICAL SANS-SERIF BOLD SMALL EPSILON;Ll;0;L;<font> 03B5;;;;N;;;;;
+1D775;MATHEMATICAL SANS-SERIF BOLD SMALL ZETA;Ll;0;L;<font> 03B6;;;;N;;;;;
+1D776;MATHEMATICAL SANS-SERIF BOLD SMALL ETA;Ll;0;L;<font> 03B7;;;;N;;;;;
+1D777;MATHEMATICAL SANS-SERIF BOLD SMALL THETA;Ll;0;L;<font> 03B8;;;;N;;;;;
+1D778;MATHEMATICAL SANS-SERIF BOLD SMALL IOTA;Ll;0;L;<font> 03B9;;;;N;;;;;
+1D779;MATHEMATICAL SANS-SERIF BOLD SMALL KAPPA;Ll;0;L;<font> 03BA;;;;N;;;;;
+1D77A;MATHEMATICAL SANS-SERIF BOLD SMALL LAMDA;Ll;0;L;<font> 03BB;;;;N;;;;;
+1D77B;MATHEMATICAL SANS-SERIF BOLD SMALL MU;Ll;0;L;<font> 03BC;;;;N;;;;;
+1D77C;MATHEMATICAL SANS-SERIF BOLD SMALL NU;Ll;0;L;<font> 03BD;;;;N;;;;;
+1D77D;MATHEMATICAL SANS-SERIF BOLD SMALL XI;Ll;0;L;<font> 03BE;;;;N;;;;;
+1D77E;MATHEMATICAL SANS-SERIF BOLD SMALL OMICRON;Ll;0;L;<font> 03BF;;;;N;;;;;
+1D77F;MATHEMATICAL SANS-SERIF BOLD SMALL PI;Ll;0;L;<font> 03C0;;;;N;;;;;
+1D780;MATHEMATICAL SANS-SERIF BOLD SMALL RHO;Ll;0;L;<font> 03C1;;;;N;;;;;
+1D781;MATHEMATICAL SANS-SERIF BOLD SMALL FINAL SIGMA;Ll;0;L;<font> 03C2;;;;N;;;;;
+1D782;MATHEMATICAL SANS-SERIF BOLD SMALL SIGMA;Ll;0;L;<font> 03C3;;;;N;;;;;
+1D783;MATHEMATICAL SANS-SERIF BOLD SMALL TAU;Ll;0;L;<font> 03C4;;;;N;;;;;
+1D784;MATHEMATICAL SANS-SERIF BOLD SMALL UPSILON;Ll;0;L;<font> 03C5;;;;N;;;;;
+1D785;MATHEMATICAL SANS-SERIF BOLD SMALL PHI;Ll;0;L;<font> 03C6;;;;N;;;;;
+1D786;MATHEMATICAL SANS-SERIF BOLD SMALL CHI;Ll;0;L;<font> 03C7;;;;N;;;;;
+1D787;MATHEMATICAL SANS-SERIF BOLD SMALL PSI;Ll;0;L;<font> 03C8;;;;N;;;;;
+1D788;MATHEMATICAL SANS-SERIF BOLD SMALL OMEGA;Ll;0;L;<font> 03C9;;;;N;;;;;
+1D789;MATHEMATICAL SANS-SERIF BOLD PARTIAL DIFFERENTIAL;Sm;0;ON;<font> 2202;;;;Y;;;;;
+1D78A;MATHEMATICAL SANS-SERIF BOLD EPSILON SYMBOL;Ll;0;L;<font> 03F5;;;;N;;;;;
+1D78B;MATHEMATICAL SANS-SERIF BOLD THETA SYMBOL;Ll;0;L;<font> 03D1;;;;N;;;;;
+1D78C;MATHEMATICAL SANS-SERIF BOLD KAPPA SYMBOL;Ll;0;L;<font> 03F0;;;;N;;;;;
+1D78D;MATHEMATICAL SANS-SERIF BOLD PHI SYMBOL;Ll;0;L;<font> 03D5;;;;N;;;;;
+1D78E;MATHEMATICAL SANS-SERIF BOLD RHO SYMBOL;Ll;0;L;<font> 03F1;;;;N;;;;;
+1D78F;MATHEMATICAL SANS-SERIF BOLD PI SYMBOL;Ll;0;L;<font> 03D6;;;;N;;;;;
+1D790;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL ALPHA;Lu;0;L;<font> 0391;;;;N;;;;;
+1D791;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL BETA;Lu;0;L;<font> 0392;;;;N;;;;;
+1D792;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL GAMMA;Lu;0;L;<font> 0393;;;;N;;;;;
+1D793;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL DELTA;Lu;0;L;<font> 0394;;;;N;;;;;
+1D794;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL EPSILON;Lu;0;L;<font> 0395;;;;N;;;;;
+1D795;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL ZETA;Lu;0;L;<font> 0396;;;;N;;;;;
+1D796;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL ETA;Lu;0;L;<font> 0397;;;;N;;;;;
+1D797;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL THETA;Lu;0;L;<font> 0398;;;;N;;;;;
+1D798;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL IOTA;Lu;0;L;<font> 0399;;;;N;;;;;
+1D799;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL KAPPA;Lu;0;L;<font> 039A;;;;N;;;;;
+1D79A;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL LAMDA;Lu;0;L;<font> 039B;;;;N;;;;;
+1D79B;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL MU;Lu;0;L;<font> 039C;;;;N;;;;;
+1D79C;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL NU;Lu;0;L;<font> 039D;;;;N;;;;;
+1D79D;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL XI;Lu;0;L;<font> 039E;;;;N;;;;;
+1D79E;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL OMICRON;Lu;0;L;<font> 039F;;;;N;;;;;
+1D79F;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL PI;Lu;0;L;<font> 03A0;;;;N;;;;;
+1D7A0;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL RHO;Lu;0;L;<font> 03A1;;;;N;;;;;
+1D7A1;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL THETA SYMBOL;Lu;0;L;<font> 03F4;;;;N;;;;;
+1D7A2;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL SIGMA;Lu;0;L;<font> 03A3;;;;N;;;;;
+1D7A3;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL TAU;Lu;0;L;<font> 03A4;;;;N;;;;;
+1D7A4;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL UPSILON;Lu;0;L;<font> 03A5;;;;N;;;;;
+1D7A5;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL PHI;Lu;0;L;<font> 03A6;;;;N;;;;;
+1D7A6;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL CHI;Lu;0;L;<font> 03A7;;;;N;;;;;
+1D7A7;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL PSI;Lu;0;L;<font> 03A8;;;;N;;;;;
+1D7A8;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL OMEGA;Lu;0;L;<font> 03A9;;;;N;;;;;
+1D7A9;MATHEMATICAL SANS-SERIF BOLD ITALIC NABLA;Sm;0;L;<font> 2207;;;;N;;;;;
+1D7AA;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ALPHA;Ll;0;L;<font> 03B1;;;;N;;;;;
+1D7AB;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL BETA;Ll;0;L;<font> 03B2;;;;N;;;;;
+1D7AC;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL GAMMA;Ll;0;L;<font> 03B3;;;;N;;;;;
+1D7AD;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL DELTA;Ll;0;L;<font> 03B4;;;;N;;;;;
+1D7AE;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL EPSILON;Ll;0;L;<font> 03B5;;;;N;;;;;
+1D7AF;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ZETA;Ll;0;L;<font> 03B6;;;;N;;;;;
+1D7B0;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ETA;Ll;0;L;<font> 03B7;;;;N;;;;;
+1D7B1;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL THETA;Ll;0;L;<font> 03B8;;;;N;;;;;
+1D7B2;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL IOTA;Ll;0;L;<font> 03B9;;;;N;;;;;
+1D7B3;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL KAPPA;Ll;0;L;<font> 03BA;;;;N;;;;;
+1D7B4;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL LAMDA;Ll;0;L;<font> 03BB;;;;N;;;;;
+1D7B5;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL MU;Ll;0;L;<font> 03BC;;;;N;;;;;
+1D7B6;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL NU;Ll;0;L;<font> 03BD;;;;N;;;;;
+1D7B7;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL XI;Ll;0;L;<font> 03BE;;;;N;;;;;
+1D7B8;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL OMICRON;Ll;0;L;<font> 03BF;;;;N;;;;;
+1D7B9;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL PI;Ll;0;L;<font> 03C0;;;;N;;;;;
+1D7BA;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL RHO;Ll;0;L;<font> 03C1;;;;N;;;;;
+1D7BB;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL FINAL SIGMA;Ll;0;L;<font> 03C2;;;;N;;;;;
+1D7BC;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL SIGMA;Ll;0;L;<font> 03C3;;;;N;;;;;
+1D7BD;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL TAU;Ll;0;L;<font> 03C4;;;;N;;;;;
+1D7BE;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL UPSILON;Ll;0;L;<font> 03C5;;;;N;;;;;
+1D7BF;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL PHI;Ll;0;L;<font> 03C6;;;;N;;;;;
+1D7C0;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL CHI;Ll;0;L;<font> 03C7;;;;N;;;;;
+1D7C1;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL PSI;Ll;0;L;<font> 03C8;;;;N;;;;;
+1D7C2;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL OMEGA;Ll;0;L;<font> 03C9;;;;N;;;;;
+1D7C3;MATHEMATICAL SANS-SERIF BOLD ITALIC PARTIAL DIFFERENTIAL;Sm;0;ON;<font> 2202;;;;Y;;;;;
+1D7C4;MATHEMATICAL SANS-SERIF BOLD ITALIC EPSILON SYMBOL;Ll;0;L;<font> 03F5;;;;N;;;;;
+1D7C5;MATHEMATICAL SANS-SERIF BOLD ITALIC THETA SYMBOL;Ll;0;L;<font> 03D1;;;;N;;;;;
+1D7C6;MATHEMATICAL SANS-SERIF BOLD ITALIC KAPPA SYMBOL;Ll;0;L;<font> 03F0;;;;N;;;;;
+1D7C7;MATHEMATICAL SANS-SERIF BOLD ITALIC PHI SYMBOL;Ll;0;L;<font> 03D5;;;;N;;;;;
+1D7C8;MATHEMATICAL SANS-SERIF BOLD ITALIC RHO SYMBOL;Ll;0;L;<font> 03F1;;;;N;;;;;
+1D7C9;MATHEMATICAL SANS-SERIF BOLD ITALIC PI SYMBOL;Ll;0;L;<font> 03D6;;;;N;;;;;
+1D7CA;MATHEMATICAL BOLD CAPITAL DIGAMMA;Lu;0;L;<font> 03DC;;;;N;;;;;
+1D7CB;MATHEMATICAL BOLD SMALL DIGAMMA;Ll;0;L;<font> 03DD;;;;N;;;;;
+1D7CE;MATHEMATICAL BOLD DIGIT ZERO;Nd;0;EN;<font> 0030;0;0;0;N;;;;;
+1D7CF;MATHEMATICAL BOLD DIGIT ONE;Nd;0;EN;<font> 0031;1;1;1;N;;;;;
+1D7D0;MATHEMATICAL BOLD DIGIT TWO;Nd;0;EN;<font> 0032;2;2;2;N;;;;;
+1D7D1;MATHEMATICAL BOLD DIGIT THREE;Nd;0;EN;<font> 0033;3;3;3;N;;;;;
+1D7D2;MATHEMATICAL BOLD DIGIT FOUR;Nd;0;EN;<font> 0034;4;4;4;N;;;;;
+1D7D3;MATHEMATICAL BOLD DIGIT FIVE;Nd;0;EN;<font> 0035;5;5;5;N;;;;;
+1D7D4;MATHEMATICAL BOLD DIGIT SIX;Nd;0;EN;<font> 0036;6;6;6;N;;;;;
+1D7D5;MATHEMATICAL BOLD DIGIT SEVEN;Nd;0;EN;<font> 0037;7;7;7;N;;;;;
+1D7D6;MATHEMATICAL BOLD DIGIT EIGHT;Nd;0;EN;<font> 0038;8;8;8;N;;;;;
+1D7D7;MATHEMATICAL BOLD DIGIT NINE;Nd;0;EN;<font> 0039;9;9;9;N;;;;;
+1D7D8;MATHEMATICAL DOUBLE-STRUCK DIGIT ZERO;Nd;0;EN;<font> 0030;0;0;0;N;;;;;
+1D7D9;MATHEMATICAL DOUBLE-STRUCK DIGIT ONE;Nd;0;EN;<font> 0031;1;1;1;N;;;;;
+1D7DA;MATHEMATICAL DOUBLE-STRUCK DIGIT TWO;Nd;0;EN;<font> 0032;2;2;2;N;;;;;
+1D7DB;MATHEMATICAL DOUBLE-STRUCK DIGIT THREE;Nd;0;EN;<font> 0033;3;3;3;N;;;;;
+1D7DC;MATHEMATICAL DOUBLE-STRUCK DIGIT FOUR;Nd;0;EN;<font> 0034;4;4;4;N;;;;;
+1D7DD;MATHEMATICAL DOUBLE-STRUCK DIGIT FIVE;Nd;0;EN;<font> 0035;5;5;5;N;;;;;
+1D7DE;MATHEMATICAL DOUBLE-STRUCK DIGIT SIX;Nd;0;EN;<font> 0036;6;6;6;N;;;;;
+1D7DF;MATHEMATICAL DOUBLE-STRUCK DIGIT SEVEN;Nd;0;EN;<font> 0037;7;7;7;N;;;;;
+1D7E0;MATHEMATICAL DOUBLE-STRUCK DIGIT EIGHT;Nd;0;EN;<font> 0038;8;8;8;N;;;;;
+1D7E1;MATHEMATICAL DOUBLE-STRUCK DIGIT NINE;Nd;0;EN;<font> 0039;9;9;9;N;;;;;
+1D7E2;MATHEMATICAL SANS-SERIF DIGIT ZERO;Nd;0;EN;<font> 0030;0;0;0;N;;;;;
+1D7E3;MATHEMATICAL SANS-SERIF DIGIT ONE;Nd;0;EN;<font> 0031;1;1;1;N;;;;;
+1D7E4;MATHEMATICAL SANS-SERIF DIGIT TWO;Nd;0;EN;<font> 0032;2;2;2;N;;;;;
+1D7E5;MATHEMATICAL SANS-SERIF DIGIT THREE;Nd;0;EN;<font> 0033;3;3;3;N;;;;;
+1D7E6;MATHEMATICAL SANS-SERIF DIGIT FOUR;Nd;0;EN;<font> 0034;4;4;4;N;;;;;
+1D7E7;MATHEMATICAL SANS-SERIF DIGIT FIVE;Nd;0;EN;<font> 0035;5;5;5;N;;;;;
+1D7E8;MATHEMATICAL SANS-SERIF DIGIT SIX;Nd;0;EN;<font> 0036;6;6;6;N;;;;;
+1D7E9;MATHEMATICAL SANS-SERIF DIGIT SEVEN;Nd;0;EN;<font> 0037;7;7;7;N;;;;;
+1D7EA;MATHEMATICAL SANS-SERIF DIGIT EIGHT;Nd;0;EN;<font> 0038;8;8;8;N;;;;;
+1D7EB;MATHEMATICAL SANS-SERIF DIGIT NINE;Nd;0;EN;<font> 0039;9;9;9;N;;;;;
+1D7EC;MATHEMATICAL SANS-SERIF BOLD DIGIT ZERO;Nd;0;EN;<font> 0030;0;0;0;N;;;;;
+1D7ED;MATHEMATICAL SANS-SERIF BOLD DIGIT ONE;Nd;0;EN;<font> 0031;1;1;1;N;;;;;
+1D7EE;MATHEMATICAL SANS-SERIF BOLD DIGIT TWO;Nd;0;EN;<font> 0032;2;2;2;N;;;;;
+1D7EF;MATHEMATICAL SANS-SERIF BOLD DIGIT THREE;Nd;0;EN;<font> 0033;3;3;3;N;;;;;
+1D7F0;MATHEMATICAL SANS-SERIF BOLD DIGIT FOUR;Nd;0;EN;<font> 0034;4;4;4;N;;;;;
+1D7F1;MATHEMATICAL SANS-SERIF BOLD DIGIT FIVE;Nd;0;EN;<font> 0035;5;5;5;N;;;;;
+1D7F2;MATHEMATICAL SANS-SERIF BOLD DIGIT SIX;Nd;0;EN;<font> 0036;6;6;6;N;;;;;
+1D7F3;MATHEMATICAL SANS-SERIF BOLD DIGIT SEVEN;Nd;0;EN;<font> 0037;7;7;7;N;;;;;
+1D7F4;MATHEMATICAL SANS-SERIF BOLD DIGIT EIGHT;Nd;0;EN;<font> 0038;8;8;8;N;;;;;
+1D7F5;MATHEMATICAL SANS-SERIF BOLD DIGIT NINE;Nd;0;EN;<font> 0039;9;9;9;N;;;;;
+1D7F6;MATHEMATICAL MONOSPACE DIGIT ZERO;Nd;0;EN;<font> 0030;0;0;0;N;;;;;
+1D7F7;MATHEMATICAL MONOSPACE DIGIT ONE;Nd;0;EN;<font> 0031;1;1;1;N;;;;;
+1D7F8;MATHEMATICAL MONOSPACE DIGIT TWO;Nd;0;EN;<font> 0032;2;2;2;N;;;;;
+1D7F9;MATHEMATICAL MONOSPACE DIGIT THREE;Nd;0;EN;<font> 0033;3;3;3;N;;;;;
+1D7FA;MATHEMATICAL MONOSPACE DIGIT FOUR;Nd;0;EN;<font> 0034;4;4;4;N;;;;;
+1D7FB;MATHEMATICAL MONOSPACE DIGIT FIVE;Nd;0;EN;<font> 0035;5;5;5;N;;;;;
+1D7FC;MATHEMATICAL MONOSPACE DIGIT SIX;Nd;0;EN;<font> 0036;6;6;6;N;;;;;
+1D7FD;MATHEMATICAL MONOSPACE DIGIT SEVEN;Nd;0;EN;<font> 0037;7;7;7;N;;;;;
+1D7FE;MATHEMATICAL MONOSPACE DIGIT EIGHT;Nd;0;EN;<font> 0038;8;8;8;N;;;;;
+1D7FF;MATHEMATICAL MONOSPACE DIGIT NINE;Nd;0;EN;<font> 0039;9;9;9;N;;;;;
+1F000;MAHJONG TILE EAST WIND;So;0;ON;;;;;N;;;;;
+1F001;MAHJONG TILE SOUTH WIND;So;0;ON;;;;;N;;;;;
+1F002;MAHJONG TILE WEST WIND;So;0;ON;;;;;N;;;;;
+1F003;MAHJONG TILE NORTH WIND;So;0;ON;;;;;N;;;;;
+1F004;MAHJONG TILE RED DRAGON;So;0;ON;;;;;N;;;;;
+1F005;MAHJONG TILE GREEN DRAGON;So;0;ON;;;;;N;;;;;
+1F006;MAHJONG TILE WHITE DRAGON;So;0;ON;;;;;N;;;;;
+1F007;MAHJONG TILE ONE OF CHARACTERS;So;0;ON;;;;;N;;;;;
+1F008;MAHJONG TILE TWO OF CHARACTERS;So;0;ON;;;;;N;;;;;
+1F009;MAHJONG TILE THREE OF CHARACTERS;So;0;ON;;;;;N;;;;;
+1F00A;MAHJONG TILE FOUR OF CHARACTERS;So;0;ON;;;;;N;;;;;
+1F00B;MAHJONG TILE FIVE OF CHARACTERS;So;0;ON;;;;;N;;;;;
+1F00C;MAHJONG TILE SIX OF CHARACTERS;So;0;ON;;;;;N;;;;;
+1F00D;MAHJONG TILE SEVEN OF CHARACTERS;So;0;ON;;;;;N;;;;;
+1F00E;MAHJONG TILE EIGHT OF CHARACTERS;So;0;ON;;;;;N;;;;;
+1F00F;MAHJONG TILE NINE OF CHARACTERS;So;0;ON;;;;;N;;;;;
+1F010;MAHJONG TILE ONE OF BAMBOOS;So;0;ON;;;;;N;;;;;
+1F011;MAHJONG TILE TWO OF BAMBOOS;So;0;ON;;;;;N;;;;;
+1F012;MAHJONG TILE THREE OF BAMBOOS;So;0;ON;;;;;N;;;;;
+1F013;MAHJONG TILE FOUR OF BAMBOOS;So;0;ON;;;;;N;;;;;
+1F014;MAHJONG TILE FIVE OF BAMBOOS;So;0;ON;;;;;N;;;;;
+1F015;MAHJONG TILE SIX OF BAMBOOS;So;0;ON;;;;;N;;;;;
+1F016;MAHJONG TILE SEVEN OF BAMBOOS;So;0;ON;;;;;N;;;;;
+1F017;MAHJONG TILE EIGHT OF BAMBOOS;So;0;ON;;;;;N;;;;;
+1F018;MAHJONG TILE NINE OF BAMBOOS;So;0;ON;;;;;N;;;;;
+1F019;MAHJONG TILE ONE OF CIRCLES;So;0;ON;;;;;N;;;;;
+1F01A;MAHJONG TILE TWO OF CIRCLES;So;0;ON;;;;;N;;;;;
+1F01B;MAHJONG TILE THREE OF CIRCLES;So;0;ON;;;;;N;;;;;
+1F01C;MAHJONG TILE FOUR OF CIRCLES;So;0;ON;;;;;N;;;;;
+1F01D;MAHJONG TILE FIVE OF CIRCLES;So;0;ON;;;;;N;;;;;
+1F01E;MAHJONG TILE SIX OF CIRCLES;So;0;ON;;;;;N;;;;;
+1F01F;MAHJONG TILE SEVEN OF CIRCLES;So;0;ON;;;;;N;;;;;
+1F020;MAHJONG TILE EIGHT OF CIRCLES;So;0;ON;;;;;N;;;;;
+1F021;MAHJONG TILE NINE OF CIRCLES;So;0;ON;;;;;N;;;;;
+1F022;MAHJONG TILE PLUM;So;0;ON;;;;;N;;;;;
+1F023;MAHJONG TILE ORCHID;So;0;ON;;;;;N;;;;;
+1F024;MAHJONG TILE BAMBOO;So;0;ON;;;;;N;;;;;
+1F025;MAHJONG TILE CHRYSANTHEMUM;So;0;ON;;;;;N;;;;;
+1F026;MAHJONG TILE SPRING;So;0;ON;;;;;N;;;;;
+1F027;MAHJONG TILE SUMMER;So;0;ON;;;;;N;;;;;
+1F028;MAHJONG TILE AUTUMN;So;0;ON;;;;;N;;;;;
+1F029;MAHJONG TILE WINTER;So;0;ON;;;;;N;;;;;
+1F02A;MAHJONG TILE JOKER;So;0;ON;;;;;N;;;;;
+1F02B;MAHJONG TILE BACK;So;0;ON;;;;;N;;;;;
+1F030;DOMINO TILE HORIZONTAL BACK;So;0;ON;;;;;N;;;;;
+1F031;DOMINO TILE HORIZONTAL-00-00;So;0;ON;;;;;N;;;;;
+1F032;DOMINO TILE HORIZONTAL-00-01;So;0;ON;;;;;N;;;;;
+1F033;DOMINO TILE HORIZONTAL-00-02;So;0;ON;;;;;N;;;;;
+1F034;DOMINO TILE HORIZONTAL-00-03;So;0;ON;;;;;N;;;;;
+1F035;DOMINO TILE HORIZONTAL-00-04;So;0;ON;;;;;N;;;;;
+1F036;DOMINO TILE HORIZONTAL-00-05;So;0;ON;;;;;N;;;;;
+1F037;DOMINO TILE HORIZONTAL-00-06;So;0;ON;;;;;N;;;;;
+1F038;DOMINO TILE HORIZONTAL-01-00;So;0;ON;;;;;N;;;;;
+1F039;DOMINO TILE HORIZONTAL-01-01;So;0;ON;;;;;N;;;;;
+1F03A;DOMINO TILE HORIZONTAL-01-02;So;0;ON;;;;;N;;;;;
+1F03B;DOMINO TILE HORIZONTAL-01-03;So;0;ON;;;;;N;;;;;
+1F03C;DOMINO TILE HORIZONTAL-01-04;So;0;ON;;;;;N;;;;;
+1F03D;DOMINO TILE HORIZONTAL-01-05;So;0;ON;;;;;N;;;;;
+1F03E;DOMINO TILE HORIZONTAL-01-06;So;0;ON;;;;;N;;;;;
+1F03F;DOMINO TILE HORIZONTAL-02-00;So;0;ON;;;;;N;;;;;
+1F040;DOMINO TILE HORIZONTAL-02-01;So;0;ON;;;;;N;;;;;
+1F041;DOMINO TILE HORIZONTAL-02-02;So;0;ON;;;;;N;;;;;
+1F042;DOMINO TILE HORIZONTAL-02-03;So;0;ON;;;;;N;;;;;
+1F043;DOMINO TILE HORIZONTAL-02-04;So;0;ON;;;;;N;;;;;
+1F044;DOMINO TILE HORIZONTAL-02-05;So;0;ON;;;;;N;;;;;
+1F045;DOMINO TILE HORIZONTAL-02-06;So;0;ON;;;;;N;;;;;
+1F046;DOMINO TILE HORIZONTAL-03-00;So;0;ON;;;;;N;;;;;
+1F047;DOMINO TILE HORIZONTAL-03-01;So;0;ON;;;;;N;;;;;
+1F048;DOMINO TILE HORIZONTAL-03-02;So;0;ON;;;;;N;;;;;
+1F049;DOMINO TILE HORIZONTAL-03-03;So;0;ON;;;;;N;;;;;
+1F04A;DOMINO TILE HORIZONTAL-03-04;So;0;ON;;;;;N;;;;;
+1F04B;DOMINO TILE HORIZONTAL-03-05;So;0;ON;;;;;N;;;;;
+1F04C;DOMINO TILE HORIZONTAL-03-06;So;0;ON;;;;;N;;;;;
+1F04D;DOMINO TILE HORIZONTAL-04-00;So;0;ON;;;;;N;;;;;
+1F04E;DOMINO TILE HORIZONTAL-04-01;So;0;ON;;;;;N;;;;;
+1F04F;DOMINO TILE HORIZONTAL-04-02;So;0;ON;;;;;N;;;;;
+1F050;DOMINO TILE HORIZONTAL-04-03;So;0;ON;;;;;N;;;;;
+1F051;DOMINO TILE HORIZONTAL-04-04;So;0;ON;;;;;N;;;;;
+1F052;DOMINO TILE HORIZONTAL-04-05;So;0;ON;;;;;N;;;;;
+1F053;DOMINO TILE HORIZONTAL-04-06;So;0;ON;;;;;N;;;;;
+1F054;DOMINO TILE HORIZONTAL-05-00;So;0;ON;;;;;N;;;;;
+1F055;DOMINO TILE HORIZONTAL-05-01;So;0;ON;;;;;N;;;;;
+1F056;DOMINO TILE HORIZONTAL-05-02;So;0;ON;;;;;N;;;;;
+1F057;DOMINO TILE HORIZONTAL-05-03;So;0;ON;;;;;N;;;;;
+1F058;DOMINO TILE HORIZONTAL-05-04;So;0;ON;;;;;N;;;;;
+1F059;DOMINO TILE HORIZONTAL-05-05;So;0;ON;;;;;N;;;;;
+1F05A;DOMINO TILE HORIZONTAL-05-06;So;0;ON;;;;;N;;;;;
+1F05B;DOMINO TILE HORIZONTAL-06-00;So;0;ON;;;;;N;;;;;
+1F05C;DOMINO TILE HORIZONTAL-06-01;So;0;ON;;;;;N;;;;;
+1F05D;DOMINO TILE HORIZONTAL-06-02;So;0;ON;;;;;N;;;;;
+1F05E;DOMINO TILE HORIZONTAL-06-03;So;0;ON;;;;;N;;;;;
+1F05F;DOMINO TILE HORIZONTAL-06-04;So;0;ON;;;;;N;;;;;
+1F060;DOMINO TILE HORIZONTAL-06-05;So;0;ON;;;;;N;;;;;
+1F061;DOMINO TILE HORIZONTAL-06-06;So;0;ON;;;;;N;;;;;
+1F062;DOMINO TILE VERTICAL BACK;So;0;ON;;;;;N;;;;;
+1F063;DOMINO TILE VERTICAL-00-00;So;0;ON;;;;;N;;;;;
+1F064;DOMINO TILE VERTICAL-00-01;So;0;ON;;;;;N;;;;;
+1F065;DOMINO TILE VERTICAL-00-02;So;0;ON;;;;;N;;;;;
+1F066;DOMINO TILE VERTICAL-00-03;So;0;ON;;;;;N;;;;;
+1F067;DOMINO TILE VERTICAL-00-04;So;0;ON;;;;;N;;;;;
+1F068;DOMINO TILE VERTICAL-00-05;So;0;ON;;;;;N;;;;;
+1F069;DOMINO TILE VERTICAL-00-06;So;0;ON;;;;;N;;;;;
+1F06A;DOMINO TILE VERTICAL-01-00;So;0;ON;;;;;N;;;;;
+1F06B;DOMINO TILE VERTICAL-01-01;So;0;ON;;;;;N;;;;;
+1F06C;DOMINO TILE VERTICAL-01-02;So;0;ON;;;;;N;;;;;
+1F06D;DOMINO TILE VERTICAL-01-03;So;0;ON;;;;;N;;;;;
+1F06E;DOMINO TILE VERTICAL-01-04;So;0;ON;;;;;N;;;;;
+1F06F;DOMINO TILE VERTICAL-01-05;So;0;ON;;;;;N;;;;;
+1F070;DOMINO TILE VERTICAL-01-06;So;0;ON;;;;;N;;;;;
+1F071;DOMINO TILE VERTICAL-02-00;So;0;ON;;;;;N;;;;;
+1F072;DOMINO TILE VERTICAL-02-01;So;0;ON;;;;;N;;;;;
+1F073;DOMINO TILE VERTICAL-02-02;So;0;ON;;;;;N;;;;;
+1F074;DOMINO TILE VERTICAL-02-03;So;0;ON;;;;;N;;;;;
+1F075;DOMINO TILE VERTICAL-02-04;So;0;ON;;;;;N;;;;;
+1F076;DOMINO TILE VERTICAL-02-05;So;0;ON;;;;;N;;;;;
+1F077;DOMINO TILE VERTICAL-02-06;So;0;ON;;;;;N;;;;;
+1F078;DOMINO TILE VERTICAL-03-00;So;0;ON;;;;;N;;;;;
+1F079;DOMINO TILE VERTICAL-03-01;So;0;ON;;;;;N;;;;;
+1F07A;DOMINO TILE VERTICAL-03-02;So;0;ON;;;;;N;;;;;
+1F07B;DOMINO TILE VERTICAL-03-03;So;0;ON;;;;;N;;;;;
+1F07C;DOMINO TILE VERTICAL-03-04;So;0;ON;;;;;N;;;;;
+1F07D;DOMINO TILE VERTICAL-03-05;So;0;ON;;;;;N;;;;;
+1F07E;DOMINO TILE VERTICAL-03-06;So;0;ON;;;;;N;;;;;
+1F07F;DOMINO TILE VERTICAL-04-00;So;0;ON;;;;;N;;;;;
+1F080;DOMINO TILE VERTICAL-04-01;So;0;ON;;;;;N;;;;;
+1F081;DOMINO TILE VERTICAL-04-02;So;0;ON;;;;;N;;;;;
+1F082;DOMINO TILE VERTICAL-04-03;So;0;ON;;;;;N;;;;;
+1F083;DOMINO TILE VERTICAL-04-04;So;0;ON;;;;;N;;;;;
+1F084;DOMINO TILE VERTICAL-04-05;So;0;ON;;;;;N;;;;;
+1F085;DOMINO TILE VERTICAL-04-06;So;0;ON;;;;;N;;;;;
+1F086;DOMINO TILE VERTICAL-05-00;So;0;ON;;;;;N;;;;;
+1F087;DOMINO TILE VERTICAL-05-01;So;0;ON;;;;;N;;;;;
+1F088;DOMINO TILE VERTICAL-05-02;So;0;ON;;;;;N;;;;;
+1F089;DOMINO TILE VERTICAL-05-03;So;0;ON;;;;;N;;;;;
+1F08A;DOMINO TILE VERTICAL-05-04;So;0;ON;;;;;N;;;;;
+1F08B;DOMINO TILE VERTICAL-05-05;So;0;ON;;;;;N;;;;;
+1F08C;DOMINO TILE VERTICAL-05-06;So;0;ON;;;;;N;;;;;
+1F08D;DOMINO TILE VERTICAL-06-00;So;0;ON;;;;;N;;;;;
+1F08E;DOMINO TILE VERTICAL-06-01;So;0;ON;;;;;N;;;;;
+1F08F;DOMINO TILE VERTICAL-06-02;So;0;ON;;;;;N;;;;;
+1F090;DOMINO TILE VERTICAL-06-03;So;0;ON;;;;;N;;;;;
+1F091;DOMINO TILE VERTICAL-06-04;So;0;ON;;;;;N;;;;;
+1F092;DOMINO TILE VERTICAL-06-05;So;0;ON;;;;;N;;;;;
+1F093;DOMINO TILE VERTICAL-06-06;So;0;ON;;;;;N;;;;;
+1F0A0;PLAYING CARD BACK;So;0;ON;;;;;N;;;;;
+1F0A1;PLAYING CARD ACE OF SPADES;So;0;ON;;;;;N;;;;;
+1F0A2;PLAYING CARD TWO OF SPADES;So;0;ON;;;;;N;;;;;
+1F0A3;PLAYING CARD THREE OF SPADES;So;0;ON;;;;;N;;;;;
+1F0A4;PLAYING CARD FOUR OF SPADES;So;0;ON;;;;;N;;;;;
+1F0A5;PLAYING CARD FIVE OF SPADES;So;0;ON;;;;;N;;;;;
+1F0A6;PLAYING CARD SIX OF SPADES;So;0;ON;;;;;N;;;;;
+1F0A7;PLAYING CARD SEVEN OF SPADES;So;0;ON;;;;;N;;;;;
+1F0A8;PLAYING CARD EIGHT OF SPADES;So;0;ON;;;;;N;;;;;
+1F0A9;PLAYING CARD NINE OF SPADES;So;0;ON;;;;;N;;;;;
+1F0AA;PLAYING CARD TEN OF SPADES;So;0;ON;;;;;N;;;;;
+1F0AB;PLAYING CARD JACK OF SPADES;So;0;ON;;;;;N;;;;;
+1F0AC;PLAYING CARD KNIGHT OF SPADES;So;0;ON;;;;;N;;;;;
+1F0AD;PLAYING CARD QUEEN OF SPADES;So;0;ON;;;;;N;;;;;
+1F0AE;PLAYING CARD KING OF SPADES;So;0;ON;;;;;N;;;;;
+1F0B1;PLAYING CARD ACE OF HEARTS;So;0;ON;;;;;N;;;;;
+1F0B2;PLAYING CARD TWO OF HEARTS;So;0;ON;;;;;N;;;;;
+1F0B3;PLAYING CARD THREE OF HEARTS;So;0;ON;;;;;N;;;;;
+1F0B4;PLAYING CARD FOUR OF HEARTS;So;0;ON;;;;;N;;;;;
+1F0B5;PLAYING CARD FIVE OF HEARTS;So;0;ON;;;;;N;;;;;
+1F0B6;PLAYING CARD SIX OF HEARTS;So;0;ON;;;;;N;;;;;
+1F0B7;PLAYING CARD SEVEN OF HEARTS;So;0;ON;;;;;N;;;;;
+1F0B8;PLAYING CARD EIGHT OF HEARTS;So;0;ON;;;;;N;;;;;
+1F0B9;PLAYING CARD NINE OF HEARTS;So;0;ON;;;;;N;;;;;
+1F0BA;PLAYING CARD TEN OF HEARTS;So;0;ON;;;;;N;;;;;
+1F0BB;PLAYING CARD JACK OF HEARTS;So;0;ON;;;;;N;;;;;
+1F0BC;PLAYING CARD KNIGHT OF HEARTS;So;0;ON;;;;;N;;;;;
+1F0BD;PLAYING CARD QUEEN OF HEARTS;So;0;ON;;;;;N;;;;;
+1F0BE;PLAYING CARD KING OF HEARTS;So;0;ON;;;;;N;;;;;
+1F0C1;PLAYING CARD ACE OF DIAMONDS;So;0;ON;;;;;N;;;;;
+1F0C2;PLAYING CARD TWO OF DIAMONDS;So;0;ON;;;;;N;;;;;
+1F0C3;PLAYING CARD THREE OF DIAMONDS;So;0;ON;;;;;N;;;;;
+1F0C4;PLAYING CARD FOUR OF DIAMONDS;So;0;ON;;;;;N;;;;;
+1F0C5;PLAYING CARD FIVE OF DIAMONDS;So;0;ON;;;;;N;;;;;
+1F0C6;PLAYING CARD SIX OF DIAMONDS;So;0;ON;;;;;N;;;;;
+1F0C7;PLAYING CARD SEVEN OF DIAMONDS;So;0;ON;;;;;N;;;;;
+1F0C8;PLAYING CARD EIGHT OF DIAMONDS;So;0;ON;;;;;N;;;;;
+1F0C9;PLAYING CARD NINE OF DIAMONDS;So;0;ON;;;;;N;;;;;
+1F0CA;PLAYING CARD TEN OF DIAMONDS;So;0;ON;;;;;N;;;;;
+1F0CB;PLAYING CARD JACK OF DIAMONDS;So;0;ON;;;;;N;;;;;
+1F0CC;PLAYING CARD KNIGHT OF DIAMONDS;So;0;ON;;;;;N;;;;;
+1F0CD;PLAYING CARD QUEEN OF DIAMONDS;So;0;ON;;;;;N;;;;;
+1F0CE;PLAYING CARD KING OF DIAMONDS;So;0;ON;;;;;N;;;;;
+1F0CF;PLAYING CARD BLACK JOKER;So;0;ON;;;;;N;;;;;
+1F0D1;PLAYING CARD ACE OF CLUBS;So;0;ON;;;;;N;;;;;
+1F0D2;PLAYING CARD TWO OF CLUBS;So;0;ON;;;;;N;;;;;
+1F0D3;PLAYING CARD THREE OF CLUBS;So;0;ON;;;;;N;;;;;
+1F0D4;PLAYING CARD FOUR OF CLUBS;So;0;ON;;;;;N;;;;;
+1F0D5;PLAYING CARD FIVE OF CLUBS;So;0;ON;;;;;N;;;;;
+1F0D6;PLAYING CARD SIX OF CLUBS;So;0;ON;;;;;N;;;;;
+1F0D7;PLAYING CARD SEVEN OF CLUBS;So;0;ON;;;;;N;;;;;
+1F0D8;PLAYING CARD EIGHT OF CLUBS;So;0;ON;;;;;N;;;;;
+1F0D9;PLAYING CARD NINE OF CLUBS;So;0;ON;;;;;N;;;;;
+1F0DA;PLAYING CARD TEN OF CLUBS;So;0;ON;;;;;N;;;;;
+1F0DB;PLAYING CARD JACK OF CLUBS;So;0;ON;;;;;N;;;;;
+1F0DC;PLAYING CARD KNIGHT OF CLUBS;So;0;ON;;;;;N;;;;;
+1F0DD;PLAYING CARD QUEEN OF CLUBS;So;0;ON;;;;;N;;;;;
+1F0DE;PLAYING CARD KING OF CLUBS;So;0;ON;;;;;N;;;;;
+1F0DF;PLAYING CARD WHITE JOKER;So;0;ON;;;;;N;;;;;
+1F100;DIGIT ZERO FULL STOP;No;0;EN;<compat> 0030 002E;;0;0;N;;;;;
+1F101;DIGIT ZERO COMMA;No;0;EN;<compat> 0030 002C;;0;0;N;;;;;
+1F102;DIGIT ONE COMMA;No;0;EN;<compat> 0031 002C;;1;1;N;;;;;
+1F103;DIGIT TWO COMMA;No;0;EN;<compat> 0032 002C;;2;2;N;;;;;
+1F104;DIGIT THREE COMMA;No;0;EN;<compat> 0033 002C;;3;3;N;;;;;
+1F105;DIGIT FOUR COMMA;No;0;EN;<compat> 0034 002C;;4;4;N;;;;;
+1F106;DIGIT FIVE COMMA;No;0;EN;<compat> 0035 002C;;5;5;N;;;;;
+1F107;DIGIT SIX COMMA;No;0;EN;<compat> 0036 002C;;6;6;N;;;;;
+1F108;DIGIT SEVEN COMMA;No;0;EN;<compat> 0037 002C;;7;7;N;;;;;
+1F109;DIGIT EIGHT COMMA;No;0;EN;<compat> 0038 002C;;8;8;N;;;;;
+1F10A;DIGIT NINE COMMA;No;0;EN;<compat> 0039 002C;;9;9;N;;;;;
+1F110;PARENTHESIZED LATIN CAPITAL LETTER A;So;0;L;<compat> 0028 0041 0029;;;;N;;;;;
+1F111;PARENTHESIZED LATIN CAPITAL LETTER B;So;0;L;<compat> 0028 0042 0029;;;;N;;;;;
+1F112;PARENTHESIZED LATIN CAPITAL LETTER C;So;0;L;<compat> 0028 0043 0029;;;;N;;;;;
+1F113;PARENTHESIZED LATIN CAPITAL LETTER D;So;0;L;<compat> 0028 0044 0029;;;;N;;;;;
+1F114;PARENTHESIZED LATIN CAPITAL LETTER E;So;0;L;<compat> 0028 0045 0029;;;;N;;;;;
+1F115;PARENTHESIZED LATIN CAPITAL LETTER F;So;0;L;<compat> 0028 0046 0029;;;;N;;;;;
+1F116;PARENTHESIZED LATIN CAPITAL LETTER G;So;0;L;<compat> 0028 0047 0029;;;;N;;;;;
+1F117;PARENTHESIZED LATIN CAPITAL LETTER H;So;0;L;<compat> 0028 0048 0029;;;;N;;;;;
+1F118;PARENTHESIZED LATIN CAPITAL LETTER I;So;0;L;<compat> 0028 0049 0029;;;;N;;;;;
+1F119;PARENTHESIZED LATIN CAPITAL LETTER J;So;0;L;<compat> 0028 004A 0029;;;;N;;;;;
+1F11A;PARENTHESIZED LATIN CAPITAL LETTER K;So;0;L;<compat> 0028 004B 0029;;;;N;;;;;
+1F11B;PARENTHESIZED LATIN CAPITAL LETTER L;So;0;L;<compat> 0028 004C 0029;;;;N;;;;;
+1F11C;PARENTHESIZED LATIN CAPITAL LETTER M;So;0;L;<compat> 0028 004D 0029;;;;N;;;;;
+1F11D;PARENTHESIZED LATIN CAPITAL LETTER N;So;0;L;<compat> 0028 004E 0029;;;;N;;;;;
+1F11E;PARENTHESIZED LATIN CAPITAL LETTER O;So;0;L;<compat> 0028 004F 0029;;;;N;;;;;
+1F11F;PARENTHESIZED LATIN CAPITAL LETTER P;So;0;L;<compat> 0028 0050 0029;;;;N;;;;;
+1F120;PARENTHESIZED LATIN CAPITAL LETTER Q;So;0;L;<compat> 0028 0051 0029;;;;N;;;;;
+1F121;PARENTHESIZED LATIN CAPITAL LETTER R;So;0;L;<compat> 0028 0052 0029;;;;N;;;;;
+1F122;PARENTHESIZED LATIN CAPITAL LETTER S;So;0;L;<compat> 0028 0053 0029;;;;N;;;;;
+1F123;PARENTHESIZED LATIN CAPITAL LETTER T;So;0;L;<compat> 0028 0054 0029;;;;N;;;;;
+1F124;PARENTHESIZED LATIN CAPITAL LETTER U;So;0;L;<compat> 0028 0055 0029;;;;N;;;;;
+1F125;PARENTHESIZED LATIN CAPITAL LETTER V;So;0;L;<compat> 0028 0056 0029;;;;N;;;;;
+1F126;PARENTHESIZED LATIN CAPITAL LETTER W;So;0;L;<compat> 0028 0057 0029;;;;N;;;;;
+1F127;PARENTHESIZED LATIN CAPITAL LETTER X;So;0;L;<compat> 0028 0058 0029;;;;N;;;;;
+1F128;PARENTHESIZED LATIN CAPITAL LETTER Y;So;0;L;<compat> 0028 0059 0029;;;;N;;;;;
+1F129;PARENTHESIZED LATIN CAPITAL LETTER Z;So;0;L;<compat> 0028 005A 0029;;;;N;;;;;
+1F12A;TORTOISE SHELL BRACKETED LATIN CAPITAL LETTER S;So;0;L;<compat> 3014 0053 3015;;;;N;;;;;
+1F12B;CIRCLED ITALIC LATIN CAPITAL LETTER C;So;0;L;<circle> 0043;;;;N;;;;;
+1F12C;CIRCLED ITALIC LATIN CAPITAL LETTER R;So;0;L;<circle> 0052;;;;N;;;;;
+1F12D;CIRCLED CD;So;0;L;<circle> 0043 0044;;;;N;;;;;
+1F12E;CIRCLED WZ;So;0;L;<circle> 0057 005A;;;;N;;;;;
+1F130;SQUARED LATIN CAPITAL LETTER A;So;0;L;<square> 0041;;;;N;;;;;
+1F131;SQUARED LATIN CAPITAL LETTER B;So;0;L;<square> 0042;;;;N;;;;;
+1F132;SQUARED LATIN CAPITAL LETTER C;So;0;L;<square> 0043;;;;N;;;;;
+1F133;SQUARED LATIN CAPITAL LETTER D;So;0;L;<square> 0044;;;;N;;;;;
+1F134;SQUARED LATIN CAPITAL LETTER E;So;0;L;<square> 0045;;;;N;;;;;
+1F135;SQUARED LATIN CAPITAL LETTER F;So;0;L;<square> 0046;;;;N;;;;;
+1F136;SQUARED LATIN CAPITAL LETTER G;So;0;L;<square> 0047;;;;N;;;;;
+1F137;SQUARED LATIN CAPITAL LETTER H;So;0;L;<square> 0048;;;;N;;;;;
+1F138;SQUARED LATIN CAPITAL LETTER I;So;0;L;<square> 0049;;;;N;;;;;
+1F139;SQUARED LATIN CAPITAL LETTER J;So;0;L;<square> 004A;;;;N;;;;;
+1F13A;SQUARED LATIN CAPITAL LETTER K;So;0;L;<square> 004B;;;;N;;;;;
+1F13B;SQUARED LATIN CAPITAL LETTER L;So;0;L;<square> 004C;;;;N;;;;;
+1F13C;SQUARED LATIN CAPITAL LETTER M;So;0;L;<square> 004D;;;;N;;;;;
+1F13D;SQUARED LATIN CAPITAL LETTER N;So;0;L;<square> 004E;;;;N;;;;;
+1F13E;SQUARED LATIN CAPITAL LETTER O;So;0;L;<square> 004F;;;;N;;;;;
+1F13F;SQUARED LATIN CAPITAL LETTER P;So;0;L;<square> 0050;;;;N;;;;;
+1F140;SQUARED LATIN CAPITAL LETTER Q;So;0;L;<square> 0051;;;;N;;;;;
+1F141;SQUARED LATIN CAPITAL LETTER R;So;0;L;<square> 0052;;;;N;;;;;
+1F142;SQUARED LATIN CAPITAL LETTER S;So;0;L;<square> 0053;;;;N;;;;;
+1F143;SQUARED LATIN CAPITAL LETTER T;So;0;L;<square> 0054;;;;N;;;;;
+1F144;SQUARED LATIN CAPITAL LETTER U;So;0;L;<square> 0055;;;;N;;;;;
+1F145;SQUARED LATIN CAPITAL LETTER V;So;0;L;<square> 0056;;;;N;;;;;
+1F146;SQUARED LATIN CAPITAL LETTER W;So;0;L;<square> 0057;;;;N;;;;;
+1F147;SQUARED LATIN CAPITAL LETTER X;So;0;L;<square> 0058;;;;N;;;;;
+1F148;SQUARED LATIN CAPITAL LETTER Y;So;0;L;<square> 0059;;;;N;;;;;
+1F149;SQUARED LATIN CAPITAL LETTER Z;So;0;L;<square> 005A;;;;N;;;;;
+1F14A;SQUARED HV;So;0;L;<square> 0048 0056;;;;N;;;;;
+1F14B;SQUARED MV;So;0;L;<square> 004D 0056;;;;N;;;;;
+1F14C;SQUARED SD;So;0;L;<square> 0053 0044;;;;N;;;;;
+1F14D;SQUARED SS;So;0;L;<square> 0053 0053;;;;N;;;;;
+1F14E;SQUARED PPV;So;0;L;<square> 0050 0050 0056;;;;N;;;;;
+1F14F;SQUARED WC;So;0;L;<square> 0057 0043;;;;N;;;;;
+1F150;NEGATIVE CIRCLED LATIN CAPITAL LETTER A;So;0;L;;;;;N;;;;;
+1F151;NEGATIVE CIRCLED LATIN CAPITAL LETTER B;So;0;L;;;;;N;;;;;
+1F152;NEGATIVE CIRCLED LATIN CAPITAL LETTER C;So;0;L;;;;;N;;;;;
+1F153;NEGATIVE CIRCLED LATIN CAPITAL LETTER D;So;0;L;;;;;N;;;;;
+1F154;NEGATIVE CIRCLED LATIN CAPITAL LETTER E;So;0;L;;;;;N;;;;;
+1F155;NEGATIVE CIRCLED LATIN CAPITAL LETTER F;So;0;L;;;;;N;;;;;
+1F156;NEGATIVE CIRCLED LATIN CAPITAL LETTER G;So;0;L;;;;;N;;;;;
+1F157;NEGATIVE CIRCLED LATIN CAPITAL LETTER H;So;0;L;;;;;N;;;;;
+1F158;NEGATIVE CIRCLED LATIN CAPITAL LETTER I;So;0;L;;;;;N;;;;;
+1F159;NEGATIVE CIRCLED LATIN CAPITAL LETTER J;So;0;L;;;;;N;;;;;
+1F15A;NEGATIVE CIRCLED LATIN CAPITAL LETTER K;So;0;L;;;;;N;;;;;
+1F15B;NEGATIVE CIRCLED LATIN CAPITAL LETTER L;So;0;L;;;;;N;;;;;
+1F15C;NEGATIVE CIRCLED LATIN CAPITAL LETTER M;So;0;L;;;;;N;;;;;
+1F15D;NEGATIVE CIRCLED LATIN CAPITAL LETTER N;So;0;L;;;;;N;;;;;
+1F15E;NEGATIVE CIRCLED LATIN CAPITAL LETTER O;So;0;L;;;;;N;;;;;
+1F15F;NEGATIVE CIRCLED LATIN CAPITAL LETTER P;So;0;L;;;;;N;;;;;
+1F160;NEGATIVE CIRCLED LATIN CAPITAL LETTER Q;So;0;L;;;;;N;;;;;
+1F161;NEGATIVE CIRCLED LATIN CAPITAL LETTER R;So;0;L;;;;;N;;;;;
+1F162;NEGATIVE CIRCLED LATIN CAPITAL LETTER S;So;0;L;;;;;N;;;;;
+1F163;NEGATIVE CIRCLED LATIN CAPITAL LETTER T;So;0;L;;;;;N;;;;;
+1F164;NEGATIVE CIRCLED LATIN CAPITAL LETTER U;So;0;L;;;;;N;;;;;
+1F165;NEGATIVE CIRCLED LATIN CAPITAL LETTER V;So;0;L;;;;;N;;;;;
+1F166;NEGATIVE CIRCLED LATIN CAPITAL LETTER W;So;0;L;;;;;N;;;;;
+1F167;NEGATIVE CIRCLED LATIN CAPITAL LETTER X;So;0;L;;;;;N;;;;;
+1F168;NEGATIVE CIRCLED LATIN CAPITAL LETTER Y;So;0;L;;;;;N;;;;;
+1F169;NEGATIVE CIRCLED LATIN CAPITAL LETTER Z;So;0;L;;;;;N;;;;;
+1F170;NEGATIVE SQUARED LATIN CAPITAL LETTER A;So;0;L;;;;;N;;;;;
+1F171;NEGATIVE SQUARED LATIN CAPITAL LETTER B;So;0;L;;;;;N;;;;;
+1F172;NEGATIVE SQUARED LATIN CAPITAL LETTER C;So;0;L;;;;;N;;;;;
+1F173;NEGATIVE SQUARED LATIN CAPITAL LETTER D;So;0;L;;;;;N;;;;;
+1F174;NEGATIVE SQUARED LATIN CAPITAL LETTER E;So;0;L;;;;;N;;;;;
+1F175;NEGATIVE SQUARED LATIN CAPITAL LETTER F;So;0;L;;;;;N;;;;;
+1F176;NEGATIVE SQUARED LATIN CAPITAL LETTER G;So;0;L;;;;;N;;;;;
+1F177;NEGATIVE SQUARED LATIN CAPITAL LETTER H;So;0;L;;;;;N;;;;;
+1F178;NEGATIVE SQUARED LATIN CAPITAL LETTER I;So;0;L;;;;;N;;;;;
+1F179;NEGATIVE SQUARED LATIN CAPITAL LETTER J;So;0;L;;;;;N;;;;;
+1F17A;NEGATIVE SQUARED LATIN CAPITAL LETTER K;So;0;L;;;;;N;;;;;
+1F17B;NEGATIVE SQUARED LATIN CAPITAL LETTER L;So;0;L;;;;;N;;;;;
+1F17C;NEGATIVE SQUARED LATIN CAPITAL LETTER M;So;0;L;;;;;N;;;;;
+1F17D;NEGATIVE SQUARED LATIN CAPITAL LETTER N;So;0;L;;;;;N;;;;;
+1F17E;NEGATIVE SQUARED LATIN CAPITAL LETTER O;So;0;L;;;;;N;;;;;
+1F17F;NEGATIVE SQUARED LATIN CAPITAL LETTER P;So;0;L;;;;;N;;;;;
+1F180;NEGATIVE SQUARED LATIN CAPITAL LETTER Q;So;0;L;;;;;N;;;;;
+1F181;NEGATIVE SQUARED LATIN CAPITAL LETTER R;So;0;L;;;;;N;;;;;
+1F182;NEGATIVE SQUARED LATIN CAPITAL LETTER S;So;0;L;;;;;N;;;;;
+1F183;NEGATIVE SQUARED LATIN CAPITAL LETTER T;So;0;L;;;;;N;;;;;
+1F184;NEGATIVE SQUARED LATIN CAPITAL LETTER U;So;0;L;;;;;N;;;;;
+1F185;NEGATIVE SQUARED LATIN CAPITAL LETTER V;So;0;L;;;;;N;;;;;
+1F186;NEGATIVE SQUARED LATIN CAPITAL LETTER W;So;0;L;;;;;N;;;;;
+1F187;NEGATIVE SQUARED LATIN CAPITAL LETTER X;So;0;L;;;;;N;;;;;
+1F188;NEGATIVE SQUARED LATIN CAPITAL LETTER Y;So;0;L;;;;;N;;;;;
+1F189;NEGATIVE SQUARED LATIN CAPITAL LETTER Z;So;0;L;;;;;N;;;;;
+1F18A;CROSSED NEGATIVE SQUARED LATIN CAPITAL LETTER P;So;0;L;;;;;N;;;;;
+1F18B;NEGATIVE SQUARED IC;So;0;L;;;;;N;;;;;
+1F18C;NEGATIVE SQUARED PA;So;0;L;;;;;N;;;;;
+1F18D;NEGATIVE SQUARED SA;So;0;L;;;;;N;;;;;
+1F18E;NEGATIVE SQUARED AB;So;0;L;;;;;N;;;;;
+1F18F;NEGATIVE SQUARED WC;So;0;L;;;;;N;;;;;
+1F190;SQUARE DJ;So;0;L;<square> 0044 004A;;;;N;;;;;
+1F191;SQUARED CL;So;0;L;;;;;N;;;;;
+1F192;SQUARED COOL;So;0;L;;;;;N;;;;;
+1F193;SQUARED FREE;So;0;L;;;;;N;;;;;
+1F194;SQUARED ID;So;0;L;;;;;N;;;;;
+1F195;SQUARED NEW;So;0;L;;;;;N;;;;;
+1F196;SQUARED NG;So;0;L;;;;;N;;;;;
+1F197;SQUARED OK;So;0;L;;;;;N;;;;;
+1F198;SQUARED SOS;So;0;L;;;;;N;;;;;
+1F199;SQUARED UP WITH EXCLAMATION MARK;So;0;L;;;;;N;;;;;
+1F19A;SQUARED VS;So;0;L;;;;;N;;;;;
+1F1E6;REGIONAL INDICATOR SYMBOL LETTER A;So;0;L;;;;;N;;;;;
+1F1E7;REGIONAL INDICATOR SYMBOL LETTER B;So;0;L;;;;;N;;;;;
+1F1E8;REGIONAL INDICATOR SYMBOL LETTER C;So;0;L;;;;;N;;;;;
+1F1E9;REGIONAL INDICATOR SYMBOL LETTER D;So;0;L;;;;;N;;;;;
+1F1EA;REGIONAL INDICATOR SYMBOL LETTER E;So;0;L;;;;;N;;;;;
+1F1EB;REGIONAL INDICATOR SYMBOL LETTER F;So;0;L;;;;;N;;;;;
+1F1EC;REGIONAL INDICATOR SYMBOL LETTER G;So;0;L;;;;;N;;;;;
+1F1ED;REGIONAL INDICATOR SYMBOL LETTER H;So;0;L;;;;;N;;;;;
+1F1EE;REGIONAL INDICATOR SYMBOL LETTER I;So;0;L;;;;;N;;;;;
+1F1EF;REGIONAL INDICATOR SYMBOL LETTER J;So;0;L;;;;;N;;;;;
+1F1F0;REGIONAL INDICATOR SYMBOL LETTER K;So;0;L;;;;;N;;;;;
+1F1F1;REGIONAL INDICATOR SYMBOL LETTER L;So;0;L;;;;;N;;;;;
+1F1F2;REGIONAL INDICATOR SYMBOL LETTER M;So;0;L;;;;;N;;;;;
+1F1F3;REGIONAL INDICATOR SYMBOL LETTER N;So;0;L;;;;;N;;;;;
+1F1F4;REGIONAL INDICATOR SYMBOL LETTER O;So;0;L;;;;;N;;;;;
+1F1F5;REGIONAL INDICATOR SYMBOL LETTER P;So;0;L;;;;;N;;;;;
+1F1F6;REGIONAL INDICATOR SYMBOL LETTER Q;So;0;L;;;;;N;;;;;
+1F1F7;REGIONAL INDICATOR SYMBOL LETTER R;So;0;L;;;;;N;;;;;
+1F1F8;REGIONAL INDICATOR SYMBOL LETTER S;So;0;L;;;;;N;;;;;
+1F1F9;REGIONAL INDICATOR SYMBOL LETTER T;So;0;L;;;;;N;;;;;
+1F1FA;REGIONAL INDICATOR SYMBOL LETTER U;So;0;L;;;;;N;;;;;
+1F1FB;REGIONAL INDICATOR SYMBOL LETTER V;So;0;L;;;;;N;;;;;
+1F1FC;REGIONAL INDICATOR SYMBOL LETTER W;So;0;L;;;;;N;;;;;
+1F1FD;REGIONAL INDICATOR SYMBOL LETTER X;So;0;L;;;;;N;;;;;
+1F1FE;REGIONAL INDICATOR SYMBOL LETTER Y;So;0;L;;;;;N;;;;;
+1F1FF;REGIONAL INDICATOR SYMBOL LETTER Z;So;0;L;;;;;N;;;;;
+1F200;SQUARE HIRAGANA HOKA;So;0;L;<square> 307B 304B;;;;N;;;;;
+1F201;SQUARED KATAKANA KOKO;So;0;L;<square> 30B3 30B3;;;;N;;;;;
+1F202;SQUARED KATAKANA SA;So;0;L;<square> 30B5;;;;N;;;;;
+1F210;SQUARED CJK UNIFIED IDEOGRAPH-624B;So;0;L;<square> 624B;;;;N;;;;;
+1F211;SQUARED CJK UNIFIED IDEOGRAPH-5B57;So;0;L;<square> 5B57;;;;N;;;;;
+1F212;SQUARED CJK UNIFIED IDEOGRAPH-53CC;So;0;L;<square> 53CC;;;;N;;;;;
+1F213;SQUARED KATAKANA DE;So;0;L;<square> 30C7;;;;N;;;;;
+1F214;SQUARED CJK UNIFIED IDEOGRAPH-4E8C;So;0;L;<square> 4E8C;;;;N;;;;;
+1F215;SQUARED CJK UNIFIED IDEOGRAPH-591A;So;0;L;<square> 591A;;;;N;;;;;
+1F216;SQUARED CJK UNIFIED IDEOGRAPH-89E3;So;0;L;<square> 89E3;;;;N;;;;;
+1F217;SQUARED CJK UNIFIED IDEOGRAPH-5929;So;0;L;<square> 5929;;;;N;;;;;
+1F218;SQUARED CJK UNIFIED IDEOGRAPH-4EA4;So;0;L;<square> 4EA4;;;;N;;;;;
+1F219;SQUARED CJK UNIFIED IDEOGRAPH-6620;So;0;L;<square> 6620;;;;N;;;;;
+1F21A;SQUARED CJK UNIFIED IDEOGRAPH-7121;So;0;L;<square> 7121;;;;N;;;;;
+1F21B;SQUARED CJK UNIFIED IDEOGRAPH-6599;So;0;L;<square> 6599;;;;N;;;;;
+1F21C;SQUARED CJK UNIFIED IDEOGRAPH-524D;So;0;L;<square> 524D;;;;N;;;;;
+1F21D;SQUARED CJK UNIFIED IDEOGRAPH-5F8C;So;0;L;<square> 5F8C;;;;N;;;;;
+1F21E;SQUARED CJK UNIFIED IDEOGRAPH-518D;So;0;L;<square> 518D;;;;N;;;;;
+1F21F;SQUARED CJK UNIFIED IDEOGRAPH-65B0;So;0;L;<square> 65B0;;;;N;;;;;
+1F220;SQUARED CJK UNIFIED IDEOGRAPH-521D;So;0;L;<square> 521D;;;;N;;;;;
+1F221;SQUARED CJK UNIFIED IDEOGRAPH-7D42;So;0;L;<square> 7D42;;;;N;;;;;
+1F222;SQUARED CJK UNIFIED IDEOGRAPH-751F;So;0;L;<square> 751F;;;;N;;;;;
+1F223;SQUARED CJK UNIFIED IDEOGRAPH-8CA9;So;0;L;<square> 8CA9;;;;N;;;;;
+1F224;SQUARED CJK UNIFIED IDEOGRAPH-58F0;So;0;L;<square> 58F0;;;;N;;;;;
+1F225;SQUARED CJK UNIFIED IDEOGRAPH-5439;So;0;L;<square> 5439;;;;N;;;;;
+1F226;SQUARED CJK UNIFIED IDEOGRAPH-6F14;So;0;L;<square> 6F14;;;;N;;;;;
+1F227;SQUARED CJK UNIFIED IDEOGRAPH-6295;So;0;L;<square> 6295;;;;N;;;;;
+1F228;SQUARED CJK UNIFIED IDEOGRAPH-6355;So;0;L;<square> 6355;;;;N;;;;;
+1F229;SQUARED CJK UNIFIED IDEOGRAPH-4E00;So;0;L;<square> 4E00;;;;N;;;;;
+1F22A;SQUARED CJK UNIFIED IDEOGRAPH-4E09;So;0;L;<square> 4E09;;;;N;;;;;
+1F22B;SQUARED CJK UNIFIED IDEOGRAPH-904A;So;0;L;<square> 904A;;;;N;;;;;
+1F22C;SQUARED CJK UNIFIED IDEOGRAPH-5DE6;So;0;L;<square> 5DE6;;;;N;;;;;
+1F22D;SQUARED CJK UNIFIED IDEOGRAPH-4E2D;So;0;L;<square> 4E2D;;;;N;;;;;
+1F22E;SQUARED CJK UNIFIED IDEOGRAPH-53F3;So;0;L;<square> 53F3;;;;N;;;;;
+1F22F;SQUARED CJK UNIFIED IDEOGRAPH-6307;So;0;L;<square> 6307;;;;N;;;;;
+1F230;SQUARED CJK UNIFIED IDEOGRAPH-8D70;So;0;L;<square> 8D70;;;;N;;;;;
+1F231;SQUARED CJK UNIFIED IDEOGRAPH-6253;So;0;L;<square> 6253;;;;N;;;;;
+1F232;SQUARED CJK UNIFIED IDEOGRAPH-7981;So;0;L;<square> 7981;;;;N;;;;;
+1F233;SQUARED CJK UNIFIED IDEOGRAPH-7A7A;So;0;L;<square> 7A7A;;;;N;;;;;
+1F234;SQUARED CJK UNIFIED IDEOGRAPH-5408;So;0;L;<square> 5408;;;;N;;;;;
+1F235;SQUARED CJK UNIFIED IDEOGRAPH-6E80;So;0;L;<square> 6E80;;;;N;;;;;
+1F236;SQUARED CJK UNIFIED IDEOGRAPH-6709;So;0;L;<square> 6709;;;;N;;;;;
+1F237;SQUARED CJK UNIFIED IDEOGRAPH-6708;So;0;L;<square> 6708;;;;N;;;;;
+1F238;SQUARED CJK UNIFIED IDEOGRAPH-7533;So;0;L;<square> 7533;;;;N;;;;;
+1F239;SQUARED CJK UNIFIED IDEOGRAPH-5272;So;0;L;<square> 5272;;;;N;;;;;
+1F23A;SQUARED CJK UNIFIED IDEOGRAPH-55B6;So;0;L;<square> 55B6;;;;N;;;;;
+1F240;TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-672C;So;0;L;<compat> 3014 672C 3015;;;;N;;;;;
+1F241;TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-4E09;So;0;L;<compat> 3014 4E09 3015;;;;N;;;;;
+1F242;TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-4E8C;So;0;L;<compat> 3014 4E8C 3015;;;;N;;;;;
+1F243;TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-5B89;So;0;L;<compat> 3014 5B89 3015;;;;N;;;;;
+1F244;TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-70B9;So;0;L;<compat> 3014 70B9 3015;;;;N;;;;;
+1F245;TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-6253;So;0;L;<compat> 3014 6253 3015;;;;N;;;;;
+1F246;TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-76D7;So;0;L;<compat> 3014 76D7 3015;;;;N;;;;;
+1F247;TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-52DD;So;0;L;<compat> 3014 52DD 3015;;;;N;;;;;
+1F248;TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-6557;So;0;L;<compat> 3014 6557 3015;;;;N;;;;;
+1F250;CIRCLED IDEOGRAPH ADVANTAGE;So;0;L;<circle> 5F97;;;;N;;;;;
+1F251;CIRCLED IDEOGRAPH ACCEPT;So;0;L;<circle> 53EF;;;;N;;;;;
+1F300;CYCLONE;So;0;ON;;;;;N;;;;;
+1F301;FOGGY;So;0;ON;;;;;N;;;;;
+1F302;CLOSED UMBRELLA;So;0;ON;;;;;N;;;;;
+1F303;NIGHT WITH STARS;So;0;ON;;;;;N;;;;;
+1F304;SUNRISE OVER MOUNTAINS;So;0;ON;;;;;N;;;;;
+1F305;SUNRISE;So;0;ON;;;;;N;;;;;
+1F306;CITYSCAPE AT DUSK;So;0;ON;;;;;N;;;;;
+1F307;SUNSET OVER BUILDINGS;So;0;ON;;;;;N;;;;;
+1F308;RAINBOW;So;0;ON;;;;;N;;;;;
+1F309;BRIDGE AT NIGHT;So;0;ON;;;;;N;;;;;
+1F30A;WATER WAVE;So;0;ON;;;;;N;;;;;
+1F30B;VOLCANO;So;0;ON;;;;;N;;;;;
+1F30C;MILKY WAY;So;0;ON;;;;;N;;;;;
+1F30D;EARTH GLOBE EUROPE-AFRICA;So;0;ON;;;;;N;;;;;
+1F30E;EARTH GLOBE AMERICAS;So;0;ON;;;;;N;;;;;
+1F30F;EARTH GLOBE ASIA-AUSTRALIA;So;0;ON;;;;;N;;;;;
+1F310;GLOBE WITH MERIDIANS;So;0;ON;;;;;N;;;;;
+1F311;NEW MOON SYMBOL;So;0;ON;;;;;N;;;;;
+1F312;WAXING CRESCENT MOON SYMBOL;So;0;ON;;;;;N;;;;;
+1F313;FIRST QUARTER MOON SYMBOL;So;0;ON;;;;;N;;;;;
+1F314;WAXING GIBBOUS MOON SYMBOL;So;0;ON;;;;;N;;;;;
+1F315;FULL MOON SYMBOL;So;0;ON;;;;;N;;;;;
+1F316;WANING GIBBOUS MOON SYMBOL;So;0;ON;;;;;N;;;;;
+1F317;LAST QUARTER MOON SYMBOL;So;0;ON;;;;;N;;;;;
+1F318;WANING CRESCENT MOON SYMBOL;So;0;ON;;;;;N;;;;;
+1F319;CRESCENT MOON;So;0;ON;;;;;N;;;;;
+1F31A;NEW MOON WITH FACE;So;0;ON;;;;;N;;;;;
+1F31B;FIRST QUARTER MOON WITH FACE;So;0;ON;;;;;N;;;;;
+1F31C;LAST QUARTER MOON WITH FACE;So;0;ON;;;;;N;;;;;
+1F31D;FULL MOON WITH FACE;So;0;ON;;;;;N;;;;;
+1F31E;SUN WITH FACE;So;0;ON;;;;;N;;;;;
+1F31F;GLOWING STAR;So;0;ON;;;;;N;;;;;
+1F320;SHOOTING STAR;So;0;ON;;;;;N;;;;;
+1F330;CHESTNUT;So;0;ON;;;;;N;;;;;
+1F331;SEEDLING;So;0;ON;;;;;N;;;;;
+1F332;EVERGREEN TREE;So;0;ON;;;;;N;;;;;
+1F333;DECIDUOUS TREE;So;0;ON;;;;;N;;;;;
+1F334;PALM TREE;So;0;ON;;;;;N;;;;;
+1F335;CACTUS;So;0;ON;;;;;N;;;;;
+1F337;TULIP;So;0;ON;;;;;N;;;;;
+1F338;CHERRY BLOSSOM;So;0;ON;;;;;N;;;;;
+1F339;ROSE;So;0;ON;;;;;N;;;;;
+1F33A;HIBISCUS;So;0;ON;;;;;N;;;;;
+1F33B;SUNFLOWER;So;0;ON;;;;;N;;;;;
+1F33C;BLOSSOM;So;0;ON;;;;;N;;;;;
+1F33D;EAR OF MAIZE;So;0;ON;;;;;N;;;;;
+1F33E;EAR OF RICE;So;0;ON;;;;;N;;;;;
+1F33F;HERB;So;0;ON;;;;;N;;;;;
+1F340;FOUR LEAF CLOVER;So;0;ON;;;;;N;;;;;
+1F341;MAPLE LEAF;So;0;ON;;;;;N;;;;;
+1F342;FALLEN LEAF;So;0;ON;;;;;N;;;;;
+1F343;LEAF FLUTTERING IN WIND;So;0;ON;;;;;N;;;;;
+1F344;MUSHROOM;So;0;ON;;;;;N;;;;;
+1F345;TOMATO;So;0;ON;;;;;N;;;;;
+1F346;AUBERGINE;So;0;ON;;;;;N;;;;;
+1F347;GRAPES;So;0;ON;;;;;N;;;;;
+1F348;MELON;So;0;ON;;;;;N;;;;;
+1F349;WATERMELON;So;0;ON;;;;;N;;;;;
+1F34A;TANGERINE;So;0;ON;;;;;N;;;;;
+1F34B;LEMON;So;0;ON;;;;;N;;;;;
+1F34C;BANANA;So;0;ON;;;;;N;;;;;
+1F34D;PINEAPPLE;So;0;ON;;;;;N;;;;;
+1F34E;RED APPLE;So;0;ON;;;;;N;;;;;
+1F34F;GREEN APPLE;So;0;ON;;;;;N;;;;;
+1F350;PEAR;So;0;ON;;;;;N;;;;;
+1F351;PEACH;So;0;ON;;;;;N;;;;;
+1F352;CHERRIES;So;0;ON;;;;;N;;;;;
+1F353;STRAWBERRY;So;0;ON;;;;;N;;;;;
+1F354;HAMBURGER;So;0;ON;;;;;N;;;;;
+1F355;SLICE OF PIZZA;So;0;ON;;;;;N;;;;;
+1F356;MEAT ON BONE;So;0;ON;;;;;N;;;;;
+1F357;POULTRY LEG;So;0;ON;;;;;N;;;;;
+1F358;RICE CRACKER;So;0;ON;;;;;N;;;;;
+1F359;RICE BALL;So;0;ON;;;;;N;;;;;
+1F35A;COOKED RICE;So;0;ON;;;;;N;;;;;
+1F35B;CURRY AND RICE;So;0;ON;;;;;N;;;;;
+1F35C;STEAMING BOWL;So;0;ON;;;;;N;;;;;
+1F35D;SPAGHETTI;So;0;ON;;;;;N;;;;;
+1F35E;BREAD;So;0;ON;;;;;N;;;;;
+1F35F;FRENCH FRIES;So;0;ON;;;;;N;;;;;
+1F360;ROASTED SWEET POTATO;So;0;ON;;;;;N;;;;;
+1F361;DANGO;So;0;ON;;;;;N;;;;;
+1F362;ODEN;So;0;ON;;;;;N;;;;;
+1F363;SUSHI;So;0;ON;;;;;N;;;;;
+1F364;FRIED SHRIMP;So;0;ON;;;;;N;;;;;
+1F365;FISH CAKE WITH SWIRL DESIGN;So;0;ON;;;;;N;;;;;
+1F366;SOFT ICE CREAM;So;0;ON;;;;;N;;;;;
+1F367;SHAVED ICE;So;0;ON;;;;;N;;;;;
+1F368;ICE CREAM;So;0;ON;;;;;N;;;;;
+1F369;DOUGHNUT;So;0;ON;;;;;N;;;;;
+1F36A;COOKIE;So;0;ON;;;;;N;;;;;
+1F36B;CHOCOLATE BAR;So;0;ON;;;;;N;;;;;
+1F36C;CANDY;So;0;ON;;;;;N;;;;;
+1F36D;LOLLIPOP;So;0;ON;;;;;N;;;;;
+1F36E;CUSTARD;So;0;ON;;;;;N;;;;;
+1F36F;HONEY POT;So;0;ON;;;;;N;;;;;
+1F370;SHORTCAKE;So;0;ON;;;;;N;;;;;
+1F371;BENTO BOX;So;0;ON;;;;;N;;;;;
+1F372;POT OF FOOD;So;0;ON;;;;;N;;;;;
+1F373;COOKING;So;0;ON;;;;;N;;;;;
+1F374;FORK AND KNIFE;So;0;ON;;;;;N;;;;;
+1F375;TEACUP WITHOUT HANDLE;So;0;ON;;;;;N;;;;;
+1F376;SAKE BOTTLE AND CUP;So;0;ON;;;;;N;;;;;
+1F377;WINE GLASS;So;0;ON;;;;;N;;;;;
+1F378;COCKTAIL GLASS;So;0;ON;;;;;N;;;;;
+1F379;TROPICAL DRINK;So;0;ON;;;;;N;;;;;
+1F37A;BEER MUG;So;0;ON;;;;;N;;;;;
+1F37B;CLINKING BEER MUGS;So;0;ON;;;;;N;;;;;
+1F37C;BABY BOTTLE;So;0;ON;;;;;N;;;;;
+1F380;RIBBON;So;0;ON;;;;;N;;;;;
+1F381;WRAPPED PRESENT;So;0;ON;;;;;N;;;;;
+1F382;BIRTHDAY CAKE;So;0;ON;;;;;N;;;;;
+1F383;JACK-O-LANTERN;So;0;ON;;;;;N;;;;;
+1F384;CHRISTMAS TREE;So;0;ON;;;;;N;;;;;
+1F385;FATHER CHRISTMAS;So;0;ON;;;;;N;;;;;
+1F386;FIREWORKS;So;0;ON;;;;;N;;;;;
+1F387;FIREWORK SPARKLER;So;0;ON;;;;;N;;;;;
+1F388;BALLOON;So;0;ON;;;;;N;;;;;
+1F389;PARTY POPPER;So;0;ON;;;;;N;;;;;
+1F38A;CONFETTI BALL;So;0;ON;;;;;N;;;;;
+1F38B;TANABATA TREE;So;0;ON;;;;;N;;;;;
+1F38C;CROSSED FLAGS;So;0;ON;;;;;N;;;;;
+1F38D;PINE DECORATION;So;0;ON;;;;;N;;;;;
+1F38E;JAPANESE DOLLS;So;0;ON;;;;;N;;;;;
+1F38F;CARP STREAMER;So;0;ON;;;;;N;;;;;
+1F390;WIND CHIME;So;0;ON;;;;;N;;;;;
+1F391;MOON VIEWING CEREMONY;So;0;ON;;;;;N;;;;;
+1F392;SCHOOL SATCHEL;So;0;ON;;;;;N;;;;;
+1F393;GRADUATION CAP;So;0;ON;;;;;N;;;;;
+1F3A0;CAROUSEL HORSE;So;0;ON;;;;;N;;;;;
+1F3A1;FERRIS WHEEL;So;0;ON;;;;;N;;;;;
+1F3A2;ROLLER COASTER;So;0;ON;;;;;N;;;;;
+1F3A3;FISHING POLE AND FISH;So;0;ON;;;;;N;;;;;
+1F3A4;MICROPHONE;So;0;ON;;;;;N;;;;;
+1F3A5;MOVIE CAMERA;So;0;ON;;;;;N;;;;;
+1F3A6;CINEMA;So;0;ON;;;;;N;;;;;
+1F3A7;HEADPHONE;So;0;ON;;;;;N;;;;;
+1F3A8;ARTIST PALETTE;So;0;ON;;;;;N;;;;;
+1F3A9;TOP HAT;So;0;ON;;;;;N;;;;;
+1F3AA;CIRCUS TENT;So;0;ON;;;;;N;;;;;
+1F3AB;TICKET;So;0;ON;;;;;N;;;;;
+1F3AC;CLAPPER BOARD;So;0;ON;;;;;N;;;;;
+1F3AD;PERFORMING ARTS;So;0;ON;;;;;N;;;;;
+1F3AE;VIDEO GAME;So;0;ON;;;;;N;;;;;
+1F3AF;DIRECT HIT;So;0;ON;;;;;N;;;;;
+1F3B0;SLOT MACHINE;So;0;ON;;;;;N;;;;;
+1F3B1;BILLIARDS;So;0;ON;;;;;N;;;;;
+1F3B2;GAME DIE;So;0;ON;;;;;N;;;;;
+1F3B3;BOWLING;So;0;ON;;;;;N;;;;;
+1F3B4;FLOWER PLAYING CARDS;So;0;ON;;;;;N;;;;;
+1F3B5;MUSICAL NOTE;So;0;ON;;;;;N;;;;;
+1F3B6;MULTIPLE MUSICAL NOTES;So;0;ON;;;;;N;;;;;
+1F3B7;SAXOPHONE;So;0;ON;;;;;N;;;;;
+1F3B8;GUITAR;So;0;ON;;;;;N;;;;;
+1F3B9;MUSICAL KEYBOARD;So;0;ON;;;;;N;;;;;
+1F3BA;TRUMPET;So;0;ON;;;;;N;;;;;
+1F3BB;VIOLIN;So;0;ON;;;;;N;;;;;
+1F3BC;MUSICAL SCORE;So;0;ON;;;;;N;;;;;
+1F3BD;RUNNING SHIRT WITH SASH;So;0;ON;;;;;N;;;;;
+1F3BE;TENNIS RACQUET AND BALL;So;0;ON;;;;;N;;;;;
+1F3BF;SKI AND SKI BOOT;So;0;ON;;;;;N;;;;;
+1F3C0;BASKETBALL AND HOOP;So;0;ON;;;;;N;;;;;
+1F3C1;CHEQUERED FLAG;So;0;ON;;;;;N;;;;;
+1F3C2;SNOWBOARDER;So;0;ON;;;;;N;;;;;
+1F3C3;RUNNER;So;0;ON;;;;;N;;;;;
+1F3C4;SURFER;So;0;ON;;;;;N;;;;;
+1F3C6;TROPHY;So;0;ON;;;;;N;;;;;
+1F3C7;HORSE RACING;So;0;ON;;;;;N;;;;;
+1F3C8;AMERICAN FOOTBALL;So;0;ON;;;;;N;;;;;
+1F3C9;RUGBY FOOTBALL;So;0;ON;;;;;N;;;;;
+1F3CA;SWIMMER;So;0;ON;;;;;N;;;;;
+1F3E0;HOUSE BUILDING;So;0;ON;;;;;N;;;;;
+1F3E1;HOUSE WITH GARDEN;So;0;ON;;;;;N;;;;;
+1F3E2;OFFICE BUILDING;So;0;ON;;;;;N;;;;;
+1F3E3;JAPANESE POST OFFICE;So;0;ON;;;;;N;;;;;
+1F3E4;EUROPEAN POST OFFICE;So;0;ON;;;;;N;;;;;
+1F3E5;HOSPITAL;So;0;ON;;;;;N;;;;;
+1F3E6;BANK;So;0;ON;;;;;N;;;;;
+1F3E7;AUTOMATED TELLER MACHINE;So;0;ON;;;;;N;;;;;
+1F3E8;HOTEL;So;0;ON;;;;;N;;;;;
+1F3E9;LOVE HOTEL;So;0;ON;;;;;N;;;;;
+1F3EA;CONVENIENCE STORE;So;0;ON;;;;;N;;;;;
+1F3EB;SCHOOL;So;0;ON;;;;;N;;;;;
+1F3EC;DEPARTMENT STORE;So;0;ON;;;;;N;;;;;
+1F3ED;FACTORY;So;0;ON;;;;;N;;;;;
+1F3EE;IZAKAYA LANTERN;So;0;ON;;;;;N;;;;;
+1F3EF;JAPANESE CASTLE;So;0;ON;;;;;N;;;;;
+1F3F0;EUROPEAN CASTLE;So;0;ON;;;;;N;;;;;
+1F400;RAT;So;0;ON;;;;;N;;;;;
+1F401;MOUSE;So;0;ON;;;;;N;;;;;
+1F402;OX;So;0;ON;;;;;N;;;;;
+1F403;WATER BUFFALO;So;0;ON;;;;;N;;;;;
+1F404;COW;So;0;ON;;;;;N;;;;;
+1F405;TIGER;So;0;ON;;;;;N;;;;;
+1F406;LEOPARD;So;0;ON;;;;;N;;;;;
+1F407;RABBIT;So;0;ON;;;;;N;;;;;
+1F408;CAT;So;0;ON;;;;;N;;;;;
+1F409;DRAGON;So;0;ON;;;;;N;;;;;
+1F40A;CROCODILE;So;0;ON;;;;;N;;;;;
+1F40B;WHALE;So;0;ON;;;;;N;;;;;
+1F40C;SNAIL;So;0;ON;;;;;N;;;;;
+1F40D;SNAKE;So;0;ON;;;;;N;;;;;
+1F40E;HORSE;So;0;ON;;;;;N;;;;;
+1F40F;RAM;So;0;ON;;;;;N;;;;;
+1F410;GOAT;So;0;ON;;;;;N;;;;;
+1F411;SHEEP;So;0;ON;;;;;N;;;;;
+1F412;MONKEY;So;0;ON;;;;;N;;;;;
+1F413;ROOSTER;So;0;ON;;;;;N;;;;;
+1F414;CHICKEN;So;0;ON;;;;;N;;;;;
+1F415;DOG;So;0;ON;;;;;N;;;;;
+1F416;PIG;So;0;ON;;;;;N;;;;;
+1F417;BOAR;So;0;ON;;;;;N;;;;;
+1F418;ELEPHANT;So;0;ON;;;;;N;;;;;
+1F419;OCTOPUS;So;0;ON;;;;;N;;;;;
+1F41A;SPIRAL SHELL;So;0;ON;;;;;N;;;;;
+1F41B;BUG;So;0;ON;;;;;N;;;;;
+1F41C;ANT;So;0;ON;;;;;N;;;;;
+1F41D;HONEYBEE;So;0;ON;;;;;N;;;;;
+1F41E;LADY BEETLE;So;0;ON;;;;;N;;;;;
+1F41F;FISH;So;0;ON;;;;;N;;;;;
+1F420;TROPICAL FISH;So;0;ON;;;;;N;;;;;
+1F421;BLOWFISH;So;0;ON;;;;;N;;;;;
+1F422;TURTLE;So;0;ON;;;;;N;;;;;
+1F423;HATCHING CHICK;So;0;ON;;;;;N;;;;;
+1F424;BABY CHICK;So;0;ON;;;;;N;;;;;
+1F425;FRONT-FACING BABY CHICK;So;0;ON;;;;;N;;;;;
+1F426;BIRD;So;0;ON;;;;;N;;;;;
+1F427;PENGUIN;So;0;ON;;;;;N;;;;;
+1F428;KOALA;So;0;ON;;;;;N;;;;;
+1F429;POODLE;So;0;ON;;;;;N;;;;;
+1F42A;DROMEDARY CAMEL;So;0;ON;;;;;N;;;;;
+1F42B;BACTRIAN CAMEL;So;0;ON;;;;;N;;;;;
+1F42C;DOLPHIN;So;0;ON;;;;;N;;;;;
+1F42D;MOUSE FACE;So;0;ON;;;;;N;;;;;
+1F42E;COW FACE;So;0;ON;;;;;N;;;;;
+1F42F;TIGER FACE;So;0;ON;;;;;N;;;;;
+1F430;RABBIT FACE;So;0;ON;;;;;N;;;;;
+1F431;CAT FACE;So;0;ON;;;;;N;;;;;
+1F432;DRAGON FACE;So;0;ON;;;;;N;;;;;
+1F433;SPOUTING WHALE;So;0;ON;;;;;N;;;;;
+1F434;HORSE FACE;So;0;ON;;;;;N;;;;;
+1F435;MONKEY FACE;So;0;ON;;;;;N;;;;;
+1F436;DOG FACE;So;0;ON;;;;;N;;;;;
+1F437;PIG FACE;So;0;ON;;;;;N;;;;;
+1F438;FROG FACE;So;0;ON;;;;;N;;;;;
+1F439;HAMSTER FACE;So;0;ON;;;;;N;;;;;
+1F43A;WOLF FACE;So;0;ON;;;;;N;;;;;
+1F43B;BEAR FACE;So;0;ON;;;;;N;;;;;
+1F43C;PANDA FACE;So;0;ON;;;;;N;;;;;
+1F43D;PIG NOSE;So;0;ON;;;;;N;;;;;
+1F43E;PAW PRINTS;So;0;ON;;;;;N;;;;;
+1F440;EYES;So;0;ON;;;;;N;;;;;
+1F442;EAR;So;0;ON;;;;;N;;;;;
+1F443;NOSE;So;0;ON;;;;;N;;;;;
+1F444;MOUTH;So;0;ON;;;;;N;;;;;
+1F445;TONGUE;So;0;ON;;;;;N;;;;;
+1F446;WHITE UP POINTING BACKHAND INDEX;So;0;ON;;;;;N;;;;;
+1F447;WHITE DOWN POINTING BACKHAND INDEX;So;0;ON;;;;;N;;;;;
+1F448;WHITE LEFT POINTING BACKHAND INDEX;So;0;ON;;;;;N;;;;;
+1F449;WHITE RIGHT POINTING BACKHAND INDEX;So;0;ON;;;;;N;;;;;
+1F44A;FISTED HAND SIGN;So;0;ON;;;;;N;;;;;
+1F44B;WAVING HAND SIGN;So;0;ON;;;;;N;;;;;
+1F44C;OK HAND SIGN;So;0;ON;;;;;N;;;;;
+1F44D;THUMBS UP SIGN;So;0;ON;;;;;N;;;;;
+1F44E;THUMBS DOWN SIGN;So;0;ON;;;;;N;;;;;
+1F44F;CLAPPING HANDS SIGN;So;0;ON;;;;;N;;;;;
+1F450;OPEN HANDS SIGN;So;0;ON;;;;;N;;;;;
+1F451;CROWN;So;0;ON;;;;;N;;;;;
+1F452;WOMANS HAT;So;0;ON;;;;;N;;;;;
+1F453;EYEGLASSES;So;0;ON;;;;;N;;;;;
+1F454;NECKTIE;So;0;ON;;;;;N;;;;;
+1F455;T-SHIRT;So;0;ON;;;;;N;;;;;
+1F456;JEANS;So;0;ON;;;;;N;;;;;
+1F457;DRESS;So;0;ON;;;;;N;;;;;
+1F458;KIMONO;So;0;ON;;;;;N;;;;;
+1F459;BIKINI;So;0;ON;;;;;N;;;;;
+1F45A;WOMANS CLOTHES;So;0;ON;;;;;N;;;;;
+1F45B;PURSE;So;0;ON;;;;;N;;;;;
+1F45C;HANDBAG;So;0;ON;;;;;N;;;;;
+1F45D;POUCH;So;0;ON;;;;;N;;;;;
+1F45E;MANS SHOE;So;0;ON;;;;;N;;;;;
+1F45F;ATHLETIC SHOE;So;0;ON;;;;;N;;;;;
+1F460;HIGH-HEELED SHOE;So;0;ON;;;;;N;;;;;
+1F461;WOMANS SANDAL;So;0;ON;;;;;N;;;;;
+1F462;WOMANS BOOTS;So;0;ON;;;;;N;;;;;
+1F463;FOOTPRINTS;So;0;ON;;;;;N;;;;;
+1F464;BUST IN SILHOUETTE;So;0;ON;;;;;N;;;;;
+1F465;BUSTS IN SILHOUETTE;So;0;ON;;;;;N;;;;;
+1F466;BOY;So;0;ON;;;;;N;;;;;
+1F467;GIRL;So;0;ON;;;;;N;;;;;
+1F468;MAN;So;0;ON;;;;;N;;;;;
+1F469;WOMAN;So;0;ON;;;;;N;;;;;
+1F46A;FAMILY;So;0;ON;;;;;N;;;;;
+1F46B;MAN AND WOMAN HOLDING HANDS;So;0;ON;;;;;N;;;;;
+1F46C;TWO MEN HOLDING HANDS;So;0;ON;;;;;N;;;;;
+1F46D;TWO WOMEN HOLDING HANDS;So;0;ON;;;;;N;;;;;
+1F46E;POLICE OFFICER;So;0;ON;;;;;N;;;;;
+1F46F;WOMAN WITH BUNNY EARS;So;0;ON;;;;;N;;;;;
+1F470;BRIDE WITH VEIL;So;0;ON;;;;;N;;;;;
+1F471;PERSON WITH BLOND HAIR;So;0;ON;;;;;N;;;;;
+1F472;MAN WITH GUA PI MAO;So;0;ON;;;;;N;;;;;
+1F473;MAN WITH TURBAN;So;0;ON;;;;;N;;;;;
+1F474;OLDER MAN;So;0;ON;;;;;N;;;;;
+1F475;OLDER WOMAN;So;0;ON;;;;;N;;;;;
+1F476;BABY;So;0;ON;;;;;N;;;;;
+1F477;CONSTRUCTION WORKER;So;0;ON;;;;;N;;;;;
+1F478;PRINCESS;So;0;ON;;;;;N;;;;;
+1F479;JAPANESE OGRE;So;0;ON;;;;;N;;;;;
+1F47A;JAPANESE GOBLIN;So;0;ON;;;;;N;;;;;
+1F47B;GHOST;So;0;ON;;;;;N;;;;;
+1F47C;BABY ANGEL;So;0;ON;;;;;N;;;;;
+1F47D;EXTRATERRESTRIAL ALIEN;So;0;ON;;;;;N;;;;;
+1F47E;ALIEN MONSTER;So;0;ON;;;;;N;;;;;
+1F47F;IMP;So;0;ON;;;;;N;;;;;
+1F480;SKULL;So;0;ON;;;;;N;;;;;
+1F481;INFORMATION DESK PERSON;So;0;ON;;;;;N;;;;;
+1F482;GUARDSMAN;So;0;ON;;;;;N;;;;;
+1F483;DANCER;So;0;ON;;;;;N;;;;;
+1F484;LIPSTICK;So;0;ON;;;;;N;;;;;
+1F485;NAIL POLISH;So;0;ON;;;;;N;;;;;
+1F486;FACE MASSAGE;So;0;ON;;;;;N;;;;;
+1F487;HAIRCUT;So;0;ON;;;;;N;;;;;
+1F488;BARBER POLE;So;0;ON;;;;;N;;;;;
+1F489;SYRINGE;So;0;ON;;;;;N;;;;;
+1F48A;PILL;So;0;ON;;;;;N;;;;;
+1F48B;KISS MARK;So;0;ON;;;;;N;;;;;
+1F48C;LOVE LETTER;So;0;L;;;;;N;;;;;
+1F48D;RING;So;0;ON;;;;;N;;;;;
+1F48E;GEM STONE;So;0;ON;;;;;N;;;;;
+1F48F;KISS;So;0;ON;;;;;N;;;;;
+1F490;BOUQUET;So;0;ON;;;;;N;;;;;
+1F491;COUPLE WITH HEART;So;0;ON;;;;;N;;;;;
+1F492;WEDDING;So;0;ON;;;;;N;;;;;
+1F493;BEATING HEART;So;0;ON;;;;;N;;;;;
+1F494;BROKEN HEART;So;0;ON;;;;;N;;;;;
+1F495;TWO HEARTS;So;0;ON;;;;;N;;;;;
+1F496;SPARKLING HEART;So;0;ON;;;;;N;;;;;
+1F497;GROWING HEART;So;0;ON;;;;;N;;;;;
+1F498;HEART WITH ARROW;So;0;ON;;;;;N;;;;;
+1F499;BLUE HEART;So;0;ON;;;;;N;;;;;
+1F49A;GREEN HEART;So;0;ON;;;;;N;;;;;
+1F49B;YELLOW HEART;So;0;ON;;;;;N;;;;;
+1F49C;PURPLE HEART;So;0;ON;;;;;N;;;;;
+1F49D;HEART WITH RIBBON;So;0;ON;;;;;N;;;;;
+1F49E;REVOLVING HEARTS;So;0;ON;;;;;N;;;;;
+1F49F;HEART DECORATION;So;0;ON;;;;;N;;;;;
+1F4A0;DIAMOND SHAPE WITH A DOT INSIDE;So;0;ON;;;;;N;;;;;
+1F4A1;ELECTRIC LIGHT BULB;So;0;ON;;;;;N;;;;;
+1F4A2;ANGER SYMBOL;So;0;ON;;;;;N;;;;;
+1F4A3;BOMB;So;0;ON;;;;;N;;;;;
+1F4A4;SLEEPING SYMBOL;So;0;ON;;;;;N;;;;;
+1F4A5;COLLISION SYMBOL;So;0;ON;;;;;N;;;;;
+1F4A6;SPLASHING SWEAT SYMBOL;So;0;ON;;;;;N;;;;;
+1F4A7;DROPLET;So;0;ON;;;;;N;;;;;
+1F4A8;DASH SYMBOL;So;0;ON;;;;;N;;;;;
+1F4A9;PILE OF POO;So;0;ON;;;;;N;;;;;
+1F4AA;FLEXED BICEPS;So;0;ON;;;;;N;;;;;
+1F4AB;DIZZY SYMBOL;So;0;ON;;;;;N;;;;;
+1F4AC;SPEECH BALLOON;So;0;ON;;;;;N;;;;;
+1F4AD;THOUGHT BALLOON;So;0;ON;;;;;N;;;;;
+1F4AE;WHITE FLOWER;So;0;ON;;;;;N;;;;;
+1F4AF;HUNDRED POINTS SYMBOL;So;0;ON;;;;;N;;;;;
+1F4B0;MONEY BAG;So;0;ON;;;;;N;;;;;
+1F4B1;CURRENCY EXCHANGE;So;0;ON;;;;;N;;;;;
+1F4B2;HEAVY DOLLAR SIGN;So;0;ON;;;;;N;;;;;
+1F4B3;CREDIT CARD;So;0;ON;;;;;N;;;;;
+1F4B4;BANKNOTE WITH YEN SIGN;So;0;ON;;;;;N;;;;;
+1F4B5;BANKNOTE WITH DOLLAR SIGN;So;0;ON;;;;;N;;;;;
+1F4B6;BANKNOTE WITH EURO SIGN;So;0;ON;;;;;N;;;;;
+1F4B7;BANKNOTE WITH POUND SIGN;So;0;ON;;;;;N;;;;;
+1F4B8;MONEY WITH WINGS;So;0;ON;;;;;N;;;;;
+1F4B9;CHART WITH UPWARDS TREND AND YEN SIGN;So;0;ON;;;;;N;;;;;
+1F4BA;SEAT;So;0;ON;;;;;N;;;;;
+1F4BB;PERSONAL COMPUTER;So;0;ON;;;;;N;;;;;
+1F4BC;BRIEFCASE;So;0;ON;;;;;N;;;;;
+1F4BD;MINIDISC;So;0;ON;;;;;N;;;;;
+1F4BE;FLOPPY DISK;So;0;ON;;;;;N;;;;;
+1F4BF;OPTICAL DISC;So;0;ON;;;;;N;;;;;
+1F4C0;DVD;So;0;ON;;;;;N;;;;;
+1F4C1;FILE FOLDER;So;0;ON;;;;;N;;;;;
+1F4C2;OPEN FILE FOLDER;So;0;ON;;;;;N;;;;;
+1F4C3;PAGE WITH CURL;So;0;ON;;;;;N;;;;;
+1F4C4;PAGE FACING UP;So;0;ON;;;;;N;;;;;
+1F4C5;CALENDAR;So;0;ON;;;;;N;;;;;
+1F4C6;TEAR-OFF CALENDAR;So;0;ON;;;;;N;;;;;
+1F4C7;CARD INDEX;So;0;ON;;;;;N;;;;;
+1F4C8;CHART WITH UPWARDS TREND;So;0;ON;;;;;N;;;;;
+1F4C9;CHART WITH DOWNWARDS TREND;So;0;ON;;;;;N;;;;;
+1F4CA;BAR CHART;So;0;ON;;;;;N;;;;;
+1F4CB;CLIPBOARD;So;0;ON;;;;;N;;;;;
+1F4CC;PUSHPIN;So;0;ON;;;;;N;;;;;
+1F4CD;ROUND PUSHPIN;So;0;ON;;;;;N;;;;;
+1F4CE;PAPERCLIP;So;0;ON;;;;;N;;;;;
+1F4CF;STRAIGHT RULER;So;0;ON;;;;;N;;;;;
+1F4D0;TRIANGULAR RULER;So;0;ON;;;;;N;;;;;
+1F4D1;BOOKMARK TABS;So;0;ON;;;;;N;;;;;
+1F4D2;LEDGER;So;0;ON;;;;;N;;;;;
+1F4D3;NOTEBOOK;So;0;ON;;;;;N;;;;;
+1F4D4;NOTEBOOK WITH DECORATIVE COVER;So;0;ON;;;;;N;;;;;
+1F4D5;CLOSED BOOK;So;0;ON;;;;;N;;;;;
+1F4D6;OPEN BOOK;So;0;ON;;;;;N;;;;;
+1F4D7;GREEN BOOK;So;0;ON;;;;;N;;;;;
+1F4D8;BLUE BOOK;So;0;ON;;;;;N;;;;;
+1F4D9;ORANGE BOOK;So;0;ON;;;;;N;;;;;
+1F4DA;BOOKS;So;0;ON;;;;;N;;;;;
+1F4DB;NAME BADGE;So;0;ON;;;;;N;;;;;
+1F4DC;SCROLL;So;0;ON;;;;;N;;;;;
+1F4DD;MEMO;So;0;ON;;;;;N;;;;;
+1F4DE;TELEPHONE RECEIVER;So;0;ON;;;;;N;;;;;
+1F4DF;PAGER;So;0;ON;;;;;N;;;;;
+1F4E0;FAX MACHINE;So;0;ON;;;;;N;;;;;
+1F4E1;SATELLITE ANTENNA;So;0;ON;;;;;N;;;;;
+1F4E2;PUBLIC ADDRESS LOUDSPEAKER;So;0;ON;;;;;N;;;;;
+1F4E3;CHEERING MEGAPHONE;So;0;ON;;;;;N;;;;;
+1F4E4;OUTBOX TRAY;So;0;ON;;;;;N;;;;;
+1F4E5;INBOX TRAY;So;0;ON;;;;;N;;;;;
+1F4E6;PACKAGE;So;0;ON;;;;;N;;;;;
+1F4E7;E-MAIL SYMBOL;So;0;ON;;;;;N;;;;;
+1F4E8;INCOMING ENVELOPE;So;0;ON;;;;;N;;;;;
+1F4E9;ENVELOPE WITH DOWNWARDS ARROW ABOVE;So;0;ON;;;;;N;;;;;
+1F4EA;CLOSED MAILBOX WITH LOWERED FLAG;So;0;ON;;;;;N;;;;;
+1F4EB;CLOSED MAILBOX WITH RAISED FLAG;So;0;ON;;;;;N;;;;;
+1F4EC;OPEN MAILBOX WITH RAISED FLAG;So;0;ON;;;;;N;;;;;
+1F4ED;OPEN MAILBOX WITH LOWERED FLAG;So;0;ON;;;;;N;;;;;
+1F4EE;POSTBOX;So;0;ON;;;;;N;;;;;
+1F4EF;POSTAL HORN;So;0;ON;;;;;N;;;;;
+1F4F0;NEWSPAPER;So;0;ON;;;;;N;;;;;
+1F4F1;MOBILE PHONE;So;0;ON;;;;;N;;;;;
+1F4F2;MOBILE PHONE WITH RIGHTWARDS ARROW AT LEFT;So;0;ON;;;;;N;;;;;
+1F4F3;VIBRATION MODE;So;0;ON;;;;;N;;;;;
+1F4F4;MOBILE PHONE OFF;So;0;ON;;;;;N;;;;;
+1F4F5;NO MOBILE PHONES;So;0;ON;;;;;N;;;;;
+1F4F6;ANTENNA WITH BARS;So;0;ON;;;;;N;;;;;
+1F4F7;CAMERA;So;0;ON;;;;;N;;;;;
+1F4F9;VIDEO CAMERA;So;0;ON;;;;;N;;;;;
+1F4FA;TELEVISION;So;0;ON;;;;;N;;;;;
+1F4FB;RADIO;So;0;ON;;;;;N;;;;;
+1F4FC;VIDEOCASSETTE;So;0;ON;;;;;N;;;;;
+1F500;TWISTED RIGHTWARDS ARROWS;So;0;ON;;;;;N;;;;;
+1F501;CLOCKWISE RIGHTWARDS AND LEFTWARDS OPEN CIRCLE ARROWS;So;0;ON;;;;;N;;;;;
+1F502;CLOCKWISE RIGHTWARDS AND LEFTWARDS OPEN CIRCLE ARROWS WITH CIRCLED ONE OVERLAY;So;0;ON;;;;;N;;;;;
+1F503;CLOCKWISE DOWNWARDS AND UPWARDS OPEN CIRCLE ARROWS;So;0;ON;;;;;N;;;;;
+1F504;ANTICLOCKWISE DOWNWARDS AND UPWARDS OPEN CIRCLE ARROWS;So;0;ON;;;;;N;;;;;
+1F505;LOW BRIGHTNESS SYMBOL;So;0;ON;;;;;N;;;;;
+1F506;HIGH BRIGHTNESS SYMBOL;So;0;ON;;;;;N;;;;;
+1F507;SPEAKER WITH CANCELLATION STROKE;So;0;ON;;;;;N;;;;;
+1F508;SPEAKER;So;0;ON;;;;;N;;;;;
+1F509;SPEAKER WITH ONE SOUND WAVE;So;0;ON;;;;;N;;;;;
+1F50A;SPEAKER WITH THREE SOUND WAVES;So;0;ON;;;;;N;;;;;
+1F50B;BATTERY;So;0;ON;;;;;N;;;;;
+1F50C;ELECTRIC PLUG;So;0;ON;;;;;N;;;;;
+1F50D;LEFT-POINTING MAGNIFYING GLASS;So;0;ON;;;;;N;;;;;
+1F50E;RIGHT-POINTING MAGNIFYING GLASS;So;0;ON;;;;;N;;;;;
+1F50F;LOCK WITH INK PEN;So;0;ON;;;;;N;;;;;
+1F510;CLOSED LOCK WITH KEY;So;0;ON;;;;;N;;;;;
+1F511;KEY;So;0;ON;;;;;N;;;;;
+1F512;LOCK;So;0;ON;;;;;N;;;;;
+1F513;OPEN LOCK;So;0;ON;;;;;N;;;;;
+1F514;BELL;So;0;ON;;;;;N;;;;;
+1F515;BELL WITH CANCELLATION STROKE;So;0;ON;;;;;N;;;;;
+1F516;BOOKMARK;So;0;ON;;;;;N;;;;;
+1F517;LINK SYMBOL;So;0;ON;;;;;N;;;;;
+1F518;RADIO BUTTON;So;0;ON;;;;;N;;;;;
+1F519;BACK WITH LEFTWARDS ARROW ABOVE;So;0;ON;;;;;N;;;;;
+1F51A;END WITH LEFTWARDS ARROW ABOVE;So;0;ON;;;;;N;;;;;
+1F51B;ON WITH EXCLAMATION MARK WITH LEFT RIGHT ARROW ABOVE;So;0;ON;;;;;N;;;;;
+1F51C;SOON WITH RIGHTWARDS ARROW ABOVE;So;0;ON;;;;;N;;;;;
+1F51D;TOP WITH UPWARDS ARROW ABOVE;So;0;ON;;;;;N;;;;;
+1F51E;NO ONE UNDER EIGHTEEN SYMBOL;So;0;ON;;;;;N;;;;;
+1F51F;KEYCAP TEN;So;0;ON;;;;;N;;;;;
+1F520;INPUT SYMBOL FOR LATIN CAPITAL LETTERS;So;0;ON;;;;;N;;;;;
+1F521;INPUT SYMBOL FOR LATIN SMALL LETTERS;So;0;ON;;;;;N;;;;;
+1F522;INPUT SYMBOL FOR NUMBERS;So;0;ON;;;;;N;;;;;
+1F523;INPUT SYMBOL FOR SYMBOLS;So;0;ON;;;;;N;;;;;
+1F524;INPUT SYMBOL FOR LATIN LETTERS;So;0;L;;;;;N;;;;;
+1F525;FIRE;So;0;ON;;;;;N;;;;;
+1F526;ELECTRIC TORCH;So;0;ON;;;;;N;;;;;
+1F527;WRENCH;So;0;ON;;;;;N;;;;;
+1F528;HAMMER;So;0;ON;;;;;N;;;;;
+1F529;NUT AND BOLT;So;0;ON;;;;;N;;;;;
+1F52A;HOCHO;So;0;ON;;;;;N;;;;;
+1F52B;PISTOL;So;0;ON;;;;;N;;;;;
+1F52C;MICROSCOPE;So;0;ON;;;;;N;;;;;
+1F52D;TELESCOPE;So;0;ON;;;;;N;;;;;
+1F52E;CRYSTAL BALL;So;0;ON;;;;;N;;;;;
+1F52F;SIX POINTED STAR WITH MIDDLE DOT;So;0;ON;;;;;N;;;;;
+1F530;JAPANESE SYMBOL FOR BEGINNER;So;0;ON;;;;;N;;;;;
+1F531;TRIDENT EMBLEM;So;0;ON;;;;;N;;;;;
+1F532;BLACK SQUARE BUTTON;So;0;ON;;;;;N;;;;;
+1F533;WHITE SQUARE BUTTON;So;0;ON;;;;;N;;;;;
+1F534;LARGE RED CIRCLE;So;0;ON;;;;;N;;;;;
+1F535;LARGE BLUE CIRCLE;So;0;ON;;;;;N;;;;;
+1F536;LARGE ORANGE DIAMOND;So;0;ON;;;;;N;;;;;
+1F537;LARGE BLUE DIAMOND;So;0;ON;;;;;N;;;;;
+1F538;SMALL ORANGE DIAMOND;So;0;ON;;;;;N;;;;;
+1F539;SMALL BLUE DIAMOND;So;0;ON;;;;;N;;;;;
+1F53A;UP-POINTING RED TRIANGLE;So;0;ON;;;;;N;;;;;
+1F53B;DOWN-POINTING RED TRIANGLE;So;0;ON;;;;;N;;;;;
+1F53C;UP-POINTING SMALL RED TRIANGLE;So;0;ON;;;;;N;;;;;
+1F53D;DOWN-POINTING SMALL RED TRIANGLE;So;0;ON;;;;;N;;;;;
+1F550;CLOCK FACE ONE OCLOCK;So;0;ON;;;;;N;;;;;
+1F551;CLOCK FACE TWO OCLOCK;So;0;ON;;;;;N;;;;;
+1F552;CLOCK FACE THREE OCLOCK;So;0;ON;;;;;N;;;;;
+1F553;CLOCK FACE FOUR OCLOCK;So;0;ON;;;;;N;;;;;
+1F554;CLOCK FACE FIVE OCLOCK;So;0;ON;;;;;N;;;;;
+1F555;CLOCK FACE SIX OCLOCK;So;0;ON;;;;;N;;;;;
+1F556;CLOCK FACE SEVEN OCLOCK;So;0;ON;;;;;N;;;;;
+1F557;CLOCK FACE EIGHT OCLOCK;So;0;ON;;;;;N;;;;;
+1F558;CLOCK FACE NINE OCLOCK;So;0;ON;;;;;N;;;;;
+1F559;CLOCK FACE TEN OCLOCK;So;0;ON;;;;;N;;;;;
+1F55A;CLOCK FACE ELEVEN OCLOCK;So;0;ON;;;;;N;;;;;
+1F55B;CLOCK FACE TWELVE OCLOCK;So;0;ON;;;;;N;;;;;
+1F55C;CLOCK FACE ONE-THIRTY;So;0;ON;;;;;N;;;;;
+1F55D;CLOCK FACE TWO-THIRTY;So;0;ON;;;;;N;;;;;
+1F55E;CLOCK FACE THREE-THIRTY;So;0;ON;;;;;N;;;;;
+1F55F;CLOCK FACE FOUR-THIRTY;So;0;ON;;;;;N;;;;;
+1F560;CLOCK FACE FIVE-THIRTY;So;0;ON;;;;;N;;;;;
+1F561;CLOCK FACE SIX-THIRTY;So;0;ON;;;;;N;;;;;
+1F562;CLOCK FACE SEVEN-THIRTY;So;0;ON;;;;;N;;;;;
+1F563;CLOCK FACE EIGHT-THIRTY;So;0;ON;;;;;N;;;;;
+1F564;CLOCK FACE NINE-THIRTY;So;0;ON;;;;;N;;;;;
+1F565;CLOCK FACE TEN-THIRTY;So;0;ON;;;;;N;;;;;
+1F566;CLOCK FACE ELEVEN-THIRTY;So;0;ON;;;;;N;;;;;
+1F567;CLOCK FACE TWELVE-THIRTY;So;0;ON;;;;;N;;;;;
+1F5FB;MOUNT FUJI;So;0;ON;;;;;N;;;;;
+1F5FC;TOKYO TOWER;So;0;ON;;;;;N;;;;;
+1F5FD;STATUE OF LIBERTY;So;0;ON;;;;;N;;;;;
+1F5FE;SILHOUETTE OF JAPAN;So;0;ON;;;;;N;;;;;
+1F5FF;MOYAI;So;0;ON;;;;;N;;;;;
+1F601;GRINNING FACE WITH SMILING EYES;So;0;ON;;;;;N;;;;;
+1F602;FACE WITH TEARS OF JOY;So;0;ON;;;;;N;;;;;
+1F603;SMILING FACE WITH OPEN MOUTH;So;0;ON;;;;;N;;;;;
+1F604;SMILING FACE WITH OPEN MOUTH AND SMILING EYES;So;0;ON;;;;;N;;;;;
+1F605;SMILING FACE WITH OPEN MOUTH AND COLD SWEAT;So;0;ON;;;;;N;;;;;
+1F606;SMILING FACE WITH OPEN MOUTH AND TIGHTLY-CLOSED EYES;So;0;ON;;;;;N;;;;;
+1F607;SMILING FACE WITH HALO;So;0;ON;;;;;N;;;;;
+1F608;SMILING FACE WITH HORNS;So;0;ON;;;;;N;;;;;
+1F609;WINKING FACE;So;0;ON;;;;;N;;;;;
+1F60A;SMILING FACE WITH SMILING EYES;So;0;ON;;;;;N;;;;;
+1F60B;FACE SAVOURING DELICIOUS FOOD;So;0;ON;;;;;N;;;;;
+1F60C;RELIEVED FACE;So;0;ON;;;;;N;;;;;
+1F60D;SMILING FACE WITH HEART-SHAPED EYES;So;0;ON;;;;;N;;;;;
+1F60E;SMILING FACE WITH SUNGLASSES;So;0;ON;;;;;N;;;;;
+1F60F;SMIRKING FACE;So;0;ON;;;;;N;;;;;
+1F610;NEUTRAL FACE;So;0;ON;;;;;N;;;;;
+1F612;UNAMUSED FACE;So;0;ON;;;;;N;;;;;
+1F613;FACE WITH COLD SWEAT;So;0;ON;;;;;N;;;;;
+1F614;PENSIVE FACE;So;0;ON;;;;;N;;;;;
+1F616;CONFOUNDED FACE;So;0;ON;;;;;N;;;;;
+1F618;FACE THROWING A KISS;So;0;ON;;;;;N;;;;;
+1F61A;KISSING FACE WITH CLOSED EYES;So;0;ON;;;;;N;;;;;
+1F61C;FACE WITH STUCK-OUT TONGUE AND WINKING EYE;So;0;ON;;;;;N;;;;;
+1F61D;FACE WITH STUCK-OUT TONGUE AND TIGHTLY-CLOSED EYES;So;0;ON;;;;;N;;;;;
+1F61E;DISAPPOINTED FACE;So;0;ON;;;;;N;;;;;
+1F620;ANGRY FACE;So;0;ON;;;;;N;;;;;
+1F621;POUTING FACE;So;0;ON;;;;;N;;;;;
+1F622;CRYING FACE;So;0;ON;;;;;N;;;;;
+1F623;PERSEVERING FACE;So;0;ON;;;;;N;;;;;
+1F624;FACE WITH LOOK OF TRIUMPH;So;0;ON;;;;;N;;;;;
+1F625;DISAPPOINTED BUT RELIEVED FACE;So;0;ON;;;;;N;;;;;
+1F628;FEARFUL FACE;So;0;ON;;;;;N;;;;;
+1F629;WEARY FACE;So;0;ON;;;;;N;;;;;
+1F62A;SLEEPY FACE;So;0;ON;;;;;N;;;;;
+1F62B;TIRED FACE;So;0;ON;;;;;N;;;;;
+1F62D;LOUDLY CRYING FACE;So;0;ON;;;;;N;;;;;
+1F630;FACE WITH OPEN MOUTH AND COLD SWEAT;So;0;ON;;;;;N;;;;;
+1F631;FACE SCREAMING IN FEAR;So;0;ON;;;;;N;;;;;
+1F632;ASTONISHED FACE;So;0;ON;;;;;N;;;;;
+1F633;FLUSHED FACE;So;0;ON;;;;;N;;;;;
+1F635;DIZZY FACE;So;0;ON;;;;;N;;;;;
+1F636;FACE WITHOUT MOUTH;So;0;ON;;;;;N;;;;;
+1F637;FACE WITH MEDICAL MASK;So;0;ON;;;;;N;;;;;
+1F638;GRINNING CAT FACE WITH SMILING EYES;So;0;ON;;;;;N;;;;;
+1F639;CAT FACE WITH TEARS OF JOY;So;0;ON;;;;;N;;;;;
+1F63A;SMILING CAT FACE WITH OPEN MOUTH;So;0;ON;;;;;N;;;;;
+1F63B;SMILING CAT FACE WITH HEART-SHAPED EYES;So;0;ON;;;;;N;;;;;
+1F63C;CAT FACE WITH WRY SMILE;So;0;ON;;;;;N;;;;;
+1F63D;KISSING CAT FACE WITH CLOSED EYES;So;0;ON;;;;;N;;;;;
+1F63E;POUTING CAT FACE;So;0;ON;;;;;N;;;;;
+1F63F;CRYING CAT FACE;So;0;ON;;;;;N;;;;;
+1F640;WEARY CAT FACE;So;0;ON;;;;;N;;;;;
+1F645;FACE WITH NO GOOD GESTURE;So;0;ON;;;;;N;;;;;
+1F646;FACE WITH OK GESTURE;So;0;ON;;;;;N;;;;;
+1F647;PERSON BOWING DEEPLY;So;0;ON;;;;;N;;;;;
+1F648;SEE-NO-EVIL MONKEY;So;0;ON;;;;;N;;;;;
+1F649;HEAR-NO-EVIL MONKEY;So;0;ON;;;;;N;;;;;
+1F64A;SPEAK-NO-EVIL MONKEY;So;0;ON;;;;;N;;;;;
+1F64B;HAPPY PERSON RAISING ONE HAND;So;0;ON;;;;;N;;;;;
+1F64C;PERSON RAISING BOTH HANDS IN CELEBRATION;So;0;ON;;;;;N;;;;;
+1F64D;PERSON FROWNING;So;0;ON;;;;;N;;;;;
+1F64E;PERSON WITH POUTING FACE;So;0;ON;;;;;N;;;;;
+1F64F;PERSON WITH FOLDED HANDS;So;0;ON;;;;;N;;;;;
+1F680;ROCKET;So;0;ON;;;;;N;;;;;
+1F681;HELICOPTER;So;0;ON;;;;;N;;;;;
+1F682;STEAM LOCOMOTIVE;So;0;ON;;;;;N;;;;;
+1F683;RAILWAY CAR;So;0;ON;;;;;N;;;;;
+1F684;HIGH-SPEED TRAIN;So;0;ON;;;;;N;;;;;
+1F685;HIGH-SPEED TRAIN WITH BULLET NOSE;So;0;ON;;;;;N;;;;;
+1F686;TRAIN;So;0;ON;;;;;N;;;;;
+1F687;METRO;So;0;ON;;;;;N;;;;;
+1F688;LIGHT RAIL;So;0;ON;;;;;N;;;;;
+1F689;STATION;So;0;ON;;;;;N;;;;;
+1F68A;TRAM;So;0;ON;;;;;N;;;;;
+1F68B;TRAM CAR;So;0;ON;;;;;N;;;;;
+1F68C;BUS;So;0;ON;;;;;N;;;;;
+1F68D;ONCOMING BUS;So;0;ON;;;;;N;;;;;
+1F68E;TROLLEYBUS;So;0;ON;;;;;N;;;;;
+1F68F;BUS STOP;So;0;ON;;;;;N;;;;;
+1F690;MINIBUS;So;0;ON;;;;;N;;;;;
+1F691;AMBULANCE;So;0;ON;;;;;N;;;;;
+1F692;FIRE ENGINE;So;0;ON;;;;;N;;;;;
+1F693;POLICE CAR;So;0;ON;;;;;N;;;;;
+1F694;ONCOMING POLICE CAR;So;0;ON;;;;;N;;;;;
+1F695;TAXI;So;0;ON;;;;;N;;;;;
+1F696;ONCOMING TAXI;So;0;ON;;;;;N;;;;;
+1F697;AUTOMOBILE;So;0;ON;;;;;N;;;;;
+1F698;ONCOMING AUTOMOBILE;So;0;ON;;;;;N;;;;;
+1F699;RECREATIONAL VEHICLE;So;0;ON;;;;;N;;;;;
+1F69A;DELIVERY TRUCK;So;0;ON;;;;;N;;;;;
+1F69B;ARTICULATED LORRY;So;0;ON;;;;;N;;;;;
+1F69C;TRACTOR;So;0;ON;;;;;N;;;;;
+1F69D;MONORAIL;So;0;ON;;;;;N;;;;;
+1F69E;MOUNTAIN RAILWAY;So;0;ON;;;;;N;;;;;
+1F69F;SUSPENSION RAILWAY;So;0;ON;;;;;N;;;;;
+1F6A0;MOUNTAIN CABLEWAY;So;0;ON;;;;;N;;;;;
+1F6A1;AERIAL TRAMWAY;So;0;ON;;;;;N;;;;;
+1F6A2;SHIP;So;0;ON;;;;;N;;;;;
+1F6A3;ROWBOAT;So;0;ON;;;;;N;;;;;
+1F6A4;SPEEDBOAT;So;0;ON;;;;;N;;;;;
+1F6A5;HORIZONTAL TRAFFIC LIGHT;So;0;ON;;;;;N;;;;;
+1F6A6;VERTICAL TRAFFIC LIGHT;So;0;ON;;;;;N;;;;;
+1F6A7;CONSTRUCTION SIGN;So;0;ON;;;;;N;;;;;
+1F6A8;POLICE CARS REVOLVING LIGHT;So;0;ON;;;;;N;;;;;
+1F6A9;TRIANGULAR FLAG ON POST;So;0;ON;;;;;N;;;;;
+1F6AA;DOOR;So;0;ON;;;;;N;;;;;
+1F6AB;NO ENTRY SIGN;So;0;ON;;;;;N;;;;;
+1F6AC;SMOKING SYMBOL;So;0;ON;;;;;N;;;;;
+1F6AD;NO SMOKING SYMBOL;So;0;ON;;;;;N;;;;;
+1F6AE;PUT LITTER IN ITS PLACE SYMBOL;So;0;ON;;;;;N;;;;;
+1F6AF;DO NOT LITTER SYMBOL;So;0;ON;;;;;N;;;;;
+1F6B0;POTABLE WATER SYMBOL;So;0;ON;;;;;N;;;;;
+1F6B1;NON-POTABLE WATER SYMBOL;So;0;ON;;;;;N;;;;;
+1F6B2;BICYCLE;So;0;ON;;;;;N;;;;;
+1F6B3;NO BICYCLES;So;0;ON;;;;;N;;;;;
+1F6B4;BICYCLIST;So;0;ON;;;;;N;;;;;
+1F6B5;MOUNTAIN BICYCLIST;So;0;ON;;;;;N;;;;;
+1F6B6;PEDESTRIAN;So;0;ON;;;;;N;;;;;
+1F6B7;NO PEDESTRIANS;So;0;ON;;;;;N;;;;;
+1F6B8;CHILDREN CROSSING;So;0;ON;;;;;N;;;;;
+1F6B9;MENS SYMBOL;So;0;ON;;;;;N;;;;;
+1F6BA;WOMENS SYMBOL;So;0;ON;;;;;N;;;;;
+1F6BB;RESTROOM;So;0;ON;;;;;N;;;;;
+1F6BC;BABY SYMBOL;So;0;ON;;;;;N;;;;;
+1F6BD;TOILET;So;0;ON;;;;;N;;;;;
+1F6BE;WATER CLOSET;So;0;ON;;;;;N;;;;;
+1F6BF;SHOWER;So;0;ON;;;;;N;;;;;
+1F6C0;BATH;So;0;ON;;;;;N;;;;;
+1F6C1;BATHTUB;So;0;ON;;;;;N;;;;;
+1F6C2;PASSPORT CONTROL;So;0;ON;;;;;N;;;;;
+1F6C3;CUSTOMS;So;0;ON;;;;;N;;;;;
+1F6C4;BAGGAGE CLAIM;So;0;ON;;;;;N;;;;;
+1F6C5;LEFT LUGGAGE;So;0;ON;;;;;N;;;;;
+1F700;ALCHEMICAL SYMBOL FOR QUINTESSENCE;So;0;ON;;;;;N;;;;;
+1F701;ALCHEMICAL SYMBOL FOR AIR;So;0;ON;;;;;N;;;;;
+1F702;ALCHEMICAL SYMBOL FOR FIRE;So;0;ON;;;;;N;;;;;
+1F703;ALCHEMICAL SYMBOL FOR EARTH;So;0;ON;;;;;N;;;;;
+1F704;ALCHEMICAL SYMBOL FOR WATER;So;0;ON;;;;;N;;;;;
+1F705;ALCHEMICAL SYMBOL FOR AQUAFORTIS;So;0;ON;;;;;N;;;;;
+1F706;ALCHEMICAL SYMBOL FOR AQUA REGIA;So;0;ON;;;;;N;;;;;
+1F707;ALCHEMICAL SYMBOL FOR AQUA REGIA-2;So;0;ON;;;;;N;;;;;
+1F708;ALCHEMICAL SYMBOL FOR AQUA VITAE;So;0;ON;;;;;N;;;;;
+1F709;ALCHEMICAL SYMBOL FOR AQUA VITAE-2;So;0;ON;;;;;N;;;;;
+1F70A;ALCHEMICAL SYMBOL FOR VINEGAR;So;0;ON;;;;;N;;;;;
+1F70B;ALCHEMICAL SYMBOL FOR VINEGAR-2;So;0;ON;;;;;N;;;;;
+1F70C;ALCHEMICAL SYMBOL FOR VINEGAR-3;So;0;ON;;;;;N;;;;;
+1F70D;ALCHEMICAL SYMBOL FOR SULFUR;So;0;ON;;;;;N;;;;;
+1F70E;ALCHEMICAL SYMBOL FOR PHILOSOPHERS SULFUR;So;0;ON;;;;;N;;;;;
+1F70F;ALCHEMICAL SYMBOL FOR BLACK SULFUR;So;0;ON;;;;;N;;;;;
+1F710;ALCHEMICAL SYMBOL FOR MERCURY SUBLIMATE;So;0;ON;;;;;N;;;;;
+1F711;ALCHEMICAL SYMBOL FOR MERCURY SUBLIMATE-2;So;0;ON;;;;;N;;;;;
+1F712;ALCHEMICAL SYMBOL FOR MERCURY SUBLIMATE-3;So;0;ON;;;;;N;;;;;
+1F713;ALCHEMICAL SYMBOL FOR CINNABAR;So;0;ON;;;;;N;;;;;
+1F714;ALCHEMICAL SYMBOL FOR SALT;So;0;ON;;;;;N;;;;;
+1F715;ALCHEMICAL SYMBOL FOR NITRE;So;0;ON;;;;;N;;;;;
+1F716;ALCHEMICAL SYMBOL FOR VITRIOL;So;0;ON;;;;;N;;;;;
+1F717;ALCHEMICAL SYMBOL FOR VITRIOL-2;So;0;ON;;;;;N;;;;;
+1F718;ALCHEMICAL SYMBOL FOR ROCK SALT;So;0;ON;;;;;N;;;;;
+1F719;ALCHEMICAL SYMBOL FOR ROCK SALT-2;So;0;ON;;;;;N;;;;;
+1F71A;ALCHEMICAL SYMBOL FOR GOLD;So;0;ON;;;;;N;;;;;
+1F71B;ALCHEMICAL SYMBOL FOR SILVER;So;0;ON;;;;;N;;;;;
+1F71C;ALCHEMICAL SYMBOL FOR IRON ORE;So;0;ON;;;;;N;;;;;
+1F71D;ALCHEMICAL SYMBOL FOR IRON ORE-2;So;0;ON;;;;;N;;;;;
+1F71E;ALCHEMICAL SYMBOL FOR CROCUS OF IRON;So;0;ON;;;;;N;;;;;
+1F71F;ALCHEMICAL SYMBOL FOR REGULUS OF IRON;So;0;ON;;;;;N;;;;;
+1F720;ALCHEMICAL SYMBOL FOR COPPER ORE;So;0;ON;;;;;N;;;;;
+1F721;ALCHEMICAL SYMBOL FOR IRON-COPPER ORE;So;0;ON;;;;;N;;;;;
+1F722;ALCHEMICAL SYMBOL FOR SUBLIMATE OF COPPER;So;0;ON;;;;;N;;;;;
+1F723;ALCHEMICAL SYMBOL FOR CROCUS OF COPPER;So;0;ON;;;;;N;;;;;
+1F724;ALCHEMICAL SYMBOL FOR CROCUS OF COPPER-2;So;0;ON;;;;;N;;;;;
+1F725;ALCHEMICAL SYMBOL FOR COPPER ANTIMONIATE;So;0;ON;;;;;N;;;;;
+1F726;ALCHEMICAL SYMBOL FOR SALT OF COPPER ANTIMONIATE;So;0;ON;;;;;N;;;;;
+1F727;ALCHEMICAL SYMBOL FOR SUBLIMATE OF SALT OF COPPER;So;0;ON;;;;;N;;;;;
+1F728;ALCHEMICAL SYMBOL FOR VERDIGRIS;So;0;ON;;;;;N;;;;;
+1F729;ALCHEMICAL SYMBOL FOR TIN ORE;So;0;ON;;;;;N;;;;;
+1F72A;ALCHEMICAL SYMBOL FOR LEAD ORE;So;0;ON;;;;;N;;;;;
+1F72B;ALCHEMICAL SYMBOL FOR ANTIMONY ORE;So;0;ON;;;;;N;;;;;
+1F72C;ALCHEMICAL SYMBOL FOR SUBLIMATE OF ANTIMONY;So;0;ON;;;;;N;;;;;
+1F72D;ALCHEMICAL SYMBOL FOR SALT OF ANTIMONY;So;0;ON;;;;;N;;;;;
+1F72E;ALCHEMICAL SYMBOL FOR SUBLIMATE OF SALT OF ANTIMONY;So;0;ON;;;;;N;;;;;
+1F72F;ALCHEMICAL SYMBOL FOR VINEGAR OF ANTIMONY;So;0;ON;;;;;N;;;;;
+1F730;ALCHEMICAL SYMBOL FOR REGULUS OF ANTIMONY;So;0;ON;;;;;N;;;;;
+1F731;ALCHEMICAL SYMBOL FOR REGULUS OF ANTIMONY-2;So;0;ON;;;;;N;;;;;
+1F732;ALCHEMICAL SYMBOL FOR REGULUS;So;0;ON;;;;;N;;;;;
+1F733;ALCHEMICAL SYMBOL FOR REGULUS-2;So;0;ON;;;;;N;;;;;
+1F734;ALCHEMICAL SYMBOL FOR REGULUS-3;So;0;ON;;;;;N;;;;;
+1F735;ALCHEMICAL SYMBOL FOR REGULUS-4;So;0;ON;;;;;N;;;;;
+1F736;ALCHEMICAL SYMBOL FOR ALKALI;So;0;ON;;;;;N;;;;;
+1F737;ALCHEMICAL SYMBOL FOR ALKALI-2;So;0;ON;;;;;N;;;;;
+1F738;ALCHEMICAL SYMBOL FOR MARCASITE;So;0;ON;;;;;N;;;;;
+1F739;ALCHEMICAL SYMBOL FOR SAL-AMMONIAC;So;0;ON;;;;;N;;;;;
+1F73A;ALCHEMICAL SYMBOL FOR ARSENIC;So;0;ON;;;;;N;;;;;
+1F73B;ALCHEMICAL SYMBOL FOR REALGAR;So;0;ON;;;;;N;;;;;
+1F73C;ALCHEMICAL SYMBOL FOR REALGAR-2;So;0;ON;;;;;N;;;;;
+1F73D;ALCHEMICAL SYMBOL FOR AURIPIGMENT;So;0;ON;;;;;N;;;;;
+1F73E;ALCHEMICAL SYMBOL FOR BISMUTH ORE;So;0;ON;;;;;N;;;;;
+1F73F;ALCHEMICAL SYMBOL FOR TARTAR;So;0;ON;;;;;N;;;;;
+1F740;ALCHEMICAL SYMBOL FOR TARTAR-2;So;0;ON;;;;;N;;;;;
+1F741;ALCHEMICAL SYMBOL FOR QUICK LIME;So;0;ON;;;;;N;;;;;
+1F742;ALCHEMICAL SYMBOL FOR BORAX;So;0;ON;;;;;N;;;;;
+1F743;ALCHEMICAL SYMBOL FOR BORAX-2;So;0;ON;;;;;N;;;;;
+1F744;ALCHEMICAL SYMBOL FOR BORAX-3;So;0;ON;;;;;N;;;;;
+1F745;ALCHEMICAL SYMBOL FOR ALUM;So;0;ON;;;;;N;;;;;
+1F746;ALCHEMICAL SYMBOL FOR OIL;So;0;ON;;;;;N;;;;;
+1F747;ALCHEMICAL SYMBOL FOR SPIRIT;So;0;ON;;;;;N;;;;;
+1F748;ALCHEMICAL SYMBOL FOR TINCTURE;So;0;ON;;;;;N;;;;;
+1F749;ALCHEMICAL SYMBOL FOR GUM;So;0;ON;;;;;N;;;;;
+1F74A;ALCHEMICAL SYMBOL FOR WAX;So;0;ON;;;;;N;;;;;
+1F74B;ALCHEMICAL SYMBOL FOR POWDER;So;0;ON;;;;;N;;;;;
+1F74C;ALCHEMICAL SYMBOL FOR CALX;So;0;ON;;;;;N;;;;;
+1F74D;ALCHEMICAL SYMBOL FOR TUTTY;So;0;ON;;;;;N;;;;;
+1F74E;ALCHEMICAL SYMBOL FOR CAPUT MORTUUM;So;0;ON;;;;;N;;;;;
+1F74F;ALCHEMICAL SYMBOL FOR SCEPTER OF JOVE;So;0;ON;;;;;N;;;;;
+1F750;ALCHEMICAL SYMBOL FOR CADUCEUS;So;0;ON;;;;;N;;;;;
+1F751;ALCHEMICAL SYMBOL FOR TRIDENT;So;0;ON;;;;;N;;;;;
+1F752;ALCHEMICAL SYMBOL FOR STARRED TRIDENT;So;0;ON;;;;;N;;;;;
+1F753;ALCHEMICAL SYMBOL FOR LODESTONE;So;0;ON;;;;;N;;;;;
+1F754;ALCHEMICAL SYMBOL FOR SOAP;So;0;ON;;;;;N;;;;;
+1F755;ALCHEMICAL SYMBOL FOR URINE;So;0;ON;;;;;N;;;;;
+1F756;ALCHEMICAL SYMBOL FOR HORSE DUNG;So;0;ON;;;;;N;;;;;
+1F757;ALCHEMICAL SYMBOL FOR ASHES;So;0;ON;;;;;N;;;;;
+1F758;ALCHEMICAL SYMBOL FOR POT ASHES;So;0;ON;;;;;N;;;;;
+1F759;ALCHEMICAL SYMBOL FOR BRICK;So;0;ON;;;;;N;;;;;
+1F75A;ALCHEMICAL SYMBOL FOR POWDERED BRICK;So;0;ON;;;;;N;;;;;
+1F75B;ALCHEMICAL SYMBOL FOR AMALGAM;So;0;ON;;;;;N;;;;;
+1F75C;ALCHEMICAL SYMBOL FOR STRATUM SUPER STRATUM;So;0;ON;;;;;N;;;;;
+1F75D;ALCHEMICAL SYMBOL FOR STRATUM SUPER STRATUM-2;So;0;ON;;;;;N;;;;;
+1F75E;ALCHEMICAL SYMBOL FOR SUBLIMATION;So;0;ON;;;;;N;;;;;
+1F75F;ALCHEMICAL SYMBOL FOR PRECIPITATE;So;0;ON;;;;;N;;;;;
+1F760;ALCHEMICAL SYMBOL FOR DISTILL;So;0;ON;;;;;N;;;;;
+1F761;ALCHEMICAL SYMBOL FOR DISSOLVE;So;0;ON;;;;;N;;;;;
+1F762;ALCHEMICAL SYMBOL FOR DISSOLVE-2;So;0;ON;;;;;N;;;;;
+1F763;ALCHEMICAL SYMBOL FOR PURIFY;So;0;ON;;;;;N;;;;;
+1F764;ALCHEMICAL SYMBOL FOR PUTREFACTION;So;0;ON;;;;;N;;;;;
+1F765;ALCHEMICAL SYMBOL FOR CRUCIBLE;So;0;ON;;;;;N;;;;;
+1F766;ALCHEMICAL SYMBOL FOR CRUCIBLE-2;So;0;ON;;;;;N;;;;;
+1F767;ALCHEMICAL SYMBOL FOR CRUCIBLE-3;So;0;ON;;;;;N;;;;;
+1F768;ALCHEMICAL SYMBOL FOR CRUCIBLE-4;So;0;ON;;;;;N;;;;;
+1F769;ALCHEMICAL SYMBOL FOR CRUCIBLE-5;So;0;ON;;;;;N;;;;;
+1F76A;ALCHEMICAL SYMBOL FOR ALEMBIC;So;0;ON;;;;;N;;;;;
+1F76B;ALCHEMICAL SYMBOL FOR BATH OF MARY;So;0;ON;;;;;N;;;;;
+1F76C;ALCHEMICAL SYMBOL FOR BATH OF VAPOURS;So;0;ON;;;;;N;;;;;
+1F76D;ALCHEMICAL SYMBOL FOR RETORT;So;0;ON;;;;;N;;;;;
+1F76E;ALCHEMICAL SYMBOL FOR HOUR;So;0;ON;;;;;N;;;;;
+1F76F;ALCHEMICAL SYMBOL FOR NIGHT;So;0;ON;;;;;N;;;;;
+1F770;ALCHEMICAL SYMBOL FOR DAY-NIGHT;So;0;ON;;;;;N;;;;;
+1F771;ALCHEMICAL SYMBOL FOR MONTH;So;0;ON;;;;;N;;;;;
+1F772;ALCHEMICAL SYMBOL FOR HALF DRAM;So;0;ON;;;;;N;;;;;
+1F773;ALCHEMICAL SYMBOL FOR HALF OUNCE;So;0;ON;;;;;N;;;;;
+20000;<CJK Ideograph Extension B, First>;Lo;0;L;;;;;N;;;;;
+2A6D6;<CJK Ideograph Extension B, Last>;Lo;0;L;;;;;N;;;;;
+2A700;<CJK Ideograph Extension C, First>;Lo;0;L;;;;;N;;;;;
+2B734;<CJK Ideograph Extension C, Last>;Lo;0;L;;;;;N;;;;;
+2B740;<CJK Ideograph Extension D, First>;Lo;0;L;;;;;N;;;;;
+2B81D;<CJK Ideograph Extension D, Last>;Lo;0;L;;;;;N;;;;;
+2F800;CJK COMPATIBILITY IDEOGRAPH-2F800;Lo;0;L;4E3D;;;;N;;;;;
+2F801;CJK COMPATIBILITY IDEOGRAPH-2F801;Lo;0;L;4E38;;;;N;;;;;
+2F802;CJK COMPATIBILITY IDEOGRAPH-2F802;Lo;0;L;4E41;;;;N;;;;;
+2F803;CJK COMPATIBILITY IDEOGRAPH-2F803;Lo;0;L;20122;;;;N;;;;;
+2F804;CJK COMPATIBILITY IDEOGRAPH-2F804;Lo;0;L;4F60;;;;N;;;;;
+2F805;CJK COMPATIBILITY IDEOGRAPH-2F805;Lo;0;L;4FAE;;;;N;;;;;
+2F806;CJK COMPATIBILITY IDEOGRAPH-2F806;Lo;0;L;4FBB;;;;N;;;;;
+2F807;CJK COMPATIBILITY IDEOGRAPH-2F807;Lo;0;L;5002;;;;N;;;;;
+2F808;CJK COMPATIBILITY IDEOGRAPH-2F808;Lo;0;L;507A;;;;N;;;;;
+2F809;CJK COMPATIBILITY IDEOGRAPH-2F809;Lo;0;L;5099;;;;N;;;;;
+2F80A;CJK COMPATIBILITY IDEOGRAPH-2F80A;Lo;0;L;50E7;;;;N;;;;;
+2F80B;CJK COMPATIBILITY IDEOGRAPH-2F80B;Lo;0;L;50CF;;;;N;;;;;
+2F80C;CJK COMPATIBILITY IDEOGRAPH-2F80C;Lo;0;L;349E;;;;N;;;;;
+2F80D;CJK COMPATIBILITY IDEOGRAPH-2F80D;Lo;0;L;2063A;;;;N;;;;;
+2F80E;CJK COMPATIBILITY IDEOGRAPH-2F80E;Lo;0;L;514D;;;;N;;;;;
+2F80F;CJK COMPATIBILITY IDEOGRAPH-2F80F;Lo;0;L;5154;;;;N;;;;;
+2F810;CJK COMPATIBILITY IDEOGRAPH-2F810;Lo;0;L;5164;;;;N;;;;;
+2F811;CJK COMPATIBILITY IDEOGRAPH-2F811;Lo;0;L;5177;;;;N;;;;;
+2F812;CJK COMPATIBILITY IDEOGRAPH-2F812;Lo;0;L;2051C;;;;N;;;;;
+2F813;CJK COMPATIBILITY IDEOGRAPH-2F813;Lo;0;L;34B9;;;;N;;;;;
+2F814;CJK COMPATIBILITY IDEOGRAPH-2F814;Lo;0;L;5167;;;;N;;;;;
+2F815;CJK COMPATIBILITY IDEOGRAPH-2F815;Lo;0;L;518D;;;;N;;;;;
+2F816;CJK COMPATIBILITY IDEOGRAPH-2F816;Lo;0;L;2054B;;;;N;;;;;
+2F817;CJK COMPATIBILITY IDEOGRAPH-2F817;Lo;0;L;5197;;;;N;;;;;
+2F818;CJK COMPATIBILITY IDEOGRAPH-2F818;Lo;0;L;51A4;;;;N;;;;;
+2F819;CJK COMPATIBILITY IDEOGRAPH-2F819;Lo;0;L;4ECC;;;;N;;;;;
+2F81A;CJK COMPATIBILITY IDEOGRAPH-2F81A;Lo;0;L;51AC;;;;N;;;;;
+2F81B;CJK COMPATIBILITY IDEOGRAPH-2F81B;Lo;0;L;51B5;;;;N;;;;;
+2F81C;CJK COMPATIBILITY IDEOGRAPH-2F81C;Lo;0;L;291DF;;;;N;;;;;
+2F81D;CJK COMPATIBILITY IDEOGRAPH-2F81D;Lo;0;L;51F5;;;;N;;;;;
+2F81E;CJK COMPATIBILITY IDEOGRAPH-2F81E;Lo;0;L;5203;;;;N;;;;;
+2F81F;CJK COMPATIBILITY IDEOGRAPH-2F81F;Lo;0;L;34DF;;;;N;;;;;
+2F820;CJK COMPATIBILITY IDEOGRAPH-2F820;Lo;0;L;523B;;;;N;;;;;
+2F821;CJK COMPATIBILITY IDEOGRAPH-2F821;Lo;0;L;5246;;;;N;;;;;
+2F822;CJK COMPATIBILITY IDEOGRAPH-2F822;Lo;0;L;5272;;;;N;;;;;
+2F823;CJK COMPATIBILITY IDEOGRAPH-2F823;Lo;0;L;5277;;;;N;;;;;
+2F824;CJK COMPATIBILITY IDEOGRAPH-2F824;Lo;0;L;3515;;;;N;;;;;
+2F825;CJK COMPATIBILITY IDEOGRAPH-2F825;Lo;0;L;52C7;;;;N;;;;;
+2F826;CJK COMPATIBILITY IDEOGRAPH-2F826;Lo;0;L;52C9;;;;N;;;;;
+2F827;CJK COMPATIBILITY IDEOGRAPH-2F827;Lo;0;L;52E4;;;;N;;;;;
+2F828;CJK COMPATIBILITY IDEOGRAPH-2F828;Lo;0;L;52FA;;;;N;;;;;
+2F829;CJK COMPATIBILITY IDEOGRAPH-2F829;Lo;0;L;5305;;;;N;;;;;
+2F82A;CJK COMPATIBILITY IDEOGRAPH-2F82A;Lo;0;L;5306;;;;N;;;;;
+2F82B;CJK COMPATIBILITY IDEOGRAPH-2F82B;Lo;0;L;5317;;;;N;;;;;
+2F82C;CJK COMPATIBILITY IDEOGRAPH-2F82C;Lo;0;L;5349;;;;N;;;;;
+2F82D;CJK COMPATIBILITY IDEOGRAPH-2F82D;Lo;0;L;5351;;;;N;;;;;
+2F82E;CJK COMPATIBILITY IDEOGRAPH-2F82E;Lo;0;L;535A;;;;N;;;;;
+2F82F;CJK COMPATIBILITY IDEOGRAPH-2F82F;Lo;0;L;5373;;;;N;;;;;
+2F830;CJK COMPATIBILITY IDEOGRAPH-2F830;Lo;0;L;537D;;;;N;;;;;
+2F831;CJK COMPATIBILITY IDEOGRAPH-2F831;Lo;0;L;537F;;;;N;;;;;
+2F832;CJK COMPATIBILITY IDEOGRAPH-2F832;Lo;0;L;537F;;;;N;;;;;
+2F833;CJK COMPATIBILITY IDEOGRAPH-2F833;Lo;0;L;537F;;;;N;;;;;
+2F834;CJK COMPATIBILITY IDEOGRAPH-2F834;Lo;0;L;20A2C;;;;N;;;;;
+2F835;CJK COMPATIBILITY IDEOGRAPH-2F835;Lo;0;L;7070;;;;N;;;;;
+2F836;CJK COMPATIBILITY IDEOGRAPH-2F836;Lo;0;L;53CA;;;;N;;;;;
+2F837;CJK COMPATIBILITY IDEOGRAPH-2F837;Lo;0;L;53DF;;;;N;;;;;
+2F838;CJK COMPATIBILITY IDEOGRAPH-2F838;Lo;0;L;20B63;;;;N;;;;;
+2F839;CJK COMPATIBILITY IDEOGRAPH-2F839;Lo;0;L;53EB;;;;N;;;;;
+2F83A;CJK COMPATIBILITY IDEOGRAPH-2F83A;Lo;0;L;53F1;;;;N;;;;;
+2F83B;CJK COMPATIBILITY IDEOGRAPH-2F83B;Lo;0;L;5406;;;;N;;;;;
+2F83C;CJK COMPATIBILITY IDEOGRAPH-2F83C;Lo;0;L;549E;;;;N;;;;;
+2F83D;CJK COMPATIBILITY IDEOGRAPH-2F83D;Lo;0;L;5438;;;;N;;;;;
+2F83E;CJK COMPATIBILITY IDEOGRAPH-2F83E;Lo;0;L;5448;;;;N;;;;;
+2F83F;CJK COMPATIBILITY IDEOGRAPH-2F83F;Lo;0;L;5468;;;;N;;;;;
+2F840;CJK COMPATIBILITY IDEOGRAPH-2F840;Lo;0;L;54A2;;;;N;;;;;
+2F841;CJK COMPATIBILITY IDEOGRAPH-2F841;Lo;0;L;54F6;;;;N;;;;;
+2F842;CJK COMPATIBILITY IDEOGRAPH-2F842;Lo;0;L;5510;;;;N;;;;;
+2F843;CJK COMPATIBILITY IDEOGRAPH-2F843;Lo;0;L;5553;;;;N;;;;;
+2F844;CJK COMPATIBILITY IDEOGRAPH-2F844;Lo;0;L;5563;;;;N;;;;;
+2F845;CJK COMPATIBILITY IDEOGRAPH-2F845;Lo;0;L;5584;;;;N;;;;;
+2F846;CJK COMPATIBILITY IDEOGRAPH-2F846;Lo;0;L;5584;;;;N;;;;;
+2F847;CJK COMPATIBILITY IDEOGRAPH-2F847;Lo;0;L;5599;;;;N;;;;;
+2F848;CJK COMPATIBILITY IDEOGRAPH-2F848;Lo;0;L;55AB;;;;N;;;;;
+2F849;CJK COMPATIBILITY IDEOGRAPH-2F849;Lo;0;L;55B3;;;;N;;;;;
+2F84A;CJK COMPATIBILITY IDEOGRAPH-2F84A;Lo;0;L;55C2;;;;N;;;;;
+2F84B;CJK COMPATIBILITY IDEOGRAPH-2F84B;Lo;0;L;5716;;;;N;;;;;
+2F84C;CJK COMPATIBILITY IDEOGRAPH-2F84C;Lo;0;L;5606;;;;N;;;;;
+2F84D;CJK COMPATIBILITY IDEOGRAPH-2F84D;Lo;0;L;5717;;;;N;;;;;
+2F84E;CJK COMPATIBILITY IDEOGRAPH-2F84E;Lo;0;L;5651;;;;N;;;;;
+2F84F;CJK COMPATIBILITY IDEOGRAPH-2F84F;Lo;0;L;5674;;;;N;;;;;
+2F850;CJK COMPATIBILITY IDEOGRAPH-2F850;Lo;0;L;5207;;;;N;;;;;
+2F851;CJK COMPATIBILITY IDEOGRAPH-2F851;Lo;0;L;58EE;;;;N;;;;;
+2F852;CJK COMPATIBILITY IDEOGRAPH-2F852;Lo;0;L;57CE;;;;N;;;;;
+2F853;CJK COMPATIBILITY IDEOGRAPH-2F853;Lo;0;L;57F4;;;;N;;;;;
+2F854;CJK COMPATIBILITY IDEOGRAPH-2F854;Lo;0;L;580D;;;;N;;;;;
+2F855;CJK COMPATIBILITY IDEOGRAPH-2F855;Lo;0;L;578B;;;;N;;;;;
+2F856;CJK COMPATIBILITY IDEOGRAPH-2F856;Lo;0;L;5832;;;;N;;;;;
+2F857;CJK COMPATIBILITY IDEOGRAPH-2F857;Lo;0;L;5831;;;;N;;;;;
+2F858;CJK COMPATIBILITY IDEOGRAPH-2F858;Lo;0;L;58AC;;;;N;;;;;
+2F859;CJK COMPATIBILITY IDEOGRAPH-2F859;Lo;0;L;214E4;;;;N;;;;;
+2F85A;CJK COMPATIBILITY IDEOGRAPH-2F85A;Lo;0;L;58F2;;;;N;;;;;
+2F85B;CJK COMPATIBILITY IDEOGRAPH-2F85B;Lo;0;L;58F7;;;;N;;;;;
+2F85C;CJK COMPATIBILITY IDEOGRAPH-2F85C;Lo;0;L;5906;;;;N;;;;;
+2F85D;CJK COMPATIBILITY IDEOGRAPH-2F85D;Lo;0;L;591A;;;;N;;;;;
+2F85E;CJK COMPATIBILITY IDEOGRAPH-2F85E;Lo;0;L;5922;;;;N;;;;;
+2F85F;CJK COMPATIBILITY IDEOGRAPH-2F85F;Lo;0;L;5962;;;;N;;;;;
+2F860;CJK COMPATIBILITY IDEOGRAPH-2F860;Lo;0;L;216A8;;;;N;;;;;
+2F861;CJK COMPATIBILITY IDEOGRAPH-2F861;Lo;0;L;216EA;;;;N;;;;;
+2F862;CJK COMPATIBILITY IDEOGRAPH-2F862;Lo;0;L;59EC;;;;N;;;;;
+2F863;CJK COMPATIBILITY IDEOGRAPH-2F863;Lo;0;L;5A1B;;;;N;;;;;
+2F864;CJK COMPATIBILITY IDEOGRAPH-2F864;Lo;0;L;5A27;;;;N;;;;;
+2F865;CJK COMPATIBILITY IDEOGRAPH-2F865;Lo;0;L;59D8;;;;N;;;;;
+2F866;CJK COMPATIBILITY IDEOGRAPH-2F866;Lo;0;L;5A66;;;;N;;;;;
+2F867;CJK COMPATIBILITY IDEOGRAPH-2F867;Lo;0;L;36EE;;;;N;;;;;
+2F868;CJK COMPATIBILITY IDEOGRAPH-2F868;Lo;0;L;36FC;;;;N;;;;;
+2F869;CJK COMPATIBILITY IDEOGRAPH-2F869;Lo;0;L;5B08;;;;N;;;;;
+2F86A;CJK COMPATIBILITY IDEOGRAPH-2F86A;Lo;0;L;5B3E;;;;N;;;;;
+2F86B;CJK COMPATIBILITY IDEOGRAPH-2F86B;Lo;0;L;5B3E;;;;N;;;;;
+2F86C;CJK COMPATIBILITY IDEOGRAPH-2F86C;Lo;0;L;219C8;;;;N;;;;;
+2F86D;CJK COMPATIBILITY IDEOGRAPH-2F86D;Lo;0;L;5BC3;;;;N;;;;;
+2F86E;CJK COMPATIBILITY IDEOGRAPH-2F86E;Lo;0;L;5BD8;;;;N;;;;;
+2F86F;CJK COMPATIBILITY IDEOGRAPH-2F86F;Lo;0;L;5BE7;;;;N;;;;;
+2F870;CJK COMPATIBILITY IDEOGRAPH-2F870;Lo;0;L;5BF3;;;;N;;;;;
+2F871;CJK COMPATIBILITY IDEOGRAPH-2F871;Lo;0;L;21B18;;;;N;;;;;
+2F872;CJK COMPATIBILITY IDEOGRAPH-2F872;Lo;0;L;5BFF;;;;N;;;;;
+2F873;CJK COMPATIBILITY IDEOGRAPH-2F873;Lo;0;L;5C06;;;;N;;;;;
+2F874;CJK COMPATIBILITY IDEOGRAPH-2F874;Lo;0;L;5F53;;;;N;;;;;
+2F875;CJK COMPATIBILITY IDEOGRAPH-2F875;Lo;0;L;5C22;;;;N;;;;;
+2F876;CJK COMPATIBILITY IDEOGRAPH-2F876;Lo;0;L;3781;;;;N;;;;;
+2F877;CJK COMPATIBILITY IDEOGRAPH-2F877;Lo;0;L;5C60;;;;N;;;;;
+2F878;CJK COMPATIBILITY IDEOGRAPH-2F878;Lo;0;L;5C6E;;;;N;;;;;
+2F879;CJK COMPATIBILITY IDEOGRAPH-2F879;Lo;0;L;5CC0;;;;N;;;;;
+2F87A;CJK COMPATIBILITY IDEOGRAPH-2F87A;Lo;0;L;5C8D;;;;N;;;;;
+2F87B;CJK COMPATIBILITY IDEOGRAPH-2F87B;Lo;0;L;21DE4;;;;N;;;;;
+2F87C;CJK COMPATIBILITY IDEOGRAPH-2F87C;Lo;0;L;5D43;;;;N;;;;;
+2F87D;CJK COMPATIBILITY IDEOGRAPH-2F87D;Lo;0;L;21DE6;;;;N;;;;;
+2F87E;CJK COMPATIBILITY IDEOGRAPH-2F87E;Lo;0;L;5D6E;;;;N;;;;;
+2F87F;CJK COMPATIBILITY IDEOGRAPH-2F87F;Lo;0;L;5D6B;;;;N;;;;;
+2F880;CJK COMPATIBILITY IDEOGRAPH-2F880;Lo;0;L;5D7C;;;;N;;;;;
+2F881;CJK COMPATIBILITY IDEOGRAPH-2F881;Lo;0;L;5DE1;;;;N;;;;;
+2F882;CJK COMPATIBILITY IDEOGRAPH-2F882;Lo;0;L;5DE2;;;;N;;;;;
+2F883;CJK COMPATIBILITY IDEOGRAPH-2F883;Lo;0;L;382F;;;;N;;;;;
+2F884;CJK COMPATIBILITY IDEOGRAPH-2F884;Lo;0;L;5DFD;;;;N;;;;;
+2F885;CJK COMPATIBILITY IDEOGRAPH-2F885;Lo;0;L;5E28;;;;N;;;;;
+2F886;CJK COMPATIBILITY IDEOGRAPH-2F886;Lo;0;L;5E3D;;;;N;;;;;
+2F887;CJK COMPATIBILITY IDEOGRAPH-2F887;Lo;0;L;5E69;;;;N;;;;;
+2F888;CJK COMPATIBILITY IDEOGRAPH-2F888;Lo;0;L;3862;;;;N;;;;;
+2F889;CJK COMPATIBILITY IDEOGRAPH-2F889;Lo;0;L;22183;;;;N;;;;;
+2F88A;CJK COMPATIBILITY IDEOGRAPH-2F88A;Lo;0;L;387C;;;;N;;;;;
+2F88B;CJK COMPATIBILITY IDEOGRAPH-2F88B;Lo;0;L;5EB0;;;;N;;;;;
+2F88C;CJK COMPATIBILITY IDEOGRAPH-2F88C;Lo;0;L;5EB3;;;;N;;;;;
+2F88D;CJK COMPATIBILITY IDEOGRAPH-2F88D;Lo;0;L;5EB6;;;;N;;;;;
+2F88E;CJK COMPATIBILITY IDEOGRAPH-2F88E;Lo;0;L;5ECA;;;;N;;;;;
+2F88F;CJK COMPATIBILITY IDEOGRAPH-2F88F;Lo;0;L;2A392;;;;N;;;;;
+2F890;CJK COMPATIBILITY IDEOGRAPH-2F890;Lo;0;L;5EFE;;;9;N;;;;;
+2F891;CJK COMPATIBILITY IDEOGRAPH-2F891;Lo;0;L;22331;;;;N;;;;;
+2F892;CJK COMPATIBILITY IDEOGRAPH-2F892;Lo;0;L;22331;;;;N;;;;;
+2F893;CJK COMPATIBILITY IDEOGRAPH-2F893;Lo;0;L;8201;;;;N;;;;;
+2F894;CJK COMPATIBILITY IDEOGRAPH-2F894;Lo;0;L;5F22;;;;N;;;;;
+2F895;CJK COMPATIBILITY IDEOGRAPH-2F895;Lo;0;L;5F22;;;;N;;;;;
+2F896;CJK COMPATIBILITY IDEOGRAPH-2F896;Lo;0;L;38C7;;;;N;;;;;
+2F897;CJK COMPATIBILITY IDEOGRAPH-2F897;Lo;0;L;232B8;;;;N;;;;;
+2F898;CJK COMPATIBILITY IDEOGRAPH-2F898;Lo;0;L;261DA;;;;N;;;;;
+2F899;CJK COMPATIBILITY IDEOGRAPH-2F899;Lo;0;L;5F62;;;;N;;;;;
+2F89A;CJK COMPATIBILITY IDEOGRAPH-2F89A;Lo;0;L;5F6B;;;;N;;;;;
+2F89B;CJK COMPATIBILITY IDEOGRAPH-2F89B;Lo;0;L;38E3;;;;N;;;;;
+2F89C;CJK COMPATIBILITY IDEOGRAPH-2F89C;Lo;0;L;5F9A;;;;N;;;;;
+2F89D;CJK COMPATIBILITY IDEOGRAPH-2F89D;Lo;0;L;5FCD;;;;N;;;;;
+2F89E;CJK COMPATIBILITY IDEOGRAPH-2F89E;Lo;0;L;5FD7;;;;N;;;;;
+2F89F;CJK COMPATIBILITY IDEOGRAPH-2F89F;Lo;0;L;5FF9;;;;N;;;;;
+2F8A0;CJK COMPATIBILITY IDEOGRAPH-2F8A0;Lo;0;L;6081;;;;N;;;;;
+2F8A1;CJK COMPATIBILITY IDEOGRAPH-2F8A1;Lo;0;L;393A;;;;N;;;;;
+2F8A2;CJK COMPATIBILITY IDEOGRAPH-2F8A2;Lo;0;L;391C;;;;N;;;;;
+2F8A3;CJK COMPATIBILITY IDEOGRAPH-2F8A3;Lo;0;L;6094;;;;N;;;;;
+2F8A4;CJK COMPATIBILITY IDEOGRAPH-2F8A4;Lo;0;L;226D4;;;;N;;;;;
+2F8A5;CJK COMPATIBILITY IDEOGRAPH-2F8A5;Lo;0;L;60C7;;;;N;;;;;
+2F8A6;CJK COMPATIBILITY IDEOGRAPH-2F8A6;Lo;0;L;6148;;;;N;;;;;
+2F8A7;CJK COMPATIBILITY IDEOGRAPH-2F8A7;Lo;0;L;614C;;;;N;;;;;
+2F8A8;CJK COMPATIBILITY IDEOGRAPH-2F8A8;Lo;0;L;614E;;;;N;;;;;
+2F8A9;CJK COMPATIBILITY IDEOGRAPH-2F8A9;Lo;0;L;614C;;;;N;;;;;
+2F8AA;CJK COMPATIBILITY IDEOGRAPH-2F8AA;Lo;0;L;617A;;;;N;;;;;
+2F8AB;CJK COMPATIBILITY IDEOGRAPH-2F8AB;Lo;0;L;618E;;;;N;;;;;
+2F8AC;CJK COMPATIBILITY IDEOGRAPH-2F8AC;Lo;0;L;61B2;;;;N;;;;;
+2F8AD;CJK COMPATIBILITY IDEOGRAPH-2F8AD;Lo;0;L;61A4;;;;N;;;;;
+2F8AE;CJK COMPATIBILITY IDEOGRAPH-2F8AE;Lo;0;L;61AF;;;;N;;;;;
+2F8AF;CJK COMPATIBILITY IDEOGRAPH-2F8AF;Lo;0;L;61DE;;;;N;;;;;
+2F8B0;CJK COMPATIBILITY IDEOGRAPH-2F8B0;Lo;0;L;61F2;;;;N;;;;;
+2F8B1;CJK COMPATIBILITY IDEOGRAPH-2F8B1;Lo;0;L;61F6;;;;N;;;;;
+2F8B2;CJK COMPATIBILITY IDEOGRAPH-2F8B2;Lo;0;L;6210;;;;N;;;;;
+2F8B3;CJK COMPATIBILITY IDEOGRAPH-2F8B3;Lo;0;L;621B;;;;N;;;;;
+2F8B4;CJK COMPATIBILITY IDEOGRAPH-2F8B4;Lo;0;L;625D;;;;N;;;;;
+2F8B5;CJK COMPATIBILITY IDEOGRAPH-2F8B5;Lo;0;L;62B1;;;;N;;;;;
+2F8B6;CJK COMPATIBILITY IDEOGRAPH-2F8B6;Lo;0;L;62D4;;;;N;;;;;
+2F8B7;CJK COMPATIBILITY IDEOGRAPH-2F8B7;Lo;0;L;6350;;;;N;;;;;
+2F8B8;CJK COMPATIBILITY IDEOGRAPH-2F8B8;Lo;0;L;22B0C;;;;N;;;;;
+2F8B9;CJK COMPATIBILITY IDEOGRAPH-2F8B9;Lo;0;L;633D;;;;N;;;;;
+2F8BA;CJK COMPATIBILITY IDEOGRAPH-2F8BA;Lo;0;L;62FC;;;;N;;;;;
+2F8BB;CJK COMPATIBILITY IDEOGRAPH-2F8BB;Lo;0;L;6368;;;;N;;;;;
+2F8BC;CJK COMPATIBILITY IDEOGRAPH-2F8BC;Lo;0;L;6383;;;;N;;;;;
+2F8BD;CJK COMPATIBILITY IDEOGRAPH-2F8BD;Lo;0;L;63E4;;;;N;;;;;
+2F8BE;CJK COMPATIBILITY IDEOGRAPH-2F8BE;Lo;0;L;22BF1;;;;N;;;;;
+2F8BF;CJK COMPATIBILITY IDEOGRAPH-2F8BF;Lo;0;L;6422;;;;N;;;;;
+2F8C0;CJK COMPATIBILITY IDEOGRAPH-2F8C0;Lo;0;L;63C5;;;;N;;;;;
+2F8C1;CJK COMPATIBILITY IDEOGRAPH-2F8C1;Lo;0;L;63A9;;;;N;;;;;
+2F8C2;CJK COMPATIBILITY IDEOGRAPH-2F8C2;Lo;0;L;3A2E;;;;N;;;;;
+2F8C3;CJK COMPATIBILITY IDEOGRAPH-2F8C3;Lo;0;L;6469;;;;N;;;;;
+2F8C4;CJK COMPATIBILITY IDEOGRAPH-2F8C4;Lo;0;L;647E;;;;N;;;;;
+2F8C5;CJK COMPATIBILITY IDEOGRAPH-2F8C5;Lo;0;L;649D;;;;N;;;;;
+2F8C6;CJK COMPATIBILITY IDEOGRAPH-2F8C6;Lo;0;L;6477;;;;N;;;;;
+2F8C7;CJK COMPATIBILITY IDEOGRAPH-2F8C7;Lo;0;L;3A6C;;;;N;;;;;
+2F8C8;CJK COMPATIBILITY IDEOGRAPH-2F8C8;Lo;0;L;654F;;;;N;;;;;
+2F8C9;CJK COMPATIBILITY IDEOGRAPH-2F8C9;Lo;0;L;656C;;;;N;;;;;
+2F8CA;CJK COMPATIBILITY IDEOGRAPH-2F8CA;Lo;0;L;2300A;;;;N;;;;;
+2F8CB;CJK COMPATIBILITY IDEOGRAPH-2F8CB;Lo;0;L;65E3;;;;N;;;;;
+2F8CC;CJK COMPATIBILITY IDEOGRAPH-2F8CC;Lo;0;L;66F8;;;;N;;;;;
+2F8CD;CJK COMPATIBILITY IDEOGRAPH-2F8CD;Lo;0;L;6649;;;;N;;;;;
+2F8CE;CJK COMPATIBILITY IDEOGRAPH-2F8CE;Lo;0;L;3B19;;;;N;;;;;
+2F8CF;CJK COMPATIBILITY IDEOGRAPH-2F8CF;Lo;0;L;6691;;;;N;;;;;
+2F8D0;CJK COMPATIBILITY IDEOGRAPH-2F8D0;Lo;0;L;3B08;;;;N;;;;;
+2F8D1;CJK COMPATIBILITY IDEOGRAPH-2F8D1;Lo;0;L;3AE4;;;;N;;;;;
+2F8D2;CJK COMPATIBILITY IDEOGRAPH-2F8D2;Lo;0;L;5192;;;;N;;;;;
+2F8D3;CJK COMPATIBILITY IDEOGRAPH-2F8D3;Lo;0;L;5195;;;;N;;;;;
+2F8D4;CJK COMPATIBILITY IDEOGRAPH-2F8D4;Lo;0;L;6700;;;;N;;;;;
+2F8D5;CJK COMPATIBILITY IDEOGRAPH-2F8D5;Lo;0;L;669C;;;;N;;;;;
+2F8D6;CJK COMPATIBILITY IDEOGRAPH-2F8D6;Lo;0;L;80AD;;;;N;;;;;
+2F8D7;CJK COMPATIBILITY IDEOGRAPH-2F8D7;Lo;0;L;43D9;;;;N;;;;;
+2F8D8;CJK COMPATIBILITY IDEOGRAPH-2F8D8;Lo;0;L;6717;;;;N;;;;;
+2F8D9;CJK COMPATIBILITY IDEOGRAPH-2F8D9;Lo;0;L;671B;;;;N;;;;;
+2F8DA;CJK COMPATIBILITY IDEOGRAPH-2F8DA;Lo;0;L;6721;;;;N;;;;;
+2F8DB;CJK COMPATIBILITY IDEOGRAPH-2F8DB;Lo;0;L;675E;;;;N;;;;;
+2F8DC;CJK COMPATIBILITY IDEOGRAPH-2F8DC;Lo;0;L;6753;;;;N;;;;;
+2F8DD;CJK COMPATIBILITY IDEOGRAPH-2F8DD;Lo;0;L;233C3;;;;N;;;;;
+2F8DE;CJK COMPATIBILITY IDEOGRAPH-2F8DE;Lo;0;L;3B49;;;;N;;;;;
+2F8DF;CJK COMPATIBILITY IDEOGRAPH-2F8DF;Lo;0;L;67FA;;;;N;;;;;
+2F8E0;CJK COMPATIBILITY IDEOGRAPH-2F8E0;Lo;0;L;6785;;;;N;;;;;
+2F8E1;CJK COMPATIBILITY IDEOGRAPH-2F8E1;Lo;0;L;6852;;;;N;;;;;
+2F8E2;CJK COMPATIBILITY IDEOGRAPH-2F8E2;Lo;0;L;6885;;;;N;;;;;
+2F8E3;CJK COMPATIBILITY IDEOGRAPH-2F8E3;Lo;0;L;2346D;;;;N;;;;;
+2F8E4;CJK COMPATIBILITY IDEOGRAPH-2F8E4;Lo;0;L;688E;;;;N;;;;;
+2F8E5;CJK COMPATIBILITY IDEOGRAPH-2F8E5;Lo;0;L;681F;;;;N;;;;;
+2F8E6;CJK COMPATIBILITY IDEOGRAPH-2F8E6;Lo;0;L;6914;;;;N;;;;;
+2F8E7;CJK COMPATIBILITY IDEOGRAPH-2F8E7;Lo;0;L;3B9D;;;;N;;;;;
+2F8E8;CJK COMPATIBILITY IDEOGRAPH-2F8E8;Lo;0;L;6942;;;;N;;;;;
+2F8E9;CJK COMPATIBILITY IDEOGRAPH-2F8E9;Lo;0;L;69A3;;;;N;;;;;
+2F8EA;CJK COMPATIBILITY IDEOGRAPH-2F8EA;Lo;0;L;69EA;;;;N;;;;;
+2F8EB;CJK COMPATIBILITY IDEOGRAPH-2F8EB;Lo;0;L;6AA8;;;;N;;;;;
+2F8EC;CJK COMPATIBILITY IDEOGRAPH-2F8EC;Lo;0;L;236A3;;;;N;;;;;
+2F8ED;CJK COMPATIBILITY IDEOGRAPH-2F8ED;Lo;0;L;6ADB;;;;N;;;;;
+2F8EE;CJK COMPATIBILITY IDEOGRAPH-2F8EE;Lo;0;L;3C18;;;;N;;;;;
+2F8EF;CJK COMPATIBILITY IDEOGRAPH-2F8EF;Lo;0;L;6B21;;;;N;;;;;
+2F8F0;CJK COMPATIBILITY IDEOGRAPH-2F8F0;Lo;0;L;238A7;;;;N;;;;;
+2F8F1;CJK COMPATIBILITY IDEOGRAPH-2F8F1;Lo;0;L;6B54;;;;N;;;;;
+2F8F2;CJK COMPATIBILITY IDEOGRAPH-2F8F2;Lo;0;L;3C4E;;;;N;;;;;
+2F8F3;CJK COMPATIBILITY IDEOGRAPH-2F8F3;Lo;0;L;6B72;;;;N;;;;;
+2F8F4;CJK COMPATIBILITY IDEOGRAPH-2F8F4;Lo;0;L;6B9F;;;;N;;;;;
+2F8F5;CJK COMPATIBILITY IDEOGRAPH-2F8F5;Lo;0;L;6BBA;;;;N;;;;;
+2F8F6;CJK COMPATIBILITY IDEOGRAPH-2F8F6;Lo;0;L;6BBB;;;;N;;;;;
+2F8F7;CJK COMPATIBILITY IDEOGRAPH-2F8F7;Lo;0;L;23A8D;;;;N;;;;;
+2F8F8;CJK COMPATIBILITY IDEOGRAPH-2F8F8;Lo;0;L;21D0B;;;;N;;;;;
+2F8F9;CJK COMPATIBILITY IDEOGRAPH-2F8F9;Lo;0;L;23AFA;;;;N;;;;;
+2F8FA;CJK COMPATIBILITY IDEOGRAPH-2F8FA;Lo;0;L;6C4E;;;;N;;;;;
+2F8FB;CJK COMPATIBILITY IDEOGRAPH-2F8FB;Lo;0;L;23CBC;;;;N;;;;;
+2F8FC;CJK COMPATIBILITY IDEOGRAPH-2F8FC;Lo;0;L;6CBF;;;;N;;;;;
+2F8FD;CJK COMPATIBILITY IDEOGRAPH-2F8FD;Lo;0;L;6CCD;;;;N;;;;;
+2F8FE;CJK COMPATIBILITY IDEOGRAPH-2F8FE;Lo;0;L;6C67;;;;N;;;;;
+2F8FF;CJK COMPATIBILITY IDEOGRAPH-2F8FF;Lo;0;L;6D16;;;;N;;;;;
+2F900;CJK COMPATIBILITY IDEOGRAPH-2F900;Lo;0;L;6D3E;;;;N;;;;;
+2F901;CJK COMPATIBILITY IDEOGRAPH-2F901;Lo;0;L;6D77;;;;N;;;;;
+2F902;CJK COMPATIBILITY IDEOGRAPH-2F902;Lo;0;L;6D41;;;;N;;;;;
+2F903;CJK COMPATIBILITY IDEOGRAPH-2F903;Lo;0;L;6D69;;;;N;;;;;
+2F904;CJK COMPATIBILITY IDEOGRAPH-2F904;Lo;0;L;6D78;;;;N;;;;;
+2F905;CJK COMPATIBILITY IDEOGRAPH-2F905;Lo;0;L;6D85;;;;N;;;;;
+2F906;CJK COMPATIBILITY IDEOGRAPH-2F906;Lo;0;L;23D1E;;;;N;;;;;
+2F907;CJK COMPATIBILITY IDEOGRAPH-2F907;Lo;0;L;6D34;;;;N;;;;;
+2F908;CJK COMPATIBILITY IDEOGRAPH-2F908;Lo;0;L;6E2F;;;;N;;;;;
+2F909;CJK COMPATIBILITY IDEOGRAPH-2F909;Lo;0;L;6E6E;;;;N;;;;;
+2F90A;CJK COMPATIBILITY IDEOGRAPH-2F90A;Lo;0;L;3D33;;;;N;;;;;
+2F90B;CJK COMPATIBILITY IDEOGRAPH-2F90B;Lo;0;L;6ECB;;;;N;;;;;
+2F90C;CJK COMPATIBILITY IDEOGRAPH-2F90C;Lo;0;L;6EC7;;;;N;;;;;
+2F90D;CJK COMPATIBILITY IDEOGRAPH-2F90D;Lo;0;L;23ED1;;;;N;;;;;
+2F90E;CJK COMPATIBILITY IDEOGRAPH-2F90E;Lo;0;L;6DF9;;;;N;;;;;
+2F90F;CJK COMPATIBILITY IDEOGRAPH-2F90F;Lo;0;L;6F6E;;;;N;;;;;
+2F910;CJK COMPATIBILITY IDEOGRAPH-2F910;Lo;0;L;23F5E;;;;N;;;;;
+2F911;CJK COMPATIBILITY IDEOGRAPH-2F911;Lo;0;L;23F8E;;;;N;;;;;
+2F912;CJK COMPATIBILITY IDEOGRAPH-2F912;Lo;0;L;6FC6;;;;N;;;;;
+2F913;CJK COMPATIBILITY IDEOGRAPH-2F913;Lo;0;L;7039;;;;N;;;;;
+2F914;CJK COMPATIBILITY IDEOGRAPH-2F914;Lo;0;L;701E;;;;N;;;;;
+2F915;CJK COMPATIBILITY IDEOGRAPH-2F915;Lo;0;L;701B;;;;N;;;;;
+2F916;CJK COMPATIBILITY IDEOGRAPH-2F916;Lo;0;L;3D96;;;;N;;;;;
+2F917;CJK COMPATIBILITY IDEOGRAPH-2F917;Lo;0;L;704A;;;;N;;;;;
+2F918;CJK COMPATIBILITY IDEOGRAPH-2F918;Lo;0;L;707D;;;;N;;;;;
+2F919;CJK COMPATIBILITY IDEOGRAPH-2F919;Lo;0;L;7077;;;;N;;;;;
+2F91A;CJK COMPATIBILITY IDEOGRAPH-2F91A;Lo;0;L;70AD;;;;N;;;;;
+2F91B;CJK COMPATIBILITY IDEOGRAPH-2F91B;Lo;0;L;20525;;;;N;;;;;
+2F91C;CJK COMPATIBILITY IDEOGRAPH-2F91C;Lo;0;L;7145;;;;N;;;;;
+2F91D;CJK COMPATIBILITY IDEOGRAPH-2F91D;Lo;0;L;24263;;;;N;;;;;
+2F91E;CJK COMPATIBILITY IDEOGRAPH-2F91E;Lo;0;L;719C;;;;N;;;;;
+2F91F;CJK COMPATIBILITY IDEOGRAPH-2F91F;Lo;0;L;243AB;;;;N;;;;;
+2F920;CJK COMPATIBILITY IDEOGRAPH-2F920;Lo;0;L;7228;;;;N;;;;;
+2F921;CJK COMPATIBILITY IDEOGRAPH-2F921;Lo;0;L;7235;;;;N;;;;;
+2F922;CJK COMPATIBILITY IDEOGRAPH-2F922;Lo;0;L;7250;;;;N;;;;;
+2F923;CJK COMPATIBILITY IDEOGRAPH-2F923;Lo;0;L;24608;;;;N;;;;;
+2F924;CJK COMPATIBILITY IDEOGRAPH-2F924;Lo;0;L;7280;;;;N;;;;;
+2F925;CJK COMPATIBILITY IDEOGRAPH-2F925;Lo;0;L;7295;;;;N;;;;;
+2F926;CJK COMPATIBILITY IDEOGRAPH-2F926;Lo;0;L;24735;;;;N;;;;;
+2F927;CJK COMPATIBILITY IDEOGRAPH-2F927;Lo;0;L;24814;;;;N;;;;;
+2F928;CJK COMPATIBILITY IDEOGRAPH-2F928;Lo;0;L;737A;;;;N;;;;;
+2F929;CJK COMPATIBILITY IDEOGRAPH-2F929;Lo;0;L;738B;;;;N;;;;;
+2F92A;CJK COMPATIBILITY IDEOGRAPH-2F92A;Lo;0;L;3EAC;;;;N;;;;;
+2F92B;CJK COMPATIBILITY IDEOGRAPH-2F92B;Lo;0;L;73A5;;;;N;;;;;
+2F92C;CJK COMPATIBILITY IDEOGRAPH-2F92C;Lo;0;L;3EB8;;;;N;;;;;
+2F92D;CJK COMPATIBILITY IDEOGRAPH-2F92D;Lo;0;L;3EB8;;;;N;;;;;
+2F92E;CJK COMPATIBILITY IDEOGRAPH-2F92E;Lo;0;L;7447;;;;N;;;;;
+2F92F;CJK COMPATIBILITY IDEOGRAPH-2F92F;Lo;0;L;745C;;;;N;;;;;
+2F930;CJK COMPATIBILITY IDEOGRAPH-2F930;Lo;0;L;7471;;;;N;;;;;
+2F931;CJK COMPATIBILITY IDEOGRAPH-2F931;Lo;0;L;7485;;;;N;;;;;
+2F932;CJK COMPATIBILITY IDEOGRAPH-2F932;Lo;0;L;74CA;;;;N;;;;;
+2F933;CJK COMPATIBILITY IDEOGRAPH-2F933;Lo;0;L;3F1B;;;;N;;;;;
+2F934;CJK COMPATIBILITY IDEOGRAPH-2F934;Lo;0;L;7524;;;;N;;;;;
+2F935;CJK COMPATIBILITY IDEOGRAPH-2F935;Lo;0;L;24C36;;;;N;;;;;
+2F936;CJK COMPATIBILITY IDEOGRAPH-2F936;Lo;0;L;753E;;;;N;;;;;
+2F937;CJK COMPATIBILITY IDEOGRAPH-2F937;Lo;0;L;24C92;;;;N;;;;;
+2F938;CJK COMPATIBILITY IDEOGRAPH-2F938;Lo;0;L;7570;;;;N;;;;;
+2F939;CJK COMPATIBILITY IDEOGRAPH-2F939;Lo;0;L;2219F;;;;N;;;;;
+2F93A;CJK COMPATIBILITY IDEOGRAPH-2F93A;Lo;0;L;7610;;;;N;;;;;
+2F93B;CJK COMPATIBILITY IDEOGRAPH-2F93B;Lo;0;L;24FA1;;;;N;;;;;
+2F93C;CJK COMPATIBILITY IDEOGRAPH-2F93C;Lo;0;L;24FB8;;;;N;;;;;
+2F93D;CJK COMPATIBILITY IDEOGRAPH-2F93D;Lo;0;L;25044;;;;N;;;;;
+2F93E;CJK COMPATIBILITY IDEOGRAPH-2F93E;Lo;0;L;3FFC;;;;N;;;;;
+2F93F;CJK COMPATIBILITY IDEOGRAPH-2F93F;Lo;0;L;4008;;;;N;;;;;
+2F940;CJK COMPATIBILITY IDEOGRAPH-2F940;Lo;0;L;76F4;;;;N;;;;;
+2F941;CJK COMPATIBILITY IDEOGRAPH-2F941;Lo;0;L;250F3;;;;N;;;;;
+2F942;CJK COMPATIBILITY IDEOGRAPH-2F942;Lo;0;L;250F2;;;;N;;;;;
+2F943;CJK COMPATIBILITY IDEOGRAPH-2F943;Lo;0;L;25119;;;;N;;;;;
+2F944;CJK COMPATIBILITY IDEOGRAPH-2F944;Lo;0;L;25133;;;;N;;;;;
+2F945;CJK COMPATIBILITY IDEOGRAPH-2F945;Lo;0;L;771E;;;;N;;;;;
+2F946;CJK COMPATIBILITY IDEOGRAPH-2F946;Lo;0;L;771F;;;;N;;;;;
+2F947;CJK COMPATIBILITY IDEOGRAPH-2F947;Lo;0;L;771F;;;;N;;;;;
+2F948;CJK COMPATIBILITY IDEOGRAPH-2F948;Lo;0;L;774A;;;;N;;;;;
+2F949;CJK COMPATIBILITY IDEOGRAPH-2F949;Lo;0;L;4039;;;;N;;;;;
+2F94A;CJK COMPATIBILITY IDEOGRAPH-2F94A;Lo;0;L;778B;;;;N;;;;;
+2F94B;CJK COMPATIBILITY IDEOGRAPH-2F94B;Lo;0;L;4046;;;;N;;;;;
+2F94C;CJK COMPATIBILITY IDEOGRAPH-2F94C;Lo;0;L;4096;;;;N;;;;;
+2F94D;CJK COMPATIBILITY IDEOGRAPH-2F94D;Lo;0;L;2541D;;;;N;;;;;
+2F94E;CJK COMPATIBILITY IDEOGRAPH-2F94E;Lo;0;L;784E;;;;N;;;;;
+2F94F;CJK COMPATIBILITY IDEOGRAPH-2F94F;Lo;0;L;788C;;;;N;;;;;
+2F950;CJK COMPATIBILITY IDEOGRAPH-2F950;Lo;0;L;78CC;;;;N;;;;;
+2F951;CJK COMPATIBILITY IDEOGRAPH-2F951;Lo;0;L;40E3;;;;N;;;;;
+2F952;CJK COMPATIBILITY IDEOGRAPH-2F952;Lo;0;L;25626;;;;N;;;;;
+2F953;CJK COMPATIBILITY IDEOGRAPH-2F953;Lo;0;L;7956;;;;N;;;;;
+2F954;CJK COMPATIBILITY IDEOGRAPH-2F954;Lo;0;L;2569A;;;;N;;;;;
+2F955;CJK COMPATIBILITY IDEOGRAPH-2F955;Lo;0;L;256C5;;;;N;;;;;
+2F956;CJK COMPATIBILITY IDEOGRAPH-2F956;Lo;0;L;798F;;;;N;;;;;
+2F957;CJK COMPATIBILITY IDEOGRAPH-2F957;Lo;0;L;79EB;;;;N;;;;;
+2F958;CJK COMPATIBILITY IDEOGRAPH-2F958;Lo;0;L;412F;;;;N;;;;;
+2F959;CJK COMPATIBILITY IDEOGRAPH-2F959;Lo;0;L;7A40;;;;N;;;;;
+2F95A;CJK COMPATIBILITY IDEOGRAPH-2F95A;Lo;0;L;7A4A;;;;N;;;;;
+2F95B;CJK COMPATIBILITY IDEOGRAPH-2F95B;Lo;0;L;7A4F;;;;N;;;;;
+2F95C;CJK COMPATIBILITY IDEOGRAPH-2F95C;Lo;0;L;2597C;;;;N;;;;;
+2F95D;CJK COMPATIBILITY IDEOGRAPH-2F95D;Lo;0;L;25AA7;;;;N;;;;;
+2F95E;CJK COMPATIBILITY IDEOGRAPH-2F95E;Lo;0;L;25AA7;;;;N;;;;;
+2F95F;CJK COMPATIBILITY IDEOGRAPH-2F95F;Lo;0;L;7AEE;;;;N;;;;;
+2F960;CJK COMPATIBILITY IDEOGRAPH-2F960;Lo;0;L;4202;;;;N;;;;;
+2F961;CJK COMPATIBILITY IDEOGRAPH-2F961;Lo;0;L;25BAB;;;;N;;;;;
+2F962;CJK COMPATIBILITY IDEOGRAPH-2F962;Lo;0;L;7BC6;;;;N;;;;;
+2F963;CJK COMPATIBILITY IDEOGRAPH-2F963;Lo;0;L;7BC9;;;;N;;;;;
+2F964;CJK COMPATIBILITY IDEOGRAPH-2F964;Lo;0;L;4227;;;;N;;;;;
+2F965;CJK COMPATIBILITY IDEOGRAPH-2F965;Lo;0;L;25C80;;;;N;;;;;
+2F966;CJK COMPATIBILITY IDEOGRAPH-2F966;Lo;0;L;7CD2;;;;N;;;;;
+2F967;CJK COMPATIBILITY IDEOGRAPH-2F967;Lo;0;L;42A0;;;;N;;;;;
+2F968;CJK COMPATIBILITY IDEOGRAPH-2F968;Lo;0;L;7CE8;;;;N;;;;;
+2F969;CJK COMPATIBILITY IDEOGRAPH-2F969;Lo;0;L;7CE3;;;;N;;;;;
+2F96A;CJK COMPATIBILITY IDEOGRAPH-2F96A;Lo;0;L;7D00;;;;N;;;;;
+2F96B;CJK COMPATIBILITY IDEOGRAPH-2F96B;Lo;0;L;25F86;;;;N;;;;;
+2F96C;CJK COMPATIBILITY IDEOGRAPH-2F96C;Lo;0;L;7D63;;;;N;;;;;
+2F96D;CJK COMPATIBILITY IDEOGRAPH-2F96D;Lo;0;L;4301;;;;N;;;;;
+2F96E;CJK COMPATIBILITY IDEOGRAPH-2F96E;Lo;0;L;7DC7;;;;N;;;;;
+2F96F;CJK COMPATIBILITY IDEOGRAPH-2F96F;Lo;0;L;7E02;;;;N;;;;;
+2F970;CJK COMPATIBILITY IDEOGRAPH-2F970;Lo;0;L;7E45;;;;N;;;;;
+2F971;CJK COMPATIBILITY IDEOGRAPH-2F971;Lo;0;L;4334;;;;N;;;;;
+2F972;CJK COMPATIBILITY IDEOGRAPH-2F972;Lo;0;L;26228;;;;N;;;;;
+2F973;CJK COMPATIBILITY IDEOGRAPH-2F973;Lo;0;L;26247;;;;N;;;;;
+2F974;CJK COMPATIBILITY IDEOGRAPH-2F974;Lo;0;L;4359;;;;N;;;;;
+2F975;CJK COMPATIBILITY IDEOGRAPH-2F975;Lo;0;L;262D9;;;;N;;;;;
+2F976;CJK COMPATIBILITY IDEOGRAPH-2F976;Lo;0;L;7F7A;;;;N;;;;;
+2F977;CJK COMPATIBILITY IDEOGRAPH-2F977;Lo;0;L;2633E;;;;N;;;;;
+2F978;CJK COMPATIBILITY IDEOGRAPH-2F978;Lo;0;L;7F95;;;;N;;;;;
+2F979;CJK COMPATIBILITY IDEOGRAPH-2F979;Lo;0;L;7FFA;;;;N;;;;;
+2F97A;CJK COMPATIBILITY IDEOGRAPH-2F97A;Lo;0;L;8005;;;;N;;;;;
+2F97B;CJK COMPATIBILITY IDEOGRAPH-2F97B;Lo;0;L;264DA;;;;N;;;;;
+2F97C;CJK COMPATIBILITY IDEOGRAPH-2F97C;Lo;0;L;26523;;;;N;;;;;
+2F97D;CJK COMPATIBILITY IDEOGRAPH-2F97D;Lo;0;L;8060;;;;N;;;;;
+2F97E;CJK COMPATIBILITY IDEOGRAPH-2F97E;Lo;0;L;265A8;;;;N;;;;;
+2F97F;CJK COMPATIBILITY IDEOGRAPH-2F97F;Lo;0;L;8070;;;;N;;;;;
+2F980;CJK COMPATIBILITY IDEOGRAPH-2F980;Lo;0;L;2335F;;;;N;;;;;
+2F981;CJK COMPATIBILITY IDEOGRAPH-2F981;Lo;0;L;43D5;;;;N;;;;;
+2F982;CJK COMPATIBILITY IDEOGRAPH-2F982;Lo;0;L;80B2;;;;N;;;;;
+2F983;CJK COMPATIBILITY IDEOGRAPH-2F983;Lo;0;L;8103;;;;N;;;;;
+2F984;CJK COMPATIBILITY IDEOGRAPH-2F984;Lo;0;L;440B;;;;N;;;;;
+2F985;CJK COMPATIBILITY IDEOGRAPH-2F985;Lo;0;L;813E;;;;N;;;;;
+2F986;CJK COMPATIBILITY IDEOGRAPH-2F986;Lo;0;L;5AB5;;;;N;;;;;
+2F987;CJK COMPATIBILITY IDEOGRAPH-2F987;Lo;0;L;267A7;;;;N;;;;;
+2F988;CJK COMPATIBILITY IDEOGRAPH-2F988;Lo;0;L;267B5;;;;N;;;;;
+2F989;CJK COMPATIBILITY IDEOGRAPH-2F989;Lo;0;L;23393;;;;N;;;;;
+2F98A;CJK COMPATIBILITY IDEOGRAPH-2F98A;Lo;0;L;2339C;;;;N;;;;;
+2F98B;CJK COMPATIBILITY IDEOGRAPH-2F98B;Lo;0;L;8201;;;;N;;;;;
+2F98C;CJK COMPATIBILITY IDEOGRAPH-2F98C;Lo;0;L;8204;;;;N;;;;;
+2F98D;CJK COMPATIBILITY IDEOGRAPH-2F98D;Lo;0;L;8F9E;;;;N;;;;;
+2F98E;CJK COMPATIBILITY IDEOGRAPH-2F98E;Lo;0;L;446B;;;;N;;;;;
+2F98F;CJK COMPATIBILITY IDEOGRAPH-2F98F;Lo;0;L;8291;;;;N;;;;;
+2F990;CJK COMPATIBILITY IDEOGRAPH-2F990;Lo;0;L;828B;;;;N;;;;;
+2F991;CJK COMPATIBILITY IDEOGRAPH-2F991;Lo;0;L;829D;;;;N;;;;;
+2F992;CJK COMPATIBILITY IDEOGRAPH-2F992;Lo;0;L;52B3;;;;N;;;;;
+2F993;CJK COMPATIBILITY IDEOGRAPH-2F993;Lo;0;L;82B1;;;;N;;;;;
+2F994;CJK COMPATIBILITY IDEOGRAPH-2F994;Lo;0;L;82B3;;;;N;;;;;
+2F995;CJK COMPATIBILITY IDEOGRAPH-2F995;Lo;0;L;82BD;;;;N;;;;;
+2F996;CJK COMPATIBILITY IDEOGRAPH-2F996;Lo;0;L;82E6;;;;N;;;;;
+2F997;CJK COMPATIBILITY IDEOGRAPH-2F997;Lo;0;L;26B3C;;;;N;;;;;
+2F998;CJK COMPATIBILITY IDEOGRAPH-2F998;Lo;0;L;82E5;;;;N;;;;;
+2F999;CJK COMPATIBILITY IDEOGRAPH-2F999;Lo;0;L;831D;;;;N;;;;;
+2F99A;CJK COMPATIBILITY IDEOGRAPH-2F99A;Lo;0;L;8363;;;;N;;;;;
+2F99B;CJK COMPATIBILITY IDEOGRAPH-2F99B;Lo;0;L;83AD;;;;N;;;;;
+2F99C;CJK COMPATIBILITY IDEOGRAPH-2F99C;Lo;0;L;8323;;;;N;;;;;
+2F99D;CJK COMPATIBILITY IDEOGRAPH-2F99D;Lo;0;L;83BD;;;;N;;;;;
+2F99E;CJK COMPATIBILITY IDEOGRAPH-2F99E;Lo;0;L;83E7;;;;N;;;;;
+2F99F;CJK COMPATIBILITY IDEOGRAPH-2F99F;Lo;0;L;8457;;;;N;;;;;
+2F9A0;CJK COMPATIBILITY IDEOGRAPH-2F9A0;Lo;0;L;8353;;;;N;;;;;
+2F9A1;CJK COMPATIBILITY IDEOGRAPH-2F9A1;Lo;0;L;83CA;;;;N;;;;;
+2F9A2;CJK COMPATIBILITY IDEOGRAPH-2F9A2;Lo;0;L;83CC;;;;N;;;;;
+2F9A3;CJK COMPATIBILITY IDEOGRAPH-2F9A3;Lo;0;L;83DC;;;;N;;;;;
+2F9A4;CJK COMPATIBILITY IDEOGRAPH-2F9A4;Lo;0;L;26C36;;;;N;;;;;
+2F9A5;CJK COMPATIBILITY IDEOGRAPH-2F9A5;Lo;0;L;26D6B;;;;N;;;;;
+2F9A6;CJK COMPATIBILITY IDEOGRAPH-2F9A6;Lo;0;L;26CD5;;;;N;;;;;
+2F9A7;CJK COMPATIBILITY IDEOGRAPH-2F9A7;Lo;0;L;452B;;;;N;;;;;
+2F9A8;CJK COMPATIBILITY IDEOGRAPH-2F9A8;Lo;0;L;84F1;;;;N;;;;;
+2F9A9;CJK COMPATIBILITY IDEOGRAPH-2F9A9;Lo;0;L;84F3;;;;N;;;;;
+2F9AA;CJK COMPATIBILITY IDEOGRAPH-2F9AA;Lo;0;L;8516;;;;N;;;;;
+2F9AB;CJK COMPATIBILITY IDEOGRAPH-2F9AB;Lo;0;L;273CA;;;;N;;;;;
+2F9AC;CJK COMPATIBILITY IDEOGRAPH-2F9AC;Lo;0;L;8564;;;;N;;;;;
+2F9AD;CJK COMPATIBILITY IDEOGRAPH-2F9AD;Lo;0;L;26F2C;;;;N;;;;;
+2F9AE;CJK COMPATIBILITY IDEOGRAPH-2F9AE;Lo;0;L;455D;;;;N;;;;;
+2F9AF;CJK COMPATIBILITY IDEOGRAPH-2F9AF;Lo;0;L;4561;;;;N;;;;;
+2F9B0;CJK COMPATIBILITY IDEOGRAPH-2F9B0;Lo;0;L;26FB1;;;;N;;;;;
+2F9B1;CJK COMPATIBILITY IDEOGRAPH-2F9B1;Lo;0;L;270D2;;;;N;;;;;
+2F9B2;CJK COMPATIBILITY IDEOGRAPH-2F9B2;Lo;0;L;456B;;;;N;;;;;
+2F9B3;CJK COMPATIBILITY IDEOGRAPH-2F9B3;Lo;0;L;8650;;;;N;;;;;
+2F9B4;CJK COMPATIBILITY IDEOGRAPH-2F9B4;Lo;0;L;865C;;;;N;;;;;
+2F9B5;CJK COMPATIBILITY IDEOGRAPH-2F9B5;Lo;0;L;8667;;;;N;;;;;
+2F9B6;CJK COMPATIBILITY IDEOGRAPH-2F9B6;Lo;0;L;8669;;;;N;;;;;
+2F9B7;CJK COMPATIBILITY IDEOGRAPH-2F9B7;Lo;0;L;86A9;;;;N;;;;;
+2F9B8;CJK COMPATIBILITY IDEOGRAPH-2F9B8;Lo;0;L;8688;;;;N;;;;;
+2F9B9;CJK COMPATIBILITY IDEOGRAPH-2F9B9;Lo;0;L;870E;;;;N;;;;;
+2F9BA;CJK COMPATIBILITY IDEOGRAPH-2F9BA;Lo;0;L;86E2;;;;N;;;;;
+2F9BB;CJK COMPATIBILITY IDEOGRAPH-2F9BB;Lo;0;L;8779;;;;N;;;;;
+2F9BC;CJK COMPATIBILITY IDEOGRAPH-2F9BC;Lo;0;L;8728;;;;N;;;;;
+2F9BD;CJK COMPATIBILITY IDEOGRAPH-2F9BD;Lo;0;L;876B;;;;N;;;;;
+2F9BE;CJK COMPATIBILITY IDEOGRAPH-2F9BE;Lo;0;L;8786;;;;N;;;;;
+2F9BF;CJK COMPATIBILITY IDEOGRAPH-2F9BF;Lo;0;L;45D7;;;;N;;;;;
+2F9C0;CJK COMPATIBILITY IDEOGRAPH-2F9C0;Lo;0;L;87E1;;;;N;;;;;
+2F9C1;CJK COMPATIBILITY IDEOGRAPH-2F9C1;Lo;0;L;8801;;;;N;;;;;
+2F9C2;CJK COMPATIBILITY IDEOGRAPH-2F9C2;Lo;0;L;45F9;;;;N;;;;;
+2F9C3;CJK COMPATIBILITY IDEOGRAPH-2F9C3;Lo;0;L;8860;;;;N;;;;;
+2F9C4;CJK COMPATIBILITY IDEOGRAPH-2F9C4;Lo;0;L;8863;;;;N;;;;;
+2F9C5;CJK COMPATIBILITY IDEOGRAPH-2F9C5;Lo;0;L;27667;;;;N;;;;;
+2F9C6;CJK COMPATIBILITY IDEOGRAPH-2F9C6;Lo;0;L;88D7;;;;N;;;;;
+2F9C7;CJK COMPATIBILITY IDEOGRAPH-2F9C7;Lo;0;L;88DE;;;;N;;;;;
+2F9C8;CJK COMPATIBILITY IDEOGRAPH-2F9C8;Lo;0;L;4635;;;;N;;;;;
+2F9C9;CJK COMPATIBILITY IDEOGRAPH-2F9C9;Lo;0;L;88FA;;;;N;;;;;
+2F9CA;CJK COMPATIBILITY IDEOGRAPH-2F9CA;Lo;0;L;34BB;;;;N;;;;;
+2F9CB;CJK COMPATIBILITY IDEOGRAPH-2F9CB;Lo;0;L;278AE;;;;N;;;;;
+2F9CC;CJK COMPATIBILITY IDEOGRAPH-2F9CC;Lo;0;L;27966;;;;N;;;;;
+2F9CD;CJK COMPATIBILITY IDEOGRAPH-2F9CD;Lo;0;L;46BE;;;;N;;;;;
+2F9CE;CJK COMPATIBILITY IDEOGRAPH-2F9CE;Lo;0;L;46C7;;;;N;;;;;
+2F9CF;CJK COMPATIBILITY IDEOGRAPH-2F9CF;Lo;0;L;8AA0;;;;N;;;;;
+2F9D0;CJK COMPATIBILITY IDEOGRAPH-2F9D0;Lo;0;L;8AED;;;;N;;;;;
+2F9D1;CJK COMPATIBILITY IDEOGRAPH-2F9D1;Lo;0;L;8B8A;;;;N;;;;;
+2F9D2;CJK COMPATIBILITY IDEOGRAPH-2F9D2;Lo;0;L;8C55;;;;N;;;;;
+2F9D3;CJK COMPATIBILITY IDEOGRAPH-2F9D3;Lo;0;L;27CA8;;;;N;;;;;
+2F9D4;CJK COMPATIBILITY IDEOGRAPH-2F9D4;Lo;0;L;8CAB;;;;N;;;;;
+2F9D5;CJK COMPATIBILITY IDEOGRAPH-2F9D5;Lo;0;L;8CC1;;;;N;;;;;
+2F9D6;CJK COMPATIBILITY IDEOGRAPH-2F9D6;Lo;0;L;8D1B;;;;N;;;;;
+2F9D7;CJK COMPATIBILITY IDEOGRAPH-2F9D7;Lo;0;L;8D77;;;;N;;;;;
+2F9D8;CJK COMPATIBILITY IDEOGRAPH-2F9D8;Lo;0;L;27F2F;;;;N;;;;;
+2F9D9;CJK COMPATIBILITY IDEOGRAPH-2F9D9;Lo;0;L;20804;;;;N;;;;;
+2F9DA;CJK COMPATIBILITY IDEOGRAPH-2F9DA;Lo;0;L;8DCB;;;;N;;;;;
+2F9DB;CJK COMPATIBILITY IDEOGRAPH-2F9DB;Lo;0;L;8DBC;;;;N;;;;;
+2F9DC;CJK COMPATIBILITY IDEOGRAPH-2F9DC;Lo;0;L;8DF0;;;;N;;;;;
+2F9DD;CJK COMPATIBILITY IDEOGRAPH-2F9DD;Lo;0;L;208DE;;;;N;;;;;
+2F9DE;CJK COMPATIBILITY IDEOGRAPH-2F9DE;Lo;0;L;8ED4;;;;N;;;;;
+2F9DF;CJK COMPATIBILITY IDEOGRAPH-2F9DF;Lo;0;L;8F38;;;;N;;;;;
+2F9E0;CJK COMPATIBILITY IDEOGRAPH-2F9E0;Lo;0;L;285D2;;;;N;;;;;
+2F9E1;CJK COMPATIBILITY IDEOGRAPH-2F9E1;Lo;0;L;285ED;;;;N;;;;;
+2F9E2;CJK COMPATIBILITY IDEOGRAPH-2F9E2;Lo;0;L;9094;;;;N;;;;;
+2F9E3;CJK COMPATIBILITY IDEOGRAPH-2F9E3;Lo;0;L;90F1;;;;N;;;;;
+2F9E4;CJK COMPATIBILITY IDEOGRAPH-2F9E4;Lo;0;L;9111;;;;N;;;;;
+2F9E5;CJK COMPATIBILITY IDEOGRAPH-2F9E5;Lo;0;L;2872E;;;;N;;;;;
+2F9E6;CJK COMPATIBILITY IDEOGRAPH-2F9E6;Lo;0;L;911B;;;;N;;;;;
+2F9E7;CJK COMPATIBILITY IDEOGRAPH-2F9E7;Lo;0;L;9238;;;;N;;;;;
+2F9E8;CJK COMPATIBILITY IDEOGRAPH-2F9E8;Lo;0;L;92D7;;;;N;;;;;
+2F9E9;CJK COMPATIBILITY IDEOGRAPH-2F9E9;Lo;0;L;92D8;;;;N;;;;;
+2F9EA;CJK COMPATIBILITY IDEOGRAPH-2F9EA;Lo;0;L;927C;;;;N;;;;;
+2F9EB;CJK COMPATIBILITY IDEOGRAPH-2F9EB;Lo;0;L;93F9;;;;N;;;;;
+2F9EC;CJK COMPATIBILITY IDEOGRAPH-2F9EC;Lo;0;L;9415;;;;N;;;;;
+2F9ED;CJK COMPATIBILITY IDEOGRAPH-2F9ED;Lo;0;L;28BFA;;;;N;;;;;
+2F9EE;CJK COMPATIBILITY IDEOGRAPH-2F9EE;Lo;0;L;958B;;;;N;;;;;
+2F9EF;CJK COMPATIBILITY IDEOGRAPH-2F9EF;Lo;0;L;4995;;;;N;;;;;
+2F9F0;CJK COMPATIBILITY IDEOGRAPH-2F9F0;Lo;0;L;95B7;;;;N;;;;;
+2F9F1;CJK COMPATIBILITY IDEOGRAPH-2F9F1;Lo;0;L;28D77;;;;N;;;;;
+2F9F2;CJK COMPATIBILITY IDEOGRAPH-2F9F2;Lo;0;L;49E6;;;;N;;;;;
+2F9F3;CJK COMPATIBILITY IDEOGRAPH-2F9F3;Lo;0;L;96C3;;;;N;;;;;
+2F9F4;CJK COMPATIBILITY IDEOGRAPH-2F9F4;Lo;0;L;5DB2;;;;N;;;;;
+2F9F5;CJK COMPATIBILITY IDEOGRAPH-2F9F5;Lo;0;L;9723;;;;N;;;;;
+2F9F6;CJK COMPATIBILITY IDEOGRAPH-2F9F6;Lo;0;L;29145;;;;N;;;;;
+2F9F7;CJK COMPATIBILITY IDEOGRAPH-2F9F7;Lo;0;L;2921A;;;;N;;;;;
+2F9F8;CJK COMPATIBILITY IDEOGRAPH-2F9F8;Lo;0;L;4A6E;;;;N;;;;;
+2F9F9;CJK COMPATIBILITY IDEOGRAPH-2F9F9;Lo;0;L;4A76;;;;N;;;;;
+2F9FA;CJK COMPATIBILITY IDEOGRAPH-2F9FA;Lo;0;L;97E0;;;;N;;;;;
+2F9FB;CJK COMPATIBILITY IDEOGRAPH-2F9FB;Lo;0;L;2940A;;;;N;;;;;
+2F9FC;CJK COMPATIBILITY IDEOGRAPH-2F9FC;Lo;0;L;4AB2;;;;N;;;;;
+2F9FD;CJK COMPATIBILITY IDEOGRAPH-2F9FD;Lo;0;L;29496;;;;N;;;;;
+2F9FE;CJK COMPATIBILITY IDEOGRAPH-2F9FE;Lo;0;L;980B;;;;N;;;;;
+2F9FF;CJK COMPATIBILITY IDEOGRAPH-2F9FF;Lo;0;L;980B;;;;N;;;;;
+2FA00;CJK COMPATIBILITY IDEOGRAPH-2FA00;Lo;0;L;9829;;;;N;;;;;
+2FA01;CJK COMPATIBILITY IDEOGRAPH-2FA01;Lo;0;L;295B6;;;;N;;;;;
+2FA02;CJK COMPATIBILITY IDEOGRAPH-2FA02;Lo;0;L;98E2;;;;N;;;;;
+2FA03;CJK COMPATIBILITY IDEOGRAPH-2FA03;Lo;0;L;4B33;;;;N;;;;;
+2FA04;CJK COMPATIBILITY IDEOGRAPH-2FA04;Lo;0;L;9929;;;;N;;;;;
+2FA05;CJK COMPATIBILITY IDEOGRAPH-2FA05;Lo;0;L;99A7;;;;N;;;;;
+2FA06;CJK COMPATIBILITY IDEOGRAPH-2FA06;Lo;0;L;99C2;;;;N;;;;;
+2FA07;CJK COMPATIBILITY IDEOGRAPH-2FA07;Lo;0;L;99FE;;;;N;;;;;
+2FA08;CJK COMPATIBILITY IDEOGRAPH-2FA08;Lo;0;L;4BCE;;;;N;;;;;
+2FA09;CJK COMPATIBILITY IDEOGRAPH-2FA09;Lo;0;L;29B30;;;;N;;;;;
+2FA0A;CJK COMPATIBILITY IDEOGRAPH-2FA0A;Lo;0;L;9B12;;;;N;;;;;
+2FA0B;CJK COMPATIBILITY IDEOGRAPH-2FA0B;Lo;0;L;9C40;;;;N;;;;;
+2FA0C;CJK COMPATIBILITY IDEOGRAPH-2FA0C;Lo;0;L;9CFD;;;;N;;;;;
+2FA0D;CJK COMPATIBILITY IDEOGRAPH-2FA0D;Lo;0;L;4CCE;;;;N;;;;;
+2FA0E;CJK COMPATIBILITY IDEOGRAPH-2FA0E;Lo;0;L;4CED;;;;N;;;;;
+2FA0F;CJK COMPATIBILITY IDEOGRAPH-2FA0F;Lo;0;L;9D67;;;;N;;;;;
+2FA10;CJK COMPATIBILITY IDEOGRAPH-2FA10;Lo;0;L;2A0CE;;;;N;;;;;
+2FA11;CJK COMPATIBILITY IDEOGRAPH-2FA11;Lo;0;L;4CF8;;;;N;;;;;
+2FA12;CJK COMPATIBILITY IDEOGRAPH-2FA12;Lo;0;L;2A105;;;;N;;;;;
+2FA13;CJK COMPATIBILITY IDEOGRAPH-2FA13;Lo;0;L;2A20E;;;;N;;;;;
+2FA14;CJK COMPATIBILITY IDEOGRAPH-2FA14;Lo;0;L;2A291;;;;N;;;;;
+2FA15;CJK COMPATIBILITY IDEOGRAPH-2FA15;Lo;0;L;9EBB;;;;N;;;;;
+2FA16;CJK COMPATIBILITY IDEOGRAPH-2FA16;Lo;0;L;4D56;;;;N;;;;;
+2FA17;CJK COMPATIBILITY IDEOGRAPH-2FA17;Lo;0;L;9EF9;;;;N;;;;;
+2FA18;CJK COMPATIBILITY IDEOGRAPH-2FA18;Lo;0;L;9EFE;;;;N;;;;;
+2FA19;CJK COMPATIBILITY IDEOGRAPH-2FA19;Lo;0;L;9F05;;;;N;;;;;
+2FA1A;CJK COMPATIBILITY IDEOGRAPH-2FA1A;Lo;0;L;9F0F;;;;N;;;;;
+2FA1B;CJK COMPATIBILITY IDEOGRAPH-2FA1B;Lo;0;L;9F16;;;;N;;;;;
+2FA1C;CJK COMPATIBILITY IDEOGRAPH-2FA1C;Lo;0;L;9F3B;;;;N;;;;;
+2FA1D;CJK COMPATIBILITY IDEOGRAPH-2FA1D;Lo;0;L;2A600;;;;N;;;;;
+E0001;LANGUAGE TAG;Cf;0;BN;;;;;N;;;;;
+E0020;TAG SPACE;Cf;0;BN;;;;;N;;;;;
+E0021;TAG EXCLAMATION MARK;Cf;0;BN;;;;;N;;;;;
+E0022;TAG QUOTATION MARK;Cf;0;BN;;;;;N;;;;;
+E0023;TAG NUMBER SIGN;Cf;0;BN;;;;;N;;;;;
+E0024;TAG DOLLAR SIGN;Cf;0;BN;;;;;N;;;;;
+E0025;TAG PERCENT SIGN;Cf;0;BN;;;;;N;;;;;
+E0026;TAG AMPERSAND;Cf;0;BN;;;;;N;;;;;
+E0027;TAG APOSTROPHE;Cf;0;BN;;;;;N;;;;;
+E0028;TAG LEFT PARENTHESIS;Cf;0;BN;;;;;N;;;;;
+E0029;TAG RIGHT PARENTHESIS;Cf;0;BN;;;;;N;;;;;
+E002A;TAG ASTERISK;Cf;0;BN;;;;;N;;;;;
+E002B;TAG PLUS SIGN;Cf;0;BN;;;;;N;;;;;
+E002C;TAG COMMA;Cf;0;BN;;;;;N;;;;;
+E002D;TAG HYPHEN-MINUS;Cf;0;BN;;;;;N;;;;;
+E002E;TAG FULL STOP;Cf;0;BN;;;;;N;;;;;
+E002F;TAG SOLIDUS;Cf;0;BN;;;;;N;;;;;
+E0030;TAG DIGIT ZERO;Cf;0;BN;;;;;N;;;;;
+E0031;TAG DIGIT ONE;Cf;0;BN;;;;;N;;;;;
+E0032;TAG DIGIT TWO;Cf;0;BN;;;;;N;;;;;
+E0033;TAG DIGIT THREE;Cf;0;BN;;;;;N;;;;;
+E0034;TAG DIGIT FOUR;Cf;0;BN;;;;;N;;;;;
+E0035;TAG DIGIT FIVE;Cf;0;BN;;;;;N;;;;;
+E0036;TAG DIGIT SIX;Cf;0;BN;;;;;N;;;;;
+E0037;TAG DIGIT SEVEN;Cf;0;BN;;;;;N;;;;;
+E0038;TAG DIGIT EIGHT;Cf;0;BN;;;;;N;;;;;
+E0039;TAG DIGIT NINE;Cf;0;BN;;;;;N;;;;;
+E003A;TAG COLON;Cf;0;BN;;;;;N;;;;;
+E003B;TAG SEMICOLON;Cf;0;BN;;;;;N;;;;;
+E003C;TAG LESS-THAN SIGN;Cf;0;BN;;;;;N;;;;;
+E003D;TAG EQUALS SIGN;Cf;0;BN;;;;;N;;;;;
+E003E;TAG GREATER-THAN SIGN;Cf;0;BN;;;;;N;;;;;
+E003F;TAG QUESTION MARK;Cf;0;BN;;;;;N;;;;;
+E0040;TAG COMMERCIAL AT;Cf;0;BN;;;;;N;;;;;
+E0041;TAG LATIN CAPITAL LETTER A;Cf;0;BN;;;;;N;;;;;
+E0042;TAG LATIN CAPITAL LETTER B;Cf;0;BN;;;;;N;;;;;
+E0043;TAG LATIN CAPITAL LETTER C;Cf;0;BN;;;;;N;;;;;
+E0044;TAG LATIN CAPITAL LETTER D;Cf;0;BN;;;;;N;;;;;
+E0045;TAG LATIN CAPITAL LETTER E;Cf;0;BN;;;;;N;;;;;
+E0046;TAG LATIN CAPITAL LETTER F;Cf;0;BN;;;;;N;;;;;
+E0047;TAG LATIN CAPITAL LETTER G;Cf;0;BN;;;;;N;;;;;
+E0048;TAG LATIN CAPITAL LETTER H;Cf;0;BN;;;;;N;;;;;
+E0049;TAG LATIN CAPITAL LETTER I;Cf;0;BN;;;;;N;;;;;
+E004A;TAG LATIN CAPITAL LETTER J;Cf;0;BN;;;;;N;;;;;
+E004B;TAG LATIN CAPITAL LETTER K;Cf;0;BN;;;;;N;;;;;
+E004C;TAG LATIN CAPITAL LETTER L;Cf;0;BN;;;;;N;;;;;
+E004D;TAG LATIN CAPITAL LETTER M;Cf;0;BN;;;;;N;;;;;
+E004E;TAG LATIN CAPITAL LETTER N;Cf;0;BN;;;;;N;;;;;
+E004F;TAG LATIN CAPITAL LETTER O;Cf;0;BN;;;;;N;;;;;
+E0050;TAG LATIN CAPITAL LETTER P;Cf;0;BN;;;;;N;;;;;
+E0051;TAG LATIN CAPITAL LETTER Q;Cf;0;BN;;;;;N;;;;;
+E0052;TAG LATIN CAPITAL LETTER R;Cf;0;BN;;;;;N;;;;;
+E0053;TAG LATIN CAPITAL LETTER S;Cf;0;BN;;;;;N;;;;;
+E0054;TAG LATIN CAPITAL LETTER T;Cf;0;BN;;;;;N;;;;;
+E0055;TAG LATIN CAPITAL LETTER U;Cf;0;BN;;;;;N;;;;;
+E0056;TAG LATIN CAPITAL LETTER V;Cf;0;BN;;;;;N;;;;;
+E0057;TAG LATIN CAPITAL LETTER W;Cf;0;BN;;;;;N;;;;;
+E0058;TAG LATIN CAPITAL LETTER X;Cf;0;BN;;;;;N;;;;;
+E0059;TAG LATIN CAPITAL LETTER Y;Cf;0;BN;;;;;N;;;;;
+E005A;TAG LATIN CAPITAL LETTER Z;Cf;0;BN;;;;;N;;;;;
+E005B;TAG LEFT SQUARE BRACKET;Cf;0;BN;;;;;N;;;;;
+E005C;TAG REVERSE SOLIDUS;Cf;0;BN;;;;;N;;;;;
+E005D;TAG RIGHT SQUARE BRACKET;Cf;0;BN;;;;;N;;;;;
+E005E;TAG CIRCUMFLEX ACCENT;Cf;0;BN;;;;;N;;;;;
+E005F;TAG LOW LINE;Cf;0;BN;;;;;N;;;;;
+E0060;TAG GRAVE ACCENT;Cf;0;BN;;;;;N;;;;;
+E0061;TAG LATIN SMALL LETTER A;Cf;0;BN;;;;;N;;;;;
+E0062;TAG LATIN SMALL LETTER B;Cf;0;BN;;;;;N;;;;;
+E0063;TAG LATIN SMALL LETTER C;Cf;0;BN;;;;;N;;;;;
+E0064;TAG LATIN SMALL LETTER D;Cf;0;BN;;;;;N;;;;;
+E0065;TAG LATIN SMALL LETTER E;Cf;0;BN;;;;;N;;;;;
+E0066;TAG LATIN SMALL LETTER F;Cf;0;BN;;;;;N;;;;;
+E0067;TAG LATIN SMALL LETTER G;Cf;0;BN;;;;;N;;;;;
+E0068;TAG LATIN SMALL LETTER H;Cf;0;BN;;;;;N;;;;;
+E0069;TAG LATIN SMALL LETTER I;Cf;0;BN;;;;;N;;;;;
+E006A;TAG LATIN SMALL LETTER J;Cf;0;BN;;;;;N;;;;;
+E006B;TAG LATIN SMALL LETTER K;Cf;0;BN;;;;;N;;;;;
+E006C;TAG LATIN SMALL LETTER L;Cf;0;BN;;;;;N;;;;;
+E006D;TAG LATIN SMALL LETTER M;Cf;0;BN;;;;;N;;;;;
+E006E;TAG LATIN SMALL LETTER N;Cf;0;BN;;;;;N;;;;;
+E006F;TAG LATIN SMALL LETTER O;Cf;0;BN;;;;;N;;;;;
+E0070;TAG LATIN SMALL LETTER P;Cf;0;BN;;;;;N;;;;;
+E0071;TAG LATIN SMALL LETTER Q;Cf;0;BN;;;;;N;;;;;
+E0072;TAG LATIN SMALL LETTER R;Cf;0;BN;;;;;N;;;;;
+E0073;TAG LATIN SMALL LETTER S;Cf;0;BN;;;;;N;;;;;
+E0074;TAG LATIN SMALL LETTER T;Cf;0;BN;;;;;N;;;;;
+E0075;TAG LATIN SMALL LETTER U;Cf;0;BN;;;;;N;;;;;
+E0076;TAG LATIN SMALL LETTER V;Cf;0;BN;;;;;N;;;;;
+E0077;TAG LATIN SMALL LETTER W;Cf;0;BN;;;;;N;;;;;
+E0078;TAG LATIN SMALL LETTER X;Cf;0;BN;;;;;N;;;;;
+E0079;TAG LATIN SMALL LETTER Y;Cf;0;BN;;;;;N;;;;;
+E007A;TAG LATIN SMALL LETTER Z;Cf;0;BN;;;;;N;;;;;
+E007B;TAG LEFT CURLY BRACKET;Cf;0;BN;;;;;N;;;;;
+E007C;TAG VERTICAL LINE;Cf;0;BN;;;;;N;;;;;
+E007D;TAG RIGHT CURLY BRACKET;Cf;0;BN;;;;;N;;;;;
+E007E;TAG TILDE;Cf;0;BN;;;;;N;;;;;
+E007F;CANCEL TAG;Cf;0;BN;;;;;N;;;;;
+E0100;VARIATION SELECTOR-17;Mn;0;NSM;;;;;N;;;;;
+E0101;VARIATION SELECTOR-18;Mn;0;NSM;;;;;N;;;;;
+E0102;VARIATION SELECTOR-19;Mn;0;NSM;;;;;N;;;;;
+E0103;VARIATION SELECTOR-20;Mn;0;NSM;;;;;N;;;;;
+E0104;VARIATION SELECTOR-21;Mn;0;NSM;;;;;N;;;;;
+E0105;VARIATION SELECTOR-22;Mn;0;NSM;;;;;N;;;;;
+E0106;VARIATION SELECTOR-23;Mn;0;NSM;;;;;N;;;;;
+E0107;VARIATION SELECTOR-24;Mn;0;NSM;;;;;N;;;;;
+E0108;VARIATION SELECTOR-25;Mn;0;NSM;;;;;N;;;;;
+E0109;VARIATION SELECTOR-26;Mn;0;NSM;;;;;N;;;;;
+E010A;VARIATION SELECTOR-27;Mn;0;NSM;;;;;N;;;;;
+E010B;VARIATION SELECTOR-28;Mn;0;NSM;;;;;N;;;;;
+E010C;VARIATION SELECTOR-29;Mn;0;NSM;;;;;N;;;;;
+E010D;VARIATION SELECTOR-30;Mn;0;NSM;;;;;N;;;;;
+E010E;VARIATION SELECTOR-31;Mn;0;NSM;;;;;N;;;;;
+E010F;VARIATION SELECTOR-32;Mn;0;NSM;;;;;N;;;;;
+E0110;VARIATION SELECTOR-33;Mn;0;NSM;;;;;N;;;;;
+E0111;VARIATION SELECTOR-34;Mn;0;NSM;;;;;N;;;;;
+E0112;VARIATION SELECTOR-35;Mn;0;NSM;;;;;N;;;;;
+E0113;VARIATION SELECTOR-36;Mn;0;NSM;;;;;N;;;;;
+E0114;VARIATION SELECTOR-37;Mn;0;NSM;;;;;N;;;;;
+E0115;VARIATION SELECTOR-38;Mn;0;NSM;;;;;N;;;;;
+E0116;VARIATION SELECTOR-39;Mn;0;NSM;;;;;N;;;;;
+E0117;VARIATION SELECTOR-40;Mn;0;NSM;;;;;N;;;;;
+E0118;VARIATION SELECTOR-41;Mn;0;NSM;;;;;N;;;;;
+E0119;VARIATION SELECTOR-42;Mn;0;NSM;;;;;N;;;;;
+E011A;VARIATION SELECTOR-43;Mn;0;NSM;;;;;N;;;;;
+E011B;VARIATION SELECTOR-44;Mn;0;NSM;;;;;N;;;;;
+E011C;VARIATION SELECTOR-45;Mn;0;NSM;;;;;N;;;;;
+E011D;VARIATION SELECTOR-46;Mn;0;NSM;;;;;N;;;;;
+E011E;VARIATION SELECTOR-47;Mn;0;NSM;;;;;N;;;;;
+E011F;VARIATION SELECTOR-48;Mn;0;NSM;;;;;N;;;;;
+E0120;VARIATION SELECTOR-49;Mn;0;NSM;;;;;N;;;;;
+E0121;VARIATION SELECTOR-50;Mn;0;NSM;;;;;N;;;;;
+E0122;VARIATION SELECTOR-51;Mn;0;NSM;;;;;N;;;;;
+E0123;VARIATION SELECTOR-52;Mn;0;NSM;;;;;N;;;;;
+E0124;VARIATION SELECTOR-53;Mn;0;NSM;;;;;N;;;;;
+E0125;VARIATION SELECTOR-54;Mn;0;NSM;;;;;N;;;;;
+E0126;VARIATION SELECTOR-55;Mn;0;NSM;;;;;N;;;;;
+E0127;VARIATION SELECTOR-56;Mn;0;NSM;;;;;N;;;;;
+E0128;VARIATION SELECTOR-57;Mn;0;NSM;;;;;N;;;;;
+E0129;VARIATION SELECTOR-58;Mn;0;NSM;;;;;N;;;;;
+E012A;VARIATION SELECTOR-59;Mn;0;NSM;;;;;N;;;;;
+E012B;VARIATION SELECTOR-60;Mn;0;NSM;;;;;N;;;;;
+E012C;VARIATION SELECTOR-61;Mn;0;NSM;;;;;N;;;;;
+E012D;VARIATION SELECTOR-62;Mn;0;NSM;;;;;N;;;;;
+E012E;VARIATION SELECTOR-63;Mn;0;NSM;;;;;N;;;;;
+E012F;VARIATION SELECTOR-64;Mn;0;NSM;;;;;N;;;;;
+E0130;VARIATION SELECTOR-65;Mn;0;NSM;;;;;N;;;;;
+E0131;VARIATION SELECTOR-66;Mn;0;NSM;;;;;N;;;;;
+E0132;VARIATION SELECTOR-67;Mn;0;NSM;;;;;N;;;;;
+E0133;VARIATION SELECTOR-68;Mn;0;NSM;;;;;N;;;;;
+E0134;VARIATION SELECTOR-69;Mn;0;NSM;;;;;N;;;;;
+E0135;VARIATION SELECTOR-70;Mn;0;NSM;;;;;N;;;;;
+E0136;VARIATION SELECTOR-71;Mn;0;NSM;;;;;N;;;;;
+E0137;VARIATION SELECTOR-72;Mn;0;NSM;;;;;N;;;;;
+E0138;VARIATION SELECTOR-73;Mn;0;NSM;;;;;N;;;;;
+E0139;VARIATION SELECTOR-74;Mn;0;NSM;;;;;N;;;;;
+E013A;VARIATION SELECTOR-75;Mn;0;NSM;;;;;N;;;;;
+E013B;VARIATION SELECTOR-76;Mn;0;NSM;;;;;N;;;;;
+E013C;VARIATION SELECTOR-77;Mn;0;NSM;;;;;N;;;;;
+E013D;VARIATION SELECTOR-78;Mn;0;NSM;;;;;N;;;;;
+E013E;VARIATION SELECTOR-79;Mn;0;NSM;;;;;N;;;;;
+E013F;VARIATION SELECTOR-80;Mn;0;NSM;;;;;N;;;;;
+E0140;VARIATION SELECTOR-81;Mn;0;NSM;;;;;N;;;;;
+E0141;VARIATION SELECTOR-82;Mn;0;NSM;;;;;N;;;;;
+E0142;VARIATION SELECTOR-83;Mn;0;NSM;;;;;N;;;;;
+E0143;VARIATION SELECTOR-84;Mn;0;NSM;;;;;N;;;;;
+E0144;VARIATION SELECTOR-85;Mn;0;NSM;;;;;N;;;;;
+E0145;VARIATION SELECTOR-86;Mn;0;NSM;;;;;N;;;;;
+E0146;VARIATION SELECTOR-87;Mn;0;NSM;;;;;N;;;;;
+E0147;VARIATION SELECTOR-88;Mn;0;NSM;;;;;N;;;;;
+E0148;VARIATION SELECTOR-89;Mn;0;NSM;;;;;N;;;;;
+E0149;VARIATION SELECTOR-90;Mn;0;NSM;;;;;N;;;;;
+E014A;VARIATION SELECTOR-91;Mn;0;NSM;;;;;N;;;;;
+E014B;VARIATION SELECTOR-92;Mn;0;NSM;;;;;N;;;;;
+E014C;VARIATION SELECTOR-93;Mn;0;NSM;;;;;N;;;;;
+E014D;VARIATION SELECTOR-94;Mn;0;NSM;;;;;N;;;;;
+E014E;VARIATION SELECTOR-95;Mn;0;NSM;;;;;N;;;;;
+E014F;VARIATION SELECTOR-96;Mn;0;NSM;;;;;N;;;;;
+E0150;VARIATION SELECTOR-97;Mn;0;NSM;;;;;N;;;;;
+E0151;VARIATION SELECTOR-98;Mn;0;NSM;;;;;N;;;;;
+E0152;VARIATION SELECTOR-99;Mn;0;NSM;;;;;N;;;;;
+E0153;VARIATION SELECTOR-100;Mn;0;NSM;;;;;N;;;;;
+E0154;VARIATION SELECTOR-101;Mn;0;NSM;;;;;N;;;;;
+E0155;VARIATION SELECTOR-102;Mn;0;NSM;;;;;N;;;;;
+E0156;VARIATION SELECTOR-103;Mn;0;NSM;;;;;N;;;;;
+E0157;VARIATION SELECTOR-104;Mn;0;NSM;;;;;N;;;;;
+E0158;VARIATION SELECTOR-105;Mn;0;NSM;;;;;N;;;;;
+E0159;VARIATION SELECTOR-106;Mn;0;NSM;;;;;N;;;;;
+E015A;VARIATION SELECTOR-107;Mn;0;NSM;;;;;N;;;;;
+E015B;VARIATION SELECTOR-108;Mn;0;NSM;;;;;N;;;;;
+E015C;VARIATION SELECTOR-109;Mn;0;NSM;;;;;N;;;;;
+E015D;VARIATION SELECTOR-110;Mn;0;NSM;;;;;N;;;;;
+E015E;VARIATION SELECTOR-111;Mn;0;NSM;;;;;N;;;;;
+E015F;VARIATION SELECTOR-112;Mn;0;NSM;;;;;N;;;;;
+E0160;VARIATION SELECTOR-113;Mn;0;NSM;;;;;N;;;;;
+E0161;VARIATION SELECTOR-114;Mn;0;NSM;;;;;N;;;;;
+E0162;VARIATION SELECTOR-115;Mn;0;NSM;;;;;N;;;;;
+E0163;VARIATION SELECTOR-116;Mn;0;NSM;;;;;N;;;;;
+E0164;VARIATION SELECTOR-117;Mn;0;NSM;;;;;N;;;;;
+E0165;VARIATION SELECTOR-118;Mn;0;NSM;;;;;N;;;;;
+E0166;VARIATION SELECTOR-119;Mn;0;NSM;;;;;N;;;;;
+E0167;VARIATION SELECTOR-120;Mn;0;NSM;;;;;N;;;;;
+E0168;VARIATION SELECTOR-121;Mn;0;NSM;;;;;N;;;;;
+E0169;VARIATION SELECTOR-122;Mn;0;NSM;;;;;N;;;;;
+E016A;VARIATION SELECTOR-123;Mn;0;NSM;;;;;N;;;;;
+E016B;VARIATION SELECTOR-124;Mn;0;NSM;;;;;N;;;;;
+E016C;VARIATION SELECTOR-125;Mn;0;NSM;;;;;N;;;;;
+E016D;VARIATION SELECTOR-126;Mn;0;NSM;;;;;N;;;;;
+E016E;VARIATION SELECTOR-127;Mn;0;NSM;;;;;N;;;;;
+E016F;VARIATION SELECTOR-128;Mn;0;NSM;;;;;N;;;;;
+E0170;VARIATION SELECTOR-129;Mn;0;NSM;;;;;N;;;;;
+E0171;VARIATION SELECTOR-130;Mn;0;NSM;;;;;N;;;;;
+E0172;VARIATION SELECTOR-131;Mn;0;NSM;;;;;N;;;;;
+E0173;VARIATION SELECTOR-132;Mn;0;NSM;;;;;N;;;;;
+E0174;VARIATION SELECTOR-133;Mn;0;NSM;;;;;N;;;;;
+E0175;VARIATION SELECTOR-134;Mn;0;NSM;;;;;N;;;;;
+E0176;VARIATION SELECTOR-135;Mn;0;NSM;;;;;N;;;;;
+E0177;VARIATION SELECTOR-136;Mn;0;NSM;;;;;N;;;;;
+E0178;VARIATION SELECTOR-137;Mn;0;NSM;;;;;N;;;;;
+E0179;VARIATION SELECTOR-138;Mn;0;NSM;;;;;N;;;;;
+E017A;VARIATION SELECTOR-139;Mn;0;NSM;;;;;N;;;;;
+E017B;VARIATION SELECTOR-140;Mn;0;NSM;;;;;N;;;;;
+E017C;VARIATION SELECTOR-141;Mn;0;NSM;;;;;N;;;;;
+E017D;VARIATION SELECTOR-142;Mn;0;NSM;;;;;N;;;;;
+E017E;VARIATION SELECTOR-143;Mn;0;NSM;;;;;N;;;;;
+E017F;VARIATION SELECTOR-144;Mn;0;NSM;;;;;N;;;;;
+E0180;VARIATION SELECTOR-145;Mn;0;NSM;;;;;N;;;;;
+E0181;VARIATION SELECTOR-146;Mn;0;NSM;;;;;N;;;;;
+E0182;VARIATION SELECTOR-147;Mn;0;NSM;;;;;N;;;;;
+E0183;VARIATION SELECTOR-148;Mn;0;NSM;;;;;N;;;;;
+E0184;VARIATION SELECTOR-149;Mn;0;NSM;;;;;N;;;;;
+E0185;VARIATION SELECTOR-150;Mn;0;NSM;;;;;N;;;;;
+E0186;VARIATION SELECTOR-151;Mn;0;NSM;;;;;N;;;;;
+E0187;VARIATION SELECTOR-152;Mn;0;NSM;;;;;N;;;;;
+E0188;VARIATION SELECTOR-153;Mn;0;NSM;;;;;N;;;;;
+E0189;VARIATION SELECTOR-154;Mn;0;NSM;;;;;N;;;;;
+E018A;VARIATION SELECTOR-155;Mn;0;NSM;;;;;N;;;;;
+E018B;VARIATION SELECTOR-156;Mn;0;NSM;;;;;N;;;;;
+E018C;VARIATION SELECTOR-157;Mn;0;NSM;;;;;N;;;;;
+E018D;VARIATION SELECTOR-158;Mn;0;NSM;;;;;N;;;;;
+E018E;VARIATION SELECTOR-159;Mn;0;NSM;;;;;N;;;;;
+E018F;VARIATION SELECTOR-160;Mn;0;NSM;;;;;N;;;;;
+E0190;VARIATION SELECTOR-161;Mn;0;NSM;;;;;N;;;;;
+E0191;VARIATION SELECTOR-162;Mn;0;NSM;;;;;N;;;;;
+E0192;VARIATION SELECTOR-163;Mn;0;NSM;;;;;N;;;;;
+E0193;VARIATION SELECTOR-164;Mn;0;NSM;;;;;N;;;;;
+E0194;VARIATION SELECTOR-165;Mn;0;NSM;;;;;N;;;;;
+E0195;VARIATION SELECTOR-166;Mn;0;NSM;;;;;N;;;;;
+E0196;VARIATION SELECTOR-167;Mn;0;NSM;;;;;N;;;;;
+E0197;VARIATION SELECTOR-168;Mn;0;NSM;;;;;N;;;;;
+E0198;VARIATION SELECTOR-169;Mn;0;NSM;;;;;N;;;;;
+E0199;VARIATION SELECTOR-170;Mn;0;NSM;;;;;N;;;;;
+E019A;VARIATION SELECTOR-171;Mn;0;NSM;;;;;N;;;;;
+E019B;VARIATION SELECTOR-172;Mn;0;NSM;;;;;N;;;;;
+E019C;VARIATION SELECTOR-173;Mn;0;NSM;;;;;N;;;;;
+E019D;VARIATION SELECTOR-174;Mn;0;NSM;;;;;N;;;;;
+E019E;VARIATION SELECTOR-175;Mn;0;NSM;;;;;N;;;;;
+E019F;VARIATION SELECTOR-176;Mn;0;NSM;;;;;N;;;;;
+E01A0;VARIATION SELECTOR-177;Mn;0;NSM;;;;;N;;;;;
+E01A1;VARIATION SELECTOR-178;Mn;0;NSM;;;;;N;;;;;
+E01A2;VARIATION SELECTOR-179;Mn;0;NSM;;;;;N;;;;;
+E01A3;VARIATION SELECTOR-180;Mn;0;NSM;;;;;N;;;;;
+E01A4;VARIATION SELECTOR-181;Mn;0;NSM;;;;;N;;;;;
+E01A5;VARIATION SELECTOR-182;Mn;0;NSM;;;;;N;;;;;
+E01A6;VARIATION SELECTOR-183;Mn;0;NSM;;;;;N;;;;;
+E01A7;VARIATION SELECTOR-184;Mn;0;NSM;;;;;N;;;;;
+E01A8;VARIATION SELECTOR-185;Mn;0;NSM;;;;;N;;;;;
+E01A9;VARIATION SELECTOR-186;Mn;0;NSM;;;;;N;;;;;
+E01AA;VARIATION SELECTOR-187;Mn;0;NSM;;;;;N;;;;;
+E01AB;VARIATION SELECTOR-188;Mn;0;NSM;;;;;N;;;;;
+E01AC;VARIATION SELECTOR-189;Mn;0;NSM;;;;;N;;;;;
+E01AD;VARIATION SELECTOR-190;Mn;0;NSM;;;;;N;;;;;
+E01AE;VARIATION SELECTOR-191;Mn;0;NSM;;;;;N;;;;;
+E01AF;VARIATION SELECTOR-192;Mn;0;NSM;;;;;N;;;;;
+E01B0;VARIATION SELECTOR-193;Mn;0;NSM;;;;;N;;;;;
+E01B1;VARIATION SELECTOR-194;Mn;0;NSM;;;;;N;;;;;
+E01B2;VARIATION SELECTOR-195;Mn;0;NSM;;;;;N;;;;;
+E01B3;VARIATION SELECTOR-196;Mn;0;NSM;;;;;N;;;;;
+E01B4;VARIATION SELECTOR-197;Mn;0;NSM;;;;;N;;;;;
+E01B5;VARIATION SELECTOR-198;Mn;0;NSM;;;;;N;;;;;
+E01B6;VARIATION SELECTOR-199;Mn;0;NSM;;;;;N;;;;;
+E01B7;VARIATION SELECTOR-200;Mn;0;NSM;;;;;N;;;;;
+E01B8;VARIATION SELECTOR-201;Mn;0;NSM;;;;;N;;;;;
+E01B9;VARIATION SELECTOR-202;Mn;0;NSM;;;;;N;;;;;
+E01BA;VARIATION SELECTOR-203;Mn;0;NSM;;;;;N;;;;;
+E01BB;VARIATION SELECTOR-204;Mn;0;NSM;;;;;N;;;;;
+E01BC;VARIATION SELECTOR-205;Mn;0;NSM;;;;;N;;;;;
+E01BD;VARIATION SELECTOR-206;Mn;0;NSM;;;;;N;;;;;
+E01BE;VARIATION SELECTOR-207;Mn;0;NSM;;;;;N;;;;;
+E01BF;VARIATION SELECTOR-208;Mn;0;NSM;;;;;N;;;;;
+E01C0;VARIATION SELECTOR-209;Mn;0;NSM;;;;;N;;;;;
+E01C1;VARIATION SELECTOR-210;Mn;0;NSM;;;;;N;;;;;
+E01C2;VARIATION SELECTOR-211;Mn;0;NSM;;;;;N;;;;;
+E01C3;VARIATION SELECTOR-212;Mn;0;NSM;;;;;N;;;;;
+E01C4;VARIATION SELECTOR-213;Mn;0;NSM;;;;;N;;;;;
+E01C5;VARIATION SELECTOR-214;Mn;0;NSM;;;;;N;;;;;
+E01C6;VARIATION SELECTOR-215;Mn;0;NSM;;;;;N;;;;;
+E01C7;VARIATION SELECTOR-216;Mn;0;NSM;;;;;N;;;;;
+E01C8;VARIATION SELECTOR-217;Mn;0;NSM;;;;;N;;;;;
+E01C9;VARIATION SELECTOR-218;Mn;0;NSM;;;;;N;;;;;
+E01CA;VARIATION SELECTOR-219;Mn;0;NSM;;;;;N;;;;;
+E01CB;VARIATION SELECTOR-220;Mn;0;NSM;;;;;N;;;;;
+E01CC;VARIATION SELECTOR-221;Mn;0;NSM;;;;;N;;;;;
+E01CD;VARIATION SELECTOR-222;Mn;0;NSM;;;;;N;;;;;
+E01CE;VARIATION SELECTOR-223;Mn;0;NSM;;;;;N;;;;;
+E01CF;VARIATION SELECTOR-224;Mn;0;NSM;;;;;N;;;;;
+E01D0;VARIATION SELECTOR-225;Mn;0;NSM;;;;;N;;;;;
+E01D1;VARIATION SELECTOR-226;Mn;0;NSM;;;;;N;;;;;
+E01D2;VARIATION SELECTOR-227;Mn;0;NSM;;;;;N;;;;;
+E01D3;VARIATION SELECTOR-228;Mn;0;NSM;;;;;N;;;;;
+E01D4;VARIATION SELECTOR-229;Mn;0;NSM;;;;;N;;;;;
+E01D5;VARIATION SELECTOR-230;Mn;0;NSM;;;;;N;;;;;
+E01D6;VARIATION SELECTOR-231;Mn;0;NSM;;;;;N;;;;;
+E01D7;VARIATION SELECTOR-232;Mn;0;NSM;;;;;N;;;;;
+E01D8;VARIATION SELECTOR-233;Mn;0;NSM;;;;;N;;;;;
+E01D9;VARIATION SELECTOR-234;Mn;0;NSM;;;;;N;;;;;
+E01DA;VARIATION SELECTOR-235;Mn;0;NSM;;;;;N;;;;;
+E01DB;VARIATION SELECTOR-236;Mn;0;NSM;;;;;N;;;;;
+E01DC;VARIATION SELECTOR-237;Mn;0;NSM;;;;;N;;;;;
+E01DD;VARIATION SELECTOR-238;Mn;0;NSM;;;;;N;;;;;
+E01DE;VARIATION SELECTOR-239;Mn;0;NSM;;;;;N;;;;;
+E01DF;VARIATION SELECTOR-240;Mn;0;NSM;;;;;N;;;;;
+E01E0;VARIATION SELECTOR-241;Mn;0;NSM;;;;;N;;;;;
+E01E1;VARIATION SELECTOR-242;Mn;0;NSM;;;;;N;;;;;
+E01E2;VARIATION SELECTOR-243;Mn;0;NSM;;;;;N;;;;;
+E01E3;VARIATION SELECTOR-244;Mn;0;NSM;;;;;N;;;;;
+E01E4;VARIATION SELECTOR-245;Mn;0;NSM;;;;;N;;;;;
+E01E5;VARIATION SELECTOR-246;Mn;0;NSM;;;;;N;;;;;
+E01E6;VARIATION SELECTOR-247;Mn;0;NSM;;;;;N;;;;;
+E01E7;VARIATION SELECTOR-248;Mn;0;NSM;;;;;N;;;;;
+E01E8;VARIATION SELECTOR-249;Mn;0;NSM;;;;;N;;;;;
+E01E9;VARIATION SELECTOR-250;Mn;0;NSM;;;;;N;;;;;
+E01EA;VARIATION SELECTOR-251;Mn;0;NSM;;;;;N;;;;;
+E01EB;VARIATION SELECTOR-252;Mn;0;NSM;;;;;N;;;;;
+E01EC;VARIATION SELECTOR-253;Mn;0;NSM;;;;;N;;;;;
+E01ED;VARIATION SELECTOR-254;Mn;0;NSM;;;;;N;;;;;
+E01EE;VARIATION SELECTOR-255;Mn;0;NSM;;;;;N;;;;;
+E01EF;VARIATION SELECTOR-256;Mn;0;NSM;;;;;N;;;;;
+F0000;<Plane 15 Private Use, First>;Co;0;L;;;;;N;;;;;
+FFFFD;<Plane 15 Private Use, Last>;Co;0;L;;;;;N;;;;;
+100000;<Plane 16 Private Use, First>;Co;0;L;;;;;N;;;;;
+10FFFD;<Plane 16 Private Use, Last>;Co;0;L;;;;;N;;;;;
diff --git a/scripts/u8_casemap/u8_casemap.pl b/scripts/u8_casemap/u8_casemap.pl
new file mode 100644
index 00000000..ccaf155d
--- /dev/null
+++ b/scripts/u8_casemap/u8_casemap.pl
@@ -0,0 +1,49 @@
+#!/usr/bin/perl
+
+# DeaDBeeF - ultimate music player for GNU/Linux systems with X11
+# Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+use utf8;
+
+open F, "<UnicodeData.txt" or die "failed to open UnicodeData.txt";
+
+print "struct u8_case_map_t {\n".
+ " const char *name;\n".
+ " const char *lower;\n".
+ "};\n".
+ "\%\%\n";
+
+while (<F>) {
+ if (/CAPITAL/ && /[^;];$/) {
+
+ /^([^;]+);/;
+ $uni_upper = $1;
+
+ /;([^;]+);$/;
+ $uni_lower = $1;
+
+ $u8_upper = chr(hex($uni_upper));
+ $u8_lower = chr(hex($uni_lower));
+
+ utf8::encode ($u8_upper);
+ utf8::encode ($u8_lower);
+
+ print "$u8_upper, \"$u8_lower\"\n";
+ }
+}
+
+close F;
diff --git a/u8_gperf.sh b/scripts/u8_gperf.sh
index 3ecffc3e..3ecffc3e 100755
--- a/u8_gperf.sh
+++ b/scripts/u8_gperf.sh
diff --git a/shortlicense b/shortlicense
index 92579bc6..09c9da8b 100644
--- a/shortlicense
+++ b/shortlicense
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
diff --git a/sj_to_unicode.h b/sj_to_unicode.h
new file mode 100644
index 00000000..15c0cde4
--- /dev/null
+++ b/sj_to_unicode.h
@@ -0,0 +1,6881 @@
+// this file was autogenerated from jis_x0208-1983.txt
+ 0x8140, 0x3000,
+ 0x8141, 0x3001,
+ 0x8142, 0x3002,
+ 0x8143, 0xFF0C,
+ 0x8144, 0xFF0E,
+ 0x8145, 0x30FB,
+ 0x8146, 0xFF1A,
+ 0x8147, 0xFF1B,
+ 0x8148, 0xFF1F,
+ 0x8149, 0xFF01,
+ 0x814A, 0x309B,
+ 0x814B, 0x309C,
+ 0x814C, 0x00B4,
+ 0x814D, 0xFF40,
+ 0x814E, 0x00A8,
+ 0x814F, 0xFF3E,
+ 0x8150, 0xFFE3,
+ 0x8151, 0xFF3F,
+ 0x8152, 0x30FD,
+ 0x8153, 0x30FE,
+ 0x8154, 0x309D,
+ 0x8155, 0x309E,
+ 0x8156, 0x3003,
+ 0x8157, 0x4EDD,
+ 0x8158, 0x3005,
+ 0x8159, 0x3006,
+ 0x815A, 0x3007,
+ 0x815B, 0x30FC,
+ 0x815C, 0x2015,
+ 0x815D, 0x2010,
+ 0x815E, 0xFF0F,
+ 0x815F, 0x005C,
+ 0x8160, 0x301C,
+ 0x8161, 0x2016,
+ 0x8162, 0xFF5C,
+ 0x8163, 0x2026,
+ 0x8164, 0x2025,
+ 0x8165, 0x2018,
+ 0x8166, 0x2019,
+ 0x8167, 0x201C,
+ 0x8168, 0x201D,
+ 0x8169, 0xFF08,
+ 0x816A, 0xFF09,
+ 0x816B, 0x3014,
+ 0x816C, 0x3015,
+ 0x816D, 0xFF3B,
+ 0x816E, 0xFF3D,
+ 0x816F, 0xFF5B,
+ 0x8170, 0xFF5D,
+ 0x8171, 0x3008,
+ 0x8172, 0x3009,
+ 0x8173, 0x300A,
+ 0x8174, 0x300B,
+ 0x8175, 0x300C,
+ 0x8176, 0x300D,
+ 0x8177, 0x300E,
+ 0x8178, 0x300F,
+ 0x8179, 0x3010,
+ 0x817A, 0x3011,
+ 0x817B, 0xFF0B,
+ 0x817C, 0x2212,
+ 0x817D, 0x00B1,
+ 0x817E, 0x00D7,
+ 0x8180, 0x00F7,
+ 0x8181, 0xFF1D,
+ 0x8182, 0x2260,
+ 0x8183, 0xFF1C,
+ 0x8184, 0xFF1E,
+ 0x8185, 0x2266,
+ 0x8186, 0x2267,
+ 0x8187, 0x221E,
+ 0x8188, 0x2234,
+ 0x8189, 0x2642,
+ 0x818A, 0x2640,
+ 0x818B, 0x00B0,
+ 0x818C, 0x2032,
+ 0x818D, 0x2033,
+ 0x818E, 0x2103,
+ 0x818F, 0xFFE5,
+ 0x8190, 0xFF04,
+ 0x8191, 0x00A2,
+ 0x8192, 0x00A3,
+ 0x8193, 0xFF05,
+ 0x8194, 0xFF03,
+ 0x8195, 0xFF06,
+ 0x8196, 0xFF0A,
+ 0x8197, 0xFF20,
+ 0x8198, 0x00A7,
+ 0x8199, 0x2606,
+ 0x819A, 0x2605,
+ 0x819B, 0x25CB,
+ 0x819C, 0x25CF,
+ 0x819D, 0x25CE,
+ 0x819E, 0x25C7,
+ 0x819F, 0x25C6,
+ 0x81A0, 0x25A1,
+ 0x81A1, 0x25A0,
+ 0x81A2, 0x25B3,
+ 0x81A3, 0x25B2,
+ 0x81A4, 0x25BD,
+ 0x81A5, 0x25BC,
+ 0x81A6, 0x203B,
+ 0x81A7, 0x3012,
+ 0x81A8, 0x2192,
+ 0x81A9, 0x2190,
+ 0x81AA, 0x2191,
+ 0x81AB, 0x2193,
+ 0x81AC, 0x3013,
+ 0x81B8, 0x2208,
+ 0x81B9, 0x220B,
+ 0x81BA, 0x2286,
+ 0x81BB, 0x2287,
+ 0x81BC, 0x2282,
+ 0x81BD, 0x2283,
+ 0x81BE, 0x222A,
+ 0x81BF, 0x2229,
+ 0x81C8, 0x2227,
+ 0x81C9, 0x2228,
+ 0x81CA, 0x00AC,
+ 0x81CB, 0x21D2,
+ 0x81CC, 0x21D4,
+ 0x81CD, 0x2200,
+ 0x81CE, 0x2203,
+ 0x81DA, 0x2220,
+ 0x81DB, 0x22A5,
+ 0x81DC, 0x2312,
+ 0x81DD, 0x2202,
+ 0x81DE, 0x2207,
+ 0x81DF, 0x2261,
+ 0x81E0, 0x2252,
+ 0x81E1, 0x226A,
+ 0x81E2, 0x226B,
+ 0x81E3, 0x221A,
+ 0x81E4, 0x223D,
+ 0x81E5, 0x221D,
+ 0x81E6, 0x2235,
+ 0x81E7, 0x222B,
+ 0x81E8, 0x222C,
+ 0x81F0, 0x212B,
+ 0x81F1, 0x2030,
+ 0x81F2, 0x266F,
+ 0x81F3, 0x266D,
+ 0x81F4, 0x266A,
+ 0x81F5, 0x2020,
+ 0x81F6, 0x2021,
+ 0x81F7, 0x00B6,
+ 0x81FC, 0x25EF,
+ 0x824F, 0xFF10,
+ 0x8250, 0xFF11,
+ 0x8251, 0xFF12,
+ 0x8252, 0xFF13,
+ 0x8253, 0xFF14,
+ 0x8254, 0xFF15,
+ 0x8255, 0xFF16,
+ 0x8256, 0xFF17,
+ 0x8257, 0xFF18,
+ 0x8258, 0xFF19,
+ 0x8260, 0xFF21,
+ 0x8261, 0xFF22,
+ 0x8262, 0xFF23,
+ 0x8263, 0xFF24,
+ 0x8264, 0xFF25,
+ 0x8265, 0xFF26,
+ 0x8266, 0xFF27,
+ 0x8267, 0xFF28,
+ 0x8268, 0xFF29,
+ 0x8269, 0xFF2A,
+ 0x826A, 0xFF2B,
+ 0x826B, 0xFF2C,
+ 0x826C, 0xFF2D,
+ 0x826D, 0xFF2E,
+ 0x826E, 0xFF2F,
+ 0x826F, 0xFF30,
+ 0x8270, 0xFF31,
+ 0x8271, 0xFF32,
+ 0x8272, 0xFF33,
+ 0x8273, 0xFF34,
+ 0x8274, 0xFF35,
+ 0x8275, 0xFF36,
+ 0x8276, 0xFF37,
+ 0x8277, 0xFF38,
+ 0x8278, 0xFF39,
+ 0x8279, 0xFF3A,
+ 0x8281, 0xFF41,
+ 0x8282, 0xFF42,
+ 0x8283, 0xFF43,
+ 0x8284, 0xFF44,
+ 0x8285, 0xFF45,
+ 0x8286, 0xFF46,
+ 0x8287, 0xFF47,
+ 0x8288, 0xFF48,
+ 0x8289, 0xFF49,
+ 0x828A, 0xFF4A,
+ 0x828B, 0xFF4B,
+ 0x828C, 0xFF4C,
+ 0x828D, 0xFF4D,
+ 0x828E, 0xFF4E,
+ 0x828F, 0xFF4F,
+ 0x8290, 0xFF50,
+ 0x8291, 0xFF51,
+ 0x8292, 0xFF52,
+ 0x8293, 0xFF53,
+ 0x8294, 0xFF54,
+ 0x8295, 0xFF55,
+ 0x8296, 0xFF56,
+ 0x8297, 0xFF57,
+ 0x8298, 0xFF58,
+ 0x8299, 0xFF59,
+ 0x829A, 0xFF5A,
+ 0x829F, 0x3041,
+ 0x82A0, 0x3042,
+ 0x82A1, 0x3043,
+ 0x82A2, 0x3044,
+ 0x82A3, 0x3045,
+ 0x82A4, 0x3046,
+ 0x82A5, 0x3047,
+ 0x82A6, 0x3048,
+ 0x82A7, 0x3049,
+ 0x82A8, 0x304A,
+ 0x82A9, 0x304B,
+ 0x82AA, 0x304C,
+ 0x82AB, 0x304D,
+ 0x82AC, 0x304E,
+ 0x82AD, 0x304F,
+ 0x82AE, 0x3050,
+ 0x82AF, 0x3051,
+ 0x82B0, 0x3052,
+ 0x82B1, 0x3053,
+ 0x82B2, 0x3054,
+ 0x82B3, 0x3055,
+ 0x82B4, 0x3056,
+ 0x82B5, 0x3057,
+ 0x82B6, 0x3058,
+ 0x82B7, 0x3059,
+ 0x82B8, 0x305A,
+ 0x82B9, 0x305B,
+ 0x82BA, 0x305C,
+ 0x82BB, 0x305D,
+ 0x82BC, 0x305E,
+ 0x82BD, 0x305F,
+ 0x82BE, 0x3060,
+ 0x82BF, 0x3061,
+ 0x82C0, 0x3062,
+ 0x82C1, 0x3063,
+ 0x82C2, 0x3064,
+ 0x82C3, 0x3065,
+ 0x82C4, 0x3066,
+ 0x82C5, 0x3067,
+ 0x82C6, 0x3068,
+ 0x82C7, 0x3069,
+ 0x82C8, 0x306A,
+ 0x82C9, 0x306B,
+ 0x82CA, 0x306C,
+ 0x82CB, 0x306D,
+ 0x82CC, 0x306E,
+ 0x82CD, 0x306F,
+ 0x82CE, 0x3070,
+ 0x82CF, 0x3071,
+ 0x82D0, 0x3072,
+ 0x82D1, 0x3073,
+ 0x82D2, 0x3074,
+ 0x82D3, 0x3075,
+ 0x82D4, 0x3076,
+ 0x82D5, 0x3077,
+ 0x82D6, 0x3078,
+ 0x82D7, 0x3079,
+ 0x82D8, 0x307A,
+ 0x82D9, 0x307B,
+ 0x82DA, 0x307C,
+ 0x82DB, 0x307D,
+ 0x82DC, 0x307E,
+ 0x82DD, 0x307F,
+ 0x82DE, 0x3080,
+ 0x82DF, 0x3081,
+ 0x82E0, 0x3082,
+ 0x82E1, 0x3083,
+ 0x82E2, 0x3084,
+ 0x82E3, 0x3085,
+ 0x82E4, 0x3086,
+ 0x82E5, 0x3087,
+ 0x82E6, 0x3088,
+ 0x82E7, 0x3089,
+ 0x82E8, 0x308A,
+ 0x82E9, 0x308B,
+ 0x82EA, 0x308C,
+ 0x82EB, 0x308D,
+ 0x82EC, 0x308E,
+ 0x82ED, 0x308F,
+ 0x82EE, 0x3090,
+ 0x82EF, 0x3091,
+ 0x82F0, 0x3092,
+ 0x82F1, 0x3093,
+ 0x8340, 0x30A1,
+ 0x8341, 0x30A2,
+ 0x8342, 0x30A3,
+ 0x8343, 0x30A4,
+ 0x8344, 0x30A5,
+ 0x8345, 0x30A6,
+ 0x8346, 0x30A7,
+ 0x8347, 0x30A8,
+ 0x8348, 0x30A9,
+ 0x8349, 0x30AA,
+ 0x834A, 0x30AB,
+ 0x834B, 0x30AC,
+ 0x834C, 0x30AD,
+ 0x834D, 0x30AE,
+ 0x834E, 0x30AF,
+ 0x834F, 0x30B0,
+ 0x8350, 0x30B1,
+ 0x8351, 0x30B2,
+ 0x8352, 0x30B3,
+ 0x8353, 0x30B4,
+ 0x8354, 0x30B5,
+ 0x8355, 0x30B6,
+ 0x8356, 0x30B7,
+ 0x8357, 0x30B8,
+ 0x8358, 0x30B9,
+ 0x8359, 0x30BA,
+ 0x835A, 0x30BB,
+ 0x835B, 0x30BC,
+ 0x835C, 0x30BD,
+ 0x835D, 0x30BE,
+ 0x835E, 0x30BF,
+ 0x835F, 0x30C0,
+ 0x8360, 0x30C1,
+ 0x8361, 0x30C2,
+ 0x8362, 0x30C3,
+ 0x8363, 0x30C4,
+ 0x8364, 0x30C5,
+ 0x8365, 0x30C6,
+ 0x8366, 0x30C7,
+ 0x8367, 0x30C8,
+ 0x8368, 0x30C9,
+ 0x8369, 0x30CA,
+ 0x836A, 0x30CB,
+ 0x836B, 0x30CC,
+ 0x836C, 0x30CD,
+ 0x836D, 0x30CE,
+ 0x836E, 0x30CF,
+ 0x836F, 0x30D0,
+ 0x8370, 0x30D1,
+ 0x8371, 0x30D2,
+ 0x8372, 0x30D3,
+ 0x8373, 0x30D4,
+ 0x8374, 0x30D5,
+ 0x8375, 0x30D6,
+ 0x8376, 0x30D7,
+ 0x8377, 0x30D8,
+ 0x8378, 0x30D9,
+ 0x8379, 0x30DA,
+ 0x837A, 0x30DB,
+ 0x837B, 0x30DC,
+ 0x837C, 0x30DD,
+ 0x837D, 0x30DE,
+ 0x837E, 0x30DF,
+ 0x8380, 0x30E0,
+ 0x8381, 0x30E1,
+ 0x8382, 0x30E2,
+ 0x8383, 0x30E3,
+ 0x8384, 0x30E4,
+ 0x8385, 0x30E5,
+ 0x8386, 0x30E6,
+ 0x8387, 0x30E7,
+ 0x8388, 0x30E8,
+ 0x8389, 0x30E9,
+ 0x838A, 0x30EA,
+ 0x838B, 0x30EB,
+ 0x838C, 0x30EC,
+ 0x838D, 0x30ED,
+ 0x838E, 0x30EE,
+ 0x838F, 0x30EF,
+ 0x8390, 0x30F0,
+ 0x8391, 0x30F1,
+ 0x8392, 0x30F2,
+ 0x8393, 0x30F3,
+ 0x8394, 0x30F4,
+ 0x8395, 0x30F5,
+ 0x8396, 0x30F6,
+ 0x839F, 0x0391,
+ 0x83A0, 0x0392,
+ 0x83A1, 0x0393,
+ 0x83A2, 0x0394,
+ 0x83A3, 0x0395,
+ 0x83A4, 0x0396,
+ 0x83A5, 0x0397,
+ 0x83A6, 0x0398,
+ 0x83A7, 0x0399,
+ 0x83A8, 0x039A,
+ 0x83A9, 0x039B,
+ 0x83AA, 0x039C,
+ 0x83AB, 0x039D,
+ 0x83AC, 0x039E,
+ 0x83AD, 0x039F,
+ 0x83AE, 0x03A0,
+ 0x83AF, 0x03A1,
+ 0x83B0, 0x03A3,
+ 0x83B1, 0x03A4,
+ 0x83B2, 0x03A5,
+ 0x83B3, 0x03A6,
+ 0x83B4, 0x03A7,
+ 0x83B5, 0x03A8,
+ 0x83B6, 0x03A9,
+ 0x83BF, 0x03B1,
+ 0x83C0, 0x03B2,
+ 0x83C1, 0x03B3,
+ 0x83C2, 0x03B4,
+ 0x83C3, 0x03B5,
+ 0x83C4, 0x03B6,
+ 0x83C5, 0x03B7,
+ 0x83C6, 0x03B8,
+ 0x83C7, 0x03B9,
+ 0x83C8, 0x03BA,
+ 0x83C9, 0x03BB,
+ 0x83CA, 0x03BC,
+ 0x83CB, 0x03BD,
+ 0x83CC, 0x03BE,
+ 0x83CD, 0x03BF,
+ 0x83CE, 0x03C0,
+ 0x83CF, 0x03C1,
+ 0x83D0, 0x03C3,
+ 0x83D1, 0x03C4,
+ 0x83D2, 0x03C5,
+ 0x83D3, 0x03C6,
+ 0x83D4, 0x03C7,
+ 0x83D5, 0x03C8,
+ 0x83D6, 0x03C9,
+ 0x8440, 0x0410,
+ 0x8441, 0x0411,
+ 0x8442, 0x0412,
+ 0x8443, 0x0413,
+ 0x8444, 0x0414,
+ 0x8445, 0x0415,
+ 0x8446, 0x0401,
+ 0x8447, 0x0416,
+ 0x8448, 0x0417,
+ 0x8449, 0x0418,
+ 0x844A, 0x0419,
+ 0x844B, 0x041A,
+ 0x844C, 0x041B,
+ 0x844D, 0x041C,
+ 0x844E, 0x041D,
+ 0x844F, 0x041E,
+ 0x8450, 0x041F,
+ 0x8451, 0x0420,
+ 0x8452, 0x0421,
+ 0x8453, 0x0422,
+ 0x8454, 0x0423,
+ 0x8455, 0x0424,
+ 0x8456, 0x0425,
+ 0x8457, 0x0426,
+ 0x8458, 0x0427,
+ 0x8459, 0x0428,
+ 0x845A, 0x0429,
+ 0x845B, 0x042A,
+ 0x845C, 0x042B,
+ 0x845D, 0x042C,
+ 0x845E, 0x042D,
+ 0x845F, 0x042E,
+ 0x8460, 0x042F,
+ 0x8470, 0x0430,
+ 0x8471, 0x0431,
+ 0x8472, 0x0432,
+ 0x8473, 0x0433,
+ 0x8474, 0x0434,
+ 0x8475, 0x0435,
+ 0x8476, 0x0451,
+ 0x8477, 0x0436,
+ 0x8478, 0x0437,
+ 0x8479, 0x0438,
+ 0x847A, 0x0439,
+ 0x847B, 0x043A,
+ 0x847C, 0x043B,
+ 0x847D, 0x043C,
+ 0x847E, 0x043D,
+ 0x8480, 0x043E,
+ 0x8481, 0x043F,
+ 0x8482, 0x0440,
+ 0x8483, 0x0441,
+ 0x8484, 0x0442,
+ 0x8485, 0x0443,
+ 0x8486, 0x0444,
+ 0x8487, 0x0445,
+ 0x8488, 0x0446,
+ 0x8489, 0x0447,
+ 0x848A, 0x0448,
+ 0x848B, 0x0449,
+ 0x848C, 0x044A,
+ 0x848D, 0x044B,
+ 0x848E, 0x044C,
+ 0x848F, 0x044D,
+ 0x8490, 0x044E,
+ 0x8491, 0x044F,
+ 0x849F, 0x2500,
+ 0x84A0, 0x2502,
+ 0x84A1, 0x250C,
+ 0x84A2, 0x2510,
+ 0x84A3, 0x2518,
+ 0x84A4, 0x2514,
+ 0x84A5, 0x251C,
+ 0x84A6, 0x252C,
+ 0x84A7, 0x2524,
+ 0x84A8, 0x2534,
+ 0x84A9, 0x253C,
+ 0x84AA, 0x2501,
+ 0x84AB, 0x2503,
+ 0x84AC, 0x250F,
+ 0x84AD, 0x2513,
+ 0x84AE, 0x251B,
+ 0x84AF, 0x2517,
+ 0x84B0, 0x2523,
+ 0x84B1, 0x2533,
+ 0x84B2, 0x252B,
+ 0x84B3, 0x253B,
+ 0x84B4, 0x254B,
+ 0x84B5, 0x2520,
+ 0x84B6, 0x252F,
+ 0x84B7, 0x2528,
+ 0x84B8, 0x2537,
+ 0x84B9, 0x253F,
+ 0x84BA, 0x251D,
+ 0x84BB, 0x2530,
+ 0x84BC, 0x2525,
+ 0x84BD, 0x2538,
+ 0x84BE, 0x2542,
+ 0x889F, 0x4E9C,
+ 0x88A0, 0x5516,
+ 0x88A1, 0x5A03,
+ 0x88A2, 0x963F,
+ 0x88A3, 0x54C0,
+ 0x88A4, 0x611B,
+ 0x88A5, 0x6328,
+ 0x88A6, 0x59F6,
+ 0x88A7, 0x9022,
+ 0x88A8, 0x8475,
+ 0x88A9, 0x831C,
+ 0x88AA, 0x7A50,
+ 0x88AB, 0x60AA,
+ 0x88AC, 0x63E1,
+ 0x88AD, 0x6E25,
+ 0x88AE, 0x65ED,
+ 0x88AF, 0x8466,
+ 0x88B0, 0x82A6,
+ 0x88B1, 0x9BF5,
+ 0x88B2, 0x6893,
+ 0x88B3, 0x5727,
+ 0x88B4, 0x65A1,
+ 0x88B5, 0x6271,
+ 0x88B6, 0x5B9B,
+ 0x88B7, 0x59D0,
+ 0x88B8, 0x867B,
+ 0x88B9, 0x98F4,
+ 0x88BA, 0x7D62,
+ 0x88BB, 0x7DBE,
+ 0x88BC, 0x9B8E,
+ 0x88BD, 0x6216,
+ 0x88BE, 0x7C9F,
+ 0x88BF, 0x88B7,
+ 0x88C0, 0x5B89,
+ 0x88C1, 0x5EB5,
+ 0x88C2, 0x6309,
+ 0x88C3, 0x6697,
+ 0x88C4, 0x6848,
+ 0x88C5, 0x95C7,
+ 0x88C6, 0x978D,
+ 0x88C7, 0x674F,
+ 0x88C8, 0x4EE5,
+ 0x88C9, 0x4F0A,
+ 0x88CA, 0x4F4D,
+ 0x88CB, 0x4F9D,
+ 0x88CC, 0x5049,
+ 0x88CD, 0x56F2,
+ 0x88CE, 0x5937,
+ 0x88CF, 0x59D4,
+ 0x88D0, 0x5A01,
+ 0x88D1, 0x5C09,
+ 0x88D2, 0x60DF,
+ 0x88D3, 0x610F,
+ 0x88D4, 0x6170,
+ 0x88D5, 0x6613,
+ 0x88D6, 0x6905,
+ 0x88D7, 0x70BA,
+ 0x88D8, 0x754F,
+ 0x88D9, 0x7570,
+ 0x88DA, 0x79FB,
+ 0x88DB, 0x7DAD,
+ 0x88DC, 0x7DEF,
+ 0x88DD, 0x80C3,
+ 0x88DE, 0x840E,
+ 0x88DF, 0x8863,
+ 0x88E0, 0x8B02,
+ 0x88E1, 0x9055,
+ 0x88E2, 0x907A,
+ 0x88E3, 0x533B,
+ 0x88E4, 0x4E95,
+ 0x88E5, 0x4EA5,
+ 0x88E6, 0x57DF,
+ 0x88E7, 0x80B2,
+ 0x88E8, 0x90C1,
+ 0x88E9, 0x78EF,
+ 0x88EA, 0x4E00,
+ 0x88EB, 0x58F1,
+ 0x88EC, 0x6EA2,
+ 0x88ED, 0x9038,
+ 0x88EE, 0x7A32,
+ 0x88EF, 0x8328,
+ 0x88F0, 0x828B,
+ 0x88F1, 0x9C2F,
+ 0x88F2, 0x5141,
+ 0x88F3, 0x5370,
+ 0x88F4, 0x54BD,
+ 0x88F5, 0x54E1,
+ 0x88F6, 0x56E0,
+ 0x88F7, 0x59FB,
+ 0x88F8, 0x5F15,
+ 0x88F9, 0x98F2,
+ 0x88FA, 0x6DEB,
+ 0x88FB, 0x80E4,
+ 0x88FC, 0x852D,
+ 0x8940, 0x9662,
+ 0x8941, 0x9670,
+ 0x8942, 0x96A0,
+ 0x8943, 0x97FB,
+ 0x8944, 0x540B,
+ 0x8945, 0x53F3,
+ 0x8946, 0x5B87,
+ 0x8947, 0x70CF,
+ 0x8948, 0x7FBD,
+ 0x8949, 0x8FC2,
+ 0x894A, 0x96E8,
+ 0x894B, 0x536F,
+ 0x894C, 0x9D5C,
+ 0x894D, 0x7ABA,
+ 0x894E, 0x4E11,
+ 0x894F, 0x7893,
+ 0x8950, 0x81FC,
+ 0x8951, 0x6E26,
+ 0x8952, 0x5618,
+ 0x8953, 0x5504,
+ 0x8954, 0x6B1D,
+ 0x8955, 0x851A,
+ 0x8956, 0x9C3B,
+ 0x8957, 0x59E5,
+ 0x8958, 0x53A9,
+ 0x8959, 0x6D66,
+ 0x895A, 0x74DC,
+ 0x895B, 0x958F,
+ 0x895C, 0x5642,
+ 0x895D, 0x4E91,
+ 0x895E, 0x904B,
+ 0x895F, 0x96F2,
+ 0x8960, 0x834F,
+ 0x8961, 0x990C,
+ 0x8962, 0x53E1,
+ 0x8963, 0x55B6,
+ 0x8964, 0x5B30,
+ 0x8965, 0x5F71,
+ 0x8966, 0x6620,
+ 0x8967, 0x66F3,
+ 0x8968, 0x6804,
+ 0x8969, 0x6C38,
+ 0x896A, 0x6CF3,
+ 0x896B, 0x6D29,
+ 0x896C, 0x745B,
+ 0x896D, 0x76C8,
+ 0x896E, 0x7A4E,
+ 0x896F, 0x9834,
+ 0x8970, 0x82F1,
+ 0x8971, 0x885B,
+ 0x8972, 0x8A60,
+ 0x8973, 0x92ED,
+ 0x8974, 0x6DB2,
+ 0x8975, 0x75AB,
+ 0x8976, 0x76CA,
+ 0x8977, 0x99C5,
+ 0x8978, 0x60A6,
+ 0x8979, 0x8B01,
+ 0x897A, 0x8D8A,
+ 0x897B, 0x95B2,
+ 0x897C, 0x698E,
+ 0x897D, 0x53AD,
+ 0x897E, 0x5186,
+ 0x8980, 0x5712,
+ 0x8981, 0x5830,
+ 0x8982, 0x5944,
+ 0x8983, 0x5BB4,
+ 0x8984, 0x5EF6,
+ 0x8985, 0x6028,
+ 0x8986, 0x63A9,
+ 0x8987, 0x63F4,
+ 0x8988, 0x6CBF,
+ 0x8989, 0x6F14,
+ 0x898A, 0x708E,
+ 0x898B, 0x7114,
+ 0x898C, 0x7159,
+ 0x898D, 0x71D5,
+ 0x898E, 0x733F,
+ 0x898F, 0x7E01,
+ 0x8990, 0x8276,
+ 0x8991, 0x82D1,
+ 0x8992, 0x8597,
+ 0x8993, 0x9060,
+ 0x8994, 0x925B,
+ 0x8995, 0x9D1B,
+ 0x8996, 0x5869,
+ 0x8997, 0x65BC,
+ 0x8998, 0x6C5A,
+ 0x8999, 0x7525,
+ 0x899A, 0x51F9,
+ 0x899B, 0x592E,
+ 0x899C, 0x5965,
+ 0x899D, 0x5F80,
+ 0x899E, 0x5FDC,
+ 0x899F, 0x62BC,
+ 0x89A0, 0x65FA,
+ 0x89A1, 0x6A2A,
+ 0x89A2, 0x6B27,
+ 0x89A3, 0x6BB4,
+ 0x89A4, 0x738B,
+ 0x89A5, 0x7FC1,
+ 0x89A6, 0x8956,
+ 0x89A7, 0x9D2C,
+ 0x89A8, 0x9D0E,
+ 0x89A9, 0x9EC4,
+ 0x89AA, 0x5CA1,
+ 0x89AB, 0x6C96,
+ 0x89AC, 0x837B,
+ 0x89AD, 0x5104,
+ 0x89AE, 0x5C4B,
+ 0x89AF, 0x61B6,
+ 0x89B0, 0x81C6,
+ 0x89B1, 0x6876,
+ 0x89B2, 0x7261,
+ 0x89B3, 0x4E59,
+ 0x89B4, 0x4FFA,
+ 0x89B5, 0x5378,
+ 0x89B6, 0x6069,
+ 0x89B7, 0x6E29,
+ 0x89B8, 0x7A4F,
+ 0x89B9, 0x97F3,
+ 0x89BA, 0x4E0B,
+ 0x89BB, 0x5316,
+ 0x89BC, 0x4EEE,
+ 0x89BD, 0x4F55,
+ 0x89BE, 0x4F3D,
+ 0x89BF, 0x4FA1,
+ 0x89C0, 0x4F73,
+ 0x89C1, 0x52A0,
+ 0x89C2, 0x53EF,
+ 0x89C3, 0x5609,
+ 0x89C4, 0x590F,
+ 0x89C5, 0x5AC1,
+ 0x89C6, 0x5BB6,
+ 0x89C7, 0x5BE1,
+ 0x89C8, 0x79D1,
+ 0x89C9, 0x6687,
+ 0x89CA, 0x679C,
+ 0x89CB, 0x67B6,
+ 0x89CC, 0x6B4C,
+ 0x89CD, 0x6CB3,
+ 0x89CE, 0x706B,
+ 0x89CF, 0x73C2,
+ 0x89D0, 0x798D,
+ 0x89D1, 0x79BE,
+ 0x89D2, 0x7A3C,
+ 0x89D3, 0x7B87,
+ 0x89D4, 0x82B1,
+ 0x89D5, 0x82DB,
+ 0x89D6, 0x8304,
+ 0x89D7, 0x8377,
+ 0x89D8, 0x83EF,
+ 0x89D9, 0x83D3,
+ 0x89DA, 0x8766,
+ 0x89DB, 0x8AB2,
+ 0x89DC, 0x5629,
+ 0x89DD, 0x8CA8,
+ 0x89DE, 0x8FE6,
+ 0x89DF, 0x904E,
+ 0x89E0, 0x971E,
+ 0x89E1, 0x868A,
+ 0x89E2, 0x4FC4,
+ 0x89E3, 0x5CE8,
+ 0x89E4, 0x6211,
+ 0x89E5, 0x7259,
+ 0x89E6, 0x753B,
+ 0x89E7, 0x81E5,
+ 0x89E8, 0x82BD,
+ 0x89E9, 0x86FE,
+ 0x89EA, 0x8CC0,
+ 0x89EB, 0x96C5,
+ 0x89EC, 0x9913,
+ 0x89ED, 0x99D5,
+ 0x89EE, 0x4ECB,
+ 0x89EF, 0x4F1A,
+ 0x89F0, 0x89E3,
+ 0x89F1, 0x56DE,
+ 0x89F2, 0x584A,
+ 0x89F3, 0x58CA,
+ 0x89F4, 0x5EFB,
+ 0x89F5, 0x5FEB,
+ 0x89F6, 0x602A,
+ 0x89F7, 0x6094,
+ 0x89F8, 0x6062,
+ 0x89F9, 0x61D0,
+ 0x89FA, 0x6212,
+ 0x89FB, 0x62D0,
+ 0x89FC, 0x6539,
+ 0x8A40, 0x9B41,
+ 0x8A41, 0x6666,
+ 0x8A42, 0x68B0,
+ 0x8A43, 0x6D77,
+ 0x8A44, 0x7070,
+ 0x8A45, 0x754C,
+ 0x8A46, 0x7686,
+ 0x8A47, 0x7D75,
+ 0x8A48, 0x82A5,
+ 0x8A49, 0x87F9,
+ 0x8A4A, 0x958B,
+ 0x8A4B, 0x968E,
+ 0x8A4C, 0x8C9D,
+ 0x8A4D, 0x51F1,
+ 0x8A4E, 0x52BE,
+ 0x8A4F, 0x5916,
+ 0x8A50, 0x54B3,
+ 0x8A51, 0x5BB3,
+ 0x8A52, 0x5D16,
+ 0x8A53, 0x6168,
+ 0x8A54, 0x6982,
+ 0x8A55, 0x6DAF,
+ 0x8A56, 0x788D,
+ 0x8A57, 0x84CB,
+ 0x8A58, 0x8857,
+ 0x8A59, 0x8A72,
+ 0x8A5A, 0x93A7,
+ 0x8A5B, 0x9AB8,
+ 0x8A5C, 0x6D6C,
+ 0x8A5D, 0x99A8,
+ 0x8A5E, 0x86D9,
+ 0x8A5F, 0x57A3,
+ 0x8A60, 0x67FF,
+ 0x8A61, 0x86CE,
+ 0x8A62, 0x920E,
+ 0x8A63, 0x5283,
+ 0x8A64, 0x5687,
+ 0x8A65, 0x5404,
+ 0x8A66, 0x5ED3,
+ 0x8A67, 0x62E1,
+ 0x8A68, 0x64B9,
+ 0x8A69, 0x683C,
+ 0x8A6A, 0x6838,
+ 0x8A6B, 0x6BBB,
+ 0x8A6C, 0x7372,
+ 0x8A6D, 0x78BA,
+ 0x8A6E, 0x7A6B,
+ 0x8A6F, 0x899A,
+ 0x8A70, 0x89D2,
+ 0x8A71, 0x8D6B,
+ 0x8A72, 0x8F03,
+ 0x8A73, 0x90ED,
+ 0x8A74, 0x95A3,
+ 0x8A75, 0x9694,
+ 0x8A76, 0x9769,
+ 0x8A77, 0x5B66,
+ 0x8A78, 0x5CB3,
+ 0x8A79, 0x697D,
+ 0x8A7A, 0x984D,
+ 0x8A7B, 0x984E,
+ 0x8A7C, 0x639B,
+ 0x8A7D, 0x7B20,
+ 0x8A7E, 0x6A2B,
+ 0x8A80, 0x6A7F,
+ 0x8A81, 0x68B6,
+ 0x8A82, 0x9C0D,
+ 0x8A83, 0x6F5F,
+ 0x8A84, 0x5272,
+ 0x8A85, 0x559D,
+ 0x8A86, 0x6070,
+ 0x8A87, 0x62EC,
+ 0x8A88, 0x6D3B,
+ 0x8A89, 0x6E07,
+ 0x8A8A, 0x6ED1,
+ 0x8A8B, 0x845B,
+ 0x8A8C, 0x8910,
+ 0x8A8D, 0x8F44,
+ 0x8A8E, 0x4E14,
+ 0x8A8F, 0x9C39,
+ 0x8A90, 0x53F6,
+ 0x8A91, 0x691B,
+ 0x8A92, 0x6A3A,
+ 0x8A93, 0x9784,
+ 0x8A94, 0x682A,
+ 0x8A95, 0x515C,
+ 0x8A96, 0x7AC3,
+ 0x8A97, 0x84B2,
+ 0x8A98, 0x91DC,
+ 0x8A99, 0x938C,
+ 0x8A9A, 0x565B,
+ 0x8A9B, 0x9D28,
+ 0x8A9C, 0x6822,
+ 0x8A9D, 0x8305,
+ 0x8A9E, 0x8431,
+ 0x8A9F, 0x7CA5,
+ 0x8AA0, 0x5208,
+ 0x8AA1, 0x82C5,
+ 0x8AA2, 0x74E6,
+ 0x8AA3, 0x4E7E,
+ 0x8AA4, 0x4F83,
+ 0x8AA5, 0x51A0,
+ 0x8AA6, 0x5BD2,
+ 0x8AA7, 0x520A,
+ 0x8AA8, 0x52D8,
+ 0x8AA9, 0x52E7,
+ 0x8AAA, 0x5DFB,
+ 0x8AAB, 0x559A,
+ 0x8AAC, 0x582A,
+ 0x8AAD, 0x59E6,
+ 0x8AAE, 0x5B8C,
+ 0x8AAF, 0x5B98,
+ 0x8AB0, 0x5BDB,
+ 0x8AB1, 0x5E72,
+ 0x8AB2, 0x5E79,
+ 0x8AB3, 0x60A3,
+ 0x8AB4, 0x611F,
+ 0x8AB5, 0x6163,
+ 0x8AB6, 0x61BE,
+ 0x8AB7, 0x63DB,
+ 0x8AB8, 0x6562,
+ 0x8AB9, 0x67D1,
+ 0x8ABA, 0x6853,
+ 0x8ABB, 0x68FA,
+ 0x8ABC, 0x6B3E,
+ 0x8ABD, 0x6B53,
+ 0x8ABE, 0x6C57,
+ 0x8ABF, 0x6F22,
+ 0x8AC0, 0x6F97,
+ 0x8AC1, 0x6F45,
+ 0x8AC2, 0x74B0,
+ 0x8AC3, 0x7518,
+ 0x8AC4, 0x76E3,
+ 0x8AC5, 0x770B,
+ 0x8AC6, 0x7AFF,
+ 0x8AC7, 0x7BA1,
+ 0x8AC8, 0x7C21,
+ 0x8AC9, 0x7DE9,
+ 0x8ACA, 0x7F36,
+ 0x8ACB, 0x7FF0,
+ 0x8ACC, 0x809D,
+ 0x8ACD, 0x8266,
+ 0x8ACE, 0x839E,
+ 0x8ACF, 0x89B3,
+ 0x8AD0, 0x8ACC,
+ 0x8AD1, 0x8CAB,
+ 0x8AD2, 0x9084,
+ 0x8AD3, 0x9451,
+ 0x8AD4, 0x9593,
+ 0x8AD5, 0x9591,
+ 0x8AD6, 0x95A2,
+ 0x8AD7, 0x9665,
+ 0x8AD8, 0x97D3,
+ 0x8AD9, 0x9928,
+ 0x8ADA, 0x8218,
+ 0x8ADB, 0x4E38,
+ 0x8ADC, 0x542B,
+ 0x8ADD, 0x5CB8,
+ 0x8ADE, 0x5DCC,
+ 0x8ADF, 0x73A9,
+ 0x8AE0, 0x764C,
+ 0x8AE1, 0x773C,
+ 0x8AE2, 0x5CA9,
+ 0x8AE3, 0x7FEB,
+ 0x8AE4, 0x8D0B,
+ 0x8AE5, 0x96C1,
+ 0x8AE6, 0x9811,
+ 0x8AE7, 0x9854,
+ 0x8AE8, 0x9858,
+ 0x8AE9, 0x4F01,
+ 0x8AEA, 0x4F0E,
+ 0x8AEB, 0x5371,
+ 0x8AEC, 0x559C,
+ 0x8AED, 0x5668,
+ 0x8AEE, 0x57FA,
+ 0x8AEF, 0x5947,
+ 0x8AF0, 0x5B09,
+ 0x8AF1, 0x5BC4,
+ 0x8AF2, 0x5C90,
+ 0x8AF3, 0x5E0C,
+ 0x8AF4, 0x5E7E,
+ 0x8AF5, 0x5FCC,
+ 0x8AF6, 0x63EE,
+ 0x8AF7, 0x673A,
+ 0x8AF8, 0x65D7,
+ 0x8AF9, 0x65E2,
+ 0x8AFA, 0x671F,
+ 0x8AFB, 0x68CB,
+ 0x8AFC, 0x68C4,
+ 0x8B40, 0x6A5F,
+ 0x8B41, 0x5E30,
+ 0x8B42, 0x6BC5,
+ 0x8B43, 0x6C17,
+ 0x8B44, 0x6C7D,
+ 0x8B45, 0x757F,
+ 0x8B46, 0x7948,
+ 0x8B47, 0x5B63,
+ 0x8B48, 0x7A00,
+ 0x8B49, 0x7D00,
+ 0x8B4A, 0x5FBD,
+ 0x8B4B, 0x898F,
+ 0x8B4C, 0x8A18,
+ 0x8B4D, 0x8CB4,
+ 0x8B4E, 0x8D77,
+ 0x8B4F, 0x8ECC,
+ 0x8B50, 0x8F1D,
+ 0x8B51, 0x98E2,
+ 0x8B52, 0x9A0E,
+ 0x8B53, 0x9B3C,
+ 0x8B54, 0x4E80,
+ 0x8B55, 0x507D,
+ 0x8B56, 0x5100,
+ 0x8B57, 0x5993,
+ 0x8B58, 0x5B9C,
+ 0x8B59, 0x622F,
+ 0x8B5A, 0x6280,
+ 0x8B5B, 0x64EC,
+ 0x8B5C, 0x6B3A,
+ 0x8B5D, 0x72A0,
+ 0x8B5E, 0x7591,
+ 0x8B5F, 0x7947,
+ 0x8B60, 0x7FA9,
+ 0x8B61, 0x87FB,
+ 0x8B62, 0x8ABC,
+ 0x8B63, 0x8B70,
+ 0x8B64, 0x63AC,
+ 0x8B65, 0x83CA,
+ 0x8B66, 0x97A0,
+ 0x8B67, 0x5409,
+ 0x8B68, 0x5403,
+ 0x8B69, 0x55AB,
+ 0x8B6A, 0x6854,
+ 0x8B6B, 0x6A58,
+ 0x8B6C, 0x8A70,
+ 0x8B6D, 0x7827,
+ 0x8B6E, 0x6775,
+ 0x8B6F, 0x9ECD,
+ 0x8B70, 0x5374,
+ 0x8B71, 0x5BA2,
+ 0x8B72, 0x811A,
+ 0x8B73, 0x8650,
+ 0x8B74, 0x9006,
+ 0x8B75, 0x4E18,
+ 0x8B76, 0x4E45,
+ 0x8B77, 0x4EC7,
+ 0x8B78, 0x4F11,
+ 0x8B79, 0x53CA,
+ 0x8B7A, 0x5438,
+ 0x8B7B, 0x5BAE,
+ 0x8B7C, 0x5F13,
+ 0x8B7D, 0x6025,
+ 0x8B7E, 0x6551,
+ 0x8B80, 0x673D,
+ 0x8B81, 0x6C42,
+ 0x8B82, 0x6C72,
+ 0x8B83, 0x6CE3,
+ 0x8B84, 0x7078,
+ 0x8B85, 0x7403,
+ 0x8B86, 0x7A76,
+ 0x8B87, 0x7AAE,
+ 0x8B88, 0x7B08,
+ 0x8B89, 0x7D1A,
+ 0x8B8A, 0x7CFE,
+ 0x8B8B, 0x7D66,
+ 0x8B8C, 0x65E7,
+ 0x8B8D, 0x725B,
+ 0x8B8E, 0x53BB,
+ 0x8B8F, 0x5C45,
+ 0x8B90, 0x5DE8,
+ 0x8B91, 0x62D2,
+ 0x8B92, 0x62E0,
+ 0x8B93, 0x6319,
+ 0x8B94, 0x6E20,
+ 0x8B95, 0x865A,
+ 0x8B96, 0x8A31,
+ 0x8B97, 0x8DDD,
+ 0x8B98, 0x92F8,
+ 0x8B99, 0x6F01,
+ 0x8B9A, 0x79A6,
+ 0x8B9B, 0x9B5A,
+ 0x8B9C, 0x4EA8,
+ 0x8B9D, 0x4EAB,
+ 0x8B9E, 0x4EAC,
+ 0x8B9F, 0x4F9B,
+ 0x8BA0, 0x4FA0,
+ 0x8BA1, 0x50D1,
+ 0x8BA2, 0x5147,
+ 0x8BA3, 0x7AF6,
+ 0x8BA4, 0x5171,
+ 0x8BA5, 0x51F6,
+ 0x8BA6, 0x5354,
+ 0x8BA7, 0x5321,
+ 0x8BA8, 0x537F,
+ 0x8BA9, 0x53EB,
+ 0x8BAA, 0x55AC,
+ 0x8BAB, 0x5883,
+ 0x8BAC, 0x5CE1,
+ 0x8BAD, 0x5F37,
+ 0x8BAE, 0x5F4A,
+ 0x8BAF, 0x602F,
+ 0x8BB0, 0x6050,
+ 0x8BB1, 0x606D,
+ 0x8BB2, 0x631F,
+ 0x8BB3, 0x6559,
+ 0x8BB4, 0x6A4B,
+ 0x8BB5, 0x6CC1,
+ 0x8BB6, 0x72C2,
+ 0x8BB7, 0x72ED,
+ 0x8BB8, 0x77EF,
+ 0x8BB9, 0x80F8,
+ 0x8BBA, 0x8105,
+ 0x8BBB, 0x8208,
+ 0x8BBC, 0x854E,
+ 0x8BBD, 0x90F7,
+ 0x8BBE, 0x93E1,
+ 0x8BBF, 0x97FF,
+ 0x8BC0, 0x9957,
+ 0x8BC1, 0x9A5A,
+ 0x8BC2, 0x4EF0,
+ 0x8BC3, 0x51DD,
+ 0x8BC4, 0x5C2D,
+ 0x8BC5, 0x6681,
+ 0x8BC6, 0x696D,
+ 0x8BC7, 0x5C40,
+ 0x8BC8, 0x66F2,
+ 0x8BC9, 0x6975,
+ 0x8BCA, 0x7389,
+ 0x8BCB, 0x6850,
+ 0x8BCC, 0x7C81,
+ 0x8BCD, 0x50C5,
+ 0x8BCE, 0x52E4,
+ 0x8BCF, 0x5747,
+ 0x8BD0, 0x5DFE,
+ 0x8BD1, 0x9326,
+ 0x8BD2, 0x65A4,
+ 0x8BD3, 0x6B23,
+ 0x8BD4, 0x6B3D,
+ 0x8BD5, 0x7434,
+ 0x8BD6, 0x7981,
+ 0x8BD7, 0x79BD,
+ 0x8BD8, 0x7B4B,
+ 0x8BD9, 0x7DCA,
+ 0x8BDA, 0x82B9,
+ 0x8BDB, 0x83CC,
+ 0x8BDC, 0x887F,
+ 0x8BDD, 0x895F,
+ 0x8BDE, 0x8B39,
+ 0x8BDF, 0x8FD1,
+ 0x8BE0, 0x91D1,
+ 0x8BE1, 0x541F,
+ 0x8BE2, 0x9280,
+ 0x8BE3, 0x4E5D,
+ 0x8BE4, 0x5036,
+ 0x8BE5, 0x53E5,
+ 0x8BE6, 0x533A,
+ 0x8BE7, 0x72D7,
+ 0x8BE8, 0x7396,
+ 0x8BE9, 0x77E9,
+ 0x8BEA, 0x82E6,
+ 0x8BEB, 0x8EAF,
+ 0x8BEC, 0x99C6,
+ 0x8BED, 0x99C8,
+ 0x8BEE, 0x99D2,
+ 0x8BEF, 0x5177,
+ 0x8BF0, 0x611A,
+ 0x8BF1, 0x865E,
+ 0x8BF2, 0x55B0,
+ 0x8BF3, 0x7A7A,
+ 0x8BF4, 0x5076,
+ 0x8BF5, 0x5BD3,
+ 0x8BF6, 0x9047,
+ 0x8BF7, 0x9685,
+ 0x8BF8, 0x4E32,
+ 0x8BF9, 0x6ADB,
+ 0x8BFA, 0x91E7,
+ 0x8BFB, 0x5C51,
+ 0x8BFC, 0x5C48,
+ 0x8C40, 0x6398,
+ 0x8C41, 0x7A9F,
+ 0x8C42, 0x6C93,
+ 0x8C43, 0x9774,
+ 0x8C44, 0x8F61,
+ 0x8C45, 0x7AAA,
+ 0x8C46, 0x718A,
+ 0x8C47, 0x9688,
+ 0x8C48, 0x7C82,
+ 0x8C49, 0x6817,
+ 0x8C4A, 0x7E70,
+ 0x8C4B, 0x6851,
+ 0x8C4C, 0x936C,
+ 0x8C4D, 0x52F2,
+ 0x8C4E, 0x541B,
+ 0x8C4F, 0x85AB,
+ 0x8C50, 0x8A13,
+ 0x8C51, 0x7FA4,
+ 0x8C52, 0x8ECD,
+ 0x8C53, 0x90E1,
+ 0x8C54, 0x5366,
+ 0x8C55, 0x8888,
+ 0x8C56, 0x7941,
+ 0x8C57, 0x4FC2,
+ 0x8C58, 0x50BE,
+ 0x8C59, 0x5211,
+ 0x8C5A, 0x5144,
+ 0x8C5B, 0x5553,
+ 0x8C5C, 0x572D,
+ 0x8C5D, 0x73EA,
+ 0x8C5E, 0x578B,
+ 0x8C5F, 0x5951,
+ 0x8C60, 0x5F62,
+ 0x8C61, 0x5F84,
+ 0x8C62, 0x6075,
+ 0x8C63, 0x6176,
+ 0x8C64, 0x6167,
+ 0x8C65, 0x61A9,
+ 0x8C66, 0x63B2,
+ 0x8C67, 0x643A,
+ 0x8C68, 0x656C,
+ 0x8C69, 0x666F,
+ 0x8C6A, 0x6842,
+ 0x8C6B, 0x6E13,
+ 0x8C6C, 0x7566,
+ 0x8C6D, 0x7A3D,
+ 0x8C6E, 0x7CFB,
+ 0x8C6F, 0x7D4C,
+ 0x8C70, 0x7D99,
+ 0x8C71, 0x7E4B,
+ 0x8C72, 0x7F6B,
+ 0x8C73, 0x830E,
+ 0x8C74, 0x834A,
+ 0x8C75, 0x86CD,
+ 0x8C76, 0x8A08,
+ 0x8C77, 0x8A63,
+ 0x8C78, 0x8B66,
+ 0x8C79, 0x8EFD,
+ 0x8C7A, 0x981A,
+ 0x8C7B, 0x9D8F,
+ 0x8C7C, 0x82B8,
+ 0x8C7D, 0x8FCE,
+ 0x8C7E, 0x9BE8,
+ 0x8C80, 0x5287,
+ 0x8C81, 0x621F,
+ 0x8C82, 0x6483,
+ 0x8C83, 0x6FC0,
+ 0x8C84, 0x9699,
+ 0x8C85, 0x6841,
+ 0x8C86, 0x5091,
+ 0x8C87, 0x6B20,
+ 0x8C88, 0x6C7A,
+ 0x8C89, 0x6F54,
+ 0x8C8A, 0x7A74,
+ 0x8C8B, 0x7D50,
+ 0x8C8C, 0x8840,
+ 0x8C8D, 0x8A23,
+ 0x8C8E, 0x6708,
+ 0x8C8F, 0x4EF6,
+ 0x8C90, 0x5039,
+ 0x8C91, 0x5026,
+ 0x8C92, 0x5065,
+ 0x8C93, 0x517C,
+ 0x8C94, 0x5238,
+ 0x8C95, 0x5263,
+ 0x8C96, 0x55A7,
+ 0x8C97, 0x570F,
+ 0x8C98, 0x5805,
+ 0x8C99, 0x5ACC,
+ 0x8C9A, 0x5EFA,
+ 0x8C9B, 0x61B2,
+ 0x8C9C, 0x61F8,
+ 0x8C9D, 0x62F3,
+ 0x8C9E, 0x6372,
+ 0x8C9F, 0x691C,
+ 0x8CA0, 0x6A29,
+ 0x8CA1, 0x727D,
+ 0x8CA2, 0x72AC,
+ 0x8CA3, 0x732E,
+ 0x8CA4, 0x7814,
+ 0x8CA5, 0x786F,
+ 0x8CA6, 0x7D79,
+ 0x8CA7, 0x770C,
+ 0x8CA8, 0x80A9,
+ 0x8CA9, 0x898B,
+ 0x8CAA, 0x8B19,
+ 0x8CAB, 0x8CE2,
+ 0x8CAC, 0x8ED2,
+ 0x8CAD, 0x9063,
+ 0x8CAE, 0x9375,
+ 0x8CAF, 0x967A,
+ 0x8CB0, 0x9855,
+ 0x8CB1, 0x9A13,
+ 0x8CB2, 0x9E78,
+ 0x8CB3, 0x5143,
+ 0x8CB4, 0x539F,
+ 0x8CB5, 0x53B3,
+ 0x8CB6, 0x5E7B,
+ 0x8CB7, 0x5F26,
+ 0x8CB8, 0x6E1B,
+ 0x8CB9, 0x6E90,
+ 0x8CBA, 0x7384,
+ 0x8CBB, 0x73FE,
+ 0x8CBC, 0x7D43,
+ 0x8CBD, 0x8237,
+ 0x8CBE, 0x8A00,
+ 0x8CBF, 0x8AFA,
+ 0x8CC0, 0x9650,
+ 0x8CC1, 0x4E4E,
+ 0x8CC2, 0x500B,
+ 0x8CC3, 0x53E4,
+ 0x8CC4, 0x547C,
+ 0x8CC5, 0x56FA,
+ 0x8CC6, 0x59D1,
+ 0x8CC7, 0x5B64,
+ 0x8CC8, 0x5DF1,
+ 0x8CC9, 0x5EAB,
+ 0x8CCA, 0x5F27,
+ 0x8CCB, 0x6238,
+ 0x8CCC, 0x6545,
+ 0x8CCD, 0x67AF,
+ 0x8CCE, 0x6E56,
+ 0x8CCF, 0x72D0,
+ 0x8CD0, 0x7CCA,
+ 0x8CD1, 0x88B4,
+ 0x8CD2, 0x80A1,
+ 0x8CD3, 0x80E1,
+ 0x8CD4, 0x83F0,
+ 0x8CD5, 0x864E,
+ 0x8CD6, 0x8A87,
+ 0x8CD7, 0x8DE8,
+ 0x8CD8, 0x9237,
+ 0x8CD9, 0x96C7,
+ 0x8CDA, 0x9867,
+ 0x8CDB, 0x9F13,
+ 0x8CDC, 0x4E94,
+ 0x8CDD, 0x4E92,
+ 0x8CDE, 0x4F0D,
+ 0x8CDF, 0x5348,
+ 0x8CE0, 0x5449,
+ 0x8CE1, 0x543E,
+ 0x8CE2, 0x5A2F,
+ 0x8CE3, 0x5F8C,
+ 0x8CE4, 0x5FA1,
+ 0x8CE5, 0x609F,
+ 0x8CE6, 0x68A7,
+ 0x8CE7, 0x6A8E,
+ 0x8CE8, 0x745A,
+ 0x8CE9, 0x7881,
+ 0x8CEA, 0x8A9E,
+ 0x8CEB, 0x8AA4,
+ 0x8CEC, 0x8B77,
+ 0x8CED, 0x9190,
+ 0x8CEE, 0x4E5E,
+ 0x8CEF, 0x9BC9,
+ 0x8CF0, 0x4EA4,
+ 0x8CF1, 0x4F7C,
+ 0x8CF2, 0x4FAF,
+ 0x8CF3, 0x5019,
+ 0x8CF4, 0x5016,
+ 0x8CF5, 0x5149,
+ 0x8CF6, 0x516C,
+ 0x8CF7, 0x529F,
+ 0x8CF8, 0x52B9,
+ 0x8CF9, 0x52FE,
+ 0x8CFA, 0x539A,
+ 0x8CFB, 0x53E3,
+ 0x8CFC, 0x5411,
+ 0x8D40, 0x540E,
+ 0x8D41, 0x5589,
+ 0x8D42, 0x5751,
+ 0x8D43, 0x57A2,
+ 0x8D44, 0x597D,
+ 0x8D45, 0x5B54,
+ 0x8D46, 0x5B5D,
+ 0x8D47, 0x5B8F,
+ 0x8D48, 0x5DE5,
+ 0x8D49, 0x5DE7,
+ 0x8D4A, 0x5DF7,
+ 0x8D4B, 0x5E78,
+ 0x8D4C, 0x5E83,
+ 0x8D4D, 0x5E9A,
+ 0x8D4E, 0x5EB7,
+ 0x8D4F, 0x5F18,
+ 0x8D50, 0x6052,
+ 0x8D51, 0x614C,
+ 0x8D52, 0x6297,
+ 0x8D53, 0x62D8,
+ 0x8D54, 0x63A7,
+ 0x8D55, 0x653B,
+ 0x8D56, 0x6602,
+ 0x8D57, 0x6643,
+ 0x8D58, 0x66F4,
+ 0x8D59, 0x676D,
+ 0x8D5A, 0x6821,
+ 0x8D5B, 0x6897,
+ 0x8D5C, 0x69CB,
+ 0x8D5D, 0x6C5F,
+ 0x8D5E, 0x6D2A,
+ 0x8D5F, 0x6D69,
+ 0x8D60, 0x6E2F,
+ 0x8D61, 0x6E9D,
+ 0x8D62, 0x7532,
+ 0x8D63, 0x7687,
+ 0x8D64, 0x786C,
+ 0x8D65, 0x7A3F,
+ 0x8D66, 0x7CE0,
+ 0x8D67, 0x7D05,
+ 0x8D68, 0x7D18,
+ 0x8D69, 0x7D5E,
+ 0x8D6A, 0x7DB1,
+ 0x8D6B, 0x8015,
+ 0x8D6C, 0x8003,
+ 0x8D6D, 0x80AF,
+ 0x8D6E, 0x80B1,
+ 0x8D6F, 0x8154,
+ 0x8D70, 0x818F,
+ 0x8D71, 0x822A,
+ 0x8D72, 0x8352,
+ 0x8D73, 0x884C,
+ 0x8D74, 0x8861,
+ 0x8D75, 0x8B1B,
+ 0x8D76, 0x8CA2,
+ 0x8D77, 0x8CFC,
+ 0x8D78, 0x90CA,
+ 0x8D79, 0x9175,
+ 0x8D7A, 0x9271,
+ 0x8D7B, 0x783F,
+ 0x8D7C, 0x92FC,
+ 0x8D7D, 0x95A4,
+ 0x8D7E, 0x964D,
+ 0x8D80, 0x9805,
+ 0x8D81, 0x9999,
+ 0x8D82, 0x9AD8,
+ 0x8D83, 0x9D3B,
+ 0x8D84, 0x525B,
+ 0x8D85, 0x52AB,
+ 0x8D86, 0x53F7,
+ 0x8D87, 0x5408,
+ 0x8D88, 0x58D5,
+ 0x8D89, 0x62F7,
+ 0x8D8A, 0x6FE0,
+ 0x8D8B, 0x8C6A,
+ 0x8D8C, 0x8F5F,
+ 0x8D8D, 0x9EB9,
+ 0x8D8E, 0x514B,
+ 0x8D8F, 0x523B,
+ 0x8D90, 0x544A,
+ 0x8D91, 0x56FD,
+ 0x8D92, 0x7A40,
+ 0x8D93, 0x9177,
+ 0x8D94, 0x9D60,
+ 0x8D95, 0x9ED2,
+ 0x8D96, 0x7344,
+ 0x8D97, 0x6F09,
+ 0x8D98, 0x8170,
+ 0x8D99, 0x7511,
+ 0x8D9A, 0x5FFD,
+ 0x8D9B, 0x60DA,
+ 0x8D9C, 0x9AA8,
+ 0x8D9D, 0x72DB,
+ 0x8D9E, 0x8FBC,
+ 0x8D9F, 0x6B64,
+ 0x8DA0, 0x9803,
+ 0x8DA1, 0x4ECA,
+ 0x8DA2, 0x56F0,
+ 0x8DA3, 0x5764,
+ 0x8DA4, 0x58BE,
+ 0x8DA5, 0x5A5A,
+ 0x8DA6, 0x6068,
+ 0x8DA7, 0x61C7,
+ 0x8DA8, 0x660F,
+ 0x8DA9, 0x6606,
+ 0x8DAA, 0x6839,
+ 0x8DAB, 0x68B1,
+ 0x8DAC, 0x6DF7,
+ 0x8DAD, 0x75D5,
+ 0x8DAE, 0x7D3A,
+ 0x8DAF, 0x826E,
+ 0x8DB0, 0x9B42,
+ 0x8DB1, 0x4E9B,
+ 0x8DB2, 0x4F50,
+ 0x8DB3, 0x53C9,
+ 0x8DB4, 0x5506,
+ 0x8DB5, 0x5D6F,
+ 0x8DB6, 0x5DE6,
+ 0x8DB7, 0x5DEE,
+ 0x8DB8, 0x67FB,
+ 0x8DB9, 0x6C99,
+ 0x8DBA, 0x7473,
+ 0x8DBB, 0x7802,
+ 0x8DBC, 0x8A50,
+ 0x8DBD, 0x9396,
+ 0x8DBE, 0x88DF,
+ 0x8DBF, 0x5750,
+ 0x8DC0, 0x5EA7,
+ 0x8DC1, 0x632B,
+ 0x8DC2, 0x50B5,
+ 0x8DC3, 0x50AC,
+ 0x8DC4, 0x518D,
+ 0x8DC5, 0x6700,
+ 0x8DC6, 0x54C9,
+ 0x8DC7, 0x585E,
+ 0x8DC8, 0x59BB,
+ 0x8DC9, 0x5BB0,
+ 0x8DCA, 0x5F69,
+ 0x8DCB, 0x624D,
+ 0x8DCC, 0x63A1,
+ 0x8DCD, 0x683D,
+ 0x8DCE, 0x6B73,
+ 0x8DCF, 0x6E08,
+ 0x8DD0, 0x707D,
+ 0x8DD1, 0x91C7,
+ 0x8DD2, 0x7280,
+ 0x8DD3, 0x7815,
+ 0x8DD4, 0x7826,
+ 0x8DD5, 0x796D,
+ 0x8DD6, 0x658E,
+ 0x8DD7, 0x7D30,
+ 0x8DD8, 0x83DC,
+ 0x8DD9, 0x88C1,
+ 0x8DDA, 0x8F09,
+ 0x8DDB, 0x969B,
+ 0x8DDC, 0x5264,
+ 0x8DDD, 0x5728,
+ 0x8DDE, 0x6750,
+ 0x8DDF, 0x7F6A,
+ 0x8DE0, 0x8CA1,
+ 0x8DE1, 0x51B4,
+ 0x8DE2, 0x5742,
+ 0x8DE3, 0x962A,
+ 0x8DE4, 0x583A,
+ 0x8DE5, 0x698A,
+ 0x8DE6, 0x80B4,
+ 0x8DE7, 0x54B2,
+ 0x8DE8, 0x5D0E,
+ 0x8DE9, 0x57FC,
+ 0x8DEA, 0x7895,
+ 0x8DEB, 0x9DFA,
+ 0x8DEC, 0x4F5C,
+ 0x8DED, 0x524A,
+ 0x8DEE, 0x548B,
+ 0x8DEF, 0x643E,
+ 0x8DF0, 0x6628,
+ 0x8DF1, 0x6714,
+ 0x8DF2, 0x67F5,
+ 0x8DF3, 0x7A84,
+ 0x8DF4, 0x7B56,
+ 0x8DF5, 0x7D22,
+ 0x8DF6, 0x932F,
+ 0x8DF7, 0x685C,
+ 0x8DF8, 0x9BAD,
+ 0x8DF9, 0x7B39,
+ 0x8DFA, 0x5319,
+ 0x8DFB, 0x518A,
+ 0x8DFC, 0x5237,
+ 0x8E40, 0x5BDF,
+ 0x8E41, 0x62F6,
+ 0x8E42, 0x64AE,
+ 0x8E43, 0x64E6,
+ 0x8E44, 0x672D,
+ 0x8E45, 0x6BBA,
+ 0x8E46, 0x85A9,
+ 0x8E47, 0x96D1,
+ 0x8E48, 0x7690,
+ 0x8E49, 0x9BD6,
+ 0x8E4A, 0x634C,
+ 0x8E4B, 0x9306,
+ 0x8E4C, 0x9BAB,
+ 0x8E4D, 0x76BF,
+ 0x8E4E, 0x6652,
+ 0x8E4F, 0x4E09,
+ 0x8E50, 0x5098,
+ 0x8E51, 0x53C2,
+ 0x8E52, 0x5C71,
+ 0x8E53, 0x60E8,
+ 0x8E54, 0x6492,
+ 0x8E55, 0x6563,
+ 0x8E56, 0x685F,
+ 0x8E57, 0x71E6,
+ 0x8E58, 0x73CA,
+ 0x8E59, 0x7523,
+ 0x8E5A, 0x7B97,
+ 0x8E5B, 0x7E82,
+ 0x8E5C, 0x8695,
+ 0x8E5D, 0x8B83,
+ 0x8E5E, 0x8CDB,
+ 0x8E5F, 0x9178,
+ 0x8E60, 0x9910,
+ 0x8E61, 0x65AC,
+ 0x8E62, 0x66AB,
+ 0x8E63, 0x6B8B,
+ 0x8E64, 0x4ED5,
+ 0x8E65, 0x4ED4,
+ 0x8E66, 0x4F3A,
+ 0x8E67, 0x4F7F,
+ 0x8E68, 0x523A,
+ 0x8E69, 0x53F8,
+ 0x8E6A, 0x53F2,
+ 0x8E6B, 0x55E3,
+ 0x8E6C, 0x56DB,
+ 0x8E6D, 0x58EB,
+ 0x8E6E, 0x59CB,
+ 0x8E6F, 0x59C9,
+ 0x8E70, 0x59FF,
+ 0x8E71, 0x5B50,
+ 0x8E72, 0x5C4D,
+ 0x8E73, 0x5E02,
+ 0x8E74, 0x5E2B,
+ 0x8E75, 0x5FD7,
+ 0x8E76, 0x601D,
+ 0x8E77, 0x6307,
+ 0x8E78, 0x652F,
+ 0x8E79, 0x5B5C,
+ 0x8E7A, 0x65AF,
+ 0x8E7B, 0x65BD,
+ 0x8E7C, 0x65E8,
+ 0x8E7D, 0x679D,
+ 0x8E7E, 0x6B62,
+ 0x8E80, 0x6B7B,
+ 0x8E81, 0x6C0F,
+ 0x8E82, 0x7345,
+ 0x8E83, 0x7949,
+ 0x8E84, 0x79C1,
+ 0x8E85, 0x7CF8,
+ 0x8E86, 0x7D19,
+ 0x8E87, 0x7D2B,
+ 0x8E88, 0x80A2,
+ 0x8E89, 0x8102,
+ 0x8E8A, 0x81F3,
+ 0x8E8B, 0x8996,
+ 0x8E8C, 0x8A5E,
+ 0x8E8D, 0x8A69,
+ 0x8E8E, 0x8A66,
+ 0x8E8F, 0x8A8C,
+ 0x8E90, 0x8AEE,
+ 0x8E91, 0x8CC7,
+ 0x8E92, 0x8CDC,
+ 0x8E93, 0x96CC,
+ 0x8E94, 0x98FC,
+ 0x8E95, 0x6B6F,
+ 0x8E96, 0x4E8B,
+ 0x8E97, 0x4F3C,
+ 0x8E98, 0x4F8D,
+ 0x8E99, 0x5150,
+ 0x8E9A, 0x5B57,
+ 0x8E9B, 0x5BFA,
+ 0x8E9C, 0x6148,
+ 0x8E9D, 0x6301,
+ 0x8E9E, 0x6642,
+ 0x8E9F, 0x6B21,
+ 0x8EA0, 0x6ECB,
+ 0x8EA1, 0x6CBB,
+ 0x8EA2, 0x723E,
+ 0x8EA3, 0x74BD,
+ 0x8EA4, 0x75D4,
+ 0x8EA5, 0x78C1,
+ 0x8EA6, 0x793A,
+ 0x8EA7, 0x800C,
+ 0x8EA8, 0x8033,
+ 0x8EA9, 0x81EA,
+ 0x8EAA, 0x8494,
+ 0x8EAB, 0x8F9E,
+ 0x8EAC, 0x6C50,
+ 0x8EAD, 0x9E7F,
+ 0x8EAE, 0x5F0F,
+ 0x8EAF, 0x8B58,
+ 0x8EB0, 0x9D2B,
+ 0x8EB1, 0x7AFA,
+ 0x8EB2, 0x8EF8,
+ 0x8EB3, 0x5B8D,
+ 0x8EB4, 0x96EB,
+ 0x8EB5, 0x4E03,
+ 0x8EB6, 0x53F1,
+ 0x8EB7, 0x57F7,
+ 0x8EB8, 0x5931,
+ 0x8EB9, 0x5AC9,
+ 0x8EBA, 0x5BA4,
+ 0x8EBB, 0x6089,
+ 0x8EBC, 0x6E7F,
+ 0x8EBD, 0x6F06,
+ 0x8EBE, 0x75BE,
+ 0x8EBF, 0x8CEA,
+ 0x8EC0, 0x5B9F,
+ 0x8EC1, 0x8500,
+ 0x8EC2, 0x7BE0,
+ 0x8EC3, 0x5072,
+ 0x8EC4, 0x67F4,
+ 0x8EC5, 0x829D,
+ 0x8EC6, 0x5C61,
+ 0x8EC7, 0x854A,
+ 0x8EC8, 0x7E1E,
+ 0x8EC9, 0x820E,
+ 0x8ECA, 0x5199,
+ 0x8ECB, 0x5C04,
+ 0x8ECC, 0x6368,
+ 0x8ECD, 0x8D66,
+ 0x8ECE, 0x659C,
+ 0x8ECF, 0x716E,
+ 0x8ED0, 0x793E,
+ 0x8ED1, 0x7D17,
+ 0x8ED2, 0x8005,
+ 0x8ED3, 0x8B1D,
+ 0x8ED4, 0x8ECA,
+ 0x8ED5, 0x906E,
+ 0x8ED6, 0x86C7,
+ 0x8ED7, 0x90AA,
+ 0x8ED8, 0x501F,
+ 0x8ED9, 0x52FA,
+ 0x8EDA, 0x5C3A,
+ 0x8EDB, 0x6753,
+ 0x8EDC, 0x707C,
+ 0x8EDD, 0x7235,
+ 0x8EDE, 0x914C,
+ 0x8EDF, 0x91C8,
+ 0x8EE0, 0x932B,
+ 0x8EE1, 0x82E5,
+ 0x8EE2, 0x5BC2,
+ 0x8EE3, 0x5F31,
+ 0x8EE4, 0x60F9,
+ 0x8EE5, 0x4E3B,
+ 0x8EE6, 0x53D6,
+ 0x8EE7, 0x5B88,
+ 0x8EE8, 0x624B,
+ 0x8EE9, 0x6731,
+ 0x8EEA, 0x6B8A,
+ 0x8EEB, 0x72E9,
+ 0x8EEC, 0x73E0,
+ 0x8EED, 0x7A2E,
+ 0x8EEE, 0x816B,
+ 0x8EEF, 0x8DA3,
+ 0x8EF0, 0x9152,
+ 0x8EF1, 0x9996,
+ 0x8EF2, 0x5112,
+ 0x8EF3, 0x53D7,
+ 0x8EF4, 0x546A,
+ 0x8EF5, 0x5BFF,
+ 0x8EF6, 0x6388,
+ 0x8EF7, 0x6A39,
+ 0x8EF8, 0x7DAC,
+ 0x8EF9, 0x9700,
+ 0x8EFA, 0x56DA,
+ 0x8EFB, 0x53CE,
+ 0x8EFC, 0x5468,
+ 0x8F40, 0x5B97,
+ 0x8F41, 0x5C31,
+ 0x8F42, 0x5DDE,
+ 0x8F43, 0x4FEE,
+ 0x8F44, 0x6101,
+ 0x8F45, 0x62FE,
+ 0x8F46, 0x6D32,
+ 0x8F47, 0x79C0,
+ 0x8F48, 0x79CB,
+ 0x8F49, 0x7D42,
+ 0x8F4A, 0x7E4D,
+ 0x8F4B, 0x7FD2,
+ 0x8F4C, 0x81ED,
+ 0x8F4D, 0x821F,
+ 0x8F4E, 0x8490,
+ 0x8F4F, 0x8846,
+ 0x8F50, 0x8972,
+ 0x8F51, 0x8B90,
+ 0x8F52, 0x8E74,
+ 0x8F53, 0x8F2F,
+ 0x8F54, 0x9031,
+ 0x8F55, 0x914B,
+ 0x8F56, 0x916C,
+ 0x8F57, 0x96C6,
+ 0x8F58, 0x919C,
+ 0x8F59, 0x4EC0,
+ 0x8F5A, 0x4F4F,
+ 0x8F5B, 0x5145,
+ 0x8F5C, 0x5341,
+ 0x8F5D, 0x5F93,
+ 0x8F5E, 0x620E,
+ 0x8F5F, 0x67D4,
+ 0x8F60, 0x6C41,
+ 0x8F61, 0x6E0B,
+ 0x8F62, 0x7363,
+ 0x8F63, 0x7E26,
+ 0x8F64, 0x91CD,
+ 0x8F65, 0x9283,
+ 0x8F66, 0x53D4,
+ 0x8F67, 0x5919,
+ 0x8F68, 0x5BBF,
+ 0x8F69, 0x6DD1,
+ 0x8F6A, 0x795D,
+ 0x8F6B, 0x7E2E,
+ 0x8F6C, 0x7C9B,
+ 0x8F6D, 0x587E,
+ 0x8F6E, 0x719F,
+ 0x8F6F, 0x51FA,
+ 0x8F70, 0x8853,
+ 0x8F71, 0x8FF0,
+ 0x8F72, 0x4FCA,
+ 0x8F73, 0x5CFB,
+ 0x8F74, 0x6625,
+ 0x8F75, 0x77AC,
+ 0x8F76, 0x7AE3,
+ 0x8F77, 0x821C,
+ 0x8F78, 0x99FF,
+ 0x8F79, 0x51C6,
+ 0x8F7A, 0x5FAA,
+ 0x8F7B, 0x65EC,
+ 0x8F7C, 0x696F,
+ 0x8F7D, 0x6B89,
+ 0x8F7E, 0x6DF3,
+ 0x8F80, 0x6E96,
+ 0x8F81, 0x6F64,
+ 0x8F82, 0x76FE,
+ 0x8F83, 0x7D14,
+ 0x8F84, 0x5DE1,
+ 0x8F85, 0x9075,
+ 0x8F86, 0x9187,
+ 0x8F87, 0x9806,
+ 0x8F88, 0x51E6,
+ 0x8F89, 0x521D,
+ 0x8F8A, 0x6240,
+ 0x8F8B, 0x6691,
+ 0x8F8C, 0x66D9,
+ 0x8F8D, 0x6E1A,
+ 0x8F8E, 0x5EB6,
+ 0x8F8F, 0x7DD2,
+ 0x8F90, 0x7F72,
+ 0x8F91, 0x66F8,
+ 0x8F92, 0x85AF,
+ 0x8F93, 0x85F7,
+ 0x8F94, 0x8AF8,
+ 0x8F95, 0x52A9,
+ 0x8F96, 0x53D9,
+ 0x8F97, 0x5973,
+ 0x8F98, 0x5E8F,
+ 0x8F99, 0x5F90,
+ 0x8F9A, 0x6055,
+ 0x8F9B, 0x92E4,
+ 0x8F9C, 0x9664,
+ 0x8F9D, 0x50B7,
+ 0x8F9E, 0x511F,
+ 0x8F9F, 0x52DD,
+ 0x8FA0, 0x5320,
+ 0x8FA1, 0x5347,
+ 0x8FA2, 0x53EC,
+ 0x8FA3, 0x54E8,
+ 0x8FA4, 0x5546,
+ 0x8FA5, 0x5531,
+ 0x8FA6, 0x5617,
+ 0x8FA7, 0x5968,
+ 0x8FA8, 0x59BE,
+ 0x8FA9, 0x5A3C,
+ 0x8FAA, 0x5BB5,
+ 0x8FAB, 0x5C06,
+ 0x8FAC, 0x5C0F,
+ 0x8FAD, 0x5C11,
+ 0x8FAE, 0x5C1A,
+ 0x8FAF, 0x5E84,
+ 0x8FB0, 0x5E8A,
+ 0x8FB1, 0x5EE0,
+ 0x8FB2, 0x5F70,
+ 0x8FB3, 0x627F,
+ 0x8FB4, 0x6284,
+ 0x8FB5, 0x62DB,
+ 0x8FB6, 0x638C,
+ 0x8FB7, 0x6377,
+ 0x8FB8, 0x6607,
+ 0x8FB9, 0x660C,
+ 0x8FBA, 0x662D,
+ 0x8FBB, 0x6676,
+ 0x8FBC, 0x677E,
+ 0x8FBD, 0x68A2,
+ 0x8FBE, 0x6A1F,
+ 0x8FBF, 0x6A35,
+ 0x8FC0, 0x6CBC,
+ 0x8FC1, 0x6D88,
+ 0x8FC2, 0x6E09,
+ 0x8FC3, 0x6E58,
+ 0x8FC4, 0x713C,
+ 0x8FC5, 0x7126,
+ 0x8FC6, 0x7167,
+ 0x8FC7, 0x75C7,
+ 0x8FC8, 0x7701,
+ 0x8FC9, 0x785D,
+ 0x8FCA, 0x7901,
+ 0x8FCB, 0x7965,
+ 0x8FCC, 0x79F0,
+ 0x8FCD, 0x7AE0,
+ 0x8FCE, 0x7B11,
+ 0x8FCF, 0x7CA7,
+ 0x8FD0, 0x7D39,
+ 0x8FD1, 0x8096,
+ 0x8FD2, 0x83D6,
+ 0x8FD3, 0x848B,
+ 0x8FD4, 0x8549,
+ 0x8FD5, 0x885D,
+ 0x8FD6, 0x88F3,
+ 0x8FD7, 0x8A1F,
+ 0x8FD8, 0x8A3C,
+ 0x8FD9, 0x8A54,
+ 0x8FDA, 0x8A73,
+ 0x8FDB, 0x8C61,
+ 0x8FDC, 0x8CDE,
+ 0x8FDD, 0x91A4,
+ 0x8FDE, 0x9266,
+ 0x8FDF, 0x937E,
+ 0x8FE0, 0x9418,
+ 0x8FE1, 0x969C,
+ 0x8FE2, 0x9798,
+ 0x8FE3, 0x4E0A,
+ 0x8FE4, 0x4E08,
+ 0x8FE5, 0x4E1E,
+ 0x8FE6, 0x4E57,
+ 0x8FE7, 0x5197,
+ 0x8FE8, 0x5270,
+ 0x8FE9, 0x57CE,
+ 0x8FEA, 0x5834,
+ 0x8FEB, 0x58CC,
+ 0x8FEC, 0x5B22,
+ 0x8FED, 0x5E38,
+ 0x8FEE, 0x60C5,
+ 0x8FEF, 0x64FE,
+ 0x8FF0, 0x6761,
+ 0x8FF1, 0x6756,
+ 0x8FF2, 0x6D44,
+ 0x8FF3, 0x72B6,
+ 0x8FF4, 0x7573,
+ 0x8FF5, 0x7A63,
+ 0x8FF6, 0x84B8,
+ 0x8FF7, 0x8B72,
+ 0x8FF8, 0x91B8,
+ 0x8FF9, 0x9320,
+ 0x8FFA, 0x5631,
+ 0x8FFB, 0x57F4,
+ 0x8FFC, 0x98FE,
+ 0x9040, 0x62ED,
+ 0x9041, 0x690D,
+ 0x9042, 0x6B96,
+ 0x9043, 0x71ED,
+ 0x9044, 0x7E54,
+ 0x9045, 0x8077,
+ 0x9046, 0x8272,
+ 0x9047, 0x89E6,
+ 0x9048, 0x98DF,
+ 0x9049, 0x8755,
+ 0x904A, 0x8FB1,
+ 0x904B, 0x5C3B,
+ 0x904C, 0x4F38,
+ 0x904D, 0x4FE1,
+ 0x904E, 0x4FB5,
+ 0x904F, 0x5507,
+ 0x9050, 0x5A20,
+ 0x9051, 0x5BDD,
+ 0x9052, 0x5BE9,
+ 0x9053, 0x5FC3,
+ 0x9054, 0x614E,
+ 0x9055, 0x632F,
+ 0x9056, 0x65B0,
+ 0x9057, 0x664B,
+ 0x9058, 0x68EE,
+ 0x9059, 0x699B,
+ 0x905A, 0x6D78,
+ 0x905B, 0x6DF1,
+ 0x905C, 0x7533,
+ 0x905D, 0x75B9,
+ 0x905E, 0x771F,
+ 0x905F, 0x795E,
+ 0x9060, 0x79E6,
+ 0x9061, 0x7D33,
+ 0x9062, 0x81E3,
+ 0x9063, 0x82AF,
+ 0x9064, 0x85AA,
+ 0x9065, 0x89AA,
+ 0x9066, 0x8A3A,
+ 0x9067, 0x8EAB,
+ 0x9068, 0x8F9B,
+ 0x9069, 0x9032,
+ 0x906A, 0x91DD,
+ 0x906B, 0x9707,
+ 0x906C, 0x4EBA,
+ 0x906D, 0x4EC1,
+ 0x906E, 0x5203,
+ 0x906F, 0x5875,
+ 0x9070, 0x58EC,
+ 0x9071, 0x5C0B,
+ 0x9072, 0x751A,
+ 0x9073, 0x5C3D,
+ 0x9074, 0x814E,
+ 0x9075, 0x8A0A,
+ 0x9076, 0x8FC5,
+ 0x9077, 0x9663,
+ 0x9078, 0x976D,
+ 0x9079, 0x7B25,
+ 0x907A, 0x8ACF,
+ 0x907B, 0x9808,
+ 0x907C, 0x9162,
+ 0x907D, 0x56F3,
+ 0x907E, 0x53A8,
+ 0x9080, 0x9017,
+ 0x9081, 0x5439,
+ 0x9082, 0x5782,
+ 0x9083, 0x5E25,
+ 0x9084, 0x63A8,
+ 0x9085, 0x6C34,
+ 0x9086, 0x708A,
+ 0x9087, 0x7761,
+ 0x9088, 0x7C8B,
+ 0x9089, 0x7FE0,
+ 0x908A, 0x8870,
+ 0x908B, 0x9042,
+ 0x908C, 0x9154,
+ 0x908D, 0x9310,
+ 0x908E, 0x9318,
+ 0x908F, 0x968F,
+ 0x9090, 0x745E,
+ 0x9091, 0x9AC4,
+ 0x9092, 0x5D07,
+ 0x9093, 0x5D69,
+ 0x9094, 0x6570,
+ 0x9095, 0x67A2,
+ 0x9096, 0x8DA8,
+ 0x9097, 0x96DB,
+ 0x9098, 0x636E,
+ 0x9099, 0x6749,
+ 0x909A, 0x6919,
+ 0x909B, 0x83C5,
+ 0x909C, 0x9817,
+ 0x909D, 0x96C0,
+ 0x909E, 0x88FE,
+ 0x909F, 0x6F84,
+ 0x90A0, 0x647A,
+ 0x90A1, 0x5BF8,
+ 0x90A2, 0x4E16,
+ 0x90A3, 0x702C,
+ 0x90A4, 0x755D,
+ 0x90A5, 0x662F,
+ 0x90A6, 0x51C4,
+ 0x90A7, 0x5236,
+ 0x90A8, 0x52E2,
+ 0x90A9, 0x59D3,
+ 0x90AA, 0x5F81,
+ 0x90AB, 0x6027,
+ 0x90AC, 0x6210,
+ 0x90AD, 0x653F,
+ 0x90AE, 0x6574,
+ 0x90AF, 0x661F,
+ 0x90B0, 0x6674,
+ 0x90B1, 0x68F2,
+ 0x90B2, 0x6816,
+ 0x90B3, 0x6B63,
+ 0x90B4, 0x6E05,
+ 0x90B5, 0x7272,
+ 0x90B6, 0x751F,
+ 0x90B7, 0x76DB,
+ 0x90B8, 0x7CBE,
+ 0x90B9, 0x8056,
+ 0x90BA, 0x58F0,
+ 0x90BB, 0x88FD,
+ 0x90BC, 0x897F,
+ 0x90BD, 0x8AA0,
+ 0x90BE, 0x8A93,
+ 0x90BF, 0x8ACB,
+ 0x90C0, 0x901D,
+ 0x90C1, 0x9192,
+ 0x90C2, 0x9752,
+ 0x90C3, 0x9759,
+ 0x90C4, 0x6589,
+ 0x90C5, 0x7A0E,
+ 0x90C6, 0x8106,
+ 0x90C7, 0x96BB,
+ 0x90C8, 0x5E2D,
+ 0x90C9, 0x60DC,
+ 0x90CA, 0x621A,
+ 0x90CB, 0x65A5,
+ 0x90CC, 0x6614,
+ 0x90CD, 0x6790,
+ 0x90CE, 0x77F3,
+ 0x90CF, 0x7A4D,
+ 0x90D0, 0x7C4D,
+ 0x90D1, 0x7E3E,
+ 0x90D2, 0x810A,
+ 0x90D3, 0x8CAC,
+ 0x90D4, 0x8D64,
+ 0x90D5, 0x8DE1,
+ 0x90D6, 0x8E5F,
+ 0x90D7, 0x78A9,
+ 0x90D8, 0x5207,
+ 0x90D9, 0x62D9,
+ 0x90DA, 0x63A5,
+ 0x90DB, 0x6442,
+ 0x90DC, 0x6298,
+ 0x90DD, 0x8A2D,
+ 0x90DE, 0x7A83,
+ 0x90DF, 0x7BC0,
+ 0x90E0, 0x8AAC,
+ 0x90E1, 0x96EA,
+ 0x90E2, 0x7D76,
+ 0x90E3, 0x820C,
+ 0x90E4, 0x8749,
+ 0x90E5, 0x4ED9,
+ 0x90E6, 0x5148,
+ 0x90E7, 0x5343,
+ 0x90E8, 0x5360,
+ 0x90E9, 0x5BA3,
+ 0x90EA, 0x5C02,
+ 0x90EB, 0x5C16,
+ 0x90EC, 0x5DDD,
+ 0x90ED, 0x6226,
+ 0x90EE, 0x6247,
+ 0x90EF, 0x64B0,
+ 0x90F0, 0x6813,
+ 0x90F1, 0x6834,
+ 0x90F2, 0x6CC9,
+ 0x90F3, 0x6D45,
+ 0x90F4, 0x6D17,
+ 0x90F5, 0x67D3,
+ 0x90F6, 0x6F5C,
+ 0x90F7, 0x714E,
+ 0x90F8, 0x717D,
+ 0x90F9, 0x65CB,
+ 0x90FA, 0x7A7F,
+ 0x90FB, 0x7BAD,
+ 0x90FC, 0x7DDA,
+ 0x9140, 0x7E4A,
+ 0x9141, 0x7FA8,
+ 0x9142, 0x817A,
+ 0x9143, 0x821B,
+ 0x9144, 0x8239,
+ 0x9145, 0x85A6,
+ 0x9146, 0x8A6E,
+ 0x9147, 0x8CCE,
+ 0x9148, 0x8DF5,
+ 0x9149, 0x9078,
+ 0x914A, 0x9077,
+ 0x914B, 0x92AD,
+ 0x914C, 0x9291,
+ 0x914D, 0x9583,
+ 0x914E, 0x9BAE,
+ 0x914F, 0x524D,
+ 0x9150, 0x5584,
+ 0x9151, 0x6F38,
+ 0x9152, 0x7136,
+ 0x9153, 0x5168,
+ 0x9154, 0x7985,
+ 0x9155, 0x7E55,
+ 0x9156, 0x81B3,
+ 0x9157, 0x7CCE,
+ 0x9158, 0x564C,
+ 0x9159, 0x5851,
+ 0x915A, 0x5CA8,
+ 0x915B, 0x63AA,
+ 0x915C, 0x66FE,
+ 0x915D, 0x66FD,
+ 0x915E, 0x695A,
+ 0x915F, 0x72D9,
+ 0x9160, 0x758F,
+ 0x9161, 0x758E,
+ 0x9162, 0x790E,
+ 0x9163, 0x7956,
+ 0x9164, 0x79DF,
+ 0x9165, 0x7C97,
+ 0x9166, 0x7D20,
+ 0x9167, 0x7D44,
+ 0x9168, 0x8607,
+ 0x9169, 0x8A34,
+ 0x916A, 0x963B,
+ 0x916B, 0x9061,
+ 0x916C, 0x9F20,
+ 0x916D, 0x50E7,
+ 0x916E, 0x5275,
+ 0x916F, 0x53CC,
+ 0x9170, 0x53E2,
+ 0x9171, 0x5009,
+ 0x9172, 0x55AA,
+ 0x9173, 0x58EE,
+ 0x9174, 0x594F,
+ 0x9175, 0x723D,
+ 0x9176, 0x5B8B,
+ 0x9177, 0x5C64,
+ 0x9178, 0x531D,
+ 0x9179, 0x60E3,
+ 0x917A, 0x60F3,
+ 0x917B, 0x635C,
+ 0x917C, 0x6383,
+ 0x917D, 0x633F,
+ 0x917E, 0x63BB,
+ 0x9180, 0x64CD,
+ 0x9181, 0x65E9,
+ 0x9182, 0x66F9,
+ 0x9183, 0x5DE3,
+ 0x9184, 0x69CD,
+ 0x9185, 0x69FD,
+ 0x9186, 0x6F15,
+ 0x9187, 0x71E5,
+ 0x9188, 0x4E89,
+ 0x9189, 0x75E9,
+ 0x918A, 0x76F8,
+ 0x918B, 0x7A93,
+ 0x918C, 0x7CDF,
+ 0x918D, 0x7DCF,
+ 0x918E, 0x7D9C,
+ 0x918F, 0x8061,
+ 0x9190, 0x8349,
+ 0x9191, 0x8358,
+ 0x9192, 0x846C,
+ 0x9193, 0x84BC,
+ 0x9194, 0x85FB,
+ 0x9195, 0x88C5,
+ 0x9196, 0x8D70,
+ 0x9197, 0x9001,
+ 0x9198, 0x906D,
+ 0x9199, 0x9397,
+ 0x919A, 0x971C,
+ 0x919B, 0x9A12,
+ 0x919C, 0x50CF,
+ 0x919D, 0x5897,
+ 0x919E, 0x618E,
+ 0x919F, 0x81D3,
+ 0x91A0, 0x8535,
+ 0x91A1, 0x8D08,
+ 0x91A2, 0x9020,
+ 0x91A3, 0x4FC3,
+ 0x91A4, 0x5074,
+ 0x91A5, 0x5247,
+ 0x91A6, 0x5373,
+ 0x91A7, 0x606F,
+ 0x91A8, 0x6349,
+ 0x91A9, 0x675F,
+ 0x91AA, 0x6E2C,
+ 0x91AB, 0x8DB3,
+ 0x91AC, 0x901F,
+ 0x91AD, 0x4FD7,
+ 0x91AE, 0x5C5E,
+ 0x91AF, 0x8CCA,
+ 0x91B0, 0x65CF,
+ 0x91B1, 0x7D9A,
+ 0x91B2, 0x5352,
+ 0x91B3, 0x8896,
+ 0x91B4, 0x5176,
+ 0x91B5, 0x63C3,
+ 0x91B6, 0x5B58,
+ 0x91B7, 0x5B6B,
+ 0x91B8, 0x5C0A,
+ 0x91B9, 0x640D,
+ 0x91BA, 0x6751,
+ 0x91BB, 0x905C,
+ 0x91BC, 0x4ED6,
+ 0x91BD, 0x591A,
+ 0x91BE, 0x592A,
+ 0x91BF, 0x6C70,
+ 0x91C0, 0x8A51,
+ 0x91C1, 0x553E,
+ 0x91C2, 0x5815,
+ 0x91C3, 0x59A5,
+ 0x91C4, 0x60F0,
+ 0x91C5, 0x6253,
+ 0x91C6, 0x67C1,
+ 0x91C7, 0x8235,
+ 0x91C8, 0x6955,
+ 0x91C9, 0x9640,
+ 0x91CA, 0x99C4,
+ 0x91CB, 0x9A28,
+ 0x91CC, 0x4F53,
+ 0x91CD, 0x5806,
+ 0x91CE, 0x5BFE,
+ 0x91CF, 0x8010,
+ 0x91D0, 0x5CB1,
+ 0x91D1, 0x5E2F,
+ 0x91D2, 0x5F85,
+ 0x91D3, 0x6020,
+ 0x91D4, 0x614B,
+ 0x91D5, 0x6234,
+ 0x91D6, 0x66FF,
+ 0x91D7, 0x6CF0,
+ 0x91D8, 0x6EDE,
+ 0x91D9, 0x80CE,
+ 0x91DA, 0x817F,
+ 0x91DB, 0x82D4,
+ 0x91DC, 0x888B,
+ 0x91DD, 0x8CB8,
+ 0x91DE, 0x9000,
+ 0x91DF, 0x902E,
+ 0x91E0, 0x968A,
+ 0x91E1, 0x9EDB,
+ 0x91E2, 0x9BDB,
+ 0x91E3, 0x4EE3,
+ 0x91E4, 0x53F0,
+ 0x91E5, 0x5927,
+ 0x91E6, 0x7B2C,
+ 0x91E7, 0x918D,
+ 0x91E8, 0x984C,
+ 0x91E9, 0x9DF9,
+ 0x91EA, 0x6EDD,
+ 0x91EB, 0x7027,
+ 0x91EC, 0x5353,
+ 0x91ED, 0x5544,
+ 0x91EE, 0x5B85,
+ 0x91EF, 0x6258,
+ 0x91F0, 0x629E,
+ 0x91F1, 0x62D3,
+ 0x91F2, 0x6CA2,
+ 0x91F3, 0x6FEF,
+ 0x91F4, 0x7422,
+ 0x91F5, 0x8A17,
+ 0x91F6, 0x9438,
+ 0x91F7, 0x6FC1,
+ 0x91F8, 0x8AFE,
+ 0x91F9, 0x8338,
+ 0x91FA, 0x51E7,
+ 0x91FB, 0x86F8,
+ 0x91FC, 0x53EA,
+ 0x9240, 0x53E9,
+ 0x9241, 0x4F46,
+ 0x9242, 0x9054,
+ 0x9243, 0x8FB0,
+ 0x9244, 0x596A,
+ 0x9245, 0x8131,
+ 0x9246, 0x5DFD,
+ 0x9247, 0x7AEA,
+ 0x9248, 0x8FBF,
+ 0x9249, 0x68DA,
+ 0x924A, 0x8C37,
+ 0x924B, 0x72F8,
+ 0x924C, 0x9C48,
+ 0x924D, 0x6A3D,
+ 0x924E, 0x8AB0,
+ 0x924F, 0x4E39,
+ 0x9250, 0x5358,
+ 0x9251, 0x5606,
+ 0x9252, 0x5766,
+ 0x9253, 0x62C5,
+ 0x9254, 0x63A2,
+ 0x9255, 0x65E6,
+ 0x9256, 0x6B4E,
+ 0x9257, 0x6DE1,
+ 0x9258, 0x6E5B,
+ 0x9259, 0x70AD,
+ 0x925A, 0x77ED,
+ 0x925B, 0x7AEF,
+ 0x925C, 0x7BAA,
+ 0x925D, 0x7DBB,
+ 0x925E, 0x803D,
+ 0x925F, 0x80C6,
+ 0x9260, 0x86CB,
+ 0x9261, 0x8A95,
+ 0x9262, 0x935B,
+ 0x9263, 0x56E3,
+ 0x9264, 0x58C7,
+ 0x9265, 0x5F3E,
+ 0x9266, 0x65AD,
+ 0x9267, 0x6696,
+ 0x9268, 0x6A80,
+ 0x9269, 0x6BB5,
+ 0x926A, 0x7537,
+ 0x926B, 0x8AC7,
+ 0x926C, 0x5024,
+ 0x926D, 0x77E5,
+ 0x926E, 0x5730,
+ 0x926F, 0x5F1B,
+ 0x9270, 0x6065,
+ 0x9271, 0x667A,
+ 0x9272, 0x6C60,
+ 0x9273, 0x75F4,
+ 0x9274, 0x7A1A,
+ 0x9275, 0x7F6E,
+ 0x9276, 0x81F4,
+ 0x9277, 0x8718,
+ 0x9278, 0x9045,
+ 0x9279, 0x99B3,
+ 0x927A, 0x7BC9,
+ 0x927B, 0x755C,
+ 0x927C, 0x7AF9,
+ 0x927D, 0x7B51,
+ 0x927E, 0x84C4,
+ 0x9280, 0x9010,
+ 0x9281, 0x79E9,
+ 0x9282, 0x7A92,
+ 0x9283, 0x8336,
+ 0x9284, 0x5AE1,
+ 0x9285, 0x7740,
+ 0x9286, 0x4E2D,
+ 0x9287, 0x4EF2,
+ 0x9288, 0x5B99,
+ 0x9289, 0x5FE0,
+ 0x928A, 0x62BD,
+ 0x928B, 0x663C,
+ 0x928C, 0x67F1,
+ 0x928D, 0x6CE8,
+ 0x928E, 0x866B,
+ 0x928F, 0x8877,
+ 0x9290, 0x8A3B,
+ 0x9291, 0x914E,
+ 0x9292, 0x92F3,
+ 0x9293, 0x99D0,
+ 0x9294, 0x6A17,
+ 0x9295, 0x7026,
+ 0x9296, 0x732A,
+ 0x9297, 0x82E7,
+ 0x9298, 0x8457,
+ 0x9299, 0x8CAF,
+ 0x929A, 0x4E01,
+ 0x929B, 0x5146,
+ 0x929C, 0x51CB,
+ 0x929D, 0x558B,
+ 0x929E, 0x5BF5,
+ 0x929F, 0x5E16,
+ 0x92A0, 0x5E33,
+ 0x92A1, 0x5E81,
+ 0x92A2, 0x5F14,
+ 0x92A3, 0x5F35,
+ 0x92A4, 0x5F6B,
+ 0x92A5, 0x5FB4,
+ 0x92A6, 0x61F2,
+ 0x92A7, 0x6311,
+ 0x92A8, 0x66A2,
+ 0x92A9, 0x671D,
+ 0x92AA, 0x6F6E,
+ 0x92AB, 0x7252,
+ 0x92AC, 0x753A,
+ 0x92AD, 0x773A,
+ 0x92AE, 0x8074,
+ 0x92AF, 0x8139,
+ 0x92B0, 0x8178,
+ 0x92B1, 0x8776,
+ 0x92B2, 0x8ABF,
+ 0x92B3, 0x8ADC,
+ 0x92B4, 0x8D85,
+ 0x92B5, 0x8DF3,
+ 0x92B6, 0x929A,
+ 0x92B7, 0x9577,
+ 0x92B8, 0x9802,
+ 0x92B9, 0x9CE5,
+ 0x92BA, 0x52C5,
+ 0x92BB, 0x6357,
+ 0x92BC, 0x76F4,
+ 0x92BD, 0x6715,
+ 0x92BE, 0x6C88,
+ 0x92BF, 0x73CD,
+ 0x92C0, 0x8CC3,
+ 0x92C1, 0x93AE,
+ 0x92C2, 0x9673,
+ 0x92C3, 0x6D25,
+ 0x92C4, 0x589C,
+ 0x92C5, 0x690E,
+ 0x92C6, 0x69CC,
+ 0x92C7, 0x8FFD,
+ 0x92C8, 0x939A,
+ 0x92C9, 0x75DB,
+ 0x92CA, 0x901A,
+ 0x92CB, 0x585A,
+ 0x92CC, 0x6802,
+ 0x92CD, 0x63B4,
+ 0x92CE, 0x69FB,
+ 0x92CF, 0x4F43,
+ 0x92D0, 0x6F2C,
+ 0x92D1, 0x67D8,
+ 0x92D2, 0x8FBB,
+ 0x92D3, 0x8526,
+ 0x92D4, 0x7DB4,
+ 0x92D5, 0x9354,
+ 0x92D6, 0x693F,
+ 0x92D7, 0x6F70,
+ 0x92D8, 0x576A,
+ 0x92D9, 0x58F7,
+ 0x92DA, 0x5B2C,
+ 0x92DB, 0x7D2C,
+ 0x92DC, 0x722A,
+ 0x92DD, 0x540A,
+ 0x92DE, 0x91E3,
+ 0x92DF, 0x9DB4,
+ 0x92E0, 0x4EAD,
+ 0x92E1, 0x4F4E,
+ 0x92E2, 0x505C,
+ 0x92E3, 0x5075,
+ 0x92E4, 0x5243,
+ 0x92E5, 0x8C9E,
+ 0x92E6, 0x5448,
+ 0x92E7, 0x5824,
+ 0x92E8, 0x5B9A,
+ 0x92E9, 0x5E1D,
+ 0x92EA, 0x5E95,
+ 0x92EB, 0x5EAD,
+ 0x92EC, 0x5EF7,
+ 0x92ED, 0x5F1F,
+ 0x92EE, 0x608C,
+ 0x92EF, 0x62B5,
+ 0x92F0, 0x633A,
+ 0x92F1, 0x63D0,
+ 0x92F2, 0x68AF,
+ 0x92F3, 0x6C40,
+ 0x92F4, 0x7887,
+ 0x92F5, 0x798E,
+ 0x92F6, 0x7A0B,
+ 0x92F7, 0x7DE0,
+ 0x92F8, 0x8247,
+ 0x92F9, 0x8A02,
+ 0x92FA, 0x8AE6,
+ 0x92FB, 0x8E44,
+ 0x92FC, 0x9013,
+ 0x9340, 0x90B8,
+ 0x9341, 0x912D,
+ 0x9342, 0x91D8,
+ 0x9343, 0x9F0E,
+ 0x9344, 0x6CE5,
+ 0x9345, 0x6458,
+ 0x9346, 0x64E2,
+ 0x9347, 0x6575,
+ 0x9348, 0x6EF4,
+ 0x9349, 0x7684,
+ 0x934A, 0x7B1B,
+ 0x934B, 0x9069,
+ 0x934C, 0x93D1,
+ 0x934D, 0x6EBA,
+ 0x934E, 0x54F2,
+ 0x934F, 0x5FB9,
+ 0x9350, 0x64A4,
+ 0x9351, 0x8F4D,
+ 0x9352, 0x8FED,
+ 0x9353, 0x9244,
+ 0x9354, 0x5178,
+ 0x9355, 0x586B,
+ 0x9356, 0x5929,
+ 0x9357, 0x5C55,
+ 0x9358, 0x5E97,
+ 0x9359, 0x6DFB,
+ 0x935A, 0x7E8F,
+ 0x935B, 0x751C,
+ 0x935C, 0x8CBC,
+ 0x935D, 0x8EE2,
+ 0x935E, 0x985B,
+ 0x935F, 0x70B9,
+ 0x9360, 0x4F1D,
+ 0x9361, 0x6BBF,
+ 0x9362, 0x6FB1,
+ 0x9363, 0x7530,
+ 0x9364, 0x96FB,
+ 0x9365, 0x514E,
+ 0x9366, 0x5410,
+ 0x9367, 0x5835,
+ 0x9368, 0x5857,
+ 0x9369, 0x59AC,
+ 0x936A, 0x5C60,
+ 0x936B, 0x5F92,
+ 0x936C, 0x6597,
+ 0x936D, 0x675C,
+ 0x936E, 0x6E21,
+ 0x936F, 0x767B,
+ 0x9370, 0x83DF,
+ 0x9371, 0x8CED,
+ 0x9372, 0x9014,
+ 0x9373, 0x90FD,
+ 0x9374, 0x934D,
+ 0x9375, 0x7825,
+ 0x9376, 0x783A,
+ 0x9377, 0x52AA,
+ 0x9378, 0x5EA6,
+ 0x9379, 0x571F,
+ 0x937A, 0x5974,
+ 0x937B, 0x6012,
+ 0x937C, 0x5012,
+ 0x937D, 0x515A,
+ 0x937E, 0x51AC,
+ 0x9380, 0x51CD,
+ 0x9381, 0x5200,
+ 0x9382, 0x5510,
+ 0x9383, 0x5854,
+ 0x9384, 0x5858,
+ 0x9385, 0x5957,
+ 0x9386, 0x5B95,
+ 0x9387, 0x5CF6,
+ 0x9388, 0x5D8B,
+ 0x9389, 0x60BC,
+ 0x938A, 0x6295,
+ 0x938B, 0x642D,
+ 0x938C, 0x6771,
+ 0x938D, 0x6843,
+ 0x938E, 0x68BC,
+ 0x938F, 0x68DF,
+ 0x9390, 0x76D7,
+ 0x9391, 0x6DD8,
+ 0x9392, 0x6E6F,
+ 0x9393, 0x6D9B,
+ 0x9394, 0x706F,
+ 0x9395, 0x71C8,
+ 0x9396, 0x5F53,
+ 0x9397, 0x75D8,
+ 0x9398, 0x7977,
+ 0x9399, 0x7B49,
+ 0x939A, 0x7B54,
+ 0x939B, 0x7B52,
+ 0x939C, 0x7CD6,
+ 0x939D, 0x7D71,
+ 0x939E, 0x5230,
+ 0x939F, 0x8463,
+ 0x93A0, 0x8569,
+ 0x93A1, 0x85E4,
+ 0x93A2, 0x8A0E,
+ 0x93A3, 0x8B04,
+ 0x93A4, 0x8C46,
+ 0x93A5, 0x8E0F,
+ 0x93A6, 0x9003,
+ 0x93A7, 0x900F,
+ 0x93A8, 0x9419,
+ 0x93A9, 0x9676,
+ 0x93AA, 0x982D,
+ 0x93AB, 0x9A30,
+ 0x93AC, 0x95D8,
+ 0x93AD, 0x50CD,
+ 0x93AE, 0x52D5,
+ 0x93AF, 0x540C,
+ 0x93B0, 0x5802,
+ 0x93B1, 0x5C0E,
+ 0x93B2, 0x61A7,
+ 0x93B3, 0x649E,
+ 0x93B4, 0x6D1E,
+ 0x93B5, 0x77B3,
+ 0x93B6, 0x7AE5,
+ 0x93B7, 0x80F4,
+ 0x93B8, 0x8404,
+ 0x93B9, 0x9053,
+ 0x93BA, 0x9285,
+ 0x93BB, 0x5CE0,
+ 0x93BC, 0x9D07,
+ 0x93BD, 0x533F,
+ 0x93BE, 0x5F97,
+ 0x93BF, 0x5FB3,
+ 0x93C0, 0x6D9C,
+ 0x93C1, 0x7279,
+ 0x93C2, 0x7763,
+ 0x93C3, 0x79BF,
+ 0x93C4, 0x7BE4,
+ 0x93C5, 0x6BD2,
+ 0x93C6, 0x72EC,
+ 0x93C7, 0x8AAD,
+ 0x93C8, 0x6803,
+ 0x93C9, 0x6A61,
+ 0x93CA, 0x51F8,
+ 0x93CB, 0x7A81,
+ 0x93CC, 0x6934,
+ 0x93CD, 0x5C4A,
+ 0x93CE, 0x9CF6,
+ 0x93CF, 0x82EB,
+ 0x93D0, 0x5BC5,
+ 0x93D1, 0x9149,
+ 0x93D2, 0x701E,
+ 0x93D3, 0x5678,
+ 0x93D4, 0x5C6F,
+ 0x93D5, 0x60C7,
+ 0x93D6, 0x6566,
+ 0x93D7, 0x6C8C,
+ 0x93D8, 0x8C5A,
+ 0x93D9, 0x9041,
+ 0x93DA, 0x9813,
+ 0x93DB, 0x5451,
+ 0x93DC, 0x66C7,
+ 0x93DD, 0x920D,
+ 0x93DE, 0x5948,
+ 0x93DF, 0x90A3,
+ 0x93E0, 0x5185,
+ 0x93E1, 0x4E4D,
+ 0x93E2, 0x51EA,
+ 0x93E3, 0x8599,
+ 0x93E4, 0x8B0E,
+ 0x93E5, 0x7058,
+ 0x93E6, 0x637A,
+ 0x93E7, 0x934B,
+ 0x93E8, 0x6962,
+ 0x93E9, 0x99B4,
+ 0x93EA, 0x7E04,
+ 0x93EB, 0x7577,
+ 0x93EC, 0x5357,
+ 0x93ED, 0x6960,
+ 0x93EE, 0x8EDF,
+ 0x93EF, 0x96E3,
+ 0x93F0, 0x6C5D,
+ 0x93F1, 0x4E8C,
+ 0x93F2, 0x5C3C,
+ 0x93F3, 0x5F10,
+ 0x93F4, 0x8FE9,
+ 0x93F5, 0x5302,
+ 0x93F6, 0x8CD1,
+ 0x93F7, 0x8089,
+ 0x93F8, 0x8679,
+ 0x93F9, 0x5EFF,
+ 0x93FA, 0x65E5,
+ 0x93FB, 0x4E73,
+ 0x93FC, 0x5165,
+ 0x9440, 0x5982,
+ 0x9441, 0x5C3F,
+ 0x9442, 0x97EE,
+ 0x9443, 0x4EFB,
+ 0x9444, 0x598A,
+ 0x9445, 0x5FCD,
+ 0x9446, 0x8A8D,
+ 0x9447, 0x6FE1,
+ 0x9448, 0x79B0,
+ 0x9449, 0x7962,
+ 0x944A, 0x5BE7,
+ 0x944B, 0x8471,
+ 0x944C, 0x732B,
+ 0x944D, 0x71B1,
+ 0x944E, 0x5E74,
+ 0x944F, 0x5FF5,
+ 0x9450, 0x637B,
+ 0x9451, 0x649A,
+ 0x9452, 0x71C3,
+ 0x9453, 0x7C98,
+ 0x9454, 0x4E43,
+ 0x9455, 0x5EFC,
+ 0x9456, 0x4E4B,
+ 0x9457, 0x57DC,
+ 0x9458, 0x56A2,
+ 0x9459, 0x60A9,
+ 0x945A, 0x6FC3,
+ 0x945B, 0x7D0D,
+ 0x945C, 0x80FD,
+ 0x945D, 0x8133,
+ 0x945E, 0x81BF,
+ 0x945F, 0x8FB2,
+ 0x9460, 0x8997,
+ 0x9461, 0x86A4,
+ 0x9462, 0x5DF4,
+ 0x9463, 0x628A,
+ 0x9464, 0x64AD,
+ 0x9465, 0x8987,
+ 0x9466, 0x6777,
+ 0x9467, 0x6CE2,
+ 0x9468, 0x6D3E,
+ 0x9469, 0x7436,
+ 0x946A, 0x7834,
+ 0x946B, 0x5A46,
+ 0x946C, 0x7F75,
+ 0x946D, 0x82AD,
+ 0x946E, 0x99AC,
+ 0x946F, 0x4FF3,
+ 0x9470, 0x5EC3,
+ 0x9471, 0x62DD,
+ 0x9472, 0x6392,
+ 0x9473, 0x6557,
+ 0x9474, 0x676F,
+ 0x9475, 0x76C3,
+ 0x9476, 0x724C,
+ 0x9477, 0x80CC,
+ 0x9478, 0x80BA,
+ 0x9479, 0x8F29,
+ 0x947A, 0x914D,
+ 0x947B, 0x500D,
+ 0x947C, 0x57F9,
+ 0x947D, 0x5A92,
+ 0x947E, 0x6885,
+ 0x9480, 0x6973,
+ 0x9481, 0x7164,
+ 0x9482, 0x72FD,
+ 0x9483, 0x8CB7,
+ 0x9484, 0x58F2,
+ 0x9485, 0x8CE0,
+ 0x9486, 0x966A,
+ 0x9487, 0x9019,
+ 0x9488, 0x877F,
+ 0x9489, 0x79E4,
+ 0x948A, 0x77E7,
+ 0x948B, 0x8429,
+ 0x948C, 0x4F2F,
+ 0x948D, 0x5265,
+ 0x948E, 0x535A,
+ 0x948F, 0x62CD,
+ 0x9490, 0x67CF,
+ 0x9491, 0x6CCA,
+ 0x9492, 0x767D,
+ 0x9493, 0x7B94,
+ 0x9494, 0x7C95,
+ 0x9495, 0x8236,
+ 0x9496, 0x8584,
+ 0x9497, 0x8FEB,
+ 0x9498, 0x66DD,
+ 0x9499, 0x6F20,
+ 0x949A, 0x7206,
+ 0x949B, 0x7E1B,
+ 0x949C, 0x83AB,
+ 0x949D, 0x99C1,
+ 0x949E, 0x9EA6,
+ 0x949F, 0x51FD,
+ 0x94A0, 0x7BB1,
+ 0x94A1, 0x7872,
+ 0x94A2, 0x7BB8,
+ 0x94A3, 0x8087,
+ 0x94A4, 0x7B48,
+ 0x94A5, 0x6AE8,
+ 0x94A6, 0x5E61,
+ 0x94A7, 0x808C,
+ 0x94A8, 0x7551,
+ 0x94A9, 0x7560,
+ 0x94AA, 0x516B,
+ 0x94AB, 0x9262,
+ 0x94AC, 0x6E8C,
+ 0x94AD, 0x767A,
+ 0x94AE, 0x9197,
+ 0x94AF, 0x9AEA,
+ 0x94B0, 0x4F10,
+ 0x94B1, 0x7F70,
+ 0x94B2, 0x629C,
+ 0x94B3, 0x7B4F,
+ 0x94B4, 0x95A5,
+ 0x94B5, 0x9CE9,
+ 0x94B6, 0x567A,
+ 0x94B7, 0x5859,
+ 0x94B8, 0x86E4,
+ 0x94B9, 0x96BC,
+ 0x94BA, 0x4F34,
+ 0x94BB, 0x5224,
+ 0x94BC, 0x534A,
+ 0x94BD, 0x53CD,
+ 0x94BE, 0x53DB,
+ 0x94BF, 0x5E06,
+ 0x94C0, 0x642C,
+ 0x94C1, 0x6591,
+ 0x94C2, 0x677F,
+ 0x94C3, 0x6C3E,
+ 0x94C4, 0x6C4E,
+ 0x94C5, 0x7248,
+ 0x94C6, 0x72AF,
+ 0x94C7, 0x73ED,
+ 0x94C8, 0x7554,
+ 0x94C9, 0x7E41,
+ 0x94CA, 0x822C,
+ 0x94CB, 0x85E9,
+ 0x94CC, 0x8CA9,
+ 0x94CD, 0x7BC4,
+ 0x94CE, 0x91C6,
+ 0x94CF, 0x7169,
+ 0x94D0, 0x9812,
+ 0x94D1, 0x98EF,
+ 0x94D2, 0x633D,
+ 0x94D3, 0x6669,
+ 0x94D4, 0x756A,
+ 0x94D5, 0x76E4,
+ 0x94D6, 0x78D0,
+ 0x94D7, 0x8543,
+ 0x94D8, 0x86EE,
+ 0x94D9, 0x532A,
+ 0x94DA, 0x5351,
+ 0x94DB, 0x5426,
+ 0x94DC, 0x5983,
+ 0x94DD, 0x5E87,
+ 0x94DE, 0x5F7C,
+ 0x94DF, 0x60B2,
+ 0x94E0, 0x6249,
+ 0x94E1, 0x6279,
+ 0x94E2, 0x62AB,
+ 0x94E3, 0x6590,
+ 0x94E4, 0x6BD4,
+ 0x94E5, 0x6CCC,
+ 0x94E6, 0x75B2,
+ 0x94E7, 0x76AE,
+ 0x94E8, 0x7891,
+ 0x94E9, 0x79D8,
+ 0x94EA, 0x7DCB,
+ 0x94EB, 0x7F77,
+ 0x94EC, 0x80A5,
+ 0x94ED, 0x88AB,
+ 0x94EE, 0x8AB9,
+ 0x94EF, 0x8CBB,
+ 0x94F0, 0x907F,
+ 0x94F1, 0x975E,
+ 0x94F2, 0x98DB,
+ 0x94F3, 0x6A0B,
+ 0x94F4, 0x7C38,
+ 0x94F5, 0x5099,
+ 0x94F6, 0x5C3E,
+ 0x94F7, 0x5FAE,
+ 0x94F8, 0x6787,
+ 0x94F9, 0x6BD8,
+ 0x94FA, 0x7435,
+ 0x94FB, 0x7709,
+ 0x94FC, 0x7F8E,
+ 0x9540, 0x9F3B,
+ 0x9541, 0x67CA,
+ 0x9542, 0x7A17,
+ 0x9543, 0x5339,
+ 0x9544, 0x758B,
+ 0x9545, 0x9AED,
+ 0x9546, 0x5F66,
+ 0x9547, 0x819D,
+ 0x9548, 0x83F1,
+ 0x9549, 0x8098,
+ 0x954A, 0x5F3C,
+ 0x954B, 0x5FC5,
+ 0x954C, 0x7562,
+ 0x954D, 0x7B46,
+ 0x954E, 0x903C,
+ 0x954F, 0x6867,
+ 0x9550, 0x59EB,
+ 0x9551, 0x5A9B,
+ 0x9552, 0x7D10,
+ 0x9553, 0x767E,
+ 0x9554, 0x8B2C,
+ 0x9555, 0x4FF5,
+ 0x9556, 0x5F6A,
+ 0x9557, 0x6A19,
+ 0x9558, 0x6C37,
+ 0x9559, 0x6F02,
+ 0x955A, 0x74E2,
+ 0x955B, 0x7968,
+ 0x955C, 0x8868,
+ 0x955D, 0x8A55,
+ 0x955E, 0x8C79,
+ 0x955F, 0x5EDF,
+ 0x9560, 0x63CF,
+ 0x9561, 0x75C5,
+ 0x9562, 0x79D2,
+ 0x9563, 0x82D7,
+ 0x9564, 0x9328,
+ 0x9565, 0x92F2,
+ 0x9566, 0x849C,
+ 0x9567, 0x86ED,
+ 0x9568, 0x9C2D,
+ 0x9569, 0x54C1,
+ 0x956A, 0x5F6C,
+ 0x956B, 0x658C,
+ 0x956C, 0x6D5C,
+ 0x956D, 0x7015,
+ 0x956E, 0x8CA7,
+ 0x956F, 0x8CD3,
+ 0x9570, 0x983B,
+ 0x9571, 0x654F,
+ 0x9572, 0x74F6,
+ 0x9573, 0x4E0D,
+ 0x9574, 0x4ED8,
+ 0x9575, 0x57E0,
+ 0x9576, 0x592B,
+ 0x9577, 0x5A66,
+ 0x9578, 0x5BCC,
+ 0x9579, 0x51A8,
+ 0x957A, 0x5E03,
+ 0x957B, 0x5E9C,
+ 0x957C, 0x6016,
+ 0x957D, 0x6276,
+ 0x957E, 0x6577,
+ 0x9580, 0x65A7,
+ 0x9581, 0x666E,
+ 0x9582, 0x6D6E,
+ 0x9583, 0x7236,
+ 0x9584, 0x7B26,
+ 0x9585, 0x8150,
+ 0x9586, 0x819A,
+ 0x9587, 0x8299,
+ 0x9588, 0x8B5C,
+ 0x9589, 0x8CA0,
+ 0x958A, 0x8CE6,
+ 0x958B, 0x8D74,
+ 0x958C, 0x961C,
+ 0x958D, 0x9644,
+ 0x958E, 0x4FAE,
+ 0x958F, 0x64AB,
+ 0x9590, 0x6B66,
+ 0x9591, 0x821E,
+ 0x9592, 0x8461,
+ 0x9593, 0x856A,
+ 0x9594, 0x90E8,
+ 0x9595, 0x5C01,
+ 0x9596, 0x6953,
+ 0x9597, 0x98A8,
+ 0x9598, 0x847A,
+ 0x9599, 0x8557,
+ 0x959A, 0x4F0F,
+ 0x959B, 0x526F,
+ 0x959C, 0x5FA9,
+ 0x959D, 0x5E45,
+ 0x959E, 0x670D,
+ 0x959F, 0x798F,
+ 0x95A0, 0x8179,
+ 0x95A1, 0x8907,
+ 0x95A2, 0x8986,
+ 0x95A3, 0x6DF5,
+ 0x95A4, 0x5F17,
+ 0x95A5, 0x6255,
+ 0x95A6, 0x6CB8,
+ 0x95A7, 0x4ECF,
+ 0x95A8, 0x7269,
+ 0x95A9, 0x9B92,
+ 0x95AA, 0x5206,
+ 0x95AB, 0x543B,
+ 0x95AC, 0x5674,
+ 0x95AD, 0x58B3,
+ 0x95AE, 0x61A4,
+ 0x95AF, 0x626E,
+ 0x95B0, 0x711A,
+ 0x95B1, 0x596E,
+ 0x95B2, 0x7C89,
+ 0x95B3, 0x7CDE,
+ 0x95B4, 0x7D1B,
+ 0x95B5, 0x96F0,
+ 0x95B6, 0x6587,
+ 0x95B7, 0x805E,
+ 0x95B8, 0x4E19,
+ 0x95B9, 0x4F75,
+ 0x95BA, 0x5175,
+ 0x95BB, 0x5840,
+ 0x95BC, 0x5E63,
+ 0x95BD, 0x5E73,
+ 0x95BE, 0x5F0A,
+ 0x95BF, 0x67C4,
+ 0x95C0, 0x4E26,
+ 0x95C1, 0x853D,
+ 0x95C2, 0x9589,
+ 0x95C3, 0x965B,
+ 0x95C4, 0x7C73,
+ 0x95C5, 0x9801,
+ 0x95C6, 0x50FB,
+ 0x95C7, 0x58C1,
+ 0x95C8, 0x7656,
+ 0x95C9, 0x78A7,
+ 0x95CA, 0x5225,
+ 0x95CB, 0x77A5,
+ 0x95CC, 0x8511,
+ 0x95CD, 0x7B86,
+ 0x95CE, 0x504F,
+ 0x95CF, 0x5909,
+ 0x95D0, 0x7247,
+ 0x95D1, 0x7BC7,
+ 0x95D2, 0x7DE8,
+ 0x95D3, 0x8FBA,
+ 0x95D4, 0x8FD4,
+ 0x95D5, 0x904D,
+ 0x95D6, 0x4FBF,
+ 0x95D7, 0x52C9,
+ 0x95D8, 0x5A29,
+ 0x95D9, 0x5F01,
+ 0x95DA, 0x97AD,
+ 0x95DB, 0x4FDD,
+ 0x95DC, 0x8217,
+ 0x95DD, 0x92EA,
+ 0x95DE, 0x5703,
+ 0x95DF, 0x6355,
+ 0x95E0, 0x6B69,
+ 0x95E1, 0x752B,
+ 0x95E2, 0x88DC,
+ 0x95E3, 0x8F14,
+ 0x95E4, 0x7A42,
+ 0x95E5, 0x52DF,
+ 0x95E6, 0x5893,
+ 0x95E7, 0x6155,
+ 0x95E8, 0x620A,
+ 0x95E9, 0x66AE,
+ 0x95EA, 0x6BCD,
+ 0x95EB, 0x7C3F,
+ 0x95EC, 0x83E9,
+ 0x95ED, 0x5023,
+ 0x95EE, 0x4FF8,
+ 0x95EF, 0x5305,
+ 0x95F0, 0x5446,
+ 0x95F1, 0x5831,
+ 0x95F2, 0x5949,
+ 0x95F3, 0x5B9D,
+ 0x95F4, 0x5CF0,
+ 0x95F5, 0x5CEF,
+ 0x95F6, 0x5D29,
+ 0x95F7, 0x5E96,
+ 0x95F8, 0x62B1,
+ 0x95F9, 0x6367,
+ 0x95FA, 0x653E,
+ 0x95FB, 0x65B9,
+ 0x95FC, 0x670B,
+ 0x9640, 0x6CD5,
+ 0x9641, 0x6CE1,
+ 0x9642, 0x70F9,
+ 0x9643, 0x7832,
+ 0x9644, 0x7E2B,
+ 0x9645, 0x80DE,
+ 0x9646, 0x82B3,
+ 0x9647, 0x840C,
+ 0x9648, 0x84EC,
+ 0x9649, 0x8702,
+ 0x964A, 0x8912,
+ 0x964B, 0x8A2A,
+ 0x964C, 0x8C4A,
+ 0x964D, 0x90A6,
+ 0x964E, 0x92D2,
+ 0x964F, 0x98FD,
+ 0x9650, 0x9CF3,
+ 0x9651, 0x9D6C,
+ 0x9652, 0x4E4F,
+ 0x9653, 0x4EA1,
+ 0x9654, 0x508D,
+ 0x9655, 0x5256,
+ 0x9656, 0x574A,
+ 0x9657, 0x59A8,
+ 0x9658, 0x5E3D,
+ 0x9659, 0x5FD8,
+ 0x965A, 0x5FD9,
+ 0x965B, 0x623F,
+ 0x965C, 0x66B4,
+ 0x965D, 0x671B,
+ 0x965E, 0x67D0,
+ 0x965F, 0x68D2,
+ 0x9660, 0x5192,
+ 0x9661, 0x7D21,
+ 0x9662, 0x80AA,
+ 0x9663, 0x81A8,
+ 0x9664, 0x8B00,
+ 0x9665, 0x8C8C,
+ 0x9666, 0x8CBF,
+ 0x9667, 0x927E,
+ 0x9668, 0x9632,
+ 0x9669, 0x5420,
+ 0x966A, 0x982C,
+ 0x966B, 0x5317,
+ 0x966C, 0x50D5,
+ 0x966D, 0x535C,
+ 0x966E, 0x58A8,
+ 0x966F, 0x64B2,
+ 0x9670, 0x6734,
+ 0x9671, 0x7267,
+ 0x9672, 0x7766,
+ 0x9673, 0x7A46,
+ 0x9674, 0x91E6,
+ 0x9675, 0x52C3,
+ 0x9676, 0x6CA1,
+ 0x9677, 0x6B86,
+ 0x9678, 0x5800,
+ 0x9679, 0x5E4C,
+ 0x967A, 0x5954,
+ 0x967B, 0x672C,
+ 0x967C, 0x7FFB,
+ 0x967D, 0x51E1,
+ 0x967E, 0x76C6,
+ 0x9680, 0x6469,
+ 0x9681, 0x78E8,
+ 0x9682, 0x9B54,
+ 0x9683, 0x9EBB,
+ 0x9684, 0x57CB,
+ 0x9685, 0x59B9,
+ 0x9686, 0x6627,
+ 0x9687, 0x679A,
+ 0x9688, 0x6BCE,
+ 0x9689, 0x54E9,
+ 0x968A, 0x69D9,
+ 0x968B, 0x5E55,
+ 0x968C, 0x819C,
+ 0x968D, 0x6795,
+ 0x968E, 0x9BAA,
+ 0x968F, 0x67FE,
+ 0x9690, 0x9C52,
+ 0x9691, 0x685D,
+ 0x9692, 0x4EA6,
+ 0x9693, 0x4FE3,
+ 0x9694, 0x53C8,
+ 0x9695, 0x62B9,
+ 0x9696, 0x672B,
+ 0x9697, 0x6CAB,
+ 0x9698, 0x8FC4,
+ 0x9699, 0x4FAD,
+ 0x969A, 0x7E6D,
+ 0x969B, 0x9EBF,
+ 0x969C, 0x4E07,
+ 0x969D, 0x6162,
+ 0x969E, 0x6E80,
+ 0x969F, 0x6F2B,
+ 0x96A0, 0x8513,
+ 0x96A1, 0x5473,
+ 0x96A2, 0x672A,
+ 0x96A3, 0x9B45,
+ 0x96A4, 0x5DF3,
+ 0x96A5, 0x7B95,
+ 0x96A6, 0x5CAC,
+ 0x96A7, 0x5BC6,
+ 0x96A8, 0x871C,
+ 0x96A9, 0x6E4A,
+ 0x96AA, 0x84D1,
+ 0x96AB, 0x7A14,
+ 0x96AC, 0x8108,
+ 0x96AD, 0x5999,
+ 0x96AE, 0x7C8D,
+ 0x96AF, 0x6C11,
+ 0x96B0, 0x7720,
+ 0x96B1, 0x52D9,
+ 0x96B2, 0x5922,
+ 0x96B3, 0x7121,
+ 0x96B4, 0x725F,
+ 0x96B5, 0x77DB,
+ 0x96B6, 0x9727,
+ 0x96B7, 0x9D61,
+ 0x96B8, 0x690B,
+ 0x96B9, 0x5A7F,
+ 0x96BA, 0x5A18,
+ 0x96BB, 0x51A5,
+ 0x96BC, 0x540D,
+ 0x96BD, 0x547D,
+ 0x96BE, 0x660E,
+ 0x96BF, 0x76DF,
+ 0x96C0, 0x8FF7,
+ 0x96C1, 0x9298,
+ 0x96C2, 0x9CF4,
+ 0x96C3, 0x59EA,
+ 0x96C4, 0x725D,
+ 0x96C5, 0x6EC5,
+ 0x96C6, 0x514D,
+ 0x96C7, 0x68C9,
+ 0x96C8, 0x7DBF,
+ 0x96C9, 0x7DEC,
+ 0x96CA, 0x9762,
+ 0x96CB, 0x9EBA,
+ 0x96CC, 0x6478,
+ 0x96CD, 0x6A21,
+ 0x96CE, 0x8302,
+ 0x96CF, 0x5984,
+ 0x96D0, 0x5B5F,
+ 0x96D1, 0x6BDB,
+ 0x96D2, 0x731B,
+ 0x96D3, 0x76F2,
+ 0x96D4, 0x7DB2,
+ 0x96D5, 0x8017,
+ 0x96D6, 0x8499,
+ 0x96D7, 0x5132,
+ 0x96D8, 0x6728,
+ 0x96D9, 0x9ED9,
+ 0x96DA, 0x76EE,
+ 0x96DB, 0x6762,
+ 0x96DC, 0x52FF,
+ 0x96DD, 0x9905,
+ 0x96DE, 0x5C24,
+ 0x96DF, 0x623B,
+ 0x96E0, 0x7C7E,
+ 0x96E1, 0x8CB0,
+ 0x96E2, 0x554F,
+ 0x96E3, 0x60B6,
+ 0x96E4, 0x7D0B,
+ 0x96E5, 0x9580,
+ 0x96E6, 0x5301,
+ 0x96E7, 0x4E5F,
+ 0x96E8, 0x51B6,
+ 0x96E9, 0x591C,
+ 0x96EA, 0x723A,
+ 0x96EB, 0x8036,
+ 0x96EC, 0x91CE,
+ 0x96ED, 0x5F25,
+ 0x96EE, 0x77E2,
+ 0x96EF, 0x5384,
+ 0x96F0, 0x5F79,
+ 0x96F1, 0x7D04,
+ 0x96F2, 0x85AC,
+ 0x96F3, 0x8A33,
+ 0x96F4, 0x8E8D,
+ 0x96F5, 0x9756,
+ 0x96F6, 0x67F3,
+ 0x96F7, 0x85AE,
+ 0x96F8, 0x9453,
+ 0x96F9, 0x6109,
+ 0x96FA, 0x6108,
+ 0x96FB, 0x6CB9,
+ 0x96FC, 0x7652,
+ 0x9740, 0x8AED,
+ 0x9741, 0x8F38,
+ 0x9742, 0x552F,
+ 0x9743, 0x4F51,
+ 0x9744, 0x512A,
+ 0x9745, 0x52C7,
+ 0x9746, 0x53CB,
+ 0x9747, 0x5BA5,
+ 0x9748, 0x5E7D,
+ 0x9749, 0x60A0,
+ 0x974A, 0x6182,
+ 0x974B, 0x63D6,
+ 0x974C, 0x6709,
+ 0x974D, 0x67DA,
+ 0x974E, 0x6E67,
+ 0x974F, 0x6D8C,
+ 0x9750, 0x7336,
+ 0x9751, 0x7337,
+ 0x9752, 0x7531,
+ 0x9753, 0x7950,
+ 0x9754, 0x88D5,
+ 0x9755, 0x8A98,
+ 0x9756, 0x904A,
+ 0x9757, 0x9091,
+ 0x9758, 0x90F5,
+ 0x9759, 0x96C4,
+ 0x975A, 0x878D,
+ 0x975B, 0x5915,
+ 0x975C, 0x4E88,
+ 0x975D, 0x4F59,
+ 0x975E, 0x4E0E,
+ 0x975F, 0x8A89,
+ 0x9760, 0x8F3F,
+ 0x9761, 0x9810,
+ 0x9762, 0x50AD,
+ 0x9763, 0x5E7C,
+ 0x9764, 0x5996,
+ 0x9765, 0x5BB9,
+ 0x9766, 0x5EB8,
+ 0x9767, 0x63DA,
+ 0x9768, 0x63FA,
+ 0x9769, 0x64C1,
+ 0x976A, 0x66DC,
+ 0x976B, 0x694A,
+ 0x976C, 0x69D8,
+ 0x976D, 0x6D0B,
+ 0x976E, 0x6EB6,
+ 0x976F, 0x7194,
+ 0x9770, 0x7528,
+ 0x9771, 0x7AAF,
+ 0x9772, 0x7F8A,
+ 0x9773, 0x8000,
+ 0x9774, 0x8449,
+ 0x9775, 0x84C9,
+ 0x9776, 0x8981,
+ 0x9777, 0x8B21,
+ 0x9778, 0x8E0A,
+ 0x9779, 0x9065,
+ 0x977A, 0x967D,
+ 0x977B, 0x990A,
+ 0x977C, 0x617E,
+ 0x977D, 0x6291,
+ 0x977E, 0x6B32,
+ 0x9780, 0x6C83,
+ 0x9781, 0x6D74,
+ 0x9782, 0x7FCC,
+ 0x9783, 0x7FFC,
+ 0x9784, 0x6DC0,
+ 0x9785, 0x7F85,
+ 0x9786, 0x87BA,
+ 0x9787, 0x88F8,
+ 0x9788, 0x6765,
+ 0x9789, 0x83B1,
+ 0x978A, 0x983C,
+ 0x978B, 0x96F7,
+ 0x978C, 0x6D1B,
+ 0x978D, 0x7D61,
+ 0x978E, 0x843D,
+ 0x978F, 0x916A,
+ 0x9790, 0x4E71,
+ 0x9791, 0x5375,
+ 0x9792, 0x5D50,
+ 0x9793, 0x6B04,
+ 0x9794, 0x6FEB,
+ 0x9795, 0x85CD,
+ 0x9796, 0x862D,
+ 0x9797, 0x89A7,
+ 0x9798, 0x5229,
+ 0x9799, 0x540F,
+ 0x979A, 0x5C65,
+ 0x979B, 0x674E,
+ 0x979C, 0x68A8,
+ 0x979D, 0x7406,
+ 0x979E, 0x7483,
+ 0x979F, 0x75E2,
+ 0x97A0, 0x88CF,
+ 0x97A1, 0x88E1,
+ 0x97A2, 0x91CC,
+ 0x97A3, 0x96E2,
+ 0x97A4, 0x9678,
+ 0x97A5, 0x5F8B,
+ 0x97A6, 0x7387,
+ 0x97A7, 0x7ACB,
+ 0x97A8, 0x844E,
+ 0x97A9, 0x63A0,
+ 0x97AA, 0x7565,
+ 0x97AB, 0x5289,
+ 0x97AC, 0x6D41,
+ 0x97AD, 0x6E9C,
+ 0x97AE, 0x7409,
+ 0x97AF, 0x7559,
+ 0x97B0, 0x786B,
+ 0x97B1, 0x7C92,
+ 0x97B2, 0x9686,
+ 0x97B3, 0x7ADC,
+ 0x97B4, 0x9F8D,
+ 0x97B5, 0x4FB6,
+ 0x97B6, 0x616E,
+ 0x97B7, 0x65C5,
+ 0x97B8, 0x865C,
+ 0x97B9, 0x4E86,
+ 0x97BA, 0x4EAE,
+ 0x97BB, 0x50DA,
+ 0x97BC, 0x4E21,
+ 0x97BD, 0x51CC,
+ 0x97BE, 0x5BEE,
+ 0x97BF, 0x6599,
+ 0x97C0, 0x6881,
+ 0x97C1, 0x6DBC,
+ 0x97C2, 0x731F,
+ 0x97C3, 0x7642,
+ 0x97C4, 0x77AD,
+ 0x97C5, 0x7A1C,
+ 0x97C6, 0x7CE7,
+ 0x97C7, 0x826F,
+ 0x97C8, 0x8AD2,
+ 0x97C9, 0x907C,
+ 0x97CA, 0x91CF,
+ 0x97CB, 0x9675,
+ 0x97CC, 0x9818,
+ 0x97CD, 0x529B,
+ 0x97CE, 0x7DD1,
+ 0x97CF, 0x502B,
+ 0x97D0, 0x5398,
+ 0x97D1, 0x6797,
+ 0x97D2, 0x6DCB,
+ 0x97D3, 0x71D0,
+ 0x97D4, 0x7433,
+ 0x97D5, 0x81E8,
+ 0x97D6, 0x8F2A,
+ 0x97D7, 0x96A3,
+ 0x97D8, 0x9C57,
+ 0x97D9, 0x9E9F,
+ 0x97DA, 0x7460,
+ 0x97DB, 0x5841,
+ 0x97DC, 0x6D99,
+ 0x97DD, 0x7D2F,
+ 0x97DE, 0x985E,
+ 0x97DF, 0x4EE4,
+ 0x97E0, 0x4F36,
+ 0x97E1, 0x4F8B,
+ 0x97E2, 0x51B7,
+ 0x97E3, 0x52B1,
+ 0x97E4, 0x5DBA,
+ 0x97E5, 0x601C,
+ 0x97E6, 0x73B2,
+ 0x97E7, 0x793C,
+ 0x97E8, 0x82D3,
+ 0x97E9, 0x9234,
+ 0x97EA, 0x96B7,
+ 0x97EB, 0x96F6,
+ 0x97EC, 0x970A,
+ 0x97ED, 0x9E97,
+ 0x97EE, 0x9F62,
+ 0x97EF, 0x66A6,
+ 0x97F0, 0x6B74,
+ 0x97F1, 0x5217,
+ 0x97F2, 0x52A3,
+ 0x97F3, 0x70C8,
+ 0x97F4, 0x88C2,
+ 0x97F5, 0x5EC9,
+ 0x97F6, 0x604B,
+ 0x97F7, 0x6190,
+ 0x97F8, 0x6F23,
+ 0x97F9, 0x7149,
+ 0x97FA, 0x7C3E,
+ 0x97FB, 0x7DF4,
+ 0x97FC, 0x806F,
+ 0x9840, 0x84EE,
+ 0x9841, 0x9023,
+ 0x9842, 0x932C,
+ 0x9843, 0x5442,
+ 0x9844, 0x9B6F,
+ 0x9845, 0x6AD3,
+ 0x9846, 0x7089,
+ 0x9847, 0x8CC2,
+ 0x9848, 0x8DEF,
+ 0x9849, 0x9732,
+ 0x984A, 0x52B4,
+ 0x984B, 0x5A41,
+ 0x984C, 0x5ECA,
+ 0x984D, 0x5F04,
+ 0x984E, 0x6717,
+ 0x984F, 0x697C,
+ 0x9850, 0x6994,
+ 0x9851, 0x6D6A,
+ 0x9852, 0x6F0F,
+ 0x9853, 0x7262,
+ 0x9854, 0x72FC,
+ 0x9855, 0x7BED,
+ 0x9856, 0x8001,
+ 0x9857, 0x807E,
+ 0x9858, 0x874B,
+ 0x9859, 0x90CE,
+ 0x985A, 0x516D,
+ 0x985B, 0x9E93,
+ 0x985C, 0x7984,
+ 0x985D, 0x808B,
+ 0x985E, 0x9332,
+ 0x985F, 0x8AD6,
+ 0x9860, 0x502D,
+ 0x9861, 0x548C,
+ 0x9862, 0x8A71,
+ 0x9863, 0x6B6A,
+ 0x9864, 0x8CC4,
+ 0x9865, 0x8107,
+ 0x9866, 0x60D1,
+ 0x9867, 0x67A0,
+ 0x9868, 0x9DF2,
+ 0x9869, 0x4E99,
+ 0x986A, 0x4E98,
+ 0x986B, 0x9C10,
+ 0x986C, 0x8A6B,
+ 0x986D, 0x85C1,
+ 0x986E, 0x8568,
+ 0x986F, 0x6900,
+ 0x9870, 0x6E7E,
+ 0x9871, 0x7897,
+ 0x9872, 0x8155,
+ 0x989F, 0x5F0C,
+ 0x98A0, 0x4E10,
+ 0x98A1, 0x4E15,
+ 0x98A2, 0x4E2A,
+ 0x98A3, 0x4E31,
+ 0x98A4, 0x4E36,
+ 0x98A5, 0x4E3C,
+ 0x98A6, 0x4E3F,
+ 0x98A7, 0x4E42,
+ 0x98A8, 0x4E56,
+ 0x98A9, 0x4E58,
+ 0x98AA, 0x4E82,
+ 0x98AB, 0x4E85,
+ 0x98AC, 0x8C6B,
+ 0x98AD, 0x4E8A,
+ 0x98AE, 0x8212,
+ 0x98AF, 0x5F0D,
+ 0x98B0, 0x4E8E,
+ 0x98B1, 0x4E9E,
+ 0x98B2, 0x4E9F,
+ 0x98B3, 0x4EA0,
+ 0x98B4, 0x4EA2,
+ 0x98B5, 0x4EB0,
+ 0x98B6, 0x4EB3,
+ 0x98B7, 0x4EB6,
+ 0x98B8, 0x4ECE,
+ 0x98B9, 0x4ECD,
+ 0x98BA, 0x4EC4,
+ 0x98BB, 0x4EC6,
+ 0x98BC, 0x4EC2,
+ 0x98BD, 0x4ED7,
+ 0x98BE, 0x4EDE,
+ 0x98BF, 0x4EED,
+ 0x98C0, 0x4EDF,
+ 0x98C1, 0x4EF7,
+ 0x98C2, 0x4F09,
+ 0x98C3, 0x4F5A,
+ 0x98C4, 0x4F30,
+ 0x98C5, 0x4F5B,
+ 0x98C6, 0x4F5D,
+ 0x98C7, 0x4F57,
+ 0x98C8, 0x4F47,
+ 0x98C9, 0x4F76,
+ 0x98CA, 0x4F88,
+ 0x98CB, 0x4F8F,
+ 0x98CC, 0x4F98,
+ 0x98CD, 0x4F7B,
+ 0x98CE, 0x4F69,
+ 0x98CF, 0x4F70,
+ 0x98D0, 0x4F91,
+ 0x98D1, 0x4F6F,
+ 0x98D2, 0x4F86,
+ 0x98D3, 0x4F96,
+ 0x98D4, 0x5118,
+ 0x98D5, 0x4FD4,
+ 0x98D6, 0x4FDF,
+ 0x98D7, 0x4FCE,
+ 0x98D8, 0x4FD8,
+ 0x98D9, 0x4FDB,
+ 0x98DA, 0x4FD1,
+ 0x98DB, 0x4FDA,
+ 0x98DC, 0x4FD0,
+ 0x98DD, 0x4FE4,
+ 0x98DE, 0x4FE5,
+ 0x98DF, 0x501A,
+ 0x98E0, 0x5028,
+ 0x98E1, 0x5014,
+ 0x98E2, 0x502A,
+ 0x98E3, 0x5025,
+ 0x98E4, 0x5005,
+ 0x98E5, 0x4F1C,
+ 0x98E6, 0x4FF6,
+ 0x98E7, 0x5021,
+ 0x98E8, 0x5029,
+ 0x98E9, 0x502C,
+ 0x98EA, 0x4FFE,
+ 0x98EB, 0x4FEF,
+ 0x98EC, 0x5011,
+ 0x98ED, 0x5006,
+ 0x98EE, 0x5043,
+ 0x98EF, 0x5047,
+ 0x98F0, 0x6703,
+ 0x98F1, 0x5055,
+ 0x98F2, 0x5050,
+ 0x98F3, 0x5048,
+ 0x98F4, 0x505A,
+ 0x98F5, 0x5056,
+ 0x98F6, 0x506C,
+ 0x98F7, 0x5078,
+ 0x98F8, 0x5080,
+ 0x98F9, 0x509A,
+ 0x98FA, 0x5085,
+ 0x98FB, 0x50B4,
+ 0x98FC, 0x50B2,
+ 0x9940, 0x50C9,
+ 0x9941, 0x50CA,
+ 0x9942, 0x50B3,
+ 0x9943, 0x50C2,
+ 0x9944, 0x50D6,
+ 0x9945, 0x50DE,
+ 0x9946, 0x50E5,
+ 0x9947, 0x50ED,
+ 0x9948, 0x50E3,
+ 0x9949, 0x50EE,
+ 0x994A, 0x50F9,
+ 0x994B, 0x50F5,
+ 0x994C, 0x5109,
+ 0x994D, 0x5101,
+ 0x994E, 0x5102,
+ 0x994F, 0x5116,
+ 0x9950, 0x5115,
+ 0x9951, 0x5114,
+ 0x9952, 0x511A,
+ 0x9953, 0x5121,
+ 0x9954, 0x513A,
+ 0x9955, 0x5137,
+ 0x9956, 0x513C,
+ 0x9957, 0x513B,
+ 0x9958, 0x513F,
+ 0x9959, 0x5140,
+ 0x995A, 0x5152,
+ 0x995B, 0x514C,
+ 0x995C, 0x5154,
+ 0x995D, 0x5162,
+ 0x995E, 0x7AF8,
+ 0x995F, 0x5169,
+ 0x9960, 0x516A,
+ 0x9961, 0x516E,
+ 0x9962, 0x5180,
+ 0x9963, 0x5182,
+ 0x9964, 0x56D8,
+ 0x9965, 0x518C,
+ 0x9966, 0x5189,
+ 0x9967, 0x518F,
+ 0x9968, 0x5191,
+ 0x9969, 0x5193,
+ 0x996A, 0x5195,
+ 0x996B, 0x5196,
+ 0x996C, 0x51A4,
+ 0x996D, 0x51A6,
+ 0x996E, 0x51A2,
+ 0x996F, 0x51A9,
+ 0x9970, 0x51AA,
+ 0x9971, 0x51AB,
+ 0x9972, 0x51B3,
+ 0x9973, 0x51B1,
+ 0x9974, 0x51B2,
+ 0x9975, 0x51B0,
+ 0x9976, 0x51B5,
+ 0x9977, 0x51BD,
+ 0x9978, 0x51C5,
+ 0x9979, 0x51C9,
+ 0x997A, 0x51DB,
+ 0x997B, 0x51E0,
+ 0x997C, 0x8655,
+ 0x997D, 0x51E9,
+ 0x997E, 0x51ED,
+ 0x9980, 0x51F0,
+ 0x9981, 0x51F5,
+ 0x9982, 0x51FE,
+ 0x9983, 0x5204,
+ 0x9984, 0x520B,
+ 0x9985, 0x5214,
+ 0x9986, 0x520E,
+ 0x9987, 0x5227,
+ 0x9988, 0x522A,
+ 0x9989, 0x522E,
+ 0x998A, 0x5233,
+ 0x998B, 0x5239,
+ 0x998C, 0x524F,
+ 0x998D, 0x5244,
+ 0x998E, 0x524B,
+ 0x998F, 0x524C,
+ 0x9990, 0x525E,
+ 0x9991, 0x5254,
+ 0x9992, 0x526A,
+ 0x9993, 0x5274,
+ 0x9994, 0x5269,
+ 0x9995, 0x5273,
+ 0x9996, 0x527F,
+ 0x9997, 0x527D,
+ 0x9998, 0x528D,
+ 0x9999, 0x5294,
+ 0x999A, 0x5292,
+ 0x999B, 0x5271,
+ 0x999C, 0x5288,
+ 0x999D, 0x5291,
+ 0x999E, 0x8FA8,
+ 0x999F, 0x8FA7,
+ 0x99A0, 0x52AC,
+ 0x99A1, 0x52AD,
+ 0x99A2, 0x52BC,
+ 0x99A3, 0x52B5,
+ 0x99A4, 0x52C1,
+ 0x99A5, 0x52CD,
+ 0x99A6, 0x52D7,
+ 0x99A7, 0x52DE,
+ 0x99A8, 0x52E3,
+ 0x99A9, 0x52E6,
+ 0x99AA, 0x98ED,
+ 0x99AB, 0x52E0,
+ 0x99AC, 0x52F3,
+ 0x99AD, 0x52F5,
+ 0x99AE, 0x52F8,
+ 0x99AF, 0x52F9,
+ 0x99B0, 0x5306,
+ 0x99B1, 0x5308,
+ 0x99B2, 0x7538,
+ 0x99B3, 0x530D,
+ 0x99B4, 0x5310,
+ 0x99B5, 0x530F,
+ 0x99B6, 0x5315,
+ 0x99B7, 0x531A,
+ 0x99B8, 0x5323,
+ 0x99B9, 0x532F,
+ 0x99BA, 0x5331,
+ 0x99BB, 0x5333,
+ 0x99BC, 0x5338,
+ 0x99BD, 0x5340,
+ 0x99BE, 0x5346,
+ 0x99BF, 0x5345,
+ 0x99C0, 0x4E17,
+ 0x99C1, 0x5349,
+ 0x99C2, 0x534D,
+ 0x99C3, 0x51D6,
+ 0x99C4, 0x535E,
+ 0x99C5, 0x5369,
+ 0x99C6, 0x536E,
+ 0x99C7, 0x5918,
+ 0x99C8, 0x537B,
+ 0x99C9, 0x5377,
+ 0x99CA, 0x5382,
+ 0x99CB, 0x5396,
+ 0x99CC, 0x53A0,
+ 0x99CD, 0x53A6,
+ 0x99CE, 0x53A5,
+ 0x99CF, 0x53AE,
+ 0x99D0, 0x53B0,
+ 0x99D1, 0x53B6,
+ 0x99D2, 0x53C3,
+ 0x99D3, 0x7C12,
+ 0x99D4, 0x96D9,
+ 0x99D5, 0x53DF,
+ 0x99D6, 0x66FC,
+ 0x99D7, 0x71EE,
+ 0x99D8, 0x53EE,
+ 0x99D9, 0x53E8,
+ 0x99DA, 0x53ED,
+ 0x99DB, 0x53FA,
+ 0x99DC, 0x5401,
+ 0x99DD, 0x543D,
+ 0x99DE, 0x5440,
+ 0x99DF, 0x542C,
+ 0x99E0, 0x542D,
+ 0x99E1, 0x543C,
+ 0x99E2, 0x542E,
+ 0x99E3, 0x5436,
+ 0x99E4, 0x5429,
+ 0x99E5, 0x541D,
+ 0x99E6, 0x544E,
+ 0x99E7, 0x548F,
+ 0x99E8, 0x5475,
+ 0x99E9, 0x548E,
+ 0x99EA, 0x545F,
+ 0x99EB, 0x5471,
+ 0x99EC, 0x5477,
+ 0x99ED, 0x5470,
+ 0x99EE, 0x5492,
+ 0x99EF, 0x547B,
+ 0x99F0, 0x5480,
+ 0x99F1, 0x5476,
+ 0x99F2, 0x5484,
+ 0x99F3, 0x5490,
+ 0x99F4, 0x5486,
+ 0x99F5, 0x54C7,
+ 0x99F6, 0x54A2,
+ 0x99F7, 0x54B8,
+ 0x99F8, 0x54A5,
+ 0x99F9, 0x54AC,
+ 0x99FA, 0x54C4,
+ 0x99FB, 0x54C8,
+ 0x99FC, 0x54A8,
+ 0x9A40, 0x54AB,
+ 0x9A41, 0x54C2,
+ 0x9A42, 0x54A4,
+ 0x9A43, 0x54BE,
+ 0x9A44, 0x54BC,
+ 0x9A45, 0x54D8,
+ 0x9A46, 0x54E5,
+ 0x9A47, 0x54E6,
+ 0x9A48, 0x550F,
+ 0x9A49, 0x5514,
+ 0x9A4A, 0x54FD,
+ 0x9A4B, 0x54EE,
+ 0x9A4C, 0x54ED,
+ 0x9A4D, 0x54FA,
+ 0x9A4E, 0x54E2,
+ 0x9A4F, 0x5539,
+ 0x9A50, 0x5540,
+ 0x9A51, 0x5563,
+ 0x9A52, 0x554C,
+ 0x9A53, 0x552E,
+ 0x9A54, 0x555C,
+ 0x9A55, 0x5545,
+ 0x9A56, 0x5556,
+ 0x9A57, 0x5557,
+ 0x9A58, 0x5538,
+ 0x9A59, 0x5533,
+ 0x9A5A, 0x555D,
+ 0x9A5B, 0x5599,
+ 0x9A5C, 0x5580,
+ 0x9A5D, 0x54AF,
+ 0x9A5E, 0x558A,
+ 0x9A5F, 0x559F,
+ 0x9A60, 0x557B,
+ 0x9A61, 0x557E,
+ 0x9A62, 0x5598,
+ 0x9A63, 0x559E,
+ 0x9A64, 0x55AE,
+ 0x9A65, 0x557C,
+ 0x9A66, 0x5583,
+ 0x9A67, 0x55A9,
+ 0x9A68, 0x5587,
+ 0x9A69, 0x55A8,
+ 0x9A6A, 0x55DA,
+ 0x9A6B, 0x55C5,
+ 0x9A6C, 0x55DF,
+ 0x9A6D, 0x55C4,
+ 0x9A6E, 0x55DC,
+ 0x9A6F, 0x55E4,
+ 0x9A70, 0x55D4,
+ 0x9A71, 0x5614,
+ 0x9A72, 0x55F7,
+ 0x9A73, 0x5616,
+ 0x9A74, 0x55FE,
+ 0x9A75, 0x55FD,
+ 0x9A76, 0x561B,
+ 0x9A77, 0x55F9,
+ 0x9A78, 0x564E,
+ 0x9A79, 0x5650,
+ 0x9A7A, 0x71DF,
+ 0x9A7B, 0x5634,
+ 0x9A7C, 0x5636,
+ 0x9A7D, 0x5632,
+ 0x9A7E, 0x5638,
+ 0x9A80, 0x566B,
+ 0x9A81, 0x5664,
+ 0x9A82, 0x562F,
+ 0x9A83, 0x566C,
+ 0x9A84, 0x566A,
+ 0x9A85, 0x5686,
+ 0x9A86, 0x5680,
+ 0x9A87, 0x568A,
+ 0x9A88, 0x56A0,
+ 0x9A89, 0x5694,
+ 0x9A8A, 0x568F,
+ 0x9A8B, 0x56A5,
+ 0x9A8C, 0x56AE,
+ 0x9A8D, 0x56B6,
+ 0x9A8E, 0x56B4,
+ 0x9A8F, 0x56C2,
+ 0x9A90, 0x56BC,
+ 0x9A91, 0x56C1,
+ 0x9A92, 0x56C3,
+ 0x9A93, 0x56C0,
+ 0x9A94, 0x56C8,
+ 0x9A95, 0x56CE,
+ 0x9A96, 0x56D1,
+ 0x9A97, 0x56D3,
+ 0x9A98, 0x56D7,
+ 0x9A99, 0x56EE,
+ 0x9A9A, 0x56F9,
+ 0x9A9B, 0x5700,
+ 0x9A9C, 0x56FF,
+ 0x9A9D, 0x5704,
+ 0x9A9E, 0x5709,
+ 0x9A9F, 0x5708,
+ 0x9AA0, 0x570B,
+ 0x9AA1, 0x570D,
+ 0x9AA2, 0x5713,
+ 0x9AA3, 0x5718,
+ 0x9AA4, 0x5716,
+ 0x9AA5, 0x55C7,
+ 0x9AA6, 0x571C,
+ 0x9AA7, 0x5726,
+ 0x9AA8, 0x5737,
+ 0x9AA9, 0x5738,
+ 0x9AAA, 0x574E,
+ 0x9AAB, 0x573B,
+ 0x9AAC, 0x5740,
+ 0x9AAD, 0x574F,
+ 0x9AAE, 0x5769,
+ 0x9AAF, 0x57C0,
+ 0x9AB0, 0x5788,
+ 0x9AB1, 0x5761,
+ 0x9AB2, 0x577F,
+ 0x9AB3, 0x5789,
+ 0x9AB4, 0x5793,
+ 0x9AB5, 0x57A0,
+ 0x9AB6, 0x57B3,
+ 0x9AB7, 0x57A4,
+ 0x9AB8, 0x57AA,
+ 0x9AB9, 0x57B0,
+ 0x9ABA, 0x57C3,
+ 0x9ABB, 0x57C6,
+ 0x9ABC, 0x57D4,
+ 0x9ABD, 0x57D2,
+ 0x9ABE, 0x57D3,
+ 0x9ABF, 0x580A,
+ 0x9AC0, 0x57D6,
+ 0x9AC1, 0x57E3,
+ 0x9AC2, 0x580B,
+ 0x9AC3, 0x5819,
+ 0x9AC4, 0x581D,
+ 0x9AC5, 0x5872,
+ 0x9AC6, 0x5821,
+ 0x9AC7, 0x5862,
+ 0x9AC8, 0x584B,
+ 0x9AC9, 0x5870,
+ 0x9ACA, 0x6BC0,
+ 0x9ACB, 0x5852,
+ 0x9ACC, 0x583D,
+ 0x9ACD, 0x5879,
+ 0x9ACE, 0x5885,
+ 0x9ACF, 0x58B9,
+ 0x9AD0, 0x589F,
+ 0x9AD1, 0x58AB,
+ 0x9AD2, 0x58BA,
+ 0x9AD3, 0x58DE,
+ 0x9AD4, 0x58BB,
+ 0x9AD5, 0x58B8,
+ 0x9AD6, 0x58AE,
+ 0x9AD7, 0x58C5,
+ 0x9AD8, 0x58D3,
+ 0x9AD9, 0x58D1,
+ 0x9ADA, 0x58D7,
+ 0x9ADB, 0x58D9,
+ 0x9ADC, 0x58D8,
+ 0x9ADD, 0x58E5,
+ 0x9ADE, 0x58DC,
+ 0x9ADF, 0x58E4,
+ 0x9AE0, 0x58DF,
+ 0x9AE1, 0x58EF,
+ 0x9AE2, 0x58FA,
+ 0x9AE3, 0x58F9,
+ 0x9AE4, 0x58FB,
+ 0x9AE5, 0x58FC,
+ 0x9AE6, 0x58FD,
+ 0x9AE7, 0x5902,
+ 0x9AE8, 0x590A,
+ 0x9AE9, 0x5910,
+ 0x9AEA, 0x591B,
+ 0x9AEB, 0x68A6,
+ 0x9AEC, 0x5925,
+ 0x9AED, 0x592C,
+ 0x9AEE, 0x592D,
+ 0x9AEF, 0x5932,
+ 0x9AF0, 0x5938,
+ 0x9AF1, 0x593E,
+ 0x9AF2, 0x7AD2,
+ 0x9AF3, 0x5955,
+ 0x9AF4, 0x5950,
+ 0x9AF5, 0x594E,
+ 0x9AF6, 0x595A,
+ 0x9AF7, 0x5958,
+ 0x9AF8, 0x5962,
+ 0x9AF9, 0x5960,
+ 0x9AFA, 0x5967,
+ 0x9AFB, 0x596C,
+ 0x9AFC, 0x5969,
+ 0x9B40, 0x5978,
+ 0x9B41, 0x5981,
+ 0x9B42, 0x599D,
+ 0x9B43, 0x4F5E,
+ 0x9B44, 0x4FAB,
+ 0x9B45, 0x59A3,
+ 0x9B46, 0x59B2,
+ 0x9B47, 0x59C6,
+ 0x9B48, 0x59E8,
+ 0x9B49, 0x59DC,
+ 0x9B4A, 0x598D,
+ 0x9B4B, 0x59D9,
+ 0x9B4C, 0x59DA,
+ 0x9B4D, 0x5A25,
+ 0x9B4E, 0x5A1F,
+ 0x9B4F, 0x5A11,
+ 0x9B50, 0x5A1C,
+ 0x9B51, 0x5A09,
+ 0x9B52, 0x5A1A,
+ 0x9B53, 0x5A40,
+ 0x9B54, 0x5A6C,
+ 0x9B55, 0x5A49,
+ 0x9B56, 0x5A35,
+ 0x9B57, 0x5A36,
+ 0x9B58, 0x5A62,
+ 0x9B59, 0x5A6A,
+ 0x9B5A, 0x5A9A,
+ 0x9B5B, 0x5ABC,
+ 0x9B5C, 0x5ABE,
+ 0x9B5D, 0x5ACB,
+ 0x9B5E, 0x5AC2,
+ 0x9B5F, 0x5ABD,
+ 0x9B60, 0x5AE3,
+ 0x9B61, 0x5AD7,
+ 0x9B62, 0x5AE6,
+ 0x9B63, 0x5AE9,
+ 0x9B64, 0x5AD6,
+ 0x9B65, 0x5AFA,
+ 0x9B66, 0x5AFB,
+ 0x9B67, 0x5B0C,
+ 0x9B68, 0x5B0B,
+ 0x9B69, 0x5B16,
+ 0x9B6A, 0x5B32,
+ 0x9B6B, 0x5AD0,
+ 0x9B6C, 0x5B2A,
+ 0x9B6D, 0x5B36,
+ 0x9B6E, 0x5B3E,
+ 0x9B6F, 0x5B43,
+ 0x9B70, 0x5B45,
+ 0x9B71, 0x5B40,
+ 0x9B72, 0x5B51,
+ 0x9B73, 0x5B55,
+ 0x9B74, 0x5B5A,
+ 0x9B75, 0x5B5B,
+ 0x9B76, 0x5B65,
+ 0x9B77, 0x5B69,
+ 0x9B78, 0x5B70,
+ 0x9B79, 0x5B73,
+ 0x9B7A, 0x5B75,
+ 0x9B7B, 0x5B78,
+ 0x9B7C, 0x6588,
+ 0x9B7D, 0x5B7A,
+ 0x9B7E, 0x5B80,
+ 0x9B80, 0x5B83,
+ 0x9B81, 0x5BA6,
+ 0x9B82, 0x5BB8,
+ 0x9B83, 0x5BC3,
+ 0x9B84, 0x5BC7,
+ 0x9B85, 0x5BC9,
+ 0x9B86, 0x5BD4,
+ 0x9B87, 0x5BD0,
+ 0x9B88, 0x5BE4,
+ 0x9B89, 0x5BE6,
+ 0x9B8A, 0x5BE2,
+ 0x9B8B, 0x5BDE,
+ 0x9B8C, 0x5BE5,
+ 0x9B8D, 0x5BEB,
+ 0x9B8E, 0x5BF0,
+ 0x9B8F, 0x5BF6,
+ 0x9B90, 0x5BF3,
+ 0x9B91, 0x5C05,
+ 0x9B92, 0x5C07,
+ 0x9B93, 0x5C08,
+ 0x9B94, 0x5C0D,
+ 0x9B95, 0x5C13,
+ 0x9B96, 0x5C20,
+ 0x9B97, 0x5C22,
+ 0x9B98, 0x5C28,
+ 0x9B99, 0x5C38,
+ 0x9B9A, 0x5C39,
+ 0x9B9B, 0x5C41,
+ 0x9B9C, 0x5C46,
+ 0x9B9D, 0x5C4E,
+ 0x9B9E, 0x5C53,
+ 0x9B9F, 0x5C50,
+ 0x9BA0, 0x5C4F,
+ 0x9BA1, 0x5B71,
+ 0x9BA2, 0x5C6C,
+ 0x9BA3, 0x5C6E,
+ 0x9BA4, 0x4E62,
+ 0x9BA5, 0x5C76,
+ 0x9BA6, 0x5C79,
+ 0x9BA7, 0x5C8C,
+ 0x9BA8, 0x5C91,
+ 0x9BA9, 0x5C94,
+ 0x9BAA, 0x599B,
+ 0x9BAB, 0x5CAB,
+ 0x9BAC, 0x5CBB,
+ 0x9BAD, 0x5CB6,
+ 0x9BAE, 0x5CBC,
+ 0x9BAF, 0x5CB7,
+ 0x9BB0, 0x5CC5,
+ 0x9BB1, 0x5CBE,
+ 0x9BB2, 0x5CC7,
+ 0x9BB3, 0x5CD9,
+ 0x9BB4, 0x5CE9,
+ 0x9BB5, 0x5CFD,
+ 0x9BB6, 0x5CFA,
+ 0x9BB7, 0x5CED,
+ 0x9BB8, 0x5D8C,
+ 0x9BB9, 0x5CEA,
+ 0x9BBA, 0x5D0B,
+ 0x9BBB, 0x5D15,
+ 0x9BBC, 0x5D17,
+ 0x9BBD, 0x5D5C,
+ 0x9BBE, 0x5D1F,
+ 0x9BBF, 0x5D1B,
+ 0x9BC0, 0x5D11,
+ 0x9BC1, 0x5D14,
+ 0x9BC2, 0x5D22,
+ 0x9BC3, 0x5D1A,
+ 0x9BC4, 0x5D19,
+ 0x9BC5, 0x5D18,
+ 0x9BC6, 0x5D4C,
+ 0x9BC7, 0x5D52,
+ 0x9BC8, 0x5D4E,
+ 0x9BC9, 0x5D4B,
+ 0x9BCA, 0x5D6C,
+ 0x9BCB, 0x5D73,
+ 0x9BCC, 0x5D76,
+ 0x9BCD, 0x5D87,
+ 0x9BCE, 0x5D84,
+ 0x9BCF, 0x5D82,
+ 0x9BD0, 0x5DA2,
+ 0x9BD1, 0x5D9D,
+ 0x9BD2, 0x5DAC,
+ 0x9BD3, 0x5DAE,
+ 0x9BD4, 0x5DBD,
+ 0x9BD5, 0x5D90,
+ 0x9BD6, 0x5DB7,
+ 0x9BD7, 0x5DBC,
+ 0x9BD8, 0x5DC9,
+ 0x9BD9, 0x5DCD,
+ 0x9BDA, 0x5DD3,
+ 0x9BDB, 0x5DD2,
+ 0x9BDC, 0x5DD6,
+ 0x9BDD, 0x5DDB,
+ 0x9BDE, 0x5DEB,
+ 0x9BDF, 0x5DF2,
+ 0x9BE0, 0x5DF5,
+ 0x9BE1, 0x5E0B,
+ 0x9BE2, 0x5E1A,
+ 0x9BE3, 0x5E19,
+ 0x9BE4, 0x5E11,
+ 0x9BE5, 0x5E1B,
+ 0x9BE6, 0x5E36,
+ 0x9BE7, 0x5E37,
+ 0x9BE8, 0x5E44,
+ 0x9BE9, 0x5E43,
+ 0x9BEA, 0x5E40,
+ 0x9BEB, 0x5E4E,
+ 0x9BEC, 0x5E57,
+ 0x9BED, 0x5E54,
+ 0x9BEE, 0x5E5F,
+ 0x9BEF, 0x5E62,
+ 0x9BF0, 0x5E64,
+ 0x9BF1, 0x5E47,
+ 0x9BF2, 0x5E75,
+ 0x9BF3, 0x5E76,
+ 0x9BF4, 0x5E7A,
+ 0x9BF5, 0x9EBC,
+ 0x9BF6, 0x5E7F,
+ 0x9BF7, 0x5EA0,
+ 0x9BF8, 0x5EC1,
+ 0x9BF9, 0x5EC2,
+ 0x9BFA, 0x5EC8,
+ 0x9BFB, 0x5ED0,
+ 0x9BFC, 0x5ECF,
+ 0x9C40, 0x5ED6,
+ 0x9C41, 0x5EE3,
+ 0x9C42, 0x5EDD,
+ 0x9C43, 0x5EDA,
+ 0x9C44, 0x5EDB,
+ 0x9C45, 0x5EE2,
+ 0x9C46, 0x5EE1,
+ 0x9C47, 0x5EE8,
+ 0x9C48, 0x5EE9,
+ 0x9C49, 0x5EEC,
+ 0x9C4A, 0x5EF1,
+ 0x9C4B, 0x5EF3,
+ 0x9C4C, 0x5EF0,
+ 0x9C4D, 0x5EF4,
+ 0x9C4E, 0x5EF8,
+ 0x9C4F, 0x5EFE,
+ 0x9C50, 0x5F03,
+ 0x9C51, 0x5F09,
+ 0x9C52, 0x5F5D,
+ 0x9C53, 0x5F5C,
+ 0x9C54, 0x5F0B,
+ 0x9C55, 0x5F11,
+ 0x9C56, 0x5F16,
+ 0x9C57, 0x5F29,
+ 0x9C58, 0x5F2D,
+ 0x9C59, 0x5F38,
+ 0x9C5A, 0x5F41,
+ 0x9C5B, 0x5F48,
+ 0x9C5C, 0x5F4C,
+ 0x9C5D, 0x5F4E,
+ 0x9C5E, 0x5F2F,
+ 0x9C5F, 0x5F51,
+ 0x9C60, 0x5F56,
+ 0x9C61, 0x5F57,
+ 0x9C62, 0x5F59,
+ 0x9C63, 0x5F61,
+ 0x9C64, 0x5F6D,
+ 0x9C65, 0x5F73,
+ 0x9C66, 0x5F77,
+ 0x9C67, 0x5F83,
+ 0x9C68, 0x5F82,
+ 0x9C69, 0x5F7F,
+ 0x9C6A, 0x5F8A,
+ 0x9C6B, 0x5F88,
+ 0x9C6C, 0x5F91,
+ 0x9C6D, 0x5F87,
+ 0x9C6E, 0x5F9E,
+ 0x9C6F, 0x5F99,
+ 0x9C70, 0x5F98,
+ 0x9C71, 0x5FA0,
+ 0x9C72, 0x5FA8,
+ 0x9C73, 0x5FAD,
+ 0x9C74, 0x5FBC,
+ 0x9C75, 0x5FD6,
+ 0x9C76, 0x5FFB,
+ 0x9C77, 0x5FE4,
+ 0x9C78, 0x5FF8,
+ 0x9C79, 0x5FF1,
+ 0x9C7A, 0x5FDD,
+ 0x9C7B, 0x60B3,
+ 0x9C7C, 0x5FFF,
+ 0x9C7D, 0x6021,
+ 0x9C7E, 0x6060,
+ 0x9C80, 0x6019,
+ 0x9C81, 0x6010,
+ 0x9C82, 0x6029,
+ 0x9C83, 0x600E,
+ 0x9C84, 0x6031,
+ 0x9C85, 0x601B,
+ 0x9C86, 0x6015,
+ 0x9C87, 0x602B,
+ 0x9C88, 0x6026,
+ 0x9C89, 0x600F,
+ 0x9C8A, 0x603A,
+ 0x9C8B, 0x605A,
+ 0x9C8C, 0x6041,
+ 0x9C8D, 0x606A,
+ 0x9C8E, 0x6077,
+ 0x9C8F, 0x605F,
+ 0x9C90, 0x604A,
+ 0x9C91, 0x6046,
+ 0x9C92, 0x604D,
+ 0x9C93, 0x6063,
+ 0x9C94, 0x6043,
+ 0x9C95, 0x6064,
+ 0x9C96, 0x6042,
+ 0x9C97, 0x606C,
+ 0x9C98, 0x606B,
+ 0x9C99, 0x6059,
+ 0x9C9A, 0x6081,
+ 0x9C9B, 0x608D,
+ 0x9C9C, 0x60E7,
+ 0x9C9D, 0x6083,
+ 0x9C9E, 0x609A,
+ 0x9C9F, 0x6084,
+ 0x9CA0, 0x609B,
+ 0x9CA1, 0x6096,
+ 0x9CA2, 0x6097,
+ 0x9CA3, 0x6092,
+ 0x9CA4, 0x60A7,
+ 0x9CA5, 0x608B,
+ 0x9CA6, 0x60E1,
+ 0x9CA7, 0x60B8,
+ 0x9CA8, 0x60E0,
+ 0x9CA9, 0x60D3,
+ 0x9CAA, 0x60B4,
+ 0x9CAB, 0x5FF0,
+ 0x9CAC, 0x60BD,
+ 0x9CAD, 0x60C6,
+ 0x9CAE, 0x60B5,
+ 0x9CAF, 0x60D8,
+ 0x9CB0, 0x614D,
+ 0x9CB1, 0x6115,
+ 0x9CB2, 0x6106,
+ 0x9CB3, 0x60F6,
+ 0x9CB4, 0x60F7,
+ 0x9CB5, 0x6100,
+ 0x9CB6, 0x60F4,
+ 0x9CB7, 0x60FA,
+ 0x9CB8, 0x6103,
+ 0x9CB9, 0x6121,
+ 0x9CBA, 0x60FB,
+ 0x9CBB, 0x60F1,
+ 0x9CBC, 0x610D,
+ 0x9CBD, 0x610E,
+ 0x9CBE, 0x6147,
+ 0x9CBF, 0x613E,
+ 0x9CC0, 0x6128,
+ 0x9CC1, 0x6127,
+ 0x9CC2, 0x614A,
+ 0x9CC3, 0x613F,
+ 0x9CC4, 0x613C,
+ 0x9CC5, 0x612C,
+ 0x9CC6, 0x6134,
+ 0x9CC7, 0x613D,
+ 0x9CC8, 0x6142,
+ 0x9CC9, 0x6144,
+ 0x9CCA, 0x6173,
+ 0x9CCB, 0x6177,
+ 0x9CCC, 0x6158,
+ 0x9CCD, 0x6159,
+ 0x9CCE, 0x615A,
+ 0x9CCF, 0x616B,
+ 0x9CD0, 0x6174,
+ 0x9CD1, 0x616F,
+ 0x9CD2, 0x6165,
+ 0x9CD3, 0x6171,
+ 0x9CD4, 0x615F,
+ 0x9CD5, 0x615D,
+ 0x9CD6, 0x6153,
+ 0x9CD7, 0x6175,
+ 0x9CD8, 0x6199,
+ 0x9CD9, 0x6196,
+ 0x9CDA, 0x6187,
+ 0x9CDB, 0x61AC,
+ 0x9CDC, 0x6194,
+ 0x9CDD, 0x619A,
+ 0x9CDE, 0x618A,
+ 0x9CDF, 0x6191,
+ 0x9CE0, 0x61AB,
+ 0x9CE1, 0x61AE,
+ 0x9CE2, 0x61CC,
+ 0x9CE3, 0x61CA,
+ 0x9CE4, 0x61C9,
+ 0x9CE5, 0x61F7,
+ 0x9CE6, 0x61C8,
+ 0x9CE7, 0x61C3,
+ 0x9CE8, 0x61C6,
+ 0x9CE9, 0x61BA,
+ 0x9CEA, 0x61CB,
+ 0x9CEB, 0x7F79,
+ 0x9CEC, 0x61CD,
+ 0x9CED, 0x61E6,
+ 0x9CEE, 0x61E3,
+ 0x9CEF, 0x61F6,
+ 0x9CF0, 0x61FA,
+ 0x9CF1, 0x61F4,
+ 0x9CF2, 0x61FF,
+ 0x9CF3, 0x61FD,
+ 0x9CF4, 0x61FC,
+ 0x9CF5, 0x61FE,
+ 0x9CF6, 0x6200,
+ 0x9CF7, 0x6208,
+ 0x9CF8, 0x6209,
+ 0x9CF9, 0x620D,
+ 0x9CFA, 0x620C,
+ 0x9CFB, 0x6214,
+ 0x9CFC, 0x621B,
+ 0x9D40, 0x621E,
+ 0x9D41, 0x6221,
+ 0x9D42, 0x622A,
+ 0x9D43, 0x622E,
+ 0x9D44, 0x6230,
+ 0x9D45, 0x6232,
+ 0x9D46, 0x6233,
+ 0x9D47, 0x6241,
+ 0x9D48, 0x624E,
+ 0x9D49, 0x625E,
+ 0x9D4A, 0x6263,
+ 0x9D4B, 0x625B,
+ 0x9D4C, 0x6260,
+ 0x9D4D, 0x6268,
+ 0x9D4E, 0x627C,
+ 0x9D4F, 0x6282,
+ 0x9D50, 0x6289,
+ 0x9D51, 0x627E,
+ 0x9D52, 0x6292,
+ 0x9D53, 0x6293,
+ 0x9D54, 0x6296,
+ 0x9D55, 0x62D4,
+ 0x9D56, 0x6283,
+ 0x9D57, 0x6294,
+ 0x9D58, 0x62D7,
+ 0x9D59, 0x62D1,
+ 0x9D5A, 0x62BB,
+ 0x9D5B, 0x62CF,
+ 0x9D5C, 0x62FF,
+ 0x9D5D, 0x62C6,
+ 0x9D5E, 0x64D4,
+ 0x9D5F, 0x62C8,
+ 0x9D60, 0x62DC,
+ 0x9D61, 0x62CC,
+ 0x9D62, 0x62CA,
+ 0x9D63, 0x62C2,
+ 0x9D64, 0x62C7,
+ 0x9D65, 0x629B,
+ 0x9D66, 0x62C9,
+ 0x9D67, 0x630C,
+ 0x9D68, 0x62EE,
+ 0x9D69, 0x62F1,
+ 0x9D6A, 0x6327,
+ 0x9D6B, 0x6302,
+ 0x9D6C, 0x6308,
+ 0x9D6D, 0x62EF,
+ 0x9D6E, 0x62F5,
+ 0x9D6F, 0x6350,
+ 0x9D70, 0x633E,
+ 0x9D71, 0x634D,
+ 0x9D72, 0x641C,
+ 0x9D73, 0x634F,
+ 0x9D74, 0x6396,
+ 0x9D75, 0x638E,
+ 0x9D76, 0x6380,
+ 0x9D77, 0x63AB,
+ 0x9D78, 0x6376,
+ 0x9D79, 0x63A3,
+ 0x9D7A, 0x638F,
+ 0x9D7B, 0x6389,
+ 0x9D7C, 0x639F,
+ 0x9D7D, 0x63B5,
+ 0x9D7E, 0x636B,
+ 0x9D80, 0x6369,
+ 0x9D81, 0x63BE,
+ 0x9D82, 0x63E9,
+ 0x9D83, 0x63C0,
+ 0x9D84, 0x63C6,
+ 0x9D85, 0x63E3,
+ 0x9D86, 0x63C9,
+ 0x9D87, 0x63D2,
+ 0x9D88, 0x63F6,
+ 0x9D89, 0x63C4,
+ 0x9D8A, 0x6416,
+ 0x9D8B, 0x6434,
+ 0x9D8C, 0x6406,
+ 0x9D8D, 0x6413,
+ 0x9D8E, 0x6426,
+ 0x9D8F, 0x6436,
+ 0x9D90, 0x651D,
+ 0x9D91, 0x6417,
+ 0x9D92, 0x6428,
+ 0x9D93, 0x640F,
+ 0x9D94, 0x6467,
+ 0x9D95, 0x646F,
+ 0x9D96, 0x6476,
+ 0x9D97, 0x644E,
+ 0x9D98, 0x652A,
+ 0x9D99, 0x6495,
+ 0x9D9A, 0x6493,
+ 0x9D9B, 0x64A5,
+ 0x9D9C, 0x64A9,
+ 0x9D9D, 0x6488,
+ 0x9D9E, 0x64BC,
+ 0x9D9F, 0x64DA,
+ 0x9DA0, 0x64D2,
+ 0x9DA1, 0x64C5,
+ 0x9DA2, 0x64C7,
+ 0x9DA3, 0x64BB,
+ 0x9DA4, 0x64D8,
+ 0x9DA5, 0x64C2,
+ 0x9DA6, 0x64F1,
+ 0x9DA7, 0x64E7,
+ 0x9DA8, 0x8209,
+ 0x9DA9, 0x64E0,
+ 0x9DAA, 0x64E1,
+ 0x9DAB, 0x62AC,
+ 0x9DAC, 0x64E3,
+ 0x9DAD, 0x64EF,
+ 0x9DAE, 0x652C,
+ 0x9DAF, 0x64F6,
+ 0x9DB0, 0x64F4,
+ 0x9DB1, 0x64F2,
+ 0x9DB2, 0x64FA,
+ 0x9DB3, 0x6500,
+ 0x9DB4, 0x64FD,
+ 0x9DB5, 0x6518,
+ 0x9DB6, 0x651C,
+ 0x9DB7, 0x6505,
+ 0x9DB8, 0x6524,
+ 0x9DB9, 0x6523,
+ 0x9DBA, 0x652B,
+ 0x9DBB, 0x6534,
+ 0x9DBC, 0x6535,
+ 0x9DBD, 0x6537,
+ 0x9DBE, 0x6536,
+ 0x9DBF, 0x6538,
+ 0x9DC0, 0x754B,
+ 0x9DC1, 0x6548,
+ 0x9DC2, 0x6556,
+ 0x9DC3, 0x6555,
+ 0x9DC4, 0x654D,
+ 0x9DC5, 0x6558,
+ 0x9DC6, 0x655E,
+ 0x9DC7, 0x655D,
+ 0x9DC8, 0x6572,
+ 0x9DC9, 0x6578,
+ 0x9DCA, 0x6582,
+ 0x9DCB, 0x6583,
+ 0x9DCC, 0x8B8A,
+ 0x9DCD, 0x659B,
+ 0x9DCE, 0x659F,
+ 0x9DCF, 0x65AB,
+ 0x9DD0, 0x65B7,
+ 0x9DD1, 0x65C3,
+ 0x9DD2, 0x65C6,
+ 0x9DD3, 0x65C1,
+ 0x9DD4, 0x65C4,
+ 0x9DD5, 0x65CC,
+ 0x9DD6, 0x65D2,
+ 0x9DD7, 0x65DB,
+ 0x9DD8, 0x65D9,
+ 0x9DD9, 0x65E0,
+ 0x9DDA, 0x65E1,
+ 0x9DDB, 0x65F1,
+ 0x9DDC, 0x6772,
+ 0x9DDD, 0x660A,
+ 0x9DDE, 0x6603,
+ 0x9DDF, 0x65FB,
+ 0x9DE0, 0x6773,
+ 0x9DE1, 0x6635,
+ 0x9DE2, 0x6636,
+ 0x9DE3, 0x6634,
+ 0x9DE4, 0x661C,
+ 0x9DE5, 0x664F,
+ 0x9DE6, 0x6644,
+ 0x9DE7, 0x6649,
+ 0x9DE8, 0x6641,
+ 0x9DE9, 0x665E,
+ 0x9DEA, 0x665D,
+ 0x9DEB, 0x6664,
+ 0x9DEC, 0x6667,
+ 0x9DED, 0x6668,
+ 0x9DEE, 0x665F,
+ 0x9DEF, 0x6662,
+ 0x9DF0, 0x6670,
+ 0x9DF1, 0x6683,
+ 0x9DF2, 0x6688,
+ 0x9DF3, 0x668E,
+ 0x9DF4, 0x6689,
+ 0x9DF5, 0x6684,
+ 0x9DF6, 0x6698,
+ 0x9DF7, 0x669D,
+ 0x9DF8, 0x66C1,
+ 0x9DF9, 0x66B9,
+ 0x9DFA, 0x66C9,
+ 0x9DFB, 0x66BE,
+ 0x9DFC, 0x66BC,
+ 0x9E40, 0x66C4,
+ 0x9E41, 0x66B8,
+ 0x9E42, 0x66D6,
+ 0x9E43, 0x66DA,
+ 0x9E44, 0x66E0,
+ 0x9E45, 0x663F,
+ 0x9E46, 0x66E6,
+ 0x9E47, 0x66E9,
+ 0x9E48, 0x66F0,
+ 0x9E49, 0x66F5,
+ 0x9E4A, 0x66F7,
+ 0x9E4B, 0x670F,
+ 0x9E4C, 0x6716,
+ 0x9E4D, 0x671E,
+ 0x9E4E, 0x6726,
+ 0x9E4F, 0x6727,
+ 0x9E50, 0x9738,
+ 0x9E51, 0x672E,
+ 0x9E52, 0x673F,
+ 0x9E53, 0x6736,
+ 0x9E54, 0x6741,
+ 0x9E55, 0x6738,
+ 0x9E56, 0x6737,
+ 0x9E57, 0x6746,
+ 0x9E58, 0x675E,
+ 0x9E59, 0x6760,
+ 0x9E5A, 0x6759,
+ 0x9E5B, 0x6763,
+ 0x9E5C, 0x6764,
+ 0x9E5D, 0x6789,
+ 0x9E5E, 0x6770,
+ 0x9E5F, 0x67A9,
+ 0x9E60, 0x677C,
+ 0x9E61, 0x676A,
+ 0x9E62, 0x678C,
+ 0x9E63, 0x678B,
+ 0x9E64, 0x67A6,
+ 0x9E65, 0x67A1,
+ 0x9E66, 0x6785,
+ 0x9E67, 0x67B7,
+ 0x9E68, 0x67EF,
+ 0x9E69, 0x67B4,
+ 0x9E6A, 0x67EC,
+ 0x9E6B, 0x67B3,
+ 0x9E6C, 0x67E9,
+ 0x9E6D, 0x67B8,
+ 0x9E6E, 0x67E4,
+ 0x9E6F, 0x67DE,
+ 0x9E70, 0x67DD,
+ 0x9E71, 0x67E2,
+ 0x9E72, 0x67EE,
+ 0x9E73, 0x67B9,
+ 0x9E74, 0x67CE,
+ 0x9E75, 0x67C6,
+ 0x9E76, 0x67E7,
+ 0x9E77, 0x6A9C,
+ 0x9E78, 0x681E,
+ 0x9E79, 0x6846,
+ 0x9E7A, 0x6829,
+ 0x9E7B, 0x6840,
+ 0x9E7C, 0x684D,
+ 0x9E7D, 0x6832,
+ 0x9E7E, 0x684E,
+ 0x9E80, 0x68B3,
+ 0x9E81, 0x682B,
+ 0x9E82, 0x6859,
+ 0x9E83, 0x6863,
+ 0x9E84, 0x6877,
+ 0x9E85, 0x687F,
+ 0x9E86, 0x689F,
+ 0x9E87, 0x688F,
+ 0x9E88, 0x68AD,
+ 0x9E89, 0x6894,
+ 0x9E8A, 0x689D,
+ 0x9E8B, 0x689B,
+ 0x9E8C, 0x6883,
+ 0x9E8D, 0x6AAE,
+ 0x9E8E, 0x68B9,
+ 0x9E8F, 0x6874,
+ 0x9E90, 0x68B5,
+ 0x9E91, 0x68A0,
+ 0x9E92, 0x68BA,
+ 0x9E93, 0x690F,
+ 0x9E94, 0x688D,
+ 0x9E95, 0x687E,
+ 0x9E96, 0x6901,
+ 0x9E97, 0x68CA,
+ 0x9E98, 0x6908,
+ 0x9E99, 0x68D8,
+ 0x9E9A, 0x6922,
+ 0x9E9B, 0x6926,
+ 0x9E9C, 0x68E1,
+ 0x9E9D, 0x690C,
+ 0x9E9E, 0x68CD,
+ 0x9E9F, 0x68D4,
+ 0x9EA0, 0x68E7,
+ 0x9EA1, 0x68D5,
+ 0x9EA2, 0x6936,
+ 0x9EA3, 0x6912,
+ 0x9EA4, 0x6904,
+ 0x9EA5, 0x68D7,
+ 0x9EA6, 0x68E3,
+ 0x9EA7, 0x6925,
+ 0x9EA8, 0x68F9,
+ 0x9EA9, 0x68E0,
+ 0x9EAA, 0x68EF,
+ 0x9EAB, 0x6928,
+ 0x9EAC, 0x692A,
+ 0x9EAD, 0x691A,
+ 0x9EAE, 0x6923,
+ 0x9EAF, 0x6921,
+ 0x9EB0, 0x68C6,
+ 0x9EB1, 0x6979,
+ 0x9EB2, 0x6977,
+ 0x9EB3, 0x695C,
+ 0x9EB4, 0x6978,
+ 0x9EB5, 0x696B,
+ 0x9EB6, 0x6954,
+ 0x9EB7, 0x697E,
+ 0x9EB8, 0x696E,
+ 0x9EB9, 0x6939,
+ 0x9EBA, 0x6974,
+ 0x9EBB, 0x693D,
+ 0x9EBC, 0x6959,
+ 0x9EBD, 0x6930,
+ 0x9EBE, 0x6961,
+ 0x9EBF, 0x695E,
+ 0x9EC0, 0x695D,
+ 0x9EC1, 0x6981,
+ 0x9EC2, 0x696A,
+ 0x9EC3, 0x69B2,
+ 0x9EC4, 0x69AE,
+ 0x9EC5, 0x69D0,
+ 0x9EC6, 0x69BF,
+ 0x9EC7, 0x69C1,
+ 0x9EC8, 0x69D3,
+ 0x9EC9, 0x69BE,
+ 0x9ECA, 0x69CE,
+ 0x9ECB, 0x5BE8,
+ 0x9ECC, 0x69CA,
+ 0x9ECD, 0x69DD,
+ 0x9ECE, 0x69BB,
+ 0x9ECF, 0x69C3,
+ 0x9ED0, 0x69A7,
+ 0x9ED1, 0x6A2E,
+ 0x9ED2, 0x6991,
+ 0x9ED3, 0x69A0,
+ 0x9ED4, 0x699C,
+ 0x9ED5, 0x6995,
+ 0x9ED6, 0x69B4,
+ 0x9ED7, 0x69DE,
+ 0x9ED8, 0x69E8,
+ 0x9ED9, 0x6A02,
+ 0x9EDA, 0x6A1B,
+ 0x9EDB, 0x69FF,
+ 0x9EDC, 0x6B0A,
+ 0x9EDD, 0x69F9,
+ 0x9EDE, 0x69F2,
+ 0x9EDF, 0x69E7,
+ 0x9EE0, 0x6A05,
+ 0x9EE1, 0x69B1,
+ 0x9EE2, 0x6A1E,
+ 0x9EE3, 0x69ED,
+ 0x9EE4, 0x6A14,
+ 0x9EE5, 0x69EB,
+ 0x9EE6, 0x6A0A,
+ 0x9EE7, 0x6A12,
+ 0x9EE8, 0x6AC1,
+ 0x9EE9, 0x6A23,
+ 0x9EEA, 0x6A13,
+ 0x9EEB, 0x6A44,
+ 0x9EEC, 0x6A0C,
+ 0x9EED, 0x6A72,
+ 0x9EEE, 0x6A36,
+ 0x9EEF, 0x6A78,
+ 0x9EF0, 0x6A47,
+ 0x9EF1, 0x6A62,
+ 0x9EF2, 0x6A59,
+ 0x9EF3, 0x6A66,
+ 0x9EF4, 0x6A48,
+ 0x9EF5, 0x6A38,
+ 0x9EF6, 0x6A22,
+ 0x9EF7, 0x6A90,
+ 0x9EF8, 0x6A8D,
+ 0x9EF9, 0x6AA0,
+ 0x9EFA, 0x6A84,
+ 0x9EFB, 0x6AA2,
+ 0x9EFC, 0x6AA3,
+ 0x9F40, 0x6A97,
+ 0x9F41, 0x8617,
+ 0x9F42, 0x6ABB,
+ 0x9F43, 0x6AC3,
+ 0x9F44, 0x6AC2,
+ 0x9F45, 0x6AB8,
+ 0x9F46, 0x6AB3,
+ 0x9F47, 0x6AAC,
+ 0x9F48, 0x6ADE,
+ 0x9F49, 0x6AD1,
+ 0x9F4A, 0x6ADF,
+ 0x9F4B, 0x6AAA,
+ 0x9F4C, 0x6ADA,
+ 0x9F4D, 0x6AEA,
+ 0x9F4E, 0x6AFB,
+ 0x9F4F, 0x6B05,
+ 0x9F50, 0x8616,
+ 0x9F51, 0x6AFA,
+ 0x9F52, 0x6B12,
+ 0x9F53, 0x6B16,
+ 0x9F54, 0x9B31,
+ 0x9F55, 0x6B1F,
+ 0x9F56, 0x6B38,
+ 0x9F57, 0x6B37,
+ 0x9F58, 0x76DC,
+ 0x9F59, 0x6B39,
+ 0x9F5A, 0x98EE,
+ 0x9F5B, 0x6B47,
+ 0x9F5C, 0x6B43,
+ 0x9F5D, 0x6B49,
+ 0x9F5E, 0x6B50,
+ 0x9F5F, 0x6B59,
+ 0x9F60, 0x6B54,
+ 0x9F61, 0x6B5B,
+ 0x9F62, 0x6B5F,
+ 0x9F63, 0x6B61,
+ 0x9F64, 0x6B78,
+ 0x9F65, 0x6B79,
+ 0x9F66, 0x6B7F,
+ 0x9F67, 0x6B80,
+ 0x9F68, 0x6B84,
+ 0x9F69, 0x6B83,
+ 0x9F6A, 0x6B8D,
+ 0x9F6B, 0x6B98,
+ 0x9F6C, 0x6B95,
+ 0x9F6D, 0x6B9E,
+ 0x9F6E, 0x6BA4,
+ 0x9F6F, 0x6BAA,
+ 0x9F70, 0x6BAB,
+ 0x9F71, 0x6BAF,
+ 0x9F72, 0x6BB2,
+ 0x9F73, 0x6BB1,
+ 0x9F74, 0x6BB3,
+ 0x9F75, 0x6BB7,
+ 0x9F76, 0x6BBC,
+ 0x9F77, 0x6BC6,
+ 0x9F78, 0x6BCB,
+ 0x9F79, 0x6BD3,
+ 0x9F7A, 0x6BDF,
+ 0x9F7B, 0x6BEC,
+ 0x9F7C, 0x6BEB,
+ 0x9F7D, 0x6BF3,
+ 0x9F7E, 0x6BEF,
+ 0x9F80, 0x9EBE,
+ 0x9F81, 0x6C08,
+ 0x9F82, 0x6C13,
+ 0x9F83, 0x6C14,
+ 0x9F84, 0x6C1B,
+ 0x9F85, 0x6C24,
+ 0x9F86, 0x6C23,
+ 0x9F87, 0x6C5E,
+ 0x9F88, 0x6C55,
+ 0x9F89, 0x6C62,
+ 0x9F8A, 0x6C6A,
+ 0x9F8B, 0x6C82,
+ 0x9F8C, 0x6C8D,
+ 0x9F8D, 0x6C9A,
+ 0x9F8E, 0x6C81,
+ 0x9F8F, 0x6C9B,
+ 0x9F90, 0x6C7E,
+ 0x9F91, 0x6C68,
+ 0x9F92, 0x6C73,
+ 0x9F93, 0x6C92,
+ 0x9F94, 0x6C90,
+ 0x9F95, 0x6CC4,
+ 0x9F96, 0x6CF1,
+ 0x9F97, 0x6CD3,
+ 0x9F98, 0x6CBD,
+ 0x9F99, 0x6CD7,
+ 0x9F9A, 0x6CC5,
+ 0x9F9B, 0x6CDD,
+ 0x9F9C, 0x6CAE,
+ 0x9F9D, 0x6CB1,
+ 0x9F9E, 0x6CBE,
+ 0x9F9F, 0x6CBA,
+ 0x9FA0, 0x6CDB,
+ 0x9FA1, 0x6CEF,
+ 0x9FA2, 0x6CD9,
+ 0x9FA3, 0x6CEA,
+ 0x9FA4, 0x6D1F,
+ 0x9FA5, 0x884D,
+ 0x9FA6, 0x6D36,
+ 0x9FA7, 0x6D2B,
+ 0x9FA8, 0x6D3D,
+ 0x9FA9, 0x6D38,
+ 0x9FAA, 0x6D19,
+ 0x9FAB, 0x6D35,
+ 0x9FAC, 0x6D33,
+ 0x9FAD, 0x6D12,
+ 0x9FAE, 0x6D0C,
+ 0x9FAF, 0x6D63,
+ 0x9FB0, 0x6D93,
+ 0x9FB1, 0x6D64,
+ 0x9FB2, 0x6D5A,
+ 0x9FB3, 0x6D79,
+ 0x9FB4, 0x6D59,
+ 0x9FB5, 0x6D8E,
+ 0x9FB6, 0x6D95,
+ 0x9FB7, 0x6FE4,
+ 0x9FB8, 0x6D85,
+ 0x9FB9, 0x6DF9,
+ 0x9FBA, 0x6E15,
+ 0x9FBB, 0x6E0A,
+ 0x9FBC, 0x6DB5,
+ 0x9FBD, 0x6DC7,
+ 0x9FBE, 0x6DE6,
+ 0x9FBF, 0x6DB8,
+ 0x9FC0, 0x6DC6,
+ 0x9FC1, 0x6DEC,
+ 0x9FC2, 0x6DDE,
+ 0x9FC3, 0x6DCC,
+ 0x9FC4, 0x6DE8,
+ 0x9FC5, 0x6DD2,
+ 0x9FC6, 0x6DC5,
+ 0x9FC7, 0x6DFA,
+ 0x9FC8, 0x6DD9,
+ 0x9FC9, 0x6DE4,
+ 0x9FCA, 0x6DD5,
+ 0x9FCB, 0x6DEA,
+ 0x9FCC, 0x6DEE,
+ 0x9FCD, 0x6E2D,
+ 0x9FCE, 0x6E6E,
+ 0x9FCF, 0x6E2E,
+ 0x9FD0, 0x6E19,
+ 0x9FD1, 0x6E72,
+ 0x9FD2, 0x6E5F,
+ 0x9FD3, 0x6E3E,
+ 0x9FD4, 0x6E23,
+ 0x9FD5, 0x6E6B,
+ 0x9FD6, 0x6E2B,
+ 0x9FD7, 0x6E76,
+ 0x9FD8, 0x6E4D,
+ 0x9FD9, 0x6E1F,
+ 0x9FDA, 0x6E43,
+ 0x9FDB, 0x6E3A,
+ 0x9FDC, 0x6E4E,
+ 0x9FDD, 0x6E24,
+ 0x9FDE, 0x6EFF,
+ 0x9FDF, 0x6E1D,
+ 0x9FE0, 0x6E38,
+ 0x9FE1, 0x6E82,
+ 0x9FE2, 0x6EAA,
+ 0x9FE3, 0x6E98,
+ 0x9FE4, 0x6EC9,
+ 0x9FE5, 0x6EB7,
+ 0x9FE6, 0x6ED3,
+ 0x9FE7, 0x6EBD,
+ 0x9FE8, 0x6EAF,
+ 0x9FE9, 0x6EC4,
+ 0x9FEA, 0x6EB2,
+ 0x9FEB, 0x6ED4,
+ 0x9FEC, 0x6ED5,
+ 0x9FED, 0x6E8F,
+ 0x9FEE, 0x6EA5,
+ 0x9FEF, 0x6EC2,
+ 0x9FF0, 0x6E9F,
+ 0x9FF1, 0x6F41,
+ 0x9FF2, 0x6F11,
+ 0x9FF3, 0x704C,
+ 0x9FF4, 0x6EEC,
+ 0x9FF5, 0x6EF8,
+ 0x9FF6, 0x6EFE,
+ 0x9FF7, 0x6F3F,
+ 0x9FF8, 0x6EF2,
+ 0x9FF9, 0x6F31,
+ 0x9FFA, 0x6EEF,
+ 0x9FFB, 0x6F32,
+ 0x9FFC, 0x6ECC,
+ 0xE040, 0x6F3E,
+ 0xE041, 0x6F13,
+ 0xE042, 0x6EF7,
+ 0xE043, 0x6F86,
+ 0xE044, 0x6F7A,
+ 0xE045, 0x6F78,
+ 0xE046, 0x6F81,
+ 0xE047, 0x6F80,
+ 0xE048, 0x6F6F,
+ 0xE049, 0x6F5B,
+ 0xE04A, 0x6FF3,
+ 0xE04B, 0x6F6D,
+ 0xE04C, 0x6F82,
+ 0xE04D, 0x6F7C,
+ 0xE04E, 0x6F58,
+ 0xE04F, 0x6F8E,
+ 0xE050, 0x6F91,
+ 0xE051, 0x6FC2,
+ 0xE052, 0x6F66,
+ 0xE053, 0x6FB3,
+ 0xE054, 0x6FA3,
+ 0xE055, 0x6FA1,
+ 0xE056, 0x6FA4,
+ 0xE057, 0x6FB9,
+ 0xE058, 0x6FC6,
+ 0xE059, 0x6FAA,
+ 0xE05A, 0x6FDF,
+ 0xE05B, 0x6FD5,
+ 0xE05C, 0x6FEC,
+ 0xE05D, 0x6FD4,
+ 0xE05E, 0x6FD8,
+ 0xE05F, 0x6FF1,
+ 0xE060, 0x6FEE,
+ 0xE061, 0x6FDB,
+ 0xE062, 0x7009,
+ 0xE063, 0x700B,
+ 0xE064, 0x6FFA,
+ 0xE065, 0x7011,
+ 0xE066, 0x7001,
+ 0xE067, 0x700F,
+ 0xE068, 0x6FFE,
+ 0xE069, 0x701B,
+ 0xE06A, 0x701A,
+ 0xE06B, 0x6F74,
+ 0xE06C, 0x701D,
+ 0xE06D, 0x7018,
+ 0xE06E, 0x701F,
+ 0xE06F, 0x7030,
+ 0xE070, 0x703E,
+ 0xE071, 0x7032,
+ 0xE072, 0x7051,
+ 0xE073, 0x7063,
+ 0xE074, 0x7099,
+ 0xE075, 0x7092,
+ 0xE076, 0x70AF,
+ 0xE077, 0x70F1,
+ 0xE078, 0x70AC,
+ 0xE079, 0x70B8,
+ 0xE07A, 0x70B3,
+ 0xE07B, 0x70AE,
+ 0xE07C, 0x70DF,
+ 0xE07D, 0x70CB,
+ 0xE07E, 0x70DD,
+ 0xE080, 0x70D9,
+ 0xE081, 0x7109,
+ 0xE082, 0x70FD,
+ 0xE083, 0x711C,
+ 0xE084, 0x7119,
+ 0xE085, 0x7165,
+ 0xE086, 0x7155,
+ 0xE087, 0x7188,
+ 0xE088, 0x7166,
+ 0xE089, 0x7162,
+ 0xE08A, 0x714C,
+ 0xE08B, 0x7156,
+ 0xE08C, 0x716C,
+ 0xE08D, 0x718F,
+ 0xE08E, 0x71FB,
+ 0xE08F, 0x7184,
+ 0xE090, 0x7195,
+ 0xE091, 0x71A8,
+ 0xE092, 0x71AC,
+ 0xE093, 0x71D7,
+ 0xE094, 0x71B9,
+ 0xE095, 0x71BE,
+ 0xE096, 0x71D2,
+ 0xE097, 0x71C9,
+ 0xE098, 0x71D4,
+ 0xE099, 0x71CE,
+ 0xE09A, 0x71E0,
+ 0xE09B, 0x71EC,
+ 0xE09C, 0x71E7,
+ 0xE09D, 0x71F5,
+ 0xE09E, 0x71FC,
+ 0xE09F, 0x71F9,
+ 0xE0A0, 0x71FF,
+ 0xE0A1, 0x720D,
+ 0xE0A2, 0x7210,
+ 0xE0A3, 0x721B,
+ 0xE0A4, 0x7228,
+ 0xE0A5, 0x722D,
+ 0xE0A6, 0x722C,
+ 0xE0A7, 0x7230,
+ 0xE0A8, 0x7232,
+ 0xE0A9, 0x723B,
+ 0xE0AA, 0x723C,
+ 0xE0AB, 0x723F,
+ 0xE0AC, 0x7240,
+ 0xE0AD, 0x7246,
+ 0xE0AE, 0x724B,
+ 0xE0AF, 0x7258,
+ 0xE0B0, 0x7274,
+ 0xE0B1, 0x727E,
+ 0xE0B2, 0x7282,
+ 0xE0B3, 0x7281,
+ 0xE0B4, 0x7287,
+ 0xE0B5, 0x7292,
+ 0xE0B6, 0x7296,
+ 0xE0B7, 0x72A2,
+ 0xE0B8, 0x72A7,
+ 0xE0B9, 0x72B9,
+ 0xE0BA, 0x72B2,
+ 0xE0BB, 0x72C3,
+ 0xE0BC, 0x72C6,
+ 0xE0BD, 0x72C4,
+ 0xE0BE, 0x72CE,
+ 0xE0BF, 0x72D2,
+ 0xE0C0, 0x72E2,
+ 0xE0C1, 0x72E0,
+ 0xE0C2, 0x72E1,
+ 0xE0C3, 0x72F9,
+ 0xE0C4, 0x72F7,
+ 0xE0C5, 0x500F,
+ 0xE0C6, 0x7317,
+ 0xE0C7, 0x730A,
+ 0xE0C8, 0x731C,
+ 0xE0C9, 0x7316,
+ 0xE0CA, 0x731D,
+ 0xE0CB, 0x7334,
+ 0xE0CC, 0x732F,
+ 0xE0CD, 0x7329,
+ 0xE0CE, 0x7325,
+ 0xE0CF, 0x733E,
+ 0xE0D0, 0x734E,
+ 0xE0D1, 0x734F,
+ 0xE0D2, 0x9ED8,
+ 0xE0D3, 0x7357,
+ 0xE0D4, 0x736A,
+ 0xE0D5, 0x7368,
+ 0xE0D6, 0x7370,
+ 0xE0D7, 0x7378,
+ 0xE0D8, 0x7375,
+ 0xE0D9, 0x737B,
+ 0xE0DA, 0x737A,
+ 0xE0DB, 0x73C8,
+ 0xE0DC, 0x73B3,
+ 0xE0DD, 0x73CE,
+ 0xE0DE, 0x73BB,
+ 0xE0DF, 0x73C0,
+ 0xE0E0, 0x73E5,
+ 0xE0E1, 0x73EE,
+ 0xE0E2, 0x73DE,
+ 0xE0E3, 0x74A2,
+ 0xE0E4, 0x7405,
+ 0xE0E5, 0x746F,
+ 0xE0E6, 0x7425,
+ 0xE0E7, 0x73F8,
+ 0xE0E8, 0x7432,
+ 0xE0E9, 0x743A,
+ 0xE0EA, 0x7455,
+ 0xE0EB, 0x743F,
+ 0xE0EC, 0x745F,
+ 0xE0ED, 0x7459,
+ 0xE0EE, 0x7441,
+ 0xE0EF, 0x745C,
+ 0xE0F0, 0x7469,
+ 0xE0F1, 0x7470,
+ 0xE0F2, 0x7463,
+ 0xE0F3, 0x746A,
+ 0xE0F4, 0x7476,
+ 0xE0F5, 0x747E,
+ 0xE0F6, 0x748B,
+ 0xE0F7, 0x749E,
+ 0xE0F8, 0x74A7,
+ 0xE0F9, 0x74CA,
+ 0xE0FA, 0x74CF,
+ 0xE0FB, 0x74D4,
+ 0xE0FC, 0x73F1,
+ 0xE140, 0x74E0,
+ 0xE141, 0x74E3,
+ 0xE142, 0x74E7,
+ 0xE143, 0x74E9,
+ 0xE144, 0x74EE,
+ 0xE145, 0x74F2,
+ 0xE146, 0x74F0,
+ 0xE147, 0x74F1,
+ 0xE148, 0x74F8,
+ 0xE149, 0x74F7,
+ 0xE14A, 0x7504,
+ 0xE14B, 0x7503,
+ 0xE14C, 0x7505,
+ 0xE14D, 0x750C,
+ 0xE14E, 0x750E,
+ 0xE14F, 0x750D,
+ 0xE150, 0x7515,
+ 0xE151, 0x7513,
+ 0xE152, 0x751E,
+ 0xE153, 0x7526,
+ 0xE154, 0x752C,
+ 0xE155, 0x753C,
+ 0xE156, 0x7544,
+ 0xE157, 0x754D,
+ 0xE158, 0x754A,
+ 0xE159, 0x7549,
+ 0xE15A, 0x755B,
+ 0xE15B, 0x7546,
+ 0xE15C, 0x755A,
+ 0xE15D, 0x7569,
+ 0xE15E, 0x7564,
+ 0xE15F, 0x7567,
+ 0xE160, 0x756B,
+ 0xE161, 0x756D,
+ 0xE162, 0x7578,
+ 0xE163, 0x7576,
+ 0xE164, 0x7586,
+ 0xE165, 0x7587,
+ 0xE166, 0x7574,
+ 0xE167, 0x758A,
+ 0xE168, 0x7589,
+ 0xE169, 0x7582,
+ 0xE16A, 0x7594,
+ 0xE16B, 0x759A,
+ 0xE16C, 0x759D,
+ 0xE16D, 0x75A5,
+ 0xE16E, 0x75A3,
+ 0xE16F, 0x75C2,
+ 0xE170, 0x75B3,
+ 0xE171, 0x75C3,
+ 0xE172, 0x75B5,
+ 0xE173, 0x75BD,
+ 0xE174, 0x75B8,
+ 0xE175, 0x75BC,
+ 0xE176, 0x75B1,
+ 0xE177, 0x75CD,
+ 0xE178, 0x75CA,
+ 0xE179, 0x75D2,
+ 0xE17A, 0x75D9,
+ 0xE17B, 0x75E3,
+ 0xE17C, 0x75DE,
+ 0xE17D, 0x75FE,
+ 0xE17E, 0x75FF,
+ 0xE180, 0x75FC,
+ 0xE181, 0x7601,
+ 0xE182, 0x75F0,
+ 0xE183, 0x75FA,
+ 0xE184, 0x75F2,
+ 0xE185, 0x75F3,
+ 0xE186, 0x760B,
+ 0xE187, 0x760D,
+ 0xE188, 0x7609,
+ 0xE189, 0x761F,
+ 0xE18A, 0x7627,
+ 0xE18B, 0x7620,
+ 0xE18C, 0x7621,
+ 0xE18D, 0x7622,
+ 0xE18E, 0x7624,
+ 0xE18F, 0x7634,
+ 0xE190, 0x7630,
+ 0xE191, 0x763B,
+ 0xE192, 0x7647,
+ 0xE193, 0x7648,
+ 0xE194, 0x7646,
+ 0xE195, 0x765C,
+ 0xE196, 0x7658,
+ 0xE197, 0x7661,
+ 0xE198, 0x7662,
+ 0xE199, 0x7668,
+ 0xE19A, 0x7669,
+ 0xE19B, 0x766A,
+ 0xE19C, 0x7667,
+ 0xE19D, 0x766C,
+ 0xE19E, 0x7670,
+ 0xE19F, 0x7672,
+ 0xE1A0, 0x7676,
+ 0xE1A1, 0x7678,
+ 0xE1A2, 0x767C,
+ 0xE1A3, 0x7680,
+ 0xE1A4, 0x7683,
+ 0xE1A5, 0x7688,
+ 0xE1A6, 0x768B,
+ 0xE1A7, 0x768E,
+ 0xE1A8, 0x7696,
+ 0xE1A9, 0x7693,
+ 0xE1AA, 0x7699,
+ 0xE1AB, 0x769A,
+ 0xE1AC, 0x76B0,
+ 0xE1AD, 0x76B4,
+ 0xE1AE, 0x76B8,
+ 0xE1AF, 0x76B9,
+ 0xE1B0, 0x76BA,
+ 0xE1B1, 0x76C2,
+ 0xE1B2, 0x76CD,
+ 0xE1B3, 0x76D6,
+ 0xE1B4, 0x76D2,
+ 0xE1B5, 0x76DE,
+ 0xE1B6, 0x76E1,
+ 0xE1B7, 0x76E5,
+ 0xE1B8, 0x76E7,
+ 0xE1B9, 0x76EA,
+ 0xE1BA, 0x862F,
+ 0xE1BB, 0x76FB,
+ 0xE1BC, 0x7708,
+ 0xE1BD, 0x7707,
+ 0xE1BE, 0x7704,
+ 0xE1BF, 0x7729,
+ 0xE1C0, 0x7724,
+ 0xE1C1, 0x771E,
+ 0xE1C2, 0x7725,
+ 0xE1C3, 0x7726,
+ 0xE1C4, 0x771B,
+ 0xE1C5, 0x7737,
+ 0xE1C6, 0x7738,
+ 0xE1C7, 0x7747,
+ 0xE1C8, 0x775A,
+ 0xE1C9, 0x7768,
+ 0xE1CA, 0x776B,
+ 0xE1CB, 0x775B,
+ 0xE1CC, 0x7765,
+ 0xE1CD, 0x777F,
+ 0xE1CE, 0x777E,
+ 0xE1CF, 0x7779,
+ 0xE1D0, 0x778E,
+ 0xE1D1, 0x778B,
+ 0xE1D2, 0x7791,
+ 0xE1D3, 0x77A0,
+ 0xE1D4, 0x779E,
+ 0xE1D5, 0x77B0,
+ 0xE1D6, 0x77B6,
+ 0xE1D7, 0x77B9,
+ 0xE1D8, 0x77BF,
+ 0xE1D9, 0x77BC,
+ 0xE1DA, 0x77BD,
+ 0xE1DB, 0x77BB,
+ 0xE1DC, 0x77C7,
+ 0xE1DD, 0x77CD,
+ 0xE1DE, 0x77D7,
+ 0xE1DF, 0x77DA,
+ 0xE1E0, 0x77DC,
+ 0xE1E1, 0x77E3,
+ 0xE1E2, 0x77EE,
+ 0xE1E3, 0x77FC,
+ 0xE1E4, 0x780C,
+ 0xE1E5, 0x7812,
+ 0xE1E6, 0x7926,
+ 0xE1E7, 0x7820,
+ 0xE1E8, 0x792A,
+ 0xE1E9, 0x7845,
+ 0xE1EA, 0x788E,
+ 0xE1EB, 0x7874,
+ 0xE1EC, 0x7886,
+ 0xE1ED, 0x787C,
+ 0xE1EE, 0x789A,
+ 0xE1EF, 0x788C,
+ 0xE1F0, 0x78A3,
+ 0xE1F1, 0x78B5,
+ 0xE1F2, 0x78AA,
+ 0xE1F3, 0x78AF,
+ 0xE1F4, 0x78D1,
+ 0xE1F5, 0x78C6,
+ 0xE1F6, 0x78CB,
+ 0xE1F7, 0x78D4,
+ 0xE1F8, 0x78BE,
+ 0xE1F9, 0x78BC,
+ 0xE1FA, 0x78C5,
+ 0xE1FB, 0x78CA,
+ 0xE1FC, 0x78EC,
+ 0xE240, 0x78E7,
+ 0xE241, 0x78DA,
+ 0xE242, 0x78FD,
+ 0xE243, 0x78F4,
+ 0xE244, 0x7907,
+ 0xE245, 0x7912,
+ 0xE246, 0x7911,
+ 0xE247, 0x7919,
+ 0xE248, 0x792C,
+ 0xE249, 0x792B,
+ 0xE24A, 0x7940,
+ 0xE24B, 0x7960,
+ 0xE24C, 0x7957,
+ 0xE24D, 0x795F,
+ 0xE24E, 0x795A,
+ 0xE24F, 0x7955,
+ 0xE250, 0x7953,
+ 0xE251, 0x797A,
+ 0xE252, 0x797F,
+ 0xE253, 0x798A,
+ 0xE254, 0x799D,
+ 0xE255, 0x79A7,
+ 0xE256, 0x9F4B,
+ 0xE257, 0x79AA,
+ 0xE258, 0x79AE,
+ 0xE259, 0x79B3,
+ 0xE25A, 0x79B9,
+ 0xE25B, 0x79BA,
+ 0xE25C, 0x79C9,
+ 0xE25D, 0x79D5,
+ 0xE25E, 0x79E7,
+ 0xE25F, 0x79EC,
+ 0xE260, 0x79E1,
+ 0xE261, 0x79E3,
+ 0xE262, 0x7A08,
+ 0xE263, 0x7A0D,
+ 0xE264, 0x7A18,
+ 0xE265, 0x7A19,
+ 0xE266, 0x7A20,
+ 0xE267, 0x7A1F,
+ 0xE268, 0x7980,
+ 0xE269, 0x7A31,
+ 0xE26A, 0x7A3B,
+ 0xE26B, 0x7A3E,
+ 0xE26C, 0x7A37,
+ 0xE26D, 0x7A43,
+ 0xE26E, 0x7A57,
+ 0xE26F, 0x7A49,
+ 0xE270, 0x7A61,
+ 0xE271, 0x7A62,
+ 0xE272, 0x7A69,
+ 0xE273, 0x9F9D,
+ 0xE274, 0x7A70,
+ 0xE275, 0x7A79,
+ 0xE276, 0x7A7D,
+ 0xE277, 0x7A88,
+ 0xE278, 0x7A97,
+ 0xE279, 0x7A95,
+ 0xE27A, 0x7A98,
+ 0xE27B, 0x7A96,
+ 0xE27C, 0x7AA9,
+ 0xE27D, 0x7AC8,
+ 0xE27E, 0x7AB0,
+ 0xE280, 0x7AB6,
+ 0xE281, 0x7AC5,
+ 0xE282, 0x7AC4,
+ 0xE283, 0x7ABF,
+ 0xE284, 0x9083,
+ 0xE285, 0x7AC7,
+ 0xE286, 0x7ACA,
+ 0xE287, 0x7ACD,
+ 0xE288, 0x7ACF,
+ 0xE289, 0x7AD5,
+ 0xE28A, 0x7AD3,
+ 0xE28B, 0x7AD9,
+ 0xE28C, 0x7ADA,
+ 0xE28D, 0x7ADD,
+ 0xE28E, 0x7AE1,
+ 0xE28F, 0x7AE2,
+ 0xE290, 0x7AE6,
+ 0xE291, 0x7AED,
+ 0xE292, 0x7AF0,
+ 0xE293, 0x7B02,
+ 0xE294, 0x7B0F,
+ 0xE295, 0x7B0A,
+ 0xE296, 0x7B06,
+ 0xE297, 0x7B33,
+ 0xE298, 0x7B18,
+ 0xE299, 0x7B19,
+ 0xE29A, 0x7B1E,
+ 0xE29B, 0x7B35,
+ 0xE29C, 0x7B28,
+ 0xE29D, 0x7B36,
+ 0xE29E, 0x7B50,
+ 0xE29F, 0x7B7A,
+ 0xE2A0, 0x7B04,
+ 0xE2A1, 0x7B4D,
+ 0xE2A2, 0x7B0B,
+ 0xE2A3, 0x7B4C,
+ 0xE2A4, 0x7B45,
+ 0xE2A5, 0x7B75,
+ 0xE2A6, 0x7B65,
+ 0xE2A7, 0x7B74,
+ 0xE2A8, 0x7B67,
+ 0xE2A9, 0x7B70,
+ 0xE2AA, 0x7B71,
+ 0xE2AB, 0x7B6C,
+ 0xE2AC, 0x7B6E,
+ 0xE2AD, 0x7B9D,
+ 0xE2AE, 0x7B98,
+ 0xE2AF, 0x7B9F,
+ 0xE2B0, 0x7B8D,
+ 0xE2B1, 0x7B9C,
+ 0xE2B2, 0x7B9A,
+ 0xE2B3, 0x7B8B,
+ 0xE2B4, 0x7B92,
+ 0xE2B5, 0x7B8F,
+ 0xE2B6, 0x7B5D,
+ 0xE2B7, 0x7B99,
+ 0xE2B8, 0x7BCB,
+ 0xE2B9, 0x7BC1,
+ 0xE2BA, 0x7BCC,
+ 0xE2BB, 0x7BCF,
+ 0xE2BC, 0x7BB4,
+ 0xE2BD, 0x7BC6,
+ 0xE2BE, 0x7BDD,
+ 0xE2BF, 0x7BE9,
+ 0xE2C0, 0x7C11,
+ 0xE2C1, 0x7C14,
+ 0xE2C2, 0x7BE6,
+ 0xE2C3, 0x7BE5,
+ 0xE2C4, 0x7C60,
+ 0xE2C5, 0x7C00,
+ 0xE2C6, 0x7C07,
+ 0xE2C7, 0x7C13,
+ 0xE2C8, 0x7BF3,
+ 0xE2C9, 0x7BF7,
+ 0xE2CA, 0x7C17,
+ 0xE2CB, 0x7C0D,
+ 0xE2CC, 0x7BF6,
+ 0xE2CD, 0x7C23,
+ 0xE2CE, 0x7C27,
+ 0xE2CF, 0x7C2A,
+ 0xE2D0, 0x7C1F,
+ 0xE2D1, 0x7C37,
+ 0xE2D2, 0x7C2B,
+ 0xE2D3, 0x7C3D,
+ 0xE2D4, 0x7C4C,
+ 0xE2D5, 0x7C43,
+ 0xE2D6, 0x7C54,
+ 0xE2D7, 0x7C4F,
+ 0xE2D8, 0x7C40,
+ 0xE2D9, 0x7C50,
+ 0xE2DA, 0x7C58,
+ 0xE2DB, 0x7C5F,
+ 0xE2DC, 0x7C64,
+ 0xE2DD, 0x7C56,
+ 0xE2DE, 0x7C65,
+ 0xE2DF, 0x7C6C,
+ 0xE2E0, 0x7C75,
+ 0xE2E1, 0x7C83,
+ 0xE2E2, 0x7C90,
+ 0xE2E3, 0x7CA4,
+ 0xE2E4, 0x7CAD,
+ 0xE2E5, 0x7CA2,
+ 0xE2E6, 0x7CAB,
+ 0xE2E7, 0x7CA1,
+ 0xE2E8, 0x7CA8,
+ 0xE2E9, 0x7CB3,
+ 0xE2EA, 0x7CB2,
+ 0xE2EB, 0x7CB1,
+ 0xE2EC, 0x7CAE,
+ 0xE2ED, 0x7CB9,
+ 0xE2EE, 0x7CBD,
+ 0xE2EF, 0x7CC0,
+ 0xE2F0, 0x7CC5,
+ 0xE2F1, 0x7CC2,
+ 0xE2F2, 0x7CD8,
+ 0xE2F3, 0x7CD2,
+ 0xE2F4, 0x7CDC,
+ 0xE2F5, 0x7CE2,
+ 0xE2F6, 0x9B3B,
+ 0xE2F7, 0x7CEF,
+ 0xE2F8, 0x7CF2,
+ 0xE2F9, 0x7CF4,
+ 0xE2FA, 0x7CF6,
+ 0xE2FB, 0x7CFA,
+ 0xE2FC, 0x7D06,
+ 0xE340, 0x7D02,
+ 0xE341, 0x7D1C,
+ 0xE342, 0x7D15,
+ 0xE343, 0x7D0A,
+ 0xE344, 0x7D45,
+ 0xE345, 0x7D4B,
+ 0xE346, 0x7D2E,
+ 0xE347, 0x7D32,
+ 0xE348, 0x7D3F,
+ 0xE349, 0x7D35,
+ 0xE34A, 0x7D46,
+ 0xE34B, 0x7D73,
+ 0xE34C, 0x7D56,
+ 0xE34D, 0x7D4E,
+ 0xE34E, 0x7D72,
+ 0xE34F, 0x7D68,
+ 0xE350, 0x7D6E,
+ 0xE351, 0x7D4F,
+ 0xE352, 0x7D63,
+ 0xE353, 0x7D93,
+ 0xE354, 0x7D89,
+ 0xE355, 0x7D5B,
+ 0xE356, 0x7D8F,
+ 0xE357, 0x7D7D,
+ 0xE358, 0x7D9B,
+ 0xE359, 0x7DBA,
+ 0xE35A, 0x7DAE,
+ 0xE35B, 0x7DA3,
+ 0xE35C, 0x7DB5,
+ 0xE35D, 0x7DC7,
+ 0xE35E, 0x7DBD,
+ 0xE35F, 0x7DAB,
+ 0xE360, 0x7E3D,
+ 0xE361, 0x7DA2,
+ 0xE362, 0x7DAF,
+ 0xE363, 0x7DDC,
+ 0xE364, 0x7DB8,
+ 0xE365, 0x7D9F,
+ 0xE366, 0x7DB0,
+ 0xE367, 0x7DD8,
+ 0xE368, 0x7DDD,
+ 0xE369, 0x7DE4,
+ 0xE36A, 0x7DDE,
+ 0xE36B, 0x7DFB,
+ 0xE36C, 0x7DF2,
+ 0xE36D, 0x7DE1,
+ 0xE36E, 0x7E05,
+ 0xE36F, 0x7E0A,
+ 0xE370, 0x7E23,
+ 0xE371, 0x7E21,
+ 0xE372, 0x7E12,
+ 0xE373, 0x7E31,
+ 0xE374, 0x7E1F,
+ 0xE375, 0x7E09,
+ 0xE376, 0x7E0B,
+ 0xE377, 0x7E22,
+ 0xE378, 0x7E46,
+ 0xE379, 0x7E66,
+ 0xE37A, 0x7E3B,
+ 0xE37B, 0x7E35,
+ 0xE37C, 0x7E39,
+ 0xE37D, 0x7E43,
+ 0xE37E, 0x7E37,
+ 0xE380, 0x7E32,
+ 0xE381, 0x7E3A,
+ 0xE382, 0x7E67,
+ 0xE383, 0x7E5D,
+ 0xE384, 0x7E56,
+ 0xE385, 0x7E5E,
+ 0xE386, 0x7E59,
+ 0xE387, 0x7E5A,
+ 0xE388, 0x7E79,
+ 0xE389, 0x7E6A,
+ 0xE38A, 0x7E69,
+ 0xE38B, 0x7E7C,
+ 0xE38C, 0x7E7B,
+ 0xE38D, 0x7E83,
+ 0xE38E, 0x7DD5,
+ 0xE38F, 0x7E7D,
+ 0xE390, 0x8FAE,
+ 0xE391, 0x7E7F,
+ 0xE392, 0x7E88,
+ 0xE393, 0x7E89,
+ 0xE394, 0x7E8C,
+ 0xE395, 0x7E92,
+ 0xE396, 0x7E90,
+ 0xE397, 0x7E93,
+ 0xE398, 0x7E94,
+ 0xE399, 0x7E96,
+ 0xE39A, 0x7E8E,
+ 0xE39B, 0x7E9B,
+ 0xE39C, 0x7E9C,
+ 0xE39D, 0x7F38,
+ 0xE39E, 0x7F3A,
+ 0xE39F, 0x7F45,
+ 0xE3A0, 0x7F4C,
+ 0xE3A1, 0x7F4D,
+ 0xE3A2, 0x7F4E,
+ 0xE3A3, 0x7F50,
+ 0xE3A4, 0x7F51,
+ 0xE3A5, 0x7F55,
+ 0xE3A6, 0x7F54,
+ 0xE3A7, 0x7F58,
+ 0xE3A8, 0x7F5F,
+ 0xE3A9, 0x7F60,
+ 0xE3AA, 0x7F68,
+ 0xE3AB, 0x7F69,
+ 0xE3AC, 0x7F67,
+ 0xE3AD, 0x7F78,
+ 0xE3AE, 0x7F82,
+ 0xE3AF, 0x7F86,
+ 0xE3B0, 0x7F83,
+ 0xE3B1, 0x7F88,
+ 0xE3B2, 0x7F87,
+ 0xE3B3, 0x7F8C,
+ 0xE3B4, 0x7F94,
+ 0xE3B5, 0x7F9E,
+ 0xE3B6, 0x7F9D,
+ 0xE3B7, 0x7F9A,
+ 0xE3B8, 0x7FA3,
+ 0xE3B9, 0x7FAF,
+ 0xE3BA, 0x7FB2,
+ 0xE3BB, 0x7FB9,
+ 0xE3BC, 0x7FAE,
+ 0xE3BD, 0x7FB6,
+ 0xE3BE, 0x7FB8,
+ 0xE3BF, 0x8B71,
+ 0xE3C0, 0x7FC5,
+ 0xE3C1, 0x7FC6,
+ 0xE3C2, 0x7FCA,
+ 0xE3C3, 0x7FD5,
+ 0xE3C4, 0x7FD4,
+ 0xE3C5, 0x7FE1,
+ 0xE3C6, 0x7FE6,
+ 0xE3C7, 0x7FE9,
+ 0xE3C8, 0x7FF3,
+ 0xE3C9, 0x7FF9,
+ 0xE3CA, 0x98DC,
+ 0xE3CB, 0x8006,
+ 0xE3CC, 0x8004,
+ 0xE3CD, 0x800B,
+ 0xE3CE, 0x8012,
+ 0xE3CF, 0x8018,
+ 0xE3D0, 0x8019,
+ 0xE3D1, 0x801C,
+ 0xE3D2, 0x8021,
+ 0xE3D3, 0x8028,
+ 0xE3D4, 0x803F,
+ 0xE3D5, 0x803B,
+ 0xE3D6, 0x804A,
+ 0xE3D7, 0x8046,
+ 0xE3D8, 0x8052,
+ 0xE3D9, 0x8058,
+ 0xE3DA, 0x805A,
+ 0xE3DB, 0x805F,
+ 0xE3DC, 0x8062,
+ 0xE3DD, 0x8068,
+ 0xE3DE, 0x8073,
+ 0xE3DF, 0x8072,
+ 0xE3E0, 0x8070,
+ 0xE3E1, 0x8076,
+ 0xE3E2, 0x8079,
+ 0xE3E3, 0x807D,
+ 0xE3E4, 0x807F,
+ 0xE3E5, 0x8084,
+ 0xE3E6, 0x8086,
+ 0xE3E7, 0x8085,
+ 0xE3E8, 0x809B,
+ 0xE3E9, 0x8093,
+ 0xE3EA, 0x809A,
+ 0xE3EB, 0x80AD,
+ 0xE3EC, 0x5190,
+ 0xE3ED, 0x80AC,
+ 0xE3EE, 0x80DB,
+ 0xE3EF, 0x80E5,
+ 0xE3F0, 0x80D9,
+ 0xE3F1, 0x80DD,
+ 0xE3F2, 0x80C4,
+ 0xE3F3, 0x80DA,
+ 0xE3F4, 0x80D6,
+ 0xE3F5, 0x8109,
+ 0xE3F6, 0x80EF,
+ 0xE3F7, 0x80F1,
+ 0xE3F8, 0x811B,
+ 0xE3F9, 0x8129,
+ 0xE3FA, 0x8123,
+ 0xE3FB, 0x812F,
+ 0xE3FC, 0x814B,
+ 0xE440, 0x968B,
+ 0xE441, 0x8146,
+ 0xE442, 0x813E,
+ 0xE443, 0x8153,
+ 0xE444, 0x8151,
+ 0xE445, 0x80FC,
+ 0xE446, 0x8171,
+ 0xE447, 0x816E,
+ 0xE448, 0x8165,
+ 0xE449, 0x8166,
+ 0xE44A, 0x8174,
+ 0xE44B, 0x8183,
+ 0xE44C, 0x8188,
+ 0xE44D, 0x818A,
+ 0xE44E, 0x8180,
+ 0xE44F, 0x8182,
+ 0xE450, 0x81A0,
+ 0xE451, 0x8195,
+ 0xE452, 0x81A4,
+ 0xE453, 0x81A3,
+ 0xE454, 0x815F,
+ 0xE455, 0x8193,
+ 0xE456, 0x81A9,
+ 0xE457, 0x81B0,
+ 0xE458, 0x81B5,
+ 0xE459, 0x81BE,
+ 0xE45A, 0x81B8,
+ 0xE45B, 0x81BD,
+ 0xE45C, 0x81C0,
+ 0xE45D, 0x81C2,
+ 0xE45E, 0x81BA,
+ 0xE45F, 0x81C9,
+ 0xE460, 0x81CD,
+ 0xE461, 0x81D1,
+ 0xE462, 0x81D9,
+ 0xE463, 0x81D8,
+ 0xE464, 0x81C8,
+ 0xE465, 0x81DA,
+ 0xE466, 0x81DF,
+ 0xE467, 0x81E0,
+ 0xE468, 0x81E7,
+ 0xE469, 0x81FA,
+ 0xE46A, 0x81FB,
+ 0xE46B, 0x81FE,
+ 0xE46C, 0x8201,
+ 0xE46D, 0x8202,
+ 0xE46E, 0x8205,
+ 0xE46F, 0x8207,
+ 0xE470, 0x820A,
+ 0xE471, 0x820D,
+ 0xE472, 0x8210,
+ 0xE473, 0x8216,
+ 0xE474, 0x8229,
+ 0xE475, 0x822B,
+ 0xE476, 0x8238,
+ 0xE477, 0x8233,
+ 0xE478, 0x8240,
+ 0xE479, 0x8259,
+ 0xE47A, 0x8258,
+ 0xE47B, 0x825D,
+ 0xE47C, 0x825A,
+ 0xE47D, 0x825F,
+ 0xE47E, 0x8264,
+ 0xE480, 0x8262,
+ 0xE481, 0x8268,
+ 0xE482, 0x826A,
+ 0xE483, 0x826B,
+ 0xE484, 0x822E,
+ 0xE485, 0x8271,
+ 0xE486, 0x8277,
+ 0xE487, 0x8278,
+ 0xE488, 0x827E,
+ 0xE489, 0x828D,
+ 0xE48A, 0x8292,
+ 0xE48B, 0x82AB,
+ 0xE48C, 0x829F,
+ 0xE48D, 0x82BB,
+ 0xE48E, 0x82AC,
+ 0xE48F, 0x82E1,
+ 0xE490, 0x82E3,
+ 0xE491, 0x82DF,
+ 0xE492, 0x82D2,
+ 0xE493, 0x82F4,
+ 0xE494, 0x82F3,
+ 0xE495, 0x82FA,
+ 0xE496, 0x8393,
+ 0xE497, 0x8303,
+ 0xE498, 0x82FB,
+ 0xE499, 0x82F9,
+ 0xE49A, 0x82DE,
+ 0xE49B, 0x8306,
+ 0xE49C, 0x82DC,
+ 0xE49D, 0x8309,
+ 0xE49E, 0x82D9,
+ 0xE49F, 0x8335,
+ 0xE4A0, 0x8334,
+ 0xE4A1, 0x8316,
+ 0xE4A2, 0x8332,
+ 0xE4A3, 0x8331,
+ 0xE4A4, 0x8340,
+ 0xE4A5, 0x8339,
+ 0xE4A6, 0x8350,
+ 0xE4A7, 0x8345,
+ 0xE4A8, 0x832F,
+ 0xE4A9, 0x832B,
+ 0xE4AA, 0x8317,
+ 0xE4AB, 0x8318,
+ 0xE4AC, 0x8385,
+ 0xE4AD, 0x839A,
+ 0xE4AE, 0x83AA,
+ 0xE4AF, 0x839F,
+ 0xE4B0, 0x83A2,
+ 0xE4B1, 0x8396,
+ 0xE4B2, 0x8323,
+ 0xE4B3, 0x838E,
+ 0xE4B4, 0x8387,
+ 0xE4B5, 0x838A,
+ 0xE4B6, 0x837C,
+ 0xE4B7, 0x83B5,
+ 0xE4B8, 0x8373,
+ 0xE4B9, 0x8375,
+ 0xE4BA, 0x83A0,
+ 0xE4BB, 0x8389,
+ 0xE4BC, 0x83A8,
+ 0xE4BD, 0x83F4,
+ 0xE4BE, 0x8413,
+ 0xE4BF, 0x83EB,
+ 0xE4C0, 0x83CE,
+ 0xE4C1, 0x83FD,
+ 0xE4C2, 0x8403,
+ 0xE4C3, 0x83D8,
+ 0xE4C4, 0x840B,
+ 0xE4C5, 0x83C1,
+ 0xE4C6, 0x83F7,
+ 0xE4C7, 0x8407,
+ 0xE4C8, 0x83E0,
+ 0xE4C9, 0x83F2,
+ 0xE4CA, 0x840D,
+ 0xE4CB, 0x8422,
+ 0xE4CC, 0x8420,
+ 0xE4CD, 0x83BD,
+ 0xE4CE, 0x8438,
+ 0xE4CF, 0x8506,
+ 0xE4D0, 0x83FB,
+ 0xE4D1, 0x846D,
+ 0xE4D2, 0x842A,
+ 0xE4D3, 0x843C,
+ 0xE4D4, 0x855A,
+ 0xE4D5, 0x8484,
+ 0xE4D6, 0x8477,
+ 0xE4D7, 0x846B,
+ 0xE4D8, 0x84AD,
+ 0xE4D9, 0x846E,
+ 0xE4DA, 0x8482,
+ 0xE4DB, 0x8469,
+ 0xE4DC, 0x8446,
+ 0xE4DD, 0x842C,
+ 0xE4DE, 0x846F,
+ 0xE4DF, 0x8479,
+ 0xE4E0, 0x8435,
+ 0xE4E1, 0x84CA,
+ 0xE4E2, 0x8462,
+ 0xE4E3, 0x84B9,
+ 0xE4E4, 0x84BF,
+ 0xE4E5, 0x849F,
+ 0xE4E6, 0x84D9,
+ 0xE4E7, 0x84CD,
+ 0xE4E8, 0x84BB,
+ 0xE4E9, 0x84DA,
+ 0xE4EA, 0x84D0,
+ 0xE4EB, 0x84C1,
+ 0xE4EC, 0x84C6,
+ 0xE4ED, 0x84D6,
+ 0xE4EE, 0x84A1,
+ 0xE4EF, 0x8521,
+ 0xE4F0, 0x84FF,
+ 0xE4F1, 0x84F4,
+ 0xE4F2, 0x8517,
+ 0xE4F3, 0x8518,
+ 0xE4F4, 0x852C,
+ 0xE4F5, 0x851F,
+ 0xE4F6, 0x8515,
+ 0xE4F7, 0x8514,
+ 0xE4F8, 0x84FC,
+ 0xE4F9, 0x8540,
+ 0xE4FA, 0x8563,
+ 0xE4FB, 0x8558,
+ 0xE4FC, 0x8548,
+ 0xE540, 0x8541,
+ 0xE541, 0x8602,
+ 0xE542, 0x854B,
+ 0xE543, 0x8555,
+ 0xE544, 0x8580,
+ 0xE545, 0x85A4,
+ 0xE546, 0x8588,
+ 0xE547, 0x8591,
+ 0xE548, 0x858A,
+ 0xE549, 0x85A8,
+ 0xE54A, 0x856D,
+ 0xE54B, 0x8594,
+ 0xE54C, 0x859B,
+ 0xE54D, 0x85EA,
+ 0xE54E, 0x8587,
+ 0xE54F, 0x859C,
+ 0xE550, 0x8577,
+ 0xE551, 0x857E,
+ 0xE552, 0x8590,
+ 0xE553, 0x85C9,
+ 0xE554, 0x85BA,
+ 0xE555, 0x85CF,
+ 0xE556, 0x85B9,
+ 0xE557, 0x85D0,
+ 0xE558, 0x85D5,
+ 0xE559, 0x85DD,
+ 0xE55A, 0x85E5,
+ 0xE55B, 0x85DC,
+ 0xE55C, 0x85F9,
+ 0xE55D, 0x860A,
+ 0xE55E, 0x8613,
+ 0xE55F, 0x860B,
+ 0xE560, 0x85FE,
+ 0xE561, 0x85FA,
+ 0xE562, 0x8606,
+ 0xE563, 0x8622,
+ 0xE564, 0x861A,
+ 0xE565, 0x8630,
+ 0xE566, 0x863F,
+ 0xE567, 0x864D,
+ 0xE568, 0x4E55,
+ 0xE569, 0x8654,
+ 0xE56A, 0x865F,
+ 0xE56B, 0x8667,
+ 0xE56C, 0x8671,
+ 0xE56D, 0x8693,
+ 0xE56E, 0x86A3,
+ 0xE56F, 0x86A9,
+ 0xE570, 0x86AA,
+ 0xE571, 0x868B,
+ 0xE572, 0x868C,
+ 0xE573, 0x86B6,
+ 0xE574, 0x86AF,
+ 0xE575, 0x86C4,
+ 0xE576, 0x86C6,
+ 0xE577, 0x86B0,
+ 0xE578, 0x86C9,
+ 0xE579, 0x8823,
+ 0xE57A, 0x86AB,
+ 0xE57B, 0x86D4,
+ 0xE57C, 0x86DE,
+ 0xE57D, 0x86E9,
+ 0xE57E, 0x86EC,
+ 0xE580, 0x86DF,
+ 0xE581, 0x86DB,
+ 0xE582, 0x86EF,
+ 0xE583, 0x8712,
+ 0xE584, 0x8706,
+ 0xE585, 0x8708,
+ 0xE586, 0x8700,
+ 0xE587, 0x8703,
+ 0xE588, 0x86FB,
+ 0xE589, 0x8711,
+ 0xE58A, 0x8709,
+ 0xE58B, 0x870D,
+ 0xE58C, 0x86F9,
+ 0xE58D, 0x870A,
+ 0xE58E, 0x8734,
+ 0xE58F, 0x873F,
+ 0xE590, 0x8737,
+ 0xE591, 0x873B,
+ 0xE592, 0x8725,
+ 0xE593, 0x8729,
+ 0xE594, 0x871A,
+ 0xE595, 0x8760,
+ 0xE596, 0x875F,
+ 0xE597, 0x8778,
+ 0xE598, 0x874C,
+ 0xE599, 0x874E,
+ 0xE59A, 0x8774,
+ 0xE59B, 0x8757,
+ 0xE59C, 0x8768,
+ 0xE59D, 0x876E,
+ 0xE59E, 0x8759,
+ 0xE59F, 0x8753,
+ 0xE5A0, 0x8763,
+ 0xE5A1, 0x876A,
+ 0xE5A2, 0x8805,
+ 0xE5A3, 0x87A2,
+ 0xE5A4, 0x879F,
+ 0xE5A5, 0x8782,
+ 0xE5A6, 0x87AF,
+ 0xE5A7, 0x87CB,
+ 0xE5A8, 0x87BD,
+ 0xE5A9, 0x87C0,
+ 0xE5AA, 0x87D0,
+ 0xE5AB, 0x96D6,
+ 0xE5AC, 0x87AB,
+ 0xE5AD, 0x87C4,
+ 0xE5AE, 0x87B3,
+ 0xE5AF, 0x87C7,
+ 0xE5B0, 0x87C6,
+ 0xE5B1, 0x87BB,
+ 0xE5B2, 0x87EF,
+ 0xE5B3, 0x87F2,
+ 0xE5B4, 0x87E0,
+ 0xE5B5, 0x880F,
+ 0xE5B6, 0x880D,
+ 0xE5B7, 0x87FE,
+ 0xE5B8, 0x87F6,
+ 0xE5B9, 0x87F7,
+ 0xE5BA, 0x880E,
+ 0xE5BB, 0x87D2,
+ 0xE5BC, 0x8811,
+ 0xE5BD, 0x8816,
+ 0xE5BE, 0x8815,
+ 0xE5BF, 0x8822,
+ 0xE5C0, 0x8821,
+ 0xE5C1, 0x8831,
+ 0xE5C2, 0x8836,
+ 0xE5C3, 0x8839,
+ 0xE5C4, 0x8827,
+ 0xE5C5, 0x883B,
+ 0xE5C6, 0x8844,
+ 0xE5C7, 0x8842,
+ 0xE5C8, 0x8852,
+ 0xE5C9, 0x8859,
+ 0xE5CA, 0x885E,
+ 0xE5CB, 0x8862,
+ 0xE5CC, 0x886B,
+ 0xE5CD, 0x8881,
+ 0xE5CE, 0x887E,
+ 0xE5CF, 0x889E,
+ 0xE5D0, 0x8875,
+ 0xE5D1, 0x887D,
+ 0xE5D2, 0x88B5,
+ 0xE5D3, 0x8872,
+ 0xE5D4, 0x8882,
+ 0xE5D5, 0x8897,
+ 0xE5D6, 0x8892,
+ 0xE5D7, 0x88AE,
+ 0xE5D8, 0x8899,
+ 0xE5D9, 0x88A2,
+ 0xE5DA, 0x888D,
+ 0xE5DB, 0x88A4,
+ 0xE5DC, 0x88B0,
+ 0xE5DD, 0x88BF,
+ 0xE5DE, 0x88B1,
+ 0xE5DF, 0x88C3,
+ 0xE5E0, 0x88C4,
+ 0xE5E1, 0x88D4,
+ 0xE5E2, 0x88D8,
+ 0xE5E3, 0x88D9,
+ 0xE5E4, 0x88DD,
+ 0xE5E5, 0x88F9,
+ 0xE5E6, 0x8902,
+ 0xE5E7, 0x88FC,
+ 0xE5E8, 0x88F4,
+ 0xE5E9, 0x88E8,
+ 0xE5EA, 0x88F2,
+ 0xE5EB, 0x8904,
+ 0xE5EC, 0x890C,
+ 0xE5ED, 0x890A,
+ 0xE5EE, 0x8913,
+ 0xE5EF, 0x8943,
+ 0xE5F0, 0x891E,
+ 0xE5F1, 0x8925,
+ 0xE5F2, 0x892A,
+ 0xE5F3, 0x892B,
+ 0xE5F4, 0x8941,
+ 0xE5F5, 0x8944,
+ 0xE5F6, 0x893B,
+ 0xE5F7, 0x8936,
+ 0xE5F8, 0x8938,
+ 0xE5F9, 0x894C,
+ 0xE5FA, 0x891D,
+ 0xE5FB, 0x8960,
+ 0xE5FC, 0x895E,
+ 0xE640, 0x8966,
+ 0xE641, 0x8964,
+ 0xE642, 0x896D,
+ 0xE643, 0x896A,
+ 0xE644, 0x896F,
+ 0xE645, 0x8974,
+ 0xE646, 0x8977,
+ 0xE647, 0x897E,
+ 0xE648, 0x8983,
+ 0xE649, 0x8988,
+ 0xE64A, 0x898A,
+ 0xE64B, 0x8993,
+ 0xE64C, 0x8998,
+ 0xE64D, 0x89A1,
+ 0xE64E, 0x89A9,
+ 0xE64F, 0x89A6,
+ 0xE650, 0x89AC,
+ 0xE651, 0x89AF,
+ 0xE652, 0x89B2,
+ 0xE653, 0x89BA,
+ 0xE654, 0x89BD,
+ 0xE655, 0x89BF,
+ 0xE656, 0x89C0,
+ 0xE657, 0x89DA,
+ 0xE658, 0x89DC,
+ 0xE659, 0x89DD,
+ 0xE65A, 0x89E7,
+ 0xE65B, 0x89F4,
+ 0xE65C, 0x89F8,
+ 0xE65D, 0x8A03,
+ 0xE65E, 0x8A16,
+ 0xE65F, 0x8A10,
+ 0xE660, 0x8A0C,
+ 0xE661, 0x8A1B,
+ 0xE662, 0x8A1D,
+ 0xE663, 0x8A25,
+ 0xE664, 0x8A36,
+ 0xE665, 0x8A41,
+ 0xE666, 0x8A5B,
+ 0xE667, 0x8A52,
+ 0xE668, 0x8A46,
+ 0xE669, 0x8A48,
+ 0xE66A, 0x8A7C,
+ 0xE66B, 0x8A6D,
+ 0xE66C, 0x8A6C,
+ 0xE66D, 0x8A62,
+ 0xE66E, 0x8A85,
+ 0xE66F, 0x8A82,
+ 0xE670, 0x8A84,
+ 0xE671, 0x8AA8,
+ 0xE672, 0x8AA1,
+ 0xE673, 0x8A91,
+ 0xE674, 0x8AA5,
+ 0xE675, 0x8AA6,
+ 0xE676, 0x8A9A,
+ 0xE677, 0x8AA3,
+ 0xE678, 0x8AC4,
+ 0xE679, 0x8ACD,
+ 0xE67A, 0x8AC2,
+ 0xE67B, 0x8ADA,
+ 0xE67C, 0x8AEB,
+ 0xE67D, 0x8AF3,
+ 0xE67E, 0x8AE7,
+ 0xE680, 0x8AE4,
+ 0xE681, 0x8AF1,
+ 0xE682, 0x8B14,
+ 0xE683, 0x8AE0,
+ 0xE684, 0x8AE2,
+ 0xE685, 0x8AF7,
+ 0xE686, 0x8ADE,
+ 0xE687, 0x8ADB,
+ 0xE688, 0x8B0C,
+ 0xE689, 0x8B07,
+ 0xE68A, 0x8B1A,
+ 0xE68B, 0x8AE1,
+ 0xE68C, 0x8B16,
+ 0xE68D, 0x8B10,
+ 0xE68E, 0x8B17,
+ 0xE68F, 0x8B20,
+ 0xE690, 0x8B33,
+ 0xE691, 0x97AB,
+ 0xE692, 0x8B26,
+ 0xE693, 0x8B2B,
+ 0xE694, 0x8B3E,
+ 0xE695, 0x8B28,
+ 0xE696, 0x8B41,
+ 0xE697, 0x8B4C,
+ 0xE698, 0x8B4F,
+ 0xE699, 0x8B4E,
+ 0xE69A, 0x8B49,
+ 0xE69B, 0x8B56,
+ 0xE69C, 0x8B5B,
+ 0xE69D, 0x8B5A,
+ 0xE69E, 0x8B6B,
+ 0xE69F, 0x8B5F,
+ 0xE6A0, 0x8B6C,
+ 0xE6A1, 0x8B6F,
+ 0xE6A2, 0x8B74,
+ 0xE6A3, 0x8B7D,
+ 0xE6A4, 0x8B80,
+ 0xE6A5, 0x8B8C,
+ 0xE6A6, 0x8B8E,
+ 0xE6A7, 0x8B92,
+ 0xE6A8, 0x8B93,
+ 0xE6A9, 0x8B96,
+ 0xE6AA, 0x8B99,
+ 0xE6AB, 0x8B9A,
+ 0xE6AC, 0x8C3A,
+ 0xE6AD, 0x8C41,
+ 0xE6AE, 0x8C3F,
+ 0xE6AF, 0x8C48,
+ 0xE6B0, 0x8C4C,
+ 0xE6B1, 0x8C4E,
+ 0xE6B2, 0x8C50,
+ 0xE6B3, 0x8C55,
+ 0xE6B4, 0x8C62,
+ 0xE6B5, 0x8C6C,
+ 0xE6B6, 0x8C78,
+ 0xE6B7, 0x8C7A,
+ 0xE6B8, 0x8C82,
+ 0xE6B9, 0x8C89,
+ 0xE6BA, 0x8C85,
+ 0xE6BB, 0x8C8A,
+ 0xE6BC, 0x8C8D,
+ 0xE6BD, 0x8C8E,
+ 0xE6BE, 0x8C94,
+ 0xE6BF, 0x8C7C,
+ 0xE6C0, 0x8C98,
+ 0xE6C1, 0x621D,
+ 0xE6C2, 0x8CAD,
+ 0xE6C3, 0x8CAA,
+ 0xE6C4, 0x8CBD,
+ 0xE6C5, 0x8CB2,
+ 0xE6C6, 0x8CB3,
+ 0xE6C7, 0x8CAE,
+ 0xE6C8, 0x8CB6,
+ 0xE6C9, 0x8CC8,
+ 0xE6CA, 0x8CC1,
+ 0xE6CB, 0x8CE4,
+ 0xE6CC, 0x8CE3,
+ 0xE6CD, 0x8CDA,
+ 0xE6CE, 0x8CFD,
+ 0xE6CF, 0x8CFA,
+ 0xE6D0, 0x8CFB,
+ 0xE6D1, 0x8D04,
+ 0xE6D2, 0x8D05,
+ 0xE6D3, 0x8D0A,
+ 0xE6D4, 0x8D07,
+ 0xE6D5, 0x8D0F,
+ 0xE6D6, 0x8D0D,
+ 0xE6D7, 0x8D10,
+ 0xE6D8, 0x9F4E,
+ 0xE6D9, 0x8D13,
+ 0xE6DA, 0x8CCD,
+ 0xE6DB, 0x8D14,
+ 0xE6DC, 0x8D16,
+ 0xE6DD, 0x8D67,
+ 0xE6DE, 0x8D6D,
+ 0xE6DF, 0x8D71,
+ 0xE6E0, 0x8D73,
+ 0xE6E1, 0x8D81,
+ 0xE6E2, 0x8D99,
+ 0xE6E3, 0x8DC2,
+ 0xE6E4, 0x8DBE,
+ 0xE6E5, 0x8DBA,
+ 0xE6E6, 0x8DCF,
+ 0xE6E7, 0x8DDA,
+ 0xE6E8, 0x8DD6,
+ 0xE6E9, 0x8DCC,
+ 0xE6EA, 0x8DDB,
+ 0xE6EB, 0x8DCB,
+ 0xE6EC, 0x8DEA,
+ 0xE6ED, 0x8DEB,
+ 0xE6EE, 0x8DDF,
+ 0xE6EF, 0x8DE3,
+ 0xE6F0, 0x8DFC,
+ 0xE6F1, 0x8E08,
+ 0xE6F2, 0x8E09,
+ 0xE6F3, 0x8DFF,
+ 0xE6F4, 0x8E1D,
+ 0xE6F5, 0x8E1E,
+ 0xE6F6, 0x8E10,
+ 0xE6F7, 0x8E1F,
+ 0xE6F8, 0x8E42,
+ 0xE6F9, 0x8E35,
+ 0xE6FA, 0x8E30,
+ 0xE6FB, 0x8E34,
+ 0xE6FC, 0x8E4A,
+ 0xE740, 0x8E47,
+ 0xE741, 0x8E49,
+ 0xE742, 0x8E4C,
+ 0xE743, 0x8E50,
+ 0xE744, 0x8E48,
+ 0xE745, 0x8E59,
+ 0xE746, 0x8E64,
+ 0xE747, 0x8E60,
+ 0xE748, 0x8E2A,
+ 0xE749, 0x8E63,
+ 0xE74A, 0x8E55,
+ 0xE74B, 0x8E76,
+ 0xE74C, 0x8E72,
+ 0xE74D, 0x8E7C,
+ 0xE74E, 0x8E81,
+ 0xE74F, 0x8E87,
+ 0xE750, 0x8E85,
+ 0xE751, 0x8E84,
+ 0xE752, 0x8E8B,
+ 0xE753, 0x8E8A,
+ 0xE754, 0x8E93,
+ 0xE755, 0x8E91,
+ 0xE756, 0x8E94,
+ 0xE757, 0x8E99,
+ 0xE758, 0x8EAA,
+ 0xE759, 0x8EA1,
+ 0xE75A, 0x8EAC,
+ 0xE75B, 0x8EB0,
+ 0xE75C, 0x8EC6,
+ 0xE75D, 0x8EB1,
+ 0xE75E, 0x8EBE,
+ 0xE75F, 0x8EC5,
+ 0xE760, 0x8EC8,
+ 0xE761, 0x8ECB,
+ 0xE762, 0x8EDB,
+ 0xE763, 0x8EE3,
+ 0xE764, 0x8EFC,
+ 0xE765, 0x8EFB,
+ 0xE766, 0x8EEB,
+ 0xE767, 0x8EFE,
+ 0xE768, 0x8F0A,
+ 0xE769, 0x8F05,
+ 0xE76A, 0x8F15,
+ 0xE76B, 0x8F12,
+ 0xE76C, 0x8F19,
+ 0xE76D, 0x8F13,
+ 0xE76E, 0x8F1C,
+ 0xE76F, 0x8F1F,
+ 0xE770, 0x8F1B,
+ 0xE771, 0x8F0C,
+ 0xE772, 0x8F26,
+ 0xE773, 0x8F33,
+ 0xE774, 0x8F3B,
+ 0xE775, 0x8F39,
+ 0xE776, 0x8F45,
+ 0xE777, 0x8F42,
+ 0xE778, 0x8F3E,
+ 0xE779, 0x8F4C,
+ 0xE77A, 0x8F49,
+ 0xE77B, 0x8F46,
+ 0xE77C, 0x8F4E,
+ 0xE77D, 0x8F57,
+ 0xE77E, 0x8F5C,
+ 0xE780, 0x8F62,
+ 0xE781, 0x8F63,
+ 0xE782, 0x8F64,
+ 0xE783, 0x8F9C,
+ 0xE784, 0x8F9F,
+ 0xE785, 0x8FA3,
+ 0xE786, 0x8FAD,
+ 0xE787, 0x8FAF,
+ 0xE788, 0x8FB7,
+ 0xE789, 0x8FDA,
+ 0xE78A, 0x8FE5,
+ 0xE78B, 0x8FE2,
+ 0xE78C, 0x8FEA,
+ 0xE78D, 0x8FEF,
+ 0xE78E, 0x9087,
+ 0xE78F, 0x8FF4,
+ 0xE790, 0x9005,
+ 0xE791, 0x8FF9,
+ 0xE792, 0x8FFA,
+ 0xE793, 0x9011,
+ 0xE794, 0x9015,
+ 0xE795, 0x9021,
+ 0xE796, 0x900D,
+ 0xE797, 0x901E,
+ 0xE798, 0x9016,
+ 0xE799, 0x900B,
+ 0xE79A, 0x9027,
+ 0xE79B, 0x9036,
+ 0xE79C, 0x9035,
+ 0xE79D, 0x9039,
+ 0xE79E, 0x8FF8,
+ 0xE79F, 0x904F,
+ 0xE7A0, 0x9050,
+ 0xE7A1, 0x9051,
+ 0xE7A2, 0x9052,
+ 0xE7A3, 0x900E,
+ 0xE7A4, 0x9049,
+ 0xE7A5, 0x903E,
+ 0xE7A6, 0x9056,
+ 0xE7A7, 0x9058,
+ 0xE7A8, 0x905E,
+ 0xE7A9, 0x9068,
+ 0xE7AA, 0x906F,
+ 0xE7AB, 0x9076,
+ 0xE7AC, 0x96A8,
+ 0xE7AD, 0x9072,
+ 0xE7AE, 0x9082,
+ 0xE7AF, 0x907D,
+ 0xE7B0, 0x9081,
+ 0xE7B1, 0x9080,
+ 0xE7B2, 0x908A,
+ 0xE7B3, 0x9089,
+ 0xE7B4, 0x908F,
+ 0xE7B5, 0x90A8,
+ 0xE7B6, 0x90AF,
+ 0xE7B7, 0x90B1,
+ 0xE7B8, 0x90B5,
+ 0xE7B9, 0x90E2,
+ 0xE7BA, 0x90E4,
+ 0xE7BB, 0x6248,
+ 0xE7BC, 0x90DB,
+ 0xE7BD, 0x9102,
+ 0xE7BE, 0x9112,
+ 0xE7BF, 0x9119,
+ 0xE7C0, 0x9132,
+ 0xE7C1, 0x9130,
+ 0xE7C2, 0x914A,
+ 0xE7C3, 0x9156,
+ 0xE7C4, 0x9158,
+ 0xE7C5, 0x9163,
+ 0xE7C6, 0x9165,
+ 0xE7C7, 0x9169,
+ 0xE7C8, 0x9173,
+ 0xE7C9, 0x9172,
+ 0xE7CA, 0x918B,
+ 0xE7CB, 0x9189,
+ 0xE7CC, 0x9182,
+ 0xE7CD, 0x91A2,
+ 0xE7CE, 0x91AB,
+ 0xE7CF, 0x91AF,
+ 0xE7D0, 0x91AA,
+ 0xE7D1, 0x91B5,
+ 0xE7D2, 0x91B4,
+ 0xE7D3, 0x91BA,
+ 0xE7D4, 0x91C0,
+ 0xE7D5, 0x91C1,
+ 0xE7D6, 0x91C9,
+ 0xE7D7, 0x91CB,
+ 0xE7D8, 0x91D0,
+ 0xE7D9, 0x91D6,
+ 0xE7DA, 0x91DF,
+ 0xE7DB, 0x91E1,
+ 0xE7DC, 0x91DB,
+ 0xE7DD, 0x91FC,
+ 0xE7DE, 0x91F5,
+ 0xE7DF, 0x91F6,
+ 0xE7E0, 0x921E,
+ 0xE7E1, 0x91FF,
+ 0xE7E2, 0x9214,
+ 0xE7E3, 0x922C,
+ 0xE7E4, 0x9215,
+ 0xE7E5, 0x9211,
+ 0xE7E6, 0x925E,
+ 0xE7E7, 0x9257,
+ 0xE7E8, 0x9245,
+ 0xE7E9, 0x9249,
+ 0xE7EA, 0x9264,
+ 0xE7EB, 0x9248,
+ 0xE7EC, 0x9295,
+ 0xE7ED, 0x923F,
+ 0xE7EE, 0x924B,
+ 0xE7EF, 0x9250,
+ 0xE7F0, 0x929C,
+ 0xE7F1, 0x9296,
+ 0xE7F2, 0x9293,
+ 0xE7F3, 0x929B,
+ 0xE7F4, 0x925A,
+ 0xE7F5, 0x92CF,
+ 0xE7F6, 0x92B9,
+ 0xE7F7, 0x92B7,
+ 0xE7F8, 0x92E9,
+ 0xE7F9, 0x930F,
+ 0xE7FA, 0x92FA,
+ 0xE7FB, 0x9344,
+ 0xE7FC, 0x932E,
+ 0xE840, 0x9319,
+ 0xE841, 0x9322,
+ 0xE842, 0x931A,
+ 0xE843, 0x9323,
+ 0xE844, 0x933A,
+ 0xE845, 0x9335,
+ 0xE846, 0x933B,
+ 0xE847, 0x935C,
+ 0xE848, 0x9360,
+ 0xE849, 0x937C,
+ 0xE84A, 0x936E,
+ 0xE84B, 0x9356,
+ 0xE84C, 0x93B0,
+ 0xE84D, 0x93AC,
+ 0xE84E, 0x93AD,
+ 0xE84F, 0x9394,
+ 0xE850, 0x93B9,
+ 0xE851, 0x93D6,
+ 0xE852, 0x93D7,
+ 0xE853, 0x93E8,
+ 0xE854, 0x93E5,
+ 0xE855, 0x93D8,
+ 0xE856, 0x93C3,
+ 0xE857, 0x93DD,
+ 0xE858, 0x93D0,
+ 0xE859, 0x93C8,
+ 0xE85A, 0x93E4,
+ 0xE85B, 0x941A,
+ 0xE85C, 0x9414,
+ 0xE85D, 0x9413,
+ 0xE85E, 0x9403,
+ 0xE85F, 0x9407,
+ 0xE860, 0x9410,
+ 0xE861, 0x9436,
+ 0xE862, 0x942B,
+ 0xE863, 0x9435,
+ 0xE864, 0x9421,
+ 0xE865, 0x943A,
+ 0xE866, 0x9441,
+ 0xE867, 0x9452,
+ 0xE868, 0x9444,
+ 0xE869, 0x945B,
+ 0xE86A, 0x9460,
+ 0xE86B, 0x9462,
+ 0xE86C, 0x945E,
+ 0xE86D, 0x946A,
+ 0xE86E, 0x9229,
+ 0xE86F, 0x9470,
+ 0xE870, 0x9475,
+ 0xE871, 0x9477,
+ 0xE872, 0x947D,
+ 0xE873, 0x945A,
+ 0xE874, 0x947C,
+ 0xE875, 0x947E,
+ 0xE876, 0x9481,
+ 0xE877, 0x947F,
+ 0xE878, 0x9582,
+ 0xE879, 0x9587,
+ 0xE87A, 0x958A,
+ 0xE87B, 0x9594,
+ 0xE87C, 0x9596,
+ 0xE87D, 0x9598,
+ 0xE87E, 0x9599,
+ 0xE880, 0x95A0,
+ 0xE881, 0x95A8,
+ 0xE882, 0x95A7,
+ 0xE883, 0x95AD,
+ 0xE884, 0x95BC,
+ 0xE885, 0x95BB,
+ 0xE886, 0x95B9,
+ 0xE887, 0x95BE,
+ 0xE888, 0x95CA,
+ 0xE889, 0x6FF6,
+ 0xE88A, 0x95C3,
+ 0xE88B, 0x95CD,
+ 0xE88C, 0x95CC,
+ 0xE88D, 0x95D5,
+ 0xE88E, 0x95D4,
+ 0xE88F, 0x95D6,
+ 0xE890, 0x95DC,
+ 0xE891, 0x95E1,
+ 0xE892, 0x95E5,
+ 0xE893, 0x95E2,
+ 0xE894, 0x9621,
+ 0xE895, 0x9628,
+ 0xE896, 0x962E,
+ 0xE897, 0x962F,
+ 0xE898, 0x9642,
+ 0xE899, 0x964C,
+ 0xE89A, 0x964F,
+ 0xE89B, 0x964B,
+ 0xE89C, 0x9677,
+ 0xE89D, 0x965C,
+ 0xE89E, 0x965E,
+ 0xE89F, 0x965D,
+ 0xE8A0, 0x965F,
+ 0xE8A1, 0x9666,
+ 0xE8A2, 0x9672,
+ 0xE8A3, 0x966C,
+ 0xE8A4, 0x968D,
+ 0xE8A5, 0x9698,
+ 0xE8A6, 0x9695,
+ 0xE8A7, 0x9697,
+ 0xE8A8, 0x96AA,
+ 0xE8A9, 0x96A7,
+ 0xE8AA, 0x96B1,
+ 0xE8AB, 0x96B2,
+ 0xE8AC, 0x96B0,
+ 0xE8AD, 0x96B4,
+ 0xE8AE, 0x96B6,
+ 0xE8AF, 0x96B8,
+ 0xE8B0, 0x96B9,
+ 0xE8B1, 0x96CE,
+ 0xE8B2, 0x96CB,
+ 0xE8B3, 0x96C9,
+ 0xE8B4, 0x96CD,
+ 0xE8B5, 0x894D,
+ 0xE8B6, 0x96DC,
+ 0xE8B7, 0x970D,
+ 0xE8B8, 0x96D5,
+ 0xE8B9, 0x96F9,
+ 0xE8BA, 0x9704,
+ 0xE8BB, 0x9706,
+ 0xE8BC, 0x9708,
+ 0xE8BD, 0x9713,
+ 0xE8BE, 0x970E,
+ 0xE8BF, 0x9711,
+ 0xE8C0, 0x970F,
+ 0xE8C1, 0x9716,
+ 0xE8C2, 0x9719,
+ 0xE8C3, 0x9724,
+ 0xE8C4, 0x972A,
+ 0xE8C5, 0x9730,
+ 0xE8C6, 0x9739,
+ 0xE8C7, 0x973D,
+ 0xE8C8, 0x973E,
+ 0xE8C9, 0x9744,
+ 0xE8CA, 0x9746,
+ 0xE8CB, 0x9748,
+ 0xE8CC, 0x9742,
+ 0xE8CD, 0x9749,
+ 0xE8CE, 0x975C,
+ 0xE8CF, 0x9760,
+ 0xE8D0, 0x9764,
+ 0xE8D1, 0x9766,
+ 0xE8D2, 0x9768,
+ 0xE8D3, 0x52D2,
+ 0xE8D4, 0x976B,
+ 0xE8D5, 0x9771,
+ 0xE8D6, 0x9779,
+ 0xE8D7, 0x9785,
+ 0xE8D8, 0x977C,
+ 0xE8D9, 0x9781,
+ 0xE8DA, 0x977A,
+ 0xE8DB, 0x9786,
+ 0xE8DC, 0x978B,
+ 0xE8DD, 0x978F,
+ 0xE8DE, 0x9790,
+ 0xE8DF, 0x979C,
+ 0xE8E0, 0x97A8,
+ 0xE8E1, 0x97A6,
+ 0xE8E2, 0x97A3,
+ 0xE8E3, 0x97B3,
+ 0xE8E4, 0x97B4,
+ 0xE8E5, 0x97C3,
+ 0xE8E6, 0x97C6,
+ 0xE8E7, 0x97C8,
+ 0xE8E8, 0x97CB,
+ 0xE8E9, 0x97DC,
+ 0xE8EA, 0x97ED,
+ 0xE8EB, 0x9F4F,
+ 0xE8EC, 0x97F2,
+ 0xE8ED, 0x7ADF,
+ 0xE8EE, 0x97F6,
+ 0xE8EF, 0x97F5,
+ 0xE8F0, 0x980F,
+ 0xE8F1, 0x980C,
+ 0xE8F2, 0x9838,
+ 0xE8F3, 0x9824,
+ 0xE8F4, 0x9821,
+ 0xE8F5, 0x9837,
+ 0xE8F6, 0x983D,
+ 0xE8F7, 0x9846,
+ 0xE8F8, 0x984F,
+ 0xE8F9, 0x984B,
+ 0xE8FA, 0x986B,
+ 0xE8FB, 0x986F,
+ 0xE8FC, 0x9870,
+ 0xE940, 0x9871,
+ 0xE941, 0x9874,
+ 0xE942, 0x9873,
+ 0xE943, 0x98AA,
+ 0xE944, 0x98AF,
+ 0xE945, 0x98B1,
+ 0xE946, 0x98B6,
+ 0xE947, 0x98C4,
+ 0xE948, 0x98C3,
+ 0xE949, 0x98C6,
+ 0xE94A, 0x98E9,
+ 0xE94B, 0x98EB,
+ 0xE94C, 0x9903,
+ 0xE94D, 0x9909,
+ 0xE94E, 0x9912,
+ 0xE94F, 0x9914,
+ 0xE950, 0x9918,
+ 0xE951, 0x9921,
+ 0xE952, 0x991D,
+ 0xE953, 0x991E,
+ 0xE954, 0x9924,
+ 0xE955, 0x9920,
+ 0xE956, 0x992C,
+ 0xE957, 0x992E,
+ 0xE958, 0x993D,
+ 0xE959, 0x993E,
+ 0xE95A, 0x9942,
+ 0xE95B, 0x9949,
+ 0xE95C, 0x9945,
+ 0xE95D, 0x9950,
+ 0xE95E, 0x994B,
+ 0xE95F, 0x9951,
+ 0xE960, 0x9952,
+ 0xE961, 0x994C,
+ 0xE962, 0x9955,
+ 0xE963, 0x9997,
+ 0xE964, 0x9998,
+ 0xE965, 0x99A5,
+ 0xE966, 0x99AD,
+ 0xE967, 0x99AE,
+ 0xE968, 0x99BC,
+ 0xE969, 0x99DF,
+ 0xE96A, 0x99DB,
+ 0xE96B, 0x99DD,
+ 0xE96C, 0x99D8,
+ 0xE96D, 0x99D1,
+ 0xE96E, 0x99ED,
+ 0xE96F, 0x99EE,
+ 0xE970, 0x99F1,
+ 0xE971, 0x99F2,
+ 0xE972, 0x99FB,
+ 0xE973, 0x99F8,
+ 0xE974, 0x9A01,
+ 0xE975, 0x9A0F,
+ 0xE976, 0x9A05,
+ 0xE977, 0x99E2,
+ 0xE978, 0x9A19,
+ 0xE979, 0x9A2B,
+ 0xE97A, 0x9A37,
+ 0xE97B, 0x9A45,
+ 0xE97C, 0x9A42,
+ 0xE97D, 0x9A40,
+ 0xE97E, 0x9A43,
+ 0xE980, 0x9A3E,
+ 0xE981, 0x9A55,
+ 0xE982, 0x9A4D,
+ 0xE983, 0x9A5B,
+ 0xE984, 0x9A57,
+ 0xE985, 0x9A5F,
+ 0xE986, 0x9A62,
+ 0xE987, 0x9A65,
+ 0xE988, 0x9A64,
+ 0xE989, 0x9A69,
+ 0xE98A, 0x9A6B,
+ 0xE98B, 0x9A6A,
+ 0xE98C, 0x9AAD,
+ 0xE98D, 0x9AB0,
+ 0xE98E, 0x9ABC,
+ 0xE98F, 0x9AC0,
+ 0xE990, 0x9ACF,
+ 0xE991, 0x9AD1,
+ 0xE992, 0x9AD3,
+ 0xE993, 0x9AD4,
+ 0xE994, 0x9ADE,
+ 0xE995, 0x9ADF,
+ 0xE996, 0x9AE2,
+ 0xE997, 0x9AE3,
+ 0xE998, 0x9AE6,
+ 0xE999, 0x9AEF,
+ 0xE99A, 0x9AEB,
+ 0xE99B, 0x9AEE,
+ 0xE99C, 0x9AF4,
+ 0xE99D, 0x9AF1,
+ 0xE99E, 0x9AF7,
+ 0xE99F, 0x9AFB,
+ 0xE9A0, 0x9B06,
+ 0xE9A1, 0x9B18,
+ 0xE9A2, 0x9B1A,
+ 0xE9A3, 0x9B1F,
+ 0xE9A4, 0x9B22,
+ 0xE9A5, 0x9B23,
+ 0xE9A6, 0x9B25,
+ 0xE9A7, 0x9B27,
+ 0xE9A8, 0x9B28,
+ 0xE9A9, 0x9B29,
+ 0xE9AA, 0x9B2A,
+ 0xE9AB, 0x9B2E,
+ 0xE9AC, 0x9B2F,
+ 0xE9AD, 0x9B32,
+ 0xE9AE, 0x9B44,
+ 0xE9AF, 0x9B43,
+ 0xE9B0, 0x9B4F,
+ 0xE9B1, 0x9B4D,
+ 0xE9B2, 0x9B4E,
+ 0xE9B3, 0x9B51,
+ 0xE9B4, 0x9B58,
+ 0xE9B5, 0x9B74,
+ 0xE9B6, 0x9B93,
+ 0xE9B7, 0x9B83,
+ 0xE9B8, 0x9B91,
+ 0xE9B9, 0x9B96,
+ 0xE9BA, 0x9B97,
+ 0xE9BB, 0x9B9F,
+ 0xE9BC, 0x9BA0,
+ 0xE9BD, 0x9BA8,
+ 0xE9BE, 0x9BB4,
+ 0xE9BF, 0x9BC0,
+ 0xE9C0, 0x9BCA,
+ 0xE9C1, 0x9BB9,
+ 0xE9C2, 0x9BC6,
+ 0xE9C3, 0x9BCF,
+ 0xE9C4, 0x9BD1,
+ 0xE9C5, 0x9BD2,
+ 0xE9C6, 0x9BE3,
+ 0xE9C7, 0x9BE2,
+ 0xE9C8, 0x9BE4,
+ 0xE9C9, 0x9BD4,
+ 0xE9CA, 0x9BE1,
+ 0xE9CB, 0x9C3A,
+ 0xE9CC, 0x9BF2,
+ 0xE9CD, 0x9BF1,
+ 0xE9CE, 0x9BF0,
+ 0xE9CF, 0x9C15,
+ 0xE9D0, 0x9C14,
+ 0xE9D1, 0x9C09,
+ 0xE9D2, 0x9C13,
+ 0xE9D3, 0x9C0C,
+ 0xE9D4, 0x9C06,
+ 0xE9D5, 0x9C08,
+ 0xE9D6, 0x9C12,
+ 0xE9D7, 0x9C0A,
+ 0xE9D8, 0x9C04,
+ 0xE9D9, 0x9C2E,
+ 0xE9DA, 0x9C1B,
+ 0xE9DB, 0x9C25,
+ 0xE9DC, 0x9C24,
+ 0xE9DD, 0x9C21,
+ 0xE9DE, 0x9C30,
+ 0xE9DF, 0x9C47,
+ 0xE9E0, 0x9C32,
+ 0xE9E1, 0x9C46,
+ 0xE9E2, 0x9C3E,
+ 0xE9E3, 0x9C5A,
+ 0xE9E4, 0x9C60,
+ 0xE9E5, 0x9C67,
+ 0xE9E6, 0x9C76,
+ 0xE9E7, 0x9C78,
+ 0xE9E8, 0x9CE7,
+ 0xE9E9, 0x9CEC,
+ 0xE9EA, 0x9CF0,
+ 0xE9EB, 0x9D09,
+ 0xE9EC, 0x9D08,
+ 0xE9ED, 0x9CEB,
+ 0xE9EE, 0x9D03,
+ 0xE9EF, 0x9D06,
+ 0xE9F0, 0x9D2A,
+ 0xE9F1, 0x9D26,
+ 0xE9F2, 0x9DAF,
+ 0xE9F3, 0x9D23,
+ 0xE9F4, 0x9D1F,
+ 0xE9F5, 0x9D44,
+ 0xE9F6, 0x9D15,
+ 0xE9F7, 0x9D12,
+ 0xE9F8, 0x9D41,
+ 0xE9F9, 0x9D3F,
+ 0xE9FA, 0x9D3E,
+ 0xE9FB, 0x9D46,
+ 0xE9FC, 0x9D48,
+ 0xEA40, 0x9D5D,
+ 0xEA41, 0x9D5E,
+ 0xEA42, 0x9D64,
+ 0xEA43, 0x9D51,
+ 0xEA44, 0x9D50,
+ 0xEA45, 0x9D59,
+ 0xEA46, 0x9D72,
+ 0xEA47, 0x9D89,
+ 0xEA48, 0x9D87,
+ 0xEA49, 0x9DAB,
+ 0xEA4A, 0x9D6F,
+ 0xEA4B, 0x9D7A,
+ 0xEA4C, 0x9D9A,
+ 0xEA4D, 0x9DA4,
+ 0xEA4E, 0x9DA9,
+ 0xEA4F, 0x9DB2,
+ 0xEA50, 0x9DC4,
+ 0xEA51, 0x9DC1,
+ 0xEA52, 0x9DBB,
+ 0xEA53, 0x9DB8,
+ 0xEA54, 0x9DBA,
+ 0xEA55, 0x9DC6,
+ 0xEA56, 0x9DCF,
+ 0xEA57, 0x9DC2,
+ 0xEA58, 0x9DD9,
+ 0xEA59, 0x9DD3,
+ 0xEA5A, 0x9DF8,
+ 0xEA5B, 0x9DE6,
+ 0xEA5C, 0x9DED,
+ 0xEA5D, 0x9DEF,
+ 0xEA5E, 0x9DFD,
+ 0xEA5F, 0x9E1A,
+ 0xEA60, 0x9E1B,
+ 0xEA61, 0x9E1E,
+ 0xEA62, 0x9E75,
+ 0xEA63, 0x9E79,
+ 0xEA64, 0x9E7D,
+ 0xEA65, 0x9E81,
+ 0xEA66, 0x9E88,
+ 0xEA67, 0x9E8B,
+ 0xEA68, 0x9E8C,
+ 0xEA69, 0x9E92,
+ 0xEA6A, 0x9E95,
+ 0xEA6B, 0x9E91,
+ 0xEA6C, 0x9E9D,
+ 0xEA6D, 0x9EA5,
+ 0xEA6E, 0x9EA9,
+ 0xEA6F, 0x9EB8,
+ 0xEA70, 0x9EAA,
+ 0xEA71, 0x9EAD,
+ 0xEA72, 0x9761,
+ 0xEA73, 0x9ECC,
+ 0xEA74, 0x9ECE,
+ 0xEA75, 0x9ECF,
+ 0xEA76, 0x9ED0,
+ 0xEA77, 0x9ED4,
+ 0xEA78, 0x9EDC,
+ 0xEA79, 0x9EDE,
+ 0xEA7A, 0x9EDD,
+ 0xEA7B, 0x9EE0,
+ 0xEA7C, 0x9EE5,
+ 0xEA7D, 0x9EE8,
+ 0xEA7E, 0x9EEF,
+ 0xEA80, 0x9EF4,
+ 0xEA81, 0x9EF6,
+ 0xEA82, 0x9EF7,
+ 0xEA83, 0x9EF9,
+ 0xEA84, 0x9EFB,
+ 0xEA85, 0x9EFC,
+ 0xEA86, 0x9EFD,
+ 0xEA87, 0x9F07,
+ 0xEA88, 0x9F08,
+ 0xEA89, 0x76B7,
+ 0xEA8A, 0x9F15,
+ 0xEA8B, 0x9F21,
+ 0xEA8C, 0x9F2C,
+ 0xEA8D, 0x9F3E,
+ 0xEA8E, 0x9F4A,
+ 0xEA8F, 0x9F52,
+ 0xEA90, 0x9F54,
+ 0xEA91, 0x9F63,
+ 0xEA92, 0x9F5F,
+ 0xEA93, 0x9F60,
+ 0xEA94, 0x9F61,
+ 0xEA95, 0x9F66,
+ 0xEA96, 0x9F67,
+ 0xEA97, 0x9F6C,
+ 0xEA98, 0x9F6A,
+ 0xEA99, 0x9F77,
+ 0xEA9A, 0x9F72,
+ 0xEA9B, 0x9F76,
+ 0xEA9C, 0x9F95,
+ 0xEA9D, 0x9F9C,
+ 0xEA9E, 0x9FA0,
+ 0xEA9F, 0x582F,
+ 0xEAA0, 0x69C7,
+ 0xEAA1, 0x9059,
+ 0xEAA2, 0x7464,
+ 0xEAA3, 0x51DC,
+ 0xEAA4, 0x7199,
+ 0
diff --git a/streamer.c b/streamer.c
index b1834cd0..e2c1f1b0 100644
--- a/streamer.c
+++ b/streamer.c
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -20,7 +20,6 @@
#include <stdio.h>
#include <assert.h>
#include <unistd.h>
-#include <samplerate.h>
#ifdef __linux__
#include <sys/prctl.h>
#endif
@@ -29,53 +28,63 @@
#include "playlist.h"
#include "common.h"
#include "streamer.h"
-#include "playback.h"
#include "messagepump.h"
#include "conf.h"
#include "plugins.h"
#include "optmath.h"
#include "volume.h"
#include "vfs.h"
+#include "premix.h"
+#include "ringbuf.h"
+#include "replaygain.h"
//#define trace(...) { fprintf(stderr, __VA_ARGS__); }
#define trace(fmt,...)
-// #define WRITE_DUMP 1
+//#define WRITE_DUMP 1
#if WRITE_DUMP
FILE *out;
#endif
+
+static int
+streamer_read_async (char *bytes, int size);
+
+static int
+streamer_set_output_format (void);
+
static intptr_t streamer_tid;
-static int src_quality;
-static SRC_STATE *src;
-static SRC_DATA srcdata;
-static int src_remaining; // number of input samples in SRC buffer
+static ddb_dsp_context_t *dsp_chain;
+static float dsp_ratio = 1;
-static int conf_replaygain_mode = 0;
-static int conf_replaygain_scale = 1;
+static DB_dsp_t *eqplug;
+static ddb_dsp_context_t *eq;
-#define SRC_BUFFER 16000
-static int src_in_remaining = 0;
-//static int16_t g_src_in_buffer[SRC_BUFFER*2];
-static __attribute__((__aligned__(16))) float g_src_in_fbuffer[SRC_BUFFER*2];
-static __attribute__((__aligned__(16))) float g_src_out_fbuffer[SRC_BUFFER*2];
+static int dsp_on = 0;
static int streaming_terminate;
// buffer up to 3 seconds at 44100Hz stereo
#define STREAM_BUFFER_SIZE 0x80000 // slightly more than 3 seconds of 44100 stereo
-#define STREAM_BUFFER_MASK 0x7ffff
-//#define STREAM_BUFFER_SIZE 0x10000 // slightly more than 3 seconds of 44100 stereo
-//#define STREAM_BUFFER_MASK 0xffff
-static int streambuffer_fill;
-static int streambuffer_pos;
-static int bytes_until_next_song = 0;
+// how much bigger should read-buffer be to allow upsampling.
+// e.g. 8000Hz -> 192000Hz upsampling requires 24x buffer size,
+// so if we originally request 4096 bytes blocks -
+// that will require 24x buffer size, which is 98304 bytes buffer
+#define MAX_DSP_RATIO 24
+
+#define MIN_BLOCK_SIZE 4096
+#define MAX_BLOCK_SIZE 16384
+#define READBUFFER_SIZE (MAX_BLOCK_SIZE * MAX_DSP_RATIO)
+static char readbuffer[READBUFFER_SIZE];
+
+static ringbuf_t streamer_ringbuf;
static char streambuffer[STREAM_BUFFER_SIZE];
+
+static int bytes_until_next_song = 0;
static uintptr_t mutex;
static uintptr_t decodemutex;
-static uintptr_t srcmutex;
static int nextsong = -1;
static int nextsong_pstate = -1;
static int badsong = -1;
@@ -91,6 +100,9 @@ static playItem_t *playing_track;
static playItem_t *streaming_track;
static playItem_t *playlist_track;
+static ddb_waveformat_t output_format;
+static int formatchanged;
+
static DB_fileinfo_t *fileinfo;
static int streamer_buffering;
@@ -108,16 +120,6 @@ streamer_unlock (void) {
mutex_unlock (mutex);
}
-void
-src_lock (void) {
- mutex_lock (srcmutex);
-}
-
-void
-src_unlock (void) {
- mutex_unlock (srcmutex);
-}
-
static void
streamer_abort_files (void) {
if (fileinfo && fileinfo->file) {
@@ -125,12 +127,10 @@ streamer_abort_files (void) {
deadbeef->fabort (fileinfo->file);
trace ("\033[0;31maborting current song done\033[37;0m\n");
}
- mutex_lock (decodemutex);
if (streamer_file) {
trace ("\033[0;31maborting streamer_file\033[37;0m\n");
deadbeef->fabort (streamer_file);
}
- mutex_unlock (decodemutex);
}
void
@@ -151,11 +151,19 @@ streamer_start_playback (playItem_t *from, playItem_t *it) {
playing_track = it;
if (playing_track) {
pl_item_ref (playing_track);
+
+ // setup replaygain
+ float albumgain = pl_get_item_replaygain (playing_track, DDB_REPLAYGAIN_ALBUMGAIN);
+ float albumpeak = pl_get_item_replaygain (playing_track, DDB_REPLAYGAIN_ALBUMPEAK);
+ float trackgain = pl_get_item_replaygain (playing_track, DDB_REPLAYGAIN_TRACKGAIN);
+ float trackpeak = pl_get_item_replaygain (playing_track, DDB_REPLAYGAIN_TRACKPEAK);
+ replaygain_set_values (albumgain, albumpeak, trackgain, trackpeak);
+
playing_track->played = 1;
playing_track->started_timestamp = time (NULL);
trace ("sending songstarted to plugins [2] current playtrack: %s\n", playing_track->fname);
plug_trigger_event (DB_EV_SONGSTARTED, 0);
- trace ("from=%p (%s), to=%p (%s) [2]\n", from, from ? from->fname : "null", it, it ? it->fname : "null");
+ trace ("from=%p (%s), to=%p (%s) [2]\n", from, from ? from->fname : "null", it, it ? pl_find_meta (it, ":URI") : "null");
plug_trigger_event_trackchange (from, it);
}
if (from) {
@@ -245,16 +253,16 @@ streamer_move_to_nextsong (int reason) {
return 0;
}
else {
- trace ("%s not found in current streaming playlist\n", it->fname);
+ trace ("%s not found in current streaming playlist\n", pl_find_meta (it, ":URI"));
// find playlist
playlist_t *old = streamer_playlist;
streamer_playlist = plt_get_list ();
int i = 0;
while (streamer_playlist) {
- trace ("searching for %s in playlist %d\n", it->fname, i);
+ trace ("searching for %s in playlist %d\n", pl_find_meta (it, ":URI"), i);
int r = str_get_idx_of (it);
if (r >= 0) {
- trace ("%s found in playlist %d\n", it->fname, i);
+ trace ("%s found in playlist %d\n", pl_find_meta (it, ":URI"), i);
pl_item_unref (it);
streamer_set_nextsong (r, 3);
pl_global_unlock ();
@@ -263,7 +271,7 @@ streamer_move_to_nextsong (int reason) {
i++;
streamer_playlist = streamer_playlist->next;
}
- trace ("%s not found in any playlists\n", it->fname);
+ trace ("%s not found in any playlists\n", pl_find_meta (it, ":URI"));
streamer_playlist = old;
pl_item_unref (it);
}
@@ -284,7 +292,8 @@ streamer_move_to_nextsong (int reason) {
pl_global_unlock ();
return 0;
}
- int pl_order = conf_get_int ("playback.order", 0);
+ int pl_order = pl_get_order ();
+
int pl_loop_mode = conf_get_int ("playback.loop", 0);
if (reason == 0 && pl_loop_mode == PLAYBACK_MODE_LOOP_SINGLE) { // song finished, loop mode is "loop 1 track"
@@ -299,7 +308,7 @@ streamer_move_to_nextsong (int reason) {
return 0;
}
- if (pl_order == PLAYBACK_ORDER_SHUFFLE) { // shuffle
+ if (pl_order == PLAYBACK_ORDER_SHUFFLE_TRACKS || pl_order == PLAYBACK_ORDER_SHUFFLE_ALBUMS) { // shuffle
if (!curr) {
// find minimal notplayed
playItem_t *pmin = NULL; // notplayed minimum
@@ -349,9 +358,11 @@ streamer_move_to_nextsong (int reason) {
}
}
if (!it) {
+ streamer_buffering = 0;
+ plug_trigger_event_trackinfochanged (streaming_track);
playItem_t *temp;
plt_reshuffle (streamer_playlist, &temp, NULL);
- streamer_set_nextsong (-2, 1);
+ streamer_set_nextsong (-2, -2);
pl_global_unlock ();
return -1;
}
@@ -372,7 +383,10 @@ streamer_move_to_nextsong (int reason) {
it = plt->head[PL_MAIN];
}
else {
- streamer_set_nextsong (-2, 1);
+ streamer_buffering = 0;
+ plug_trigger_event_trackinfochanged (streaming_track);
+ badsong = -1;
+ streamer_set_nextsong (-2, -2);
pl_global_unlock ();
return 0;
}
@@ -420,7 +434,7 @@ streamer_move_to_prevsong (void) {
}
int pl_order = conf_get_int ("playback.order", 0);
int pl_loop_mode = conf_get_int ("playback.loop", 0);
- if (pl_order == PLAYBACK_ORDER_SHUFFLE) { // shuffle
+ if (pl_order == PLAYBACK_ORDER_SHUFFLE_TRACKS || pl_order == PLAYBACK_ORDER_SHUFFLE_ALBUMS) { // shuffle
if (!playlist_track) {
plt_unlock ();
return streamer_move_to_nextsong (1);
@@ -442,6 +456,13 @@ streamer_move_to_prevsong (void) {
pmax = i;
}
}
+
+ if (pmax && pl_order == PLAYBACK_ORDER_SHUFFLE_ALBUMS) {
+ while (pmax && pmax->next[PL_MAIN] && pmax->next[PL_MAIN]->played && pmax->shufflerating == pmax->next[PL_MAIN]->shufflerating) {
+ pmax = pmax->next[PL_MAIN];
+ }
+ }
+
playItem_t *it = pmax;
if (!it) {
// that means 1st in playlist, take amax
@@ -529,7 +550,7 @@ streamer_song_removed_notify (playItem_t *it) {
playlist_track = playlist_track->next[PL_MAIN];
// queue new next song for streaming
if (bytes_until_next_song > 0) {
- streambuffer_fill = bytes_until_next_song;
+ streamer_ringbuf.remaining = bytes_until_next_song;
streamer_move_to_nextsong (0);
}
}
@@ -539,7 +560,9 @@ streamer_song_removed_notify (playItem_t *it) {
// that must be called after last sample from str_playing_song was done reading
static int
streamer_set_current (playItem_t *it) {
+ DB_output_t *output = plug_get_output ();
int err = 0;
+ DB_fileinfo_t *new_fileinfo = NULL;
playItem_t *from, *to;
// need to add refs here, because streamer_start_playback can destroy items
from = playing_track;
@@ -551,24 +574,18 @@ streamer_set_current (playItem_t *it) {
pl_item_ref (to);
}
trace ("\033[0;35mstreamer_set_current from %p to %p\033[37;0m\n", from, it);
- if (!playing_track || p_isstopped ()) {
- trace ("buffering = on\n");
+ if (!playing_track || output->state () == OUTPUT_STATE_STOPPED) {
streamer_buffering = 1;
trace ("\033[0;35mstreamer_start_playback[1] from %p to %p\033[37;0m\n", from, it);
streamer_start_playback (from, it);
bytes_until_next_song = -1;
}
-// code below breaks seekbar drawing during transition between tracks
trace ("streamer_set_current %p, buns=%d\n", it, bytes_until_next_song);
mutex_lock (decodemutex);
- if (fileinfo) {
- fileinfo->plugin->free (fileinfo);
- fileinfo = NULL;
- if (streaming_track) {
- pl_item_unref (streaming_track);
- streaming_track = NULL;
- }
+ if (streaming_track) {
+ pl_item_unref (streaming_track);
+ streaming_track = NULL;
}
mutex_unlock (decodemutex);
if (!it) {
@@ -581,14 +598,17 @@ streamer_set_current (playItem_t *it) {
if (from) {
plug_trigger_event_trackinfochanged (from);
}
- if (!it->decoder_id && it->filetype && !strcmp (it->filetype, "content")) {
+ pl_lock ();
+ const char *decoder_id = pl_find_meta (it, ":DECODER");
+ const char *filetype = pl_find_meta (it, ":FILETYPE");
+ if (!decoder_id && filetype && !strcmp (filetype, "content")) {
// try to get content-type
mutex_lock (decodemutex);
- trace ("\033[0;34mopening file %s\033[37;0m\n", it->fname);
- DB_FILE *fp = streamer_file = vfs_fopen (it->fname);
+ trace ("\033[0;34mopening file %s\033[37;0m\n", pl_find_meta (it, ":URI"));
+ DB_FILE *fp = streamer_file = vfs_fopen (pl_find_meta (it, ":URI"));
mutex_unlock (decodemutex);
const char *plug = NULL;
- if (fp) {
+ if (fp && vfs_get_content_type) {
const char *ct = vfs_get_content_type (fp);
if (ct) {
trace ("got content-type: %s\n", ct);
@@ -618,32 +638,57 @@ streamer_set_current (playItem_t *it) {
// match by decoder
for (int i = 0; decoders[i]; i++) {
if (!strcmp (decoders[i]->plugin.id, plug)) {
- it->decoder_id = decoders[i]->plugin.id;
- it->filetype = decoders[i]->filetypes[0];
+ pl_replace_meta (it, ":DECODER", decoders[i]->plugin.id);
+ decoder_id = decoders[i]->plugin.id;
+ pl_replace_meta (it, ":FILETYPE", decoders[i]->filetypes[0]);
trace ("\033[0;34mfound plugin %s\033[37;0m\n", plug);
}
}
}
else {
- trace ("\033[0;34mclosed file %s (bad or interrupted)\033[37;0m\n", it->fname);
+ trace ("\033[0;34mclosed file %s (bad or interrupted)\033[37;0m\n", pl_find_meta (it, ":URI"));
}
}
- if (it->decoder_id) {
+ playlist_track = it;
+ if (decoder_id) {
DB_decoder_t *dec = NULL;
- dec = plug_get_decoder_for_id (it->decoder_id);
+ dec = plug_get_decoder_for_id (decoder_id);
+ if (!dec) {
+ // find new decoder by file extension
+ const char *fname = pl_find_meta (it, ":URI");
+ const char *ext = strrchr (fname, '.');
+ if (ext) {
+ ext++;
+ DB_decoder_t **decs = plug_get_decoder_list ();
+ for (int i = 0; decs[i]; i++) {
+ const char **exts = decs[i]->exts;
+ if (exts) {
+ for (int j = 0; exts[j]; j++) {
+ if (!strcasecmp (exts[j], ext)) {
+ fprintf (stderr, "streamer: %s : changed decoder plugin to %s\n", fname, decs[i]->plugin.id);
+ pl_replace_meta (it, ":DECODER", decs[i]->plugin.id);
+ pl_replace_meta (it, ":FILETYPE", ext);
+ dec = decs[i];
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
if (dec) {
- trace ("\033[0;33minit decoder for %s\033[37;0m\n", it->fname);
- fileinfo = dec->open ();
- if (fileinfo && dec->init (fileinfo, DB_PLAYITEM (it)) != 0) {
+ trace ("\033[0;33minit decoder for %s (%s)\033[37;0m\n", pl_find_meta (it, ":URI"), decoder_id);
+ new_fileinfo = dec->open (0);
+ if (new_fileinfo && dec->init (new_fileinfo, DB_PLAYITEM (it)) != 0) {
trace ("\033[0;31mfailed to init decoder\033[37;0m\n")
- dec->free (fileinfo);
- fileinfo = NULL;
+ dec->free (new_fileinfo);
+ new_fileinfo = NULL;
}
}
- if (!dec || !fileinfo) {
+ if (!dec || !new_fileinfo) {
it->played = 1;
- trace ("decoder->init returned %p\n", fileinfo);
+ trace ("decoder->init returned %p\n", new_fileinfo);
streamer_buffering = 0;
if (playlist_track == it) {
trace ("redraw track %d; playing_track=%p; playlist_track=%p\n", to, playing_track, playlist_track);
@@ -660,12 +705,11 @@ streamer_set_current (playItem_t *it) {
streaming_track = it;
pl_item_ref (streaming_track);
mutex_unlock (decodemutex);
- trace ("bps=%d, channels=%d, samplerate=%d\n", fileinfo->bps, fileinfo->channels, fileinfo->samplerate);
+ trace ("bps=%d, channels=%d, samplerate=%d\n", new_fileinfo->fmt.bps, new_fileinfo->fmt.channels, new_fileinfo->fmt.samplerate);
}
-// FIXME: that might break streaming at boundaries between 2 different samplerates
-// streamer_reset (0); // reset SRC
}
else {
+ pl_unlock ();
trace ("no decoder in playitem!\n");
it->played = 1;
streamer_buffering = 0;
@@ -680,7 +724,17 @@ streamer_set_current (playItem_t *it) {
}
return -1;
}
+ pl_unlock ();
success:
+ mutex_lock (decodemutex);
+ if (new_fileinfo) {
+ if (fileinfo) {
+ fileinfo->plugin->free (fileinfo);
+ fileinfo = NULL;
+ }
+ fileinfo = new_fileinfo;
+ }
+ mutex_unlock (decodemutex);
plug_trigger_event_trackinfochanged (to);
trace ("\033[0;32mstr: %p (%s), ply: %p (%s)\033[37;0m\n", streaming_track, streaming_track ? streaming_track->fname : "null", playing_track, playing_track ? playing_track->fname : "null");
@@ -719,12 +773,13 @@ streamer_get_apx_bitrate (void) {
void
streamer_set_nextsong (int song, int pstate) {
+ DB_output_t *output = plug_get_output ();
trace ("streamer_set_nextsong %d %d\n", song, pstate);
- streamer_lock ();
streamer_abort_files ();
+ streamer_lock ();
nextsong = song;
nextsong_pstate = pstate;
- if (p_isstopped ()) {
+ if (output->state () == OUTPUT_STATE_STOPPED) {
if (pstate == 1) { // means user initiated this
streamer_playlist = plt_get_curr_ptr ();
}
@@ -741,29 +796,26 @@ streamer_set_seek (float pos) {
seekpos = pos;
}
-static int
-streamer_read_async (char *bytes, int size);
-
static void
streamer_start_new_song (void) {
- trace ("nextsong=%d\n", nextsong);
+ trace ("nextsong=%d (badsong=%d)\n", nextsong, badsong);
streamer_lock ();
+ DB_output_t *output = plug_get_output ();
int sng = nextsong;
int initsng = nextsong;
int pstate = nextsong_pstate;
nextsong = -1;
- src_remaining = 0;
streamer_unlock ();
if (badsong == sng) {
trace ("looped to bad file. stopping...\n");
- streamer_set_nextsong (-2, 1);
+ streamer_set_nextsong (-2, -2);
badsong = -1;
return;
}
playItem_t *try = str_get_for_idx (sng);
if (!try) { // track is not in playlist
trace ("track #%d is not in playlist; stopping playback\n", sng);
- p_stop ();
+ output->stop ();
mutex_lock (decodemutex);
if (playing_track) {
@@ -806,39 +858,59 @@ streamer_start_new_song (void) {
try = NULL;
badsong = -1;
trace ("pstate = %d\n", pstate);
- trace ("playback state = %d\n", p_state ());
+ trace ("playback state = %d\n", output->state ());
if (pstate == 0) {
- p_stop ();
+ output->stop ();
}
else if (pstate == 1 || pstate == 3) {
last_bitrate = -1;
avg_bitrate = -1;
- if (p_state () != OUTPUT_STATE_PLAYING) {
+ if (output->state () != OUTPUT_STATE_PLAYING) {
streamer_reset (1);
- if (fileinfo) {
- plug_get_output ()->change_rate (fileinfo->samplerate);
+ if (!dsp_on && fileinfo && memcmp (&output_format, &fileinfo->fmt, sizeof (ddb_waveformat_t))) {
+ memcpy (&output_format, &fileinfo->fmt, sizeof (ddb_waveformat_t));
+ fprintf (stderr, "streamer_set_output_format %dbit %s %dch %dHz channelmask=%X\n", output_format.bps, output_format.is_float ? "float" : "int", output_format.channels, output_format.samplerate, output_format.channelmask);
+ streamer_set_output_format ();
}
- if (p_play () < 0) {
- fprintf (stderr, "streamer: failed to start playback; output plugin doesn't work\n");
- streamer_set_nextsong (-2, 0);
+ if (output->state () != OUTPUT_STATE_PLAYING) {
+ if (0 != output->play ()) {
+ memset (&output_format, 0, sizeof (output_format));
+ fprintf (stderr, "streamer: failed to start playback (start track)\n");
+ streamer_set_nextsong (-2, 0);
+ }
}
}
}
else if (pstate == 2) {
- if (p_get_state () == OUTPUT_STATE_STOPPED) {
+ if (output->state () == OUTPUT_STATE_STOPPED) {
last_bitrate = -1;
avg_bitrate = -1;
streamer_reset (1);
- if (fileinfo) {
- plug_get_output ()->change_rate (fileinfo->samplerate);
+ if (fileinfo && memcmp (&output_format, &fileinfo->fmt, sizeof (ddb_waveformat_t))) {
+ memcpy (&output_format, &fileinfo->fmt, sizeof (ddb_waveformat_t));
+ formatchanged = 1;
}
- if (p_play () < 0) {
- fprintf (stderr, "streamer: failed to start playback; output plugin doesn't work\n");
+ // we need to start playback before we can pause it
+ if (0 != output->play ()) {
+ memset (&output_format, 0, sizeof (output_format));
+ fprintf (stderr, "streamer: failed to start playback (start track)\n");
streamer_set_nextsong (-2, 0);
- return;
}
}
- p_pause ();
+ output->pause ();
+ }
+}
+
+void
+streamer_next (int bytesread) {
+ streamer_lock ();
+ bytes_until_next_song = streamer_ringbuf.remaining + bytesread;
+ streamer_unlock ();
+ if (conf_get_int ("playlist.stop_after_current", 0)) {
+ streamer_set_nextsong (-2, 1);
+ }
+ else {
+ streamer_move_to_nextsong (0);
}
}
@@ -847,13 +919,17 @@ streamer_thread (void *ctx) {
#ifdef __linux__
prctl (PR_SET_NAME, "deadbeef-stream", 0, 0, 0, 0);
#endif
- src_remaining = 0;
while (!streaming_terminate) {
struct timeval tm1;
+ DB_output_t *output = plug_get_output ();
gettimeofday (&tm1, NULL);
if (nextsong >= 0) { // start streaming next song
trace ("\033[0;34mnextsong=%d\033[37;0m\n", nextsong);
+ if (playing_track) {
+ trace ("sending songfinished to plugins [3]\n");
+ plug_trigger_event (DB_EV_SONGFINISHED, 0);
+ }
streamer_start_new_song ();
// it's totally possible that song was switched
// while streamer_set_current was running,
@@ -866,7 +942,7 @@ streamer_thread (void *ctx) {
bytes_until_next_song = -1;
trace ("nextsong=-2\n");
nextsong = -1;
- p_stop ();
+ output->stop ();
if (playing_track) {
trace ("sending songfinished to plugins [1]\n");
plug_trigger_event (DB_EV_SONGFINISHED, 0);
@@ -886,7 +962,7 @@ streamer_thread (void *ctx) {
streamer_unlock ();
continue;
}
- else if (p_isstopped ()) {
+ else if (output->state () == OUTPUT_STATE_STOPPED) {
usleep (50000);
continue;
}
@@ -896,7 +972,7 @@ streamer_thread (void *ctx) {
if (!streaming_track) {
// means last song was deleted during final drain
nextsong = -1;
- p_stop ();
+ output->stop ();
streamer_set_current (NULL);
streamer_unlock ();
continue;
@@ -920,53 +996,51 @@ streamer_thread (void *ctx) {
playpos = 0;
seekpos = -1;
- // try to switch samplerate to the closest supported by output plugin
- if (conf_get_int ("playback.dynsamplerate", 0)) {
-
- // don't switch if unchanged
- int prevtrack_samplerate = p_get_rate ();
- if (prevtrack_samplerate != fileinfo->samplerate) {
- int newrate = plug_get_output ()->change_rate (fileinfo->samplerate);
- if (newrate != prevtrack_samplerate) {
- // restart streaming of current track
- trace ("streamer: output samplerate changed from %d to %d; restarting track\n", prevtrack_samplerate, newrate);
- mutex_lock (decodemutex);
- fileinfo->plugin->free (fileinfo);
- fileinfo = NULL;
- DB_decoder_t *dec = NULL;
- dec = plug_get_decoder_for_id (streaming_track->decoder_id);
- if (dec) {
- fileinfo = dec->open ();
- if (fileinfo && dec->init (fileinfo, DB_PLAYITEM (streaming_track)) < 0) {
- dec->free (fileinfo);
- fileinfo = NULL;
- }
- }
- if (!dec || !fileinfo) {
- // FIXME: handle error
- }
- mutex_unlock (decodemutex);
- bytes_until_next_song = -1;
- streamer_buffering = 1;
- streamer_reset (1);
- if (fileinfo) {
- prevtrack_samplerate = fileinfo->samplerate;
+ // don't switch if unchanged
+ ddb_waveformat_t prevfmt;
+ memcpy (&prevfmt, &output->fmt, sizeof (ddb_waveformat_t));
+ if (memcmp (&output_format, &fileinfo->fmt, sizeof (ddb_waveformat_t))) {
+ memcpy (&output_format, &fileinfo->fmt, sizeof (ddb_waveformat_t));
+ formatchanged = 1;
+#if 0
+ // FIXME: this breaks gapless playback if output sampletate was
+ // changed by dsp plugin
+ memcpy (&output_format, &fileinfo->fmt, sizeof (ddb_waveformat_t));
+ streamer_unlock (); // prevent race-condition in output plugins
+ output->setformat (&fileinfo->fmt);
+ streamer_lock ();
+ // check if the format actually changed
+ if (memcmp (&output->fmt, &prevfmt, sizeof (ddb_waveformat_t))) {
+ // restart streaming of current track
+ trace ("streamer: output samplerate changed from %d to %d; restarting track\n", prevfmt.samplerate, output->fmt.samplerate);
+ mutex_lock (decodemutex);
+ fileinfo->plugin->free (fileinfo);
+ fileinfo = NULL;
+ DB_decoder_t *dec = NULL;
+ dec = plug_get_decoder_for_id (streaming_track->decoder_id);
+ if (dec) {
+ fileinfo = dec->open (0);
+ if (fileinfo && dec->init (fileinfo, DB_PLAYITEM (streaming_track)) < 0) {
+ dec->free (fileinfo);
+ fileinfo = NULL;
}
}
- }
-
- // output plugin may stop playback before switching samplerate
- if (p_state () != OUTPUT_STATE_PLAYING) {
- if (fileinfo) {
- plug_get_output ()->change_rate (fileinfo->samplerate);
+ if (!dec || !fileinfo) {
+ // FIXME: handle error
}
- if (p_play () < 0) {
- fprintf (stderr, "streamer: failed to start playback after samplerate change; output plugin doesn't work\n");
- streamer_set_nextsong (-2, 0);
- streamer_unlock ();
- continue;
+ mutex_unlock (decodemutex);
+ bytes_until_next_song = -1;
+ streamer_buffering = 1;
+ streamer_reset (1);
+ if (output->state () != OUTPUT_STATE_PLAYING) {
+ if (0 != output->play ()) {
+ memset (&output_format, 0, sizeof (output_format));
+ fprintf (stderr, "streamer: failed to start playback (track transition format change)\n");
+ streamer_set_nextsong (-2, 0);
+ }
}
}
+#endif
}
streamer_unlock ();
}
@@ -986,6 +1060,7 @@ streamer_thread (void *ctx) {
mutex_lock (decodemutex);
if(fileinfo) {
fileinfo->plugin->free (fileinfo);
+ fileinfo = NULL;
pl_item_unref (streaming_track);
streaming_track = NULL;
}
@@ -1003,9 +1078,12 @@ streamer_thread (void *ctx) {
mutex_lock (decodemutex);
DB_decoder_t *dec = NULL;
- dec = plug_get_decoder_for_id (streaming_track->decoder_id);
+ pl_lock ();
+ const char *decoder_id = pl_find_meta (streaming_track, ":DECODER");
+ dec = plug_get_decoder_for_id (decoder_id);
+ pl_unlock ();
if (dec) {
- fileinfo = dec->open ();
+ fileinfo = dec->open (0);
if (fileinfo && dec->init (fileinfo, DB_PLAYITEM (streaming_track)) != 0) {
dec->free (fileinfo);
fileinfo = NULL;
@@ -1030,14 +1108,15 @@ streamer_thread (void *ctx) {
if (streaming_track) {
plug_trigger_event_trackinfochanged (streaming_track);
}
- if (fileinfo && playing_track && playing_track->_duration > 0) {
+ float dur = pl_get_item_duration (playing_track);
+ if (fileinfo && playing_track && dur > 0) {
+ if (pos >= dur) {
+ output->stop ();
+ streamer_move_to_nextsong (1);
+ continue;
+ }
streamer_lock ();
streamer_reset (1);
-#if 0
- streambuffer_fill = 0;
- streambuffer_pos = 0;
- src_remaining = 0;
-#endif
if (fileinfo->plugin->seek (fileinfo, pos) >= 0) {
playpos = fileinfo->readpos;
}
@@ -1048,41 +1127,74 @@ streamer_thread (void *ctx) {
}
// read ahead at 2x speed of output samplerate, in 4k blocks
- int rate = p_get_rate ();
+ int rate = output->fmt.samplerate;
if (!rate) {
trace ("str: got 0 output samplerate\n");
usleep(20000);
continue;
}
- int channels = 2; // FIXME: needs to be queried from output plugin
- int bytes_in_one_second = rate * sizeof (int16_t) * channels;
- const int blocksize = 4096;
- int alloc_time = 1000 / (bytes_in_one_second * 2 / blocksize);
-
+ int channels = output->fmt.channels;
+ int bytes_in_one_second = rate * (output->fmt.bps>>3) * channels;
+ const int blocksize = MIN_BLOCK_SIZE;
+ int alloc_time = 1000 / (bytes_in_one_second / blocksize);
+ alloc_time /= 1.2;
+
+ int skip = 0;
+ if (bytes_until_next_song >= 0) {
+ // check if streaming format differs from output
+ if (memcmp(&fileinfo->fmt, &output_format, sizeof (ddb_waveformat_t))) {
+ skip = 1;
+ streamer_buffering = 0;
+ }
+ }
streamer_lock ();
- if (streambuffer_fill < (STREAM_BUFFER_SIZE-blocksize)) {
- int sz = STREAM_BUFFER_SIZE - streambuffer_fill;
+
+ if (!formatchanged && !skip && streamer_ringbuf.remaining < (STREAM_BUFFER_SIZE-blocksize * MAX_DSP_RATIO)) {
+ int sz = STREAM_BUFFER_SIZE - streamer_ringbuf.remaining;
int minsize = blocksize;
// speed up buffering when empty
- if (streambuffer_fill < 16384) {
+ if (streamer_ringbuf.remaining < MAX_BLOCK_SIZE) {
minsize *= 4;
alloc_time *= 4;
}
sz = min (minsize, sz);
assert ((sz&3) == 0);
- char buf[sz];
+ // buffer must be larger enough to accomodate resamplers/pitchers/...
+ // FIXME: bounds checking
streamer_unlock ();
- int bytesread = streamer_read_async (buf,sz);
+
+ // ensure that size is possible with current format
+ int samplesize = output->fmt.channels * (output->fmt.bps>>3);
+ if (sz % samplesize) {
+ sz -= (sz % samplesize);
+ }
+
+ int bytesread = 0;
+ do {
+ int prev_buns = bytes_until_next_song;
+ int nb = streamer_read_async (readbuffer+bytesread,sz-bytesread);
+ bytesread += nb;
+ struct timeval tm2;
+ gettimeofday (&tm2, NULL);
+ int ms = (tm2.tv_sec*1000+tm2.tv_usec/1000) - (tm1.tv_sec*1000+tm1.tv_usec/1000);
+ if (ms >= alloc_time) {
+ break;
+ }
+ if (prev_buns != bytes_until_next_song) {
+ break;
+ }
+ } while (bytesread < sz-100);
streamer_lock ();
- memcpy (streambuffer+streambuffer_fill, buf, sz);
+
if (bytesread > 0) {
- streambuffer_fill += bytesread;
+ ringbuf_write (&streamer_ringbuf, readbuffer, bytesread);
}
-// if (streamer_buffering) trace ("fill: %d, read: %d, size=%d, blocksize=%d\n", streambuffer_fill, bytesread, STREAM_BUFFER_SIZE, blocksize);
+
+ //trace ("fill: %d, read: %d, size=%d, blocksize=%d\n", streamer_ringbuf.remaining, bytesread, STREAM_BUFFER_SIZE, blocksize);
}
streamer_unlock ();
- if ((streambuffer_fill > 128000 && streamer_buffering) || !streaming_track) {
+ if ((streamer_ringbuf.remaining > 128000 && streamer_buffering) || !streaming_track) {
streamer_buffering = 0;
if (streaming_track) {
plug_trigger_event_trackinfochanged (streaming_track);
@@ -1092,12 +1204,11 @@ streamer_thread (void *ctx) {
gettimeofday (&tm2, NULL);
int ms = (tm2.tv_sec*1000+tm2.tv_usec/1000) - (tm1.tv_sec*1000+tm1.tv_usec/1000);
+ //trace ("slept %dms (alloc=%dms, bytespersec=%d, chan=%d, blocksize=%d), fill: %d/%d (cursor=%d)\n", alloc_time-ms, alloc_time, bytes_in_one_second, output->fmt.channels, blocksize, streamer_ringbuf.remaining, STREAM_BUFFER_SIZE, streamer_ringbuf.cursor);
alloc_time -= ms;
if (!streamer_buffering && alloc_time > 0) {
usleep (alloc_time * 1000);
-// usleep (1000);
}
-// trace ("fill: %d/%d\n", streambuffer_fill, STREAM_BUFFER_SIZE);
}
// stop streaming song
@@ -1115,10 +1226,208 @@ streamer_thread (void *ctx) {
playing_track = NULL;
}
mutex_unlock (decodemutex);
+}
+
+void
+streamer_dsp_chain_free (ddb_dsp_context_t *dsp_chain) {
+ while (dsp_chain) {
+ ddb_dsp_context_t *next = dsp_chain->next;
+ dsp_chain->plugin->close (dsp_chain);
+ dsp_chain = next;
+ }
+}
+
+ddb_dsp_context_t *
+streamer_dsp_chain_load (const char *fname) {
+ int err = 1;
+ FILE *fp = fopen (fname, "rt");
+ if (!fp) {
+ return NULL;
+ }
+
+ char temp[100];
+ ddb_dsp_context_t *chain = NULL;
+ ddb_dsp_context_t *tail = NULL;
+ for (;;) {
+ // plugin enabled {
+ int enabled = 0;
+ int err = fscanf (fp, "%100s %d {\n", temp, &enabled);
+ if (err == EOF) {
+ break;
+ }
+ else if (2 != err) {
+ fprintf (stderr, "error plugin name\n");
+ goto error;
+ }
+
+ DB_dsp_t *plug = (DB_dsp_t *)deadbeef->plug_get_for_id (temp);
+ if (!plug) {
+ fprintf (stderr, "streamer_dsp_chain_load: plugin %s not found. preset will not be loaded\n", temp);
+ goto error;
+ }
+ ddb_dsp_context_t *ctx = plug->open ();
+ if (!ctx) {
+ fprintf (stderr, "streamer_dsp_chain_load: failed to open ctxance of plugin %s\n", temp);
+ goto error;
+ }
+
+ if (tail) {
+ tail->next = ctx;
+ tail = ctx;
+ }
+ else {
+ tail = chain = ctx;
+ }
+
+ int n = 0;
+ for (;;) {
+ char value[1000];
+ if (!fgets (temp, sizeof (temp), fp)) {
+ fprintf (stderr, "streamer_dsp_chain_load: unexpected eof while reading plugin params\n");
+ goto error;
+ }
+ if (!strcmp (temp, "}\n")) {
+ break;
+ }
+ else if (1 != sscanf (temp, "\t%1000[^\n]\n", value)) {
+ fprintf (stderr, "streamer_dsp_chain_load: error loading param %d\n", n);
+ goto error;
+ }
+ if (plug->num_params) {
+ plug->set_param (ctx, n, value);
+ }
+ n++;
+ }
+ ctx->enabled = enabled;
+ }
+
+ err = 0;
+error:
+ if (err) {
+ fprintf (stderr, "streamer_dsp_chain_load: error loading %s\n", fname);
+ }
+ if (fp) {
+ fclose (fp);
+ }
+ if (err && chain) {
+ streamer_dsp_chain_free (chain);
+ chain = NULL;
+ }
+ return chain;
+}
+
+int
+streamer_dsp_chain_save (const char *fname, ddb_dsp_context_t *chain) {
+ FILE *fp = fopen (fname, "w+t");
+ if (!fp) {
+ return -1;
+ }
+
+ ddb_dsp_context_t *ctx = chain;
+ while (ctx) {
+ fprintf (fp, "%s %d {\n", ctx->plugin->plugin.id, (int)ctx->enabled);
+ if (ctx->plugin->num_params) {
+ int n = ctx->plugin->num_params ();
+ int i;
+ for (i = 0; i < n; i++) {
+ char v[1000];
+ ctx->plugin->get_param (ctx, i, v, sizeof (v));
+ fprintf (fp, "\t%s\n", v);
+ }
+ }
+ fprintf (fp, "}\n");
+ ctx = ctx->next;
+ }
+
+ fclose (fp);
+ return 0;
+}
+
+void
+streamer_dsp_postinit (void) {
+ // note about EQ hack:
+ // we 1st check if there's an EQ in dsp chain, and just use it
+ // if not -- we add our own
+
+ // eq plug
+ if (eqplug) {
+ ddb_dsp_context_t *p;
+
+ for (p = dsp_chain; p; p = p->next) {
+ if (!strcmp (p->plugin->plugin.id, "supereq")) {
+ break;
+ }
+ }
+ if (p) {
+ eq = p;
+ }
+ else {
+ eq = eqplug->open ();
+ eq->enabled = 0;
+ eq->next = dsp_chain;
+ dsp_chain = eq;
+ }
+
+ }
+ ddb_dsp_context_t *ctx = dsp_chain;
+ while (ctx) {
+ if (ctx->enabled) {
+ break;
+ }
+ ctx = ctx->next;
+ }
+ if (!ctx && fileinfo) {
+ if (memcmp (&output_format, &fileinfo->fmt, sizeof (ddb_waveformat_t))) {
+ memcpy (&output_format, &fileinfo->fmt, sizeof (ddb_waveformat_t));
+ formatchanged = 1;
+ }
+ dsp_on = 0;
+ }
+ else if (ctx) {
+ dsp_on = 1;
+ // set some very generic format, this will allow playback of weird
+ // formats after fixing them with dsp plugins
+ output_format.bps = 16;
+ output_format.is_float = 0;
+ output_format.channels = 2;
+ output_format.samplerate = 44100;
+ output_format.channelmask = 3;
+ streamer_set_output_format ();
+ }
+ else if (!ctx) {
+ dsp_on = 0;
+ }
+}
+
+void
+streamer_dsp_refresh (void) {
+ mutex_lock (decodemutex);
+ streamer_dsp_postinit ();
+ mutex_unlock (decodemutex);
+}
- if (src) {
- src_delete (src);
- src = NULL;
+void
+streamer_dsp_init (void) {
+ // load dsp chain from file
+ char fname[PATH_MAX];
+ snprintf (fname, sizeof (fname), "%s/dspconfig", plug_get_config_dir ());
+ dsp_chain = streamer_dsp_chain_load (fname);
+
+ eqplug = (DB_dsp_t *)plug_get_for_id ("supereq");
+ streamer_dsp_postinit ();
+
+ // load legacy eq settings from pre-0.5
+ if (conf_find ("eq.", NULL)) {
+ eq->enabled = deadbeef->conf_get_int ("eq.enable", 0);
+ char s[50];
+ eqplug->set_param (eq, 0, (conf_get_str ("eq.preamp", "0", s, sizeof (s)), s));
+ for (int i = 0; i < 18; i++) {
+ char key[100];
+ snprintf (key, sizeof (key), "eq.band%d", i);
+ eqplug->set_param (eq, 1+i, (conf_get_str (key, "0", s, sizeof (s)), s));
+ }
+ // delete obsolete settings
+ conf_remove_items ("eq.");
}
}
@@ -1129,14 +1438,14 @@ streamer_init (void) {
#endif
mutex = mutex_create ();
decodemutex = mutex_create ();
- srcmutex = mutex_create ();
- src_quality = conf_get_int ("src_quality", 2);
- src = src_new (src_quality, 2, NULL);
- conf_replaygain_mode = conf_get_int ("replaygain_mode", 0);
- conf_replaygain_scale = conf_get_int ("replaygain_scale", 1);
- if (!src) {
- return -1;
- }
+
+ ringbuf_init (&streamer_ringbuf, streambuffer, STREAM_BUFFER_SIZE);
+
+ pl_set_order (conf_get_int ("playback.order", 0));
+
+ streamer_dsp_init ();
+
+ replaygain_set (conf_get_int ("replaygain_mode", 0), conf_get_int ("replaygain_scale", 1), conf_get_float ("replaygain_preamp", 0));
streamer_tid = thread_start (streamer_thread, NULL);
return 0;
}
@@ -1166,8 +1475,16 @@ streamer_free (void) {
decodemutex = 0;
mutex_free (mutex);
mutex = 0;
- mutex_free (srcmutex);
- srcmutex = 0;
+
+ char fname[PATH_MAX];
+ snprintf (fname, sizeof (fname), "%s/dspconfig", plug_get_config_dir ());
+ streamer_dsp_chain_save (fname, dsp_chain);
+
+ streamer_dsp_chain_free (dsp_chain);
+ dsp_chain = NULL;
+
+ eqplug = NULL;
+ eq = NULL;
}
void
@@ -1176,433 +1493,166 @@ streamer_reset (int full) { // must be called when current song changes by exter
fprintf (stderr, "ERROR: someone called streamer_reset after exit\n");
return; // failsafe, in case someone calls streamer reset after deinit
}
- src_lock ();
if (full) {
streamer_lock ();
- streambuffer_pos = 0;
- streambuffer_fill = 0;
+ streamer_ringbuf.remaining = 0;
streamer_unlock ();
}
- src_remaining = 0;
- src_reset (src);
- // reset dsp
- DB_dsp_t **dsp = deadbeef->plug_get_dsp_list ();
- //int srate = p_get_rate ();
- for (int i = 0; dsp[i]; i++) {
- if (dsp[i]->enabled ()) {
- dsp[i]->reset ();
- }
- }
- src_unlock ();
-}
-
-int replaygain = 1;
-int replaygain_scale = 1;
-static void
-apply_replay_gain_int16 (playItem_t *it, char *bytes, int size) {
- if (!replaygain || !conf_replaygain_mode) {
- return;
- }
- int vol = 1000;
- if (conf_replaygain_mode == 1) {
- if (it->replaygain_track_gain == 0) {
- return;
- }
- vol = db_to_amp (streaming_track->replaygain_track_gain) * 1000;
- if (conf_replaygain_scale && replaygain_scale) {
- if (vol * streaming_track->replaygain_track_peak > 1000) {
- vol = 1000 / streaming_track->replaygain_track_peak;
- }
- }
- }
- else if (conf_replaygain_mode == 2) {
- if (it->replaygain_album_gain == 0) {
- return;
- }
- vol = db_to_amp (streaming_track->replaygain_album_gain) * 1000;
- if (conf_replaygain_scale && replaygain_scale) {
- if (vol * streaming_track->replaygain_album_peak > 1000) {
- vol = 1000 / streaming_track->replaygain_album_peak;
- }
- }
- }
- int16_t *s = (int16_t*)bytes;
- for (int j = 0; j < size/2; j++) {
- int32_t sample = ((int32_t)(*s)) * vol / 1000;
- if (sample > 0x7fff) {
- sample = 0x7fff;
- }
- else if (sample < -0x8000) {
- sample = -0x8000;
+ // reset dsp
+ ddb_dsp_context_t *dsp = dsp_chain;
+ while (dsp) {
+ if (dsp->plugin->reset) {
+ dsp->plugin->reset (dsp);
}
- *s = (int16_t)sample;
- s++;
+ dsp = dsp->next;
}
}
-static void
-apply_replay_gain_float32 (playItem_t *it, char *bytes, int size) {
- if (!replaygain || !conf_replaygain_mode) {
- return;
- }
- float vol = 1.f;
- if (conf_replaygain_mode == 1) {
- if (it->replaygain_track_gain == 0) {
- return;
- }
- vol = db_to_amp (it->replaygain_track_gain);
- if (conf_replaygain_scale && replaygain_scale) {
- if (vol * it->replaygain_track_peak > 1.f) {
- vol = 1.f / it->replaygain_track_peak;
- }
- }
- }
- else if (conf_replaygain_mode == 2) {
- if (it->replaygain_album_gain == 0) {
- return;
- }
- vol = db_to_amp (it->replaygain_album_gain);
- if (conf_replaygain_scale && replaygain_scale) {
- if (vol * it->replaygain_album_peak > 1.f) {
- vol = 1.f / it->replaygain_album_peak;
- }
- }
- }
- float *s = (float*)bytes;
- for (int j = 0; j < size/4; j++) {
- float sample = ((float)*s) * vol;
- if (sample > 1.f) {
- sample = 1.f;
- }
- else if (sample < -1.f) {
- sample = -1.f;
+static int
+streamer_set_output_format (void) {
+ DB_output_t *output = plug_get_output ();
+ int playing = (output->state () == OUTPUT_STATE_PLAYING);
+
+ fprintf (stderr, "streamer_set_output_format %dbit %s %dch %dHz channelmask=%X, bufferfill: %d\n", output_format.bps, output_format.is_float ? "float" : "int", output_format.channels, output_format.samplerate, output_format.channelmask, streamer_ringbuf.remaining);
+ output->setformat (&output_format);
+ streamer_buffering = 1;
+ if (playing && output->state () != OUTPUT_STATE_PLAYING) {
+ if (0 != output->play ()) {
+ memset (&output_format, 0, sizeof (output_format));
+ fprintf (stderr, "streamer: failed to start playback (streamer_read format change)\n");
+ streamer_set_nextsong (-2, 0);
+ return -1;
}
- *s = sample;
- s++;
}
}
-static void
-mono_int16_to_stereo_int16 (int16_t *in, int16_t *out, int nsamples) {
- while (nsamples > 0) {
- int16_t sample = *in++;
- *out++ = sample;
- *out++ = sample;
- nsamples--;
- }
-}
-
-#if 0
-static void
-int16_to_float32 (int16_t *in, float *out, int nsamples) {
- while (nsamples > 0) {
- *out++ = (*in++)/(float)0x7fff;
- nsamples--;
+// decodes data and converts to current output format
+// returns number of bytes been read
+static int
+streamer_read_async (char *bytes, int size) {
+ DB_output_t *output = plug_get_output ();
+ int initsize = size;
+ int bytesread = 0;
+ mutex_lock (decodemutex);
+ if (!fileinfo) {
+ // means there's nothing left to stream, so just do nothing
+ mutex_unlock (decodemutex);
+ return 0;
}
-}
+ int is_eof = 0;
-static void
-mono_int16_to_stereo_float32 (int16_t *in, float *out, int nsamples) {
- while (nsamples > 0) {
- float sample = (*in++)/(float)0x7fff;
- *out++ = sample;
- *out++ = sample;
- nsamples--;
- }
-}
+ if (fileinfo->fmt.samplerate != -1) {
+ int outputsamplesize = output->fmt.channels * output->fmt.bps / 8;
+ int inputsamplesize = fileinfo->fmt.channels * fileinfo->fmt.bps / 8;
-static void
-mono_float32_to_stereo_float32 (float *in, float *out, int nsamples) {
- while (nsamples > 0) {
- float sample = *in++;
- *out++ = sample;
- *out++ = sample;
- nsamples--;
- }
-}
-#endif
+ if (!memcmp (&fileinfo->fmt, &output->fmt, sizeof (ddb_waveformat_t)) && !dsp_on) {
+ // pass through from input to output
+ bytesread = fileinfo->plugin->read (fileinfo, bytes, size);
-static void
-float32_to_int16 (float *in, int16_t *out, int nsamples) {
- fpu_control ctl;
- fpu_setround (&ctl);
- while (nsamples > 0) {
- float sample = *in++;
- if (sample > 1) {
- sample = 1;
- }
- else if (sample < -1) {
- sample = -1;
+ if (bytesread != size) {
+ is_eof = 1;
+ }
}
- *out++ = (int16_t)ftoi (sample*0x7fff);
- nsamples--;
- }
- fpu_restore (ctl);
-}
+ else if (dsp_on) {
+ // convert to float, pass through streamer DSP chain
+ int dspsamplesize = fileinfo->fmt.channels * sizeof (float);
+ int dsp_num_frames = size / (output->fmt.channels * output->fmt.bps / 8);
-/*
+ char outbuf[dsp_num_frames * dspsamplesize];
- src algorithm
+ ddb_waveformat_t dspfmt;
+ memcpy (&dspfmt, &fileinfo->fmt, sizeof (ddb_waveformat_t));
+ dspfmt.bps = 32;
+ dspfmt.is_float = 1;
- initsize = size;
- while (size > 0) {
- need_frames = SRC_BUFFER - src_remaining
- read_samples (need_frames)
- src_process (output_frames)
- convert_to_int16 (bytes, size)
- // handle errors
- }
- return initsize-size;
-
-*/
-
-static int
-streamer_read_data_for_src (int16_t *buffer, int frames) {
- int channels = fileinfo->channels;
- if (channels > 2) {
- channels = 2;
- }
- int bytesread = fileinfo->plugin->read_int16 (fileinfo, (uint8_t*)buffer, frames * sizeof (int16_t) * channels);
- apply_replay_gain_int16 (streaming_track, (uint8_t*)buffer, bytesread);
- if (channels == 1) {
- // convert to stereo
- int n = frames-1;
- while (n >= 0) {
- buffer[n*2+0] = buffer[n];
- buffer[n*2+1] = buffer[n];
- n--;
- }
- }
- return bytesread / (sizeof (int16_t) * channels);
-}
+ int inputsize = dsp_num_frames * inputsamplesize;
+ char input[inputsize];
-static int
-streamer_read_data_for_src_float (float *buffer, int frames) {
- int channels = fileinfo->channels;
- if (channels > 2) {
- channels = 2;
- }
- if (fileinfo->plugin->read_float32) {
- int bytesread = fileinfo->plugin->read_float32 (fileinfo, (uint8_t*)buffer, frames * sizeof (float) * channels);
- apply_replay_gain_float32 (streaming_track, (uint8_t*)buffer, bytesread);
- if (channels == 1) {
- // convert to stereo
- int n = frames-1;
- while (n >= 0) {
- buffer[n*2+1] = buffer[n];
- buffer[n*2+0] = buffer[n];
- n--;
+ // decode pcm
+ int nb = fileinfo->plugin->read (fileinfo, input, inputsize);
+ if (nb != inputsize) {
+ is_eof = 1;
}
- }
- return bytesread / (sizeof (float) * channels);
- }
+ inputsize = nb;
+
+ if (inputsize > 0) {
+ // make *MAX_DSP_RATIO sized buffer for float data
+ char tempbuf[inputsize/inputsamplesize * dspsamplesize * MAX_DSP_RATIO];
+
+ // convert to float
+ int tempsize = pcm_convert (&fileinfo->fmt, input, &dspfmt, tempbuf, inputsize);
+ int nframes = inputsize / inputsamplesize;
+ ddb_dsp_context_t *dsp = dsp_chain;
+ float ratio = 1.f;
+ int maxframes = sizeof (tempbuf) / dspsamplesize;
+ while (dsp) {
+ if (dsp->enabled) {
+ float r = 1;
+ nframes = dsp->plugin->process (dsp, (float *)tempbuf, nframes, maxframes, &dspfmt, &r);
+ ratio *= r;
+ }
+ dsp = dsp->next;
+ }
+ dsp_ratio = ratio;
+
+ ddb_waveformat_t outfmt;
+ // preserve sampleformat, but take channels, samplerate
+ outfmt.bps = fileinfo->fmt.bps;
+ outfmt.is_float = fileinfo->fmt.is_float;
+ // channelmask from dsp chain
+ outfmt.channels = dspfmt.channels;
+ outfmt.samplerate = dspfmt.samplerate;
+ outfmt.channelmask = dspfmt.channelmask;
+ outfmt.is_bigendian = fileinfo->fmt.is_bigendian;
+ if (memcmp (&output_format, &outfmt, sizeof (ddb_waveformat_t)) && bytes_until_next_song <= 0) {
+ memcpy (&output_format, &outfmt, sizeof (ddb_waveformat_t));
+ streamer_set_output_format ();
+ }
-// trace ("read_float32 not impl\n");
- int16_t intbuffer[frames*2];
- int res = streamer_read_data_for_src (intbuffer, frames);
- for (int i = 0; i < res; i++) {
- buffer[i*2+0] = intbuffer[i*2+0]/(float)0x7fff;
- buffer[i*2+1] = intbuffer[i*2+1]/(float)0x7fff;
- }
- return res;
-}
+ //printf ("convert to %dbit %s %dch %dHz channelmask=%X\n", output->fmt.bps, output->fmt.is_float ? "float" : "int", output->fmt.channels, output->fmt.samplerate, output->fmt.channelmask);
+ int n = pcm_convert (&dspfmt, tempbuf, &output->fmt, bytes, nframes * dspsamplesize);
-static int
-streamer_decode_src_libsamplerate (uint8_t *bytes, int size) {
- int initsize = size;
- int16_t *out = (int16_t *)bytes;
- int samplerate = fileinfo->samplerate;
- if (!samplerate) {
- return 0;
- }
- float ratio = p_get_rate ()/(float)samplerate;
- while (size > 0) {
- int n_output_frames = size / sizeof (int16_t) / 2;
- int n_input_frames = n_output_frames * samplerate / p_get_rate () + 100;
- // read data from decoder
- if (n_input_frames >= SRC_BUFFER - src_remaining ) {
- n_input_frames = SRC_BUFFER - src_remaining;
- }
-
- int nread;
- if (!n_input_frames) {
- nread = 0;
+ bytesread = n;
+ }
}
else {
- nread = streamer_read_data_for_src_float (&g_src_in_fbuffer[src_remaining*2], n_input_frames);
+ // convert from input fmt to output fmt
+ int inputsize = size/outputsamplesize*inputsamplesize;
+ char input[inputsize];
+ int nb = fileinfo->plugin->read (fileinfo, input, inputsize);
+ if (nb != inputsize) {
+ bytesread = nb;
+ is_eof = 1;
+ }
+ inputsize = nb;
+ bytesread = pcm_convert (&fileinfo->fmt, input, &output->fmt, bytes, inputsize);
}
- src_remaining += nread;
- if (!src_remaining) {
- trace ("SRC input buffer empty\n");
- break;
+#if WRITE_DUMP
+ if (bytesread) {
+ fwrite (bytes, 1, bytesread, out);
}
- // resample
-
- srcdata.data_in = g_src_in_fbuffer;
- srcdata.data_out = g_src_out_fbuffer;
- srcdata.input_frames = src_remaining;
- srcdata.output_frames = size/4;
- srcdata.src_ratio = ratio;
-// trace ("SRC from %d to %d\n", samplerate, p_get_rate ());
- srcdata.end_of_input = 0;//(nread == n_input_frames) ? 0 : 1;
- //if (streamer_buffering)
- src_lock ();
- src_set_ratio (src, ratio);
- int src_err = src_process (src, &srcdata);
- src_unlock ();
- if (src_err) {
- const char *err = src_strerror (src_err) ;
- fprintf (stderr, "src_process error %s\n"
- "srcdata.data_in=%p, srcdata.data_out=%p, srcdata.input_frames=%d, srcdata.output_frames=%d, srcdata.src_ratio=%f", err, srcdata.data_in, srcdata.data_out, (int)srcdata.input_frames, (int)srcdata.output_frames, (float)srcdata.src_ratio);
- exit (-1);
- }
- // convert back to s16 format
- int genbytes = srcdata.output_frames_gen * 4;
- int bytesread = min(size, genbytes);
- float32_to_int16 ((float*)g_src_out_fbuffer, (int16_t*)bytes, bytesread>>1);
- size -= bytesread;
- bytes += bytesread;
- // calculate how many unused input samples left
- src_remaining -= srcdata.input_frames_used;
-
- // copy spare samples for next update
- if (src_remaining > 0) {
- memmove (g_src_in_fbuffer, &g_src_in_fbuffer[srcdata.input_frames_used*2], src_remaining * sizeof (float) * 2);
- }
-
-// if (nread != n_input_frames) {
-// trace ("nread=%d, n_input_frames=%d, mismatch!\n", nread, n_input_frames);
-// break;
-// }
- }
- return initsize-size;
-}
+#endif
-#if 0
-static int
-streamer_decode_src (uint8_t *bytes, int size) {
- int initsize = size;
- int16_t *out = (int16_t *)bytes;
- DB_decoder_t *decoder = streaming_track->decoder;
- int samplerate = decoder->info.samplerate;
- float ratio = (float)samplerate / p_get_rate ();
- while (size > 0) {
- int n_output_frames = size / sizeof (int16_t) / 2;
- int n_input_frames = n_output_frames * samplerate / p_get_rate () + 100;
- // read data from decoder
- if (n_input_frames > SRC_BUFFER - src_remaining ) {
- n_input_frames = SRC_BUFFER - src_remaining;
- }
- int nread = streamer_read_data_for_src (&g_src_in_buffer[src_remaining*2], n_input_frames);
- src_remaining += nread;
- // resample
- float idx = 0;
- int i = 0;
- while (i < n_output_frames && idx < src_remaining) {
- int k = (int)idx;
- out[0] = g_src_in_buffer[k*2+0];
- out[1] = g_src_in_buffer[k*2+1];
- i++;
- idx += ratio;
- out += 2;
- }
- size -= i*4;
- src_remaining -= idx;
- if (src_remaining < 0) {
- src_remaining = 0;
- }
- else if (src_remaining > 0) {
- memmove (g_src_in_buffer, &g_src_in_buffer[(SRC_BUFFER-src_remaining)*2], src_remaining*2*sizeof (int16_t));
- }
- if (nread != n_input_frames) {
- break;
- }
+ replaygain_apply (&output->fmt, streaming_track, bytes, bytesread);
}
- return initsize-size;
-}
-#endif
+ mutex_unlock (decodemutex);
+ if (!is_eof) {
+ return bytesread;
+ }
+ else {
+ // that means EOF
+ trace ("streamer: EOF! buns: %d, bytesread: %d, buffering: %d, bufferfill: %d\n", bytes_until_next_song, bytesread, streamer_buffering, streamer_ringbuf.remaining);
-// returns number of bytes been read
-static int
-streamer_read_async (char *bytes, int size) {
- int initsize = size;
- for (;;) {
- int bytesread = 0;
- mutex_lock (decodemutex);
- if (!fileinfo) {
- // means there's nothing left to stream, so just do nothing
- mutex_unlock (decodemutex);
- break;
- }
- if (fileinfo->samplerate != -1) {
- int nchannels = fileinfo->channels;
- if (nchannels > 2) {
- nchannels = 2;
- }
- int samplerate = fileinfo->samplerate;
- if (fileinfo->samplerate == p_get_rate ()) {
- // samplerate match
- if (nchannels == 2) {
- bytesread = fileinfo->plugin->read_int16 (fileinfo, bytes, size);
- apply_replay_gain_int16 (streaming_track, bytes, bytesread);
- }
- else {
- uint8_t buffer[size>>1];
- bytesread = fileinfo->plugin->read_int16 (fileinfo, buffer, size>>1);
- apply_replay_gain_int16 (streaming_track, buffer, bytesread);
- mono_int16_to_stereo_int16 ((int16_t*)buffer, (int16_t*)bytes, size>>2);
- bytesread *= 2;
- }
- }
- else if (src_is_valid_ratio (p_get_rate ()/(double)samplerate)) {
- bytesread = streamer_decode_src_libsamplerate (bytes, size);
- }
- else {
- fprintf (stderr, "error: invalid ratio! %d / %d (this indicates decoder or streamer bug)\n", p_get_rate (), samplerate);
- fprintf (stderr, "error: file: %s\n", streaming_track ? streaming_track->fname : "(null)");
- // immediately start streaming next track
- bytes_until_next_song = -1;
- }
- }
- trace ("streamer: bytesread=%d\n", bytesread);
- if (bytesread > 0) {
- // apply dsp
- DB_dsp_t **dsp = deadbeef->plug_get_dsp_list ();
- int srate = p_get_rate ();
- for (int i = 0; dsp[i]; i++) {
- if (dsp[i]->enabled ()) {
- dsp[i]->process_int16 ((int16_t *)bytes, bytesread/4, 2, 16, srate);
- }
- }
- }
- mutex_unlock (decodemutex);
- bytes += bytesread;
- size -= bytesread;
- trace ("streamer: size=%d\n", size);
- if (size == 0) {
- return initsize;
- }
- else {
- // that means EOF
- trace ("streamer: EOF! buns: %d\n", bytes_until_next_song);
-
- // in case of decoder error, or EOF while buffering - switch to next song instantly
- if (bytesread < 0 || (bytes_until_next_song < 0 && streamer_is_buffering() && bytesread == 0) || bytes_until_next_song < 0) {
- trace ("finished streaming song, queueing next\n");
- bytes_until_next_song = streambuffer_fill;
- if (conf_get_int ("playlist.stop_after_current", 0)) {
- streamer_set_nextsong (-2, 1);
- }
- else {
- streamer_move_to_nextsong (0);
- }
- }
- break;
+ // in case of decoder error, or EOF while buffering - switch to next song instantly
+ if (bytesread < 0 || (bytes_until_next_song >= 0 && streamer_buffering && bytesread == 0) || bytes_until_next_song < 0) {
+ trace ("finished streaming song, queueing next (%d %d %d %d)\n", bytesread, bytes_until_next_song, streamer_buffering, nextsong_pstate);
+ streamer_next (bytesread);
}
}
- return initsize - size;
+ return bytesread;
}
+
int
streamer_read (char *bytes, int size) {
#if 0
@@ -1612,17 +1662,17 @@ streamer_read (char *bytes, int size) {
if (!playing_track) {
return -1;
}
+ DB_output_t *output = plug_get_output ();
+ if (formatchanged && bytes_until_next_song <= 0) {
+ streamer_set_output_format ();
+ formatchanged = 0;
+ }
streamer_lock ();
- int sz = min (size, streambuffer_fill);
+ int sz = min (size, streamer_ringbuf.remaining);
if (sz) {
- memcpy (bytes, streambuffer, sz);
- memmove (streambuffer, streambuffer+sz, streambuffer_fill-sz);
- streambuffer_fill -= sz;
- playpos += (float)sz/p_get_rate ()/4.f;
- playing_track->playtime += (float)sz/p_get_rate ()/4.f;
- if (playlist_track) {
- playing_track->filetype = playlist_track->filetype;
- }
+ ringbuf_read (&streamer_ringbuf, bytes, sz);
+ playpos += (float)sz/output->fmt.samplerate/((output->fmt.bps>>3)*output->fmt.channels) * dsp_ratio;
+ playing_track->playtime += (float)sz/output->fmt.samplerate/((output->fmt.bps>>3)*output->fmt.channels);
if (playlist_track) {
playlist_track->playtime = playing_track->playtime;
}
@@ -1667,20 +1717,70 @@ streamer_read (char *bytes, int size) {
int ms = (tm2.tv_sec*1000+tm2.tv_usec/1000) - (tm1.tv_sec*1000+tm1.tv_usec/1000);
printf ("streamer_read took %d ms\n", ms);
#endif
-#if WRITE_DUMP
- fwrite (bytes, 1, sz, out);
-#endif
+
+ if (!output->has_volume) {
+ char *stream = bytes;
+ int bytesread = sz;
+ if (output->fmt.bps == 16) {
+ int16_t ivolume = volume_get_amp () * 1000;
+ for (int i = 0; i < bytesread/2; i++) {
+ int16_t sample = *((int16_t*)stream);
+ *((int16_t*)stream) = (int16_t)(((int32_t)sample) * ivolume / 1000);
+ stream += 2;
+ }
+ }
+ else if (output->fmt.bps == 8) {
+ int16_t ivolume = volume_get_amp () * 255;
+ for (int i = 0; i < bytesread; i++) {
+ *stream = (int8_t)(((int32_t)(*stream)) * ivolume / 1000);
+ stream++;
+ }
+ }
+ else if (output->fmt.bps == 24) {
+ int16_t ivolume = volume_get_amp () * 1000;
+ for (int i = 0; i < bytesread/3; i++) {
+ int32_t sample = ((unsigned char)stream[0]) | ((unsigned char)stream[1]<<8) | (stream[2]<<16);
+ int32_t newsample = (int64_t)sample * ivolume / 1000;
+ stream[0] = (newsample&0x0000ff);
+ stream[1] = (newsample&0x00ff00)>>8;
+ stream[2] = (newsample&0xff0000)>>16;
+ stream += 3;
+ }
+ }
+ else if (output->fmt.bps == 32 && !output->fmt.is_float) {
+ int16_t ivolume = volume_get_amp () * 1000;
+ for (int i = 0; i < bytesread/4; i++) {
+ int32_t sample = *((int32_t*)stream);
+ int32_t newsample = (int64_t)sample * ivolume / 1000;
+ *((int32_t*)stream) = newsample;
+ stream += 4;
+ }
+ }
+ else if (output->fmt.bps == 32 && output->fmt.is_float) {
+ float fvolume = volume_get_amp ();
+ for (int i = 0; i < bytesread/4; i++) {
+ *((float*)stream) = (*((float*)stream)) * fvolume;
+ stream += 4;
+ }
+ }
+ }
+
return sz;
}
int
streamer_get_fill (void) {
- return streambuffer_fill;
+ return streamer_ringbuf.remaining;
}
int
streamer_ok_to_read (int len) {
- if (len >= 0 && (bytes_until_next_song > 0 || streambuffer_fill >= (len*2))) {
+ DB_output_t *output = plug_get_output ();
+ if (formatchanged && bytes_until_next_song <= 0) {
+ streamer_set_output_format ();
+ formatchanged = 0;
+ }
+ if (len >= 0 && (bytes_until_next_song > 0 || streamer_ringbuf.remaining >= (len*2))) {
return 1;
}
else {
@@ -1689,46 +1789,27 @@ streamer_ok_to_read (int len) {
return 0;
}
-int
-streamer_is_buffering (void) {
- if (streambuffer_fill < 16384) {
- return 1;
- }
- else {
- return 0;
- }
-}
-
void
streamer_configchanged (void) {
- conf_replaygain_mode = conf_get_int ("replaygain_mode", 0);
- conf_replaygain_scale = conf_get_int ("replaygain_scale", 1);
- int q = conf_get_int ("src_quality", 2);
- if (q != src_quality && q >= SRC_SINC_BEST_QUALITY && q <= SRC_LINEAR) {
- src_lock ();
- trace ("changing src_quality from %d to %d\n", src_quality, q);
- src_quality = q;
- if (src) {
- src_delete (src);
- src = NULL;
- }
- memset (&srcdata, 0, sizeof (srcdata));
- src = src_new (src_quality, 2, NULL);
- src_unlock ();
+ replaygain_set (conf_get_int ("replaygain_mode", 0), conf_get_int ("replaygain_scale", 1), conf_get_float ("replaygain_preamp", 0));
+ pl_set_order (conf_get_int ("playback.order", 0));
+ if (playing_track) {
+ playing_track->played = 1;
}
}
void
streamer_play_current_track (void) {
playlist_t *plt = plt_get_curr_ptr ();
- if (p_ispaused () && playing_track) {
+ DB_output_t *output = plug_get_output ();
+ if (output->state () == OUTPUT_STATE_PAUSED && playing_track) {
// unpause currently paused track
- p_unpause ();
+ output->unpause ();
plug_trigger_event_paused (0);
}
else if (plt->current_row[PL_MAIN] != -1) {
// play currently selected track in current playlist
- p_stop ();
+ output->stop ();
// get next song in queue
int idx = -1;
playItem_t *next = pl_playqueue_getnext ();
@@ -1746,7 +1827,7 @@ streamer_play_current_track (void) {
}
else {
// restart currently playing track
- p_stop ();
+ output->stop ();
streamer_set_nextsong (0, 1);
}
}
@@ -1775,3 +1856,58 @@ streamer_notify_playlist_deleted (playlist_t *plt) {
streamer_playlist = NULL;
}
}
+
+ddb_dsp_context_t *
+streamer_get_dsp_chain (void) {
+ return dsp_chain;
+}
+
+static ddb_dsp_context_t *
+dsp_clone (ddb_dsp_context_t *from) {
+ ddb_dsp_context_t *dsp = from->plugin->open ();
+ char param[2000];
+ if (from->plugin->num_params) {
+ int n = from->plugin->num_params ();
+ for (int i = 0; i < n; i++) {
+ from->plugin->get_param (from, i, param, sizeof (param));
+ dsp->plugin->set_param (dsp, i, param);
+ }
+ }
+ dsp->enabled = from->enabled;
+ return dsp;
+}
+
+void
+streamer_set_dsp_chain (ddb_dsp_context_t *chain) {
+ mutex_lock (decodemutex);
+ streamer_dsp_chain_free (dsp_chain);
+
+ dsp_chain = NULL;
+ eq = NULL;
+
+ ddb_dsp_context_t *tail = NULL;
+ while (chain) {
+ ddb_dsp_context_t *new = dsp_clone (chain);
+ if (tail) {
+ tail->next = new;
+ tail = new;
+ }
+ else {
+ dsp_chain = tail = new;
+ }
+ chain = chain->next;
+ }
+
+ streamer_dsp_postinit ();
+
+ char fname[PATH_MAX];
+ snprintf (fname, sizeof (fname), "%s/dspconfig", plug_get_config_dir ());
+ streamer_dsp_chain_save (fname, dsp_chain);
+ streamer_reset (1);
+
+ mutex_unlock (decodemutex);
+ DB_output_t *output = plug_get_output ();
+ if (playing_track && output->state () != OUTPUT_STATE_STOPPED) {
+ deadbeef->streamer_seek (playpos);
+ }
+}
diff --git a/streamer.h b/streamer.h
index 3bcdbe49..77b14fe0 100644
--- a/streamer.h
+++ b/streamer.h
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -60,9 +60,6 @@ streamer_ok_to_read (int len);
float
streamer_get_playpos (void);
-int
-streamer_is_buffering (void);
-
void
streamer_song_removed_notify (playItem_t *it);
@@ -111,4 +108,13 @@ str_get_idx_of (playItem_t *it);
void
streamer_notify_playlist_deleted (playlist_t *plt);
+struct ddb_dsp_context_s *
+streamer_get_dsp_chain (void);
+
+void
+streamer_set_dsp_chain (struct ddb_dsp_context_s *chain);
+
+void
+streamer_dsp_refresh (void);
+
#endif // __STREAMER_H
diff --git a/threading.h b/threading.h
index dee1cc3c..d7ff5686 100644
--- a/threading.h
+++ b/threading.h
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -29,6 +29,12 @@ thread_start_low_priority (void (*fn)(void *ctx), void *ctx);
int
thread_join (intptr_t tid);
+int
+thread_detach (intptr_t tid);
+
+void
+thread_exit (void *retval);
+
uintptr_t
mutex_create (void);
diff --git a/threading_pthread.c b/threading_pthread.c
index 66db5844..d870ac36 100644
--- a/threading_pthread.c
+++ b/threading_pthread.c
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -21,6 +21,9 @@
#include <errno.h>
#include <string.h>
#include "threading.h"
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
intptr_t
thread_start (void (*fn)(void *ctx), void *ctx) {
@@ -40,7 +43,6 @@ thread_start (void (*fn)(void *ctx), void *ctx) {
s = pthread_attr_destroy (&attr);
if (s != 0) {
fprintf (stderr, "pthread_attr_destroy failed: %s\n", strerror (s));
-// pthread_cancel (tid); // missing on android
return 0;
}
return tid;
@@ -69,12 +71,14 @@ thread_start_low_priority (void (*fn)(void *ctx), void *ctx) {
fprintf (stderr, "pthread_create failed: %s\n", strerror (s));
return 0;
}
+#if !STATICLINK
s = pthread_setschedprio (tid, minprio);
if (s != 0) {
fprintf (stderr, "pthread_setschedprio failed: %s\n", strerror (s));
pthread_cancel (tid);
return 0;
}
+#endif
s = pthread_attr_destroy (&attr);
if (s != 0) {
@@ -99,6 +103,21 @@ thread_join (intptr_t tid) {
return 0;
}
+int
+thread_detach (intptr_t tid) {
+ int s = pthread_detach ((pthread_t)tid);
+ if (s) {
+ fprintf (stderr, "pthread_detach failed: %s\n", strerror (s));
+ return -1;
+ }
+ return 0;
+}
+
+void
+thread_exit (void *retval) {
+ pthread_exit (retval);
+}
+
uintptr_t
mutex_create_nonrecursive (void) {
pthread_mutex_t *mtx = malloc (sizeof (pthread_mutex_t));
diff --git a/tools/apbuild/Apbuild/GCC.pm b/tools/apbuild/Apbuild/GCC.pm
new file mode 100644
index 00000000..b4246148
--- /dev/null
+++ b/tools/apbuild/Apbuild/GCC.pm
@@ -0,0 +1,539 @@
+# Various gcc-related functions
+package Apbuild::GCC;
+
+use strict;
+use Apbuild::Utils;
+use IPC::Open3;
+
+
+######## Special constants; used for parsing GCC parameters ########
+
+# Parameters that require an extra parameter
+our $extraTypes = 'o|u|Xlinker|b|V|MF|MT|MQ|I|L|R|Wl,-rpath|isystem|D|x';
+# Linker parameters
+our $linkerTypes = 'L|Wl|o$|l|s|n|R';
+# Files with these extensions are objects
+our $staticLibTypes = 'a|al';
+our $objectTypes = "o|os|so(\\.\\d+)*|la|lo|$staticLibTypes";
+our $headerTypes = 'h|hpp';
+# Source file types
+our $cTypes = 'c|C';
+our $cxxTypes = 'cpp|cxx|cc|c\+\+';
+our $srcTypes = "$cTypes|$cxxTypes";
+
+
+######## Methods ########
+
+##
+# Apbuild::GCC->new(gcc_command)
+# gcc_command: The command for invoking GCC.
+#
+# Create a new Apbuild:GCC object.
+sub new {
+ my ($class, $gcc) = @_;
+ my %self;
+
+ $self{gcc} = $gcc;
+ $self{gcc_file} = checkCommand($gcc);
+ if (!defined $self{gcc_file}) {
+ error "$gcc: command not found\n";
+ exit 127;
+ }
+
+ # FIXME: should use gcc -print-search-paths.
+ $self{searchPaths} = ["/usr/lib", "/usr/local/lib"];
+ foreach (reverse(split(/:/, $ENV{LIBRARY_PATH}))) {
+ push @{$self{searchPaths}}, $_;
+ }
+
+ bless \%self, $class;
+ return \%self;
+}
+
+##
+# $gcc->capabilities()
+# Returns: a hash with capabilities for this compiler.
+#
+# Check GCC's capabilities. This function will return
+# a hash with the following keys:
+# libgcc : Is 1 if gcc supports the parameter -{shared,static}-libgcc.
+# as_needed: Is 1 if gcc's linker supports --as-needed.
+# abi2 : Is 1 if gcc supports -fabi-version=2.
+#
+# This function takes care of caching results.
+sub capabilities {
+ my ($self) = @_;
+ my (%capabilities, %cache);
+
+ my $gcc = $self->{gcc};
+ my $gcc_file = $self->{gcc_file};
+
+ # First, check the cache
+ my @stat = stat $gcc_file;
+ my $gcc_mtime = $stat[9];
+ my $home = homeDir();
+ if (-f "$home/.apbuild") {
+ parseDataFile("$home/.apbuild", \%cache);
+ if ($cache{version} != 2) {
+ # Cache file version incompatible; delete cache
+ %cache = ();
+
+ } else {
+ if ($cache{"mtime_$gcc_file"} != $gcc_mtime) {
+ # Cache out of date for this compiler; update cache
+ delete $cache{"libgcc_$gcc_file"};
+ delete $cache{"abi2_$gcc_file"};
+ delete $cache{"as_needed_$gcc_file"};
+ delete $cache{"hash_style_$gcc_file"};
+ delete $cache{"stack_protector_$gcc_file"};
+ delete $cache{"fortify_source_$gcc_file"};
+ }
+ }
+ }
+
+ my $lc_all = $ENV{LC_ALL};
+ $ENV{LC_ALL} = 'C';
+
+ if (exists $cache{"libgcc_$gcc_file"} && exists $cache{"abi2_$gcc_file"}) {
+ $capabilities{libgcc} = $cache{"libgcc_$gcc_file"};
+ $capabilities{abi2} = $cache{"abi2_$gcc_file"};
+
+ } else {
+ # Get output from 'gcc -v'
+ my ($r, $w, $e);
+
+ my $pid = open3($w, $r, $e, $gcc_file, '-v');
+ close $w if ($w);
+ close $e if ($e);
+ my @output = <$r>;
+ waitpid $pid, 0;
+
+ # Check whether gcc >= 3.0
+ my ($major, $minor) = $output[@output - 1] =~ /version ([0-9]+)\.([0-9]+)/;
+ if ($major >= 3) {
+ $capabilities{libgcc} = 1;
+ $cache{"libgcc_$gcc_file"} = 1;
+ } else {
+ $capabilities{libgcc} = 0;
+ $cache{"libgcc_$gcc_file"} = 0;
+ }
+
+ if ($major > 3 || ($major >= 3 && $minor >= 4)) {
+ $capabilities{abi2} = 1;
+ $cache{"abi2_$gcc_file"} = 1;
+ } else {
+ $capabilities{abi2} = 0;
+ $cache{"abi2_$gcc_file"} = 0;
+ }
+
+ $cache{"mtime_$gcc_file"} = $gcc_mtime;
+ }
+
+ if (exists $cache{"as_needed_$gcc_file"}) {
+ $capabilities{as_needed} = $cache{"as_needed_$gcc_file"};
+
+ } else {
+ my ($r, $w, $e);
+
+ my $pid = open3($w, $r, $e, $gcc_file, '-Wl,--help');
+ close $w if ($w);
+ close $e if ($e);
+ local($/);
+ my $output = <$r>;
+ waitpid $pid, 0;
+
+ if ($output =~ /--as-needed/) {
+ $capabilities{as_needed} = 1;
+ $cache{"as_needed_$gcc_file"} = 1;
+ } else {
+ $capabilities{as_needed} = 0;
+ $cache{"as_needed_$gcc_file"} = 0;
+ }
+ }
+
+ if (exists $cache{"hash_style_$gcc_file"}) {
+ $capabilities{hash_style} = $cache{"hash_style_$gcc_file"};
+ } else {
+ my ($r, $w, $e);
+
+ my $pid = open3($w, $r, $e, $gcc_file, '-Wl,--help');
+ close $w if ($w);
+ close $e if ($e);
+ local($/);
+ my $output = <$r>;
+ waitpid $pid, 0;
+
+ if ($output =~ /--hash-style/) {
+ $capabilities{hash_style} = 1;
+ $cache{"hash_style_$gcc_file"} = 1;
+ } else {
+ $capabilities{hash_style} = 0;
+ $cache{"hash_style_$gcc_file"} = 0;
+ }
+ }
+
+ if (exists $cache{"stack_protector_$gcc_file"}) {
+ $capabilities{stack_protector} = $cache{"stack_protector_$gcc_file"};
+ } else {
+ # Get output from 'gcc -v'
+ my ($r, $w, $e);
+
+ my $pid = open3($w, $r, $e, $gcc_file, '-v');
+ close $w if ($w);
+ close $e if ($e);
+ my @output = <$r>;
+ waitpid $pid, 0;
+
+ # Check whether gcc >= 3.0
+ my ($major, $minor) = $output[@output - 1] =~ /version ([0-9]+)\.([0-9]+)/;
+ if ($major >= 4 && $minor >= 1) {
+ $capabilities{stack_protector} = 1;
+ $cache{"stack_protector_$gcc_file"} = 1;
+ } else {
+ $capabilities{stack_protector} = 0;
+ $cache{"stack_protector_$gcc_file"} = 0;
+ }
+ }
+
+ if (exists $cache{"fortify_source_$gcc_file"}) {
+ $capabilities{fortify_source} = $cache{"fortify_source_$gcc_file"};
+ } else {
+ # Get output from 'gcc -v'
+ my ($r, $w, $e);
+
+ my $pid = open3($w, $r, $e, $gcc_file, '-v');
+ close $w if ($w);
+ close $e if ($e);
+ my @output = <$r>;
+ waitpid $pid, 0;
+
+ # Check whether gcc >= 4.1
+ my ($major, $minor) = $output[@output - 1] =~ /version ([0-9]+)\.([0-9]+)/;
+ if ($major >= 4 && $minor >= 1) {
+ $capabilities{fortify_source} = 1;
+ $cache{"fortify_source_$gcc_file"} = 1;
+ } else {
+ $capabilities{fortify_source} = 0;
+ $cache{"fortify_source_$gcc_file"} = 0;
+ }
+ }
+
+ if (defined $lc_all) {
+ $ENV{LC_ALL} = $lc_all;
+ } else {
+ delete $ENV{LC_ALL};
+ }
+
+ $cache{version} = 2;
+ writeDataFile("$home/.apbuild", \%cache);
+ return %capabilities;
+}
+
+
+##
+# $gcc->command()
+#
+# Returns the GCC command associated with this Apbuild::GCC object.
+sub command {
+ my ($self) = @_;
+ return $self->{gcc};
+}
+
+
+##
+# $gcc->foreach(args, callback)
+# args: a reference to an array which contains GCC parameters.
+# callback: the callback function which will be called in every iteration of the loop.
+#
+# Iterate through each GCC parameter. $callback will be called as follows:
+# $callback->(type, args...);
+# $type is the current parameter's type, either "param" or "file" (source file).
+# args is an array of parameters. If this parameter is a parameter which excepts
+# another parameter (such as -o, it expects a filename), then the expected
+# parameter will also be passed to the callback function.
+sub foreach {
+ my ($self, $args, $callback) = @_;
+ for (my $i = 0; $i < @{$args}; $i++) {
+ $_ = $args->[$i];
+ if (/^-/ || /\.($objectTypes|$headerTypes)$/ || /.*\.so\.?$/) {
+ # Parameter
+ if (/^-($extraTypes)$/) {
+ # This parameter expects another parameter
+ $callback->("param", $_, $args->[$i + 1]);
+ $i++;
+ } else {
+ $callback->("param", $_);
+ }
+
+ } else {
+ # File
+ $callback->("file", $_);
+ }
+ }
+}
+
+##
+# $gcc->splitParams(args, files, params)
+# args: a reference to an array which contains GCC parameters.
+# files: a reference to an array, or undef.
+# params: a reference to an array, or undef.
+#
+# Parse GCC's parameters. Seperate files and arguments.
+# A list of files will be stored in the array referenced to by $file,
+# a list of non-file parameters will be stored in the array referenced to by $params.
+sub splitParams {
+ my ($self, $args, $files, $params) = @_;
+
+ my $callback = sub {
+ my $type = shift;
+ if ($type eq "param") {
+ push @{$params}, @_ if ($params);
+ } elsif ($type eq "file") {
+ push @{$files}, $_[0] if ($files);
+ }
+ };
+ $self->foreach($args, $callback);
+}
+
+
+sub stripLinkerParams {
+ my ($self, $r_params, $linking) = @_;
+ my @params;
+ my $i = 0;
+
+ my $callback = sub {
+ my $type = shift;
+ if ($type eq 'param' && $_[0] =~ /^-($linkerTypes)/) {
+ push @{$linking}, @_;
+ } else {
+ push @params, @_;
+ }
+ };
+ $self->foreach($r_params, $callback);
+ @{$r_params} = @params;
+}
+
+
+sub addSearchPaths {
+ my ($self, $dir) = @_;
+ push @{$self->{searchPaths}}, $dir;
+}
+
+# Parse $args and extract library search paths from it.
+# Those paths, along with paths added by addSearchPaths(),
+# will be appended to $paths.
+sub getSearchPaths {
+ my ($self, $args, $paths) = @_;
+
+ my $callback = sub {
+ my $type = shift;
+ return if ($type ne "param");
+
+ if ($_[0] eq "-L") {
+ push @{$paths}, $_[1];
+
+ } elsif ($_[0] =~ /^-L(.+)/ || $_[0] =~ /^--library-path=(.+)/) {
+ push @{$paths}, $1;
+ }
+ };
+ $self->foreach($args, $callback);
+
+ push @{$paths}, @{$self->{searchPaths}};
+}
+
+
+##
+# $gcc->isLibrary(arg, libname)
+#
+# Check whether $arg is a (dynamic) library argument.
+# The base library name will be stored in $$libname.
+sub isLibrary {
+ my ($self, $arg, $libname) = @_;
+ if ($arg =~ /^-l(.+)/ || $arg =~ /^--library=(.+)/ || $arg =~ /^(?:.*\/)?lib([^\/]+)\.so/) {
+ $$libname = $1 if ($libname);
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+##
+# $gcc->isObject(arg)
+#
+# Check whether $arg is an object. This includes static libraries.
+sub isObject {
+ my ($self, $arg) = @_;
+ return $arg !~ /^-/ && $arg =~ /\.($objectTypes)$/;
+}
+
+sub isStaticLib {
+ my ($self, $arg) = @_;
+ return $arg !~ /^-/ && $arg =~ /\.($staticLibTypes)$/;
+}
+
+##
+# $gcc->isSource(file)
+#
+# Checks whether $file is a source file.
+sub isSource {
+ my ($self, $file) = @_;
+ return $file =~ /\.($srcTypes)$/;
+}
+
+##
+# $gcc->isCxxSource(file)
+#
+# Checks whether $file is a C++ source file.
+sub isCxxSource {
+ my ($self, $file) = @_;
+ return $file =~ /\.($cxxTypes)$/;
+}
+
+
+# I wish I know how to explain what these functions do, but I can't. :(
+# If you know a better way to name these, please do tell me.
+sub sourceOrderIsImportant {
+ my ($self, $arg) = @_;
+ return $arg =~ /^-(x)$/;
+}
+
+sub linkOrderIsImportant {
+ my ($self, $arg) = @_;
+ return $arg =~ /^-(Wl,--whole-archive|Wl,--no-whole-archive)$/;
+}
+
+##
+# $gcc->getOutputFile(args)
+# args: a reference to an array which contains GCC parameters.
+# Returns: a filename.
+#
+# Parse the GCC arguments and detect the output filename.
+sub getOutputFile {
+ my ($gcc, $args) = @_;
+ my ($output, $compilingToObject, $source);
+
+ my $callback = sub {
+ my $type = shift;
+ if ($type eq 'param' && $_[0] eq '-o') {
+ $output = $_[1];
+
+ } elsif ($type eq 'param' && $_[0] eq '-c') {
+ $compilingToObject = 1;
+
+ } elsif ($type eq 'file' && $gcc->isSource($_[0])) {
+ $source = $_[0];
+ }
+ };
+ $gcc->foreach($args, $callback);
+
+ if (defined $output) {
+ return $output;
+ } elsif ($compilingToObject) {
+ $source =~ s/\.[^.]*?$/.o/;
+ return $source;
+ } else {
+ return "a.out";
+ }
+}
+
+##
+# $gcc->setOutputFile(args, new_output_file)
+# args: a reference to an array which contains GCC parameters.
+# new_output_file: the new output filename.
+#
+# Parse the GCC arguments and change the output filename.
+# The array referenced by $args will be modified.
+sub setOutputFile {
+ my ($gcc, $args, $new_output_file) = @_;
+ my (@newArgs, $changed);
+
+ my $callback = sub {
+ my $type = shift;
+
+ if ($type eq 'param' && $_[0] eq '-o') {
+ push @newArgs, "-o", $new_output_file;
+ $changed = 1;
+
+ } else {
+ push @newArgs, @_;
+ }
+ };
+ $gcc->foreach($args, $callback);
+
+ if (!$changed) {
+ push @newArgs, "-o", $new_output_file if (!$changed);
+ }
+ @{$args} = @newArgs;
+}
+
+
+##
+# $gcc->situation(args)
+# args: a reference to an array which contains GCC arguments.
+# Returns: 'compile', 'depcheck', 'compile and link', 'linking' or 'other'.
+#
+# Detect the situation in which the compiler is used.
+# Basically, there are 5 situations in which the compiler is used:
+# 1) Compilation (to an object file).
+# 2) Linking.
+# 3) Compilation and linking.
+# 4) Dependancy checking with -M* or -E.
+# 5) None of the above. Compiler is invoked with --help or something.
+# Note that source files may also contain non-C/C++ files.
+sub situation {
+ my ($self, $args) = @_;
+
+ my $files = 0;
+ for (@{$args}) {
+ $files++ if (!(/^-/));
+ }
+
+ for (@{$args}) {
+ if (/^-c$/) {
+ # Situation 1
+ return 'compile';
+ } elsif (/^-M(|M|G)$/ || /^-E$/) {
+ # Situation 4
+ return 'depcheck';
+ }
+ }
+
+ if ($files == 1)
+ {
+ my $i = 0;
+ for (@{$args})
+ {
+ if (!(/^-/) && (/\.($headerTypes)$/))
+ {
+ print($args->[$i], "\n");
+ return 'precompiled header';
+ }
+ $i++;
+ }
+ }
+
+ my $i = 0;
+ for (@{$args}) {
+ if (!(/^-/) && !(/\.($objectTypes)$/)) {
+ if ($i > 0 && $args->[$i - 1] =~ /^-($extraTypes)$/) {
+ $i++;
+ next;
+ } else {
+ # Situation 3
+ return 'compile and link';
+ }
+ }
+ $i++;
+ }
+
+ if ($files == 0) {
+ # Situation 5
+ return 'other';
+ } else {
+ # Situation 2
+ return 'linking';
+ }
+}
+
+
+1;
diff --git a/tools/apbuild/Apbuild/Utils.pm b/tools/apbuild/Apbuild/Utils.pm
new file mode 100644
index 00000000..a5089299
--- /dev/null
+++ b/tools/apbuild/Apbuild/Utils.pm
@@ -0,0 +1,195 @@
+package Apbuild::Utils;
+
+use strict;
+use warnings;
+use Exporter;
+use base qw(Exporter);
+use IO::Handle;
+use IPC::Open2;
+use POSIX;
+use Cwd qw(abs_path);
+
+
+our @EXPORT = qw(debug error checkCommand empty homeDir searchLib searchStaticLib soname run parseDataFile writeDataFile);
+our $debugOpened = 0;
+
+
+##
+# debug(message)
+#
+# If the environment variable $APBUILD_DEBUG is set to 1,
+# then print a debugging message to /dev/tty (not stdout or stderr).
+sub debug {
+ return if (empty($ENV{APBUILD_DEBUG}) || !$ENV{APBUILD_DEBUG});
+
+ if (!$debugOpened) {
+ if (open DEBUG, '>/dev/tty') {
+ $debugOpened = 1;
+ } else {
+ return;
+ }
+ }
+
+ my @args = split /\n/, "@_";
+ foreach (@args) {
+ $_ = '# ' . $_;
+ $_ .= "\n";
+ }
+
+ print DEBUG "\033[1;33m";
+ print DEBUG join '', @args;
+ print DEBUG "\033[0m";
+ DEBUG->flush;
+}
+
+
+##
+# error(message)
+#
+# Print an error message to stderr. It will be displayed in red.
+sub error {
+ print STDERR "\033[1;31m";
+ print STDERR $_[0];
+ print STDERR "\033[0m";
+ STDERR->flush;
+}
+
+
+##
+# checkCommand(file)
+# file: an command's filename.
+# Returns: the full path to $file, or undef if $file is not a valid command.
+#
+# Checks whether $file is an executable which is in $PATH or the working directory.
+#
+# Example:
+# checkCommand('gcc'); # Returns "/usr/bin/gcc"
+sub checkCommand {
+ my ($file, $file2) = split / /, $_[0];
+ $file = $file2 if ($file =~ /ccache/);
+
+ return abs_path($file) if (-x $file);
+ foreach my $dir (split /:+/, $ENV{PATH}) {
+ if (-x "$dir/$file") {
+ return "$dir/$file";
+ }
+ }
+ return undef;
+}
+
+##
+# empty(str)
+#
+# Checks whether $str is undefined or empty.
+sub empty {
+ return !defined($_[0]) || $_[0] eq '';
+}
+
+##
+# homeDir()
+#
+# Returns the user's home folder.
+sub homeDir {
+ if (!$ENV{HOME}) {
+ my $user = getpwuid(POSIX::getuid());
+ $ENV{HOME} = (getpwnam($user))[7];
+ }
+ return $ENV{HOME};
+}
+
+##
+# searchLib(basename, [extra_paths])
+# basename: the base name of the library.
+# extra_paths: a reference to an array, which contains extra folders in which to look for the library.
+# Returns: the absolute path to the library, or undef if not found.
+#
+# Get the absolute path of a (static or shared) library.
+#
+# Example:
+# searchLib("libfoo.so.1"); # Returns "/usr/lib/libfoo.so.1"
+sub searchLib {
+ my ($basename, $extra_paths) = @_;
+
+ if ($extra_paths) {
+ foreach my $path (reverse(@{$extra_paths})) {
+ return "$path/$basename" if (-f "$path/$basename");
+ }
+ }
+ foreach my $path ('/usr/local/lib', '/lib', '/usr/lib') {
+ return "$path/$basename" if (-f "$path/$basename");
+ }
+ return undef;
+}
+
+##
+# soname(lib)
+# lib: a filename to a shared library.
+# Returns: the soname.
+#
+# Get the soname of the specified shared library by reading
+# the SONAME section of the shared library file.
+sub soname {
+ my ($lib) = @_;
+ my ($r, $w);
+
+ if (open2($r, $w, 'objdump', '-p', $lib)) {
+ close $w;
+ my @lines = <$r>;
+ close $r;
+
+ my ($soname) = grep {/SONAME/} @lines;
+ $soname =~ s/.*?SONAME[ \t]+//;
+ $soname =~ s/\n//gs;
+ return $soname;
+
+ } else {
+ my ($soname) = $lib =~ /.*\/lib(.+)\.so/;
+ return $soname;
+ }
+}
+
+##
+# run(args...)
+# Returns: the command's exit code.
+#
+# Run a command with system().
+sub run {
+ # split the first item in @_ into "words". The `printf ...`
+ # takes care of respecting ' and " quotes so we don't split a
+ # quoted string that contains whitespace. If $cmd itself
+ # contains \n, this will still go wrong.
+ my $cmd = shift @_;
+ my @words = `printf '%s\n' $cmd`;
+ chomp @words;
+ my $status = system(@words, @_);
+ return 127 if ($status == -1);
+ return $status / 256 if ($status != 0);
+ return 0;
+}
+
+sub parseDataFile {
+ my ($file, $r_hash) = @_;
+
+ %{$r_hash} = ();
+ return if (!open FILE, "< $file");
+ foreach (<FILE>) {
+ next if (/^#/);
+ s/[\r\n]//g;
+ next if (length($_) == 0);
+
+ my ($key, $value) = split / /, $_, 2;
+ $r_hash->{$key} = $value;
+ }
+ close FILE;
+}
+
+sub writeDataFile {
+ my ($file, $r_hash) = @_;
+ return if (!open FILE, "> $file");
+ foreach my $key (sort(keys %{$r_hash})) {
+ print FILE "$key $r_hash->{$key}\n";
+ }
+ close FILE;
+}
+
+1;
diff --git a/tools/apbuild/BINARY-PORTABILITY-NOTES b/tools/apbuild/BINARY-PORTABILITY-NOTES
new file mode 100644
index 00000000..9a34566a
--- /dev/null
+++ b/tools/apbuild/BINARY-PORTABILITY-NOTES
@@ -0,0 +1,36 @@
+1) C++ ABI
+The C++ ABI generated by GCC version 2.95, 2.96, 3.0, and 3.1.1 are
+incompatible with each other. This means that, for examples, apps compiled
+with GCC 2.95 cannot link to libraries compiled with GCC 3.2.
+
+GCC 3.4 is the latest ABI at the moment (April 2005). But the most widely
+used ABI at the moment is the GCC 3.2 ABI.
+
+2) Symbol collisions, be aware of what libraries are implicitly linked in.
+Imagine the following situation:
+- foo contains the symbol foobar (a function).
+- libbar contains a symbol with the same name, but is a totally different
+ function.
+- foo is linked to libbar.
+When foo tries to call foobar(), it's undefined whether it will call the
+foobar() from it's own binary, or the one from libbar. Depending on what
+those functions do, foo may crash or do something it isn't supposed to do.
+
+Solution: rtld features, -Bgroup. However, at this moment these are not
+supported by glibc. Until they are, keep these in mind:
+- You should mark all functions that you do not want to export (or show up
+ in the symbol table) as static.
+- If you're a library, you should namespace all functions.
+- Internal functions that are used within a library, but across multiple
+ .c files, should be prefixed by a _ or __.
+
+3) Linking against shared versions of X11 extension libs
+Some X libraries, such as libXrender, are originally not shared libraries.
+Distributions just created shared library versions to save memory. So
+some distributions don't ship the shared versions at all. Apbuild
+automatically statically links some of those X libraries (you can turn
+this behavior off of course).
+
+4) Usage of sys_errlist
+
+5) Don't use TLS (the __thread keyword).
diff --git a/tools/apbuild/ChangeLog b/tools/apbuild/ChangeLog
new file mode 100644
index 00000000..fe1587ce
--- /dev/null
+++ b/tools/apbuild/ChangeLog
@@ -0,0 +1,375 @@
+2009-03-13 Jan Niklas Hasse <jhasse@gmail.com>
+
+ * apgcc: Use warn instead of print to display warnings. Thanks to Scott
+ Pakin for the patch.
+
+-------------------- 2.0.8 was released --------------------
+
+2009-03-11 Jan Niklas Hasse <jhasse@gmail.com>
+
+ * Apbuild/GCC.pm: Applied patch by Mike Lundy which fixes compiling of
+ libpng where apgcc detected a symbol list as precompiled header rather than
+ a depcheck. Fixes #118.
+ * apsymbols.h: New symbol list created on a GLIBC_2.9 machine by Mike
+ Lundy. Thanks! Fixes #117.
+
+2009-03-11 Jan Niklas Hasse <jhasse@gmail.com>
+
+ * apgcc: Applied patch by Scott Pakin which shows a warning message when
+ a library in APBUILD_STATIC isn't found.
+ * Apbuild/GCC.pm: getSearchPaths: Correctly add the content of the list not
+ a reference. Also a patch by Scott Pakin, thanks!
+
+2009-03-10 Jan Niklas Hasse <jhasse@gmail.com>
+
+ * apgcc: Applied patch by Scott Pakin which fixes statically compiling
+ of libuuid.
+
+-------------------- 2.0.7 was released --------------------
+
+2008-11-10 Jan Niklas Hasse <jhasse@gmail.com>
+
+ * Apbuild/GCC.pm: Check if FORTIFY_SOURCE is available. I'm not sure if
+ this really was introduced in gcc 4.1, but it should fix the the linker
+ errors in Ubuntu 8.10 and other new distros using this feature.
+ * apgcc: Add -U_FORTIFY_SOURCE to deactivate FORTIFY_SOURCE=2.
+
+2008-09-11 Jan Niklas Hasse <jhasse@gmail.com>
+
+ * buildlist: Bump minimum GLibc version to 2.3 (from 2.2)
+ * apsymbols.h: update list to work with the new 2.3 glibc min version
+ (Patch from Taj, me and Isak, should fix #20)
+ * apgcc: Check if APBUILD_STATIC_X is definied to prevent warnings.
+
+2008-08-03 Jan Niklas Hasse <jhasse@gmail.com>
+
+ * relaytool: Check if /dev/tty exists. Fixes #63
+
+2008-08-03 Jan Niklas Hasse <jhasse@gmail.com>
+
+ * apgcc: Don't statically link X11 libs by default. Fixes #61
+
+-------------------- 2.0.6 was released --------------------
+
+Sun Dec 30 19:17:03 UTC 2007 Taj Morton <tajmorton@gmail.com>
+ * relaytool: Apply patch from res in ticket #52. Now, if a lib cannot be relaytooled
+ for some reason, a stub that ensures libwhatever_is_present is defined will be
+ generated.
+
+Sun Sep 30 00:29:13 UTC 2007 Taj Morton <tajmorton@gmail.com>
+ * relaytool: When multi-linking, use the first SONAME passed to --multilink
+ as the name to use for the _is_present variable and _symbol_is_present function.
+ Fixes #37.
+
+Sat Sep 22 02:39:11 UTC 2007 Taj Morton <tajmorton@gmail.com>
+ * relaytool: Add --out-dir feature by user 'res' in ticket #50.
+
+2007-09-22 Isak Savo <isak.savo@gmail.com>
+
+ * relaytool (arch_ptr_size): Use 'uname -m' instead of 'arch' to get
+ machine name. Patch from user 'res' in ticket #51 (ticket fixed by
+ this commit)
+
+Tue Aug 14 17:04:32 UTC 2007 Taj Morton <tajmorton@gmail.com>
+ * apgcc: Apply patch from Unfleshed One for precompiled header support. Fixes #32.
+ * Apbuild/GCC.pm: Apply patch from Unfleshed One from precompiled header and
+ SCons/Qt4 integration. Fixes #32.
+
+Tue Aug 14 16:51:30 UTC 2007 Taj Morton <tajmorton@gmail.com>
+ * relaytool: When running on unsupported arch, give correct
+ defines for lib_is_present and symbol_is_present.
+
+Mon Jul 9 23:22:21 UTC 2007 Curtis L. Knight <knighcl@gmail.com>
+ * apgcc: Update for 2.0.6 release.
+ * Makefile: Update for 2.0.6 release.
+
+-------------------- 2.0.5 was released --------------------
+
+Mon Jun 4 02:03:06 UTC 2007 Taj Morton <tajmorton@gmail.com>
+ * apgcc: Append statically linked file's deps before adjusting
+ link line so that you can statically link the deps of the
+ libs you're statically linking (if that made any sense).
+
+Sat May 26 15:28:14 UTC 2007 Taj Morton <tajmorton@gmail.com>
+ * make-icons: Put icons into a directory called icons relative to
+ where make-icons was run from. Ask user for type so that icons get
+ put in correct subdirectory.
+
+Fri May 25 03:02:28 UTC 2007 Curtis L. Knight <knighcl@gmail.com>
+ * apgcc: Update for 2.0.5 release.
+ * Makefile: Update for 2.0.5 release.
+
+Wed May 23 00:45:48 UTC 2007 Taj Morton <tajmorton@gmail.com>
+ * apgcc: When statically linking, find the lib's DT_NEEDED entries
+ and link against them so we don't get linking errors.
+
+Thu May 17 20:38:11 UTC 2007 Taj Morton <tajmorton@gmail.com>
+ * relaytool: Use /bin/bash instead of /bin/sh so we can work on
+ Ubuntu (where sh -> dash). Thanks ACSpike. Add multilink support
+ to relaytool (TODO: document it better).
+
+-------------------- 2.0.4 was released --------------------
+
+Sun Apr 8 11:22:23 UTC 2007 Curtis L. Knight <knighcl@gmail.com>
+ * apgcc: Update for 2.0.4 release.
+ * Makefile: Update for 2.0.4 release.
+
+Sat Mar 31 21:09:45 UTC 2007 Taj Morton <tajmorton@gmail.com>
+ * Apbuild/GCC.pm: Check if gcc supports -fstack-protector,
+ so it can be disabled.
+ * apgcc: If gcc supports -fstack-protector, disable it (it adds a
+ silent dependency on GLIBC 2.4).
+ * apsymbols.h: Rebuilt with GLIBC 2.4. Thanks to Chris Guirl for
+ rebuilding.
+
+Thu Mar 29 05:08:40 UTC 2007 Taj Morton <tajmorton@gmail.com>
+ * apgcc: Respect the $APBUILD_NO_STATIC_X variable (as
+ documented on website). This doesn't mean it's a good idea
+ to use this features.
+
+-------------------- 2.0.3 was released --------------------
+
+Sun Dec 17 01:05:08 UTC 2006 Curtis L. Knight <knighcl@fastmail.fm>
+ * apgcc: Update for 2.0.3 release.
+ * Makefile: Update for 2.0.3 release.
+
+Sat Nov 25 23:20:07 UTC 2006 Taj Morton <tajmorton@gmail.com>
+ * Apbuild/GCC.pm: Detect if ld supports --hash-style so that we
+ can force both .gnu.hash and .hash to be generated on FC6.
+ * apgcc: If linker supports --hash-style, generate both .gnu.hash
+ and .hash sections so that binary works with linkers with support for
+ either type. By default, FC6 only generates .gnu.hash which makes its
+ binaries only work on systems with .gnu.hash. See:
+ http://fcp.surfsite.org/modules/newbb/viewtopic.php?topic_id=29929&forum=10&post_id=128939
+
+-------------------- 2.0.2 was released --------------------
+
+Thu Nov 2 22:53:33 UTC 2006 Taj Morton <tajmorton@gmail.com>
+ * apgcc: Allow people to replace -I flags passed to apgcc with ones from
+ $APBUILD_INCLUDE. For example /opt/kde/include=/home/taj/kde-includes/3.3
+ replaces -I/opt/kde/include with -I/home/taj/kde-includes/3.3. This is only
+ useful for apps where include path order is important (amarok 1.4.3, see
+ comments for details).
+
+-------------------- 2.0.1 was released --------------------
+
+Fri Oct 13 14:54:54 UTC 2006 Taj Morton <tajmorton@gmail.com>
+ * apgcc: Revert commit that "Just use[d] the multiple-file code for link and compile
+ in 1 command." This broke compiling main/libexec. Post 1.2 this code will get
+ better, I promise. :)
+
+Thu Oct 12 04:36:56 UTC 2006 Taj Morton <tajmorton@gmail.com>
+ * apgcc: [translateLibNames()]: Always find libstdc++ if compiling C++, force
+ use of the compilers libstdc++, instead of what libtool provides (which
+ is probably wrong when using your non-system g++).
+
+Mon Oct 9 00:57:48 UTC 2006 Taj Morton <tajmorton@gmail.com>
+ * apgcc: Remove special case with compiling and linking in 1 command with
+ 1 file. This code never called linkObjects() and so X libs were never
+ statically linked in. Just use the multiple-file code for link and compile in 1
+ command.
+ [forceStatic()]: Link Xfixes if Xcursor is linked because sometimes Xcursor
+ depends on Xfixes (on Slack 11, xorg 6.9.0, at least).
+
+Sun Sep 24 22:38:50 UTC 2006 Taj Morton <tajmorton@gmail.com>
+ * apgcc: [rearrangeForAsNeeded()]: Put -lXRender at the end of the
+ link command. See
+ http://lists.sunsite.dk/cgi-bin/ezmlm-cgi?21:mss:5187:200609:lkfnloheeaingojmnemi
+ for details.
+
+2006-09-13 Isak Savo <isak.savo@gmail.com>
+
+ * Makefile (PREFIX): Replaced bash specific '[[' testing with 'test' to work better with Ubuntu Edgy's 'dash' shell
+
+Thu Sep 7 19:10:53 UTC 2006 Taj Morton <tajmorton@gmail.com>
+ * apgcc: When compiling and linking in 1 command make sure
+ bogus deps are stripped. Note: I did not update the
+ double-compilation part of the code to have the fix because
+ it's dead code.
+
+Tue May 30 01:04:05 2006 Mike Hearn <mike@plan99.net>
+
+ * relaytool: Add x64 support based on patch by Psyche.
+ Fix a couple of minor bugs and make the code flow better.
+
+Thu Apr 13 23:56:32 2006 Mike Hearn <mike@plan99.net>
+
+ * apgcc (translateLibNames): Only drop libstdc++.so from the
+ arguments list when double compiling. This fixes the case
+ when libtool passes -nostdlib and then gives us a libstdc++
+ directly. However it's kind of a hack and will need to be
+ changed to work properly with double compiling.
+
+2006-03-04 Hongli Lai <hongli@plan99.net>
+
+ * apgcc: Apply patch by Francesco Montorsi.
+ This adds a new option APBUILD_RESOLVE_LIBPATH, which is a
+ space-seperated list of regular expressions which specify the
+ libraries whose path must be resolved into absolute paths.
+ This works around certain linking problems with static libraries,
+ when the order of the linking arguments is changed.
+
+2006-02-04 Peter Lund <firefly@diku.dk>
+
+ * APBuild/GCC.pm: Fix double linking of .moc.o files
+
+2006-02-01 Peter Lund <firefly@diku.dk>
+
+ * apgcc: Add support gcc-2.9x.
+ Minor comment/--help fixes. See
+ http://comments.gmane.org/gmane.comp.autopackage.devel/4408
+ for more details
+ * APBuild/GCC.pm, APBuild/Utils.pm: Make apgcc work with ccache.
+
+2006-01-23 Peter Lund <firefly@diku.dk>
+
+ * Makefile: Use eager notation (`:=') instead of `=' for var assignment. Add $(PROGS)-variable to hold all binary names.
+
+
+2005-12-02 Hongli Lai <hongli@plan99.net>
+ * apgcc (rearrangeForAsNeeded):
+ Special case -lbfd and -liberty as they can cause link failures in
+ some cases.
+
+2005-11-30 Hongli Lai <hongli@plan99.net>
+ * apgcc:
+ Do not link to incorrect libstdc++ version: remove
+ /usr/lib/libstdc++.so.x from the arguments.
+
+2005-11-08 Hongli Lai <hongli@plan99.net>
+ * apgcc, Apbuild/GCC.pm, Apbuild/Utils.pm:
+ - Code cleanups.
+ - Fix C++ double compiling bugs: correctly set output filename
+ when -o is not given, surpress gcc output when double compiling.
+
+2005-11-07 Hongli Lai <hongli@plan99.net>
+ * apgcc (linkObjects): remove duplicate system() call which
+ does nothing good but breaks some libtool versions.
+
+2005-10-30 Jan Nieuwenhuizen <janneke@gnu.org>
+
+ * Apbuild/GCC.pm (new): New member variable: searchPaths. Bugfix:
+ add LIBRARY_PATH to initialization.
+ (addSearchPaths): New function.
+ (getSearchPaths): Use searchPaths.
+
+ * Apbuild/Utils.pm (searchLib): Bugfix: correct order of search
+ dirs.
+
+ * apgcc (removeLibraries): Maintain searchPath for full .so name.
+
+October 16 2005 <hongli@plan99.net>
+ * apgcc: Correctly double compile C++ binaries during linking.
+
+September 28 2005 Hongli Lai <hongli@plan99.net>
+ * Support $APBUILD_NO_RPATH: don't add rpath entries.
+ Feature request by Andreas.
+
+September 3 2005 Hongli Lai <hongli@plan99.net>
+ * relaytool: support W, V and G symbols (experimental C++ support)
+
+August 5 2005 Hongli Lai <hongli@plan99.net>
+ * apgcc and GCC.pm: fixed an argument reordering bug.
+ * Makefile: add make-icons to distrbution.
+
+2005-08-02 Mike Hearn <mike@plan99.net>
+ * relaytool: Remove -include flags, if any. This makes relaytool
+ precompiled-header safe.
+
+2005-07-31 Mike Hearn <mike@plan99.net>
+ * relaytool.m4, relaytool: Optimization: use -ffunction-sections
+ and --gc-sections to eliminate unused jump slots
+ * relaytool: Don't break when CFLAGS is set
+ * relaytool: Optimization: only generate jump slots for exported
+ symbols from the library.
+
+July 30 2005 Hongli Lai <hongli@plan99.net>
+ * Apbuild/GCC.pm: Commit Joseph's patch: fix $gcc->isLibrary()
+
+2005-07-20 Mike Hearn <mike@plan99.net>
+ * Makefile (dist): Ship relaytool.m4, make extra scripts +x
+ * relaytool.m4: Big improvements to the way you integrate with
+ C/C++ build systems.
+
+July 9 2005 Hongli Lai <hongli@plan99.net>
+ * apgcc, Apbuild/GCC.pm (rearrangeForAsNeeded):
+ Fix rearrangement of objects: don't recognize parameters
+ (-Wl,foo.so) as objects.
+
+Thu Jun 16 22:43:55 2005 Mike Hearn <mike@navi.cx>
+ * make-icons: Add a script to generate icon theme dropins from an SVG
+ file, a convenient utility for developers
+
+May 31 2005 Hongli Lai <hongli@navi.cx>
+ * apgcc: Automatically compile C++ source files with two different
+ ABIs. By default, C++ files are compiled with ABI 1. Another
+ file with ABI 2 is stored as output.o.GCCABI2
+
+May 16th 2005 Vincent Béron <vberon@mecano.gme.usherb.ca>
+ * relaytool: Keep only one copy of a given symbol per lib.
+ * relaytool: libdl won't ever be supported by relaytool, so skip it.
+ * relaytool: Add a --version option, reorganize a bit the rest of --help.
+ * relaytool: Allow generating a stub file for every library passed in args.
+ * relaytool: Skip generating a stub for libraries for which no functions
+ are called or no variables used.
+ * relaytool: Use proper quoting.
+ * relaytool: Support old nm versions
+
+May 15th 2005 Vincent Béron <vberon@mecano.gme.usherb.ca>
+ * relaytool: Allow relaytool to understand more than one --relay
+ parameter.
+ * relaytool: Enable (via --minimal-list) relaytool to only
+ generate the minimum list of symbols by looking which ones are
+ undefined in .o objects.
+ * relaytool: Use CFLAGS (if available) while compiling the stub file.
+ * relaytool: Use a shell function to do the same thing as
+ readlink -f as the latter isn't always understood by readlink.
+ * relaytool: Fix a typo in PPC C code.
+
+May 14th 2005 Vincent Béron <vberon@mecano.gme.usherb.ca>
+ * relaytool: Don't accidentally exclude all symbols with _init
+ or _fini in their names.
+
+April 16 2005 Hongli Lai <hongli@navi.cx>
+ * Add new tool 'scandeps' which makes it easier for you to find
+ your software's library dependancies.
+ * Improve documentation.
+
+April 15 2005 Hongli Lai <hongli@navi.cx>
+ * apgcc: add support for $APBUILD_INCLUDE, which allows you
+ to prepend any folder to the header search path.
+ * Improve documentation.
+
+Fri Apr 15 22:47:06 2005 Mike Hearn <mike@navi.cx>
+ * apsymbols.h: Update to glibc 2.3.5
+ * buildlist: Don't spew so many errors
+
+April 10 2005 Hongli Lai <hongli@navi.cx>
+ * What? We have a ChangeLog? I didn't know that!
+ In the last 2 weeks I worked on these:
+ - Support for GCC 3.4+'s --as-needed, for smarter automatic bogus
+ dependancy stripping.
+ - Improved our own dependancy stripper.
+ - Big code cleanups.
+
+Tue Apr 5 02:14:49 2005 Mike Hearn <mike@navi.cx>
+ * relaytool.m4: Add an autoconf check for relaytool
+
+Mon Feb 14 00:37:46 2005 Mike Hearn <mike@navi.cx>
+ * relaytool: Add --no-replace option, fix misc bugs revealed by
+ actually using relaytool in a real app
+
+Fri Feb 11 23:49:24 2005 Mike Hearn <mike@navi.cx>
+ * relaytool: don't request PROT_EXEC permissions, they aren't
+ needed
+
+2004-06-06 Mike Hearn <mike@navi.cx>
+ * relaytool: make relaytool jump thunks NX safe by using mmap
+ rather than malloc.
+
+ * relaytool: Fix ELF scoping of dummy symbols for variable
+ imports, so the definitions in the imported lib don't get
+ resolved to the dummies (not all libs are compiled -Bsymbolic)
+
+ * relaytool: support partial maps
+
diff --git a/tools/apbuild/Makefile b/tools/apbuild/Makefile
new file mode 100644
index 00000000..0b0441b4
--- /dev/null
+++ b/tools/apbuild/Makefile
@@ -0,0 +1,55 @@
+.PHONY: all install uninstall
+
+PREFIX:=$(shell test x"`id -u`" = "x0" && if test -f /usr/bin/apgcc; then echo /usr; else echo /usr/local; fi || echo ~/.local)
+BINDIR:=$(PREFIX)/bin
+PERLDIR:=$(PREFIX)/share/apbuild
+INCLUDEDIR:=$(PREFIX)/include/apbuild
+ACLOCALDIR:=$(PREFIX)/share/aclocal
+
+PACKAGE=apbuild
+# Don't forget to bump the version in apgcc too.
+VERSION=2.0.9
+
+PROGS:=apgcc apg++ relaytool scandeps make-icons
+
+all:
+ @echo No compilation is required. To install, type 'make install'.
+ @echo "(Current prefix=$(PREFIX))"
+
+install:
+ mkdir -p $(BINDIR)
+ cp $(PROGS) $(BINDIR)
+ chmod +x $(BINDIR)/apgcc $(BINDIR)/apg++ $(BINDIR)/scandeps $(BINDIR)/make-icons $(BINDIR)/relaytool
+ mkdir -p $(PERLDIR)/Apbuild
+ cp Apbuild/*.pm $(PERLDIR)/Apbuild/
+ mkdir -p $(INCLUDEDIR)
+ cp ctype.h apsymbols.h $(INCLUDEDIR)
+ mkdir -p $(ACLOCALDIR)
+ cp relaytool.m4 $(ACLOCALDIR)
+ echo >> $(INCLUDEDIR)/apsymbols.h
+ echo "/* apbuild version" $(VERSION) "*/" >> $(INCLUDEDIR)/apsymbols.h
+ @echo --------------
+ @echo "Installation complete. Please read README for usage."
+
+uninstall:
+ rm -f $(addprefix $(BINDIR)/, $(PROGS))
+ rm -f $(PERLDIR)/Apbuild/*.pm
+ rmdir $(PERLDIR)/Apbuild $(PERLDIR)
+ rm -f $(INCLUDEDIR)/ctype.h
+ rm -f $(INCLUDEDIR)/apsymbols.h
+ rm -f $(ACLOCALDIR)/relaytool.m4
+
+distdir:
+ rm -rf $(PACKAGE)-$(VERSION)
+ mkdir $(PACKAGE)-$(VERSION)
+ cp -R BINARY-PORTABILITY-NOTES Makefile apsymbols.h ctype.h README $(PROGS) buildlist relaytool.m4 $(PACKAGE)-$(VERSION)/
+ mkdir $(PACKAGE)-$(VERSION)/test-app
+ mkdir $(PACKAGE)-$(VERSION)/Apbuild
+ cp Apbuild/*.pm $(PACKAGE)-$(VERSION)/Apbuild/
+ cp test-app/randomapp1.c $(PACKAGE)-$(VERSION)/test-app/
+
+dist: distdir
+ rm -f $(PACKAGE)-$(VERSION).tar.gz
+ tar -cf $(PACKAGE)-$(VERSION).tar $(PACKAGE)-$(VERSION)
+ gzip --best $(PACKAGE)-$(VERSION).tar
+ rm -rf $(PACKAGE)-$(VERSION)
diff --git a/tools/apbuild/README b/tools/apbuild/README
new file mode 100644
index 00000000..9bc79658
--- /dev/null
+++ b/tools/apbuild/README
@@ -0,0 +1 @@
+Please read http://autopackage.org/aptools.html for documentation.
diff --git a/tools/apbuild/apg++ b/tools/apbuild/apg++
new file mode 100755
index 00000000..30357b53
--- /dev/null
+++ b/tools/apbuild/apg++
@@ -0,0 +1,10 @@
+#!/usr/bin/env perl
+# Simple C++ wrapper for apgcc.
+
+use strict;
+use FindBin;
+
+my $apgcc = "$FindBin::Bin/apgcc";
+$ENV{APBUILD_CXX_MODE} = 1;
+my $a = do $apgcc;
+die $@ if ($@);
diff --git a/tools/apbuild/apgcc b/tools/apbuild/apgcc
new file mode 100755
index 00000000..2aba0071
--- /dev/null
+++ b/tools/apbuild/apgcc
@@ -0,0 +1,1023 @@
+#!/usr/bin/env perl
+# apbuild - a GCC wrapper for creating portable binaries
+# Copyright (c) 2003,2004,2005 Hongli Lai
+# Distributed under the GNU General Public License
+
+use warnings;
+use strict;
+use FindBin qw($RealBin);
+use File::Spec;
+use lib $RealBin;
+use lib "$RealBin/../share/apbuild";
+use IPC::Open2;
+use POSIX;
+use Cwd;
+
+use Apbuild::GCC;
+use Apbuild::Utils;
+
+# Don't forget to bump the version in Makefile too.
+our $APBUILD_VERSION = "2.0.9";
+
+
+######## Initialization ########
+
+# In C mode:
+# $gcc is the default compiler.
+# $gxx2 is not set.
+#
+# In C++ mode:
+# $gcc is g++ 3.2.
+# $gxx2 is g++ 3.4, and it might not be set.
+# Double compiling is only enabled if both are set.
+#
+# Note that $APBUILD_CXX_MODE is an internal environment variable
+# which should not be set by the user.
+our ($gcc, $gxx2);
+
+if ($ENV{APBUILD_CXX_MODE}) {
+ # C++ support; user can:
+ # - Not set APBUILD_CXX1/2 at all -> use g++ as default, and don't double compile C++ sources.
+ # - Set APBUILD_CXX1 and APBUILD_CXX2 -> enable double compiling.
+ # - Set only APBUILD_CXX1 -> don't double compile.
+ # - Set only APBUILD_CXX2 -> use 'g++' as default for APBUILD_CXX1, and enable double compiling.
+
+ if (empty($ENV{APBUILD_CXX1}) && empty($ENV{APBUILD_CXX2})) {
+ $gcc = new Apbuild::GCC('g++');
+
+ } elsif (!empty($ENV{APBUILD_CXX1}) && !empty($ENV{APBUILD_CXX2})) {
+ $gcc = new Apbuild::GCC($ENV{APBUILD_CXX1});
+ $gxx2 = new Apbuild::GCC($ENV{APBUILD_CXX2});
+
+ } elsif (!empty($ENV{APBUILD_CXX1})) {
+ $gcc = new Apbuild::GCC($ENV{APBUILD_CXX1});
+
+ } elsif (!empty($ENV{APBUILD_CXX2})) {
+ $gcc = new Apbuild::GCC('g++');
+ $gxx2 = new Apbuild::GCC($ENV{APBUILD_CXX2});
+ }
+
+} else {
+ my $gcc_command = 'gcc';
+ $gcc_command = $ENV{APBUILD_CC} if (!empty($ENV{APBUILD_CC}));
+ $gcc = new Apbuild::GCC($gcc_command);
+}
+
+
+our $appath;
+our $libgcc = $ENV{APBUILD_STATIC_LIBGCC} ? '-static-libgcc' : '-shared-libgcc';
+
+# Find out where apgcc is located and determine the apbuild header
+# path relative to the apgcc script location.
+$appath = $ENV{APBUILD_PATH} if (!empty($ENV{APBUILD_PATH}));
+if (!defined $appath) {
+ $appath = $FindBin::Bin;
+ $appath =~ s/\/*$//g;
+ $appath =~ s/^(.*)\/.*?$/$1/;
+ $appath .= '/include/apbuild';
+ if (! -f "$appath/apsymbols.h" && -f "$FindBin::Bin/apsymbols.h") {
+ $appath = $FindBin::Bin;
+ }
+}
+
+# Special constants
+our @linking = ('-Wl,--enable-new-dtags,--rpath,${ORIGIN}/../lib,--rpath,${ORIGIN}/../lib/autopackage');
+our @include = ("-I$appath", '-include', "$appath/apsymbols.h", "-DAPBUILD_VERSION=\"$APBUILD_VERSION\"");
+our $extraTypes = $Apbuild::GCC::extraTypes;
+our $srcTypes = $Apbuild::GCC::srcTypes;
+
+
+@linking = () if ($ENV{APBUILD_NO_RPATH});
+if (!empty($ENV{APBUILD_INCLUDE})) {
+ foreach my $dir (split /:+/, $ENV{APBUILD_INCLUDE}) {
+ if ($dir =~ /=/) {
+ # allow people to force changing a path with oldpath=newpath, e.g.,:
+ # $echo $APBUILD_INCLUDE
+ # /opt/kde/include=/home/taj/kde-headers/kde-3.3.2/kde/include
+ # would change -I/opt/kde/include to my KDE 3.3 headers.
+ # this works around problems where the order of the include
+ # directories is important. Added for amarok 1.4.3 which has a
+ # header named scriptmanager.h. KDE also has a header named
+ # scriptmanager. Order of -I flags forces amarok header to be
+ # included.
+ my @splitpaths = split(/=/, $dir);
+ if (-d $splitpaths[1]) {
+ foreach (@ARGV) {
+ s/-I$splitpaths[0]$/-I$splitpaths[1]/g;
+ }
+ }
+ }
+ else {
+ push @include, "-I$dir" if (-d $dir);
+ }
+ }
+}
+
+# Include the apbuild include folder, and all folders inside that folder.
+if (opendir D, $appath) {
+ foreach my $dir (readdir D) {
+ if ($dir !~ /^\./ && -d "$appath/$dir") {
+ push @include, "-I$appath/$dir";
+ }
+ }
+ closedir D;
+}
+
+if (!empty($ENV{APBUILD_PROJECTNAME})) {
+ push @linking, '-Wl,--rpath,${ORIGIN}/../lib/' . $ENV{APBUILD_PROJECTNAME};
+}
+
+
+our %capabilities = $gcc->capabilities;
+if ($capabilities{hash_style}) {
+ # By default FC6 only generates a .gnu.hash section, not
+ # .hash (which is the only thing that FC5 and most other
+ # distros understand).
+ # Force generation of both sections if the linker supports it
+ # so that the binary will run on other systems.
+ # See http://fcp.surfsite.org/modules/newbb/viewtopic.php?topic_id=29929&forum=10&post_id=128939
+ # for more details
+ push @linking, '-Wl,--hash-style=both';
+}
+
+if ($capabilities{stack_protector}) {
+ # gcc-4.1 introduced stack protection to help check for
+ # buffer overflows. This introduces a silent dependency on
+ # glibc 2.4 (__stack_chk_fail@@GLIBC_2.4)
+ # Not many people have glibc 2.4 yet, so disable it.
+ push @include, "-fno-stack-protector";
+}
+
+if ($capabilities{fortify_source}) {
+ # Some distros (e.g. Ubuntu 8.10) activate a bufferoverflow protection
+ # which is only available since glibc 2.3.4. Apbuild removes all symbols
+ # newer then 2.3, so this can't be used.
+ push @include, "-U_FORTIFY_SOURCE";
+}
+
+our %capabilities_gxx2;
+%capabilities_gxx2 = $gxx2->capabilities if ($gxx2);
+push @linking, $libgcc if ($capabilities{libgcc});
+
+
+############# Detect compilation situation #############
+
+our $situation = $gcc->situation(\@ARGV);
+if ($ENV{APBUILD_CXX_MODE}) {
+ debug "apg++ @ARGV\n";
+} else {
+ debug "apgcc @ARGV\n";
+}
+debug "Situation: $situation\n";
+
+
+# Handle each situation
+# Only situations that involve compiling or linking need to be treated specially
+if ($situation eq 'compile') {
+ # Extract the parameters and files
+ my (@files, @params);
+ $gcc->splitParams(\@ARGV, \@files, \@params);
+
+ # Compile each source file to an object file.
+ # Force GCC to compile C/C++ source files with older glibc symbols.
+ debug "\@files: is @files\n";
+ foreach my $file (@files) {
+ if ($gxx2 && $gxx2->isCxxSource($file)) {
+ # This is a C++ source file. Compile the file twice with different ABIs.
+ my $src = $file;
+ my $old_gcc;
+ my %old_cap;
+
+ compileSource($src, \@ARGV);
+
+ $old_gcc = $gcc;
+ %old_cap = %capabilities;
+ $gcc = $gxx2;
+ %capabilities = %capabilities_gxx2;
+
+ beginDoubleCompiling();
+ compileSource($src, \@ARGV, '.GCCABI2');
+ endDoubleCompiling();
+
+ $gcc = $old_gcc;
+ %capabilities = %old_cap;
+
+ } else {
+ compileSource($file, \@ARGV);
+ }
+ }
+ exit;
+
+} elsif ($situation eq 'linking') {
+ linkObjects(\@ARGV);
+
+ if ($gxx2) {
+ # Check whether there are .GCCABI2 objects. Link them if there are.
+ my @options;
+ my $doubleCompile;
+
+ my $callback = sub {
+ my $type = shift;
+
+ if ($type eq 'param' && ($gxx2->isLibrary($_[0]) || $gxx2->isObject($_[0])) && !$gxx2->isStaticLib($_[0]) && -f "$_[0].GCCABI2") {
+ push @options, "$_[0].GCCABI2";
+ $doubleCompile = 1;
+ } else {
+ push @options, @_;
+ }
+ };
+
+ $gcc = $gxx2;
+ %capabilities = %capabilities_gxx2;
+
+ $gcc->foreach(\@ARGV, $callback);
+
+ if ($doubleCompile) {
+ debug "Double compiling.\n";
+ beginDoubleCompiling();
+ linkObjects(\@options, ".GCCABI2");
+ endDoubleCompiling();
+ }
+ }
+ exit;
+} elsif ($situation eq 'precompiled header') {
+ # Extract the parameters and files
+ my (@files, @params);
+ $gcc->splitParams(\@ARGV, \@files, \@params);
+
+ # Compile each source file to an object file.
+ # Force GCC to compile C/C++ source files with older glibc symbols.
+ debug "\@files: is @files\n";
+ foreach my $file (@files)
+ {
+ compileSource($file, \@ARGV);
+ }
+} elsif ($situation eq 'compile and link') {
+ # Extract the parameters and files
+ my (@params, @files, @linking2);
+ my @command;
+ my $status;
+
+ # Seperate files and linker options.
+ # @params are all options except linker options, and is used for compilation of each individual source file.
+ # @files are the source files.
+ $gcc->splitParams(\@ARGV, \@files, \@params);
+ $gcc->stripLinkerParams(\@params, \@linking2);
+
+ # Compile & link only one source file
+ if (@files == 1) {
+ my @options = modifyLinkerOptions(@params);
+ push @options, @linking2;
+
+ if ($gxx2 && $gxx2->isCxxSource($files[0])) {
+ # This is a C++ file. Compile twice with different ABIs.
+ compileSource($files[0], \@ARGV);
+ manipulateDeps(@options);
+
+ $gcc = $gxx2;
+ %capabilities = %capabilities_gxx2;
+
+ beginDoubleCompiling();
+ compileSource($files[0], \@ARGV, '.GCCABI2');
+ manipulateDeps(@options);
+ endDoubleCompiling();
+
+ } else {
+ compileSource($files[0], [@linking, @options], undef);
+ manipulateDeps($files[0], @options);
+ }
+
+ exit;
+ }
+
+ # Compile individual files into objects
+ my $cxx;
+ debug "Multiple source files: @files\n";
+ foreach my $file (@files) {
+ my $out = $file;
+ $out =~ s/^(.*)\..*?$/$1.o/;
+
+ if ($gxx2 && $gxx2->isCxxSource($file)) {
+ # This is a C++ file. Compile twice with different ABIs.
+ my $old_gcc;
+ my %old_cap;
+
+ $cxx = 1;
+ compileSource($file, [@ARGV, '-c']);
+
+ $old_gcc = $gcc;
+ %old_cap = %capabilities;
+ $gcc = $gxx2;
+ %capabilities = %capabilities_gxx2;
+
+ beginDoubleCompiling();
+ compileSource($file, [@ARGV, '-c'], '.GCCABI2');
+ endDoubleCompiling();
+
+ $gcc = $old_gcc;
+ %capabilities = %old_cap;
+
+ } else {
+ compileSource($file, [@params, '-c'], undef);
+ }
+
+ $file = $out;
+ }
+
+ # Finally, link all objects together.
+ my @options = (@params, @linking2);
+ linkObjects([@files, @options]);
+
+ if ($cxx) {
+ $gcc = $gxx2;
+ %capabilities = %capabilities_gxx2;
+
+ # Also link the objects with ABI 2 together
+ foreach (@files) {
+ $_ .= ".GCCABI2";
+ }
+ beginDoubleCompiling();
+ linkObjects([@files, @options], '.GCCABI2');
+ endDoubleCompiling();
+ }
+ exit;
+
+} else {
+ my $ret = run($gcc->command, @ARGV);
+ if (defined $ARGV[0] && $ARGV[0] eq '--help') {
+ print "\napbuild environment variables:\n";
+ print " APBUILD_PATH=path Specifies the include path for apsymbols.h\n" .
+ " (like: /usr/local/include/apbuild)\n" .
+ " APBUILD_DEBUG=1 Enable debugging messages\n" .
+ " APBUILD_BOGUS_DEPS=deps Specify a list of whitespace-seperated bogus\n" .
+ " library dependancies (like: X11 ICE png). These\n" .
+ " libraries will not be linked.\n" .
+ " APBUILD_STATIC=deps Specify a list of whitespace-seperated libraries\n" .
+ " to statically link to (like: popt z). You can also\n" .
+ " explicitly specify a filename to the static library.\n" .
+ " Example: popt=/usr/lib/libpopt.a\n" .
+ " APBUILD_STATIC_X=1 Force static linking of some X extension libraries\n" .
+ " Don't use this unless you know what you're doing.\n" .
+ " APBUILD_DISABLE_BOGUS_DETECTOR=1 Disable the automatic bogus dependancy\n" .
+ " detector. This is useful when linking to libraries\n" .
+ " don't have correct DT_NEEDED entries, like GTK 1.2.\n" .
+ " APBUILD_NOT_BOGUS=deps If you want to use the automatic bogus dependancy\n" .
+ " dectector anyway, then you can specify a list of\n" .
+ " dependancies here that are not bogus.\n" .
+ " APBUILD_STATIC_LIBGCC=1 Link all binaries with -static-libgcc. See the gcc\n" .
+ " info page for more info about this option.\n" .
+ " APBUILD_PROJECTNAME If non-empty, apbuild will add\n" .
+ " \$ORIGIN/../lib/\$APBUILD_PROJECTNAME to the library\n" .
+ " search path.\n" .
+ " APBUILD_INCLUDE Prepend the specified directory to the compiler's\n" .
+ " header search path. The compiler will search this\n" .
+ " directory first, before searching any other\n" .
+ " directory. This is useful in combination with the\n" .
+ " older GTK headers package (see the autopackage\n" .
+ " website). You can specify multiple directories,\n" .
+ " seperated by a ':', just like the \$PATH environment\n" .
+ " variable.\n" .
+ " APBUILD_NO_RPATH Do not add rpath entries during linking.\n" .
+ " APBUILD_CC Use the specified C compiler. Default value: gcc\n" .
+ " APBUILD_CXX1,APBUILD_CXX2 Use the specified C++ compiler. Default value: g++\n" .
+ " Set both variables to enable double compiling. The\n" .
+ " first should be set to the g++ 3.2 compiler and the\n" .
+ " second should be set to the g++ 3.4 (or newer)\n" .
+ " compiler.\n" .
+ " APBUILD_RESOLVE_LIBPATH A whitespace-separated list of regular expressions which\n" .
+ " specify the libraries whose path must be resolved into\n" .
+ " an absolute path.\n";
+ }
+ exit $ret;
+}
+
+
+######## Functions ########
+
+
+sub modifyLinkerOptions {
+ my @argv = @_;
+
+ # Remove manually specified bogus library dependancies
+ my @bogusDeps;
+ @bogusDeps = split / +/, $ENV{APBUILD_BOGUS_DEPS} if (!empty($ENV{APBUILD_BOGUS_DEPS}));
+
+ # We call removeLibraries() twice because it may detect
+ # some dependancies after we've resolved the library names
+ @argv = removeLibraries(\@bogusDeps, @argv);
+ @argv = translateLibNames(@argv);
+ @argv = removeLibraries(\@bogusDeps, @argv);
+
+ @argv = removeStaticGlibc(@argv);
+ if ($capabilities{as_needed}) {
+ @argv = rearrangeForAsNeeded(@argv);
+ @argv = forceStatic(@argv);
+ }
+
+ return @argv;
+}
+
+
+sub removeLibraries {
+ my $blacklist = shift;
+ return @_ if (@{$blacklist} == 0);
+
+ my @args;
+ my $callback = sub {
+ my $type = shift;
+ if ($type ne "param") {
+ push @args, @_;
+ return;
+ }
+
+ my $lib;
+ $_ = $_[0];
+ if (/^-l(.+)/) {
+ $lib = $1
+ } elsif (/(.*)\/lib(.+)\.so/) {
+ $gcc->addSearchPaths($1);
+ $lib = $2;
+ } else {
+ push @args, @_;
+ return;
+ }
+
+ # We now have a library parameter; remove this parameter
+ # if the library's in the blacklist
+ foreach my $dep (@{$blacklist}) {
+ return if ($lib eq $dep);
+ }
+ push @args, @_;
+ };
+
+ $gcc->foreach(\@_, $callback);
+ return @args;
+}
+
+
+# This function translates library linker options to something saner.
+# - On my system, -lpng links to libpng.so. However, libpng.so is a symlink to libpng12.so.
+# This function translates -lpng to -lpng12 so that the automatic bogus dependancy stripper
+# can detect this as a bogus dependancy.
+# - Translate /usr/lib/libpng.so to /usr/lib/libpng12.so because the soname is different.
+# - Translates -pthread to -lpthread.
+# - When in C++ mode, removes libstdc++.so from the argument list. This causes trouble when
+# double compiling, unless the -nostdlib option is specified and we're not double compiling.
+# libtool can put us in this configuration.
+
+# TODO: correctly handle static libraries.
+# apg++ ... -L/usr/lib -Wl,-Bstatic -lphysfs -Wl,-Bdynamic
+# -> /usr/lib/gcc-lib/i686-pc-linux-gnu/3.3.5/../../../../i686-pc-linux-gnu/bin/ld: cannot find -lphysfs-1.0
+sub translateLibNames {
+ my (@args, @searchPaths);
+
+ # Get a list of search paths
+ $gcc->getSearchPaths(\@_, \@searchPaths);
+
+ my $staticMode = 0;
+ my $callback = sub {
+ my $type = shift;
+ my $dontAdd;
+
+ if ($type ne 'param') {
+ push @args, @_;
+ return;
+ }
+
+ $_ = $_[0];
+ if (/^-Wl,(.+)/) {
+ # Detect whether the next library will be linked statically or dynamically
+ foreach my $arg (split /,/, $1) {
+ if ($arg eq '-Bdynamic') {
+ $staticMode = 0;
+ } elsif ($arg eq '-Bstatic') {
+ $staticMode = 1;
+ }
+ }
+
+ } elsif ($staticMode) {
+ # Don't try to resolve library name if it's linked statically
+
+ } elsif (/^-l(.+)/ || /--library=(.+)/) {
+ my $libname = $1;
+
+ # Resolve libname if explicitely asked to, through APBUILD_RESOLVE_LIBPATH.
+ my @libtosolve = split / +/, $ENV{APBUILD_RESOLVE_LIBPATH} if (!empty($ENV{APBUILD_RESOLVE_LIBPATH}));
+ foreach (@libtosolve) {
+ my $regexp = $_;
+ if ($libname =~ /($regexp)/) {
+ my $file = searchLib("lib$libname.a", \@searchPaths);
+ if ($file && -f $file) {
+ debug "resolved", $_[0], "as", $file;
+ # Replace -lXXX with the absolute path for libXXX.a
+ $_[0] = $file;
+ last;
+ }
+ }
+ }
+
+ # Library is a symlink; check whether the sonames match
+ my $lib = searchLib("lib$libname.so", \@searchPaths);
+ if ($lib && -l $lib) {
+ my ($soname1) = $lib =~ /.*\/lib(.+)\.so/;
+ my $lib2 = soname($lib);
+ my ($soname2) = $lib2 =~ /lib(.+)\.so/;
+
+ if ($soname1 ne $soname2 && defined searchLib("lib$soname2.so", \@searchPaths)) {
+ $_[0] = "-l$soname2";
+ }
+ }
+
+ } elsif ($_ eq '-pthread') {
+ $_[0] = "-lpthread";
+
+ } elsif ($ENV{APBUILD_CXX_MODE} && /\/?libstdc\+\+\.so(.[56])?/) {
+ # drop this in double compile mode as it can cause issues
+ # in single-compile mode leave it alone, otherwise, libtool can break
+ # ^^^ That used to be true
+ # Now drop it and add the compilers stdc++
+ # Works around libtool problems where the wrong libstdc++.so is
+ # picked up from .la files of dependencies
+ my @command = ($gcc->command, "--print-file-name=libstdc++.so");
+ chomp($_[0] = `@command`);
+
+ } elsif (/(.*)\/?(lib.+\.so.*)/) {
+ $gcc->addSearchPaths ($1);
+ push @searchPaths, $1;
+ my $lib = searchLib($2, \@searchPaths);
+ if (defined $lib) {
+ my $soname = soname($lib);
+ $lib = searchLib($soname, \@searchPaths);
+ $_[0] = $lib if (defined $lib);
+ }
+ }
+ push @args, @_ if (!$dontAdd);
+ };
+ $gcc->foreach(\@_, $callback);
+
+ return @args;
+}
+
+
+# Replace -static with something else. We can't statically link to glibc!
+# So we statically link to everything but glibc.
+sub removeStaticGlibc {
+ my $hasStatic = 0;
+ foreach (@_) {
+ if ($_ eq '-static') {
+ $hasStatic = 1;
+ last;
+ }
+ }
+ return @_ if (!$hasStatic);
+
+ my @argv;
+ foreach (@_) {
+ if ((/^-l(.+)/ || /^--library=(.+)/) && defined $1 && $1 ne 'c') {
+ push @argv, '-Wl,-Bstatic';
+ push @argv, $_;
+ push @argv, '-Wl,-Bdynamic';
+ } elsif ($_ ne "-static") {
+ push @argv, $_;
+ }
+ }
+ return @argv;
+}
+
+
+# 'gcc -Wl,--as-needed foo.o -lpng' breaks the binary.
+# 'gcc foo.o -Wl,--as-needed -lpng' doesn't.
+# Move object files to before the first library flag.
+#
+# Furthermore, -lbfd and -liberty must be the last arguments, or
+# an app won't link properly in some cases. XRender needs to be
+# after XCursor for some reason, so push it to the end too.
+sub rearrangeForAsNeeded {
+ my @args;
+ my @nonParams;
+ my @last;
+
+ my $callback = sub {
+ my $type = shift;
+
+ if ($type ne "param") {
+ push @nonParams, @_;
+
+ } elsif ($_[0] eq "-lbfd" || $_[0] eq "-liberty" || $_[0] eq "-lXrender") {
+ push @last, @_;
+
+ } elsif ($gcc->isLibrary($_[0])) {
+ push @args, @_;
+
+ } elsif ($gcc->isObject($_[0]) || $gcc->linkOrderIsImportant($_[0])) {
+ push @nonParams, @_;
+
+ } else {
+ push @args, @_;
+ }
+ };
+
+ $gcc->foreach(\@_, $callback);
+ unshift @args, "-Wl,--as-needed";
+ unshift @args, @nonParams;
+ push @args, @last;
+ return @args;
+}
+
+
+################ Automatic bogus dependancy stripper ################
+
+
+# Automatically detecting bogus dependancies & force static linking to certain X libraries
+sub manipulateDeps {
+ return if ($capabilities{as_needed});
+ my @searchPaths;
+ my $output = 'a.out';
+ my $i = 0;
+ my @deps;
+ my @argv;
+
+ if ($ENV{APBUILD_DISABLE_BOGUS_DETECTOR}) {
+ @argv = @_;
+ goto FINAL;
+ }
+
+ # Get a list of search paths and the output filename
+ for ($i = 0; $i < @_; $i++) {
+ if ($_[$i] eq "-L") {
+ push (@searchPaths, $_[$i + 1]) if (defined $_[$i + 1]);
+ $i++;
+ } elsif ($_[$i] =~ /^-L(.+)/ || $_[$i] =~ /^--library-path=(.+)/) {
+ push (@searchPaths, $1);
+ } elsif ($_[$i] eq "-o") {
+ $output = $_[$i + 1] if (defined $_[$i + 1]);
+ $i++;
+ }
+ }
+
+ # Find out what libraries the executable needs
+ my ($r, $w);
+ my $pid = open2 ($r, $w, 'objdump', '-p', $output);
+ close ($w);
+ foreach (<$r>) {
+ next unless (/^ NEEDED/);
+ s/^ NEEDED[ \t]+//;
+ s/\n//;
+ my $lib = searchLib ($_, \@searchPaths);
+ push (@deps, $lib) if (defined $lib);
+ }
+ close ($r);
+ waitpid ($pid, 0);
+
+ # Some -l options have no effect. For example, when linking apollon,
+ # -lXinerama is passed, yet the resulting executable doesn't have a
+ # DT_NEEDED entry for libXinerama.so. Remove those options so that
+ # they won't interfere with forceStatic().
+ foreach (@_) {
+ if ((/^-l(.+)/ || /^--library=(.+)/)
+ && !searchLib("lib$1.a", \@searchPaths)
+ && !(/^-lpng$/) # Special case the libpng mess, bah
+ ) {
+ # "Xinerama"
+ my $arg = $1;
+ # Only add to @argv if $arg is in @deps
+ foreach my $dep (@deps) {
+ # "/usr/X11R6/lib/libXinerama.so.1" -> "Xinerama"
+ my ($soname) = $dep =~ /.*\/lib(.+)\.so/;
+ if ($arg eq $soname) {
+ push (@argv, "-l$arg");
+ last;
+ }
+ }
+ } else {
+ push (@argv, $_);
+ }
+ }
+
+ # Find out which symbols the executable needs, and which symbols are provided
+ # by the libraries it's linked to.
+ my %appsyms = extractSymbols ('UBV', $output);
+ my @bogusDeps;
+
+ foreach my $lib (@deps) {
+ # Never remove libc, libgcc_s and libstdc++
+ next if ($lib =~ /^\/lib\/lib(c|gcc_s|stdc\+\+)\.so/);
+
+ my %libsyms = extractSymbols ('TBVRDSWG', $lib);
+ my $bogus = 1;
+
+ foreach my $sym (keys %libsyms) {
+ if (defined $appsyms{$sym}) {
+ debug ("Real dependancy $lib: $sym (lib: $libsyms{$sym} - app: $appsyms{$sym})\n");
+ $bogus = 0;
+ last;
+ }
+ }
+
+ if ($bogus) {
+ my ($soname) = $lib =~ /.*\/lib(.+)\.so/;
+ push (@bogusDeps, $soname);
+ }
+ }
+
+ FINAL: {
+ # Don't strip dependancies that are explicitly marked as not bogus
+ my %notBogus;
+ if (!empty($ENV{APBUILD_NOT_BOGUS})) {
+ foreach (split / +/, $ENV{APBUILD_NOT_BOGUS}) {
+ $notBogus{$_} = 1;
+ }
+ }
+
+ my @tmp;
+ foreach (@bogusDeps) {
+ push @tmp, $_ if (!$notBogus{$_});
+ }
+ @bogusDeps = @tmp;
+
+ my @options = removeLibraries(\@bogusDeps, @argv);
+ @options = forceStatic(@options);
+
+ if ("@options" ne "@argv") {
+ my @command = ($gcc->command, @include, @linking, @options);
+ debug("Bogus dependancies: @bogusDeps\n") if (@bogusDeps);
+ debug("Relinking: @command\n");
+ my $status = run(@command);
+ exit($status) if ($status != 0);
+ }
+ }
+}
+
+sub extractSymbols {
+ my $types = shift;
+ my %symbols = ();
+ my ($r, $w);
+ my $pid = open2 ($r, $w, 'nm', '-D', @_);
+
+ close ($w);
+ foreach (<$r>) {
+ if (/^.{9}[$types]/) {
+ s/\n//;
+ s/^.{9}//;
+ my ($type, $name) = split (/ /, $_, 2);
+ $symbols{$name} = $type;
+ }
+ }
+ close ($r);
+ waitpid ($pid, 0);
+ return %symbols;
+}
+
+
+# Force static linking against libraries in $APBUILD_STATIC and certain X libraries.
+sub forceStatic {
+ my (%xlibs, %staticList, $X11linked, $linkedToStaticX);
+ my (@args, @searchPaths);
+
+ # Create a list of libraries that we want to statically link
+ $gcc->getSearchPaths(\@_, \@searchPaths);
+ if (defined $ENV{'APBUILD_NO_STATIC_X'}) {
+ warn "WARNING: APBUILD_NO_STATIC_X is no longer used because it became the default behaviour.\n";
+ }
+ if (defined $ENV{'APBUILD_STATIC_X'} && $ENV{'APBUILD_STATIC_X'} eq "1") {
+ foreach (qw(Xrender Xcursor Xfixes Xi Xinerama Xrandr Xv Xxf86dga Xxf86misc Xxf86vm)) {
+ my $file = searchLib("lib$_.a", \@searchPaths);
+ $staticList{$_} = $file if (defined $file);
+ $xlibs{$_} = 1;
+ }
+ }
+
+ my @static_deps;
+ if (!empty($ENV{APBUILD_STATIC})) {
+ foreach (split / +/, $ENV{APBUILD_STATIC}) {
+ my ($lib, $file) = split /=/, $_, 2;
+ $file = searchLib("lib$lib.a", \@searchPaths) if (!defined $file);
+ $staticList{$lib} = $file if (defined $file);
+
+ if (defined $file) {
+ # find the DT_NEEDED entries that this library-to-be-made-static
+ # has so that final linking works (the deps need to be added after the static lib so the bogus stripper doesn't remove them)
+ my ($r, $w);
+ my $abslib = searchLib("lib$lib.so", \@searchPaths);
+ if (!defined $abslib) {
+ warn "WARNING: Failed to find lib$lib.so in " . join(":", @searchPaths) . ".\n";
+ next;
+ }
+ my $pid = open2 ($r, $w, 'objdump', '-p', $abslib);
+ close ($w);
+ foreach (<$r>) {
+ next unless (/^ NEEDED\s+lib(.+?)\.so/);
+ s/^ NEEDED\s+lib(.+?)\.so(.*)/$1/;
+ s/\n//;
+ push(@static_deps, "-l$_");
+ }
+ close ($r);
+ waitpid ($pid, 0);
+ }
+ }
+ }
+
+ push (@_, @static_deps);
+
+ # Modify linker options for static linking
+ my $callback = sub {
+ my $type = shift;
+ my $libname;
+ if ($type eq "param" && $gcc->isLibrary($_[0], \$libname)) {
+ $X11linked = 1 if (!$X11linked && $libname eq 'X11');
+ if ($staticList{$libname}) {
+ # This parameter is a library and is in the list of libraries
+ # to statically link; replace parameter by a filename to the
+ # static library
+ push @args, $staticList{$libname};
+ $linkedToStaticX = 1 if ($xlibs{$libname});
+
+ if ($libname eq "Xcursor") {
+ # With some versions of X11 (on Slack 11,
+ # xorg 6.9.0, anyway), Xcursor links against Xfixes.
+ # If we switch Xcursor to being linked statically,
+ # force linking of Xfixes too so we don't get
+ # undefined symbol errors from Xcursor.
+ push @args, $staticList{"Xfixes"};
+ }
+
+ } else {
+ push @args, @_;
+ }
+
+ } else {
+ push @args, @_;
+ }
+ };
+ $gcc->foreach(\@_, $callback);
+
+ # The app must be linked to libX11 if it has statically linked any the static X libraries
+ push @args, "-lX11" if ($linkedToStaticX && !$X11linked);
+ return @args;
+}
+
+##
+# compileSource(source, argss, extension, extra...)
+# source: the source filename.
+# args: the full GCC arguments (may include other source files) used for compilation.
+# extension: if not undef, $extension will be appended to the output object file's filename.
+# extra: extra parameters to pass to the compiler.
+sub compileSource {
+ my ($source, $args, $ext) = @_;
+ my (@command, @tmp, @params, @sourceParams, @otherParams);
+
+ $gcc->splitParams($args, undef, \@tmp);
+ push @tmp, $source;
+
+ if (defined $ext) {
+ # Change the output file's extension.
+ $gcc->setOutputFile(\@tmp, $gcc->getOutputFile(\@tmp) . $ext);
+ }
+ $gcc->splitParams(\@tmp, undef, \@params);
+
+ my $callback = sub {
+ my $type = shift;
+ if ($type eq 'param' && $gcc->sourceOrderIsImportant($_[0])) {
+ push @sourceParams, @_;
+ } else {
+ push @otherParams, @_;
+ }
+ };
+ $gcc->foreach(\@params, $callback);
+
+ if ($source =~ /\.($srcTypes)$/) {
+ @command = ($gcc->command, @include, @sourceParams, $source, @otherParams);
+ } else {
+ @command = ($gcc->command, @sourceParams, $source, @otherParams);
+ }
+
+ debug "@command\n";
+ my $status = run(@command);
+ exit($status) if ($status != 0);
+}
+
+# Checks whether there should be an ABI2 version of a certain static library.
+sub checkStaticLibrary {
+ my ($lib, $ext) = @_;
+ my ($pid, $r, $w, @objects, $doubleCompile);
+ my (undef, $libdir, $libname) = File::Spec->splitpath($lib);
+ my $newlib = "$lib$ext";
+
+ # Return the ABI2 version if already exists.
+ return $newlib if (-f $newlib);
+
+ # Check the content of the archive. Check whether
+ # there are ABI2 versions of the object files inside.
+ $pid = open2($r, $w, 'ar', 't', $lib);
+ close($w);
+ while ((my $file = <$r>)) {
+ $file =~ s/\n//g;
+ if (-f "$libdir/$file$ext") {
+ push @objects, "$file$ext";
+ $doubleCompile = 1;
+ } else {
+ push @objects, $file;
+ }
+ }
+ close($r);
+ waitpid ($pid, 0);
+
+ if ($doubleCompile) {
+ my $oldDir = getcwd();
+ $newlib = "$libname$ext";
+ debug "Creating static library $newlib\n";
+
+ chdir($libdir);
+ my @command = ("ar", "cru", $newlib, @objects);
+ debug(@command);
+ my $ret = run(@command);
+ exit($ret) if ($ret != 0);
+
+ @command = ("ranlib", $newlib);
+ debug(@command);
+ $ret = run(@command);
+ exit($ret) if ($ret != 0);
+
+ chdir($oldDir);
+ return $newlib;
+ } else {
+ return undef;
+ }
+}
+
+sub linkObjects {
+ my ($args, $ext) = @_;
+ my @options = modifyLinkerOptions(@{$args});
+
+ if (defined $ext) {
+ $gcc->setOutputFile(\@options, $gcc->getOutputFile(\@options) . $ext);
+
+ # Check whether this object links to any static libraries.
+ # If it does, check whether there should be an ABI2 version of that
+ # static library, and attempt to create it.
+ my @options2;
+
+ my $callback = sub {
+ my $type = shift;
+ if ($type eq 'param' && $gcc->isStaticLib($_[0])) {
+ my $newlib = checkStaticLibrary($_[0], $ext);
+ if (defined $newlib) {
+ push @options2, $newlib;
+ } else {
+ push @options2, @_;
+ }
+ } else {
+ push @options2, @_;
+ }
+ };
+ $gcc->foreach(\@options, $callback);
+ @options = @options2;
+ }
+
+ my @command = ($gcc->command, @linking, @options);
+ debug "@command\n";
+
+ my $status = run(@command);
+ exit ($status) if ($status != 0);
+
+ my (@files, @options2);
+ $gcc->splitParams(\@options, \@files, \@options2);
+ manipulateDeps(@files, @options2);
+}
+
+##
+# beginDoubleCompiling()
+#
+# Prepare the environment for double compiling.
+sub beginDoubleCompiling {
+ # Since g++ will be executed another time, we don't want it to
+ # print output to stdout/stderr, because it can potentially
+ # screw up some build systems such as libtool.
+ # stderr will go to the console (/dev/tty), stdout will be
+ # lost (/dev/null).
+
+ our $stdout_fd = fileno(STDOUT);
+ our $stderr_fd = fileno(STDERR);
+ our $stdout_saved = POSIX::dup($stdout_fd);
+ our $stderr_saved = POSIX::dup($stderr_fd);
+
+ my $fd1 = POSIX::open("/dev/null", O_CREAT | O_WRONLY, 0644);
+ my $fd2 = POSIX::open("/dev/tty", O_CREAT | O_WRONLY, 0644);
+ POSIX::dup2($fd1, $stdout_fd);
+ POSIX::dup2($fd2, $stderr_fd);
+ POSIX::close($fd1);
+ POSIX::close($fd2);
+}
+
+##
+# endDoubleCompiling()
+#
+# Unprepare the environment for double compiling.
+sub endDoubleCompiling {
+ our ($stdout_fd, $stderr_fd, $stdout_saved, $stderr_saved);
+
+ POSIX::dup2($stdout_saved, $stdout_fd);
+ POSIX::dup2($stderr_saved, $stderr_fd);
+ POSIX::close($stdout_saved);
+ POSIX::close($stderr_saved);
+}
diff --git a/tools/apbuild/apsymbols.h b/tools/apbuild/apsymbols.h
new file mode 100644
index 00000000..32c7b18c
--- /dev/null
+++ b/tools/apbuild/apsymbols.h
@@ -0,0 +1,275 @@
+/* apbuild embedded metadata */
+#define APBUILD_NOTE_METADATA(s) __asm__(".section .metadata, \"MS\", @note, 1\n\t.string \"" s "\"\n\t.previous\n\t")
+
+#ifdef APBUILD_VERSION
+APBUILD_NOTE_METADATA("apbuild.version=" APBUILD_VERSION);
+#endif
+
+/* apbuild generated symbol exclusion list */
+__asm__(".symver _sys_errlist,_sys_errlist@GLIBC_2.0");
+__asm__(".symver _sys_nerr,_sys_nerr@GLIBC_2.0");
+__asm__(".symver _sys_siglist,_sys_siglist@GLIBC_2.0");
+__asm__(".symver clnt_pcreateerror,clnt_pcreateerror@GLIBC_2.0");
+__asm__(".symver clnt_spcreateerror,clnt_spcreateerror@GLIBC_2.0");
+__asm__(".symver feupdateenv,feupdateenv@GLIBC_2.1");
+__asm__(".symver lio_listio,lio_listio@GLIBC_2.1");
+__asm__(".symver lio_listio64,lio_listio64@GLIBC_2.1");
+__asm__(".symver nftw,nftw@GLIBC_2.1");
+__asm__(".symver nftw64,nftw64@GLIBC_2.1");
+__asm__(".symver posix_fadvise64,posix_fadvise64@GLIBC_2.2");
+__asm__(".symver posix_fallocate64,posix_fallocate64@GLIBC_2.2");
+__asm__(".symver pthread_cond_broadcast,pthread_cond_broadcast@GLIBC_2.0");
+__asm__(".symver pthread_cond_destroy,pthread_cond_destroy@GLIBC_2.0");
+__asm__(".symver pthread_cond_init,pthread_cond_init@GLIBC_2.0");
+__asm__(".symver pthread_cond_signal,pthread_cond_signal@GLIBC_2.0");
+__asm__(".symver pthread_cond_timedwait,pthread_cond_timedwait@GLIBC_2.0");
+__asm__(".symver pthread_cond_wait,pthread_cond_wait@GLIBC_2.0");
+__asm__(".symver regexec,regexec@GLIBC_2.0");
+__asm__(".symver rpc_createerr,rpc_createerr@GLIBC_2.0");
+__asm__(".symver sys_errlist,sys_errlist@GLIBC_2.0");
+__asm__(".symver sys_nerr,sys_nerr@GLIBC_2.0");
+__asm__(".symver sys_sigabbrev,sys_sigabbrev@GLIBC_2.0");
+__asm__(".symver sys_siglist,sys_siglist@GLIBC_2.0");
+__asm__(".symver vm86,vm86@GLIBC_2.0");
+__asm__(".symver __rpc_thread_createerr,__rpc_thread_createerr@GLIBC_2.2.3");
+__asm__(".symver __guard,__guard@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __gethostname_chk,__gethostname_chk@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver epoll_create,epoll_create@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __getdomainname_chk,__getdomainname_chk@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __vswprintf_chk,__vswprintf_chk@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __stpcpy_chk,__stpcpy_chk@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver timerfd_gettime,timerfd_gettime@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver inotify_init1,inotify_init1@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __wcstombs_chk,__wcstombs_chk@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __printf_chk,__printf_chk@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __fgetws_chk,__fgetws_chk@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __register_atfork,__register_atfork@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver gnu_dev_major,gnu_dev_major@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __vfwprintf_chk,__vfwprintf_chk@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __wcpcpy_chk,__wcpcpy_chk@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver open_wmemstream,open_wmemstream@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver inet6_opt_append,inet6_opt_append@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver timerfd_create,timerfd_create@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __swprintf_chk,__swprintf_chk@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver getipv4sourcefilter,getipv4sourcefilter@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __vwprintf_chk,__vwprintf_chk@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver readlinkat,readlinkat@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __wctomb_chk,__wctomb_chk@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __readlink_chk,__readlink_chk@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver setipv4sourcefilter,setipv4sourcefilter@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __isoc99_sscanf,__isoc99_sscanf@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __getlogin_r_chk,__getlogin_r_chk@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver sync_file_range,sync_file_range@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __open64_2,__open64_2@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver inet6_rth_init,inet6_rth_init@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver inet6_opt_next,inet6_opt_next@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __fxstatat64,__fxstatat64@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver unlinkat,unlinkat@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __fwprintf_chk,__fwprintf_chk@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __mempcpy_chk,__mempcpy_chk@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver epoll_wait,epoll_wait@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver mkfifoat,mkfifoat@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __isoc99_scanf,__isoc99_scanf@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __read_chk,__read_chk@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __fgetws_unlocked_chk,__fgetws_unlocked_chk@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __vsprintf_chk,__vsprintf_chk@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __wcsncpy_chk,__wcsncpy_chk@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __stack_chk_fail,__stack_chk_fail@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver inotify_rm_watch,inotify_rm_watch@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver xdr_quad_t,xdr_quad_t@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __sched_cpualloc,__sched_cpualloc@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __obstack_vprintf_chk,__obstack_vprintf_chk@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __isoc99_swscanf,__isoc99_swscanf@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __isoc99_vfwscanf,__isoc99_vfwscanf@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __sched_cpufree,__sched_cpufree@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver inet6_opt_finish,inet6_opt_finish@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __confstr_chk,__confstr_chk@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __wcsncat_chk,__wcsncat_chk@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver setsourcefilter,setsourcefilter@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver xdr_u_quad_t,xdr_u_quad_t@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __fread_unlocked_chk,__fread_unlocked_chk@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver eaccess,eaccess@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver inet6_option_alloc,inet6_option_alloc@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __openat64_2,__openat64_2@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver sched_setaffinity,sched_setaffinity@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver inet6_option_append,inet6_option_append@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver futimens,futimens@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver renameat,renameat@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __wmemset_chk,__wmemset_chk@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver inet6_opt_get_val,inet6_opt_get_val@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver unshare,unshare@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __isoc99_vsscanf,__isoc99_vsscanf@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver signalfd,signalfd@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver inet6_option_next,inet6_option_next@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver inet6_rth_add,inet6_rth_add@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver semtimedop,semtimedop@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver utimensat,utimensat@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver inet6_rth_segments,inet6_rth_segments@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __pread_chk,__pread_chk@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __syslog_chk,__syslog_chk@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver eventfd,eventfd@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __fgets_unlocked_chk,__fgets_unlocked_chk@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __getcwd_chk,__getcwd_chk@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver fchmodat,fchmodat@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver dup3,dup3@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __vprintf_chk,__vprintf_chk@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __fprintf_chk,__fprintf_chk@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __wmemcpy_chk,__wmemcpy_chk@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __isoc99_wscanf,__isoc99_wscanf@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __wcscpy_chk,__wcscpy_chk@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __isoc99_fscanf,__isoc99_fscanf@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __mbstowcs_chk,__mbstowcs_chk@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __dprintf_chk,__dprintf_chk@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __wmempcpy_chk,__wmempcpy_chk@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver symlinkat,symlinkat@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __memmove_chk,__memmove_chk@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __getwd_chk,__getwd_chk@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __vsnprintf_chk,__vsnprintf_chk@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver mkostemp64,mkostemp64@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver eventfd_read,eventfd_read@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver remap_file_pages,remap_file_pages@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __isoc99_vswscanf,__isoc99_vswscanf@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver fdopendir,fdopendir@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __openat_2,__openat_2@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __fgets_chk,__fgets_chk@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __strncpy_chk,__strncpy_chk@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __sched_cpucount,__sched_cpucount@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __mbsrtowcs_chk,__mbsrtowcs_chk@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __wcscat_chk,__wcscat_chk@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver inet6_option_space,inet6_option_space@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver sched_getaffinity,sched_getaffinity@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __open_2,__open_2@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver fchownat,fchownat@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver timerfd_settime,timerfd_settime@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver sched_getcpu,sched_getcpu@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __getgroups_chk,__getgroups_chk@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver inet6_opt_init,inet6_opt_init@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __snprintf_chk,__snprintf_chk@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver mkdirat,mkdirat@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __memset_chk,__memset_chk@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __strncat_chk,__strncat_chk@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver inet6_rth_space,inet6_rth_space@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __recv_chk,__recv_chk@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver inet6_rth_reverse,inet6_rth_reverse@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __stack_smash_handler,__stack_smash_handler@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __realpath_chk,__realpath_chk@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver qsort_r,qsort_r@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __obstack_printf_chk,__obstack_printf_chk@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver inet6_rth_getaddr,inet6_rth_getaddr@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver splice,splice@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver eventfd_write,eventfd_write@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver vmsplice,vmsplice@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver getsourcefilter,getsourcefilter@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __isoc99_vwscanf,__isoc99_vwscanf@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver epoll_ctl,epoll_ctl@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver gnu_dev_minor,gnu_dev_minor@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __memcpy_chk,__memcpy_chk@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __isoc99_vfscanf,__isoc99_vfscanf@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __stpncpy_chk,__stpncpy_chk@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver inet6_opt_find,inet6_opt_find@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __mbsnrtowcs_chk,__mbsnrtowcs_chk@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver strerror_l,strerror_l@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __fread_chk,__fread_chk@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __wcsnrtombs_chk,__wcsnrtombs_chk@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __wprintf_chk,__wprintf_chk@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver epoll_create1,epoll_create1@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __vfprintf_chk,__vfprintf_chk@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __vsyslog_chk,__vsyslog_chk@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver inotify_add_watch,inotify_add_watch@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __wcrtomb_chk,__wcrtomb_chk@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver epoll_pwait,epoll_pwait@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __strcpy_chk,__strcpy_chk@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __vdprintf_chk,__vdprintf_chk@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __vasprintf_chk,__vasprintf_chk@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __xpg_strerror_r,__xpg_strerror_r@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __wcpncpy_chk,__wcpncpy_chk@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver inet6_option_init,inet6_option_init@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __wmemmove_chk,__wmemmove_chk@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __sprintf_chk,__sprintf_chk@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver futimesat,futimesat@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __pread64_chk,__pread64_chk@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver strptime_l,strptime_l@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver lchmod,lchmod@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __chk_fail,__chk_fail@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __isoc99_vscanf,__isoc99_vscanf@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __wcsrtombs_chk,__wcsrtombs_chk@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver pipe2,pipe2@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __strcat_chk,__strcat_chk@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver faccessat,faccessat@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __asprintf_chk,__asprintf_chk@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver ppoll,ppoll@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __recvfrom_chk,__recvfrom_chk@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver inet6_opt_set_val,inet6_opt_set_val@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __ptsname_r_chk,__ptsname_r_chk@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __isoc99_fwscanf,__isoc99_fwscanf@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __gets_chk,__gets_chk@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver gnu_dev_makedev,gnu_dev_makedev@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __xmknodat,__xmknodat@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver inet6_option_find,inet6_option_find@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __ttyname_r_chk,__ttyname_r_chk@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __readlinkat_chk,__readlinkat_chk@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver dlmopen,dlmopen@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver dladdr1,dladdr1@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver dlinfo,dlinfo@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver pthread_mutexattr_getprotocol,pthread_mutexattr_getprotocol@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver pthread_mutex_setprioceiling,pthread_mutex_setprioceiling@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver pthread_mutexattr_setprioceiling,pthread_mutexattr_setprioceiling@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __pthread_unregister_cancel_restore,__pthread_unregister_cancel_restore@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver pthread_attr_setaffinity_np,pthread_attr_setaffinity_np@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __pthread_cleanup_routine,__pthread_cleanup_routine@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver pthread_condattr_getclock,pthread_condattr_getclock@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __pthread_register_cancel_defer,__pthread_register_cancel_defer@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __pthread_unwind_next,__pthread_unwind_next@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver pthread_timedjoin_np,pthread_timedjoin_np@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver pthread_setaffinity_np,pthread_setaffinity_np@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver pthread_mutex_getprioceiling,pthread_mutex_getprioceiling@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver pthread_mutexattr_getprioceiling,pthread_mutexattr_getprioceiling@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver pthread_attr_getaffinity_np,pthread_attr_getaffinity_np@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver pthread_barrierattr_getpshared,pthread_barrierattr_getpshared@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver pthread_condattr_setclock,pthread_condattr_setclock@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver pthread_tryjoin_np,pthread_tryjoin_np@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver pthread_setschedprio,pthread_setschedprio@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver pthread_getaffinity_np,pthread_getaffinity_np@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver pthread_mutexattr_setrobust_np,pthread_mutexattr_setrobust_np@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver pthread_mutexattr_getrobust_np,pthread_mutexattr_getrobust_np@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver pthread_mutexattr_setprotocol,pthread_mutexattr_setprotocol@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver pthread_mutex_consistent_np,pthread_mutex_consistent_np@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver ns_put16,ns_put16@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver ns_name_pton,ns_name_pton@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver ns_name_skip,ns_name_skip@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver ns_name_pack,ns_name_pack@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver ns_name_ntol,ns_name_ntol@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver ns_sprintrr,ns_sprintrr@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver ns_format_ttl,ns_format_ttl@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver ns_name_ntop,ns_name_ntop@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver ns_name_compress,ns_name_compress@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver ns_name_unpack,ns_name_unpack@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver ns_put32,ns_put32@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver ns_sprintrrf,ns_sprintrrf@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver ns_datetosecs,ns_datetosecs@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver ns_get16,ns_get16@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver ns_msg_getflag,ns_msg_getflag@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver ns_samedomain,ns_samedomain@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __p_rcode,__p_rcode@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver ns_parse_ttl,ns_parse_ttl@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver ns_get32,ns_get32@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver ns_skiprr,ns_skiprr@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver ns_parserr,ns_parserr@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver ns_name_rollback,ns_name_rollback@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver ns_samename,ns_samename@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver ns_name_uncompress,ns_name_uncompress@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver ns_subdomain,ns_subdomain@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver ns_makecanon,ns_makecanon@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver ns_initparse,ns_initparse@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver mq_open,mq_open@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver __mq_open_2,__mq_open_2@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver mq_timedsend,mq_timedsend@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver mq_notify,mq_notify@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver mq_receive,mq_receive@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver mq_close,mq_close@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver mq_getattr,mq_getattr@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver mq_send,mq_send@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver mq_unlink,mq_unlink@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver mq_setattr,mq_setattr@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver mq_timedreceive,mq_timedreceive@GLIBC_DONT_USE_THIS_SYMBOL");
+__asm__(".symver td_thr_tlsbase,td_thr_tlsbase@GLIBC_DONT_USE_THIS_SYMBOL");
diff --git a/tools/apbuild/buildlist b/tools/apbuild/buildlist
new file mode 100755
index 00000000..24e789fd
--- /dev/null
+++ b/tools/apbuild/buildlist
@@ -0,0 +1,48 @@
+#!/bin/bash
+
+# get a list of all symbols - YOU MUST RUN THIS SCRIPT WITH THE LATEST VERSIONS OF GLIBC
+# currently blacklists all newer than 2.3.0
+
+if [ -e syms ]; then rm syms; fi
+if [ -e allsym ]; then rm allsym; fi
+for f in /lib/*; do
+ if [ ! -f $f ]; then continue; fi
+ readelf -s --wide $f >>syms
+ objdump -T $f | grep "GLIBC_" | sed 's/\(.*\)GLIBC_//; s/)//' | grep -v PRIVATE | column -t >>allsym
+done
+
+
+# get a list of all symbol versions only available in 2.3+
+grep @@GLIBC_ syms | awk ' { print $8 } ' | sed 's/@@/ /; /GLIBC_P/d; s/GLIBC_//' | awk ' { if ($2 > 2.3) print $1 " " $2 } ' | column -t >glibc2.4.syms
+
+# select the symbols that already existed, but were obsoleted by 2.2+ versions
+cat glibc2.4.syms | awk '{print $1}' | while read; do grep $REPLY allsym; done | sed '/2\.4/d' >syms-to-header
+
+# select the latest symbols of that set
+# build a header from them
+cat syms-to-header | awk '{print $2 " " $1 }' | sort | uniq >output
+cat glibc2.4.syms | sort | uniq >> output
+
+cat output | sort | uniq | awk '{print $2 " " $1}' | sort -k2,1 | awk '{ if ($1 <= 2.3) print $1 " " $2 }' | column -t | sort -k2 | uniq -f1 >output2
+
+# output the symbols that are brand new to 2.3+, ie not the ones that had earlier versions
+cat glibc2.4.syms | awk '{ print $1 }' | while read; do if ! grep "$REPLY" output2 >/dev/null; then echo "DONT_USE_THIS_SYMBOL $REPLY" >>output2; fi; done;
+
+cat output2 | column -t | awk '{ print "__asm__(\".symver " $2 "," $2 "@GLIBC_" $1 "\");" }' > output
+
+# now remove dl_iterate_phdr as it's weak anyway (we should probably do this for all weak syms)
+cat output | sed 's/__asm__("\.symver dl_iterate_phdr.*//' >output2
+
+cat <<EOF >apsymbols.h
+/* apbuild embedded metadata */
+#define APBUILD_NOTE_METADATA(s) \
+ __asm__(".section .metadata, \"MS\", @note, 1\n\t.string \"" s "\"\n\t.previous\n\t")
+
+#ifdef APBUILD_VERSION
+APBUILD_NOTE_METADATA("apbuild.version=" APBUILD_VERSION);
+#endif
+
+/* apbuild generated symbol exclusion list */
+EOF
+cat output2 >> apsymbols.h
+rm output2
diff --git a/tools/apbuild/ctype.h b/tools/apbuild/ctype.h
new file mode 100644
index 00000000..2db84cc1
--- /dev/null
+++ b/tools/apbuild/ctype.h
@@ -0,0 +1,268 @@
+/* Copyright (C) 1991,92,93,95,96,97,98,99,2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/*
+ * ISO C99 Standard 7.4: Character handling <ctype.h>
+ */
+
+#ifndef _CTYPE_H
+#define _CTYPE_H 1
+
+#include <features.h>
+#include <bits/types.h>
+
+__BEGIN_DECLS
+
+#ifndef _ISbit
+/* These are all the characteristics of characters.
+ If there get to be more than 16 distinct characteristics,
+ many things must be changed that use `unsigned short int's.
+
+ The characteristics are stored always in network byte order (big
+ endian). We define the bit value interpretations here dependent on the
+ machine's byte order. */
+
+# include <endian.h>
+# if __BYTE_ORDER == __BIG_ENDIAN
+# define _ISbit(bit) (1 << (bit))
+# else /* __BYTE_ORDER == __LITTLE_ENDIAN */
+# define _ISbit(bit) ((bit) < 8 ? ((1 << (bit)) << 8) : ((1 << (bit)) >> 8))
+# endif
+
+enum
+{
+ _ISupper = _ISbit (0), /* UPPERCASE. */
+ _ISlower = _ISbit (1), /* lowercase. */
+ _ISalpha = _ISbit (2), /* Alphabetic. */
+ _ISdigit = _ISbit (3), /* Numeric. */
+ _ISxdigit = _ISbit (4), /* Hexadecimal numeric. */
+ _ISspace = _ISbit (5), /* Whitespace. */
+ _ISprint = _ISbit (6), /* Printing. */
+ _ISgraph = _ISbit (7), /* Graphical. */
+ _ISblank = _ISbit (8), /* Blank (usually SPC and TAB). */
+ _IScntrl = _ISbit (9), /* Control character. */
+ _ISpunct = _ISbit (10), /* Punctuation. */
+ _ISalnum = _ISbit (11) /* Alphanumeric. */
+};
+#endif /* ! _ISbit */
+
+/* These are defined in ctype-info.c.
+ The declarations here must match those in localeinfo.h.
+
+ These point into arrays of 384, so they can be indexed by any `unsigned
+ char' value [0,255]; by EOF (-1); or by any `signed char' value
+ [-128,-1). ISO C requires that the ctype functions work for `unsigned
+ char' values and for EOF; we also support negative `signed char' values
+ for broken old programs. The case conversion arrays are of `int's
+ rather than `unsigned char's because tolower (EOF) must be EOF, which
+ doesn't fit into an `unsigned char'. But today more important is that
+ the arrays are also used for multi-byte character sets. */
+extern __const unsigned short int *__ctype_b; /* Characteristics. */
+extern __const __int32_t *__ctype_tolower; /* Case conversions. */
+extern __const __int32_t *__ctype_toupper; /* Case conversions. */
+
+__asm__(".symver __ctype_b,__ctype_b@GLIBC_2.0");
+__asm__(".symver __ctype_tolower,__ctype_tolower@GLIBC_2.0");
+__asm__(".symver __ctype_toupper,__ctype_toupper@GLIBC_2.0");
+
+#define __isctype(c, type) \
+ (__ctype_b[(int) (c)] & (unsigned short int) type)
+
+#define __isascii(c) (((c) & ~0x7f) == 0) /* If C is a 7 bit value. */
+#define __toascii(c) ((c) & 0x7f) /* Mask off high bits. */
+
+#define __exctype(name) extern int name (int) __THROW
+
+/* The following names are all functions:
+ int isCHARACTERISTIC(int c);
+ which return nonzero iff C has CHARACTERISTIC.
+ For the meaning of the characteristic names, see the `enum' above. */
+__exctype (isalnum);
+__exctype (isalpha);
+__exctype (iscntrl);
+__exctype (isdigit);
+__exctype (islower);
+__exctype (isgraph);
+__exctype (isprint);
+__exctype (ispunct);
+__exctype (isspace);
+__exctype (isupper);
+__exctype (isxdigit);
+
+#ifdef __USE_ISOC99
+__exctype (isblank);
+#endif
+
+
+/* Return the lowercase version of C. */
+extern int tolower (int __c) __THROW;
+
+/* Return the uppercase version of C. */
+extern int toupper (int __c) __THROW;
+
+
+#if defined __USE_SVID || defined __USE_MISC || defined __USE_XOPEN
+
+/* Return nonzero iff C is in the ASCII set
+ (i.e., is no more than 7 bits wide). */
+extern int isascii (int __c) __THROW;
+
+/* Return the part of C that is in the ASCII set
+ (i.e., the low-order 7 bits of C). */
+extern int toascii (int __c) __THROW;
+
+/* These are the same as `toupper' and `tolower' except that they do not
+ check the argument for being in the range of a `char'. */
+__exctype (_toupper);
+__exctype (_tolower);
+#endif /* Use SVID or use misc. */
+
+/* This code is needed for the optimized mapping functions. */
+#define __tobody(c, f, a, args) \
+ (__extension__ \
+ ({ int __res; \
+ if (sizeof (c) > 1) \
+ { \
+ if (__builtin_constant_p (c)) \
+ { \
+ int __c = (c); \
+ __res = __c < -128 || __c > 255 ? __c : a[__c]; \
+ } \
+ else \
+ __res = f args; \
+ } \
+ else \
+ __res = a[(int) (c)]; \
+ __res; }))
+
+#ifndef __NO_CTYPE
+# define isalnum(c) __isctype((c), _ISalnum)
+# define isalpha(c) __isctype((c), _ISalpha)
+# define iscntrl(c) __isctype((c), _IScntrl)
+# define isdigit(c) __isctype((c), _ISdigit)
+# define islower(c) __isctype((c), _ISlower)
+# define isgraph(c) __isctype((c), _ISgraph)
+# define isprint(c) __isctype((c), _ISprint)
+# define ispunct(c) __isctype((c), _ISpunct)
+# define isspace(c) __isctype((c), _ISspace)
+# define isupper(c) __isctype((c), _ISupper)
+# define isxdigit(c) __isctype((c), _ISxdigit)
+
+# ifdef __USE_ISOC99
+# define isblank(c) __isctype((c), _ISblank)
+# endif
+
+# if __GNUC__ >= 2 && defined __OPTIMIZE__ && !defined __cplusplus
+# define tolower(c) __tobody (c, tolower, __ctype_tolower, (c))
+# define toupper(c) __tobody (c, toupper, __ctype_toupper, (c))
+# endif /* Optimizing gcc */
+
+# if defined __USE_SVID || defined __USE_MISC || defined __USE_XOPEN
+# define isascii(c) __isascii (c)
+# define toascii(c) __toascii (c)
+
+# define _tolower(c) ((int) __ctype_tolower[(int) (c)])
+# define _toupper(c) ((int) __ctype_toupper[(int) (c)])
+# endif
+
+#endif /* Not __NO_CTYPE. */
+
+
+#ifdef __USE_GNU
+/* The concept of one static locale per category is not very well
+ thought out. Many applications will need to process its data using
+ information from several different locales. Another application is
+ the implementation of the internationalization handling in the
+ upcoming ISO C++ standard library. To support this another set of
+ the functions using locale data exist which have an additional
+ argument.
+
+ Attention: all these functions are *not* standardized in any form.
+ This is a proof-of-concept implementation. */
+
+/* Structure for reentrant locale using functions. This is an
+ (almost) opaque type for the user level programs. */
+# include <xlocale.h>
+
+/* These definitions are similar to the ones above but all functions
+ take as an argument a handle for the locale which shall be used. */
+# define __isctype_l(c, type, locale) \
+ ((locale)->__ctype_b[(int) (c)] & (unsigned short int) type)
+
+# define __exctype_l(name) extern int name (int, __locale_t) __THROW
+
+/* The following names are all functions:
+ int isCHARACTERISTIC(int c, locale_t *locale);
+ which return nonzero iff C has CHARACTERISTIC.
+ For the meaning of the characteristic names, see the `enum' above. */
+__exctype_l (__isalnum_l);
+__exctype_l (__isalpha_l);
+__exctype_l (__iscntrl_l);
+__exctype_l (__isdigit_l);
+__exctype_l (__islower_l);
+__exctype_l (__isgraph_l);
+__exctype_l (__isprint_l);
+__exctype_l (__ispunct_l);
+__exctype_l (__isspace_l);
+__exctype_l (__isupper_l);
+__exctype_l (__isxdigit_l);
+
+__exctype_l (__isblank_l);
+
+
+/* Return the lowercase version of C in locale L. */
+extern int __tolower_l (int __c, __locale_t __l) __THROW;
+
+/* Return the uppercase version of C. */
+extern int __toupper_l (int __c, __locale_t __l) __THROW;
+
+# if __GNUC__ >= 2 && defined __OPTIMIZE__ && !defined __cplusplus
+# define __tolower_l(c, locale) \
+ __tobody (c, __tolower_l, (locale)->__ctype_tolower, (c, locale))
+# define __toupper_l(c, locale) \
+ __tobody (c, __toupper_l, (locale)->__ctype_toupper, (c, locale))
+# endif /* Optimizing gcc */
+
+
+# ifndef __NO_CTYPE
+# define __isalnum_l(c,l) __isctype_l((c), _ISalnum, (l))
+# define __isalpha_l(c,l) __isctype_l((c), _ISalpha, (l))
+# define __iscntrl_l(c,l) __isctype_l((c), _IScntrl, (l))
+# define __isdigit_l(c,l) __isctype_l((c), _ISdigit, (l))
+# define __islower_l(c,l) __isctype_l((c), _ISlower, (l))
+# define __isgraph_l(c,l) __isctype_l((c), _ISgraph, (l))
+# define __isprint_l(c,l) __isctype_l((c), _ISprint, (l))
+# define __ispunct_l(c,l) __isctype_l((c), _ISpunct, (l))
+# define __isspace_l(c,l) __isctype_l((c), _ISspace, (l))
+# define __isupper_l(c,l) __isctype_l((c), _ISupper, (l))
+# define __isxdigit_l(c,l) __isctype_l((c), _ISxdigit, (l))
+
+# define __isblank_l(c,l) __isctype_l((c), _ISblank, (l))
+
+# if defined __USE_SVID || defined __USE_MISC || defined __USE_XOPEN
+# define __isascii_l(c,l) __isascii(c)
+# define __toascii_l(c,l) __toascii(c)
+# endif
+
+# endif /* Not __NO_CTYPE. */
+
+#endif /* Use GNU. */
+
+__END_DECLS
+
+#endif /* ctype.h */
diff --git a/tools/apbuild/make-icons b/tools/apbuild/make-icons
new file mode 100755
index 00000000..32c0c600
--- /dev/null
+++ b/tools/apbuild/make-icons
@@ -0,0 +1,58 @@
+#!/bin/sh
+
+#
+# This script generates a directory and an automake fragment from an SVG
+# file. It's useful when you have an SVG and want to pre-render icons of
+# various sizes from it, then install them into the users icon theme.
+#
+# For autopackage users, put the following line in your specfile:
+#
+# installIcon share/icons/hicolor
+#
+# It uses rsvg to render the icons
+
+if [[ "$1" == "" ]] || [[ "$2" == "" ]] || [[ "$1" == "--help" ]] || [[ "$1" == "-h" ]]; then
+ echo "Usage: make-icons myprogram.svg type"
+ echo
+ echo "Generates a subdirectory called icons with an icon theme tree"
+ echo "in it. Also outputs some automake code you can copy/paste".
+ echo ""
+ echo "type is the type of icon and should be one of the following:"
+ echo "apps, mimetypes, actions, devices, filesystems"
+ echo "See FDO spec for details--you most likely want apps or mimetypes"
+ exit 0
+fi
+
+if ! which rsvg >/dev/null; then
+ # a part of librsvg
+ echo "make-icons: this script needs the rsvg program installed"
+ exit 1
+fi
+
+if [ ! -e $1 ]; then
+ echo "make-icons: the given file does not exist"
+ exit 1
+fi
+
+if [[ "$2" != "apps" && "$2" != "mimetypes" && "$2" != "actions" && "$2" != "devices" && "$2" != "filesystems" ]]; then
+ echo "make-icons: $2 is not a valid icon type. type should be one of these:"
+ echo "apps, mimetypes, actions, devices, filesystems"
+ echo "See FDO spec for details--you most likely want apps or mimetypes"
+ exit 1
+fi
+mkdir -p icons/scalable/$2
+cp $1 icons/scalable/$2
+
+newname="`basename $1`"
+echo "iconSVGdir = \$(datadir)/icons/hicolor/scalable/$2"
+echo "iconSVG_DATA = icons/scalable/$2/$newname"
+
+newname="${newname/.svg/}.png"
+
+
+for size in 128 64 48 24 16; do
+ mkdir -p icons/${size}x${size}/$2
+ rsvg --width=$size --height=$size $1 icons/${size}x${size}/$2/$newname
+ echo "icon${size}dir = \$(datadir)/icons/hicolor/${size}x${size}/$2"
+ echo "icon${size}_DATA = icons/${size}x${size}/$2/$newname"
+done
diff --git a/tools/apbuild/relaytool b/tools/apbuild/relaytool
new file mode 100755
index 00000000..40b6de03
--- /dev/null
+++ b/tools/apbuild/relaytool
@@ -0,0 +1,584 @@
+#!/bin/bash
+
+# relaytool 1.2
+# Copyright 2004-2005 Mike Hearn <mike@plan99.net>
+# Copyright 2005 Vincent Béron <vberon@mecano.gme.usherb.ca>
+# Copyright 2006 Psyche <psyche@ruidoabsurdo.com>
+# Copyright 2007 Taj Morton <tajmorton@gmail.com>
+#
+#############################################################################
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+#############################################################################
+#
+# TODO:
+# - Figure out how to grab the GOT addr on PowerPC
+# - Port to more archs
+# - Figure out a way to check if we're on an ELF platform or not,
+# maybe check for _GLOBAL_OFFSET_TABLE_ ?
+
+using_partial_map=false
+using_minimal_list=false
+using_multilink=false
+outdir="."
+
+if [[ "$1" == "--version" ]]; then
+ echo "Relaytool 1.11"
+ echo "Copyright 2004 Mike Hearn"
+ echo "Copyright 2005 Vincent Béron"
+ echo
+ echo "See $0 for license details."
+ exit 1
+fi
+
+if [[ "$@" == "" ]] || [[ "$1" == "--help" ]] || [[ "$1" == "-h" ]]; then
+ echo "Relaytool will generate a file that can be used instead of linking"
+ echo "directly against a library, which will dlopen the DSO at init time"
+ echo
+ echo "Usage: relaytool [OPTION]... [LINKER COMMAND]..."
+ echo
+ echo "Options:"
+ echo " --relay LIB If a matching -lLIB is found, generate a file"
+ echo " that can be used instead of linking directly to"
+ echo " LIB. The name of the file is echoed on stdout."
+ echo " Multiple --relay can be used together, a file will"
+ echo " be generated for each matching ones."
+ echo " --replace-all-libs Generate a file for every -lLIB parameter."
+ echo " --minimal-list OBJ_LIST Will look in OBJ_LIST for undefined symbols, and"
+ echo " generate a file creating only the needed symbols"
+ echo " for each LIB."
+ echo " --partial-map MAP_FILE Generate a file creating only the symbols contained"
+ echo " in MAP_FILE. Will apply to all further -lLIB"
+ echo " parameters, so in general is not suitable to"
+ echo " multiple libs in the same invocation of relaytool."
+ echo " --no-replace Echo -lLIB on stdout even if a --relay LIB is"
+ echo " found, so it'll be linked in normally."
+ echo " --multilink [SONAMES...] If a library has different SONAMES on different"
+ echo " Linux distributions you can specify the various"
+ echo " SONAMES that it's known by here. Relaytool will"
+ echo " attempt to load them (in the order provided) until"
+ echo " one if found. This cannot be used with multiple"
+ echo " --relay options. The first SONAME in the list will"
+ echo " be used as the name in the _is_present variable and"
+ echo " _symbol_is_present function."
+ echo " --out-dir DIRECTORY Write stub file to DIRECTORY instead of CWD."
+ echo "Linker commands:"
+ echo " -LPATH Add PATH to the list of paths to search for LIBs."
+ echo " -lLIB If a matching --relay LIB is found (or if"
+ echo " --replace-all-libs is specified), generate a file"
+ echo " that can be used instead of linking directly to"
+ echo " LIB. If there's no --relay LIB, echo -lLIB to"
+ echo " stdout."
+ echo " All other linker commands are passed as is to stdout."
+ echo "Other commands:"
+ echo " --help|-h Print this help."
+ echo " --version Print version information."
+ exit 1
+fi
+
+function error() {
+ echo $@ >/dev/stderr
+ exit 1
+}
+
+function readfinallink() {
+ link_name="$1"
+ while [ -L "$link_name" ]; do
+ new_name=$( readlink "$link_name" )
+ if [ "${new_name:0:1}" == "/" ]; then
+ link_name="$new_name"
+ else
+ link_name="`dirname "$link_name"`/$new_name"
+ fi
+ done
+ if [ -f "$link_name" ]; then
+ echo -n "$link_name"
+ exit 0
+ else
+ exit 1
+ fi
+}
+
+function relay() {
+ lib="$1"
+ if $using_multilink; then
+ libname=$( echo $( basename ${multilinklist[0]} ) | sed 's/\.so.*//' | tr '-' '_' | tr '.' '_' )
+ else
+ libname=$( echo $( basename "$lib" ) | sed 's/\.so.*//' | tr '-' '_' | tr '.' '_' )
+ fi
+ soname=$( objdump -x "$lib" |grep SONAME | awk '{print $2}' )
+ outfile="$outdir/`basename "$soname"`.stub.c"
+
+ echo -n "$outfile"
+
+ if $using_partial_map; then
+ functions=$( grep "^F " "$partial_map" | cut -d' ' -f2 )
+ variables=$( grep "^V " "$partial_map" | cut -d' ' -f2 )
+ else
+ functions=$( nm --extern-only -D "$lib" | awk '{ if (($2 == "T") || ($2 == "W")) print $3; }' | LC_ALL=C grep -v '\(\<_init\>\|\<_fini\>\)' | LC_ALL=C sort -u )
+ variables=$( nm --extern-only -D "$lib" | awk '{ if (($2 == "D") || ($2 == "G") || ($2 == "B") || ($2 == "V")) print $3; }' | LC_ALL=C sort -u )
+ fi
+ if $using_minimal_list; then
+ functions="$functions
+$( nm `echo "$object_list"` | awk '{ if ($1 == "U") print $2; }' | LC_ALL=C sort -u )"
+ functions=$( echo "$functions" | LC_ALL=C sort | LC_ALL=C uniq -d )
+ variables="$variables
+$( nm `echo "$object_list"` | awk '{ if ($1 == "U") print $2; }' | LC_ALL=C sort -u )"
+ variables=$( echo "$variables" | LC_ALL=C sort | LC_ALL=C uniq -d )
+ fi
+
+ if [ "$functions" == "" ] && [ "$variables" == "" ]; then
+ # Nothing will be used, so do nothing for that lib
+ exit 1
+ fi
+
+ cat <<EOF >"$outfile"
+/* automatically generated: `date` by `id -un`@`uname -n`, do not edit
+ *
+ * Built by relaytool, a program for building delay-load jumptables
+ * relaytool is (C) 2004 Mike Hearn <mike@navi.cx>
+ * See http://autopackage.org/ for details.
+ */
+#include <dlfcn.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <sys/mman.h>
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+static void **ptrs;
+static char *functions[] = {
+EOF
+
+ for s in $functions; do
+ echo " \"$s\"," >>"$outfile"
+ done
+ echo " 0" >>"$outfile"
+
+ cat <<EOF >>"$outfile"
+};
+
+static char *variables[] = {
+EOF
+
+ for s in $variables; do
+ echo " \"$s\"," >>"$outfile"
+ done
+ echo " 0" >>"$outfile"
+
+ cat <<EOF >>"$outfile"
+};
+
+/* 1 if present, 0 if not */
+int ${libname}_is_present = 0;
+
+static void *handle = 0;
+
+/* 1 if present, 0 if not, 0 with warning to stderr if lib not present or symbol not found */
+int ${libname}_symbol_is_present(char *s)
+{
+ int i;
+
+ if( !${libname}_is_present ) {
+ fprintf(stderr, "%s: relaytool: `basename "$lib"` not present so cannot check for symbol %s.\n", getenv("_"), s);
+ fprintf(stderr, "%s: relaytool: This probably indicates a bug in the application, please report.\n", getenv("_"));
+ return 0;
+ }
+
+ i = 0;
+ while (functions[i++]) if (!strcmp( functions[i - 1], s )) return ptrs[i - 1] > 0 ? 1 : 0;
+ i = 0;
+ while (variables[i++]) if (!strcmp( variables[i - 1], s )) return dlsym( handle, s ) > 0 ? 1 : 0;
+
+ fprintf( stderr, "%s: relaytool: %s is an unknown symbol in `basename "$lib"`.\n", getenv("_"), s );
+ fprintf( stderr, "%s: relaytool: If you are the developer of this program, please correct the symbol name or rerun relaytool.\n", getenv("_") );
+ return 0;
+}
+
+__attribute__((noreturn)) void _relaytool_stubcall_${libname}(int offset)
+{
+ fprintf( stderr, "%s: relaytool: stub call to `basename "${lib}"`:%s, aborting.\n", getenv("_"),
+ functions[offset / sizeof(void*)] );
+ exit( 1 );
+}
+
+#if defined( __i386__ )
+ #define FIXUP_GOT_RELOC(sym, addr) \\
+ asm("\tmovl %0, %%eax\n" \\
+ "\tmovl %%eax, " sym "@GOT(%%ebx)\n" : : "r" (addr));
+#elif defined( __powerpc__ )
+
+ /* The PowerPC ELF ABI is a twisted nightmare. Until I figure it out,
+ for now we don't support GOT fixup on this architecture */
+
+ #error Variables are not currently supported on PowerPC
+
+#elif defined( __x86_64__ )
+ #define FIXUP_GOT_RELOC(sym, addr) \\
+ asm("\tmovq %0, %%rax\n" \\
+ "\tmovq %%rax, " sym "@GOT(%%rbx)\n" : : "r" (addr));
+#else
+ #error Please define FIXUP_GOT_RELOC for your architecture
+#endif
+
+void __attribute__((constructor)) _relaytool_init_${libname}()
+{
+ int i = 0;
+
+ ptrs = malloc( sizeof(functions) );
+ memset( ptrs, 0, sizeof(functions) );
+EOF
+ if $using_multilink; then
+ echo -n "char *multilink_libs[${#multilinklist[@]}] = {" | cat >> "$outfile"
+ for l in ${multilinklist[@]}; do
+ echo -n "\"$l\"" | cat >> "$outfile";
+ if [[ "$l" != "${multilinklist[${#multilinklist[@]}-1]}" ]]; then
+ echo -n ", " | cat >> "$outfile";
+ else
+ echo "};" | cat >> "$outfile"
+ fi
+ done
+ echo 'int multilink_count=0;' | cat >> "$outfile"
+
+ echo 'while (!handle) {
+ handle = dlopen(multilink_libs[multilink_count++], RTLD_LAZY );' | cat >> "$outfile"
+ echo "if (multilink_count==${#multilinklist[@]}) break;}"| cat >> "$outfile"
+ else
+ echo "handle = dlopen( \"$soname\", RTLD_LAZY );" | cat >> "$outfile"
+ fi
+cat <<EOF >>"$outfile"
+ if (!handle) return;
+
+ ${libname}_is_present = 1;
+
+ /* build function jumptable */
+ while (functions[i++]) ptrs[i - 1] = dlsym( handle, functions[i - 1] );
+
+EOF
+
+ if [ "$variables" != "" ]; then echo " /* now fixup the global offset table for variable imports */" >>"$outfile"; fi
+ for s in $variables; do
+ echo " FIXUP_GOT_RELOC( \"$s\", dlsym(handle, \"$s\") );" >>"$outfile"
+ done
+
+ cat <<EOF >>"$outfile"
+}
+
+#if defined( __i386__ )
+
+#define JUMP_SLOT(name, index) \\
+ asm(".section .text." name ", \"ax\", @progbits\n" \\
+ ".globl " name "\n" \\
+ ".hidden " name "\n" \\
+ " .type " name ", @function\n" \\
+ name ":\n" \\
+ " movl ptrs, %eax\n" \\
+ " movl " #index "(%eax), %eax\n" \\
+ " test %eax, %eax\n" \\
+ " jnz JS" #index "\n" \\
+ " push \$" #index "\n" \\
+ " call _relaytool_stubcall_${libname}\n" \\
+ "JS" #index ": jmp *%eax\n");
+
+
+#elif defined( __x86_64__ )
+
+#define JUMP_SLOT(name, index) \\
+ asm(".section .text." name ", \"ax\", @progbits\n" \\
+ ".globl " name "\n" \\
+ ".hidden " name "\n" \\
+ " .type " name ", @function\n" \\
+ name ":\n" \\
+ " movq ptrs, %r11\n" \\
+ " movq " #index "(%r11), %r11\n" \\
+ " test %r11, %r11\n" \\
+ " jnz JS" #index "\n" \\
+ " push $" #index "\n" \\
+ " call _relaytool_stubcall_${libname}\n" \\
+ "JS" #index ": jmp *%r11\n");
+#elif defined( __powerpc__ )
+
+#define JUMP_SLOT(name, index) \ \
+ asm(".section .text." name ", \"ax\", @progbits\n" \\
+ ".globl " name "\n" \\
+ ".hidden " name "\n" \\
+ " .type " name ", @function\n" \\
+ name ":\n" \\
+ " lis r11, ptrs@ha\n" \\
+ " lwz r11, " #index "(r11)\n" \\
+ " cmpi cr0,r11,0\n" \\
+ " beq- 1f\n" \\
+ " mtctr r11\n" \\
+ " bctr\n" \\
+ "1: li r3, " #index "\n" \\
+ " b _relaytool_stubcall_${libname}\n" \\
+ );
+
+#else
+ #error Please define JUMP_SLOT for your architecture
+#endif
+
+/* define placeholders for the variable imports: their type doesn't matter,
+ however we must restrict ELF symbol scope to prevent the definition in the imported
+ shared library being bound to this dummy symbol (not all libs are compiled -Bsymbolic)
+ */
+EOF
+
+ for s in $variables; do
+ echo "int $s __attribute__(( visibility(\"hidden\") )) = -1;" >>"$outfile"
+ done
+
+ cat <<EOF >>"$outfile"
+
+/* define each jump slot in its own section. this increases generated code
+ size, but it means unused slots can be deleted by the linker when
+ --gc-sections is used.
+ */
+EOF
+
+# now generate the stubs
+ c=0
+ for s in $functions; do
+ echo "JUMP_SLOT(\"$s\", $[c * $arch_ptr_size]);" >>"$outfile"
+ (( c++ ))
+ done
+
+ echo >>"$outfile"
+
+ cat <<EOF >>"$outfile"
+
+#ifdef __cplusplus
+ }
+#endif
+EOF
+
+}
+
+function fakerelay() {
+ lib="$1"
+ libname=$( echo $( basename "$lib" ) | sed 's/\.so.*//' | tr '-' '_' | tr '.' '_' )
+ soname=$( objdump -x "$lib" |grep SONAME | awk '{print $2}' )
+ outfile="$outdir/`basename "$soname"`.stub.c"
+
+ echo -n "$outfile"
+
+ cat <<EOF >"$outfile"
+/* automatically generated: `date` by `id -un`@`uname -n`, do not edit
+ *
+ * Built by relaytool, a program for building delay-load jumptables
+ * relaytool is (C) 2004 Mike Hearn <mike@navi.cx>
+ * See http://autopackage.org/ for details.
+ */
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* 1 if present, 0 if not */
+int ${libname}_is_present = 1;
+
+/* 1 if present, 0 if not, 0 with warning to stderr if lib not present or symbol not found */
+int ${libname}_symbol_is_present(char * s)
+{
+ return 1;
+}
+
+#ifdef __cplusplus
+ }
+#endif
+EOF
+
+}
+
+no_replace=false
+replace_all=false
+arch_ok=false
+arch_ptr_size=0
+case `uname -m` in
+ i386 | i486 | i586 | i686 )
+ arch_ok=true
+ arch_ptr_size=4
+ ;;
+ x86_64)
+ arch_ok=true
+ arch_ptr_size=8
+ ;;
+esac
+
+searchpath=( "/usr/lib" "/usr/local/lib" "/lib" `pwd` )
+multilinklist=( )
+relaylist=( )
+
+# process arguments
+i=1
+while (( i <= $# )); do
+ a="${!i}"
+
+ if [ "${a:0:2}" == "-L" ]; then
+ searchpath[${#searchpath}]="${a:2}"
+ echo -n "$a " # copy to stdout
+
+ elif [ "$a" == "--replace-all-libs" ]; then
+ replace_all=true
+
+ elif [ "$a" == "--partial-map" ]; then
+ using_partial_map=true
+ (( i++ ))
+ partial_map="${!i}"
+
+ elif [ "$a" == "--minimal-list" ]; then
+ using_minimal_list=true
+ (( i++ ))
+ object_list="${!i}"
+
+ elif [ "$a" == "--no-replace" ]; then
+ no_replace=true
+
+ elif [ "$a" == "--multilink" ]; then
+ using_multilink=true
+ (( i++ ))
+ while [[ $i -lt $# && ${!i:0:2} != "--" ]]; do
+ multilinklist[${#multilinklist[@]}]="${!i}"
+ (( i++ ))
+ done
+ continue # $i has already been incremented, just continue with the loop
+
+ elif [ "$a" == "--relay" ]; then
+ (( i++ ))
+ relaylist[${#relaylist[@]}]="${!i}"
+
+ elif [ "$a" == "--out-dir" ]; then
+ (( i++ ))
+ outdir="${!i}"
+
+ elif [ "$a" == "-ldl" ]; then
+ # libdl won't ever be supported by relaytool, so just pass it to stdout
+ echo -n "$a "
+
+ elif [ "${a:0:2}" == "-l" ]; then
+ lib="${a:2}"
+
+ # is this lib meant to be relayed?
+ if $replace_all; then
+ found=true
+ else
+ found=false
+ for b in ${relaylist[@]}; do
+ if [ "$b" == "$lib" ]; then
+ found=true
+ fi
+ done
+ fi
+
+ if $found && $arch_ok; then
+
+ # yes, so let's find its absolute filename by checking in each search path directory
+ spfound=false
+ for d in ${searchpath[@]}; do
+ if [ -e "$d/lib$lib.so" ]; then
+
+ absname=$( readfinallink "$d/lib$lib.so" )
+ if [ $? != 0 ] || [ ! -f "$absname" ]; then
+ error broken symlink "$absname"
+ fi
+
+ stubfile=$( relay "$absname" )
+
+ # now we have to compile the stub
+ if [ $? == 0 ]; then
+ stubobj=$( echo "$stubfile" | sed 's/\.c$/\.o/' )
+ # remove -include flags from CFLAGS, if any
+ CFLAGS=$( echo $CFLAGS | sed 's/-include .*\.h//g' )
+ if [ -e /dev/tty ]; then
+ ${CC:-gcc} ${CFLAGS} -fPIC -c -o "$stubobj" "$stubfile" 2>/dev/tty
+ else
+ ${CC:-gcc} ${CFLAGS} -fPIC -c -o "$stubobj" "$stubfile"
+ fi
+ echo -n "$stubobj "
+ fi
+
+ if $no_replace; then
+ echo -n "-l$lib "
+ fi
+
+ spfound=true
+ break;
+ fi
+ done
+
+ if ! $spfound; then
+ error could not find "$lib" in search path
+ fi
+ elif $found && ! $arch_ok; then
+ # yes, so let's find its absolute filename by checking in each search path directory
+ spfound=false
+ for d in ${searchpath[@]}; do
+ if [ -e "$d/lib$lib.so" ]; then
+
+ absname=$( readfinallink "$d/lib$lib.so" )
+ if [ $? != 0 ] || [ ! -f "$absname" ]; then
+ error broken symlink "$absname"
+ fi
+
+ # Create a stub C source that just contains dummy
+ # libwhatever_... support functions
+ stubfile=$( fakerelay "$absname" )
+
+ # now we have to compile the stub
+ if [ $? == 0 ]; then
+ stubobj=$( echo "$stubfile" | sed 's/\.c$/\.o/' )
+ # remove -include flags from CFLAGS, if any
+ CFLAGS=$( echo $CFLAGS | sed 's/-include .*\.h//g' )
+ if [ -e /dev/tty ]; then
+ ${CC:-gcc} ${CFLAGS} -fPIC -c -o "$stubobj" "$stubfile" 2>/dev/tty
+ else
+ ${CC:-gcc} ${CFLAGS} -fPIC -c -o "$stubobj" "$stubfile"
+ fi
+ echo -n "$stubobj "
+ fi
+
+ if $no_replace; then
+ echo -n "-l$lib "
+ fi
+
+ spfound=true
+ break;
+ fi
+ done
+
+ if ! $spfound; then
+ error could not find "$lib" in search path
+ fi
+ else
+ echo -n "$a "
+ fi
+
+ else
+ # just copy whatever we don't recognise
+ echo -n "$a "
+ fi
+
+ (( i++ ))
+done
+echo
diff --git a/tools/apbuild/relaytool.m4 b/tools/apbuild/relaytool.m4
new file mode 100644
index 00000000..f8f20f98
--- /dev/null
+++ b/tools/apbuild/relaytool.m4
@@ -0,0 +1,28 @@
+dnl Usage: RELAYTOOL(LIBRARY_NAME, LIBS, CFLAGS, ACTION-IF-WEAK-LINK-IS-POSSIBLE)
+
+dnl Example:
+dnl RELAYTOOL("gtkspell", GTKSPELL_LIBS, GTKSPELL_CFLAGS, gtkspell_weak=yes)
+dnl Will modify GTKSPELL_LIBS to include a call to relaytool if available
+dnl or if not, will modify GTKSPELL_CFLAGS to include -D switches to define
+dnl libgtkspell_is_present=1 and libgtkspell_symbol_is_present=1
+
+AC_DEFUN([RELAYTOOL], [
+ if test -z "$RELAYTOOL_PROG"; then
+ AC_PATH_PROG(RELAYTOOL_PROG, relaytool, no)
+ fi
+
+ AC_MSG_CHECKING(whether we can weak link $1)
+
+ _RELAYTOOL_PROCESSED_NAME=`echo "$1" | sed 's/-/_/g;s/\./_/g;'`
+ _RELAYTOOL_UPPER_NAME=`echo $_RELAYTOOL_PROCESSED_NAME | tr '[[:lower:]]' '[[:upper:]]'`
+
+ if test "$RELAYTOOL_PROG" = "no"; then
+ AC_MSG_RESULT(no)
+ $3="-DRELAYTOOL_${_RELAYTOOL_UPPER_NAME}='static const int lib${_RELAYTOOL_PROCESSED_NAME}_is_present = 1; static int __attribute__((unused)) lib${_RELAYTOOL_PROCESSED_NAME}_symbol_is_present(char *m) { return 1; }' $$3"
+ else
+ AC_MSG_RESULT(yes)
+ $2="-Wl,--gc-sections \`relaytool --relay $1 $$2\`"
+ $3="-DRELAYTOOL_${_RELAYTOOL_UPPER_NAME}='extern int lib${_RELAYTOOL_PROCESSED_NAME}_is_present; extern int lib${_RELAYTOOL_PROCESSED_NAME}_symbol_is_present(char *s);' $$3"
+ $4
+ fi
+])
diff --git a/tools/apbuild/scandeps b/tools/apbuild/scandeps
new file mode 100755
index 00000000..7d057129
--- /dev/null
+++ b/tools/apbuild/scandeps
@@ -0,0 +1,137 @@
+#!/usr/bin/env perl
+use strict;
+use IPC::Open2;
+
+if ($ARGV[0] eq '--version') {
+ print "scandeps version 1.0\n";
+ print "Copright (c) 2005 Hongli Lai\n";
+ print "Licensed under the GNU General Public License v2.\n";
+ exit;
+} elsif ($ARGV[0] eq '--help') {
+ print "Usage: scandeps [FILES...]\n";
+ print "This script scans ELF binaries' library dependancies and prints a nice report\n" .
+ "of the dependancies.\n";
+ exit;
+}
+
+
+# First, generate a list of binaries. Either scan user-specified files,
+# or scan all files in the current directory (including subfolders).
+my @files;
+
+if (@ARGV > 0) {
+ # Scan user-specified files
+ @files = @ARGV;
+} else {
+ # Scan directory recursively
+ @files = scandir(".");
+}
+
+# Now get the dependancies for all binaries
+# %fileDeps: hash which contains a list of dependancies. The filename is the key.
+# %depFiles: hash which contains a list of files. The dependancy is the key.
+my (%fileDeps, %depFiles);
+getdeps(\%fileDeps, \%depFiles, \@files);
+
+print "Common dependancies:\n";
+foreach my $dep (keys %depFiles) {
+ if (@{$depFiles{$dep}} == @files) {
+ print " $dep\n";
+ }
+}
+print "\n";
+
+print "All dependancies:\n";
+my @keys = keys %depFiles;
+@keys = sort { @{$depFiles{$b}} - @{$depFiles{$a}} } @keys;
+foreach my $dep (@keys) {
+ my $num = scalar(@{$depFiles{$dep}});
+ my $word = ($num > 1) ? "files" : "file";
+ printf " %-40s (used by %3d $word)\n", $dep, $num;
+}
+
+print "\n";
+print "Dependancies and associated binaries:\n";
+foreach my $dep (@keys) {
+ print " $dep:\n";
+ if (@{$depFiles{$dep}} == @files) {
+ print " All files depend on this library.\n";
+ } else {
+ foreach my $file (@{$depFiles{$dep}}) {
+ print " $file\n";
+ }
+ }
+ print "\n";
+}
+
+
+##################################
+
+sub fatal {
+ print STDERR $_[0];
+ exit 1;
+}
+
+sub isELF {
+ my ($f, $data);
+
+ if (!open($f, $_[0])) {
+ print STDERR "Warning: cannot open file '$_[0]' for reading.\n";
+ return 0;
+ }
+
+ binmode $f;
+ sysread $f, $data, 4;
+ close $f;
+ return $data eq "\177ELF";
+}
+
+sub scandir {
+ my $d;
+
+ if (!opendir($d, $_[0])) {
+ print STDERR "Warning: cannot open directory '$_[0]' for reading.\n";
+ return;
+ }
+
+ my @files;
+ foreach my $file (readdir($d)) {
+ next if ($file eq "." || $file eq "..");
+
+ $file = "$_[0]/$file";
+ if (-d $file) {
+ # Recurse into subdirectory
+ push @files, scandir("$file");
+
+ } elsif (-f $file && -x $file && isELF($file)) {
+ push @files, $file;
+ }
+ }
+ closedir($d);
+ return @files;
+}
+
+sub getdeps {
+ my ($fileDeps, $depFiles, $files) = @_;
+ my ($r, $w);
+ if (!open2($r, $w, 'objdump', '-p', @{$files})) {
+ fatal("Cannot communicate with objdump.\n");
+ }
+ close $w;
+
+ my $currentFile;
+ foreach my $line (<$r>) {
+ if ($line =~ /^(.+):[ \t]+file format /) {
+ $currentFile = $1;
+ $currentFile =~ s/^.\///;
+
+ } elsif ($line =~ /NEEDED[ \t]+(.+)$/) {
+ $fileDeps->{$currentFile} = [] if (!exists $fileDeps->{$currentFile});
+ push @{$fileDeps->{$currentFile}}, $1;
+
+ $depFiles->{$1} = [] if (!exists $depFiles->{$1});
+ push @{$depFiles->{$1}}, $currentFile;
+ }
+ }
+ close $r;
+}
diff --git a/tools/apbuild/test-app/randomapp1.c b/tools/apbuild/test-app/randomapp1.c
new file mode 100644
index 00000000..70252276
--- /dev/null
+++ b/tools/apbuild/test-app/randomapp1.c
@@ -0,0 +1,16 @@
+#include <stdio.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <fnmatch.h>
+
+int main() {
+ char *respath = malloc(PATH_MAX);
+ unsigned char c = (unsigned char)"c";
+
+ printf("foo\n");
+ printf("%d\n", isalpha(c));
+ realpath("/some/path", respath);
+ fnmatch ("foo", "bar", 0);
+ return 0;
+}
diff --git a/tools/pluginfo/Makefile b/tools/pluginfo/Makefile
new file mode 100644
index 00000000..108e47e7
--- /dev/null
+++ b/tools/pluginfo/Makefile
@@ -0,0 +1,9 @@
+#CC=../apbuild/apgcc
+CC=gcc
+CFLAGS=-Wall
+LDFLAGS=-lpthread -ldl -lm
+
+pluginfo: pluginfo.o
+
+clean:
+ rm *.o pluginfo
diff --git a/tools/pluginfo/pluginfo.c b/tools/pluginfo/pluginfo.c
new file mode 100644
index 00000000..d5d20de2
--- /dev/null
+++ b/tools/pluginfo/pluginfo.c
@@ -0,0 +1,77 @@
+/*
+ DeaDBeeF - ultimate music player for GNU/Linux systems with X11
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <dlfcn.h>
+#include "../../deadbeef.h"
+
+int
+main (int argc, char *argv[]) {
+ char d_name[256];
+ void *handle;
+ size_t l;
+
+ if (argc <= 1) {
+ fprintf (stderr, "usage: pluginfo plugin.so\n");
+ exit (-1);
+ }
+ char *slash = strrchr (argv[1], '/');
+ if (!slash) {
+ slash = argv[1];
+ }
+ else {
+ slash++;
+ }
+ l = strlen (slash);
+ if (l < 3 || strcasecmp (&slash[l-3], ".so")) {
+ fprintf (stderr, "pluginfo: invalid fname %s\n", argv[1]);
+ exit (-1);
+ }
+
+ strcpy (d_name, slash);
+
+ handle = dlopen (argv[1], RTLD_NOW);
+ if (!handle) {
+ fprintf (stderr, "dlopen error: %s\n", dlerror ());
+ exit (-1);
+ }
+ d_name[l-3] = 0;
+ strcat (d_name, "_load");
+ DB_plugin_t *(*plug_load)(DB_functions_t *api) = dlsym (handle, d_name);
+ if (!plug_load) {
+ fprintf (stderr, "pluginfo: dlsym error: %s\n", dlerror ());
+ dlclose (handle);
+ exit (-1);
+ }
+
+ DB_plugin_t *plug = plug_load ((DB_functions_t *)0xdeadbeef);
+ printf ("type=\"%d\"\n", plug->type);
+ printf ("api_version=\"%d.%d\"\n", plug->api_vmajor, plug->api_vminor);
+ printf ("version=\"%d.%d\"\n", plug->version_major, plug->version_minor);
+ printf ("id=\"%s\"\n", plug->id);
+ printf ("name=\"%s\"\n", plug->name);
+ printf ("descr=\"%s\"\n", plug->descr);
+ printf ("author=\"%s\"\n", plug->author);
+ printf ("email=\"%s\"\n", plug->email);
+ printf ("website=\"%s\"\n", plug->website);
+
+ dlclose (handle);
+ return 0;
+}
diff --git a/translators.txt b/translators.txt
index c8745820..9a628e40 100644
--- a/translators.txt
+++ b/translators.txt
@@ -1,7 +1,19 @@
+Belarusian
+ Максім Тамковіч <quendimax@tut.by>
+
Bengali
Ummey Salma Snigdha <snighda@ankur.org.bd>
Israt Jahan <israt@ankur.org.bd>
+Bulgarian
+ Радослав <Rec.ku@hotmail.com>
+
+Catalan
+ sisco <sisco.garcia@ubuntu.cat>
+
+Chinese (Simplified)
+ Yinghua_Wang <wantinghard@gmail.com>
+
Danish
Joe Hansen <joedalton2@yahoo.dk>
@@ -11,6 +23,9 @@ German
Greek
Giorgos Koutsikos <ragecryx@yahoo.gr>, 2010
+Hungarian
+ Peter Polonkai <polesz@nedudu.hu>
+
English (United Kingdom)
Steve (Yorvyk) Cook <yorvik.ubunto@googlemail.com>
@@ -47,6 +62,9 @@ Kazakh
Khmer
SatyaN <satyathavy@gmail.com>
+Luganda
+ kizito <kbirabwa@yahoo.co.uk>
+
Dutch
depaz <depazzz@gmail.com>
@@ -75,6 +93,9 @@ Serbian (latin)
Swedish
Martin <brother@bsnet.se>
+Turkish
+ bahadiroglu <bahadiroglu33@gmail.com>
+
Ukrainian
Yarema aka Knedlyk <yupadmin@gmail.com>
diff --git a/u8_lc_map.h b/u8_lc_map.h
index c3c5da49..4963f7b8 100644
--- a/u8_lc_map.h
+++ b/u8_lc_map.h
@@ -1,6 +1,6 @@
/* C code produced by gperf version 3.0.4 */
/* Command-line: gperf -c -t -H u8_lc_hash -N u8_lc_in_word_set u8_lc_map.txt */
-/* Computed positions: -k'1-2' */
+/* Computed positions: -k'1-2,$' */
#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
&& ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
@@ -35,12 +35,12 @@ struct u8_case_map_t {
const char *lower;
};
-#define TOTAL_KEYWORDS 49
-#define MIN_WORD_LENGTH 2
-#define MAX_WORD_LENGTH 2
-#define MIN_HASH_VALUE 0
-#define MAX_HASH_VALUE 67
-/* maximum key range = 68, duplicates = 0 */
+#define TOTAL_KEYWORDS 1007
+#define MIN_WORD_LENGTH 1
+#define MAX_WORD_LENGTH 4
+#define MIN_HASH_VALUE 1
+#define MAX_HASH_VALUE 2519
+/* maximum key range = 2519, duplicates = 0 */
#ifdef __GNUC__
__inline
@@ -49,42 +49,54 @@ __inline
inline
#endif
#endif
-/*ARGSUSED*/
static unsigned int
u8_lc_hash (str, len)
register const char *str;
register unsigned int len;
{
- static unsigned char asso_values[] =
+ static unsigned short asso_values[] =
{
- 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 68, 33, 60,
- 68, 68, 28, 23, 18, 13, 8, 3, 62, 68,
- 68, 61, 68, 68, 62, 50, 57, 40, 52, 47,
- 30, 42, 20, 37, 10, 32, 0, 27, 22, 17,
- 12, 7, 2, 61, 56, 51, 46, 41, 36, 31,
- 26, 21, 16, 11, 6, 1, 68, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 68, 5, 68, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 68, 0, 68,
- 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 68, 68
+ 2520, 2520, 2520, 2520, 2520, 2520, 2520, 2520, 2520, 2520,
+ 2520, 2520, 2520, 2520, 2520, 2520, 2520, 2520, 2520, 2520,
+ 2520, 2520, 2520, 2520, 2520, 2520, 2520, 2520, 2520, 2520,
+ 2520, 2520, 2520, 2520, 2520, 2520, 2520, 2520, 2520, 2520,
+ 2520, 2520, 2520, 2520, 2520, 2520, 2520, 2520, 2520, 2520,
+ 2520, 2520, 2520, 2520, 2520, 2520, 2520, 2520, 2520, 2520,
+ 2520, 2520, 2520, 2520, 2520, 135, 130, 125, 120, 115,
+ 110, 105, 100, 95, 90, 85, 80, 75, 70, 65,
+ 60, 55, 50, 45, 40, 35, 30, 25, 20, 15,
+ 0, 2520, 2520, 2520, 2520, 2520, 2520, 2520, 2520, 2520,
+ 2520, 2520, 2520, 2520, 2520, 2520, 2520, 2520, 2520, 2520,
+ 2520, 2520, 2520, 2520, 2520, 2520, 2520, 2520, 2520, 2520,
+ 2520, 2520, 2520, 2520, 2520, 2520, 2520, 2520, 973, 70,
+ 3, 662, 532, 480, 232, 540, 137, 920, 155, 785,
+ 215, 421, 405, 275, 42, 420, 20, 665, 2, 475,
+ 512, 765, 201, 860, 135, 720, 195, 961, 370, 882,
+ 676, 991, 310, 825, 6, 858, 136, 876, 835, 85,
+ 75, 362, 40, 10, 345, 1015, 741, 770, 901, 50,
+ 406, 500, 976, 511, 900, 742, 645, 257, 81, 457,
+ 975, 775, 191, 796, 25, 15, 170, 425, 620, 750,
+ 5, 0, 565, 460, 875, 867, 105, 550, 405, 580,
+ 155, 320, 765, 660, 2520, 2520, 2520, 2520, 2520, 2520,
+ 2520, 2520, 2520, 2520, 2520, 0, 390, 2520, 2520, 2520,
+ 2520, 2520, 2520, 2520, 5, 2520, 2520, 2520, 2520, 340,
+ 30, 2520, 2520, 2520, 2520, 2520, 2520, 2520, 2520, 2520,
+ 2520, 2520, 2520, 2520, 2520, 2520, 2520, 2520, 2520, 2520,
+ 2520, 2520, 2520, 2520, 2520, 2520, 2520, 2520, 2520, 2520,
+ 2520, 2520
};
- return asso_values[(unsigned char)str[1]] + asso_values[(unsigned char)str[0]];
+ register int hval = len;
+
+ switch (hval)
+ {
+ default:
+ hval += asso_values[(unsigned char)str[1]+16];
+ /*FALLTHROUGH*/
+ case 1:
+ hval += asso_values[(unsigned char)str[0]];
+ break;
+ }
+ return hval + asso_values[(unsigned char)str[len - 1]];
}
#ifdef __GNUC__
@@ -100,117 +112,2585 @@ u8_lc_in_word_set (str, len)
{
static struct u8_case_map_t wordlist[] =
{
-#line 35 "u8_lc_map.txt"
- {"\320\234", "м"},
-#line 54 "u8_lc_map.txt"
- {"\320\257", "я"},
-#line 41 "u8_lc_map.txt"
- {"\320\242", "т"},
+ {""},
+#line 31 "u8_lc_map.txt"
+ {"Z", "z"},
+ {""}, {""}, {""},
+#line 539 "u8_lc_map.txt"
+ {"\341\271\224", "ṕ"},
+#line 530 "u8_lc_map.txt"
+ {"\341\271\202", "ṃ"},
+ {""}, {""},
+#line 547 "u8_lc_map.txt"
+ {"\341\271\244", "ṥ"},
+#line 507 "u8_lc_map.txt"
+ {"\341\270\224", "ḕ"},
+#line 498 "u8_lc_map.txt"
+ {"\341\270\202", "ḃ"},
+ {""}, {""},
+#line 515 "u8_lc_map.txt"
+ {"\341\270\244", "ḥ"},
+#line 194 "u8_lc_map.txt"
+ {"\310\224", "ȕ"},
+ {""}, {""}, {""}, {""},
+#line 917 "u8_lc_map.txt"
+ {"\352\235\224", "ꝕ"},
+#line 908 "u8_lc_map.txt"
+ {"\352\235\202", "ꝃ"},
+ {""},
+#line 538 "u8_lc_map.txt"
+ {"\341\271\222", "ṓ"},
+#line 925 "u8_lc_map.txt"
+ {"\352\235\244", "ꝥ"},
+#line 52 "u8_lc_map.txt"
+ {"\303\224", "ô"},
+ {""}, {""},
+#line 506 "u8_lc_map.txt"
+ {"\341\270\222", "ḓ"},
+#line 463 "u8_lc_map.txt"
+ {"\341\202\244", "ⴄ"},
+#line 185 "u8_lc_map.txt"
+ {"\310\202", "ȃ"},
+#line 30 "u8_lc_map.txt"
+ {"Y", "y"},
+ {""},
+#line 472 "u8_lc_map.txt"
+ {"\341\202\255", "ⴍ"},
+ {""}, {""}, {""}, {""},
+#line 916 "u8_lc_map.txt"
+ {"\352\235\222", "ꝓ"},
+ {""},
+#line 34 "u8_lc_map.txt"
+ {"\303\202", "â"},
+#line 29 "u8_lc_map.txt"
+ {"X", "x"},
+ {""},
+#line 551 "u8_lc_map.txt"
+ {"\341\271\254", "ṭ"},
+ {""},
+#line 537 "u8_lc_map.txt"
+ {"\341\271\220", "ṑ"},
+ {""}, {""},
+#line 519 "u8_lc_map.txt"
+ {"\341\270\254", "ḭ"},
+ {""},
+#line 505 "u8_lc_map.txt"
+ {"\341\270\220", "ḑ"},
+#line 28 "u8_lc_map.txt"
+ {"W", "w"},
+ {""}, {""},
+#line 894 "u8_lc_map.txt"
+ {"\352\234\244", "ꜥ"},
+ {""}, {""}, {""},
+#line 929 "u8_lc_map.txt"
+ {"\352\235\254", "ꝭ"},
+ {""},
+#line 915 "u8_lc_map.txt"
+ {"\352\235\220", "ꝑ"},
+#line 27 "u8_lc_map.txt"
+ {"V", "v"},
+ {""},
+#line 471 "u8_lc_map.txt"
+ {"\341\202\254", "ⴌ"},
+ {""}, {""}, {""}, {""}, {""}, {""}, {""},
+#line 26 "u8_lc_map.txt"
+ {"U", "u"},
+ {""},
+#line 478 "u8_lc_map.txt"
+ {"\341\202\263", "ⴓ"},
+ {""}, {""}, {""}, {""},
+#line 550 "u8_lc_map.txt"
+ {"\341\271\252", "ṫ"},
+ {""}, {""},
+#line 25 "u8_lc_map.txt"
+ {"T", "t"},
+ {""},
+#line 518 "u8_lc_map.txt"
+ {"\341\270\252", "ḫ"},
+#line 559 "u8_lc_map.txt"
+ {"\341\271\274", "ṽ"},
+#line 891 "u8_lc_map.txt"
+ {"\352\232\224", "ꚕ"},
+#line 882 "u8_lc_map.txt"
+ {"\352\232\202", "ꚃ"},
+ {""},
+#line 898 "u8_lc_map.txt"
+ {"\352\234\254", "ꜭ"},
+#line 527 "u8_lc_map.txt"
+ {"\341\270\274", "ḽ"},
+ {""},
+#line 24 "u8_lc_map.txt"
+ {"S", "s"},
+ {""},
+#line 928 "u8_lc_map.txt"
+ {"\352\235\252", "ꝫ"},
+ {""},
+#line 868 "u8_lc_map.txt"
+ {"\352\231\224", "ꙕ"},
+#line 859 "u8_lc_map.txt"
+ {"\352\231\202", "ꙃ"},
+ {""},
+#line 469 "u8_lc_map.txt"
+ {"\341\202\252", "ⴊ"},
+#line 876 "u8_lc_map.txt"
+ {"\352\231\244", "ꙥ"},
+ {""},
+#line 23 "u8_lc_map.txt"
+ {"R", "r"},
+ {""},
+#line 890 "u8_lc_map.txt"
+ {"\352\232\222", "ꚓ"},
+#line 487 "u8_lc_map.txt"
+ {"\341\202\274", "ⴜ"},
+ {""}, {""}, {""},
+#line 468 "u8_lc_map.txt"
+ {"\341\202\251", "ⴉ"},
+ {""}, {""},
+#line 22 "u8_lc_map.txt"
+ {"Q", "q"},
+ {""},
+#line 867 "u8_lc_map.txt"
+ {"\352\231\222", "ꙓ"},
+ {""},
+#line 236 "u8_lc_map.txt"
+ {"\316\224", "δ"},
{""}, {""},
+#line 690 "u8_lc_map.txt"
+ {"\341\276\255", "ᾥ"},
+ {""}, {""},
+#line 21 "u8_lc_map.txt"
+ {"P", "p"},
+ {""},
+#line 897 "u8_lc_map.txt"
+ {"\352\234\252", "ꜫ"},
+ {""},
+#line 889 "u8_lc_map.txt"
+ {"\352\232\220", "ꚑ"},
+ {""}, {""},
+#line 206 "u8_lc_map.txt"
+ {"\310\254", "ȭ"},
+#line 905 "u8_lc_map.txt"
+ {"\352\234\274", "ꜽ"},
+ {""},
+#line 20 "u8_lc_map.txt"
+ {"O", "o"},
+ {""},
+#line 880 "u8_lc_map.txt"
+ {"\352\231\254", "ꙭ"},
+ {""},
+#line 866 "u8_lc_map.txt"
+ {"\352\231\220", "ꙑ"},
+ {""}, {""},
+#line 542 "u8_lc_map.txt"
+ {"\341\271\232", "ṛ"},
+#line 548 "u8_lc_map.txt"
+ {"\341\271\246", "ṧ"},
+#line 533 "u8_lc_map.txt"
+ {"\341\271\210", "ṉ"},
+#line 19 "u8_lc_map.txt"
+ {"N", "n"},
+ {""},
+#line 510 "u8_lc_map.txt"
+ {"\341\270\232", "ḛ"},
+#line 516 "u8_lc_map.txt"
+ {"\341\270\246", "ḧ"},
+#line 501 "u8_lc_map.txt"
+ {"\341\270\210", "ḉ"},
+ {""}, {""},
+#line 689 "u8_lc_map.txt"
+ {"\341\276\254", "ᾤ"},
+ {""}, {""},
+#line 18 "u8_lc_map.txt"
+ {"M", "m"},
+ {""},
+#line 920 "u8_lc_map.txt"
+ {"\352\235\232", "ꝛ"},
+#line 926 "u8_lc_map.txt"
+ {"\352\235\246", "ꝧ"},
+#line 911 "u8_lc_map.txt"
+ {"\352\235\210", "ꝉ"},
+ {""}, {""},
+#line 534 "u8_lc_map.txt"
+ {"\341\271\212", "ṋ"},
+#line 465 "u8_lc_map.txt"
+ {"\341\202\246", "ⴆ"},
+ {""},
+#line 17 "u8_lc_map.txt"
+ {"L", "l"},
+ {""},
+#line 502 "u8_lc_map.txt"
+ {"\341\270\212", "ḋ"},
+ {""},
+#line 348 "u8_lc_map.txt"
+ {"\322\224", "ҕ"},
+ {""}, {""},
+#line 879 "u8_lc_map.txt"
+ {"\352\231\252", "ꙫ"},
+ {""}, {""},
+#line 16 "u8_lc_map.txt"
+ {"K", "k"},
+ {""},
+#line 912 "u8_lc_map.txt"
+ {"\352\235\212", "ꝋ"},
+ {""}, {""}, {""}, {""}, {""}, {""},
+#line 72 "u8_lc_map.txt"
+ {"\304\224", "ĕ"},
+#line 15 "u8_lc_map.txt"
+ {"J", "j"},
+ {""},
+#line 687 "u8_lc_map.txt"
+ {"\341\276\252", "ᾢ"},
+#line 895 "u8_lc_map.txt"
+ {"\352\234\246", "ꜧ"},
+ {""}, {""}, {""}, {""},
+#line 697 "u8_lc_map.txt"
+ {"\341\276\274", "ᾳ"},
+ {""},
+#line 14 "u8_lc_map.txt"
+ {"I", "i"},
+ {""},
+#line 686 "u8_lc_map.txt"
+ {"\341\276\251", "ᾡ"},
+ {""},
+#line 63 "u8_lc_map.txt"
+ {"\304\202", "ă"},
+ {""}, {""},
+#line 543 "u8_lc_map.txt"
+ {"\341\271\234", "ṝ"},
+ {""}, {""},
+#line 13 "u8_lc_map.txt"
+ {"H", "h"},
+ {""},
+#line 511 "u8_lc_map.txt"
+ {"\341\270\234", "ḝ"},
+#line 541 "u8_lc_map.txt"
+ {"\341\271\230", "ṙ"},
+ {""}, {""}, {""}, {""},
+#line 509 "u8_lc_map.txt"
+ {"\341\270\230", "ḙ"},
+ {""},
#line 12 "u8_lc_map.txt"
+ {"G", "g"},
+ {""},
+#line 921 "u8_lc_map.txt"
+ {"\352\235\234", "ꝝ"},
+ {""}, {""}, {""},
+#line 197 "u8_lc_map.txt"
+ {"\310\232", "ț"},
+#line 535 "u8_lc_map.txt"
+ {"\341\271\214", "ṍ"},
+#line 919 "u8_lc_map.txt"
+ {"\352\235\230", "ꝙ"},
+#line 885 "u8_lc_map.txt"
+ {"\352\232\210", "ꚉ"},
+#line 11 "u8_lc_map.txt"
+ {"F", "f"},
+ {""},
+#line 503 "u8_lc_map.txt"
+ {"\341\270\214", "ḍ"},
+ {""}, {""}, {""},
+#line 57 "u8_lc_map.txt"
+ {"\303\232", "ú"},
+#line 871 "u8_lc_map.txt"
+ {"\352\231\232", "ꙛ"},
+#line 877 "u8_lc_map.txt"
+ {"\352\231\246", "ꙧ"},
+#line 862 "u8_lc_map.txt"
+ {"\352\231\210", "ꙉ"},
+#line 10 "u8_lc_map.txt"
+ {"E", "e"},
+ {""},
+#line 913 "u8_lc_map.txt"
+ {"\352\235\214", "ꝍ"},
+ {""},
+#line 532 "u8_lc_map.txt"
+ {"\341\271\206", "ṇ"},
+ {""}, {""},
+#line 886 "u8_lc_map.txt"
+ {"\352\232\212", "ꚋ"},
+ {""},
+#line 500 "u8_lc_map.txt"
+ {"\341\270\206", "ḇ"},
+#line 9 "u8_lc_map.txt"
+ {"D", "d"},
+#line 198 "u8_lc_map.txt"
+ {"\310\234", "ȝ"},
+#line 679 "u8_lc_map.txt"
+ {"\341\276\232", "ᾒ"},
+ {""},
+#line 669 "u8_lc_map.txt"
+ {"\341\276\210", "ᾀ"},
+ {""}, {""},
+#line 863 "u8_lc_map.txt"
+ {"\352\231\212", "ꙋ"},
+ {""},
+#line 910 "u8_lc_map.txt"
+ {"\352\235\206", "ꝇ"},
+#line 8 "u8_lc_map.txt"
+ {"C", "c"},
+#line 59 "u8_lc_map.txt"
{"\303\234", "ü"},
-#line 53 "u8_lc_map.txt"
- {"\320\256", "ю"},
-#line 40 "u8_lc_map.txt"
- {"\320\241", "с"},
+ {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
#line 7 "u8_lc_map.txt"
- {"\303\211", "é"},
+ {"B", "b"},
+ {""},
+#line 671 "u8_lc_map.txt"
+ {"\341\276\212", "ᾂ"},
+ {""}, {""}, {""}, {""}, {""}, {""}, {""},
+#line 6 "u8_lc_map.txt"
+ {"A", "a"},
+ {""}, {""}, {""},
+#line 932 "u8_lc_map.txt"
+ {"\352\235\273", "ꝼ"},
+ {""}, {""},
+#line 360 "u8_lc_map.txt"
+ {"\322\254", "ҭ"},
+ {""},
+#line 486 "u8_lc_map.txt"
+ {"\341\202\273", "ⴛ"},
+ {""}, {""}, {""}, {""}, {""}, {""}, {""},
+#line 872 "u8_lc_map.txt"
+ {"\352\231\234", "ꙝ"},
+ {""}, {""}, {""},
+#line 220 "u8_lc_map.txt"
+ {"\311\212", "ɋ"},
+#line 84 "u8_lc_map.txt"
+ {"\304\254", "ĭ"},
+#line 870 "u8_lc_map.txt"
+ {"\352\231\230", "ꙙ"},
+ {""}, {""},
+#line 189 "u8_lc_map.txt"
+ {"\310\212", "ȋ"},
+#line 887 "u8_lc_map.txt"
+ {"\352\232\214", "ꚍ"},
+ {""}, {""}, {""}, {""},
+#line 681 "u8_lc_map.txt"
+ {"\341\276\234", "ᾔ"},
+ {""}, {""}, {""},
+#line 42 "u8_lc_map.txt"
+ {"\303\212", "ê"},
+#line 864 "u8_lc_map.txt"
+ {"\352\231\214", "ꙍ"},
+#line 677 "u8_lc_map.txt"
+ {"\341\276\230", "ᾐ"},
+ {""}, {""}, {""},
+#line 546 "u8_lc_map.txt"
+ {"\341\271\242", "ṣ"},
+ {""},
+#line 884 "u8_lc_map.txt"
+ {"\352\232\206", "ꚇ"},
+ {""},
+#line 242 "u8_lc_map.txt"
+ {"\316\232", "κ"},
+#line 514 "u8_lc_map.txt"
+ {"\341\270\242", "ḣ"},
+ {""}, {""}, {""}, {""},
+#line 673 "u8_lc_map.txt"
+ {"\341\276\214", "ᾄ"},
+ {""},
+#line 861 "u8_lc_map.txt"
+ {"\352\231\206", "ꙇ"},
+ {""}, {""},
+#line 924 "u8_lc_map.txt"
+ {"\352\235\242", "ꝣ"},
+ {""},
+#line 379 "u8_lc_map.txt"
+ {"\323\224", "ӕ"},
+ {""}, {""},
+#line 461 "u8_lc_map.txt"
+ {"\341\202\242", "ⴂ"},
+ {""}, {""}, {""},
+#line 193 "u8_lc_map.txt"
+ {"\310\222", "ȓ"},
+ {""}, {""},
+#line 219 "u8_lc_map.txt"
+ {"\311\210", "ɉ"},
+ {""},
+#line 244 "u8_lc_map.txt"
+ {"\316\234", "μ"},
+ {""}, {""},
+#line 188 "u8_lc_map.txt"
+ {"\310\210", "ȉ"},
+ {""},
+#line 50 "u8_lc_map.txt"
+ {"\303\222", "ò"},
+#line 552 "u8_lc_map.txt"
+ {"\341\271\256", "ṯ"},
+ {""}, {""}, {""}, {""},
+#line 520 "u8_lc_map.txt"
+ {"\341\270\256", "ḯ"},
+ {""},
+#line 40 "u8_lc_map.txt"
+ {"\303\210", "è"},
+#line 936 "u8_lc_map.txt"
+ {"\352\236\202", "ꞃ"},
+ {""},
+#line 893 "u8_lc_map.txt"
+ {"\352\234\242", "ꜣ"},
+#line 944 "u8_lc_map.txt"
+ {"\352\236\244", "ꞥ"},
+ {""}, {""}, {""},
+#line 930 "u8_lc_map.txt"
+ {"\352\235\256", "ꝯ"},
+ {""},
+#line 696 "u8_lc_map.txt"
+ {"\341\276\273", "ά"},
+ {""},
+#line 351 "u8_lc_map.txt"
+ {"\322\232", "қ"},
+#line 473 "u8_lc_map.txt"
+ {"\341\202\256", "ⴎ"},
+ {""}, {""}, {""}, {""},
+#line 544 "u8_lc_map.txt"
+ {"\341\271\236", "ṟ"},
+ {""}, {""}, {""}, {""},
+#line 512 "u8_lc_map.txt"
+ {"\341\270\236", "ḟ"},
+ {""}, {""}, {""},
+#line 75 "u8_lc_map.txt"
+ {"\304\232", "ě"},
+#line 676 "u8_lc_map.txt"
+ {"\341\276\217", "ᾇ"},
+ {""},
+#line 470 "u8_lc_map.txt"
+ {"\341\202\253", "ⴋ"},
+ {""}, {""},
+#line 922 "u8_lc_map.txt"
+ {"\352\235\236", "ꝟ"},
+ {""}, {""}, {""},
+#line 352 "u8_lc_map.txt"
+ {"\322\234", "ҝ"},
+#line 899 "u8_lc_map.txt"
+ {"\352\234\256", "ꜯ"},
+ {""},
+#line 941 "u8_lc_map.txt"
+ {"\352\236\220", "ꞑ"},
+ {""},
+#line 229 "u8_lc_map.txt"
+ {"\316\212", "ί"},
+ {""}, {""}, {""}, {""}, {""},
+#line 875 "u8_lc_map.txt"
+ {"\352\231\242", "ꙣ"},
+ {""}, {""}, {""},
+#line 76 "u8_lc_map.txt"
+ {"\304\234", "ĝ"},
+#line 536 "u8_lc_map.txt"
+ {"\341\271\216", "ṏ"},
+#line 555 "u8_lc_map.txt"
+ {"\341\271\264", "ṵ"},
+#line 848 "u8_lc_map.txt"
+ {"\342\263\224", "ⳕ"},
+#line 839 "u8_lc_map.txt"
+ {"\342\263\202", "ⳃ"},
+#line 221 "u8_lc_map.txt"
+ {"\311\214", "ɍ"},
+#line 504 "u8_lc_map.txt"
+ {"\341\270\216", "ḏ"},
+#line 523 "u8_lc_map.txt"
+ {"\341\270\264", "ḵ"},
+#line 298 "u8_lc_map.txt"
+ {"\320\224", "д"},
+ {""},
+#line 190 "u8_lc_map.txt"
+ {"\310\214", "ȍ"},
+#line 857 "u8_lc_map.txt"
+ {"\342\263\255", "ⳮ"},
+#line 202 "u8_lc_map.txt"
+ {"\310\244", "ȥ"},
+#line 816 "u8_lc_map.txt"
+ {"\342\262\224", "ⲕ"},
+#line 807 "u8_lc_map.txt"
+ {"\342\262\202", "ⲃ"},
+ {""},
+#line 914 "u8_lc_map.txt"
+ {"\352\235\216", "ꝏ"},
+#line 824 "u8_lc_map.txt"
+ {"\342\262\244", "ⲥ"},
+ {""}, {""},
+#line 44 "u8_lc_map.txt"
+ {"\303\214", "ì"},
+#line 847 "u8_lc_map.txt"
+ {"\342\263\222", "ⳓ"},
+#line 479 "u8_lc_map.txt"
+ {"\341\202\264", "ⴔ"},
+#line 280 "u8_lc_map.txt"
+ {"\320\202", "ђ"},
+ {""}, {""}, {""}, {""},
+#line 103 "u8_lc_map.txt"
+ {"\305\224", "ŕ"},
+ {""},
+#line 234 "u8_lc_map.txt"
+ {"\316\222", "β"},
+#line 815 "u8_lc_map.txt"
+ {"\342\262\222", "ⲓ"},
+ {""}, {""}, {""}, {""},
+#line 391 "u8_lc_map.txt"
+ {"\323\254", "ӭ"},
+ {""},
+#line 227 "u8_lc_map.txt"
+ {"\316\210", "έ"},
+ {""},
+#line 343 "u8_lc_map.txt"
+ {"\322\212", "ҋ"},
+ {""}, {""},
+#line 846 "u8_lc_map.txt"
+ {"\342\263\220", "ⳑ"},
+ {""}, {""},
+#line 691 "u8_lc_map.txt"
+ {"\341\276\256", "ᾦ"},
+#line 901 "u8_lc_map.txt"
+ {"\352\234\264", "ꜵ"},
+ {""}, {""}, {""},
+#line 828 "u8_lc_map.txt"
+ {"\342\262\254", "ⲭ"},
+ {""},
+#line 814 "u8_lc_map.txt"
+ {"\342\262\220", "ⲑ"},
+ {""},
+#line 67 "u8_lc_map.txt"
+ {"\304\212", "ċ"},
+#line 873 "u8_lc_map.txt"
+ {"\352\231\236", "ꙟ"},
+ {""},
+#line 599 "u8_lc_map.txt"
+ {"\341\273\224", "ổ"},
+#line 590 "u8_lc_map.txt"
+ {"\341\273\202", "ể"},
+ {""}, {""},
+#line 607 "u8_lc_map.txt"
+ {"\341\273\244", "ụ"},
+#line 688 "u8_lc_map.txt"
+ {"\341\276\253", "ᾣ"},
+ {""}, {""}, {""}, {""},
+#line 933 "u8_lc_map.txt"
+ {"\352\235\275", "ᵹ"},
+ {""}, {""},
+#line 683 "u8_lc_map.txt"
+ {"\341\276\236", "ᾖ"},
+ {""},
+#line 488 "u8_lc_map.txt"
+ {"\341\202\275", "ⴝ"},
+ {""}, {""},
+#line 598 "u8_lc_map.txt"
+ {"\341\273\222", "ồ"},
+ {""}, {""}, {""},
+#line 347 "u8_lc_map.txt"
+ {"\322\222", "ғ"},
+#line 888 "u8_lc_map.txt"
+ {"\352\232\216", "ꚏ"},
+#line 945 "u8_lc_map.txt"
+ {"\352\236\246", "ꞧ"},
+ {""}, {""},
+#line 214 "u8_lc_map.txt"
+ {"\311\201", "ɂ"},
+#line 827 "u8_lc_map.txt"
+ {"\342\262\252", "ⲫ"},
+ {""}, {""}, {""}, {""},
+#line 865 "u8_lc_map.txt"
+ {"\352\231\216", "ꙏ"},
+#line 836 "u8_lc_map.txt"
+ {"\342\262\274", "ⲽ"},
+ {""}, {""},
+#line 71 "u8_lc_map.txt"
+ {"\304\222", "ē"},
+#line 611 "u8_lc_map.txt"
+ {"\341\273\254", "ử"},
+ {""},
+#line 597 "u8_lc_map.txt"
+ {"\341\273\220", "ố"},
{""},
#line 33 "u8_lc_map.txt"
+ {"\303\201", "á"},
+ {""}, {""},
+#line 66 "u8_lc_map.txt"
+ {"\304\210", "ĉ"},
+ {""}, {""},
+#line 675 "u8_lc_map.txt"
+ {"\341\276\216", "ᾆ"},
+ {""},
+#line 540 "u8_lc_map.txt"
+ {"\341\271\226", "ṗ"},
+ {""},
+#line 230 "u8_lc_map.txt"
+ {"\316\214", "ό"},
+ {""},
+#line 251 "u8_lc_map.txt"
+ {"\316\244", "τ"},
+#line 508 "u8_lc_map.txt"
+ {"\341\270\226", "ḗ"},
+ {""}, {""},
+#line 480 "u8_lc_map.txt"
+ {"\341\202\265", "ⴕ"},
+ {""}, {""}, {""}, {""},
+#line 322 "u8_lc_map.txt"
+ {"\320\254", "ь"},
+#line 674 "u8_lc_map.txt"
+ {"\341\276\215", "ᾅ"},
+#line 918 "u8_lc_map.txt"
+ {"\352\235\226", "ꝗ"},
+ {""},
+#line 382 "u8_lc_map.txt"
+ {"\323\232", "ӛ"},
+ {""},
+#line 482 "u8_lc_map.txt"
+ {"\341\202\267", "ⴗ"},
+#line 531 "u8_lc_map.txt"
+ {"\341\271\204", "ṅ"},
+#line 216 "u8_lc_map.txt"
+ {"\311\204", "ʉ"},
+ {""},
+#line 610 "u8_lc_map.txt"
+ {"\341\273\252", "ừ"},
+ {""},
+#line 499 "u8_lc_map.txt"
+ {"\341\270\204", "ḅ"},
+#line 186 "u8_lc_map.txt"
+ {"\310\204", "ȅ"},
+ {""},
+#line 851 "u8_lc_map.txt"
+ {"\342\263\232", "ⳛ"},
+#line 619 "u8_lc_map.txt"
+ {"\341\273\274", "ỽ"},
+#line 842 "u8_lc_map.txt"
+ {"\342\263\210", "ⳉ"},
+ {""}, {""},
+#line 115 "u8_lc_map.txt"
+ {"\305\254", "ŭ"},
+ {""},
+#line 909 "u8_lc_map.txt"
+ {"\352\235\204", "ꝅ"},
+#line 36 "u8_lc_map.txt"
+ {"\303\204", "ä"},
+ {""},
+#line 819 "u8_lc_map.txt"
+ {"\342\262\232", "ⲛ"},
+#line 825 "u8_lc_map.txt"
+ {"\342\262\246", "ⲧ"},
+#line 810 "u8_lc_map.txt"
+ {"\342\262\210", "ⲉ"},
+ {""},
+#line 383 "u8_lc_map.txt"
+ {"\323\234", "ӝ"},
+ {""}, {""}, {""}, {""}, {""},
+#line 843 "u8_lc_map.txt"
+ {"\342\263\212", "ⳋ"},
+ {""}, {""}, {""},
+#line 344 "u8_lc_map.txt"
+ {"\322\214", "ҍ"},
+ {""},
+#line 356 "u8_lc_map.txt"
+ {"\322\244", "ҥ"},
+#line 571 "u8_lc_map.txt"
+ {"\341\272\224", "ẕ"},
+#line 562 "u8_lc_map.txt"
+ {"\341\272\202", "ẃ"},
+ {""},
+#line 811 "u8_lc_map.txt"
+ {"\342\262\212", "ⲋ"},
+#line 575 "u8_lc_map.txt"
+ {"\341\272\244", "ấ"},
+ {""}, {""}, {""}, {""}, {""}, {""}, {""},
+#line 68 "u8_lc_map.txt"
+ {"\304\214", "č"},
+ {""},
+#line 80 "u8_lc_map.txt"
+ {"\304\244", "ĥ"},
+#line 938 "u8_lc_map.txt"
+ {"\352\236\206", "ꞇ"},
+#line 764 "u8_lc_map.txt"
+ {"\342\260\224", "ⱄ"},
+#line 746 "u8_lc_map.txt"
+ {"\342\260\202", "ⰲ"},
+#line 570 "u8_lc_map.txt"
+ {"\341\272\222", "ẓ"},
+ {""},
+#line 780 "u8_lc_map.txt"
+ {"\342\260\244", "ⱔ"},
+ {""}, {""},
+#line 711 "u8_lc_map.txt"
+ {"\341\277\254", "ῥ"},
+#line 789 "u8_lc_map.txt"
+ {"\342\260\255", "ⱝ"},
+#line 892 "u8_lc_map.txt"
+ {"\352\232\226", "ꚗ"},
+ {""}, {""},
+#line 602 "u8_lc_map.txt"
+ {"\341\273\232", "ớ"},
+#line 608 "u8_lc_map.txt"
+ {"\341\273\246", "ủ"},
+#line 593 "u8_lc_map.txt"
+ {"\341\273\210", "ỉ"},
+ {""}, {""},
+#line 852 "u8_lc_map.txt"
+ {"\342\263\234", "ⳝ"},
+#line 762 "u8_lc_map.txt"
+ {"\342\260\222", "ⱂ"},
+#line 869 "u8_lc_map.txt"
+ {"\352\231\226", "ꙗ"},
+ {""}, {""},
+#line 579 "u8_lc_map.txt"
+ {"\341\272\254", "ậ"},
+#line 850 "u8_lc_map.txt"
+ {"\342\263\230", "ⳙ"},
+#line 569 "u8_lc_map.txt"
+ {"\341\272\220", "ẑ"},
+ {""}, {""},
+#line 820 "u8_lc_map.txt"
+ {"\342\262\234", "ⲝ"},
+ {""},
+#line 883 "u8_lc_map.txt"
+ {"\352\232\204", "ꚅ"},
+ {""},
+#line 304 "u8_lc_map.txt"
{"\320\232", "к"},
-#line 52 "u8_lc_map.txt"
- {"\320\255", "э"},
+#line 594 "u8_lc_map.txt"
+ {"\341\273\212", "ị"},
+#line 818 "u8_lc_map.txt"
+ {"\342\262\230", "ⲙ"},
+ {""}, {""}, {""},
+#line 844 "u8_lc_map.txt"
+ {"\342\263\214", "ⳍ"},
+#line 788 "u8_lc_map.txt"
+ {"\342\260\254", "ⱜ"},
+#line 860 "u8_lc_map.txt"
+ {"\352\231\204", "ꙅ"},
+#line 760 "u8_lc_map.txt"
+ {"\342\260\220", "ⱀ"},
+ {""},
+#line 709 "u8_lc_map.txt"
+ {"\341\277\252", "ὺ"},
+ {""},
+#line 138 "u8_lc_map.txt"
+ {"\306\224", "ɣ"},
+ {""}, {""},
+#line 812 "u8_lc_map.txt"
+ {"\342\262\214", "ⲍ"},
+#line 716 "u8_lc_map.txt"
+ {"\341\277\274", "ῳ"},
+ {""}, {""},
+#line 106 "u8_lc_map.txt"
+ {"\305\232", "ś"},
+#line 708 "u8_lc_map.txt"
+ {"\341\277\251", "ῡ"},
+ {""},
+#line 841 "u8_lc_map.txt"
+ {"\342\263\206", "ⳇ"},
+ {""},
+#line 306 "u8_lc_map.txt"
+ {"\320\234", "м"},
+#line 578 "u8_lc_map.txt"
+ {"\341\272\252", "ẫ"},
+ {""},
+#line 126 "u8_lc_map.txt"
+ {"\306\202", "ƃ"},
+ {""}, {""},
+#line 558 "u8_lc_map.txt"
+ {"\341\271\272", "ṻ"},
+#line 587 "u8_lc_map.txt"
+ {"\341\272\274", "ẽ"},
+#line 809 "u8_lc_map.txt"
+ {"\342\262\206", "ⲇ"},
+ {""},
+#line 378 "u8_lc_map.txt"
+ {"\323\222", "ӓ"},
+#line 526 "u8_lc_map.txt"
+ {"\341\270\272", "ḻ"},
+#line 745 "u8_lc_map.txt"
+ {"\342\260\201", "ⰱ"},
+#line 195 "u8_lc_map.txt"
+ {"\310\226", "ȗ"},
+ {""}, {""},
+#line 603 "u8_lc_map.txt"
+ {"\341\273\234", "ờ"},
+#line 786 "u8_lc_map.txt"
+ {"\342\260\252", "ⱚ"},
+ {""}, {""},
+#line 107 "u8_lc_map.txt"
+ {"\305\234", "ŝ"},
+#line 943 "u8_lc_map.txt"
+ {"\352\236\242", "ꞣ"},
+#line 601 "u8_lc_map.txt"
+ {"\341\273\230", "ộ"},
+#line 54 "u8_lc_map.txt"
+ {"\303\226", "ö"},
+ {""}, {""},
+#line 485 "u8_lc_map.txt"
+ {"\341\202\272", "ⴚ"},
+#line 785 "u8_lc_map.txt"
+ {"\342\260\251", "ⱙ"},
+#line 456 "u8_lc_map.txt"
+ {"\325\224", "ք"},
+#line 493 "u8_lc_map.txt"
+ {"\341\203\202", "ⴢ"},
+ {""},
+#line 269 "u8_lc_map.txt"
+ {"\317\254", "ϭ"},
+ {""}, {""}, {""}, {""},
+#line 595 "u8_lc_map.txt"
+ {"\341\273\214", "ọ"},
+#line 545 "u8_lc_map.txt"
+ {"\341\271\240", "ṡ"},
+ {""}, {""}, {""}, {""},
+#line 513 "u8_lc_map.txt"
+ {"\341\270\240", "ḡ"},
+#line 438 "u8_lc_map.txt"
+ {"\325\202", "ղ"},
+ {""},
+#line 155 "u8_lc_map.txt"
+ {"\306\263", "ƴ"},
+#line 705 "u8_lc_map.txt"
+ {"\341\277\232", "ὶ"},
+ {""},
+#line 698 "u8_lc_map.txt"
+ {"\341\277\210", "ὲ"},
+ {""}, {""},
+#line 904 "u8_lc_map.txt"
+ {"\352\234\272", "ꜻ"},
+#line 923 "u8_lc_map.txt"
+ {"\352\235\240", "ꝡ"},
+#line 592 "u8_lc_map.txt"
+ {"\341\273\206", "ệ"},
+ {""},
+#line 288 "u8_lc_map.txt"
+ {"\320\212", "њ"},
+ {""},
+#line 459 "u8_lc_map.txt"
+ {"\341\202\240", "ⴀ"},
+ {""}, {""}, {""},
+#line 332 "u8_lc_map.txt"
+ {"\321\254", "ѭ"},
+#line 576 "u8_lc_map.txt"
+ {"\341\272\246", "ầ"},
+#line 565 "u8_lc_map.txt"
+ {"\341\272\210", "ẉ"},
+#line 64 "u8_lc_map.txt"
+ {"\304\204", "ą"},
+ {""},
+#line 700 "u8_lc_map.txt"
+ {"\341\277\212", "ὴ"},
+ {""}, {""}, {""},
+#line 993 "u8_lc_map.txt"
+ {"\360\220\220\224", "𐐼"},
+#line 975 "u8_lc_map.txt"
+ {"\360\220\220\202", "𐐪"},
+ {""}, {""},
+#line 1009 "u8_lc_map.txt"
+ {"\360\220\220\244", "𐑌"},
+#line 98 "u8_lc_map.txt"
+ {"\305\212", "ŋ"},
+#line 855 "u8_lc_map.txt"
+ {"\342\263\242", "ⳣ"},
+#line 770 "u8_lc_map.txt"
+ {"\342\260\232", "ⱊ"},
+#line 782 "u8_lc_map.txt"
+ {"\342\260\246", "ⱖ"},
+#line 752 "u8_lc_map.txt"
+ {"\342\260\210", "ⰸ"},
+#line 199 "u8_lc_map.txt"
+ {"\310\236", "ȟ"},
+#line 566 "u8_lc_map.txt"
+ {"\341\272\212", "ẋ"},
+#line 211 "u8_lc_map.txt"
+ {"\310\273", "ȼ"},
+#line 192 "u8_lc_map.txt"
+ {"\310\220", "ȑ"},
+#line 258 "u8_lc_map.txt"
+ {"\316\253", "ϋ"},
+#line 205 "u8_lc_map.txt"
+ {"\310\252", "ȫ"},
+#line 823 "u8_lc_map.txt"
+ {"\342\262\242", "ⲣ"},
+ {""},
+#line 991 "u8_lc_map.txt"
+ {"\360\220\220\222", "𐐺"},
+ {""},
+#line 61 "u8_lc_map.txt"
+ {"\303\236", "þ"},
+#line 364 "u8_lc_map.txt"
+ {"\322\264", "ҵ"},
+#line 387 "u8_lc_map.txt"
+ {"\323\244", "ӥ"},
+#line 48 "u8_lc_map.txt"
+ {"\303\220", "ð"},
+ {""},
+#line 296 "u8_lc_map.txt"
+ {"\320\222", "в"},
+#line 492 "u8_lc_map.txt"
+ {"\341\203\201", "ⴡ"},
+#line 754 "u8_lc_map.txt"
+ {"\342\260\212", "ⰺ"},
+ {""}, {""}, {""},
+#line 150 "u8_lc_map.txt"
+ {"\306\254", "ƭ"},
+#line 553 "u8_lc_map.txt"
+ {"\341\271\260", "ṱ"},
+#line 286 "u8_lc_map.txt"
+ {"\320\210", "ј"},
+#line 218 "u8_lc_map.txt"
+ {"\311\206", "ɇ"},
+ {""},
+#line 88 "u8_lc_map.txt"
+ {"\304\264", "ĵ"},
+#line 521 "u8_lc_map.txt"
+ {"\341\270\260", "ḱ"},
+ {""},
+#line 187 "u8_lc_map.txt"
+ {"\310\206", "ȇ"},
+#line 989 "u8_lc_map.txt"
+ {"\360\220\220\220", "𐐸"},
+#line 695 "u8_lc_map.txt"
+ {"\341\276\272", "ὰ"},
+#line 703 "u8_lc_map.txt"
+ {"\341\277\230", "ῐ"},
+#line 238 "u8_lc_map.txt"
+ {"\316\226", "ζ"},
+ {""},
+#line 102 "u8_lc_map.txt"
+ {"\305\222", "œ"},
+ {""}, {""},
+#line 931 "u8_lc_map.txt"
+ {"\352\235\271", "ꝺ"},
#line 38 "u8_lc_map.txt"
- {"\320\240", "р"},
-#line 20 "u8_lc_map.txt"
- {"\303\210", "è"},
+ {"\303\206", "æ"},
+#line 260 "u8_lc_map.txt"
+ {"\317\232", "ϛ"},
+#line 829 "u8_lc_map.txt"
+ {"\342\262\256", "ⲯ"},
+#line 475 "u8_lc_map.txt"
+ {"\341\202\260", "ⴐ"},
+#line 484 "u8_lc_map.txt"
+ {"\341\202\271", "ⴙ"},
+ {""}, {""},
+#line 702 "u8_lc_map.txt"
+ {"\341\277\214", "ῃ"},
+#line 874 "u8_lc_map.txt"
+ {"\352\231\240", "ꙡ"},
+#line 856 "u8_lc_map.txt"
+ {"\342\263\253", "ⳬ"},
+ {""}, {""},
+#line 606 "u8_lc_map.txt"
+ {"\341\273\242", "ợ"},
+#line 940 "u8_lc_map.txt"
+ {"\352\236\215", "ɥ"},
+#line 411 "u8_lc_map.txt"
+ {"\324\224", "ԕ"},
{""},
-#line 11 "u8_lc_map.txt"
- {"\303\232", "ú"},
-#line 51 "u8_lc_map.txt"
- {"\320\254", "ь"},
-#line 39 "u8_lc_map.txt"
- {"\320\237", "п"},
-#line 19 "u8_lc_map.txt"
- {"\303\207", "ç"},
+#line 222 "u8_lc_map.txt"
+ {"\311\216", "ɏ"},
+#line 853 "u8_lc_map.txt"
+ {"\342\263\236", "ⳟ"},
+#line 772 "u8_lc_map.txt"
+ {"\342\260\234", "ⱌ"},
+#line 974 "u8_lc_map.txt"
+ {"\360\220\220\201", "𐐩"},
+ {""},
+#line 191 "u8_lc_map.txt"
+ {"\310\216", "ȏ"},
+#line 567 "u8_lc_map.txt"
+ {"\341\272\214", "ẍ"},
+#line 724 "u8_lc_map.txt"
+ {"\342\222\274", "ⓖ"},
+#line 768 "u8_lc_map.txt"
+ {"\342\260\230", "ⱈ"},
+ {""},
+#line 261 "u8_lc_map.txt"
+ {"\317\234", "ϝ"},
+#line 821 "u8_lc_map.txt"
+ {"\342\262\236", "ⲟ"},
+ {""},
+#line 402 "u8_lc_map.txt"
+ {"\324\202", "ԃ"},
+ {""},
+#line 46 "u8_lc_map.txt"
+ {"\303\216", "î"},
+#line 476 "u8_lc_map.txt"
+ {"\341\202\261", "ⴑ"},
+ {""}, {""}, {""}, {""},
+#line 490 "u8_lc_map.txt"
+ {"\341\202\277", "ⴟ"},
+#line 756 "u8_lc_map.txt"
+ {"\342\260\214", "ⰼ"},
+#line 564 "u8_lc_map.txt"
+ {"\341\272\206", "ẇ"},
+ {""}, {""}, {""}, {""},
+#line 349 "u8_lc_map.txt"
+ {"\322\226", "җ"},
+ {""}, {""},
+#line 612 "u8_lc_map.txt"
+ {"\341\273\256", "ữ"},
+ {""},
+#line 715 "u8_lc_map.txt"
+ {"\341\277\273", "ώ"},
+ {""},
+#line 370 "u8_lc_map.txt"
+ {"\323\201", "ӂ"},
+#line 845 "u8_lc_map.txt"
+ {"\342\263\216", "ⳏ"},
+ {""}, {""},
+#line 750 "u8_lc_map.txt"
+ {"\342\260\206", "ⰶ"},
+#line 290 "u8_lc_map.txt"
+ {"\320\214", "ќ"},
+ {""},
+#line 314 "u8_lc_map.txt"
+ {"\320\244", "ф"},
+#line 73 "u8_lc_map.txt"
+ {"\304\226", "ė"},
+ {""},
+#line 246 "u8_lc_map.txt"
+ {"\316\236", "ξ"},
+#line 813 "u8_lc_map.txt"
+ {"\342\262\216", "ⲏ"},
+#line 832 "u8_lc_map.txt"
+ {"\342\262\264", "ⲵ"},
+ {""}, {""},
+#line 257 "u8_lc_map.txt"
+ {"\316\252", "ϊ"},
+#line 680 "u8_lc_map.txt"
+ {"\341\276\233", "ᾓ"},
+ {""}, {""}, {""},
+#line 423 "u8_lc_map.txt"
+ {"\324\263", "գ"},
+#line 604 "u8_lc_map.txt"
+ {"\341\273\236", "ở"},
+ {""}, {""}, {""},
+#line 99 "u8_lc_map.txt"
+ {"\305\214", "ō"},
+#line 549 "u8_lc_map.txt"
+ {"\341\271\250", "ṩ"},
+#line 111 "u8_lc_map.txt"
+ {"\305\244", "ť"},
+ {""}, {""}, {""},
+#line 517 "u8_lc_map.txt"
+ {"\341\270\250", "ḩ"},
+ {""},
+#line 999 "u8_lc_map.txt"
+ {"\360\220\220\232", "𐑂"},
+#line 1011 "u8_lc_map.txt"
+ {"\360\220\220\246", "𐑎"},
+#line 981 "u8_lc_map.txt"
+ {"\360\220\220\210", "𐐰"},
+#line 462 "u8_lc_map.txt"
+ {"\341\202\243", "ⴃ"},
+ {""},
+#line 694 "u8_lc_map.txt"
+ {"\341\276\271", "ᾱ"},
+#line 226 "u8_lc_map.txt"
+ {"\316\206", "ά"},
+ {""},
+#line 927 "u8_lc_map.txt"
+ {"\352\235\250", "ꝩ"},
+ {""}, {""}, {""},
+#line 142 "u8_lc_map.txt"
+ {"\306\234", "ɯ"},
+#line 467 "u8_lc_map.txt"
+ {"\341\202\250", "ⴈ"},
+#line 759 "u8_lc_map.txt"
+ {"\342\260\217", "ⰿ"},
+ {""}, {""}, {""}, {""}, {""},
+#line 983 "u8_lc_map.txt"
+ {"\360\220\220\212", "𐐲"},
+ {""}, {""},
+#line 596 "u8_lc_map.txt"
+ {"\341\273\216", "ỏ"},
+#line 615 "u8_lc_map.txt"
+ {"\341\273\264", "ỵ"},
+ {""}, {""},
+#line 353 "u8_lc_map.txt"
+ {"\322\236", "ҟ"},
+#line 175 "u8_lc_map.txt"
+ {"\307\254", "ǭ"},
+#line 323 "u8_lc_map.txt"
+ {"\320\255", "э"},
+#line 346 "u8_lc_map.txt"
+ {"\322\220", "ґ"},
+ {""},
+#line 359 "u8_lc_map.txt"
+ {"\322\252", "ҫ"},
+#line 574 "u8_lc_map.txt"
+ {"\341\272\242", "ả"},
+ {""},
+#line 666 "u8_lc_map.txt"
+ {"\341\275\255", "ὥ"},
+#line 464 "u8_lc_map.txt"
+ {"\341\202\245", "ⴅ"},
+#line 231 "u8_lc_map.txt"
+ {"\316\216", "ύ"},
+#line 896 "u8_lc_map.txt"
+ {"\352\234\250", "ꜩ"},
+ {""},
+#line 937 "u8_lc_map.txt"
+ {"\352\236\204", "ꞅ"},
+ {""},
+#line 77 "u8_lc_map.txt"
+ {"\304\236", "ğ"},
+#line 640 "u8_lc_map.txt"
+ {"\341\274\255", "ἥ"},
+#line 91 "u8_lc_map.txt"
+ {"\304\273", "ļ"},
+#line 70 "u8_lc_map.txt"
+ {"\304\220", "đ"},
+ {""},
+#line 83 "u8_lc_map.txt"
+ {"\304\252", "ī"},
+#line 672 "u8_lc_map.txt"
+ {"\341\276\213", "ᾃ"},
+#line 778 "u8_lc_map.txt"
+ {"\342\260\242", "ⱒ"},
+ {""}, {""},
+#line 279 "u8_lc_map.txt"
+ {"\320\201", "ё"},
+#line 395 "u8_lc_map.txt"
+ {"\323\264", "ӵ"},
+#line 466 "u8_lc_map.txt"
+ {"\341\202\247", "ⴇ"},
+ {""}, {""}, {""},
+#line 557 "u8_lc_map.txt"
+ {"\341\271\270", "ṹ"},
+#line 554 "u8_lc_map.txt"
+ {"\341\271\262", "ṳ"},
+#line 1001 "u8_lc_map.txt"
+ {"\360\220\220\234", "𐑄"},
+ {""}, {""},
+#line 525 "u8_lc_map.txt"
+ {"\341\270\270", "ḹ"},
+#line 522 "u8_lc_map.txt"
+ {"\341\270\262", "ḳ"},
+#line 665 "u8_lc_map.txt"
+ {"\341\275\254", "ὤ"},
+#line 997 "u8_lc_map.txt"
+ {"\360\220\220\230", "𐑀"},
+#line 131 "u8_lc_map.txt"
+ {"\306\212", "ɗ"},
+#line 580 "u8_lc_map.txt"
+ {"\341\272\256", "ắ"},
+#line 90 "u8_lc_map.txt"
+ {"\304\271", "ĺ"},
+#line 710 "u8_lc_map.txt"
+ {"\341\277\253", "ύ"},
+#line 65 "u8_lc_map.txt"
+ {"\304\206", "ć"},
+#line 94 "u8_lc_map.txt"
+ {"\305\201", "ł"},
+#line 639 "u8_lc_map.txt"
+ {"\341\274\254", "ἤ"},
+ {""},
+#line 849 "u8_lc_map.txt"
+ {"\342\263\226", "ⳗ"},
+ {""}, {""},
+#line 483 "u8_lc_map.txt"
+ {"\341\202\270", "ⴘ"},
+#line 477 "u8_lc_map.txt"
+ {"\341\202\262", "ⴒ"},
+#line 985 "u8_lc_map.txt"
+ {"\360\220\220\214", "𐐴"},
+ {""}, {""},
+#line 878 "u8_lc_map.txt"
+ {"\352\231\250", "ꙩ"},
+#line 790 "u8_lc_map.txt"
+ {"\342\260\256", "ⱞ"},
+#line 817 "u8_lc_map.txt"
+ {"\342\262\226", "ⲗ"},
+ {""},
+#line 345 "u8_lc_map.txt"
+ {"\322\216", "ҏ"},
+#line 209 "u8_lc_map.txt"
+ {"\310\262", "ȳ"},
+#line 256 "u8_lc_map.txt"
+ {"\316\251", "ω"},
+ {""}, {""}, {""},
+#line 572 "u8_lc_map.txt"
+ {"\341\272\236", "ß"},
+#line 208 "u8_lc_map.txt"
+ {"\310\260", "ȱ"},
+#line 840 "u8_lc_map.txt"
+ {"\342\263\204", "ⳅ"},
+#line 282 "u8_lc_map.txt"
+ {"\320\204", "є"},
+#line 979 "u8_lc_map.txt"
+ {"\360\220\220\206", "𐐮"},
+#line 685 "u8_lc_map.txt"
+ {"\341\276\250", "ᾠ"},
+ {""},
+#line 663 "u8_lc_map.txt"
+ {"\341\275\252", "ὢ"},
+#line 787 "u8_lc_map.txt"
+ {"\342\260\253", "ⱛ"},
+#line 69 "u8_lc_map.txt"
+ {"\304\216", "ď"},
+#line 903 "u8_lc_map.txt"
+ {"\352\234\270", "ꜹ"},
+#line 900 "u8_lc_map.txt"
+ {"\352\234\262", "ꜳ"},
+#line 808 "u8_lc_map.txt"
+ {"\342\262\204", "ⲅ"},
+ {""},
+#line 446 "u8_lc_map.txt"
+ {"\325\212", "պ"},
+#line 637 "u8_lc_map.txt"
+ {"\341\274\252", "ἢ"},
+#line 774 "u8_lc_map.txt"
+ {"\342\260\236", "ⱎ"},
+#line 662 "u8_lc_map.txt"
+ {"\341\275\251", "ὡ"},
+ {""},
+#line 217 "u8_lc_map.txt"
+ {"\311\205", "ʌ"},
+ {""},
+#line 647 "u8_lc_map.txt"
+ {"\341\274\274", "ἴ"},
+#line 723 "u8_lc_map.txt"
+ {"\342\222\273", "ⓕ"},
+ {""},
+#line 56 "u8_lc_map.txt"
+ {"\303\231", "ù"},
+#line 636 "u8_lc_map.txt"
+ {"\341\274\251", "ἡ"},
+#line 265 "u8_lc_map.txt"
+ {"\317\244", "ϥ"},
+ {""}, {""}, {""},
+#line 678 "u8_lc_map.txt"
+ {"\341\276\231", "ᾑ"},
+ {""},
+#line 380 "u8_lc_map.txt"
+ {"\323\226", "ӗ"},
{""},
-#line 31 "u8_lc_map.txt"
- {"\320\230", "и"},
-#line 50 "u8_lc_map.txt"
- {"\320\253", "ы"},
#line 37 "u8_lc_map.txt"
- {"\320\236", "о"},
-#line 16 "u8_lc_map.txt"
- {"\303\206", "æ"},
+ {"\303\205", "å"},
+#line 568 "u8_lc_map.txt"
+ {"\341\272\216", "ẏ"},
+#line 583 "u8_lc_map.txt"
+ {"\341\272\264", "ẵ"},
+#line 600 "u8_lc_map.txt"
+ {"\341\273\226", "ỗ"},
+#line 529 "u8_lc_map.txt"
+ {"\341\271\200", "ṁ"},
+#line 414 "u8_lc_map.txt"
+ {"\324\232", "ԛ"},
+#line 560 "u8_lc_map.txt"
+ {"\341\271\276", "ṿ"},
+#line 556 "u8_lc_map.txt"
+ {"\341\271\266", "ṷ"},
{""},
-#line 17 "u8_lc_map.txt"
+#line 497 "u8_lc_map.txt"
+ {"\341\270\200", "ḁ"},
+#line 250 "u8_lc_map.txt"
+ {"\316\243", "σ"},
+#line 528 "u8_lc_map.txt"
+ {"\341\270\276", "ḿ"},
+#line 524 "u8_lc_map.txt"
+ {"\341\270\266", "ḷ"},
+#line 988 "u8_lc_map.txt"
+ {"\360\220\220\217", "𐐷"},
+ {""}, {""},
+#line 60 "u8_lc_map.txt"
+ {"\303\235", "ý"},
+#line 758 "u8_lc_map.txt"
+ {"\342\260\216", "ⰾ"},
+#line 684 "u8_lc_map.txt"
+ {"\341\276\237", "ᾗ"},
+#line 907 "u8_lc_map.txt"
+ {"\352\235\200", "ꝁ"},
+#line 454 "u8_lc_map.txt"
+ {"\325\222", "ւ"},
+#line 934 "u8_lc_map.txt"
+ {"\352\235\276", "ꝿ"},
+#line 328 "u8_lc_map.txt"
+ {"\321\244", "ѥ"},
+#line 591 "u8_lc_map.txt"
+ {"\341\273\204", "ễ"},
+ {""}, {""},
+#line 489 "u8_lc_map.txt"
+ {"\341\202\276", "ⴞ"},
+#line 481 "u8_lc_map.txt"
+ {"\341\202\266", "ⴖ"},
+#line 444 "u8_lc_map.txt"
+ {"\325\210", "ո"},
+ {""},
+#line 415 "u8_lc_map.txt"
+ {"\324\234", "ԝ"},
+#line 119 "u8_lc_map.txt"
+ {"\305\264", "ŵ"},
+#line 761 "u8_lc_map.txt"
+ {"\342\260\221", "ⱁ"},
+#line 757 "u8_lc_map.txt"
+ {"\342\260\215", "ⰽ"},
+ {""},
+#line 651 "u8_lc_map.txt"
+ {"\341\275\210", "ὀ"},
+#line 693 "u8_lc_map.txt"
+ {"\341\276\270", "ᾰ"},
+ {""}, {""}, {""}, {""},
+#line 631 "u8_lc_map.txt"
+ {"\341\274\232", "ἒ"},
+#line 460 "u8_lc_map.txt"
+ {"\341\202\241", "ⴁ"},
+#line 621 "u8_lc_map.txt"
+ {"\341\274\210", "ἀ"},
+ {""}, {""}, {""}, {""},
+#line 1007 "u8_lc_map.txt"
+ {"\360\220\220\242", "𐑊"},
+ {""},
+#line 184 "u8_lc_map.txt"
+ {"\310\200", "ȁ"},
+#line 906 "u8_lc_map.txt"
+ {"\352\234\276", "ꜿ"},
+#line 902 "u8_lc_map.txt"
+ {"\352\234\266", "ꜷ"},
+#line 653 "u8_lc_map.txt"
+ {"\341\275\212", "ὂ"},
+#line 321 "u8_lc_map.txt"
+ {"\320\253", "ы"},
+ {""},
+#line 670 "u8_lc_map.txt"
+ {"\341\276\211", "ᾁ"},
+#line 942 "u8_lc_map.txt"
+ {"\352\236\240", "ꞡ"},
+ {""}, {""},
+#line 32 "u8_lc_map.txt"
+ {"\303\200", "à"},
+#line 623 "u8_lc_map.txt"
+ {"\341\274\212", "ἂ"},
+#line 147 "u8_lc_map.txt"
+ {"\306\244", "ƥ"},
+ {""}, {""},
+#line 384 "u8_lc_map.txt"
+ {"\323\236", "ӟ"},
+#line 474 "u8_lc_map.txt"
+ {"\341\202\257", "ⴏ"},
+ {""},
+#line 377 "u8_lc_map.txt"
+ {"\323\220", "ӑ"},
+ {""},
+#line 390 "u8_lc_map.txt"
+ {"\323\252", "ӫ"},
+#line 196 "u8_lc_map.txt"
+ {"\310\230", "ș"},
+ {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
+#line 241 "u8_lc_map.txt"
+ {"\316\231", "ι"},
+#line 55 "u8_lc_map.txt"
{"\303\230", "ø"},
-#line 49 "u8_lc_map.txt"
- {"\320\252", "ъ"},
-#line 36 "u8_lc_map.txt"
- {"\320\235", "н"},
-#line 15 "u8_lc_map.txt"
- {"\303\205", "å"},
{""},
-#line 29 "u8_lc_map.txt"
+#line 300 "u8_lc_map.txt"
{"\320\226", "ж"},
-#line 48 "u8_lc_map.txt"
- {"\320\251", "щ"},
-#line 34 "u8_lc_map.txt"
- {"\320\233", "л"},
-#line 13 "u8_lc_map.txt"
- {"\303\204", "ä"},
+#line 881 "u8_lc_map.txt"
+ {"\352\232\200", "ꚁ"},
+#line 406 "u8_lc_map.txt"
+ {"\324\212", "ԋ"},
+ {""},
+#line 765 "u8_lc_map.txt"
+ {"\342\260\225", "ⱅ"},
+ {""}, {""},
+#line 366 "u8_lc_map.txt"
+ {"\322\270", "ҹ"},
+#line 835 "u8_lc_map.txt"
+ {"\342\262\272", "ⲻ"},
+#line 749 "u8_lc_map.txt"
+ {"\342\260\205", "ⰵ"},
+ {""},
+#line 858 "u8_lc_map.txt"
+ {"\352\231\200", "ꙁ"},
+ {""}, {""},
+#line 682 "u8_lc_map.txt"
+ {"\341\276\235", "ᾕ"},
+ {""}, {""},
+#line 448 "u8_lc_map.txt"
+ {"\325\214", "ռ"},
+#line 633 "u8_lc_map.txt"
+ {"\341\274\234", "ἔ"},
+ {""},
+#line 104 "u8_lc_map.txt"
+ {"\305\226", "ŗ"},
+ {""}, {""},
+#line 245 "u8_lc_map.txt"
+ {"\316\235", "ν"},
+#line 629 "u8_lc_map.txt"
+ {"\341\274\230", "ἐ"},
+#line 1003 "u8_lc_map.txt"
+ {"\360\220\220\236", "𐑆"},
+ {""}, {""},
+#line 363 "u8_lc_map.txt"
+ {"\322\262", "ҳ"},
+#line 854 "u8_lc_map.txt"
+ {"\342\263\240", "ⳡ"},
+#line 655 "u8_lc_map.txt"
+ {"\341\275\214", "ὄ"},
+ {""},
+#line 213 "u8_lc_map.txt"
+ {"\310\276", "ⱦ"},
+ {""},
+#line 362 "u8_lc_map.txt"
+ {"\322\260", "ұ"},
+ {""}, {""}, {""},
+#line 625 "u8_lc_map.txt"
+ {"\341\274\214", "ἄ"},
+#line 822 "u8_lc_map.txt"
+ {"\342\262\240", "ⲡ"},
+ {""},
+#line 766 "u8_lc_map.txt"
+ {"\342\260\226", "ⱆ"},
+#line 410 "u8_lc_map.txt"
+ {"\324\222", "ԓ"},
+#line 87 "u8_lc_map.txt"
+ {"\304\262", "ij"},
+#line 58 "u8_lc_map.txt"
+ {"\303\233", "û"},
+#line 563 "u8_lc_map.txt"
+ {"\341\272\204", "ẅ"},
+ {""}, {""}, {""},
+#line 86 "u8_lc_map.txt"
+ {"\304\260", "i"},
+#line 405 "u8_lc_map.txt"
+ {"\324\210", "ԉ"},
+ {""}, {""},
+#line 618 "u8_lc_map.txt"
+ {"\341\273\272", "ỻ"},
+ {""}, {""}, {""},
+#line 125 "u8_lc_map.txt"
+ {"\306\201", "ɓ"},
+#line 368 "u8_lc_map.txt"
+ {"\322\274", "ҽ"},
+ {""},
+#line 987 "u8_lc_map.txt"
+ {"\360\220\220\216", "𐐶"},
+#line 748 "u8_lc_map.txt"
+ {"\342\260\204", "ⰴ"},
+ {""}, {""},
+#line 203 "u8_lc_map.txt"
+ {"\310\246", "ȧ"},
+ {""}, {""},
+#line 308 "u8_lc_map.txt"
+ {"\320\236", "о"},
+#line 692 "u8_lc_map.txt"
+ {"\341\276\257", "ᾧ"},
+#line 751 "u8_lc_map.txt"
+ {"\342\260\207", "ⰷ"},
+#line 294 "u8_lc_map.txt"
+ {"\320\220", "а"},
+ {""},
+#line 320 "u8_lc_map.txt"
+ {"\320\252", "ъ"},
+#line 271 "u8_lc_map.txt"
+ {"\317\264", "θ"},
+ {""},
+#line 990 "u8_lc_map.txt"
+ {"\360\220\220\221", "𐐹"},
+#line 986 "u8_lc_map.txt"
+ {"\360\220\220\215", "𐐵"},
+ {""}, {""}, {""},
+#line 646 "u8_lc_map.txt"
+ {"\341\274\273", "ἳ"},
+ {""}, {""},
+#line 939 "u8_lc_map.txt"
+ {"\352\236\213", "ꞌ"},
+#line 605 "u8_lc_map.txt"
+ {"\341\273\240", "ỡ"},
+ {""}, {""},
+#line 108 "u8_lc_map.txt"
+ {"\305\236", "ş"},
+#line 240 "u8_lc_map.txt"
+ {"\316\230", "θ"},
+#line 123 "u8_lc_map.txt"
+ {"\305\273", "ż"},
+#line 101 "u8_lc_map.txt"
+ {"\305\220", "ő"},
+ {""},
+#line 114 "u8_lc_map.txt"
+ {"\305\252", "ū"},
+#line 496 "u8_lc_map.txt"
+ {"\341\203\205", "ⴥ"},
+ {""}, {""},
+#line 284 "u8_lc_map.txt"
+ {"\320\206", "і"},
+#line 437 "u8_lc_map.txt"
+ {"\325\201", "ձ"},
+#line 628 "u8_lc_map.txt"
+ {"\341\274\217", "ἇ"},
+ {""}, {""},
+#line 127 "u8_lc_map.txt"
+ {"\306\204", "ƅ"},
+ {""},
+#line 336 "u8_lc_map.txt"
+ {"\321\264", "ѵ"},
+#line 830 "u8_lc_map.txt"
+ {"\342\262\260", "ⲱ"},
+#line 725 "u8_lc_map.txt"
+ {"\342\222\275", "ⓗ"},
+ {""}, {""}, {""},
+#line 171 "u8_lc_map.txt"
+ {"\307\244", "ǥ"},
+ {""}, {""}, {""}, {""},
+#line 122 "u8_lc_map.txt"
+ {"\305\271", "ź"},
+ {""}, {""},
+#line 342 "u8_lc_map.txt"
+ {"\322\200", "ҁ"},
{""},
-#line 14 "u8_lc_map.txt"
- {"\303\226", "ö"},
#line 47 "u8_lc_map.txt"
- {"\320\250", "ш"},
-#line 32 "u8_lc_map.txt"
+ {"\303\217", "ï"},
+ {""}, {""},
+#line 407 "u8_lc_map.txt"
+ {"\324\214", "ԍ"},
+ {""},
+#line 419 "u8_lc_map.txt"
+ {"\324\244", "ԥ"},
+ {""}, {""},
+#line 292 "u8_lc_map.txt"
+ {"\320\216", "ў"},
+ {""}, {""},
+#line 994 "u8_lc_map.txt"
+ {"\360\220\220\225", "𐐽"},
+ {""},
+#line 62 "u8_lc_map.txt"
+ {"\304\200", "ā"},
+#line 946 "u8_lc_map.txt"
+ {"\352\236\250", "ꞩ"},
+#line 243 "u8_lc_map.txt"
+ {"\316\233", "λ"},
+#line 978 "u8_lc_map.txt"
+ {"\360\220\220\205", "𐐭"},
+ {""}, {""},
+#line 350 "u8_lc_map.txt"
+ {"\322\230", "ҙ"},
+ {""},
+#line 794 "u8_lc_map.txt"
+ {"\342\261\244", "ɽ"},
+#line 440 "u8_lc_map.txt"
+ {"\325\204", "մ"},
+ {""},
+#line 714 "u8_lc_map.txt"
+ {"\341\277\272", "ὼ"},
+#line 798 "u8_lc_map.txt"
+ {"\342\261\255", "ɑ"},
+#line 495 "u8_lc_map.txt"
+ {"\341\203\204", "ⴤ"},
+ {""},
+#line 100 "u8_lc_map.txt"
+ {"\305\216", "ŏ"},
+ {""},
+#line 613 "u8_lc_map.txt"
+ {"\341\273\260", "ự"},
+ {""}, {""}, {""},
+#line 74 "u8_lc_map.txt"
+ {"\304\230", "ę"},
+ {""}, {""}, {""}, {""},
+#line 586 "u8_lc_map.txt"
+ {"\341\272\272", "ẻ"},
+#line 719 "u8_lc_map.txt"
+ {"\342\222\267", "ⓑ"},
+#line 667 "u8_lc_map.txt"
+ {"\341\275\256", "ὦ"},
+ {""},
+#line 210 "u8_lc_map.txt"
+ {"\310\272", "ⱥ"},
+#line 201 "u8_lc_map.txt"
+ {"\310\242", "ȣ"},
+#line 253 "u8_lc_map.txt"
+ {"\316\246", "φ"},
+ {""},
+#line 730 "u8_lc_map.txt"
+ {"\342\223\202", "ⓜ"},
+#line 995 "u8_lc_map.txt"
+ {"\360\220\220\226", "𐐾"},
+#line 641 "u8_lc_map.txt"
+ {"\341\274\256", "ἦ"},
+#line 950 "u8_lc_map.txt"
+ {"\357\274\244", "d"},
+ {""}, {""},
+#line 397 "u8_lc_map.txt"
+ {"\323\270", "ӹ"},
+#line 959 "u8_lc_map.txt"
+ {"\357\274\255", "m"},
+ {""}, {""}, {""},
+#line 664 "u8_lc_map.txt"
+ {"\341\275\253", "ὣ"},
+ {""},
+#line 319 "u8_lc_map.txt"
+ {"\320\251", "щ"},
+ {""}, {""},
+#line 369 "u8_lc_map.txt"
+ {"\322\276", "ҿ"},
+ {""}, {""},
+#line 638 "u8_lc_map.txt"
+ {"\341\274\253", "ἣ"},
+ {""},
+#line 977 "u8_lc_map.txt"
+ {"\360\220\220\204", "𐐬"},
+ {""},
+#line 573 "u8_lc_map.txt"
+ {"\341\272\240", "ạ"},
+ {""},
+#line 747 "u8_lc_map.txt"
+ {"\342\260\203", "ⰳ"},
+ {""},
+#line 394 "u8_lc_map.txt"
+ {"\323\262", "ӳ"},
+#line 763 "u8_lc_map.txt"
+ {"\342\260\223", "ⱃ"},
+#line 980 "u8_lc_map.txt"
+ {"\360\220\220\207", "𐐯"},
+ {""}, {""},
+#line 826 "u8_lc_map.txt"
+ {"\342\262\250", "ⲩ"},
+#line 393 "u8_lc_map.txt"
+ {"\323\260", "ӱ"},
+ {""}, {""}, {""},
+#line 958 "u8_lc_map.txt"
+ {"\357\274\254", "l"},
+ {""},
+#line 776 "u8_lc_map.txt"
+ {"\342\260\240", "ⱐ"},
+ {""}, {""}, {""},
+#line 232 "u8_lc_map.txt"
+ {"\316\217", "ώ"},
+ {""}, {""},
+#line 262 "u8_lc_map.txt"
+ {"\317\236", "ϟ"},
+#line 965 "u8_lc_map.txt"
+ {"\357\274\263", "s"},
+#line 357 "u8_lc_map.txt"
+ {"\322\246", "ҧ"},
+#line 139 "u8_lc_map.txt"
+ {"\306\226", "ɩ"},
+ {""},
+#line 268 "u8_lc_map.txt"
+ {"\317\252", "ϫ"},
+#line 706 "u8_lc_map.txt"
+ {"\341\277\233", "ί"},
+#line 796 "u8_lc_map.txt"
+ {"\342\261\251", "ⱪ"},
+ {""}, {""},
+#line 372 "u8_lc_map.txt"
+ {"\323\205", "ӆ"},
+#line 399 "u8_lc_map.txt"
+ {"\323\274", "ӽ"},
+ {""}, {""}, {""},
+#line 313 "u8_lc_map.txt"
+ {"\320\243", "у"},
+#line 627 "u8_lc_map.txt"
+ {"\341\274\216", "ἆ"},
+#line 81 "u8_lc_map.txt"
+ {"\304\246", "ħ"},
+ {""}, {""}, {""},
+#line 729 "u8_lc_map.txt"
+ {"\342\223\201", "ⓛ"},
+ {""}, {""},
+#line 656 "u8_lc_map.txt"
+ {"\341\275\215", "ὅ"},
+ {""},
+#line 956 "u8_lc_map.txt"
+ {"\357\274\252", "j"},
+#line 273 "u8_lc_map.txt"
+ {"\317\271", "ϲ"},
+#line 713 "u8_lc_map.txt"
+ {"\341\277\271", "ό"},
+#line 717 "u8_lc_map.txt"
+ {"\342\204\262", "ⅎ"},
+ {""},
+#line 609 "u8_lc_map.txt"
+ {"\341\273\250", "ứ"},
+#line 626 "u8_lc_map.txt"
+ {"\341\274\215", "ἅ"},
+ {""},
+#line 403 "u8_lc_map.txt"
+ {"\324\204", "ԅ"},
+#line 331 "u8_lc_map.txt"
+ {"\321\252", "ѫ"},
+#line 955 "u8_lc_map.txt"
+ {"\357\274\251", "i"},
+#line 771 "u8_lc_map.txt"
+ {"\342\260\233", "ⱋ"},
+ {""}, {""}, {""}, {""},
+#line 581 "u8_lc_map.txt"
+ {"\341\272\260", "ằ"},
+#line 458 "u8_lc_map.txt"
+ {"\325\226", "ֆ"},
+ {""}, {""}, {""}, {""}, {""}, {""}, {""},
+#line 834 "u8_lc_map.txt"
+ {"\342\262\270", "ⲹ"},
+#line 831 "u8_lc_map.txt"
+ {"\342\262\262", "ⲳ"},
+ {""}, {""},
+#line 39 "u8_lc_map.txt"
+ {"\303\207", "ç"},
+ {""}, {""}, {""},
+#line 935 "u8_lc_map.txt"
+ {"\352\236\200", "ꞁ"},
+#line 207 "u8_lc_map.txt"
+ {"\310\256", "ȯ"},
+#line 177 "u8_lc_map.txt"
+ {"\307\264", "ǵ"},
+#line 215 "u8_lc_map.txt"
+ {"\311\203", "ƀ"},
+#line 494 "u8_lc_map.txt"
+ {"\341\203\203", "ⴣ"},
+#line 212 "u8_lc_map.txt"
+ {"\310\275", "ƚ"},
+#line 121 "u8_lc_map.txt"
+ {"\305\270", "ÿ"},
+ {""}, {""},
+#line 648 "u8_lc_map.txt"
+ {"\341\274\275", "ἵ"},
+ {""}, {""},
+#line 701 "u8_lc_map.txt"
+ {"\341\277\213", "ή"},
+ {""},
+#line 135 "u8_lc_map.txt"
+ {"\306\220", "ɛ"},
+ {""}, {""},
+#line 424 "u8_lc_map.txt"
+ {"\324\264", "դ"},
+#line 35 "u8_lc_map.txt"
+ {"\303\203", "ã"},
+ {""}, {""}, {""},
+#line 722 "u8_lc_map.txt"
+ {"\342\222\272", "ⓔ"},
+#line 767 "u8_lc_map.txt"
+ {"\342\260\227", "ⱇ"},
+#line 53 "u8_lc_map.txt"
+ {"\303\225", "õ"},
+ {""},
+#line 303 "u8_lc_map.txt"
{"\320\231", "й"},
-#line 18 "u8_lc_map.txt"
- {"\303\200", "à"},
+#line 118 "u8_lc_map.txt"
+ {"\305\262", "ų"},
+#line 952 "u8_lc_map.txt"
+ {"\357\274\246", "f"},
+#line 736 "u8_lc_map.txt"
+ {"\342\223\210", "ⓢ"},
+ {""}, {""},
+#line 381 "u8_lc_map.txt"
+ {"\323\230", "ә"},
+#line 117 "u8_lc_map.txt"
+ {"\305\260", "ű"},
+ {""}, {""},
+#line 283 "u8_lc_map.txt"
+ {"\320\205", "ѕ"},
+#line 617 "u8_lc_map.txt"
+ {"\341\273\270", "ỹ"},
+#line 614 "u8_lc_map.txt"
+ {"\341\273\262", "ỳ"},
{""},
-#line 25 "u8_lc_map.txt"
- {"\320\223", "г"},
-#line 46 "u8_lc_map.txt"
- {"\320\247", "ч"},
-#line 30 "u8_lc_map.txt"
- {"\320\227", "з"},
+#line 128 "u8_lc_map.txt"
+ {"\306\206", "ɔ"},
+#line 367 "u8_lc_map.txt"
+ {"\322\272", "һ"},
+#line 355 "u8_lc_map.txt"
+ {"\322\242", "ң"},
+#line 755 "u8_lc_map.txt"
+ {"\342\260\213", "ⰻ"},
{""}, {""},
-#line 10 "u8_lc_map.txt"
- {"\303\223", "ó"},
+#line 976 "u8_lc_map.txt"
+ {"\360\220\220\203", "𐐫"},
+#line 738 "u8_lc_map.txt"
+ {"\342\223\212", "ⓤ"},
+ {""},
+#line 992 "u8_lc_map.txt"
+ {"\360\220\220\223", "𐐻"},
+ {""}, {""},
+#line 307 "u8_lc_map.txt"
+ {"\320\235", "н"},
+ {""},
+#line 452 "u8_lc_map.txt"
+ {"\325\220", "ր"},
+#line 838 "u8_lc_map.txt"
+ {"\342\263\200", "ⳁ"},
+#line 96 "u8_lc_map.txt"
+ {"\305\205", "ņ"},
+#line 79 "u8_lc_map.txt"
+ {"\304\242", "ģ"},
+ {""}, {""},
+#line 1005 "u8_lc_map.txt"
+ {"\360\220\220\240", "𐑈"},
+ {""},
+#line 707 "u8_lc_map.txt"
+ {"\341\277\250", "ῠ"},
+ {""}, {""},
+#line 806 "u8_lc_map.txt"
+ {"\342\262\200", "ⲁ"},
+ {""},
+#line 837 "u8_lc_map.txt"
+ {"\342\262\276", "ⲿ"},
+#line 833 "u8_lc_map.txt"
+ {"\342\262\266", "ⲷ"},
+ {""}, {""},
+#line 133 "u8_lc_map.txt"
+ {"\306\216", "ǝ"},
+ {""},
#line 45 "u8_lc_map.txt"
+ {"\303\215", "í"},
+ {""}, {""},
+#line 400 "u8_lc_map.txt"
+ {"\323\276", "ӿ"},
+#line 577 "u8_lc_map.txt"
+ {"\341\272\250", "ẩ"},
+ {""}, {""},
+#line 442 "u8_lc_map.txt"
+ {"\325\206", "ն"},
+ {""}, {""},
+#line 779 "u8_lc_map.txt"
+ {"\342\260\243", "ⱓ"},
+ {""}, {""}, {""},
+#line 704 "u8_lc_map.txt"
+ {"\341\277\231", "ῑ"},
+ {""},
+#line 412 "u8_lc_map.txt"
+ {"\324\226", "ԗ"},
+ {""}, {""}, {""},
+#line 784 "u8_lc_map.txt"
+ {"\342\260\250", "ⱘ"},
+ {""}, {""},
+#line 278 "u8_lc_map.txt"
+ {"\320\200", "ѐ"},
+ {""},
+#line 200 "u8_lc_map.txt"
+ {"\310\240", "ƞ"},
+ {""}, {""}, {""},
+#line 49 "u8_lc_map.txt"
+ {"\303\221", "ñ"},
+ {""},
+#line 1000 "u8_lc_map.txt"
+ {"\360\220\220\233", "𐑃"},
+ {""}, {""},
+#line 740 "u8_lc_map.txt"
+ {"\342\223\214", "ⓦ"},
+#line 388 "u8_lc_map.txt"
+ {"\323\246", "ӧ"},
+ {""},
+#line 589 "u8_lc_map.txt"
+ {"\341\273\200", "ề"},
+#line 450 "u8_lc_map.txt"
+ {"\325\216", "վ"},
+#line 620 "u8_lc_map.txt"
+ {"\341\273\276", "ỿ"},
+#line 616 "u8_lc_map.txt"
+ {"\341\273\266", "ỷ"},
+#line 237 "u8_lc_map.txt"
+ {"\316\225", "ε"},
+ {""},
+#line 781 "u8_lc_map.txt"
+ {"\342\260\245", "ⱕ"},
+#line 302 "u8_lc_map.txt"
+ {"\320\230", "и"},
+#line 769 "u8_lc_map.txt"
+ {"\342\260\231", "ⱉ"},
+#line 721 "u8_lc_map.txt"
+ {"\342\222\271", "ⓓ"},
+ {""}, {""}, {""},
+#line 149 "u8_lc_map.txt"
+ {"\306\251", "ʃ"},
+#line 734 "u8_lc_map.txt"
+ {"\342\223\206", "ⓠ"},
+ {""}, {""},
+#line 712 "u8_lc_map.txt"
+ {"\341\277\270", "ὸ"},
+ {""}, {""}, {""}, {""}, {""}, {""},
+#line 783 "u8_lc_map.txt"
+ {"\342\260\247", "ⱗ"},
+ {""}, {""},
+#line 105 "u8_lc_map.txt"
+ {"\305\230", "ř"},
+ {""},
+#line 252 "u8_lc_map.txt"
+ {"\316\245", "υ"},
+#line 775 "u8_lc_map.txt"
+ {"\342\260\237", "ⱏ"},
+#line 168 "u8_lc_map.txt"
+ {"\307\236", "ǟ"},
+#line 585 "u8_lc_map.txt"
+ {"\341\272\270", "ẹ"},
+#line 582 "u8_lc_map.txt"
+ {"\341\272\262", "ẳ"},
+ {""}, {""},
+#line 174 "u8_lc_map.txt"
+ {"\307\252", "ǫ"},
+#line 699 "u8_lc_map.txt"
+ {"\341\277\211", "έ"},
+ {""},
+#line 996 "u8_lc_map.txt"
+ {"\360\220\220\227", "𐐿"},
+ {""},
+#line 361 "u8_lc_map.txt"
+ {"\322\256", "ү"},
+#line 727 "u8_lc_map.txt"
+ {"\342\222\277", "ⓙ"},
+ {""}, {""}, {""},
+#line 416 "u8_lc_map.txt"
+ {"\324\236", "ԟ"},
+ {""},
+#line 431 "u8_lc_map.txt"
+ {"\324\273", "ի"},
+#line 409 "u8_lc_map.txt"
+ {"\324\220", "ԑ"},
+ {""},
+#line 338 "u8_lc_map.txt"
+ {"\321\270", "ѹ"},
+ {""},
+#line 305 "u8_lc_map.txt"
+ {"\320\233", "л"},
+ {""}, {""},
+#line 85 "u8_lc_map.txt"
+ {"\304\256", "į"},
+#line 743 "u8_lc_map.txt"
+ {"\342\223\217", "ⓩ"},
+#line 254 "u8_lc_map.txt"
+ {"\316\247", "χ"},
+#line 984 "u8_lc_map.txt"
+ {"\360\220\220\213", "𐐳"},
+#line 92 "u8_lc_map.txt"
+ {"\304\275", "ľ"},
+#line 93 "u8_lc_map.txt"
+ {"\304\277", "ŀ"},
+ {""},
+#line 792 "u8_lc_map.txt"
+ {"\342\261\242", "ɫ"},
+ {""}, {""}, {""}, {""},
+#line 753 "u8_lc_map.txt"
+ {"\342\260\211", "ⰹ"},
+ {""}, {""},
+#line 51 "u8_lc_map.txt"
+ {"\303\223", "ó"},
+#line 335 "u8_lc_map.txt"
+ {"\321\262", "ѳ"},
+#line 429 "u8_lc_map.txt"
+ {"\324\271", "թ"},
+ {""},
+#line 404 "u8_lc_map.txt"
+ {"\324\206", "ԇ"},
+ {""}, {""},
+#line 334 "u8_lc_map.txt"
+ {"\321\260", "ѱ"},
+ {""}, {""}, {""},
+#line 233 "u8_lc_map.txt"
+ {"\316\221", "α"},
+#line 316 "u8_lc_map.txt"
{"\320\246", "ц"},
-#line 27 "u8_lc_map.txt"
+ {""}, {""},
+#line 43 "u8_lc_map.txt"
+ {"\303\213", "ë"},
+#line 645 "u8_lc_map.txt"
+ {"\341\274\272", "ἲ"},
+#line 248 "u8_lc_map.txt"
+ {"\316\240", "π"},
+ {""}, {""},
+#line 158 "u8_lc_map.txt"
+ {"\306\270", "ƹ"},
+#line 948 "u8_lc_map.txt"
+ {"\357\274\242", "b"},
+ {""}, {""}, {""},
+#line 398 "u8_lc_map.txt"
+ {"\323\272", "ӻ"},
+#line 386 "u8_lc_map.txt"
+ {"\323\242", "ӣ"},
+#line 799 "u8_lc_map.txt"
+ {"\342\261\256", "ɱ"},
+#line 1008 "u8_lc_map.txt"
+ {"\360\220\220\243", "𐑋"},
+ {""}, {""},
+#line 340 "u8_lc_map.txt"
+ {"\321\274", "ѽ"},
+#line 112 "u8_lc_map.txt"
+ {"\305\246", "ŧ"},
+ {""},
+#line 561 "u8_lc_map.txt"
+ {"\341\272\200", "ẁ"},
+#line 408 "u8_lc_map.txt"
+ {"\324\216", "ԏ"},
+#line 588 "u8_lc_map.txt"
+ {"\341\272\276", "ế"},
+#line 584 "u8_lc_map.txt"
+ {"\341\272\266", "ặ"},
+#line 773 "u8_lc_map.txt"
+ {"\342\260\235", "ⱍ"},
+ {""},
+#line 156 "u8_lc_map.txt"
+ {"\306\265", "ƶ"},
+#line 154 "u8_lc_map.txt"
+ {"\306\262", "ʋ"},
+ {""}, {""},
+#line 797 "u8_lc_map.txt"
+ {"\342\261\253", "ⱬ"},
+ {""}, {""}, {""}, {""}, {""},
+#line 744 "u8_lc_map.txt"
+ {"\342\260\200", "ⰰ"},
+ {""}, {""}, {""}, {""}, {""},
+#line 960 "u8_lc_map.txt"
+ {"\357\274\256", "n"},
+#line 293 "u8_lc_map.txt"
+ {"\320\217", "џ"},
+ {""}, {""}, {""},
+#line 1010 "u8_lc_map.txt"
+ {"\360\220\220\245", "𐑍"},
+ {""},
+#line 998 "u8_lc_map.txt"
+ {"\360\220\220\231", "𐑁"},
+ {""}, {""}, {""},
+#line 354 "u8_lc_map.txt"
+ {"\322\240", "ҡ"},
+#line 777 "u8_lc_map.txt"
+ {"\342\260\241", "ⱑ"},
+ {""}, {""},
+#line 159 "u8_lc_map.txt"
+ {"\306\274", "ƽ"},
+ {""},
+#line 957 "u8_lc_map.txt"
+ {"\357\274\253", "k"},
+ {""}, {""}, {""}, {""}, {""},
+#line 1012 "u8_lc_map.txt"
+ {"\360\220\220\247", "𐑏"},
+ {""}, {""},
+#line 78 "u8_lc_map.txt"
+ {"\304\240", "ġ"},
+#line 658 "u8_lc_map.txt"
+ {"\341\275\233", "ὓ"},
+ {""},
+#line 1004 "u8_lc_map.txt"
+ {"\360\220\220\237", "𐑇"},
+#line 143 "u8_lc_map.txt"
+ {"\306\235", "ɲ"},
+ {""}, {""}, {""},
+#line 235 "u8_lc_map.txt"
+ {"\316\223", "γ"},
+#line 632 "u8_lc_map.txt"
+ {"\341\274\233", "ἓ"},
+ {""}, {""}, {""}, {""},
+#line 720 "u8_lc_map.txt"
+ {"\342\222\270", "ⓒ"},
+ {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
+ {""}, {""}, {""}, {""},
+#line 441 "u8_lc_map.txt"
+ {"\325\205", "յ"},
+#line 312 "u8_lc_map.txt"
+ {"\320\242", "т"},
+ {""},
+#line 644 "u8_lc_map.txt"
+ {"\341\274\271", "ἱ"},
+ {""}, {""},
+#line 742 "u8_lc_map.txt"
+ {"\342\223\216", "ⓨ"},
+#line 966 "u8_lc_map.txt"
+ {"\357\274\264", "t"},
+ {""}, {""},
+#line 373 "u8_lc_map.txt"
+ {"\323\207", "ӈ"},
+ {""}, {""},
+#line 982 "u8_lc_map.txt"
+ {"\360\220\220\211", "𐐱"},
+ {""},
+#line 276 "u8_lc_map.txt"
+ {"\317\276", "ͼ"},
+ {""}, {""}, {""}, {""}, {""},
+#line 110 "u8_lc_map.txt"
+ {"\305\242", "ţ"},
+#line 741 "u8_lc_map.txt"
+ {"\342\223\215", "ⓧ"},
+ {""},
+#line 491 "u8_lc_map.txt"
+ {"\341\203\200", "ⴠ"},
+#line 392 "u8_lc_map.txt"
+ {"\323\256", "ӯ"},
+ {""}, {""}, {""}, {""}, {""}, {""},
+#line 371 "u8_lc_map.txt"
+ {"\323\203", "ӄ"},
+ {""}, {""}, {""},
+#line 650 "u8_lc_map.txt"
+ {"\341\274\277", "ἷ"},
+ {""},
+#line 654 "u8_lc_map.txt"
+ {"\341\275\213", "ὃ"},
+ {""},
+#line 180 "u8_lc_map.txt"
+ {"\307\270", "ǹ"},
+#line 141 "u8_lc_map.txt"
+ {"\306\230", "ƙ"},
+ {""}, {""}, {""},
+#line 341 "u8_lc_map.txt"
+ {"\321\276", "ѿ"},
+#line 624 "u8_lc_map.txt"
+ {"\341\274\213", "ἃ"},
+#line 266 "u8_lc_map.txt"
+ {"\317\246", "ϧ"},
+ {""}, {""}, {""}, {""}, {""}, {""},
+#line 1002 "u8_lc_map.txt"
+ {"\360\220\220\235", "𐑅"},
+#line 428 "u8_lc_map.txt"
+ {"\324\270", "ը"},
+ {""}, {""}, {""}, {""},
+#line 436 "u8_lc_map.txt"
+ {"\325\200", "հ"},
+#line 726 "u8_lc_map.txt"
+ {"\342\222\276", "ⓘ"},
+#line 718 "u8_lc_map.txt"
+ {"\342\222\266", "ⓐ"},
+ {""}, {""}, {""},
+#line 973 "u8_lc_map.txt"
+ {"\360\220\220\200", "𐐨"},
+ {""}, {""}, {""}, {""}, {""},
+#line 803 "u8_lc_map.txt"
+ {"\342\261\265", "ⱶ"},
+ {""}, {""},
+#line 425 "u8_lc_map.txt"
+ {"\324\265", "ե"},
+#line 422 "u8_lc_map.txt"
+ {"\324\262", "բ"},
+#line 329 "u8_lc_map.txt"
+ {"\321\246", "ѧ"},
+ {""}, {""},
+#line 166 "u8_lc_map.txt"
+ {"\307\231", "ǚ"},
+#line 733 "u8_lc_map.txt"
+ {"\342\223\205", "ⓟ"},
+ {""}, {""},
+#line 1006 "u8_lc_map.txt"
+ {"\360\220\220\241", "𐑉"},
+ {""}, {""},
+#line 376 "u8_lc_map.txt"
+ {"\323\215", "ӎ"},
+#line 661 "u8_lc_map.txt"
+ {"\341\275\250", "ὠ"},
+ {""}, {""},
+#line 182 "u8_lc_map.txt"
+ {"\307\274", "ǽ"},
+#line 259 "u8_lc_map.txt"
+ {"\317\217", "ϗ"},
+ {""}, {""},
+#line 285 "u8_lc_map.txt"
+ {"\320\207", "ї"},
+#line 635 "u8_lc_map.txt"
+ {"\341\274\250", "ἠ"},
+ {""}, {""}, {""}, {""},
+#line 967 "u8_lc_map.txt"
+ {"\357\274\265", "u"},
+ {""}, {""}, {""}, {""},
+#line 432 "u8_lc_map.txt"
+ {"\324\274", "լ"},
+ {""}, {""}, {""},
+#line 324 "u8_lc_map.txt"
+ {"\320\256", "ю"},
+ {""},
+#line 969 "u8_lc_map.txt"
+ {"\357\274\267", "w"},
+#line 657 "u8_lc_map.txt"
+ {"\341\275\231", "ὑ"},
+ {""},
+#line 97 "u8_lc_map.txt"
+ {"\305\207", "ň"},
+ {""},
+#line 281 "u8_lc_map.txt"
+ {"\320\203", "ѓ"},
+ {""}, {""}, {""},
+#line 630 "u8_lc_map.txt"
+ {"\341\274\231", "ἑ"},
+#line 385 "u8_lc_map.txt"
+ {"\323\240", "ӡ"},
+#line 299 "u8_lc_map.txt"
{"\320\225", "е"},
+ {""},
+#line 204 "u8_lc_map.txt"
+ {"\310\250", "ȩ"},
+ {""}, {""}, {""}, {""},
+#line 116 "u8_lc_map.txt"
+ {"\305\256", "ů"},
+#line 239 "u8_lc_map.txt"
+ {"\316\227", "η"},
+ {""},
+#line 732 "u8_lc_map.txt"
+ {"\342\223\204", "ⓞ"},
+#line 124 "u8_lc_map.txt"
+ {"\305\275", "ž"},
+#line 660 "u8_lc_map.txt"
+ {"\341\275\237", "ὗ"},
+#line 365 "u8_lc_map.txt"
+ {"\322\266", "ҷ"},
+#line 95 "u8_lc_map.txt"
+ {"\305\203", "ń"},
+ {""}, {""}, {""},
+#line 735 "u8_lc_map.txt"
+ {"\342\223\207", "ⓡ"},
+ {""}, {""}, {""},
+#line 274 "u8_lc_map.txt"
+ {"\317\272", "ϻ"},
+#line 264 "u8_lc_map.txt"
+ {"\317\242", "ϣ"},
+ {""},
+#line 315 "u8_lc_map.txt"
+ {"\320\245", "х"},
{""}, {""},
-#line 23 "u8_lc_map.txt"
+#line 89 "u8_lc_map.txt"
+ {"\304\266", "ķ"},
+ {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
+#line 643 "u8_lc_map.txt"
+ {"\341\274\270", "ἰ"},
+#line 134 "u8_lc_map.txt"
+ {"\306\217", "ə"},
+ {""}, {""},
+#line 401 "u8_lc_map.txt"
+ {"\324\200", "ԁ"},
+ {""}, {""}, {""}, {""}, {""}, {""},
+#line 291 "u8_lc_map.txt"
+ {"\320\215", "ѝ"},
+#line 652 "u8_lc_map.txt"
+ {"\341\275\211", "ὁ"},
+ {""},
+#line 339 "u8_lc_map.txt"
+ {"\321\272", "ѻ"},
+#line 327 "u8_lc_map.txt"
+ {"\321\242", "ѣ"},
+#line 317 "u8_lc_map.txt"
+ {"\320\247", "ч"},
+#line 224 "u8_lc_map.txt"
+ {"\315\262", "ͳ"},
+ {""},
+#line 41 "u8_lc_map.txt"
+ {"\303\211", "é"},
+#line 622 "u8_lc_map.txt"
+ {"\341\274\211", "ἁ"},
+ {""}, {""},
+#line 223 "u8_lc_map.txt"
+ {"\315\260", "ͱ"},
+ {""},
+#line 413 "u8_lc_map.txt"
+ {"\324\230", "ԙ"},
+ {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
+#line 272 "u8_lc_map.txt"
+ {"\317\267", "ϸ"},
+ {""}, {""}, {""}, {""},
+#line 295 "u8_lc_map.txt"
{"\320\221", "б"},
-#line 44 "u8_lc_map.txt"
- {"\320\245", "х"},
-#line 26 "u8_lc_map.txt"
- {"\320\224", "д"},
+#line 451 "u8_lc_map.txt"
+ {"\325\217", "տ"},
+ {""}, {""}, {""}, {""},
+#line 310 "u8_lc_map.txt"
+ {"\320\240", "р"},
{""}, {""},
-#line 9 "u8_lc_map.txt"
- {"\303\221", "ñ"},
-#line 43 "u8_lc_map.txt"
- {"\320\244", "ф"},
-#line 24 "u8_lc_map.txt"
- {"\320\222", "в"},
+#line 375 "u8_lc_map.txt"
+ {"\323\213", "ӌ"},
+ {""}, {""}, {""},
+#line 659 "u8_lc_map.txt"
+ {"\341\275\235", "ὕ"},
+#line 183 "u8_lc_map.txt"
+ {"\307\276", "ǿ"},
+#line 146 "u8_lc_map.txt"
+ {"\306\242", "ƣ"},
+#line 167 "u8_lc_map.txt"
+ {"\307\233", "ǜ"},
+ {""}, {""}, {""}, {""},
+#line 634 "u8_lc_map.txt"
+ {"\341\274\235", "ἕ"},
{""}, {""},
-#line 28 "u8_lc_map.txt"
- {"\320\201", "ё"},
-#line 42 "u8_lc_map.txt"
- {"\320\243", "у"},
-#line 22 "u8_lc_map.txt"
- {"\320\220", "а"},
+#line 255 "u8_lc_map.txt"
+ {"\316\250", "ψ"},
+ {""},
+#line 109 "u8_lc_map.txt"
+ {"\305\240", "š"},
{""}, {""},
-#line 6 "u8_lc_map.txt"
- {"\303\201", "á"},
-#line 8 "u8_lc_map.txt"
- {"\303\215", "í"},
-#line 21 "u8_lc_map.txt"
- {"\303\212", "ê"}
+#line 434 "u8_lc_map.txt"
+ {"\324\276", "ծ"},
+ {""}, {""}, {""}, {""}, {""},
+#line 649 "u8_lc_map.txt"
+ {"\341\274\276", "ἶ"},
+ {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
+#line 972 "u8_lc_map.txt"
+ {"\357\274\272", "z"},
+#line 172 "u8_lc_map.txt"
+ {"\307\246", "ǧ"},
+#line 791 "u8_lc_map.txt"
+ {"\342\261\240", "ⱡ"},
+ {""}, {""},
+#line 249 "u8_lc_map.txt"
+ {"\316\241", "ρ"},
+ {""}, {""}, {""},
+#line 270 "u8_lc_map.txt"
+ {"\317\256", "ϯ"},
+ {""}, {""}, {""},
+#line 275 "u8_lc_map.txt"
+ {"\317\275", "ͻ"},
+#line 277 "u8_lc_map.txt"
+ {"\317\277", "ͽ"},
+ {""},
+#line 420 "u8_lc_map.txt"
+ {"\324\246", "ԧ"},
+#line 731 "u8_lc_map.txt"
+ {"\342\223\203", "ⓝ"},
+ {""}, {""},
+#line 157 "u8_lc_map.txt"
+ {"\306\267", "ʒ"},
+ {""},
+#line 668 "u8_lc_map.txt"
+ {"\341\275\257", "ὧ"},
+ {""},
+#line 228 "u8_lc_map.txt"
+ {"\316\211", "ή"},
+ {""}, {""}, {""}, {""},
+#line 358 "u8_lc_map.txt"
+ {"\322\250", "ҩ"},
+#line 642 "u8_lc_map.txt"
+ {"\341\274\257", "ἧ"},
+ {""}, {""}, {""},
+#line 297 "u8_lc_map.txt"
+ {"\320\223", "г"},
+ {""}, {""}, {""}, {""},
+#line 333 "u8_lc_map.txt"
+ {"\321\256", "ѯ"},
+ {""}, {""}, {""}, {""},
+#line 82 "u8_lc_map.txt"
+ {"\304\250", "ĩ"},
+ {""},
+#line 161 "u8_lc_map.txt"
+ {"\307\217", "ǐ"},
+ {""}, {""},
+#line 289 "u8_lc_map.txt"
+ {"\320\213", "ћ"},
+ {""}, {""}, {""}, {""}, {""},
+#line 396 "u8_lc_map.txt"
+ {"\323\266", "ӷ"},
+ {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
+#line 129 "u8_lc_map.txt"
+ {"\306\207", "ƈ"},
+ {""}, {""},
+#line 801 "u8_lc_map.txt"
+ {"\342\261\260", "ɒ"},
+ {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
+ {""}, {""},
+#line 151 "u8_lc_map.txt"
+ {"\306\256", "ʈ"},
+ {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
+ {""}, {""}, {""}, {""}, {""}, {""}, {""},
+#line 962 "u8_lc_map.txt"
+ {"\357\274\260", "p"},
+#line 971 "u8_lc_map.txt"
+ {"\357\274\271", "y"},
+ {""},
+#line 181 "u8_lc_map.txt"
+ {"\307\272", "ǻ"},
+#line 170 "u8_lc_map.txt"
+ {"\307\242", "ǣ"},
+#line 805 "u8_lc_map.txt"
+ {"\342\261\277", "ɀ"},
+ {""}, {""},
+#line 443 "u8_lc_map.txt"
+ {"\325\207", "շ"},
+ {""},
+#line 263 "u8_lc_map.txt"
+ {"\317\240", "ϡ"},
+ {""}, {""}, {""}, {""}, {""}, {""}, {""},
+#line 430 "u8_lc_map.txt"
+ {"\324\272", "ժ"},
+#line 418 "u8_lc_map.txt"
+ {"\324\242", "ԣ"},
+ {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
+#line 963 "u8_lc_map.txt"
+ {"\357\274\261", "q"},
+#line 439 "u8_lc_map.txt"
+ {"\325\203", "ճ"},
+ {""}, {""}, {""}, {""}, {""},
+#line 457 "u8_lc_map.txt"
+ {"\325\225", "օ"},
+ {""}, {""}, {""},
+#line 326 "u8_lc_map.txt"
+ {"\321\240", "ѡ"},
+ {""}, {""}, {""},
+#line 739 "u8_lc_map.txt"
+ {"\342\223\213", "ⓥ"},
+#line 247 "u8_lc_map.txt"
+ {"\316\237", "ο"},
+ {""}, {""}, {""}, {""},
+#line 148 "u8_lc_map.txt"
+ {"\306\247", "ƨ"},
+ {""}, {""}, {""},
+#line 179 "u8_lc_map.txt"
+ {"\307\267", "ƿ"},
+#line 793 "u8_lc_map.txt"
+ {"\342\261\243", "ᵽ"},
+ {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
+#line 120 "u8_lc_map.txt"
+ {"\305\266", "ŷ"},
+ {""}, {""}, {""}, {""},
+#line 427 "u8_lc_map.txt"
+ {"\324\267", "է"},
+ {""}, {""}, {""}, {""},
+#line 136 "u8_lc_map.txt"
+ {"\306\221", "ƒ"},
+ {""}, {""}, {""}, {""}, {""},
+#line 145 "u8_lc_map.txt"
+ {"\306\240", "ơ"},
+ {""}, {""}, {""},
+#line 949 "u8_lc_map.txt"
+ {"\357\274\243", "c"},
+#line 449 "u8_lc_map.txt"
+ {"\325\215", "ս"},
+ {""}, {""}, {""},
+#line 301 "u8_lc_map.txt"
+ {"\320\227", "з"},
+ {""}, {""}, {""}, {""},
+#line 954 "u8_lc_map.txt"
+ {"\357\274\250", "h"},
+ {""}, {""}, {""},
+#line 389 "u8_lc_map.txt"
+ {"\323\250", "ө"},
+ {""}, {""}, {""}, {""}, {""}, {""}, {""},
+#line 795 "u8_lc_map.txt"
+ {"\342\261\247", "ⱨ"},
+ {""}, {""}, {""}, {""}, {""}, {""},
+#line 176 "u8_lc_map.txt"
+ {"\307\256", "ǯ"},
+#line 453 "u8_lc_map.txt"
+ {"\325\221", "ց"},
+ {""}, {""},
+#line 951 "u8_lc_map.txt"
+ {"\357\274\245", "e"},
+ {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
+#line 164 "u8_lc_map.txt"
+ {"\307\225", "ǖ"},
+ {""}, {""}, {""}, {""},
+#line 802 "u8_lc_map.txt"
+ {"\342\261\262", "ⱳ"},
+#line 433 "u8_lc_map.txt"
+ {"\324\275", "խ"},
+#line 435 "u8_lc_map.txt"
+ {"\324\277", "կ"},
+ {""},
+#line 953 "u8_lc_map.txt"
+ {"\357\274\247", "g"},
+ {""}, {""}, {""}, {""}, {""}, {""}, {""},
+#line 374 "u8_lc_map.txt"
+ {"\323\211", "ӊ"},
+ {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
+#line 137 "u8_lc_map.txt"
+ {"\306\223", "ɠ"},
+ {""}, {""}, {""}, {""}, {""},
+#line 970 "u8_lc_map.txt"
+ {"\357\274\270", "x"},
+#line 964 "u8_lc_map.txt"
+ {"\357\274\262", "r"},
+ {""}, {""}, {""}, {""}, {""}, {""}, {""},
+#line 132 "u8_lc_map.txt"
+ {"\306\213", "ƌ"},
+ {""}, {""}, {""}, {""}, {""}, {""},
+#line 160 "u8_lc_map.txt"
+ {"\307\215", "ǎ"},
+ {""}, {""}, {""},
+#line 737 "u8_lc_map.txt"
+ {"\342\223\211", "ⓣ"},
+ {""}, {""}, {""},
+#line 318 "u8_lc_map.txt"
+ {"\320\250", "ш"},
+ {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
+#line 455 "u8_lc_map.txt"
+ {"\325\223", "փ"},
+ {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
+#line 113 "u8_lc_map.txt"
+ {"\305\250", "ũ"},
+#line 162 "u8_lc_map.txt"
+ {"\307\221", "ǒ"},
+#line 804 "u8_lc_map.txt"
+ {"\342\261\276", "ȿ"},
+ {""}, {""},
+#line 447 "u8_lc_map.txt"
+ {"\325\213", "ջ"},
+#line 311 "u8_lc_map.txt"
+ {"\320\241", "с"},
+#line 169 "u8_lc_map.txt"
+ {"\307\240", "ǡ"},
+ {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
+#line 337 "u8_lc_map.txt"
+ {"\321\266", "ѷ"},
+ {""}, {""}, {""}, {""}, {""},
+#line 417 "u8_lc_map.txt"
+ {"\324\240", "ԡ"},
+ {""}, {""},
+#line 287 "u8_lc_map.txt"
+ {"\320\211", "љ"},
+#line 153 "u8_lc_map.txt"
+ {"\306\261", "ʊ"},
+ {""}, {""},
+#line 728 "u8_lc_map.txt"
+ {"\342\223\200", "ⓚ"},
+ {""}, {""},
+#line 968 "u8_lc_map.txt"
+ {"\357\274\266", "v"},
+ {""}, {""},
+#line 325 "u8_lc_map.txt"
+ {"\320\257", "я"},
+ {""}, {""}, {""}, {""}, {""}, {""},
+#line 800 "u8_lc_map.txt"
+ {"\342\261\257", "ɐ"},
+ {""}, {""}, {""}, {""},
+#line 947 "u8_lc_map.txt"
+ {"\357\274\241", "a"},
+ {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
+ {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
+ {""}, {""}, {""}, {""}, {""},
+#line 961 "u8_lc_map.txt"
+ {"\357\274\257", "o"},
+ {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
+#line 163 "u8_lc_map.txt"
+ {"\307\223", "ǔ"},
+ {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
+ {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
+ {""}, {""},
+#line 140 "u8_lc_map.txt"
+ {"\306\227", "ɨ"},
+ {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
+ {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
+ {""}, {""}, {""}, {""}, {""},
+#line 267 "u8_lc_map.txt"
+ {"\317\250", "ϩ"},
+ {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
+ {""}, {""}, {""}, {""}, {""}, {""}, {""},
+#line 309 "u8_lc_map.txt"
+ {"\320\237", "п"},
+ {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
+ {""}, {""}, {""},
+#line 330 "u8_lc_map.txt"
+ {"\321\250", "ѩ"},
+ {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
+ {""}, {""}, {""}, {""}, {""}, {""},
+#line 421 "u8_lc_map.txt"
+ {"\324\261", "ա"},
+ {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
+ {""}, {""}, {""}, {""}, {""},
+#line 178 "u8_lc_map.txt"
+ {"\307\266", "ƕ"},
+ {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
+ {""}, {""}, {""}, {""}, {""},
+#line 426 "u8_lc_map.txt"
+ {"\324\266", "զ"},
+ {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
+ {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
+ {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
+ {""}, {""},
+#line 165 "u8_lc_map.txt"
+ {"\307\227", "ǘ"},
+ {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
+#line 130 "u8_lc_map.txt"
+ {"\306\211", "ɖ"},
+ {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
+#line 152 "u8_lc_map.txt"
+ {"\306\257", "ư"},
+ {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
+ {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
+ {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
+ {""}, {""},
+#line 445 "u8_lc_map.txt"
+ {"\325\211", "չ"},
+ {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
+ {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
+ {""}, {""}, {""}, {""},
+#line 225 "u8_lc_map.txt"
+ {"\315\266", "ͷ"},
+ {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
+ {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
+ {""}, {""}, {""},
+#line 173 "u8_lc_map.txt"
+ {"\307\250", "ǩ"},
+ {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
+ {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
+ {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
+ {""}, {""}, {""}, {""},
+#line 144 "u8_lc_map.txt"
+ {"\306\237", "ɵ"}
};
if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
@@ -227,5 +2707,3 @@ u8_lc_in_word_set (str, len)
}
return 0;
}
-#line 55 "u8_lc_map.txt"
-
diff --git a/u8_lc_map.txt b/u8_lc_map.txt
index 43b6927f..e151bba1 100644
--- a/u8_lc_map.txt
+++ b/u8_lc_map.txt
@@ -3,29 +3,300 @@ struct u8_case_map_t {
const char *lower;
};
%%
+A, "a"
+B, "b"
+C, "c"
+D, "d"
+E, "e"
+F, "f"
+G, "g"
+H, "h"
+I, "i"
+J, "j"
+K, "k"
+L, "l"
+M, "m"
+N, "n"
+O, "o"
+P, "p"
+Q, "q"
+R, "r"
+S, "s"
+T, "t"
+U, "u"
+V, "v"
+W, "w"
+X, "x"
+Y, "y"
+Z, "z"
+À, "à"
Á, "á"
-É, "é"
-Í, "í"
-Ñ, "ñ"
-Ó, "ó"
-Ú, "ú"
-Ü, "ü"
+Â, "â"
+Ã, "ã"
Ä, "ä"
-Ö, "ö"
Å, "å"
Æ, "æ"
-Ø, "ø"
-À, "à"
Ç, "ç"
È, "è"
+É, "é"
Ê, "ê"
+Ë, "ë"
+Ì, "ì"
+Í, "í"
+Î, "î"
+Ï, "ï"
+Ð, "ð"
+Ñ, "ñ"
+Ò, "ò"
+Ó, "ó"
+Ô, "ô"
+Õ, "õ"
+Ö, "ö"
+Ø, "ø"
+Ù, "ù"
+Ú, "ú"
+Û, "û"
+Ü, "ü"
+Ý, "ý"
+Þ, "þ"
+Ā, "ā"
+Ă, "ă"
+Ą, "ą"
+Ć, "ć"
+Ĉ, "ĉ"
+Ċ, "ċ"
+Č, "č"
+Ď, "ď"
+Đ, "đ"
+Ē, "ē"
+Ĕ, "ĕ"
+Ė, "ė"
+Ę, "ę"
+Ě, "ě"
+Ĝ, "ĝ"
+Ğ, "ğ"
+Ġ, "ġ"
+Ģ, "ģ"
+Ĥ, "ĥ"
+Ħ, "ħ"
+Ĩ, "ĩ"
+Ī, "ī"
+Ĭ, "ĭ"
+Į, "į"
+İ, "i"
+IJ, "ij"
+Ĵ, "ĵ"
+Ķ, "ķ"
+Ĺ, "ĺ"
+Ļ, "ļ"
+Ľ, "ľ"
+Ŀ, "ŀ"
+Ł, "ł"
+Ń, "ń"
+Ņ, "ņ"
+Ň, "ň"
+Ŋ, "ŋ"
+Ō, "ō"
+Ŏ, "ŏ"
+Ő, "ő"
+Œ, "œ"
+Ŕ, "ŕ"
+Ŗ, "ŗ"
+Ř, "ř"
+Ś, "ś"
+Ŝ, "ŝ"
+Ş, "ş"
+Š, "š"
+Ţ, "ţ"
+Ť, "ť"
+Ŧ, "ŧ"
+Ũ, "ũ"
+Ū, "ū"
+Ŭ, "ŭ"
+Ů, "ů"
+Ű, "ű"
+Ų, "ų"
+Ŵ, "ŵ"
+Ŷ, "ŷ"
+Ÿ, "ÿ"
+Ź, "ź"
+Ż, "ż"
+Ž, "ž"
+Ɓ, "ɓ"
+Ƃ, "ƃ"
+Ƅ, "ƅ"
+Ɔ, "ɔ"
+Ƈ, "ƈ"
+Ɖ, "ɖ"
+Ɗ, "ɗ"
+Ƌ, "ƌ"
+Ǝ, "ǝ"
+Ə, "ə"
+Ɛ, "ɛ"
+Ƒ, "ƒ"
+Ɠ, "ɠ"
+Ɣ, "ɣ"
+Ɩ, "ɩ"
+Ɨ, "ɨ"
+Ƙ, "ƙ"
+Ɯ, "ɯ"
+Ɲ, "ɲ"
+Ɵ, "ɵ"
+Ơ, "ơ"
+Ƣ, "ƣ"
+Ƥ, "ƥ"
+Ƨ, "ƨ"
+Ʃ, "ʃ"
+Ƭ, "ƭ"
+Ʈ, "ʈ"
+Ư, "ư"
+Ʊ, "ʊ"
+Ʋ, "ʋ"
+Ƴ, "ƴ"
+Ƶ, "ƶ"
+Ʒ, "ʒ"
+Ƹ, "ƹ"
+Ƽ, "ƽ"
+Ǎ, "ǎ"
+Ǐ, "ǐ"
+Ǒ, "ǒ"
+Ǔ, "ǔ"
+Ǖ, "ǖ"
+Ǘ, "ǘ"
+Ǚ, "ǚ"
+Ǜ, "ǜ"
+Ǟ, "ǟ"
+Ǡ, "ǡ"
+Ǣ, "ǣ"
+Ǥ, "ǥ"
+Ǧ, "ǧ"
+Ǩ, "ǩ"
+Ǫ, "ǫ"
+Ǭ, "ǭ"
+Ǯ, "ǯ"
+Ǵ, "ǵ"
+Ƕ, "ƕ"
+Ƿ, "ƿ"
+Ǹ, "ǹ"
+Ǻ, "ǻ"
+Ǽ, "ǽ"
+Ǿ, "ǿ"
+Ȁ, "ȁ"
+Ȃ, "ȃ"
+Ȅ, "ȅ"
+Ȇ, "ȇ"
+Ȉ, "ȉ"
+Ȋ, "ȋ"
+Ȍ, "ȍ"
+Ȏ, "ȏ"
+Ȑ, "ȑ"
+Ȓ, "ȓ"
+Ȕ, "ȕ"
+Ȗ, "ȗ"
+Ș, "ș"
+Ț, "ț"
+Ȝ, "ȝ"
+Ȟ, "ȟ"
+Ƞ, "ƞ"
+Ȣ, "ȣ"
+Ȥ, "ȥ"
+Ȧ, "ȧ"
+Ȩ, "ȩ"
+Ȫ, "ȫ"
+Ȭ, "ȭ"
+Ȯ, "ȯ"
+Ȱ, "ȱ"
+Ȳ, "ȳ"
+Ⱥ, "ⱥ"
+Ȼ, "ȼ"
+Ƚ, "ƚ"
+Ⱦ, "ⱦ"
+Ɂ, "ɂ"
+Ƀ, "ƀ"
+Ʉ, "ʉ"
+Ʌ, "ʌ"
+Ɇ, "ɇ"
+Ɉ, "ɉ"
+Ɋ, "ɋ"
+Ɍ, "ɍ"
+Ɏ, "ɏ"
+Ͱ, "ͱ"
+Ͳ, "ͳ"
+Ͷ, "ͷ"
+Ά, "ά"
+Έ, "έ"
+Ή, "ή"
+Ί, "ί"
+Ό, "ό"
+Ύ, "ύ"
+Ώ, "ώ"
+Α, "α"
+Β, "β"
+Γ, "γ"
+Δ, "δ"
+Ε, "ε"
+Ζ, "ζ"
+Η, "η"
+Θ, "θ"
+Ι, "ι"
+Κ, "κ"
+Λ, "λ"
+Μ, "μ"
+Ν, "ν"
+Ξ, "ξ"
+Ο, "ο"
+Π, "π"
+Ρ, "ρ"
+Σ, "σ"
+Τ, "τ"
+Υ, "υ"
+Φ, "φ"
+Χ, "χ"
+Ψ, "ψ"
+Ω, "ω"
+Ϊ, "ϊ"
+Ϋ, "ϋ"
+Ϗ, "ϗ"
+Ϛ, "ϛ"
+Ϝ, "ϝ"
+Ϟ, "ϟ"
+Ϡ, "ϡ"
+Ϣ, "ϣ"
+Ϥ, "ϥ"
+Ϧ, "ϧ"
+Ϩ, "ϩ"
+Ϫ, "ϫ"
+Ϭ, "ϭ"
+Ϯ, "ϯ"
+ϴ, "θ"
+Ϸ, "ϸ"
+Ϲ, "ϲ"
+Ϻ, "ϻ"
+Ͻ, "ͻ"
+Ͼ, "ͼ"
+Ͽ, "ͽ"
+Ѐ, "ѐ"
+Ё, "ё"
+Ђ, "ђ"
+Ѓ, "ѓ"
+Є, "є"
+Ѕ, "ѕ"
+І, "і"
+Ї, "ї"
+Ј, "ј"
+Љ, "љ"
+Њ, "њ"
+Ћ, "ћ"
+Ќ, "ќ"
+Ѝ, "ѝ"
+Ў, "ў"
+Џ, "џ"
А, "а"
Б, "б"
В, "в"
Г, "г"
Д, "д"
Е, "е"
-Ё, "ё"
Ж, "ж"
З, "з"
И, "и"
@@ -35,8 +306,8 @@ struct u8_case_map_t {
М, "м"
Н, "н"
О, "о"
-Р, "р"
П, "п"
+Р, "р"
С, "с"
Т, "т"
У, "у"
@@ -52,4 +323,690 @@ struct u8_case_map_t {
Э, "э"
Ю, "ю"
Я, "я"
-%%
+Ѡ, "ѡ"
+Ѣ, "ѣ"
+Ѥ, "ѥ"
+Ѧ, "ѧ"
+Ѩ, "ѩ"
+Ѫ, "ѫ"
+Ѭ, "ѭ"
+Ѯ, "ѯ"
+Ѱ, "ѱ"
+Ѳ, "ѳ"
+Ѵ, "ѵ"
+Ѷ, "ѷ"
+Ѹ, "ѹ"
+Ѻ, "ѻ"
+Ѽ, "ѽ"
+Ѿ, "ѿ"
+Ҁ, "ҁ"
+Ҋ, "ҋ"
+Ҍ, "ҍ"
+Ҏ, "ҏ"
+Ґ, "ґ"
+Ғ, "ғ"
+Ҕ, "ҕ"
+Җ, "җ"
+Ҙ, "ҙ"
+Қ, "қ"
+Ҝ, "ҝ"
+Ҟ, "ҟ"
+Ҡ, "ҡ"
+Ң, "ң"
+Ҥ, "ҥ"
+Ҧ, "ҧ"
+Ҩ, "ҩ"
+Ҫ, "ҫ"
+Ҭ, "ҭ"
+Ү, "ү"
+Ұ, "ұ"
+Ҳ, "ҳ"
+Ҵ, "ҵ"
+Ҷ, "ҷ"
+Ҹ, "ҹ"
+Һ, "һ"
+Ҽ, "ҽ"
+Ҿ, "ҿ"
+Ӂ, "ӂ"
+Ӄ, "ӄ"
+Ӆ, "ӆ"
+Ӈ, "ӈ"
+Ӊ, "ӊ"
+Ӌ, "ӌ"
+Ӎ, "ӎ"
+Ӑ, "ӑ"
+Ӓ, "ӓ"
+Ӕ, "ӕ"
+Ӗ, "ӗ"
+Ә, "ә"
+Ӛ, "ӛ"
+Ӝ, "ӝ"
+Ӟ, "ӟ"
+Ӡ, "ӡ"
+Ӣ, "ӣ"
+Ӥ, "ӥ"
+Ӧ, "ӧ"
+Ө, "ө"
+Ӫ, "ӫ"
+Ӭ, "ӭ"
+Ӯ, "ӯ"
+Ӱ, "ӱ"
+Ӳ, "ӳ"
+Ӵ, "ӵ"
+Ӷ, "ӷ"
+Ӹ, "ӹ"
+Ӻ, "ӻ"
+Ӽ, "ӽ"
+Ӿ, "ӿ"
+Ԁ, "ԁ"
+Ԃ, "ԃ"
+Ԅ, "ԅ"
+Ԇ, "ԇ"
+Ԉ, "ԉ"
+Ԋ, "ԋ"
+Ԍ, "ԍ"
+Ԏ, "ԏ"
+Ԑ, "ԑ"
+Ԓ, "ԓ"
+Ԕ, "ԕ"
+Ԗ, "ԗ"
+Ԙ, "ԙ"
+Ԛ, "ԛ"
+Ԝ, "ԝ"
+Ԟ, "ԟ"
+Ԡ, "ԡ"
+Ԣ, "ԣ"
+Ԥ, "ԥ"
+Ԧ, "ԧ"
+Ա, "ա"
+Բ, "բ"
+Գ, "գ"
+Դ, "դ"
+Ե, "ե"
+Զ, "զ"
+Է, "է"
+Ը, "ը"
+Թ, "թ"
+Ժ, "ժ"
+Ի, "ի"
+Լ, "լ"
+Խ, "խ"
+Ծ, "ծ"
+Կ, "կ"
+Հ, "հ"
+Ձ, "ձ"
+Ղ, "ղ"
+Ճ, "ճ"
+Մ, "մ"
+Յ, "յ"
+Ն, "ն"
+Շ, "շ"
+Ո, "ո"
+Չ, "չ"
+Պ, "պ"
+Ջ, "ջ"
+Ռ, "ռ"
+Ս, "ս"
+Վ, "վ"
+Տ, "տ"
+Ր, "ր"
+Ց, "ց"
+Ւ, "ւ"
+Փ, "փ"
+Ք, "ք"
+Օ, "օ"
+Ֆ, "ֆ"
+Ⴀ, "ⴀ"
+Ⴁ, "ⴁ"
+Ⴂ, "ⴂ"
+Ⴃ, "ⴃ"
+Ⴄ, "ⴄ"
+Ⴅ, "ⴅ"
+Ⴆ, "ⴆ"
+Ⴇ, "ⴇ"
+Ⴈ, "ⴈ"
+Ⴉ, "ⴉ"
+Ⴊ, "ⴊ"
+Ⴋ, "ⴋ"
+Ⴌ, "ⴌ"
+Ⴍ, "ⴍ"
+Ⴎ, "ⴎ"
+Ⴏ, "ⴏ"
+Ⴐ, "ⴐ"
+Ⴑ, "ⴑ"
+Ⴒ, "ⴒ"
+Ⴓ, "ⴓ"
+Ⴔ, "ⴔ"
+Ⴕ, "ⴕ"
+Ⴖ, "ⴖ"
+Ⴗ, "ⴗ"
+Ⴘ, "ⴘ"
+Ⴙ, "ⴙ"
+Ⴚ, "ⴚ"
+Ⴛ, "ⴛ"
+Ⴜ, "ⴜ"
+Ⴝ, "ⴝ"
+Ⴞ, "ⴞ"
+Ⴟ, "ⴟ"
+Ⴠ, "ⴠ"
+Ⴡ, "ⴡ"
+Ⴢ, "ⴢ"
+Ⴣ, "ⴣ"
+Ⴤ, "ⴤ"
+Ⴥ, "ⴥ"
+Ḁ, "ḁ"
+Ḃ, "ḃ"
+Ḅ, "ḅ"
+Ḇ, "ḇ"
+Ḉ, "ḉ"
+Ḋ, "ḋ"
+Ḍ, "ḍ"
+Ḏ, "ḏ"
+Ḑ, "ḑ"
+Ḓ, "ḓ"
+Ḕ, "ḕ"
+Ḗ, "ḗ"
+Ḙ, "ḙ"
+Ḛ, "ḛ"
+Ḝ, "ḝ"
+Ḟ, "ḟ"
+Ḡ, "ḡ"
+Ḣ, "ḣ"
+Ḥ, "ḥ"
+Ḧ, "ḧ"
+Ḩ, "ḩ"
+Ḫ, "ḫ"
+Ḭ, "ḭ"
+Ḯ, "ḯ"
+Ḱ, "ḱ"
+Ḳ, "ḳ"
+Ḵ, "ḵ"
+Ḷ, "ḷ"
+Ḹ, "ḹ"
+Ḻ, "ḻ"
+Ḽ, "ḽ"
+Ḿ, "ḿ"
+Ṁ, "ṁ"
+Ṃ, "ṃ"
+Ṅ, "ṅ"
+Ṇ, "ṇ"
+Ṉ, "ṉ"
+Ṋ, "ṋ"
+Ṍ, "ṍ"
+Ṏ, "ṏ"
+Ṑ, "ṑ"
+Ṓ, "ṓ"
+Ṕ, "ṕ"
+Ṗ, "ṗ"
+Ṙ, "ṙ"
+Ṛ, "ṛ"
+Ṝ, "ṝ"
+Ṟ, "ṟ"
+Ṡ, "ṡ"
+Ṣ, "ṣ"
+Ṥ, "ṥ"
+Ṧ, "ṧ"
+Ṩ, "ṩ"
+Ṫ, "ṫ"
+Ṭ, "ṭ"
+Ṯ, "ṯ"
+Ṱ, "ṱ"
+Ṳ, "ṳ"
+Ṵ, "ṵ"
+Ṷ, "ṷ"
+Ṹ, "ṹ"
+Ṻ, "ṻ"
+Ṽ, "ṽ"
+Ṿ, "ṿ"
+Ẁ, "ẁ"
+Ẃ, "ẃ"
+Ẅ, "ẅ"
+Ẇ, "ẇ"
+Ẉ, "ẉ"
+Ẋ, "ẋ"
+Ẍ, "ẍ"
+Ẏ, "ẏ"
+Ẑ, "ẑ"
+Ẓ, "ẓ"
+Ẕ, "ẕ"
+ẞ, "ß"
+Ạ, "ạ"
+Ả, "ả"
+Ấ, "ấ"
+Ầ, "ầ"
+Ẩ, "ẩ"
+Ẫ, "ẫ"
+Ậ, "ậ"
+Ắ, "ắ"
+Ằ, "ằ"
+Ẳ, "ẳ"
+Ẵ, "ẵ"
+Ặ, "ặ"
+Ẹ, "ẹ"
+Ẻ, "ẻ"
+Ẽ, "ẽ"
+Ế, "ế"
+Ề, "ề"
+Ể, "ể"
+Ễ, "ễ"
+Ệ, "ệ"
+Ỉ, "ỉ"
+Ị, "ị"
+Ọ, "ọ"
+Ỏ, "ỏ"
+Ố, "ố"
+Ồ, "ồ"
+Ổ, "ổ"
+Ỗ, "ỗ"
+Ộ, "ộ"
+Ớ, "ớ"
+Ờ, "ờ"
+Ở, "ở"
+Ỡ, "ỡ"
+Ợ, "ợ"
+Ụ, "ụ"
+Ủ, "ủ"
+Ứ, "ứ"
+Ừ, "ừ"
+Ử, "ử"
+Ữ, "ữ"
+Ự, "ự"
+Ỳ, "ỳ"
+Ỵ, "ỵ"
+Ỷ, "ỷ"
+Ỹ, "ỹ"
+Ỻ, "ỻ"
+Ỽ, "ỽ"
+Ỿ, "ỿ"
+Ἀ, "ἀ"
+Ἁ, "ἁ"
+Ἂ, "ἂ"
+Ἃ, "ἃ"
+Ἄ, "ἄ"
+Ἅ, "ἅ"
+Ἆ, "ἆ"
+Ἇ, "ἇ"
+Ἐ, "ἐ"
+Ἑ, "ἑ"
+Ἒ, "ἒ"
+Ἓ, "ἓ"
+Ἔ, "ἔ"
+Ἕ, "ἕ"
+Ἠ, "ἠ"
+Ἡ, "ἡ"
+Ἢ, "ἢ"
+Ἣ, "ἣ"
+Ἤ, "ἤ"
+Ἥ, "ἥ"
+Ἦ, "ἦ"
+Ἧ, "ἧ"
+Ἰ, "ἰ"
+Ἱ, "ἱ"
+Ἲ, "ἲ"
+Ἳ, "ἳ"
+Ἴ, "ἴ"
+Ἵ, "ἵ"
+Ἶ, "ἶ"
+Ἷ, "ἷ"
+Ὀ, "ὀ"
+Ὁ, "ὁ"
+Ὂ, "ὂ"
+Ὃ, "ὃ"
+Ὄ, "ὄ"
+Ὅ, "ὅ"
+Ὑ, "ὑ"
+Ὓ, "ὓ"
+Ὕ, "ὕ"
+Ὗ, "ὗ"
+Ὠ, "ὠ"
+Ὡ, "ὡ"
+Ὢ, "ὢ"
+Ὣ, "ὣ"
+Ὤ, "ὤ"
+Ὥ, "ὥ"
+Ὦ, "ὦ"
+Ὧ, "ὧ"
+ᾈ, "ᾀ"
+ᾉ, "ᾁ"
+ᾊ, "ᾂ"
+ᾋ, "ᾃ"
+ᾌ, "ᾄ"
+ᾍ, "ᾅ"
+ᾎ, "ᾆ"
+ᾏ, "ᾇ"
+ᾘ, "ᾐ"
+ᾙ, "ᾑ"
+ᾚ, "ᾒ"
+ᾛ, "ᾓ"
+ᾜ, "ᾔ"
+ᾝ, "ᾕ"
+ᾞ, "ᾖ"
+ᾟ, "ᾗ"
+ᾨ, "ᾠ"
+ᾩ, "ᾡ"
+ᾪ, "ᾢ"
+ᾫ, "ᾣ"
+ᾬ, "ᾤ"
+ᾭ, "ᾥ"
+ᾮ, "ᾦ"
+ᾯ, "ᾧ"
+Ᾰ, "ᾰ"
+Ᾱ, "ᾱ"
+Ὰ, "ὰ"
+Ά, "ά"
+ᾼ, "ᾳ"
+Ὲ, "ὲ"
+Έ, "έ"
+Ὴ, "ὴ"
+Ή, "ή"
+ῌ, "ῃ"
+Ῐ, "ῐ"
+Ῑ, "ῑ"
+Ὶ, "ὶ"
+Ί, "ί"
+Ῠ, "ῠ"
+Ῡ, "ῡ"
+Ὺ, "ὺ"
+Ύ, "ύ"
+Ῥ, "ῥ"
+Ὸ, "ὸ"
+Ό, "ό"
+Ὼ, "ὼ"
+Ώ, "ώ"
+ῼ, "ῳ"
+Ⅎ, "ⅎ"
+Ⓐ, "ⓐ"
+Ⓑ, "ⓑ"
+Ⓒ, "ⓒ"
+Ⓓ, "ⓓ"
+Ⓔ, "ⓔ"
+Ⓕ, "ⓕ"
+Ⓖ, "ⓖ"
+Ⓗ, "ⓗ"
+Ⓘ, "ⓘ"
+Ⓙ, "ⓙ"
+Ⓚ, "ⓚ"
+Ⓛ, "ⓛ"
+Ⓜ, "ⓜ"
+Ⓝ, "ⓝ"
+Ⓞ, "ⓞ"
+Ⓟ, "ⓟ"
+Ⓠ, "ⓠ"
+Ⓡ, "ⓡ"
+Ⓢ, "ⓢ"
+Ⓣ, "ⓣ"
+Ⓤ, "ⓤ"
+Ⓥ, "ⓥ"
+Ⓦ, "ⓦ"
+Ⓧ, "ⓧ"
+Ⓨ, "ⓨ"
+Ⓩ, "ⓩ"
+Ⰰ, "ⰰ"
+Ⰱ, "ⰱ"
+Ⰲ, "ⰲ"
+Ⰳ, "ⰳ"
+Ⰴ, "ⰴ"
+Ⰵ, "ⰵ"
+Ⰶ, "ⰶ"
+Ⰷ, "ⰷ"
+Ⰸ, "ⰸ"
+Ⰹ, "ⰹ"
+Ⰺ, "ⰺ"
+Ⰻ, "ⰻ"
+Ⰼ, "ⰼ"
+Ⰽ, "ⰽ"
+Ⰾ, "ⰾ"
+Ⰿ, "ⰿ"
+Ⱀ, "ⱀ"
+Ⱁ, "ⱁ"
+Ⱂ, "ⱂ"
+Ⱃ, "ⱃ"
+Ⱄ, "ⱄ"
+Ⱅ, "ⱅ"
+Ⱆ, "ⱆ"
+Ⱇ, "ⱇ"
+Ⱈ, "ⱈ"
+Ⱉ, "ⱉ"
+Ⱊ, "ⱊ"
+Ⱋ, "ⱋ"
+Ⱌ, "ⱌ"
+Ⱍ, "ⱍ"
+Ⱎ, "ⱎ"
+Ⱏ, "ⱏ"
+Ⱐ, "ⱐ"
+Ⱑ, "ⱑ"
+Ⱒ, "ⱒ"
+Ⱓ, "ⱓ"
+Ⱔ, "ⱔ"
+Ⱕ, "ⱕ"
+Ⱖ, "ⱖ"
+Ⱗ, "ⱗ"
+Ⱘ, "ⱘ"
+Ⱙ, "ⱙ"
+Ⱚ, "ⱚ"
+Ⱛ, "ⱛ"
+Ⱜ, "ⱜ"
+Ⱝ, "ⱝ"
+Ⱞ, "ⱞ"
+Ⱡ, "ⱡ"
+Ɫ, "ɫ"
+Ᵽ, "ᵽ"
+Ɽ, "ɽ"
+Ⱨ, "ⱨ"
+Ⱪ, "ⱪ"
+Ⱬ, "ⱬ"
+Ɑ, "ɑ"
+Ɱ, "ɱ"
+Ɐ, "ɐ"
+Ɒ, "ɒ"
+Ⱳ, "ⱳ"
+Ⱶ, "ⱶ"
+Ȿ, "ȿ"
+Ɀ, "ɀ"
+Ⲁ, "ⲁ"
+Ⲃ, "ⲃ"
+Ⲅ, "ⲅ"
+Ⲇ, "ⲇ"
+Ⲉ, "ⲉ"
+Ⲋ, "ⲋ"
+Ⲍ, "ⲍ"
+Ⲏ, "ⲏ"
+Ⲑ, "ⲑ"
+Ⲓ, "ⲓ"
+Ⲕ, "ⲕ"
+Ⲗ, "ⲗ"
+Ⲙ, "ⲙ"
+Ⲛ, "ⲛ"
+Ⲝ, "ⲝ"
+Ⲟ, "ⲟ"
+Ⲡ, "ⲡ"
+Ⲣ, "ⲣ"
+Ⲥ, "ⲥ"
+Ⲧ, "ⲧ"
+Ⲩ, "ⲩ"
+Ⲫ, "ⲫ"
+Ⲭ, "ⲭ"
+Ⲯ, "ⲯ"
+Ⲱ, "ⲱ"
+Ⲳ, "ⲳ"
+Ⲵ, "ⲵ"
+Ⲷ, "ⲷ"
+Ⲹ, "ⲹ"
+Ⲻ, "ⲻ"
+Ⲽ, "ⲽ"
+Ⲿ, "ⲿ"
+Ⳁ, "ⳁ"
+Ⳃ, "ⳃ"
+Ⳅ, "ⳅ"
+Ⳇ, "ⳇ"
+Ⳉ, "ⳉ"
+Ⳋ, "ⳋ"
+Ⳍ, "ⳍ"
+Ⳏ, "ⳏ"
+Ⳑ, "ⳑ"
+Ⳓ, "ⳓ"
+Ⳕ, "ⳕ"
+Ⳗ, "ⳗ"
+Ⳙ, "ⳙ"
+Ⳛ, "ⳛ"
+Ⳝ, "ⳝ"
+Ⳟ, "ⳟ"
+Ⳡ, "ⳡ"
+Ⳣ, "ⳣ"
+Ⳬ, "ⳬ"
+Ⳮ, "ⳮ"
+Ꙁ, "ꙁ"
+Ꙃ, "ꙃ"
+Ꙅ, "ꙅ"
+Ꙇ, "ꙇ"
+Ꙉ, "ꙉ"
+Ꙋ, "ꙋ"
+Ꙍ, "ꙍ"
+Ꙏ, "ꙏ"
+Ꙑ, "ꙑ"
+Ꙓ, "ꙓ"
+Ꙕ, "ꙕ"
+Ꙗ, "ꙗ"
+Ꙙ, "ꙙ"
+Ꙛ, "ꙛ"
+Ꙝ, "ꙝ"
+Ꙟ, "ꙟ"
+Ꙡ, "ꙡ"
+Ꙣ, "ꙣ"
+Ꙥ, "ꙥ"
+Ꙧ, "ꙧ"
+Ꙩ, "ꙩ"
+Ꙫ, "ꙫ"
+Ꙭ, "ꙭ"
+Ꚁ, "ꚁ"
+Ꚃ, "ꚃ"
+Ꚅ, "ꚅ"
+Ꚇ, "ꚇ"
+Ꚉ, "ꚉ"
+Ꚋ, "ꚋ"
+Ꚍ, "ꚍ"
+Ꚏ, "ꚏ"
+Ꚑ, "ꚑ"
+Ꚓ, "ꚓ"
+Ꚕ, "ꚕ"
+Ꚗ, "ꚗ"
+Ꜣ, "ꜣ"
+Ꜥ, "ꜥ"
+Ꜧ, "ꜧ"
+Ꜩ, "ꜩ"
+Ꜫ, "ꜫ"
+Ꜭ, "ꜭ"
+Ꜯ, "ꜯ"
+Ꜳ, "ꜳ"
+Ꜵ, "ꜵ"
+Ꜷ, "ꜷ"
+Ꜹ, "ꜹ"
+Ꜻ, "ꜻ"
+Ꜽ, "ꜽ"
+Ꜿ, "ꜿ"
+Ꝁ, "ꝁ"
+Ꝃ, "ꝃ"
+Ꝅ, "ꝅ"
+Ꝇ, "ꝇ"
+Ꝉ, "ꝉ"
+Ꝋ, "ꝋ"
+Ꝍ, "ꝍ"
+Ꝏ, "ꝏ"
+Ꝑ, "ꝑ"
+Ꝓ, "ꝓ"
+Ꝕ, "ꝕ"
+Ꝗ, "ꝗ"
+Ꝙ, "ꝙ"
+Ꝛ, "ꝛ"
+Ꝝ, "ꝝ"
+Ꝟ, "ꝟ"
+Ꝡ, "ꝡ"
+Ꝣ, "ꝣ"
+Ꝥ, "ꝥ"
+Ꝧ, "ꝧ"
+Ꝩ, "ꝩ"
+Ꝫ, "ꝫ"
+Ꝭ, "ꝭ"
+Ꝯ, "ꝯ"
+Ꝺ, "ꝺ"
+Ꝼ, "ꝼ"
+Ᵹ, "ᵹ"
+Ꝿ, "ꝿ"
+Ꞁ, "ꞁ"
+Ꞃ, "ꞃ"
+Ꞅ, "ꞅ"
+Ꞇ, "ꞇ"
+Ꞌ, "ꞌ"
+Ɥ, "ɥ"
+Ꞑ, "ꞑ"
+Ꞡ, "ꞡ"
+Ꞣ, "ꞣ"
+Ꞥ, "ꞥ"
+Ꞧ, "ꞧ"
+Ꞩ, "ꞩ"
+A, "a"
+B, "b"
+C, "c"
+D, "d"
+E, "e"
+F, "f"
+G, "g"
+H, "h"
+I, "i"
+J, "j"
+K, "k"
+L, "l"
+M, "m"
+N, "n"
+O, "o"
+P, "p"
+Q, "q"
+R, "r"
+S, "s"
+T, "t"
+U, "u"
+V, "v"
+W, "w"
+X, "x"
+Y, "y"
+Z, "z"
+𐐀, "𐐨"
+𐐁, "𐐩"
+𐐂, "𐐪"
+𐐃, "𐐫"
+𐐄, "𐐬"
+𐐅, "𐐭"
+𐐆, "𐐮"
+𐐇, "𐐯"
+𐐈, "𐐰"
+𐐉, "𐐱"
+𐐊, "𐐲"
+𐐋, "𐐳"
+𐐌, "𐐴"
+𐐍, "𐐵"
+𐐎, "𐐶"
+𐐏, "𐐷"
+𐐐, "𐐸"
+𐐑, "𐐹"
+𐐒, "𐐺"
+𐐓, "𐐻"
+𐐔, "𐐼"
+𐐕, "𐐽"
+𐐖, "𐐾"
+𐐗, "𐐿"
+𐐘, "𐑀"
+𐐙, "𐑁"
+𐐚, "𐑂"
+𐐛, "𐑃"
+𐐜, "𐑄"
+𐐝, "𐑅"
+𐐞, "𐑆"
+𐐟, "𐑇"
+𐐠, "𐑈"
+𐐡, "𐑉"
+𐐢, "𐑊"
+𐐣, "𐑋"
+𐐤, "𐑌"
+𐐥, "𐑍"
+𐐦, "𐑎"
+𐐧, "𐑏"
diff --git a/utf8.c b/utf8.c
index f25ade2c..6249f94a 100644
--- a/utf8.c
+++ b/utf8.c
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -590,14 +590,13 @@ int u8_valid (const char *str,
/* See that we covered the entire length if a length was
* passed in, or that we ended on a nul if not
*/
- if (max_len >= 0 &&
- p != (str + max_len))
+ if (max_len >= 0 && p != (str + max_len) && *p != 0) {
return 0;
- else if (max_len < 0 &&
- *p != '\0')
+ }
+ else if (max_len < 0 && *p != '\0') {
return 0;
- else
- return 1;
+ }
+ return 1;
}
#if 0
@@ -689,6 +688,34 @@ utfcasestr (const char *s1, const char *s2) {
return NULL;
}
+int
+u8_strcasecmp (const char *a, const char *b) {
+ const char *p1 = a, *p2 = b;
+ while (*p1 && *p2) {
+ int32_t i1 = 0;
+ int32_t i2 = 0;
+ char s1[10], s2[10];
+ const char *next;
+ u8_nextchar (p1, &i1);
+ u8_nextchar (p2, &i2);
+ int l1 = u8_tolower (p1, i1, s1);
+ int l2 = u8_tolower (p2, i2, s2);
+ int res = 0;
+ if (l1 != l2) {
+ res = l1-l2;
+ }
+ else {
+ res = memcmp (s1, s2, l1);
+ }
+ if (res) {
+ return res;
+ }
+ p1 += i1;
+ p2 += i2;
+ }
+ return 0;
+}
+
void
u8_lc_map_test (void) {
struct u8_case_map_t *lc;
diff --git a/utf8.h b/utf8.h
index 7ec66ef5..9deb08a3 100644
--- a/utf8.h
+++ b/utf8.h
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -98,6 +98,12 @@ int u8_valid (const char *str,
int max_len,
const char **end);
+int
+u8_tolower (const signed char *c, int l, char *out);
+
+int
+u8_strcasecmp (const char *a, const char *b);
+
const char *
utfcasestr (const char *s1, const char *s2);
diff --git a/vfs.c b/vfs.c
index d4cf6ab2..08badec1 100644
--- a/vfs.c
+++ b/vfs.c
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@@ -32,14 +32,15 @@ vfs_fopen (const char *fname) {
int i;
for (i = 0; plugs[i]; i++) {
DB_vfs_t *p = plugs[i];
- if (!p->scheme_names) {
+ if (!p->get_schemes) {
fallback = p;
continue;
}
int n;
- for (n = 0; p->scheme_names[n]; n++) {
- size_t l = strlen (p->scheme_names[n]);
- if (!strncasecmp (p->scheme_names[n], fname, l)) {
+ const char **scheme_names = p->get_schemes ();
+ for (n = 0; scheme_names[n]; n++) {
+ size_t l = strlen (scheme_names[n]);
+ if (!strncasecmp (scheme_names[n], fname, l)) {
return p->open (fname);
}
}
diff --git a/vfs.h b/vfs.h
index 418365bc..b07bcaf3 100644
--- a/vfs.h
+++ b/vfs.h
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
diff --git a/vfs_stdio.c b/vfs_stdio.c
index a6fb5dba..2f62aa72 100644
--- a/vfs_stdio.c
+++ b/vfs_stdio.c
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@@ -21,11 +21,16 @@
#include <stdlib.h>
#include <assert.h>
#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
static DB_functions_t *deadbeef;
typedef struct {
DB_vfs_t *vfs;
- FILE *stream;
+ int stream;
+ int64_t offs;
} STDIO_FILE;
static DB_vfs_t plugin;
@@ -35,20 +40,21 @@ stdio_open (const char *fname) {
if (!memcmp (fname, "file://", 7)) {
fname += 7;
}
- FILE *file = fopen (fname, "rb");
- if (!file) {
+ int file = open (fname, O_LARGEFILE);
+ if (file == -1) {
return NULL;
}
STDIO_FILE *fp = malloc (sizeof (STDIO_FILE));
fp->vfs = &plugin;
fp->stream = file;
+ fp->offs = 0;
return (DB_FILE*)fp;
}
static void
stdio_close (DB_FILE *stream) {
assert (stream);
- fclose (((STDIO_FILE *)stream)->stream);
+ close (((STDIO_FILE *)stream)->stream);
free (stream);
}
@@ -56,36 +62,44 @@ static size_t
stdio_read (void *ptr, size_t size, size_t nmemb, DB_FILE *stream) {
assert (stream);
assert (ptr);
- return fread (ptr, size, nmemb, ((STDIO_FILE *)stream)->stream);
+ int res = read (((STDIO_FILE*)stream)->stream, ptr, size*nmemb);
+ if (res == -1) {
+ return 0;
+ }
+ ((STDIO_FILE*)stream)->offs += res;
+ return res / size;
}
static int
stdio_seek (DB_FILE *stream, int64_t offset, int whence) {
assert (stream);
- return fseek (((STDIO_FILE *)stream)->stream, offset, whence);
+ off64_t res = lseek64 (((STDIO_FILE *)stream)->stream, offset, whence);
+ if (res == -1) {
+ return -1;
+ }
+ ((STDIO_FILE*)stream)->offs = res;
+ return 0;
}
static int64_t
stdio_tell (DB_FILE *stream) {
assert (stream);
- return ftell (((STDIO_FILE *)stream)->stream);
+ return ((STDIO_FILE*)stream)->offs;
}
static void
stdio_rewind (DB_FILE *stream) {
assert (stream);
- rewind (((STDIO_FILE *)stream)->stream);
+ stdio_seek (stream, 0, SEEK_SET);
}
static int64_t
stdio_getlength (DB_FILE *stream) {
assert (stream);
STDIO_FILE *f = (STDIO_FILE *)stream;
- size_t pos = ftell (f->stream);
- fseek (f->stream, 0, SEEK_END);
- size_t sz = ftell (f->stream);
- fseek (f->stream, pos, SEEK_SET);
- return sz;
+ int64_t size = lseek64 (f->stream, 0, SEEK_END);
+ lseek64 (f->stream, f->offs, SEEK_SET);
+ return size;
}
const char *
@@ -93,6 +107,11 @@ stdio_get_content_type (DB_FILE *stream) {
return NULL;
}
+int
+stdio_is_streaming (void) {
+ return 0;
+}
+
// standard stdio vfs
static DB_vfs_t plugin = {
DB_PLUGIN_SET_API_VERSION
@@ -100,9 +119,24 @@ static DB_vfs_t plugin = {
.plugin.version_minor = 1,
.plugin.type = DB_PLUGIN_VFS,
.plugin.name = "stdio vfs",
- .plugin.descr = "Standard IO plugin",
- .plugin.author = "Alexey Yakovenko",
- .plugin.email = "waker@users.sourceforge.net",
+ .plugin.descr = "Standard IO plugin\nUsed for reading normal local files\nIt is statically linked, so you can't delete it.",
+ .plugin.copyright =
+ "Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>\n"
+ "\n"
+ "This program is free software; you can redistribute it and/or\n"
+ "modify it under the terms of the GNU General Public License\n"
+ "as published by the Free Software Foundation; either version 2\n"
+ "of the License, or (at your option) any later version.\n"
+ "\n"
+ "This program is distributed in the hope that it will be useful,\n"
+ "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+ "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+ "GNU General Public License for more details.\n"
+ "\n"
+ "You should have received a copy of the GNU General Public License\n"
+ "along with this program; if not, write to the Free Software\n"
+ "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n"
+ ,
.plugin.website = "http://deadbeef.sf.net",
.open = stdio_open,
.close = stdio_close,
@@ -112,7 +146,7 @@ static DB_vfs_t plugin = {
.rewind = stdio_rewind,
.getlength = stdio_getlength,
.get_content_type = stdio_get_content_type,
- .scheme_names = NULL // this is NULL because that's a fallback vfs, used when no other matching vfs plugin found
+ .is_streaming = stdio_is_streaming
};
DB_plugin_t *
diff --git a/volume.c b/volume.c
index a8fe1156..db32ed99 100644
--- a/volume.c
+++ b/volume.c
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
diff --git a/volume.h b/volume.h
index 73c38c0c..593088e2 100644
--- a/volume.h
+++ b/volume.h
@@ -1,6 +1,6 @@
/*
DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License